From 203ea9817360815352a8fe471c3864bc51efb411 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 26 Jan 2015 17:46:39 -0500 Subject: [PATCH] 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 | 34 +++++++++++++++++++++++++++++----- src/video/x11/SDL_x11modes.c | 6 +++++- src/video/x11/SDL_x11video.h | 1 + src/video/x11/SDL_x11window.h | 3 +-- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 645c7741d3d13..c99b1971b371a 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 0fc6d23862557..5248f7655bfd7 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 f076ccec18427..ed6b14fa400d1 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 789d2f7cc0248..ce3f58439ba7f 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