diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 7466fc461d3f8..5cad582e21409 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -337,6 +337,7 @@ void SDL_RemoveMouse(SDL_MouseID mouseID, bool send_event) for (int i = 0; i < mouse->num_sources; ++i) { SDL_MouseInputSource *source = &mouse->sources[i]; if (source->mouseID == mouseID) { + SDL_free(source->clickstate); if (i != mouse->num_sources - 1) { SDL_memcpy(&mouse->sources[i], &mouse->sources[i + 1], (mouse->num_sources - i - 1) * sizeof(mouse->sources[i])); } @@ -728,6 +729,9 @@ static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL // Use unclamped values if we're getting events outside the window mouse->last_x = relative ? mouse->x : x; mouse->last_y = relative ? mouse->y : y; + + mouse->click_motion_x += xrel; + mouse->click_motion_y += yrel; } // Move the mouse cursor, if needed @@ -795,29 +799,29 @@ static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID m mouse->sources = sources; ++mouse->num_sources; source = &sources[mouse->num_sources - 1]; + SDL_zerop(source); source->mouseID = mouseID; - source->buttonstate = 0; return source; } return NULL; } -static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button) +static SDL_MouseClickState *GetMouseClickState(SDL_MouseInputSource *source, Uint8 button) { - if (button >= mouse->num_clickstates) { + if (button >= source->num_clickstates) { int i, count = button + 1; - SDL_MouseClickState *clickstate = (SDL_MouseClickState *)SDL_realloc(mouse->clickstate, count * sizeof(*mouse->clickstate)); + SDL_MouseClickState *clickstate = (SDL_MouseClickState *)SDL_realloc(source->clickstate, count * sizeof(*source->clickstate)); if (!clickstate) { return NULL; } - mouse->clickstate = clickstate; + source->clickstate = clickstate; - for (i = mouse->num_clickstates; i < count; ++i) { - SDL_zero(mouse->clickstate[i]); + for (i = source->num_clickstates; i < count; ++i) { + SDL_zero(source->clickstate[i]); } - mouse->num_clickstates = count; + source->num_clickstates = count; } - return &mouse->clickstate[button]; + return &source->clickstate[button]; } static void SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 button, bool down, int clicks) @@ -882,19 +886,19 @@ static void SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL source->buttonstate = buttonstate; if (clicks < 0) { - SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button); + SDL_MouseClickState *clickstate = GetMouseClickState(source, button); if (clickstate) { if (down) { Uint64 now = SDL_GetTicks(); if (now >= (clickstate->last_timestamp + mouse->double_click_time) || - SDL_fabs((double)mouse->x - clickstate->last_x) > mouse->double_click_radius || - SDL_fabs((double)mouse->y - clickstate->last_y) > mouse->double_click_radius) { + SDL_fabs(mouse->click_motion_x - clickstate->click_motion_x) > mouse->double_click_radius || + SDL_fabs(mouse->click_motion_y - clickstate->click_motion_y) > mouse->double_click_radius) { clickstate->click_count = 0; } clickstate->last_timestamp = now; - clickstate->last_x = mouse->x; - clickstate->last_y = mouse->y; + clickstate->click_motion_x = mouse->click_motion_x; + clickstate->click_motion_y = mouse->click_motion_y; if (clickstate->click_count < 255) { ++clickstate->click_count; } @@ -1001,17 +1005,15 @@ void SDL_QuitMouse(void) mouse->cur_cursor = NULL; if (mouse->sources) { + for (int i = 0; i < mouse->num_sources; ++i) { + SDL_MouseInputSource *source = &mouse->sources[i]; + SDL_free(source->clickstate); + } SDL_free(mouse->sources); mouse->sources = NULL; } mouse->num_sources = 0; - if (mouse->clickstate) { - SDL_free(mouse->clickstate); - mouse->clickstate = NULL; - } - mouse->num_clickstates = 0; - SDL_RemoveHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME, SDL_MouseDoubleClickTimeChanged, mouse); diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index b1040fff495f7..074e64225f87f 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -39,17 +39,22 @@ struct SDL_Cursor typedef struct { - SDL_MouseID mouseID; - Uint32 buttonstate; -} SDL_MouseInputSource; - -typedef struct -{ - float last_x, last_y; Uint64 last_timestamp; + double click_motion_x; + double click_motion_y; Uint8 click_count; } SDL_MouseClickState; +typedef struct +{ + SDL_MouseID mouseID; + Uint32 buttonstate; + + // Data for double-click tracking + int num_clickstates; + SDL_MouseClickState *clickstate; +} SDL_MouseInputSource; + typedef struct { // Create a cursor from a surface @@ -93,6 +98,8 @@ typedef struct float x_accu; float y_accu; float last_x, last_y; // the last reported x and y coordinates + double click_motion_x; + double click_motion_y; bool has_position; bool relative_mode; bool relative_mode_warp_motion; @@ -123,10 +130,6 @@ typedef struct int num_sources; SDL_MouseInputSource *sources; - // Data for double-click tracking - int num_clickstates; - SDL_MouseClickState *clickstate; - SDL_Cursor *cursors; SDL_Cursor *def_cursor; SDL_Cursor *cur_cursor;