[PATCH] Added edge enter trigger delay setting.

Danny Baumann dannybaumann at web.de
Thu Jul 12 00:51:25 PDT 2007


Plugins can mark edge actions as immediate with the metadata tag <ignore_edge_delay>.
---
 include/compiz.h     |   42 ++++++++++-----
 metadata/core.xml.in |    7 +++
 src/display.c        |    5 ++-
 src/event.c          |  142 ++++++++++++++++++++++++++++++++++++++++++++------
 src/metadata.c       |   12 ++++-
 5 files changed, 176 insertions(+), 32 deletions(-)

diff --git a/include/compiz.h b/include/compiz.h
index cefb7d7..f5d6e95 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -26,7 +26,7 @@
 #ifndef _COMPIZ_H
 #define _COMPIZ_H
 
-#define ABIVERSION 20070706
+#define ABIVERSION 20070712
 
 #include <stdio.h>
 #include <sys/time.h>
@@ -290,18 +290,19 @@ typedef enum {
 } CompBindingType;
 
 typedef enum {
-    CompActionStateInitKey     = 1 <<  0,
-    CompActionStateTermKey     = 1 <<  1,
-    CompActionStateInitButton  = 1 <<  2,
-    CompActionStateTermButton  = 1 <<  3,
-    CompActionStateInitBell    = 1 <<  4,
-    CompActionStateInitEdge    = 1 <<  5,
-    CompActionStateTermEdge    = 1 <<  6,
-    CompActionStateInitEdgeDnd = 1 <<  7,
-    CompActionStateTermEdgeDnd = 1 <<  8,
-    CompActionStateCommit      = 1 <<  9,
-    CompActionStateCancel      = 1 << 10,
-    CompActionStateAutoGrab    = 1 << 11
+    CompActionStateInitKey         = 1 <<  0,
+    CompActionStateTermKey         = 1 <<  1,
+    CompActionStateInitButton      = 1 <<  2,
+    CompActionStateTermButton      = 1 <<  3,
+    CompActionStateInitBell        = 1 <<  4,
+    CompActionStateInitEdge        = 1 <<  5,
+    CompActionStateTermEdge        = 1 <<  6,
+    CompActionStateInitEdgeDnd     = 1 <<  7,
+    CompActionStateTermEdgeDnd     = 1 <<  8,
+    CompActionStateCommit          = 1 <<  9,
+    CompActionStateCancel          = 1 << 10,
+    CompActionStateAutoGrab        = 1 << 11,
+    CompActionStateIgnoreEdgeDelay = 1 << 12
 } CompActionState;
 
 typedef enum {
@@ -587,7 +588,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 +906,8 @@ struct _CompDisplay {
     CompTimeoutHandle autoRaiseHandle;
     Window	      autoRaiseWindow;
 
+    CompTimeoutHandle edgeDelayHandle;
+
     CompOptionValue plugin;
     Bool	    dirtyPluginList;
 
@@ -1107,6 +1111,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 69e7de3..2c7ed60 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 *
@@ -1981,6 +1982,8 @@ addDisplay (char *name)
 
     d->logMessage = logMessage;
 
+    d->edgeDelayHandle = 0;
+
     d->display = dpy = XOpenDisplay (name);
     if (!d->display)
     {
diff --git a/src/event.c b/src/event.c
index ab530c2..c12d55d 100644
--- a/src/event.c
+++ b/src/event.c
@@ -595,6 +595,7 @@ isEdgeAction (CompOption      *option,
 static Bool
 isEdgeEnterAction (CompOption      *option,
 		   CompActionState state,
+		   CompActionState ignoreState,
 		   unsigned int    edge,
 		   CompAction      **action)
 {
@@ -607,6 +608,15 @@ isEdgeEnterAction (CompOption      *option,
     if (!option->value.action.initiate)
 	return FALSE;
 
+    if (ignoreState)
+    {
+	if (!((option->value.action.state & CompActionStateIgnoreEdgeDelay) ==
+	      (ignoreState & CompActionStateIgnoreEdgeDelay)))
+	{
+	    return FALSE;
+	}
+    }
+
     *action = &option->value.action;
 
     return TRUE;
@@ -634,6 +644,7 @@ triggerEdgeEnterBindings (CompDisplay	  *d,
 			  CompOption	  *option,
 			  int		  nOption,
 			  CompActionState state,
+			  CompActionState ignoreState,
 			  unsigned int	  edge,
 			  CompOption	  *argument,
 			  int		  nArgument)
@@ -642,7 +653,7 @@ triggerEdgeEnterBindings (CompDisplay	  *d,
 
     while (nOption--)
     {
-	if (isEdgeEnterAction (option, state, edge, &action))
+	if (isEdgeEnterAction (option, state, ignoreState, edge, &action))
 	{
 	    if ((*action->initiate) (d, action, state, argument, nArgument))
 		return TRUE;
@@ -680,6 +691,62 @@ triggerEdgeLeaveBindings (CompDisplay	  *d,
 }
 
 static Bool
+triggerAllEdgeEnterBindings (CompDisplay     *d,
+			     CompActionState state,
+			     CompActionState ignoreState,
+			     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, ignoreState, edge,
+					  argument, nArgument))
+	    {
+		return TRUE;
+	    }
+	}
+    }
+
+    option = compGetDisplayOptions (d, &nOption);
+    if (triggerEdgeEnterBindings(d,
+				 option, nOption,
+				 state, ignoreState, edge,
+				 argument, nArgument))
+    {
+	return TRUE;
+    }
+
+    return FALSE;
+}
+
+static Bool
+delayedEdgeTimeout (void *closure)
+{
+    CompDelayedEdgeSettings *settings = (CompDelayedEdgeSettings *) closure;
+    CompDisplay *d = settings->d;
+
+    triggerAllEdgeEnterBindings (d,
+				 settings->state,
+				 ~CompActionStateIgnoreEdgeDelay,
+				 settings->edge,
+				 settings->option, 7);
+
+    free (settings);
+
+    return FALSE;
+}
+
+static Bool
 handleActionEvent (CompDisplay *d,
 		   XEvent      *event)
 {
@@ -848,6 +915,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 +980,37 @@ handleActionEvent (CompDisplay *d,
 
 	    if (edge)
 	    {
+		int                     delay;
+		CompDelayedEdgeSettings *delayedSettings = NULL;
+
+		delay = d->opt[COMP_DISPLAY_OPTION_EDGE_DELAY].value.i;
 		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 +1022,27 @@ 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;
-		    }
-		}
+		    CompActionState ignoreState;
 
-		option = compGetDisplayOptions (d, &nOption);
-		if (triggerEdgeEnterBindings (d, option, nOption, state,
-					      edge, o, 7))
-		    return TRUE;
+		    for (i = 0; i < 7; i++)
+			delayedSettings->option[i] = o[i];
+
+		    d->edgeDelayHandle = compAddTimeout (delay,
+							 delayedEdgeTimeout,
+							 delayedSettings);
+
+		    ignoreState = CompActionStateIgnoreEdgeDelay;
+		    if (triggerAllEdgeEnterBindings (d, state, ignoreState,
+						     edge, o, 7))
+			return TRUE;
+		}
+		else
+		{
+		    if (triggerAllEdgeEnterBindings (d, state, 0, edge, o, 7))
+			return TRUE;
+		}
 	    }
 	} break;
     case ClientMessage:
@@ -1041,14 +1151,14 @@ handleActionEvent (CompDisplay *d,
 		    {
 			option = (*p->vTable->getDisplayOptions) (p, d, &nOption);
 			if (triggerEdgeEnterBindings (d, option, nOption, state,
-						      edge, o, 6))
+						      0, edge, o, 6))
 			    return TRUE;
 		    }
 		}
 
 		option = compGetDisplayOptions (d, &nOption);
 		if (triggerEdgeEnterBindings (d, option, nOption, state,
-					      edge, o, 6))
+					      0, edge, o, 6))
 		    return TRUE;
 	    }
 
diff --git a/src/metadata.c b/src/metadata.c
index 337c91c..51e7211 100644
--- a/src/metadata.c
+++ b/src/metadata.c
@@ -851,7 +851,7 @@ initActionState (CompMetadata    *metadata,
     };
     int	      i;
     CompXPath xPath;
-    char      *grab;
+    char      *grab, *ignoreEdgeDelay;
 
     *state = CompActionStateAutoGrab;
 
@@ -864,6 +864,16 @@ initActionState (CompMetadata    *metadata,
 	free (grab);
     }
 
+    ignoreEdgeDelay = stringFromMetadataPathElement (metadata, path,
+						     "ignore_edge_delay");
+    if (ignoreEdgeDelay)
+    {
+	if (strcmp (ignoreEdgeDelay, "true") == 0)
+	    *state |= CompActionStateIgnoreEdgeDelay;
+
+	free (ignoreEdgeDelay);
+    }
+
     if (!initXPathFromMetadataPathElement (&xPath, metadata, BAD_CAST path,
 					   BAD_CAST "allowed"))
 	return;
-- 
1.5.2.2


--=-x8OTMg0wWYf/MMFSKHv3
Content-Disposition: attachment; filename*0=0003-Also-use-delayed-edge-setting-for-DnD-edge-bindings.patc; filename*1=h
Content-Type: application/mbox; name=0003-Also-use-delayed-edge-setting-for-DnD-edge-bindings.patch
Content-Transfer-Encoding: 7bit



More information about the compiz mailing list