Skip to content

Commit

Permalink
X11: Don't delay delivery of focus events unless we just changed vidm…
Browse files Browse the repository at this point in the history
…odes.

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.
  • Loading branch information
icculus committed Jan 26, 2015
1 parent 34a5c70 commit 203ea98
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 8 deletions.
34 changes: 29 additions & 5 deletions src/video/x11/SDL_x11events.c
Expand Up @@ -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;

Expand All @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
6 changes: 5 additions & 1 deletion src/video/x11/SDL_x11modes.c
Expand Up @@ -24,6 +24,7 @@

#include "SDL_hints.h"
#include "SDL_x11video.h"
#include "SDL_timer.h"
#include "edid.h"

/* #define X11MODES_DEBUG */
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/video/x11/SDL_x11video.h
Expand Up @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions src/video/x11/SDL_x11window.h
Expand Up @@ -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>
Expand Down

0 comments on commit 203ea98

Please sign in to comment.