Skip to content

Commit

Permalink
fix errenous delta when warping
Browse files Browse the repository at this point in the history
The following changes do not alter any logic:
- rename x/ydelta fields to x/y_accu to better reflect what it actually is about
- coalesce the logic for modifying internal state to one spot, branch based on whether the input was a move or a warp

The following changes alter the logic:
- put the x/y_accu addition under the relative branch only, warps should not add to the accumulation buffer by any definition
- (MAIN FIX) when the destination window desires relative mode, warp events should be dropped if SDL_MOUSE_RELATIVE_WARP_MOTION is false, or have x/yrel set to zero if true
  • Loading branch information
expikr committed Nov 14, 2024
1 parent 20cd429 commit 8560cc7
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 28 deletions.
49 changes: 23 additions & 26 deletions src/events/SDL_mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,6 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL
ConstrainMousePosition(mouse, window, &x, &y);
} else {
ConstrainMousePosition(mouse, window, &x, &y);

if (mouse->has_position) {
xrel = x - mouse->last_x;
yrel = y - mouse->last_y;
Expand All @@ -814,25 +813,30 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL
yrel = 0.0f;
}

if (mouse->has_position) {
// Update internal mouse coordinates
if (!mouse->relative_mode) {
{ // modify internal state
if (relative) {
if (mouse->has_position) {
mouse->x += xrel;
mouse->y += yrel;
ConstrainMousePosition(mouse, window, &mouse->x, &mouse->y);
} else {
mouse->x = x;
mouse->y = y;
}
mouse->last_x = mouse->x;
mouse->last_y = mouse->y;
mouse->x_accu += xrel;
mouse->y_accu += yrel;
} else {
// Use unclamped values if we're getting events outside the window
mouse->x = x;
mouse->y = y;
} else {
mouse->x += xrel;
mouse->y += yrel;
ConstrainMousePosition(mouse, window, &mouse->x, &mouse->y);
mouse->last_x = x;
mouse->last_y = y;
}
} else {
mouse->x = x;
mouse->y = y;
mouse->has_position = true;
}

mouse->xdelta += xrel;
mouse->ydelta += yrel;

// Move the mouse cursor, if needed
if (mouse->cursor_shown && !mouse->relative_mode &&
mouse->MoveCursor && mouse->cur_cursor) {
Expand All @@ -841,6 +845,7 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL

// Post the event, if desired
if (SDL_EventEnabled(SDL_EVENT_MOUSE_MOTION)) {
if (!relative && !mouse->relative_mode_warp_motion && mouse->focus && (mouse->focus->flags & SDL_WINDOW_MOUSE_RELATIVE_MODE)) return;
SDL_Event event;
event.type = SDL_EVENT_MOUSE_MOTION;
event.common.timestamp = timestamp;
Expand All @@ -855,14 +860,6 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL
event.motion.yrel = yrel;
SDL_PushEvent(&event);
}
if (relative) {
mouse->last_x = mouse->x;
mouse->last_y = mouse->y;
} else {
// Use unclamped values if we're getting events outside the window
mouse->last_x = x;
mouse->last_y = y;
}
}

static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID mouseID, bool down, Uint8 button)
Expand Down Expand Up @@ -1178,13 +1175,13 @@ SDL_MouseButtonFlags SDL_GetRelativeMouseState(float *x, float *y)
SDL_Mouse *mouse = SDL_GetMouse();

if (x) {
*x = mouse->xdelta;
*x = mouse->x_accu;
}
if (y) {
*y = mouse->ydelta;
*y = mouse->y_accu;
}
mouse->xdelta = 0.0f;
mouse->ydelta = 0.0f;
mouse->x_accu = 0.0f;
mouse->y_accu = 0.0f;
return SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, true);
}

Expand Down
4 changes: 2 additions & 2 deletions src/events/SDL_mouse_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ typedef struct
SDL_Window *focus;
float x;
float y;
float xdelta;
float ydelta;
float x_accu;
float y_accu;
float last_x, last_y; // the last reported x and y coordinates
bool has_position;
bool relative_mode;
Expand Down

0 comments on commit 8560cc7

Please sign in to comment.