Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
We need to queue the focus in/out changes because they may occur duri…
Browse files Browse the repository at this point in the history
…ng video mode changes and we can respond to them by triggering more mode changes.
  • Loading branch information
slouken committed Sep 28, 2012
1 parent c3872b6 commit 5ea5ff4
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 29 deletions.
106 changes: 77 additions & 29 deletions src/video/x11/SDL_x11events.c
Expand Up @@ -28,6 +28,7 @@
#include <unistd.h>
#include <limits.h> /* For INT_MAX */

#include "SDL_x11video.h"
#include "SDL_x11video.h"
#include "SDL_x11touch.h"
#include "SDL_x11xinput2.h"
Expand Down Expand Up @@ -109,6 +110,34 @@ static void X11_HandleGenericEvent(SDL_VideoData *videodata,XEvent event)
#endif /* SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */


static void
X11_DispatchFocusIn(SDL_WindowData *data)
{
#ifdef DEBUG_XEVENTS
printf("window %p: Dispatching FocusIn\n", data);
#endif
SDL_SetKeyboardFocus(data->window);
#ifdef X_HAVE_UTF8_STRING
if (data->ic) {
XSetICFocus(data->ic);
}
#endif
}

static void
X11_DispatchFocusOut(SDL_WindowData *data)
{
#ifdef DEBUG_XEVENTS
printf("window %p: Dispatching FocusOut\n", data);
#endif
SDL_SetKeyboardFocus(NULL);
#ifdef X_HAVE_UTF8_STRING
if (data->ic) {
XUnsetICFocus(data->ic);
}
#endif
}

static void
X11_DispatchMapNotify(SDL_WindowData *data)
{
Expand Down Expand Up @@ -186,7 +215,7 @@ X11_DispatchEvent(_THIS)
/* Gaining mouse coverage? */
case EnterNotify:{
#ifdef DEBUG_XEVENTS
printf("EnterNotify! (%d,%d,%d)\n",
printf("window %p: EnterNotify! (%d,%d,%d)\n", data,
xevent.xcrossing.x,
xevent.xcrossing.y,
xevent.xcrossing.mode);
Expand All @@ -201,7 +230,7 @@ X11_DispatchEvent(_THIS)
/* Losing mouse coverage? */
case LeaveNotify:{
#ifdef DEBUG_XEVENTS
printf("LeaveNotify! (%d,%d,%d)\n",
printf("window %p: LeaveNotify! (%d,%d,%d)\n", data,
xevent.xcrossing.x,
xevent.xcrossing.y,
xevent.xcrossing.mode);
Expand All @@ -221,35 +250,27 @@ X11_DispatchEvent(_THIS)
/* Gaining input focus? */
case FocusIn:{
#ifdef DEBUG_XEVENTS
printf("FocusIn!\n");
#endif
SDL_SetKeyboardFocus(data->window);
#ifdef X_HAVE_UTF8_STRING
if (data->ic) {
XSetICFocus(data->ic);
}
printf("window %p: FocusIn!\n", data);
#endif
data->pending_focus = PENDING_FOCUS_IN;
data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_IN_TIME;
}
break;

/* Losing input focus? */
case FocusOut:{
#ifdef DEBUG_XEVENTS
printf("FocusOut!\n");
#endif
SDL_SetKeyboardFocus(NULL);
#ifdef X_HAVE_UTF8_STRING
if (data->ic) {
XUnsetICFocus(data->ic);
}
printf("window %p: FocusOut!\n", data);
#endif
data->pending_focus = PENDING_FOCUS_OUT;
data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_OUT_TIME;
}
break;

/* Generated upon EnterWindow and FocusIn */
case KeymapNotify:{
#ifdef DEBUG_XEVENTS
printf("KeymapNotify!\n");
printf("window %p: KeymapNotify!\n", data);
#endif
/* FIXME:
X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector);
Expand All @@ -260,7 +281,7 @@ X11_DispatchEvent(_THIS)
/* Has the keyboard layout changed? */
case MappingNotify:{
#ifdef DEBUG_XEVENTS
printf("MappingNotify!\n");
printf("window %p: MappingNotify!\n", data);
#endif
X11_UpdateKeymap(_this);
}
Expand All @@ -274,7 +295,7 @@ X11_DispatchEvent(_THIS)
Status status = 0;

#ifdef DEBUG_XEVENTS
printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode);
#endif
SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
#if 1
Expand Down Expand Up @@ -313,7 +334,7 @@ X11_DispatchEvent(_THIS)
KeyCode keycode = xevent.xkey.keycode;

#ifdef DEBUG_XEVENTS
printf("KeyRelease (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent.xkey.keycode);
#endif
if (X11_KeyRepeat(display, &xevent)) {
/* We're about to get a repeated key down, ignore the key up */
Expand All @@ -326,7 +347,7 @@ X11_DispatchEvent(_THIS)
/* Have we been iconified? */
case UnmapNotify:{
#ifdef DEBUG_XEVENTS
printf("UnmapNotify!\n");
printf("window %p: UnmapNotify!\n", data);
#endif
X11_DispatchUnmapNotify(data);
}
Expand All @@ -335,7 +356,7 @@ X11_DispatchEvent(_THIS)
/* Have we been restored? */
case MapNotify:{
#ifdef DEBUG_XEVENTS
printf("MapNotify!\n");
printf("window %p: MapNotify!\n", data);
#endif
X11_DispatchMapNotify(data);
}
Expand All @@ -344,7 +365,7 @@ X11_DispatchEvent(_THIS)
/* Have we been resized or moved? */
case ConfigureNotify:{
#ifdef DEBUG_XEVENTS
printf("ConfigureNotify! (resize: %dx%d)\n",
printf("window %p: ConfigureNotify! (resize: %dx%d)\n", data,
xevent.xconfigure.width, xevent.xconfigure.height);
#endif
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED,
Expand All @@ -368,7 +389,7 @@ X11_DispatchEvent(_THIS)
/* Do we need to refresh ourselves? */
case Expose:{
#ifdef DEBUG_XEVENTS
printf("Expose (count = %d)\n", xevent.xexpose.count);
printf("window %p: Expose (count = %d)\n", data, xevent.xexpose.count);
#endif
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
}
Expand All @@ -378,7 +399,7 @@ X11_DispatchEvent(_THIS)
SDL_Mouse *mouse = SDL_GetMouse();
if(!mouse->relative_mode) {
#ifdef DEBUG_MOTION
printf("X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y);
printf("window %p: X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y);
#endif

SDL_SendMouseMotion(data->window, 0, xevent.xmotion.x, xevent.xmotion.y);
Expand Down Expand Up @@ -411,7 +432,7 @@ X11_DispatchEvent(_THIS)

char *name = XGetAtomName(display, xevent.xproperty.atom);
if (name) {
printf("PropertyNotify: %s %s\n", name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed");
printf("window %p: PropertyNotify: %s %s\n", data, name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed");
XFree(name);
}

Expand Down Expand Up @@ -508,7 +529,7 @@ X11_DispatchEvent(_THIS)

req = &xevent.xselectionrequest;
#ifdef DEBUG_XEVENTS
printf("SelectionRequest (requestor = %ld, target = %ld)\n",
printf("window %p: SelectionRequest (requestor = %ld, target = %ld)\n", data,
req->requestor, req->target);
#endif

Expand Down Expand Up @@ -538,7 +559,7 @@ X11_DispatchEvent(_THIS)

case SelectionNotify: {
#ifdef DEBUG_XEVENTS
printf("SelectionNotify (requestor = %ld, target = %ld)\n",
printf("window %p: SelectionNotify (requestor = %ld, target = %ld)\n", data,
xevent.xselection.requestor, xevent.xselection.target);
#endif
videodata->selection_waiting = SDL_FALSE;
Expand All @@ -547,13 +568,36 @@ X11_DispatchEvent(_THIS)

default:{
#ifdef DEBUG_XEVENTS
printf("Unhandled event %d\n", xevent.type);
printf("window %p: Unhandled event %d\n", data, xevent.type);
#endif
}
break;
}
}

static void
X11_HandleFocusChanges(_THIS)
{
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
int i;

if (videodata && videodata->windowlist) {
for (i = 0; i < videodata->numwindows; ++i) {
SDL_WindowData *data = videodata->windowlist[i];
if (data && data->pending_focus != PENDING_FOCUS_NONE) {
Uint32 now = SDL_GetTicks();
if ( (int)(data->pending_focus_time-now) <= 0 ) {
if ( data->pending_focus == PENDING_FOCUS_IN ) {
X11_DispatchFocusIn(data);
} else {
X11_DispatchFocusOut(data);
}
data->pending_focus = PENDING_FOCUS_NONE;
}
}
}
}
}
/* Ack! XPending() actually performs a blocking read if no events available */
static int
X11_Pending(Display * display)
Expand Down Expand Up @@ -606,6 +650,10 @@ X11_PumpEvents(_THIS)
while (X11_Pending(data->display)) {
X11_DispatchEvent(_this);
}

/* FIXME: Only need to do this when there are pending focus changes */
X11_HandleFocusChanges(_this);

/*Dont process evtouch events if XInput2 multitouch is supported*/
if(X11_Xinput2IsMultitouchSupported()) {
return;
Expand Down
16 changes: 16 additions & 0 deletions src/video/x11/SDL_x11window.h
Expand Up @@ -23,6 +23,20 @@
#ifndef _SDL_x11window_h
#define _SDL_x11window_h

/* We need to queue the focus in/out changes because they may occur during
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

typedef enum
{
PENDING_FOCUS_NONE,
PENDING_FOCUS_IN,
PENDING_FOCUS_OUT
} PendingFocusEnum;

typedef struct
{
SDL_Window *window;
Expand All @@ -39,6 +53,8 @@ typedef struct
GC gc;
XIC ic;
SDL_bool created;
PendingFocusEnum pending_focus;
Uint32 pending_focus_time;
struct SDL_VideoData *videodata;
} SDL_WindowData;

Expand Down

0 comments on commit 5ea5ff4

Please sign in to comment.