Fix pointer warp between screens.

In certain situations (pointer entering root on new screen)
the focus would not be properly set on the new screen.

SVN revision: 47768
This commit is contained in:
Kim Woelders 2010-04-05 17:48:37 +00:00
parent 7afd6cbe38
commit 25ea64b7b0
5 changed files with 54 additions and 18 deletions

View File

@ -521,13 +521,56 @@ FocusNewDesk(void)
XUngrabKeyboard(disp, CurrentTime);
}
void
FocusCheckScreen(void)
static void
_FocusScreenSendEvent(Window xwin, int x, int y, Time t, int enter)
{
if (EQueryPointer(NULL, NULL, NULL, NULL, NULL))
return; /* On screen */
XEvent xe;
FocusToEWin(NULL, FOCUS_DESK_LEAVE);
xe.type = (enter) ? EnterNotify : LeaveNotify;
xe.xcrossing.window = xwin;
xe.xcrossing.root = xwin;
xe.xcrossing.subwindow = 0;
xe.xcrossing.time = t;
xe.xcrossing.x = xe.xcrossing.x_root = x;
xe.xcrossing.y = xe.xcrossing.y_root = y;
xe.xcrossing.mode = NotifyNormal;
xe.xcrossing.detail = NotifyNonlinear;
xe.xcrossing.same_screen = (enter) ? True : False;
xe.xcrossing.focus = (enter) ? False : True;
xe.xcrossing.state = 0;
XSendEvent(disp, xwin, False, EnterWindowMask | LeaveWindowMask, &xe);
}
void
FocusScreen(int scr)
{
Window xwin;
Time t;
int x, y;
if (scr < 0 || scr >= ScreenCount(disp))
return;
/* IIRC warping to a different screen once did cause
* LeaveNotify's on the current root window. This does not
* happen in xorg 1.5.3 (and probably other versions).
* So, send LeaveNotify to current root and EnterNotify
* to new root. */
t = EGetTimestamp();
/* Report LeaveNotify on current root window */
xwin = WinGetXwin(VROOT);
EXQueryPointer(xwin, &x, &y, NULL, NULL);
_FocusScreenSendEvent(xwin, x, y, t, 0);
/* Do warp and report EnterNotify on new root window */
xwin = RootWindow(disp, scr);
x = DisplayWidth(disp, scr) / 2;
y = DisplayHeight(disp, scr) / 2;
EXWarpPointer(xwin, x, y);
_FocusScreenSendEvent(xwin, x, y, t, 1);
}
static void

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
* Copyright (C) 2004-2009 Kim Woelders
* Copyright (C) 2004-2010 Kim Woelders
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@ -49,7 +49,7 @@ void FocusHandleChange(EWin * ewin, XEvent * ev);
void FocusHandleClick(EWin * ewin, Win win);
void FocusNewDeskBegin(void);
void FocusNewDesk(void);
void FocusCheckScreen(void);
void FocusScreen(int scr);
void ClickGrabsUpdate(void);

View File

@ -1266,16 +1266,7 @@ IPC_Warp(const char *params)
{
x = (Dpy.screen + 1) % ScreenCount(disp);
sscanf(params, "%*s %i", &x);
if (x >= 0 && x < ScreenCount(disp))
{
EXWarpPointer(RootWindow(disp, x), DisplayWidth(disp, x) / 2,
DisplayHeight(disp, x) / 2);
/* IIRC warping to a different screen once did cause
* LeaveNotify's on the current root window. This does not
* happen in xorg 1.5.3 (and probably other versions).
* So, check and focus out if left. */
FocusCheckScreen();
}
FocusScreen(x);
}
else
{

View File

@ -1135,7 +1135,7 @@ EXWarpPointer(Window xwin, int x, int y)
XWarpPointer(disp, None, xwin, 0, 0, 0, 0, x, y);
}
static Bool
Bool
EXQueryPointer(Window xwin, int *px, int *py, Window * pchild,
unsigned int *pmask)
{

View File

@ -221,6 +221,8 @@ Pixmap EWindowGetShapePixmapInverted(Win win);
Bool EQueryPointer(Win win, int *px, int *py,
Window * pchild, unsigned int *pmask);
Bool EXQueryPointer(Window xwin, int *px, int *py,
Window * pchild, unsigned int *pmask);
unsigned int EAllocColor(Colormap cmap, unsigned int argb);