[PATCH] Added screen edge trigger delay setting.

Danny Baumann dannybaumann at web.de
Tue Jun 19 05:39:40 PDT 2007


---
 include/compiz.h     |   17 ++++++-
 metadata/core.xml.in |    7 +++
 src/display.c        |    5 ++-
 src/event.c          |  130 +++++++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 143 insertions(+), 16 deletions(-)

diff --git a/include/compiz.h b/include/compiz.h
index dd34f00..abb1169 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -26,7 +26,7 @@
 #ifndef _COMPIZ_H
 #define _COMPIZ_H
 
-#define ABIVERSION 20070606
+#define ABIVERSION 20070619
 
 #include <stdio.h>
 #include <sys/time.h>
@@ -587,7 +587,8 @@ typedef int CompFileWatchHandle;
 #define COMP_DISPLAY_OPTION_TERMINAL			  56
 #define COMP_DISPLAY_OPTION_RUN_TERMINAL		  57
 #define COMP_DISPLAY_OPTION_PING_DELAY			  58
-#define COMP_DISPLAY_OPTION_NUM				  59
+#define COMP_DISPLAY_OPTION_EDGE_DELAY                    59
+#define COMP_DISPLAY_OPTION_NUM				  60
 
 typedef CompOption *(*GetDisplayOptionsProc) (CompDisplay *display,
 					      int	  *count);
@@ -904,6 +905,8 @@ struct _CompDisplay {
     CompTimeoutHandle autoRaiseHandle;
     Window	      autoRaiseWindow;
 
+    CompTimeoutHandle edgeDelayHandle;
+
     CompOptionValue plugin;
     Bool	    dirtyPluginList;
 
@@ -1107,6 +1110,16 @@ findCursorAtDisplay (CompDisplay *display);
 
 /* event.c */
 
+typedef struct _CompDelayedEdgeSettings
+{
+    CompDisplay *d;
+
+    unsigned int edge;
+    unsigned int state;
+
+    CompOption option[7];
+} CompDelayedEdgeSettings;
+
 void
 handleEvent (CompDisplay *display,
 	     XEvent      *event);
diff --git a/metadata/core.xml.in b/metadata/core.xml.in
index 8424ab1..64d418a 100644
--- a/metadata/core.xml.in
+++ b/metadata/core.xml.in
@@ -44,6 +44,13 @@
 		<min>0</min>
 		<max>10000</max>
 	    </option>
+	    <option name="edge_delay" type="int">
+		<_short>Edge Trigger Delay</_short>
+		<_long>Duration the pointer must reset 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" type="action">
 		<_short>Close Window</_short>
 		<_long>Close active window</_long>
diff --git a/src/display.c b/src/display.c
index a988b38..cd4e570 100644
--- a/src/display.c
+++ b/src/display.c
@@ -726,7 +726,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", "action", 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 *
@@ -1979,6 +1980,8 @@ addDisplay (char *name)
     d->autoRaiseHandle = 0;
     d->autoRaiseWindow = None;
 
+    d->edgeDelayHandle = 0;
+
     d->display = dpy = XOpenDisplay (name);
     if (!d->display)
     {
diff --git a/src/event.c b/src/event.c
index 335cd56..35cc472 100644
--- a/src/event.c
+++ b/src/event.c
@@ -680,6 +680,60 @@ triggerEdgeLeaveBindings (CompDisplay	  *d,
 }
 
 static Bool
+triggerAllEdgeEnterBindings (CompDisplay     *d,
+			     CompActionState state,
+			     unsigned int	edge,
+			     CompOption	*argument,
+			     int		nArgument)
+{
+    CompOption *option;
+    int        nOption;
+    CompPlugin *p;
+
+    for (p = getPlugins(); p; p = p->next)
+    {
+	if (p->vTable->getDisplayOptions)
+	{
+	    option = (*p->vTable->getDisplayOptions) (p, d, &nOption);
+	    if (triggerEdgeEnterBindings (d,
+					  option, nOption,
+					  state, edge,
+					  argument, nArgument))
+	    {
+		return TRUE;
+	    }
+	}
+    }
+
+    option = compGetDisplayOptions (d, &nOption);
+    if (triggerEdgeEnterBindings(d,
+				 option, nOption,
+				 state, edge,
+				 argument, nArgument))
+    {
+	return TRUE;
+    }
+
+    return FALSE;
+}
+
+static Bool
+delayedEdgeTimeout (void *closure)
+{
+    CompDelayedEdgeSettings *settings = (CompDelayedEdgeSettings *) closure;
+    CompDisplay *d = settings->d;
+
+    triggerAllEdgeEnterBindings (d,
+				 settings->state,
+				 settings->edge,
+				 settings->option, 7);
+
+    free (settings);
+
+    return FALSE;
+}
+
+static Bool
 handleActionEvent (CompDisplay *d,
 		   XEvent      *event)
 {
@@ -848,6 +902,16 @@ handleActionEvent (CompDisplay *d,
 
 	    if (edgeWindow && edgeWindow != event->xcrossing.window)
 	    {
+		if (d->edgeDelayHandle)
+		{
+		    void *closure;
+
+		    closure = compRemoveTimeout (d->edgeDelayHandle);
+		    if (closure)
+			free (closure);
+		    d->edgeDelayHandle = 0;
+		}
+
 		state = CompActionStateTermEdge;
 		edge  = 0;
 
@@ -903,10 +967,51 @@ handleActionEvent (CompDisplay *d,
 
 	    if (edge)
 	    {
+		int                     delay;
+		CompDelayedEdgeSettings *delayedSettings = NULL;
+		CompScreen              *s;
+
+		delay = d->opt[COMP_DISPLAY_OPTION_EDGE_DELAY].value.i;
+		if (delay > 0)
+		{
+		    /* if any plugin, such as move, already has a screen
+		       grab, we most likely don't want to delay screen edge
+		       triggering, as it would delay e.g. edge flipping */
+		    for (s = d->screens; s; s = s->next)
+			if (otherScreenGrabExist (s, 0))
+			{
+			    delay = 0;
+			    break;
+			}
+		}
+
 		state = CompActionStateInitEdge;
 
+		if (edgeWindow                            &&
+		    edgeWindow != event->xcrossing.window &&
+		    d->edgeDelayHandle)
+		{
+		    void *closure;
+
+		    closure = compRemoveTimeout (d->edgeDelayHandle);
+		    if (closure)
+			free (closure);
+		    d->edgeDelayHandle = 0;
+		}
+
 		edgeWindow = event->xcrossing.window;
 
+		if (delay > 0)
+		{
+		    delayedSettings = malloc (sizeof (CompDelayedEdgeSettings));
+		    if (delayedSettings)
+		    {
+			delayedSettings->d     = d;
+			delayedSettings->edge  = edge;
+			delayedSettings->state = state;
+		    }
+		}
+
 		o[0].value.i = event->xcrossing.window;
 		o[1].value.i = d->activeWindow;
 		o[2].value.i = event->xcrossing.state;
@@ -918,21 +1023,20 @@ handleActionEvent (CompDisplay *d,
 		o[6].name    = "time";
 		o[6].value.i = event->xcrossing.time;
 
-		for (p = getPlugins (); p; p = p->next)
+		if (delayedSettings)
 		{
-		    if (p->vTable->getDisplayOptions)
-		    {
-			option = (*p->vTable->getDisplayOptions) (p, d, &nOption);
-			if (triggerEdgeEnterBindings (d, option, nOption, state,
-						      edge, o, 7))
-			    return TRUE;
-		    }
-		}
+		    for (i = 0; i < 7; i++)
+			delayedSettings->option[i] = o[i];
 
-		option = compGetDisplayOptions (d, &nOption);
-		if (triggerEdgeEnterBindings (d, option, nOption, state,
-					      edge, o, 7))
-		    return TRUE;
+		    d->edgeDelayHandle = compAddTimeout (delay,
+							 delayedEdgeTimeout,
+							 delayedSettings);
+		}
+		else
+		{
+		    if (triggerAllEdgeEnterBindings (d, state, edge, o, 7))
+			return TRUE;
+		}
 	    }
 	} break;
     case ClientMessage:
-- 
1.5.0.6


--=-IrIVjqs5PuKBKjYXjxbg--



More information about the compiz mailing list