X11: Don't delay delivery of focus events unless we just changed vidmodes. Normally there's a 200 millisecond delay on all focus events in case there was a vidmode change, now we note the last vidmode change and only impose this delay if a change happened extremely recently. Thanks to Epic Games for reporting this issue.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c
index 645c774..c99b197 100644
--- a/src/video/x11/SDL_x11events.c
+++ b/src/video/x11/SDL_x11events.c
@@ -677,8 +677,17 @@ X11_DispatchEvent(_THIS)
data->window == SDL_GetKeyboardFocus()) {
ReconcileKeyboardState(_this, data);
}
- data->pending_focus = PENDING_FOCUS_IN;
- data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_IN_TIME;
+ if (!videodata->last_mode_change_deadline) /* no recent mode changes */
+ {
+ data->pending_focus = PENDING_FOCUS_NONE;
+ data->pending_focus_time = 0;
+ X11_DispatchFocusIn(data);
+ }
+ else
+ {
+ data->pending_focus = PENDING_FOCUS_IN;
+ data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME;
+ }
}
break;
@@ -701,8 +710,17 @@ X11_DispatchEvent(_THIS)
#ifdef DEBUG_XEVENTS
printf("window %p: FocusOut!\n", data);
#endif
- data->pending_focus = PENDING_FOCUS_OUT;
- data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_OUT_TIME;
+ if (!videodata->last_mode_change_deadline) /* no recent mode changes */
+ {
+ data->pending_focus = PENDING_FOCUS_NONE;
+ data->pending_focus_time = 0;
+ X11_DispatchFocusOut(data);
+ }
+ else
+ {
+ data->pending_focus = PENDING_FOCUS_OUT;
+ data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME;
+ }
}
break;
@@ -1283,9 +1301,15 @@ X11_PumpEvents(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+ if (data->last_mode_change_deadline) {
+ if (SDL_TICKS_PASSED(SDL_GetTicks(), data->last_mode_change_deadline)) {
+ data->last_mode_change_deadline = 0; /* assume we're done. */
+ }
+ }
+
/* Update activity every 30 seconds to prevent screensaver */
if (_this->suspend_screensaver) {
- Uint32 now = SDL_GetTicks();
+ const Uint32 now = SDL_GetTicks();
if (!data->screensaver_activity ||
SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) {
X11_XResetScreenSaver(data->display);
diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c
index 0fc6d23..5248f76 100644
--- a/src/video/x11/SDL_x11modes.c
+++ b/src/video/x11/SDL_x11modes.c
@@ -24,6 +24,7 @@
#include "SDL_hints.h"
#include "SDL_x11video.h"
+#include "SDL_timer.h"
#include "edid.h"
/* #define X11MODES_DEBUG */
@@ -813,10 +814,13 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display)
int
X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode)
{
- Display *display = ((SDL_VideoData *) _this->driverdata)->display;
+ SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
+ Display *display = viddata->display;
SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
+ viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2);
+
#if SDL_VIDEO_DRIVER_X11_XRANDR
if (data->use_xrandr) {
XRRScreenResources *res;
diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h
index f076cce..ed6b14f 100644
--- a/src/video/x11/SDL_x11video.h
+++ b/src/video/x11/SDL_x11video.h
@@ -112,6 +112,7 @@ typedef struct SDL_VideoData
SDL_Scancode key_layout[256];
SDL_bool selection_waiting;
+ Uint32 last_mode_change_deadline;
} SDL_VideoData;
extern SDL_bool X11_UseDirectColorVisuals(void);
diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h
index 789d2f7..ce3f584 100644
--- a/src/video/x11/SDL_x11window.h
+++ b/src/video/x11/SDL_x11window.h
@@ -27,8 +27,7 @@
video mode changes and we can respond to them by triggering more mode
changes.
*/
-#define PENDING_FOCUS_IN_TIME 200
-#define PENDING_FOCUS_OUT_TIME 200
+#define PENDING_FOCUS_TIME 200
#if SDL_VIDEO_OPENGL_EGL
#include <EGL/egl.h>