[fusion-commits] Compiz mirror: Changes to 'master' (73cdcba0a8054b5cc9308dd58b5ebee1bf44378c)

compiz at server.opencompositing.org compiz at server.opencompositing.org
Sun Mar 16 13:30:05 CET 2008


New commits:
commit 73cdcba0a8054b5cc9308dd58b5ebee1bf44378c
Merge: d9023254f8eaa2a3c974dda50f23258766595daa bcf10582274d9b4cfe474735532eec0f83cc0ea7
Author: Danny Baumann <dannybaumann at web.de>
Date:   Sun Mar 16 12:51:25 2008 +0100

    Merge branch 'master' of git+ssh://maniac@git.freedesktop.org/git/xorg/app/compiz

commit d9023254f8eaa2a3c974dda50f23258766595daa
Author: Danny Baumann <dannybaumann at web.de>
Date:   Sun Mar 16 12:31:44 2008 +0100

    Use passed geometry for constraining min/max size rather than server geometry.
    The passed geometry might be different to the server geometry, so don't override the changes.

commit 871aa2d72293a6c2d1283590dde96bbe55494e4e
Author: Danny Baumann <dannybaumann at web.de>
Date:   Sat Mar 15 18:15:49 2008 +0100

    Improve comment and variable name.

commit eab55dc460cabf0d938a7798f893a41683038670
Author: Danny Baumann <dannybaumann at web.de>
Date:   Sat Mar 15 14:48:45 2008 +0100

    Also set w->managed on MapNotify event.
    When not doing that, w->managed can be wrongly set to FALSE on a mapped, non-override_redirect window if a client maps its window and unmaps it right after that.
    Scenario:
    - client calls XMapWindow and XUnmapWindow
    - we get MapRequest, set w->managed to true and map the window by calling XMapWindow
    - we get UnmapNotify (for client unmap) and set w->managed to false
    - we get MapNotify (for our map call) and don't set w->managed to true

commit a3753157b10eb4da5ff172e148cbd11c8ebd2284
Author: Danny Baumann <dannybaumann at web.de>
Date:   Sat Mar 15 14:48:35 2008 +0100

    Bump ABIVERSION.

commit e0e6a7f36aa23932391ac727b83670fad4b37f68
Author: Danny Baumann <dannybaumann at web.de>
Date:   Sat Mar 15 14:47:25 2008 +0100

    Add nodelay hint to flip edges.

commit 6b7c4054eba499bf0ce94152637ab5875f2781a5
Author: Danny Baumann <dannybaumann at web.de>
Date:   Mon Feb 25 09:23:10 2008 +0100

    Also use screen edge delays for DnD actions.

commit 410814ebb599bb31dff17e9ed7871a870b940ef7
Author: Danny Baumann <dannybaumann at web.de>
Date:   Sat Mar 15 14:45:40 2008 +0100

    Added screen edge trigger delay settings.
     Plugins intending to prevent edge delays should add the metadata hint <nodelay> to their edge options.

commit 57410ff2b2784d812b597b93aa6a0d6a06e8bcec
Author: Danny Baumann <dannybaumann at web.de>
Date:   Sat Mar 15 14:40:20 2008 +0100

    Add option for selecting the amount of focus stealing prevention.

commit b6194e28fa155d15ee9a9135db13a20f11d0b151
Author: Danny Baumann <dannybaumann at web.de>
Date:   Sat Mar 15 14:33:30 2008 +0100

    The largedesktop plugins are responsible for switching viewports when a window is activated.

commit 67bc2cd6e4b00439d865493f4e46b1c2c608be77
Author: Danny Baumann <dannybaumann at web.de>
Date:   Wed Mar 12 00:03:27 2008 +0100

    Switch viewports on window activation, not on focus change.

commit 7ad6926d9f03dd146cdf0bfac1e29ec52d2e320c
Author: Danny Baumann <dannybaumann at web.de>
Date:   Sat Mar 15 14:32:24 2008 +0100

    Make activateWindow function wrappable so plugins can react on window activation.


 include/compiz-core.h  |   39 ++++++++++--
 metadata/core.xml.in   |   30 +++++++++
 metadata/rotate.xml.in |    2 +
 plugins/plane.c        |   38 ++++++-----
 plugins/rotate.c       |   89 ++++++++++++++-------------
 plugins/scale.c        |   40 +------------
 src/display.c          |    5 +-
 src/event.c            |  158 +++++++++++++++++++++++++++++++++++++++++-------
 src/metadata.c         |   28 +++++++--
 src/screen.c           |    3 +
 src/window.c           |   72 ++++++++++++++--------
 11 files changed, 342 insertions(+), 162 deletions(-)


Modified: compiz/include/compiz-core.h
===================================================================
--- compiz/include/compiz-core.h
+++ compiz/include/compiz-core.h
@@ -28,7 +28,7 @@
 
 #include <compiz-plugin.h>
 
-#define CORE_ABIVERSION 20080314
+#define CORE_ABIVERSION 20080315
 
 #include <stdio.h>
 #include <sys/time.h>
@@ -399,7 +399,8 @@ typedef enum {
     CompActionStateTermEdgeDnd = 1 <<  8,
     CompActionStateCommit      = 1 <<  9,
     CompActionStateCancel      = 1 << 10,
-    CompActionStateAutoGrab    = 1 << 11
+    CompActionStateAutoGrab    = 1 << 11,
+    CompActionStateNoEdgeDelay = 1 << 12
 } CompActionState;
 
 typedef enum {
@@ -797,7 +798,8 @@ removeFileWatch (CompFileWatchHandle handle);
 #define COMP_DISPLAY_OPTION_TERMINAL			     64
 #define COMP_DISPLAY_OPTION_RUN_TERMINAL_KEY		     65
 #define COMP_DISPLAY_OPTION_PING_DELAY			     66
-#define COMP_DISPLAY_OPTION_NUM				     67
+#define COMP_DISPLAY_OPTION_EDGE_DELAY                       67
+#define COMP_DISPLAY_OPTION_NUM				     68
 
 typedef void (*HandleEventProc) (CompDisplay *display,
 				 XEvent	     *event);
@@ -1072,6 +1074,8 @@ struct _CompDisplay {
     CompTimeoutHandle autoRaiseHandle;
     Window	      autoRaiseWindow;
 
+    CompTimeoutHandle edgeDelayHandle;
+
     CompOptionValue plugin;
     Bool	    dirtyPluginList;
 
@@ -1253,6 +1257,17 @@ findCursorAtDisplay (CompDisplay *display);
 
 /* event.c */
 
+typedef struct _CompDelayedEdgeSettings
+{
+    CompDisplay *d;
+
+    unsigned int edge;
+    unsigned int state;
+
+    CompOption   option[7];
+    unsigned int nOption;
+} CompDelayedEdgeSettings;
+
 void
 handleEvent (CompDisplay *display,
 	     XEvent      *event);
@@ -1707,10 +1722,11 @@ disableTexture (CompScreen  *screen,
 #define COMP_SCREEN_OPTION_DETECT_OUTPUTS	  10
 #define COMP_SCREEN_OPTION_OUTPUTS		  11
 #define COMP_SCREEN_OPTION_OVERLAPPING_OUTPUTS	  12
-#define COMP_SCREEN_OPTION_FOCUS_PREVENTION_MATCH 13
-#define COMP_SCREEN_OPTION_OPACITY_MATCHES	  14
-#define COMP_SCREEN_OPTION_OPACITY_VALUES	  15
-#define COMP_SCREEN_OPTION_NUM		          16
+#define COMP_SCREEN_OPTION_FOCUS_PREVENTION_LEVEL 13
+#define COMP_SCREEN_OPTION_FOCUS_PREVENTION_MATCH 14
+#define COMP_SCREEN_OPTION_OPACITY_MATCHES	  15
+#define COMP_SCREEN_OPTION_OPACITY_VALUES	  16
+#define COMP_SCREEN_OPTION_NUM		          17
 
 #ifndef GLX_EXT_texture_from_pixmap
 #define GLX_BIND_TO_TEXTURE_RGB_EXT        0x20D0
@@ -1738,6 +1754,12 @@ disableTexture (CompScreen  *screen,
 #define OUTPUT_OVERLAP_MODE_PREFER_SMALLER 2
 #define OUTPUT_OVERLAP_MODE_LAST           OUTPUT_OVERLAP_MODE_PREFER_SMALLER
 
+#define FOCUS_PREVENTION_LEVEL_NONE     0
+#define FOCUS_PREVENTION_LEVEL_LOW      1
+#define FOCUS_PREVENTION_LEVEL_HIGH     2
+#define FOCUS_PREVENTION_LEVEL_VERYHIGH 3
+#define FOCUS_PREVENTION_LEVEL_LAST     FOCUS_PREVENTION_LEVEL_VERYHIGH
+
 typedef void (*FuncPtr) (void);
 typedef FuncPtr (*GLXGetProcAddressProc) (const GLubyte *procName);
 
@@ -1843,6 +1865,8 @@ typedef void (*GetAllowedActionsForWindowProc) (CompWindow   *w,
 
 typedef Bool (*FocusWindowProc) (CompWindow *window);
 
+typedef void (*ActivateWindowProc) (CompWindow *window);
+
 typedef Bool (*PlaceWindowProc) (CompWindow *window,
 				 int        x,
 				 int        y,
@@ -2180,6 +2204,7 @@ struct _CompScreen {
     GetOutputExtentsForWindowProc   getOutputExtentsForWindow;
     GetAllowedActionsForWindowProc  getAllowedActionsForWindow;
     FocusWindowProc		    focusWindow;
+    ActivateWindowProc              activateWindow;
     PlaceWindowProc                 placeWindow;
     ValidateWindowResizeRequestProc validateWindowResizeRequest;
 

Modified: compiz/metadata/core.xml.in
===================================================================
--- compiz/metadata/core.xml.in
+++ compiz/metadata/core.xml.in
@@ -48,6 +48,13 @@
 		<min>0</min>
 		<max>10000</max>
 	    </option>
+	    <option name="edge_delay" type="int">
+		<_short>Edge Trigger Delay</_short>
+		<_long>Duration the pointer must rest in a screen edge before an edge action is taken.</_long>
+		<default>0</default>
+		<min>0</min>
+		<max>10000</max>
+	    </option>
 	    <option name="close_window_key" type="key">
 		<_short>Close Window</_short>
 		<_long>Close active window</_long>
@@ -425,6 +432,29 @@
 		    <_name>Prefer smaller output</_name>
 		</desc>
 	    </option>
+	    <option name="focus_prevention_level" type="int">
+		<_short>Focus Prevention Level</_short>
+		<_long>Level of focus stealing prevention</_long>
+		<min>0</min>
+		<max>3</max>
+		<default>1</default>
+		<desc>
+		    <value>0</value>
+		    <_name>Off</_name>
+		</desc>
+		<desc>
+		    <value>1</value>
+		    <_name>Low</_name>
+		</desc>
+		<desc>
+		    <value>2</value>
+		    <_name>High</_name>
+		</desc>
+		<desc>
+		    <value>3</value>
+		    <_name>Very High</_name>
+		</desc>
+	    </option>
 	    <option name="focus_prevention_match" type="match">
 		<_short>Focus Prevention Windows</_short>
 		<_long>Focus prevention windows</_long>

Modified: compiz/metadata/rotate.xml.in
===================================================================
--- compiz/metadata/rotate.xml.in
+++ compiz/metadata/rotate.xml.in
@@ -181,6 +181,7 @@
 	    <option name="rotate_flip_left_edge" type="edge">
 		<_short>Rotate Flip Left</_short>
 		<_long>Flip to left viewport and warp pointer</_long>
+		<nodelay>true</nodelay>
 		<default>
 		  <edge name="Left"/>
 		</default>
@@ -188,6 +189,7 @@
 	    <option name="rotate_flip_right_edge" type="edge">
 		<_short>Rotate Flip Right</_short>
 		<_long>Flip to right viewport and warp pointer</_long>
+		<nodelay>true</nodelay>
 		<default>
 		  <edge name="Right"/>
 		</default>

Modified: compiz/plugins/plane.c
===================================================================
--- compiz/plugins/plane.c
+++ compiz/plugins/plane.c
@@ -71,6 +71,7 @@ typedef struct _PlaneScreen {
     PreparePaintScreenProc		preparePaintScreen;
     DonePaintScreenProc			donePaintScreen;
     PaintOutputProc			paintOutput;
+    ActivateWindowProc                  activateWindow;
 
     CompTimeoutHandle			timeoutHandle;
     int					timer;
@@ -358,7 +359,6 @@ planeHandleEvent (CompDisplay *d,
 		  XEvent      *event)
 {
     CompScreen *s;
-    Window     activeWindow = d->activeWindow;
 
     PLANE_DISPLAY (d);
 
@@ -392,28 +392,30 @@ planeHandleEvent (CompDisplay *d,
     UNWRAP (pd, d, handleEvent);
     (*d->handleEvent) (d, event);
     WRAP (pd, d, handleEvent, planeHandleEvent);
+}
 
-    if (activeWindow != d->activeWindow)
-    {
-	CompWindow *w;
+static void
+planeActivateWindow (CompWindow *w)
+{
+    CompScreen *s = w->screen;
 
-	w = findWindowAtDisplay (d, d->activeWindow);
-	if (w && w->placed)
-	{
-	    s = w->screen;
+    PLANE_SCREEN (s);
 
-	    if (!otherScreenGrabExist (s, "plane", "switcher", "cube", 0))
-	    {
-		int dx, dy;
+    if (w->placed &&
+	!otherScreenGrabExist (s, "plane", "switcher", "cube", 0))
+    {
+	int dx, dy;
 
-		defaultViewportForWindow (w, &dx, &dy);
-		dx -= s->x;
-		dy -= s->y;
+	defaultViewportForWindow (w, &dx, &dy);
+	dx -= s->x;
+	dy -= s->y;
 
-		moveViewport (s, dx, dy);
-	    }
-	}
+	moveViewport (s, dx, dy);
     }
+
+    UNWRAP (ps, s, activateWindow);
+    (*s->activateWindow) (w);
+    WRAP (ps, s, activateWindow, planeActivateWindow);
 }
 
 static CompOption *
@@ -634,6 +636,7 @@ planeInitScreen (CompPlugin *p,
     WRAP (ps, s, preparePaintScreen, planePreparePaintScreen);
     WRAP (ps, s, donePaintScreen, planeDonePaintScreen);
     WRAP (ps, s, paintOutput, planePaintOutput);
+    WRAP (ps, s, activateWindow, planeActivateWindow);
 
     s->base.privates[pd->screenPrivateIndex].ptr = ps;
 
@@ -650,6 +653,7 @@ planeFiniScreen (CompPlugin *p,
     UNWRAP (ps, s, preparePaintScreen);
     UNWRAP (ps, s, donePaintScreen);
     UNWRAP (ps, s, paintOutput);
+    UNWRAP (ps, s, activateWindow);
 
     free (ps);
 }

Modified: compiz/plugins/rotate.c
===================================================================
--- compiz/plugins/rotate.c
+++ compiz/plugins/rotate.c
@@ -110,6 +110,7 @@ typedef struct _RotateScreen {
     PaintOutputProc		 paintOutput;
     WindowGrabNotifyProc	 windowGrabNotify;
     WindowUngrabNotifyProc	 windowUngrabNotify;
+    ActivateWindowProc           activateWindow;
 
     CubeGetRotationProc getRotation;
 
@@ -1472,7 +1473,6 @@ rotateHandleEvent (CompDisplay *d,
 		   XEvent      *event)
 {
     CompScreen *s;
-    Window     activeWindow = d->activeWindow;
 
     ROTATE_DISPLAY (d);
 
@@ -1579,63 +1579,63 @@ rotateHandleEvent (CompDisplay *d,
     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)
-	{
-	    s = w->screen;
+static void
+rotateActivateWindow (CompWindow *w)
+{
+    CompScreen *s = w->screen;
 
-	    if (!otherScreenGrabExist (s, "rotate", "switcher", "cube", 0))
-	    {
-		int dx;
+    ROTATE_SCREEN (s);
 
-		ROTATE_SCREEN (s);
+    if (w->placed &&
+	!otherScreenGrabExist (s, "rotate", "switcher", "cube", 0))
+    {
+	int dx;
 
-		/* reset movement */
-		rs->moveTo = 0.0f;
+	/* reset movement */
+	rs->moveTo = 0.0f;
 
-		defaultViewportForWindow (w, &dx, NULL);
-		dx -= 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 (s->display->display, s->root,
+			   &win, &win, &x, &y, &i, &i, &ui);
 
-		    if (dx * 2 > s->hsize)
-			dx -= s->hsize;
-		    else if (dx * 2 < -s->hsize)
-			dx += s->hsize;
+	    if (dx * 2 > s->hsize)
+		dx -= s->hsize;
+	    else if (dx * 2 < -s->hsize)
+		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 (s->display, NULL, 0, o, 4);
 	}
     }
+
+    UNWRAP (rs, s, activateWindow);
+    (*s->activateWindow) (w);
+    WRAP (rs, s, activateWindow, rotateActivateWindow);
 }
 
 static void
@@ -1880,6 +1880,7 @@ rotateInitScreen (CompPlugin *p,
     WRAP (rs, s, paintOutput, rotatePaintOutput);
     WRAP (rs, s, windowGrabNotify, rotateWindowGrabNotify);
     WRAP (rs, s, windowUngrabNotify, rotateWindowUngrabNotify);
+    WRAP (rs, s, activateWindow, rotateActivateWindow);
 
     WRAP (rs, cs, getRotation, rotateGetRotation);
 

Modified: compiz/plugins/scale.c
===================================================================
--- compiz/plugins/scale.c
+++ compiz/plugins/scale.c
@@ -987,33 +987,6 @@ scaleCheckForWindowAt (CompScreen *s,
 }
 
 static void
-sendViewportMoveRequest (CompScreen *s,
-			 int	    x,
-			 int	    y)
-{
-    XEvent xev;
-
-    xev.xclient.type    = ClientMessage;
-    xev.xclient.display = s->display->display;
-    xev.xclient.format  = 32;
-
-    xev.xclient.message_type = s->display->desktopViewportAtom;
-    xev.xclient.window	     = s->root;
-
-    xev.xclient.data.l[0] = x;
-    xev.xclient.data.l[1] = y;
-    xev.xclient.data.l[2] = 0;
-    xev.xclient.data.l[3] = 0;
-    xev.xclient.data.l[4] = 0;
-
-    XSendEvent (s->display->display,
-		s->root,
-		FALSE,
-		SubstructureRedirectMask | SubstructureNotifyMask,
-		&xev);
-}
-
-static void
 sendDndStatusMessage (CompScreen *s,
 		      Window	 source)
 {
@@ -1099,18 +1072,7 @@ scaleTerminate (CompDisplay     *d,
 		{
 		    w = findWindowAtScreen (s, sd->selectedWindow);
 		    if (w)
-		    {
-			int x, y;
-
-			activateWindow (w);
-
-			defaultViewportForWindow (w, &x, &y);
-
-			if (x != s->x || y != s->y)
-			    sendViewportMoveRequest (s,
-						     x * s->width,
-						     y * s->height);
-		    }
+			(*s->activateWindow) (w);
 		}
 
 		ss->state = SCALE_STATE_IN;

Modified: compiz/src/display.c
===================================================================
--- compiz/src/display.c
+++ compiz/src/display.c
@@ -753,7 +753,8 @@ const CompMetadataOptionInfo coreDisplayOptionInfo[COMP_DISPLAY_OPTION_NUM] = {
     { "ignore_hints_when_maximized", "bool", 0, 0, 0 },
     { "command_terminal", "string", 0, 0, 0 },
     { "run_command_terminal_key", "key", 0, runCommandTerminal, 0 },
-    { "ping_delay", "int", "<min>1000</min>", 0, 0 }
+    { "ping_delay", "int", "<min>1000</min>", 0, 0 },
+    { "edge_delay", "int", "<min>0</min>", 0, 0 }
 };
 
 CompOption *
@@ -1995,6 +1996,8 @@ addDisplay (const char *name)
     d->screenPrivateIndices = 0;
     d->screenPrivateLen     = 0;
 
+    d->edgeDelayHandle = 0;
+
     d->logMessage = logMessage;
 
     d->modMap = 0;

Modified: compiz/src/event.c
===================================================================
--- compiz/src/event.c
+++ compiz/src/event.c
@@ -604,6 +604,7 @@ isEdgeAction (CompOption      *option,
 static Bool
 isEdgeEnterAction (CompOption      *option,
 		   CompActionState state,
+		   CompActionState delayState,
 		   unsigned int    edge,
 		   CompAction      **action)
 {
@@ -616,6 +617,18 @@ isEdgeEnterAction (CompOption      *option,
     if (!option->value.action.initiate)
 	return FALSE;
 
+    if (delayState)
+    {
+	if ((option->value.action.state & CompActionStateNoEdgeDelay) !=
+	    (delayState & CompActionStateNoEdgeDelay))
+	{
+	    /* ignore edge actions which shouldn't be delayed when invoking
+	       undelayed edges (or vice versa) */
+	    return FALSE;
+	}
+    }
+
+
     *action = &option->value.action;
 
     return TRUE;
@@ -643,6 +656,7 @@ triggerEdgeEnterBindings (CompDisplay	  *d,
 			  CompOption	  *option,
 			  int		  nOption,
 			  CompActionState state,
+			  CompActionState delayState,
 			  unsigned int	  edge,
 			  CompOption	  *argument,
 			  int		  nArgument)
@@ -651,7 +665,7 @@ triggerEdgeEnterBindings (CompDisplay	  *d,
 
     while (nOption--)
     {
-	if (isEdgeEnterAction (option, state, edge, &action))
+	if (isEdgeEnterAction (option, state, delayState, edge, &action))
 	{
 	    if ((*action->initiate) (d, action, state, argument, nArgument))
 		return TRUE;
@@ -689,6 +703,106 @@ triggerEdgeLeaveBindings (CompDisplay	  *d,
 }
 
 static Bool
+triggerAllEdgeEnterBindings (CompDisplay     *d,
+			     CompActionState state,
+			     CompActionState delayState,
+			     unsigned int    edge,
+			     CompOption	     *argument,
+			     int	     nArgument)
+{
+    CompOption *option;
+    int        nOption;
+    CompPlugin *p;
+
+    for (p = getPlugins (); p; p = p->next)
+    {
+	if (p->vTable->getObjectOptions)
+	{
+	    option = (*p->vTable->getObjectOptions) (p, &d->base, &nOption);
+	    if (triggerEdgeEnterBindings (d,
+					  option, nOption,
+					  state, delayState, edge,
+					  argument, nArgument))
+	    {
+		return TRUE;
+	    }
+	}
+    }
+    return FALSE;
+}
+
+static Bool
+delayedEdgeTimeout (void *closure)
+{
+    CompDelayedEdgeSettings *settings = (CompDelayedEdgeSettings *) closure;
+
+    triggerAllEdgeEnterBindings (settings->d,
+				 settings->state,
+				 ~CompActionStateNoEdgeDelay,
+				 settings->edge,
+				 settings->option,
+				 settings->nOption);
+
+    free (settings);
+
+    return FALSE;
+}
+
+static Bool
+triggerEdgeEnter (CompDisplay     *d,
+		  unsigned int    edge,
+		  CompActionState state,
+		  CompOption      *argument,
+		  unsigned int    nArgument)
+{
+    int                     delay;
+    CompDelayedEdgeSettings *delayedSettings = NULL;
+
+    delay = d->opt[COMP_DISPLAY_OPTION_EDGE_DELAY].value.i;
+
+    if (nArgument > 7)
+	nArgument = 7;
+
+    if (delay > 0)
+    {
+	delayedSettings = malloc (sizeof (CompDelayedEdgeSettings));
+	if (delayedSettings)
+	{
+	    delayedSettings->d       = d;
+	    delayedSettings->edge    = edge;
+	    delayedSettings->state   = state;
+	    delayedSettings->nOption = nArgument;
+	}
+    }
+
+    if (delayedSettings)
+    {
+	CompActionState delayState;
+	int             i;
+
+	for (i = 0; i < nArgument; i++)
+	    delayedSettings->option[i] = argument[i];
+
+	d->edgeDelayHandle = compAddTimeout (delay,
+					     delayedEdgeTimeout,
+					     delayedSettings);
+
+	delayState = CompActionStateNoEdgeDelay;
+	if (triggerAllEdgeEnterBindings (d, state, delayState,
+					 edge, argument, nArgument))
+	    return TRUE;
+    }
+    else
+    {
+	if (triggerAllEdgeEnterBindings (d, state, 0, edge,
+					 argument, nArgument))
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+static Bool
 handleActionEvent (CompDisplay *d,
 		   XEvent      *event)
 {
@@ -833,6 +947,16 @@ handleActionEvent (CompDisplay *d,
 	    if (!s)
 		return FALSE;
 
+	    if (d->edgeDelayHandle)
+	    {
+		void *closure;
+
+		closure = compRemoveTimeout (d->edgeDelayHandle);
+		if (closure)
+		    free (closure);
+		d->edgeDelayHandle = 0;
+	    }
+
 	    if (edgeWindow && edgeWindow != event->xcrossing.window)
 	    {
 		state = CompActionStateTermEdge;
@@ -900,18 +1024,11 @@ handleActionEvent (CompDisplay *d,
 		o[6].name    = "time";
 		o[6].value.i = event->xcrossing.time;
 
-		for (p = getPlugins (); p; p = p->next)
-		{
-		    if (!p->vTable->getObjectOptions)
-			continue;
-
-		    option = (*p->vTable->getObjectOptions) (p, obj, &nOption);
-		    if (triggerEdgeEnterBindings (d, option, nOption, state,
-						  edge, o, 7))
-			return TRUE;
-		}
+		if (triggerEdgeEnter (d, edge, state, o, 7))
+		    return TRUE;
 	    }
-	} break;
+	}
+	break;
     case ClientMessage:
 	if (event->xclient.message_type == d->xdndEnterAtom)
 	{
@@ -1007,16 +1124,8 @@ handleActionEvent (CompDisplay *d,
 		o[4].value.i = event->xclient.data.l[2] & 0xffff;
 		o[5].value.i = root;
 
-		for (p = getPlugins (); p; p = p->next)
-		{
-		    if (!p->vTable->getObjectOptions)
-			continue;
-
-		    option = (*p->vTable->getObjectOptions) (p, obj, &nOption);
-		    if (triggerEdgeEnterBindings (d, option, nOption, state,
-						  edge, o, 6))
-			return TRUE;
-		}
+		if (triggerEdgeEnter (d, edge, state, o, 6))
+		    return TRUE;
 	    }
 
 	    xdndWindow = None;
@@ -1231,6 +1340,9 @@ handleEvent (CompDisplay *d,
 	w = findWindowAtDisplay (d, event->xmap.window);
 	if (w)
 	{
+	    if (!w->attrib.override_redirect)
+		w->managed = TRUE;
+
 	    /* been shaded */
 	    if (w->height == 0)
 	    {
@@ -1549,7 +1661,7 @@ handleEvent (CompDisplay *d,
 		if (event->xclient.data.l[0] != 1 ||
 		    allowWindowFocus (w, 0, event->xclient.data.l[1]))
 		{
-		    activateWindow (w);
+		    (*w->screen->activateWindow) (w);
 		}
 	    }
 	}

Modified: compiz/src/metadata.c
===================================================================
--- compiz/src/metadata.c
+++ compiz/src/metadata.c
@@ -895,6 +895,7 @@ initFloatRestriction (CompMetadata	    *metadata,
 
 static void
 initActionState (CompMetadata    *metadata,
+		 CompOptionType  type,
 		 CompActionState *state,
 		 const char      *path)
 {
@@ -923,6 +924,20 @@ initActionState (CompMetadata    *metadata,
 	free (grab);
     }
 
+    if (type == CompOptionTypeEdge)
+    {
+	char *noEdgeDelay;
+
+	noEdgeDelay = stringFromMetadataPathElement (metadata, path, "nodelay");
+	if (noEdgeDelay)
+	{
+	    if (strcmp (noEdgeDelay, "true") == 0)
+		*state |= CompActionStateNoEdgeDelay;
+
+	    free (noEdgeDelay);
+	}
+    }
+
     if (!initXPathFromMetadataPathElement (&xPath, metadata, BAD_CAST path,
 					   BAD_CAST "allowed"))
 	return;
@@ -1006,23 +1021,23 @@ initOptionFromMetadataPath (CompDisplay   *d,
 	initColorValue (&option->value, defaultDoc, defaultNode);
 	break;
     case CompOptionTypeAction:
-	initActionState (metadata, &state, (char *) path);
+	initActionState (metadata, option->type, &state, (char *) path);
 	initActionValue (d, &option->value, state, defaultDoc, defaultNode);
 	break;
     case CompOptionTypeKey:
-	initActionState (metadata, &state, (char *) path);
+	initActionState (metadata, option->type, &state, (char *) path);
 	initKeyValue (d, &option->value, state, defaultDoc, defaultNode);
 	break;
     case CompOptionTypeButton:
-	initActionState (metadata, &state, (char *) path);
+	initActionState (metadata, option->type, &state, (char *) path);
 	initButtonValue (d, &option->value, state, defaultDoc, defaultNode);
 	break;
     case CompOptionTypeEdge:
-	initActionState (metadata, &state, (char *) path);
+	initActionState (metadata, option->type, &state, (char *) path);
 	initEdgeValue (d, &option->value, state, defaultDoc, defaultNode);
 	break;
     case CompOptionTypeBell:
-	initActionState (metadata, &state, (char *) path);
+	initActionState (metadata, option->type, &state, (char *) path);
 	initBellValue (d, &option->value, state, defaultDoc, defaultNode);
 	break;
     case CompOptionTypeMatch:
@@ -1054,7 +1069,8 @@ initOptionFromMetadataPath (CompDisplay   *d,
 	case CompOptionTypeButton:
 	case CompOptionTypeEdge:
 	case CompOptionTypeBell:
-	    initActionState (metadata, &state, (char *) path);
+	    initActionState (metadata, option->value.list.type,
+			     &state, (char *) path);
 	    break;
 	case CompOptionTypeMatch:
 	    helper = boolFromMetadataPathElement (metadata, (char *) path,

Modified: compiz/src/screen.c
===================================================================
--- compiz/src/screen.c
+++ compiz/src/screen.c
@@ -641,6 +641,8 @@ const CompMetadataOptionInfo coreScreenOptionInfo[COMP_SCREEN_OPTION_NUM] = {
     { "outputs", "list", "<type>string</type>", 0, 0 },
     { "overlapping_outputs", "int",
       RESTOSTRING (0, OUTPUT_OVERLAP_MODE_LAST), 0, 0 },
+    { "focus_prevention_level", "int",
+      RESTOSTRING (0, FOCUS_PREVENTION_LEVEL_LAST), 0, 0 },
     { "focus_prevention_match", "match", 0, 0, 0 },
     { "opacity_matches", "list", "<type>match</type>", 0, 0 },
     { "opacity_values", "list", "<type>int</type>", 0, 0 }
@@ -1755,6 +1757,7 @@ addScreen (CompDisplay *display,
     s->getOutputExtentsForWindow   = getOutputExtentsForWindow;
     s->getAllowedActionsForWindow  = getAllowedActionsForWindow;
     s->focusWindow		   = focusWindow;
+    s->activateWindow              = activateWindow;
     s->placeWindow                 = placeWindow;
     s->validateWindowResizeRequest = validateWindowResizeRequest;
 

Modified: compiz/src/window.c
===================================================================
--- compiz/src/window.c
+++ compiz/src/window.c
@@ -3589,28 +3589,28 @@ addWindowSizeChanges (CompWindow     *w,
 	}
 
 	/* constrain window width if smaller than minimum width */
-	if (!(mask & CWWidth) && w->serverWidth < w->sizeHints.min_width)
+	if (!(mask & CWWidth) && oldWidth < w->sizeHints.min_width)
 	{
 	    xwc->width = w->sizeHints.min_width;
 	    mask |= CWWidth;
 	}
 
 	/* constrain window width if greater than maximum width */
-	if (!(mask & CWWidth) && w->serverWidth > w->sizeHints.max_width)
+	if (!(mask & CWWidth) && oldWidth > w->sizeHints.max_width)
 	{
 	    xwc->width = w->sizeHints.max_width;
 	    mask |= CWWidth;
 	}
 
 	/* constrain window height if smaller than minimum height */
-	if (!(mask & CWHeight) && w->serverHeight < w->sizeHints.min_height)
+	if (!(mask & CWHeight) && oldHeight < w->sizeHints.min_height)
 	{
 	    xwc->height = w->sizeHints.min_height;
 	    mask |= CWHeight;
 	}
 
 	/* constrain window height if greater than maximum height */
-	if (!(mask & CWHeight) && w->serverHeight > w->sizeHints.max_height)
+	if (!(mask & CWHeight) && oldHeight > w->sizeHints.max_height)
 	{
 	    xwc->height = w->sizeHints.max_height;
 	    mask |= CWHeight;
@@ -4697,14 +4697,17 @@ 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;
+    CompDisplay  *d = w->screen->display;
+    CompScreen   *s = w->screen;
+    CompWindow   *active;
+    Time	 wUserTime, aUserTime;
+    Bool         gotTimestamp = FALSE;
+    CompMatch    *match;
+    int          level, vx, vy;
 
-    if (w->id == d->activeWindow)
+    level = s->opt[COMP_SCREEN_OPTION_FOCUS_PREVENTION_LEVEL].value.i;
+
+    if (level == FOCUS_PREVENTION_LEVEL_NONE)
 	return TRUE;
 
     /* not in current viewport */
@@ -4717,37 +4720,53 @@ isWindowFocusAllowed (CompWindow *w,
 	/* the caller passed a timestamp, so use that
 	   instead of the window's user time */
 	wUserTime = timestamp;
+	gotTimestamp = TRUE;
     }
     else
     {
-	if (!getWindowUserTime (w, &wUserTime))
+	if (getWindowUserTime (w, &wUserTime))
+	{
+	    gotTimestamp = TRUE;
+	}
+	else if (w->initialTimestampSet)
 	{
-	    /* no user time or initial timestamp */
-	    if (!w->initialTimestampSet)
-		return TRUE;
-
 	    wUserTime = w->initialTimestamp;
+	    gotTimestamp = TRUE;
 	}
+    }
 
+    if (gotTimestamp && !wUserTime)
+    {
 	/* window explicitly requested no focus */
-	if (!wUserTime)
-	    return FALSE;
+	return FALSE;
     }
 
-    /* can't get user time for active window */
-    active = findWindowAtDisplay (d, d->activeWindow);
-    if (!active || !getWindowUserTime (active, &aUserTime))
+    /* allow focus for excluded windows */
+    match = &s->opt[COMP_SCREEN_OPTION_FOCUS_PREVENTION_MATCH].value.match;
+    if (!matchEval (match, w))
 	return TRUE;
 
-    match = &s->opt[COMP_SCREEN_OPTION_FOCUS_PREVENTION_MATCH].value.match;
+    if (level == FOCUS_PREVENTION_LEVEL_VERYHIGH)
+	return FALSE;
 
-    /* focus prevention */
-    if (matchEval (match, w))
+    if (!gotTimestamp)
     {
-	if (XSERVER_TIME_IS_BEFORE (wUserTime, aUserTime))
+	/* unsure as we have nothing to compare - allow focus in low level,
+	   don't allow in high level */
+	if (level == FOCUS_PREVENTION_LEVEL_HIGH)
 	    return FALSE;
+
+	return TRUE;
     }
 
+    /* can't get user time for active window */
+    active = findWindowAtDisplay (d, d->activeWindow);
+    if (!active || !getWindowUserTime (active, &aUserTime))
+	return TRUE;
+
+    if (XSERVER_TIME_IS_BEFORE (wUserTime, aUserTime))
+	return FALSE;
+
     return TRUE;
 }
 
@@ -4758,6 +4777,9 @@ allowWindowFocus (CompWindow   *w,
 {
     Bool retval;
 
+    if (w->id == w->screen->display->activeWindow)
+	return TRUE;
+
     /* do not focus windows of these types */
     if (w->type & noFocusMask)
 	return FALSE;


More information about the commits mailing list