From 67bdbcca445fe4dc9f6cdf197f77c1f40e8a9229 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 29 Sep 2016 16:05:29 -0700 Subject: [PATCH] Implemented SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH on X11 --- src/video/x11/SDL_x11events.c | 29 ++++++++++++++++++++++++----- src/video/x11/SDL_x11window.h | 1 + 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 8e585083a19df..51f2915b7836c 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 3a3e894ffb096..5c5f7d53690a9 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;