rendered paste bodydiff --git a/plugins/plane.c b/plugins/plane.c
index 7c9a03c..2a7c7e6 100644
--- a/plugins/plane.c
+++ b/plugins/plane.c
@@ -364,38 +364,14 @@ static void
planeHandleEvent (CompDisplay *d,
XEvent *event)
{
+ Window activeWindow = d->activeWindow;
CompScreen *s;
PLANE_DISPLAY (d);
switch (event->type) {
case ClientMessage:
- if (event->xclient.message_type == d->winActiveAtom)
- {
- CompWindow *w;
-
- w = findWindowAtDisplay (d, event->xclient.window);
- if (w)
- {
- int dx, dy;
-
- s = w->screen;
-
- /* window must be placed */
- if (!w->placed)
- break;
-
- if (otherScreenGrabExist (s, "plane", "switcher", "cube", 0))
- break;
-
- defaultViewportForWindow (w, &dx, &dy);
- dx -= s->x;
- dy -= s->y;
-
- moveViewport (s, dx, dy);
- }
- }
- else if (event->xclient.message_type == d->desktopViewportAtom)
+ if (event->xclient.message_type == d->desktopViewportAtom)
{
int dx, dy;
@@ -423,6 +399,26 @@ planeHandleEvent (CompDisplay *d,
UNWRAP (pd, d, handleEvent);
(*d->handleEvent) (d, event);
WRAP (pd, d, handleEvent, planeHandleEvent);
+
+ if (activeWindow != d->activeWindow)
+ {
+ CompWindow *w;
+
+ w = findWindowAtDisplay (d, d->activeWindow);
+ if (w && w->placed &&
+ !otherScreenGrabExist (w->screen, "plane", "switcher", "cube", 0))
+ {
+ int dx, dy;
+
+ s = w->screen;
+
+ defaultViewportForWindow (w, &dx, &dy);
+ dx -= s->x;
+ dy -= s->y;
+
+ moveViewport (s, dx, dy);
+ }
+ }
}
static void
diff --git a/plugins/rotate.c b/plugins/rotate.c
index 05eb363..7b5ee20 100644
--- a/plugins/rotate.c
+++ b/plugins/rotate.c
@@ -1435,6 +1435,7 @@ rotateHandleEvent (CompDisplay *d,
XEvent *event)
{
CompScreen *s;
+ Window activeWindow = d->activeWindow;
ROTATE_DISPLAY (d);
@@ -1483,22 +1484,14 @@ rotateHandleEvent (CompDisplay *d,
}
break;
case ClientMessage:
- if (event->xclient.message_type == d->winActiveAtom)
+ if (event->xclient.message_type == d->desktopViewportAtom)
{
- CompWindow *w;
-
- w = findWindowAtDisplay (d, event->xclient.window);
- if (w)
+ s = findScreenAtDisplay (d, event->xclient.window);
+ if (s)
{
int dx;
- ROTATE_SCREEN (w->screen);
-
- s = w->screen;
-
- /* window must be placed */
- if (!w->placed)
- break;
+ ROTATE_SCREEN (s);
if (otherScreenGrabExist (s, "rotate", "switcher", "cube", 0))
break;
@@ -1506,8 +1499,7 @@ rotateHandleEvent (CompDisplay *d,
/* reset movement */
rs->moveTo = 0.0f;
- defaultViewportForWindow (w, &dx, NULL);
- dx -= s->x;
+ dx = event->xclient.data.l[0] / s->width - s->x;
if (dx)
{
Window win;
@@ -1543,64 +1535,68 @@ rotateHandleEvent (CompDisplay *d,
}
}
}
- else if (event->xclient.message_type == d->desktopViewportAtom)
+ default:
+ break;
+ }
+
+ UNWRAP (rd, d, handleEvent);
+ (*d->handleEvent) (d, event);
+ WRAP (rd, d, handleEvent, rotateHandleEvent);
+
+ if (activeWindow != d->activeWindow)
+ {
+ CompWindow *w;
+
+ w = findWindowAtDisplay (d, d->activeWindow);
+ if (w && w->placed &&
+ !otherScreenGrabExist (w->screen, "rotate", "switcher", "cube", 0))
{
- s = findScreenAtDisplay (d, event->xclient.window);
- if (s)
- {
- int dx;
+ int dx;
- ROTATE_SCREEN (s);
+ ROTATE_SCREEN (w->screen);
- if (otherScreenGrabExist (s, "rotate", "switcher", "cube", 0))
- break;
+ s = w->screen;
- /* reset movement */
- rs->moveTo = 0.0f;
+ /* reset movement */
+ rs->moveTo = 0.0f;
- dx = event->xclient.data.l[0] / s->width - s->x;
- if (dx)
- {
- Window win;
- int i, x, y;
- unsigned int ui;
- CompOption o[4];
+ defaultViewportForWindow (w, &dx, NULL);
+ dx -= s->x;
+ if (dx)
+ {
+ Window win;
+ int i, x, y;
+ unsigned int ui;
+ CompOption o[4];
- XQueryPointer (d->display, s->root,
- &win, &win, &x, &y, &i, &i, &ui);
+ XQueryPointer (d->display, s->root,
+ &win, &win, &x, &y, &i, &i, &ui);
- if (dx > (s->hsize + 1) / 2)
- dx -= s->hsize;
- else if (dx < -(s->hsize + 1) / 2)
- dx += s->hsize;
+ if (dx > (s->hsize + 1) / 2)
+ dx -= s->hsize;
+ else if (dx < -(s->hsize + 1) / 2)
+ dx += s->hsize;
- o[0].type = CompOptionTypeInt;
- o[0].name = "x";
- o[0].value.i = x;
+ o[0].type = CompOptionTypeInt;
+ o[0].name = "x";
+ o[0].value.i = x;
- o[1].type = CompOptionTypeInt;
- o[1].name = "y";
- o[1].value.i = y;
+ o[1].type = CompOptionTypeInt;
+ o[1].name = "y";
+ o[1].value.i = y;
- o[2].type = CompOptionTypeInt;
- o[2].name = "root";
- o[2].value.i = s->root;
+ o[2].type = CompOptionTypeInt;
+ o[2].name = "root";
+ o[2].value.i = s->root;
- o[3].type = CompOptionTypeInt;
- o[3].name = "direction";
- o[3].value.i = dx;
+ o[3].type = CompOptionTypeInt;
+ o[3].name = "direction";
+ o[3].value.i = dx;
- rotate (d, NULL, 0, o, 4);
- }
+ rotate (d, NULL, 0, o, 4);
}
}
- default:
- break;
}
-
- UNWRAP (rd, d, handleEvent);
- (*d->handleEvent) (d, event);
- WRAP (rd, d, handleEvent, rotateHandleEvent);
}
static void
diff --git a/src/window.c b/src/window.c
index b3c0edd..3943101 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4557,6 +4557,95 @@ setWindowUserTime (CompWindow *w,
(time2) != 0) \
)
+static Bool
+isWindowFocusAllowed (CompWindow *w,
+ Time timestamp)
+{
+ CompDisplay *d = w->screen->display;
+ CompScreen *s = w->screen;
+ CompWindow *active;
+ Time wUserTime, aUserTime;
+ CompMatch *match;
+ int vx, vy;
+
+ if (w->id == d->activeWindow)
+ return TRUE;
+
+ /* not in current viewport */
+ defaultViewportForWindow (w, &vx, &vy);
+ if (vx != s->x || vy != s->y)
+ return FALSE;
+
+ if (timestamp)
+ {
+ /* the caller passed a timestamp, so use that
+ instead of the window's user time */
+ wUserTime = timestamp;
+ }
+ else
+ {
+ if (!getWindowUserTime (w, &wUserTime))
+ {
+ /* no user time or initial timestamp */
+ if (!w->initialTimestampSet)
+ return TRUE;
+
+ wUserTime = w->initialTimestamp;
+ }
+
+ /* window explicitly requested no focus */
+ if (!wUserTime)
+ return FALSE;
+ }
+
+ /* can't get user time for active window */
+ active = findWindowAtDisplay (d, d->activeWindow);
+ if (!active || !getWindowUserTime (active, &aUserTime))
+ return TRUE;
+
+ match = &s->opt[COMP_SCREEN_OPTION_FOCUS_PREVENTION_MATCH].value.match;
+
+ /* focus prevention */
+ if (matchEval (match, w))
+ {
+ if (XSERVER_TIME_IS_BEFORE (wUserTime, aUserTime))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+allowWindowFocus (CompWindow *w,
+ unsigned int noFocusMask,
+ Time timestamp)
+{
+ Bool retval;
+
+ /* do not focus windows of these types */
+ if (w->type & noFocusMask)
+ return FALSE;
+
+ /* window doesn't take focus */
+ if (!w->inputHint && !(w->protocols & CompWindowProtocolTakeFocusMask))
+ return FALSE;
+
+ retval = isWindowFocusAllowed (w, timestamp);
+
+ if (!retval)
+ {
+ /* add demands attention state if focus was prevented */
+ unsigned int state = w->state;
+
+ state |= CompWindowStateDemandsAttentionMask;
+ if (state != w->state)
+ changeWindowState (w, state);
+ }
+
+ return FALSE;
+}
+
+
Bool
allowWindowFocus (CompWindow *w,
unsigned int noFocusMask,