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 9319ad4f430cc9f5
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
     1.1 --- a/src/video/x11/SDL_x11events.c	Mon Jan 26 22:27:27 2015 +0100
     1.2 +++ b/src/video/x11/SDL_x11events.c	Mon Jan 26 17:46:39 2015 -0500
     1.3 @@ -677,8 +677,17 @@
     1.4                  data->window == SDL_GetKeyboardFocus()) {
     1.5                  ReconcileKeyboardState(_this, data);
     1.6              }
     1.7 -            data->pending_focus = PENDING_FOCUS_IN;
     1.8 -            data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_IN_TIME;
     1.9 +            if (!videodata->last_mode_change_deadline) /* no recent mode changes */
    1.10 +            {
    1.11 +                data->pending_focus = PENDING_FOCUS_NONE;
    1.12 +                data->pending_focus_time = 0;
    1.13 +                X11_DispatchFocusIn(data);
    1.14 +            }
    1.15 +            else
    1.16 +            {
    1.17 +                data->pending_focus = PENDING_FOCUS_IN;
    1.18 +                data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME;
    1.19 +            }
    1.20          }
    1.21          break;
    1.22  
    1.23 @@ -701,8 +710,17 @@
    1.24  #ifdef DEBUG_XEVENTS
    1.25              printf("window %p: FocusOut!\n", data);
    1.26  #endif
    1.27 -            data->pending_focus = PENDING_FOCUS_OUT;
    1.28 -            data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_OUT_TIME;
    1.29 +            if (!videodata->last_mode_change_deadline) /* no recent mode changes */
    1.30 +            {
    1.31 +                data->pending_focus = PENDING_FOCUS_NONE;
    1.32 +                data->pending_focus_time = 0;
    1.33 +                X11_DispatchFocusOut(data);
    1.34 +            }
    1.35 +            else
    1.36 +            {
    1.37 +                data->pending_focus = PENDING_FOCUS_OUT;
    1.38 +                data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME;
    1.39 +            }
    1.40          }
    1.41          break;
    1.42  
    1.43 @@ -1283,9 +1301,15 @@
    1.44  {
    1.45      SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    1.46  
    1.47 +    if (data->last_mode_change_deadline) {
    1.48 +        if (SDL_TICKS_PASSED(SDL_GetTicks(), data->last_mode_change_deadline)) {
    1.49 +            data->last_mode_change_deadline = 0;  /* assume we're done. */
    1.50 +        }
    1.51 +    }
    1.52 +
    1.53      /* Update activity every 30 seconds to prevent screensaver */
    1.54      if (_this->suspend_screensaver) {
    1.55 -        Uint32 now = SDL_GetTicks();
    1.56 +        const Uint32 now = SDL_GetTicks();
    1.57          if (!data->screensaver_activity ||
    1.58              SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) {
    1.59              X11_XResetScreenSaver(data->display);
     2.1 --- a/src/video/x11/SDL_x11modes.c	Mon Jan 26 22:27:27 2015 +0100
     2.2 +++ b/src/video/x11/SDL_x11modes.c	Mon Jan 26 17:46:39 2015 -0500
     2.3 @@ -24,6 +24,7 @@
     2.4  
     2.5  #include "SDL_hints.h"
     2.6  #include "SDL_x11video.h"
     2.7 +#include "SDL_timer.h"
     2.8  #include "edid.h"
     2.9  
    2.10  /* #define X11MODES_DEBUG */
    2.11 @@ -813,10 +814,13 @@
    2.12  int
    2.13  X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode)
    2.14  {
    2.15 -    Display *display = ((SDL_VideoData *) _this->driverdata)->display;
    2.16 +    SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
    2.17 +    Display *display = viddata->display;
    2.18      SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
    2.19      SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
    2.20  
    2.21 +    viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2);
    2.22 +
    2.23  #if SDL_VIDEO_DRIVER_X11_XRANDR
    2.24      if (data->use_xrandr) {
    2.25          XRRScreenResources *res;
     3.1 --- a/src/video/x11/SDL_x11video.h	Mon Jan 26 22:27:27 2015 +0100
     3.2 +++ b/src/video/x11/SDL_x11video.h	Mon Jan 26 17:46:39 2015 -0500
     3.3 @@ -112,6 +112,7 @@
     3.4      SDL_Scancode key_layout[256];
     3.5      SDL_bool selection_waiting;
     3.6  
     3.7 +    Uint32 last_mode_change_deadline;
     3.8  } SDL_VideoData;
     3.9  
    3.10  extern SDL_bool X11_UseDirectColorVisuals(void);
     4.1 --- a/src/video/x11/SDL_x11window.h	Mon Jan 26 22:27:27 2015 +0100
     4.2 +++ b/src/video/x11/SDL_x11window.h	Mon Jan 26 17:46:39 2015 -0500
     4.3 @@ -27,8 +27,7 @@
     4.4     video mode changes and we can respond to them by triggering more mode
     4.5     changes.
     4.6  */
     4.7 -#define PENDING_FOCUS_IN_TIME   200
     4.8 -#define PENDING_FOCUS_OUT_TIME  200
     4.9 +#define PENDING_FOCUS_TIME   200
    4.10  
    4.11  #if SDL_VIDEO_OPENGL_EGL   
    4.12  #include <EGL/egl.h>