All pastes #742422 Raw Edit

Meins

public text v1 · immutable
#742422 ·published 2007-10-19 14:41 UTC
rendered paste body
diff --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,