فهرست منبع

x11: Reject click-through button events based on serial

XInput2 may send mouse buttons presses on both the master and slave devices, and the click-through button event should be ignored on both if required.
Frank Praznik 1 روز پیش
والد
کامیت
8371c09aa7
4فایلهای تغییر یافته به همراه10 افزوده شده و 7 حذف شده
  1. 7 5
      src/video/x11/SDL_x11events.c
  2. 1 1
      src/video/x11/SDL_x11events.h
  3. 1 0
      src/video/x11/SDL_x11window.h
  4. 1 1
      src/video/x11/SDL_x11xinput2.c

+ 7 - 5
src/video/x11/SDL_x11events.c

@@ -1130,7 +1130,7 @@ 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, unsigned long serial)
 {
 {
     SDL_Window *window = windowdata->window;
     SDL_Window *window = windowdata->window;
     int xticks = 0, yticks = 0;
     int xticks = 0, yticks = 0;
@@ -1149,7 +1149,6 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
     if (X11_IsWheelEvent(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;
         if (button > 7) {
         if (button > 7) {
             /* X button values 4-7 are used for scrolling, so X1 is 8, X2 is 9, ...
             /* X button values 4-7 are used for scrolling, so X1 is 8, X2 is 9, ...
                => subtract (8-SDL_BUTTON_X1) to get value SDL expects */
                => subtract (8-SDL_BUTTON_X1) to get value SDL expects */
@@ -1164,11 +1163,14 @@ void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, S
         if (windowdata->last_focus_event_time) {
         if (windowdata->last_focus_event_time) {
             const int X11_FOCUS_CLICK_TIMEOUT = 10;
             const int X11_FOCUS_CLICK_TIMEOUT = 10;
             if (SDL_GetTicks() < (windowdata->last_focus_event_time + X11_FOCUS_CLICK_TIMEOUT)) {
             if (SDL_GetTicks() < (windowdata->last_focus_event_time + X11_FOCUS_CLICK_TIMEOUT)) {
-                ignore_click = !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, false);
+                if (!SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, false)) {
+                    // Ignore all press events with this serial.
+                    windowdata->ignore_button_press_serial = serial;
+                }
             }
             }
             windowdata->last_focus_event_time = 0;
             windowdata->last_focus_event_time = 0;
         }
         }
-        if (!ignore_click) {
+        if (serial != windowdata->ignore_button_press_serial) {
             SDL_SendMouseButton(timestamp, window, mouseID, button, true);
             SDL_SendMouseButton(timestamp, window, mouseID, button, true);
         }
         }
     }
     }
@@ -1872,7 +1874,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
         }
         }
 
 
         X11_HandleButtonPress(_this, data, SDL_GLOBAL_MOUSE_ID, xevent->xbutton.button,
         X11_HandleButtonPress(_this, data, SDL_GLOBAL_MOUSE_ID, xevent->xbutton.button,
-                              xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.time);
+                              xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.time, xevent->xbutton.serial);
     } break;
     } break;
 
 
     case ButtonRelease:
     case ButtonRelease:

+ 1 - 1
src/video/x11/SDL_x11events.h

@@ -31,7 +31,7 @@ extern void X11_ReconcileKeyboardState(SDL_VideoDevice *_this);
 extern void X11_GetBorderValues(SDL_WindowData *data);
 extern void X11_GetBorderValues(SDL_WindowData *data);
 extern Uint64 X11_GetEventTimestamp(unsigned long time);
 extern Uint64 X11_GetEventTimestamp(unsigned long time);
 extern void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_KeyboardID keyboardID, XEvent *xevent);
 extern void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_KeyboardID keyboardID, XEvent *xevent);
-extern void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time);
+extern void X11_HandleButtonPress(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, float x, float y, unsigned long time, unsigned long serial);
 extern void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time);
 extern void X11_HandleButtonRelease(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_MouseID mouseID, int button, unsigned long time);
 extern SDL_WindowData *X11_FindWindow(SDL_VideoData *videodata, Window window);
 extern SDL_WindowData *X11_FindWindow(SDL_VideoData *videodata, 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);

+ 1 - 0
src/video/x11/SDL_x11window.h

@@ -63,6 +63,7 @@ struct SDL_WindowData
     bool xinput2_keyboard_enabled;
     bool xinput2_keyboard_enabled;
     bool mouse_grabbed;
     bool mouse_grabbed;
     Uint64 last_focus_event_time;
     Uint64 last_focus_event_time;
+    unsigned long ignore_button_press_serial;
     PendingFocusEnum pending_focus;
     PendingFocusEnum pending_focus;
     Uint64 pending_focus_time;
     Uint64 pending_focus_time;
     bool pending_move;
     bool pending_move;

+ 1 - 1
src/video/x11/SDL_x11xinput2.c

@@ -646,7 +646,7 @@ void X11_HandleXinput2Event(SDL_VideoDevice *_this, XGenericEventCookie *cookie)
 
 
             if (down) {
             if (down) {
                 X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button,
                 X11_HandleButtonPress(_this, windowdata, (SDL_MouseID)xev->sourceid, button,
-                                      (float)xev->event_x, (float)xev->event_y, xev->time);
+                                      (float)xev->event_x, (float)xev->event_y, xev->time, xev->serial);
             } else {
             } else {
                 X11_HandleButtonRelease(_this, windowdata, (SDL_MouseID)xev->sourceid, button, xev->time);
                 X11_HandleButtonRelease(_this, windowdata, (SDL_MouseID)xev->sourceid, button, xev->time);
             }
             }