X11: Don't delay delivery of focus events unless we just changed vidmodes.
authorRyan C. Gordon <icculus@icculus.org>
Mon, 26 Jan 2015 17:46:39 -0500
changeset 9319 ad4f430cc9f5
parent 9318 3ad27ca380f3
child 9320 38f5bcc808a9
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.
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11modes.c
src/video/x11/SDL_x11video.h
src/video/x11/SDL_x11window.h
--- a/src/video/x11/SDL_x11events.c	Mon Jan 26 22:27:27 2015 +0100
+++ b/src/video/x11/SDL_x11events.c	Mon Jan 26 17:46:39 2015 -0500
@@ -677,8 +677,17 @@
                 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 @@
 #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 @@
 {
     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);
--- a/src/video/x11/SDL_x11modes.c	Mon Jan 26 22:27:27 2015 +0100
+++ b/src/video/x11/SDL_x11modes.c	Mon Jan 26 17:46:39 2015 -0500
@@ -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 @@
 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;
--- a/src/video/x11/SDL_x11video.h	Mon Jan 26 22:27:27 2015 +0100
+++ b/src/video/x11/SDL_x11video.h	Mon Jan 26 17:46:39 2015 -0500
@@ -112,6 +112,7 @@
     SDL_Scancode key_layout[256];
     SDL_bool selection_waiting;
 
+    Uint32 last_mode_change_deadline;
 } SDL_VideoData;
 
 extern SDL_bool X11_UseDirectColorVisuals(void);
--- a/src/video/x11/SDL_x11window.h	Mon Jan 26 22:27:27 2015 +0100
+++ b/src/video/x11/SDL_x11window.h	Mon Jan 26 17:46:39 2015 -0500
@@ -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>