x11: Filter mouse wheel events from "Master" devices
Discard wheel events from "Master" devices to avoid duplicates, as wheel events are stateless and can't be deduplicated.
This commit is contained in:
@@ -194,7 +194,7 @@ static bool X11_KeyRepeat(Display *display, XEvent *event)
|
|||||||
return d.found;
|
return d.found;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool X11_IsWheelEvent(Display *display, int button, int *xticks, int *yticks)
|
bool X11_IsWheelEvent(int button, int *xticks, int *yticks)
|
||||||
{
|
{
|
||||||
/* according to the xlib docs, no specific mouse wheel events exist.
|
/* according to the xlib docs, no specific mouse wheel events exist.
|
||||||
However, the defacto standard is that the vertical wheel is X buttons
|
However, the defacto standard is that the vertical wheel is X buttons
|
||||||
@@ -1016,8 +1016,6 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
|
|||||||
void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time)
|
void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time)
|
||||||
{
|
{
|
||||||
SDL_Window *window = windowdata->window;
|
SDL_Window *window = windowdata->window;
|
||||||
const SDL_VideoData *videodata = _this->internal;
|
|
||||||
Display *display = videodata->display;
|
|
||||||
int xticks = 0, yticks = 0;
|
int xticks = 0, yticks = 0;
|
||||||
Uint64 timestamp = X11_GetEventTimestamp(time);
|
Uint64 timestamp = X11_GetEventTimestamp(time);
|
||||||
|
|
||||||
@@ -1031,7 +1029,7 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
|
|||||||
SDL_SendMouseMotion(timestamp, window, mouseID, false, x, y);
|
SDL_SendMouseMotion(timestamp, window, mouseID, false, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (X11_IsWheelEvent(display, button, &xticks, &yticks)) {
|
if (X11_IsWheelEvent(button, &xticks, &yticks)) {
|
||||||
SDL_SendMouseWheel(timestamp, window, mouseID, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL);
|
SDL_SendMouseWheel(timestamp, window, mouseID, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL);
|
||||||
} else {
|
} else {
|
||||||
bool ignore_click = false;
|
bool ignore_click = false;
|
||||||
@@ -1063,8 +1061,6 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
|
|||||||
void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time)
|
void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time)
|
||||||
{
|
{
|
||||||
SDL_Window *window = windowdata->window;
|
SDL_Window *window = windowdata->window;
|
||||||
const SDL_VideoData *videodata = _this->internal;
|
|
||||||
Display *display = videodata->display;
|
|
||||||
// The X server sends a Release event for each Press for wheels. Ignore them.
|
// The X server sends a Release event for each Press for wheels. Ignore them.
|
||||||
int xticks = 0, yticks = 0;
|
int xticks = 0, yticks = 0;
|
||||||
Uint64 timestamp = X11_GetEventTimestamp(time);
|
Uint64 timestamp = X11_GetEventTimestamp(time);
|
||||||
@@ -1072,7 +1068,7 @@ void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata,
|
|||||||
#ifdef DEBUG_XEVENTS
|
#ifdef DEBUG_XEVENTS
|
||||||
SDL_Log("window 0x%lx: ButtonRelease (X11 button = %d)", windowdata->xwindow, button);
|
SDL_Log("window 0x%lx: ButtonRelease (X11 button = %d)", windowdata->xwindow, button);
|
||||||
#endif
|
#endif
|
||||||
if (!X11_IsWheelEvent(display, button, &xticks, &yticks)) {
|
if (!X11_IsWheelEvent(button, &xticks, &yticks)) {
|
||||||
if (button > 7) {
|
if (button > 7) {
|
||||||
// see explanation at case ButtonPress
|
// see explanation at case ButtonPress
|
||||||
button -= (8 - SDL_BUTTON_X1);
|
button -= (8 - SDL_BUTTON_X1);
|
||||||
|
|||||||
@@ -36,5 +36,6 @@ extern void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *wind
|
|||||||
extern SDL_WindowData *X11_FindWindow(SDL_VideoDevice *_this, Window window);
|
extern SDL_WindowData *X11_FindWindow(SDL_VideoDevice *_this, Window window);
|
||||||
extern bool X11_ProcessHitTest(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y, bool force_new_result);
|
extern bool X11_ProcessHitTest(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y, bool force_new_result);
|
||||||
extern bool X11_TriggerHitTestAction(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y);
|
extern bool X11_TriggerHitTestAction(SDL_VideoDevice *_this, SDL_WindowData *data, const float x, const float y);
|
||||||
|
extern bool X11_IsWheelEvent(int button, int *xticks, int *yticks);
|
||||||
|
|
||||||
#endif // SDL_x11events_h_
|
#endif // SDL_x11events_h_
|
||||||
|
|||||||
@@ -425,6 +425,14 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
|
|||||||
} else {
|
} else {
|
||||||
// Otherwise assume a regular mouse
|
// Otherwise assume a regular mouse
|
||||||
SDL_WindowData *windowdata = xinput2_get_sdlwindowdata(videodata, xev->event);
|
SDL_WindowData *windowdata = xinput2_get_sdlwindowdata(videodata, xev->event);
|
||||||
|
int x_ticks = 0, y_ticks = 0;
|
||||||
|
|
||||||
|
/* Discard wheel events from "Master" devices to avoid duplicates,
|
||||||
|
* as coarse wheel events are stateless and can't be deduplicated.
|
||||||
|
*/
|
||||||
|
if (xev->deviceid != xev->sourceid && X11_IsWheelEvent(button, &x_ticks, &y_ticks)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (down) {
|
if (down) {
|
||||||
X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button,
|
X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button,
|
||||||
|
|||||||
Reference in New Issue
Block a user