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.
This commit is contained in:
parent
b40f346c7e
commit
2c196568a8
2 changed files with 93 additions and 29 deletions
|
@ -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"
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue