Commit 67bdbcca445fe4dc9f6cdf197f77c1f40e8a9229

Sam Lantinga 2016-09-29T16:05:29

Implemented SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH on X11

diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c
index 8e58508..51f2915 100644
--- a/src/video/x11/SDL_x11events.c
+++ b/src/video/x11/SDL_x11events.c
@@ -35,6 +35,7 @@
 #include "../../events/SDL_mouse_c.h"
 #include "../../events/SDL_touch_c.h"
 
+#include "SDL_hints.h"
 #include "SDL_timer.h"
 #include "SDL_syswm.h"
 
@@ -523,9 +524,9 @@ X11_UpdateUserTime(SDL_WindowData *data, const unsigned long latest)
         X11_XChangeProperty(display, data->xwindow, videodata->_NET_WM_USER_TIME,
                             XA_CARDINAL, 32, PropModeReplace,
                             (const unsigned char *) &latest, 1);
-        #if DEBUG_XEVENTS
+#ifdef DEBUG_XEVENTS
         printf("window %p: updating _NET_WM_USER_TIME to %lu\n", data, latest);
-        #endif
+#endif
         data->user_time = latest;
     }
 }
@@ -711,6 +712,7 @@ X11_DispatchEvent(_THIS)
                 data->pending_focus = PENDING_FOCUS_IN;
                 data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME;
             }
+            data->last_focus_event_time = SDL_GetTicks();
         }
         break;
 
@@ -987,7 +989,7 @@ X11_DispatchEvent(_THIS)
             SDL_Mouse *mouse = SDL_GetMouse();
             if(!mouse->relative_mode || mouse->relative_mode_warp) {
 #ifdef DEBUG_MOTION
-                printf("window %p: X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y);
+                printf("window %p: X11 motion: %d,%d\n", data, xevent.xmotion.x, xevent.xmotion.y);
 #endif
 
                 SDL_SendMouseMotion(data->window, 0, 0, xevent.xmotion.x, xevent.xmotion.y);
@@ -997,9 +999,13 @@ X11_DispatchEvent(_THIS)
 
     case ButtonPress:{
             int xticks = 0, yticks = 0;
+#ifdef DEBUG_XEVENTS
+            printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent.xbutton.button);
+#endif
             if (X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) {
                 SDL_SendMouseWheel(data->window, 0, xticks, yticks, SDL_MOUSEWHEEL_NORMAL);
             } else {
+                SDL_bool ignore_click = SDL_FALSE;
                 int button = xevent.xbutton.button;
                 if(button == Button1) {
                     if (ProcessHitTest(_this, data, &xevent)) {
@@ -1012,7 +1018,17 @@ X11_DispatchEvent(_THIS)
                        => subtract (8-SDL_BUTTON_X1) to get value SDL expects */
                     button -= (8-SDL_BUTTON_X1);
                 }
-                SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button);
+                if (data->last_focus_event_time) {
+                    const int X11_FOCUS_CLICK_TIMEOUT = 10;
+                    if (!SDL_TICKS_PASSED(SDL_GetTicks(), data->last_focus_event_time + X11_FOCUS_CLICK_TIMEOUT)) {
+                        const char *hint = SDL_GetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH);
+                        ignore_click = (!hint || *hint == '0');
+                    }
+                    data->last_focus_event_time = 0;
+                }
+                if (!ignore_click) {
+                    SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button);
+                }
             }
             X11_UpdateUserTime(data, xevent.xbutton.time);
         }
@@ -1022,7 +1038,10 @@ X11_DispatchEvent(_THIS)
             int button = xevent.xbutton.button;
             /* The X server sends a Release event for each Press for wheels. Ignore them. */
             int xticks = 0, yticks = 0;
-            if (!X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) {
+#ifdef DEBUG_XEVENTS
+            printf("window %p: ButtonRelease (X11 button = %d)\n", data, xevent.xbutton.button);
+#endif
+            if (!X11_IsWheelEvent(display, &xevent, &xticks, &yticks)) {
                 if (button > 7) {
                     /* see explanation at case ButtonPress */
                     button -= (8-SDL_BUTTON_X1);
diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h
index 3a3e894..5c5f7d5 100644
--- a/src/video/x11/SDL_x11window.h
+++ b/src/video/x11/SDL_x11window.h
@@ -60,6 +60,7 @@ typedef struct
     int border_right;
     int border_top;
     int border_bottom;
+    Uint32 last_focus_event_time;
     PendingFocusEnum pending_focus;
     Uint32 pending_focus_time;
     XConfigureEvent last_xconfigure;