Fixed mouse click count for relative mode and multiple mice
We'll track the click count separately for each input source, and the click distance is calculated using a point on an infinite plane that is pushed around by mouse motion deltas, unclamped by the window edge.
This commit is contained in:
parent
ed75d9d22a
commit
483e79bf82
2 changed files with 36 additions and 31 deletions
|
@ -337,6 +337,7 @@ void SDL_RemoveMouse(SDL_MouseID mouseID, bool send_event)
|
||||||
for (int i = 0; i < mouse->num_sources; ++i) {
|
for (int i = 0; i < mouse->num_sources; ++i) {
|
||||||
SDL_MouseInputSource *source = &mouse->sources[i];
|
SDL_MouseInputSource *source = &mouse->sources[i];
|
||||||
if (source->mouseID == mouseID) {
|
if (source->mouseID == mouseID) {
|
||||||
|
SDL_free(source->clickstate);
|
||||||
if (i != mouse->num_sources - 1) {
|
if (i != mouse->num_sources - 1) {
|
||||||
SDL_memcpy(&mouse->sources[i], &mouse->sources[i + 1], (mouse->num_sources - i - 1) * sizeof(mouse->sources[i]));
|
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
|
// Use unclamped values if we're getting events outside the window
|
||||||
mouse->last_x = relative ? mouse->x : x;
|
mouse->last_x = relative ? mouse->x : x;
|
||||||
mouse->last_y = relative ? mouse->y : y;
|
mouse->last_y = relative ? mouse->y : y;
|
||||||
|
|
||||||
|
mouse->click_motion_x += xrel;
|
||||||
|
mouse->click_motion_y += yrel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the mouse cursor, if needed
|
// Move the mouse cursor, if needed
|
||||||
|
@ -795,29 +799,29 @@ static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID m
|
||||||
mouse->sources = sources;
|
mouse->sources = sources;
|
||||||
++mouse->num_sources;
|
++mouse->num_sources;
|
||||||
source = &sources[mouse->num_sources - 1];
|
source = &sources[mouse->num_sources - 1];
|
||||||
|
SDL_zerop(source);
|
||||||
source->mouseID = mouseID;
|
source->mouseID = mouseID;
|
||||||
source->buttonstate = 0;
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
return NULL;
|
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;
|
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) {
|
if (!clickstate) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
mouse->clickstate = clickstate;
|
source->clickstate = clickstate;
|
||||||
|
|
||||||
for (i = mouse->num_clickstates; i < count; ++i) {
|
for (i = source->num_clickstates; i < count; ++i) {
|
||||||
SDL_zero(mouse->clickstate[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)
|
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;
|
source->buttonstate = buttonstate;
|
||||||
|
|
||||||
if (clicks < 0) {
|
if (clicks < 0) {
|
||||||
SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button);
|
SDL_MouseClickState *clickstate = GetMouseClickState(source, button);
|
||||||
if (clickstate) {
|
if (clickstate) {
|
||||||
if (down) {
|
if (down) {
|
||||||
Uint64 now = SDL_GetTicks();
|
Uint64 now = SDL_GetTicks();
|
||||||
|
|
||||||
if (now >= (clickstate->last_timestamp + mouse->double_click_time) ||
|
if (now >= (clickstate->last_timestamp + mouse->double_click_time) ||
|
||||||
SDL_fabs((double)mouse->x - clickstate->last_x) > mouse->double_click_radius ||
|
SDL_fabs(mouse->click_motion_x - clickstate->click_motion_x) > mouse->double_click_radius ||
|
||||||
SDL_fabs((double)mouse->y - clickstate->last_y) > mouse->double_click_radius) {
|
SDL_fabs(mouse->click_motion_y - clickstate->click_motion_y) > mouse->double_click_radius) {
|
||||||
clickstate->click_count = 0;
|
clickstate->click_count = 0;
|
||||||
}
|
}
|
||||||
clickstate->last_timestamp = now;
|
clickstate->last_timestamp = now;
|
||||||
clickstate->last_x = mouse->x;
|
clickstate->click_motion_x = mouse->click_motion_x;
|
||||||
clickstate->last_y = mouse->y;
|
clickstate->click_motion_y = mouse->click_motion_y;
|
||||||
if (clickstate->click_count < 255) {
|
if (clickstate->click_count < 255) {
|
||||||
++clickstate->click_count;
|
++clickstate->click_count;
|
||||||
}
|
}
|
||||||
|
@ -1001,17 +1005,15 @@ void SDL_QuitMouse(void)
|
||||||
mouse->cur_cursor = NULL;
|
mouse->cur_cursor = NULL;
|
||||||
|
|
||||||
if (mouse->sources) {
|
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);
|
SDL_free(mouse->sources);
|
||||||
mouse->sources = NULL;
|
mouse->sources = NULL;
|
||||||
}
|
}
|
||||||
mouse->num_sources = 0;
|
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_RemoveHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME,
|
||||||
SDL_MouseDoubleClickTimeChanged, mouse);
|
SDL_MouseDoubleClickTimeChanged, mouse);
|
||||||
|
|
||||||
|
|
|
@ -39,16 +39,21 @@ struct SDL_Cursor
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
SDL_MouseID mouseID;
|
Uint64 last_timestamp;
|
||||||
Uint32 buttonstate;
|
double click_motion_x;
|
||||||
} SDL_MouseInputSource;
|
double click_motion_y;
|
||||||
|
Uint8 click_count;
|
||||||
|
} SDL_MouseClickState;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
float last_x, last_y;
|
SDL_MouseID mouseID;
|
||||||
Uint64 last_timestamp;
|
Uint32 buttonstate;
|
||||||
Uint8 click_count;
|
|
||||||
} SDL_MouseClickState;
|
// Data for double-click tracking
|
||||||
|
int num_clickstates;
|
||||||
|
SDL_MouseClickState *clickstate;
|
||||||
|
} SDL_MouseInputSource;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -93,6 +98,8 @@ typedef struct
|
||||||
float x_accu;
|
float x_accu;
|
||||||
float y_accu;
|
float y_accu;
|
||||||
float last_x, last_y; // the last reported x and y coordinates
|
float last_x, last_y; // the last reported x and y coordinates
|
||||||
|
double click_motion_x;
|
||||||
|
double click_motion_y;
|
||||||
bool has_position;
|
bool has_position;
|
||||||
bool relative_mode;
|
bool relative_mode;
|
||||||
bool relative_mode_warp_motion;
|
bool relative_mode_warp_motion;
|
||||||
|
@ -123,10 +130,6 @@ typedef struct
|
||||||
int num_sources;
|
int num_sources;
|
||||||
SDL_MouseInputSource *sources;
|
SDL_MouseInputSource *sources;
|
||||||
|
|
||||||
// Data for double-click tracking
|
|
||||||
int num_clickstates;
|
|
||||||
SDL_MouseClickState *clickstate;
|
|
||||||
|
|
||||||
SDL_Cursor *cursors;
|
SDL_Cursor *cursors;
|
||||||
SDL_Cursor *def_cursor;
|
SDL_Cursor *def_cursor;
|
||||||
SDL_Cursor *cur_cursor;
|
SDL_Cursor *cur_cursor;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue