-
Notifications
You must be signed in to change notification settings - Fork 524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sokol_app.h: initial mouse position #1170
base: master
Are you sure you want to change the base?
sokol_app.h: initial mouse position #1170
Conversation
Send an initial mouse move event just after init and before the first frame. That allows the app to know where the mouse is before mouse is actually moved.
To test, run the event-sapp sample on macos, and notice that the MOUSE_MOVE box shows the correct mouse pos value. Previously it would show 0.00 0.00 |
Hmm, that sounds like a weird use case tbh... wouldn't it be better to disable the aiming mechanism (and visualization) until the first 'proper' mouse event is received? From googling around it looks like on HTML5 it's not possible to poll the mouse position, so any mechanism to get an initial mouse position without the mouse being moved first wouldn't work there. Does GLFW have a solution for that problem (because the GLFW code base is sort-of the reference for sokol_app.h, it doesn't help with HTML5 problems though). |
PS: please ignore the broken CI build, that's a problem with the sokol-d build.zig not being fixed for zig 0.14.x |
Yes, this example was quite specific. I had the "problem" before with other things though. I see three ways to fix it:
Yes, could definitely implement mouse_pos_is_valid() and not aim or offset the camera as long as it returns false. But I think it would be great if user code didn't have to worry about it (not just for this specific example, but for all games/app using sokol and storing + polling the mouse position in that way). For the web it's unfortunate that the mouse pos is not accessible from the start. But since many things require user interaction to start working anyway (e.g sound) I think many people require the user to focus the app/game before starting already, and I presume this would send a mouse_move event? I tested on windows and it happened to work with no change beyond what I did for macos. It seems that windows sends a WM_MOUSEMOVE event at startup, which updates the internal sokol mouse pos even if the sokol_event is never sent (since it happens before init_cb is called). |
I need to think about this a bit more. I was thinking that sokol_app.h should track an internal is_mouse_pos_valid flag which is set to true on the first received mouse move event, and that this flag should also go into But it turns out that on some platforms the current mouse position is also sent in non-mouse-move events (from the operating system), and in that case the So it actually is possible to receive a mouse position and delta piggybacked on another OS event before the first mouse-move event arries. ...and in the past there have also been fixes to make such mouse positions reported in non-mouse-move events work before the first mouse-move event is received. There is still a phase after start where the internally tracked mouse position isn't valid, but it is not necessarily the first mouse move event which provides the first valid mouse position, it can be any other OS-specific event. ...it might still make sense to add a flag to As a conversative workaround I would suggest that you track your own mouse state, something like: typedef struct {
float x, y;
bool valid;
} mouse_pos_t; ...and in the sokol-app event handler function, update this when receiving mouse-button or -move events: ...
case SAPP_EVENTTYPE_MOUSE_DOWN:
case SAPP_EVENTTYPE_MOUSE_UP:
case SAPP_EVENTTYPE_MOUSE_MOVE:
mouse_pos.valid = true;
mouse_pos.x = ev->mouse_x;
mouse_pos.y = ev->mouse_y;
break;
... |
I already do what you suggest, but want to get the mouse pos at app launch, before the user moves the mouse (to remove the requirement of checking that the position is valid every time I need the position). Passing the mouse pos via another event at app launch would 100% fulfil that need. Personally, I think sending an initial mouse_event is also fine and actually makes some sense — you don't know what the mouse was doing just before app launch, so you might as well pretend it "moved". The fact that Windows does this too (it seems to send a WM_MOUSEMOVE to the window when it opens) conforts me in that idea. In any case I think this is a pretty small issue, more a case of polish than an actual problem, and I'm perfectly happy patching it on my side for my own use. So if you want to avoid wasting time and brain energy on this we can close the issue |
Send an initial mouse move event just after init and before the first frame. That allows the app to know where the mouse is before mouse is actually moved.
My use case was a small topdown shooter game where you aim with the mouse. At app launch the aim target was the top-left corner of the window, and as soon as you moved the mouse the target would jump, also teleporting the camera, which was jarring.
I initially wanted to modify only applicationDidFinishLaunching and send the event from there, but the user code might do some setup in init and not be ready to receive a move event before (the samples do that with dear imgui). Therefore I put the sending of the event in _sapp_frame, just after init.
If that sounds like a good improvement, I can implement the other platforms. I'll look at windows now.