Due to E16's poor support for Xnest (read: X crashes), I found myself
using pekwm.

Don't think I'll switch my main desktops, but there are two features I
really like: tabs and keychains/maps (like C-x or C-c in Emacs).
Keymapping was easier to write, so here goes.

This is just a simple first effort:

Working:
* It compiles. :)
* It does actions only if their keymap is currently active, and
  doesn't do them if it isn't.
* The base keymap is reactivated correctly.
* Nested keymaps are (sort of) possible.
* Events with actions in inactive keychains should not have their
  keys grabbed.
* Probably mouse buttons. But anyone who'd put a mouse in a keychain
  is crazy!

Buggy:
* If you want to use something like focus_next with it that will
  repeat in the keymap you have to put a BEGIN_CHAIN action along
  with the action you plan to repeat. (probably not fixable)

How to use:
* The action "__A_BEGIN_CHAIN n" begins a chain by changing the
  current keymap to n.
* A key definition can have one "__KEYMAP n" part (0 is the default).
  The action will then only run if the current keymap is keymap n.
* Keymap names are #define'd numbers like everything else in e
  config, not strings.

Example: 
  __NEXT_ACTION
    __KEY F12
    __EVENT __KEY_PRESS
    __ACTION __A_GOTO_DESK 1
  __NEXT_ACTION
    __KEY F1
    __EVENT __KEY_PRESS
    __ACTION __A_BEGIN_CHAIN 1
  __NEXT_ACTION
    __KEY F2
    __KEYMAP 1
    __EVENT __KEY_PRESS
    __ACTION __A_FOCUS_NEXT

Result: F2 will only change focus if you hit F1 first. F1 then F12 does
nothing.

-- 
BAM - Open head, insert foot.
diff -ruwN e.orig/src/E.h e.chains/src/E.h
--- e.orig/src/E.h	2003-10-27 02:38:45.000000000 -0500
+++ e.chains/src/E.h	2003-10-27 07:45:37.000000000 -0500
@@ -502,8 +502,9 @@
 #define ACTION_NEVERFOCUS             101
 #define ACTION_SKIPLISTS              102
 #define ACTION_SWAPMOVE               103
+#define ACTION_BEGIN_CHAIN            104
 /* false number excluding the above list */
-#define ACTION_NUMBEROF               104
+#define ACTION_NUMBEROF               105
 
 #define MODE_NONE                 0
 #define MODE_MOVE                 1
@@ -738,6 +739,7 @@
    char               *key_str;
    char               *tooltipstring;
    ActionType         *action;
+   int                 keymap;
 }
 Action;
 
@@ -2069,7 +2071,7 @@
 void                UnGrabButtonGrabs(EWin * ewin);
 ActionClass        *CreateAclass(char *name);
 Action             *CreateAction(char event, char anymod, int mod, int anybut,
-				 int but, char anykey, char *key,
+				 int but, char anykey, int keymap, char *key,
 				 char *tooltipstring);
 void                RemoveActionType(ActionType * ActionTypeToRemove);
 void                RemoveAction(Action * ActionToRemove);
@@ -2187,7 +2189,10 @@
 int                 doShowHideGroup(void *params);
 int                 doZoom(void *params);
 int                 initFunctionArray(void);
+int                 doBeginChain(void *params);
+void                DeactivateKeymap(int old_keymap);
 
+/* grabs.c functions */
 void                GrabActionKey(Action * a);
 void                UnGrabActionKey(Action * a);
 void                GrabTheButtons(Window win);
@@ -3047,6 +3052,7 @@
 extern char        *badtheme;
 extern char        *badreason;
 extern char        *e_machine_name;
+extern int          current_keymap;
 
 #ifdef HAS_XINERAMA
 extern char         xinerama_active;
diff -ruwN e.orig/src/actions.c e.chains/src/actions.c
--- e.orig/src/actions.c	2003-10-27 02:38:45.000000000 -0500
+++ e.chains/src/actions.c	2003-10-27 07:45:37.000000000 -0500
@@ -186,7 +186,7 @@
 
 Action             *
 CreateAction(char event, char anymod, int mod, int anybut, int but,
-	     char anykey, char *key, char *tooltipstring)
+	     char anykey, int keymap, char *key, char *tooltipstring)
 {
    Action             *act;
 
@@ -200,6 +200,7 @@
    act->anybutton = anybut;
    act->button = but;
    act->anykey = anykey;
+   act->keymap = keymap;
    if (!key)
       act->key = 0;
    else
@@ -460,8 +461,17 @@
 			       ok = 1;
 			 }
 		    }
+
+		  if (act->keymap != current_keymap)
+		    {
+		       if (ok)
+			  DeactivateKeymap(current_keymap);
+		       ok = 0;
+		    }
+
 		  if (ok)
 		    {
+		       DeactivateKeymap(current_keymap);
 		       handleAction(act->action);
 		       val = 1;
 		    }
@@ -2899,6 +2909,37 @@
 }
 
 int
+doBeginChain(void *params)
+{
+   void              **lst;
+   int                 i, j, num;
+   ActionClass        *actc;
+   int                 d = 0;
+
+   EDBUG(6, "doBeginChain");
+
+   sscanf((char *)params, "%i", &current_keymap);
+
+   lst = ListItemType(&num, LIST_TYPE_ACLASS_GLOBAL);
+   if (lst)
+     {
+	for (i = 0; i < num; i++)
+	  {
+	     actc = (ActionClass *) lst[i];
+	     for (j = 0; j < actc->num; j++)
+	       {
+		  if (actc->list[j]->keymap ==  current_keymap)
+		     GrabActionKey(actc->list[j]);
+	       }
+	  }
+	Efree(lst);
+     }
+
+   params = NULL;
+   EDBUG_RETURN(0);
+}
+
+int
 doFocusNext(void *params)
 {
    EDBUG(6, "doFocusNext");
@@ -4057,6 +4098,35 @@
    ActionFunctions[ACTION_NEVERFOCUS] = (int (*)(void *))(doNeverFocus);
    ActionFunctions[ACTION_SKIPLISTS] = (int (*)(void *))(doSkipLists);
    ActionFunctions[ACTION_SWAPMOVE] = (int (*)(void *))(doSwapMove);
+   ActionFunctions[ACTION_BEGIN_CHAIN] = (int (*)(void *))(doBeginChain);
 
    EDBUG_RETURN(0);
 }
+
+void
+DeactivateKeymap(int old_keymap)
+{
+   void              **lst;
+   int                 i, j, num;
+   ActionClass        *actc;
+
+   current_keymap = 0;
+
+   if (old_keymap != 0)
+     {
+	lst = ListItemType(&num, LIST_TYPE_ACLASS_GLOBAL);
+	if (lst)
+	  {
+	     for (i = 0; i < num; i++)
+	       {
+		  actc = (ActionClass *) lst[i];
+		  for (j = 0; j < actc->num; j++)
+		    {
+		       if (actc->list[j]->keymap ==  old_keymap)
+			  UnGrabActionKey(actc->list[j]);
+		    }
+	       }
+	     Efree(lst);
+	  }
+     }
+}
diff -ruwN e.orig/src/comms.c e.chains/src/comms.c
--- e.orig/src/comms.c	2003-10-27 02:38:45.000000000 -0500
+++ e.chains/src/comms.c	2003-10-27 07:45:37.000000000 -0500
@@ -794,7 +794,7 @@
 		     mod = Mod5Mask | ControlMask;
 		  else if (mod == 20)
 		     mod = Mod5Mask | ControlMask | ShiftMask;
-		  a = CreateAction(4, 0, mod, 0, 0, 0, key, NULL);
+		  a = CreateAction(4, 0, mod, 0, 0, 0, 0, key, NULL);
 		  GrabActionKey(a);
 		  AddAction(ac, a);
 		  if (atword(buf, 4))
diff -ruwN e.orig/src/conf.h e.chains/src/conf.h
--- e.orig/src/conf.h	2003-10-27 02:38:45.000000000 -0500
+++ e.chains/src/conf.h	2003-10-27 02:40:49.000000000 -0500
@@ -50,6 +50,7 @@
 #define CONFIG_NEXT 105
 #define CONFIG_INHERIT 106
 #define CONFIG_ACTION_TOOLTIP 107
+#define CONFIG_KEYMAP 108
 #define TEXT_ORIENTATION 200
 #define TEXT_JUSTIFICATION 201
 #define TEXT_MODE 202
diff -ruwN e.orig/src/config.c e.chains/src/config.c
--- e.orig/src/config.c	2003-10-27 02:38:45.000000000 -0500
+++ e.chains/src/config.c	2003-10-27 07:48:30.000000000 -0500
@@ -2081,6 +2081,7 @@
    int                 anybut = 0;
    int                 but = 0;
    int                 first = 1;
+   int                 keymap = 0;
    char                anykey = 0;
    char               *key = NULL;
    char               *action_tooltipstring = NULL;
@@ -2227,6 +2228,9 @@
 		  break;
 	       }
 	     break;
+	  case CONFIG_KEYMAP:
+	     keymap = atoi(s2);
+	     break;
 	  case CONFIG_ANYMOD:
 	  case ACLASS_ANYMOD:
 	     anymod = atoi(s2);
@@ -2255,13 +2259,14 @@
 	     mod = 0;
 	     anymod = 0;
 	     anybut = 0;
+	     keymap = 0;
 	     first = 1;
 	     break;
 	  case CONFIG_ACTION:
 	     if (first)
 	       {
 		  a = CreateAction(event, anymod, mod, anybut, but, anykey,
-				   key, action_tooltipstring);
+				   keymap, key, action_tooltipstring);
 		  /* the correct place to grab an action key */
 		  if (action_tooltipstring)
 		    {
@@ -2271,7 +2276,7 @@
 		  if (key)
 		     Efree(key);
 		  key = NULL;
-		  if (global)
+		  if ((global) && (!keymap))
 		     GrabActionKey(a);
 		  AddAction(ac, a);
 		  first = 0;
diff -ruwN e.orig/src/desktops.c e.chains/src/desktops.c
--- e.orig/src/desktops.c	2003-10-27 02:38:45.000000000 -0500
+++ e.chains/src/desktops.c	2003-10-27 07:45:37.000000000 -0500
@@ -1049,16 +1049,16 @@
 	  {
 	     ac = CreateAclass(s);
 	     AddItem(ac, ac->name, 0, LIST_TYPE_ACLASS);
-	     a = CreateAction(EVENT_MOUSE_DOWN, 0, 0, 0, 1, 0, NULL, NULL);
+	     a = CreateAction(EVENT_MOUSE_DOWN, 0, 0, 0, 1, 0, 0, NULL, NULL);
 	     AddAction(ac, a);
 	     param = Emalloc(3);
 	     Esnprintf(param, 3, "%i", i);
 	     AddToAction(a, ACTION_DESKTOP_DRAG, param);
-	     a = CreateAction(EVENT_MOUSE_DOWN, 0, 0, 0, 3, 0, NULL, NULL);
+	     a = CreateAction(EVENT_MOUSE_DOWN, 0, 0, 0, 3, 0, 0, NULL, NULL);
 	     AddAction(ac, a);
 	     Esnprintf(s, sizeof(s), "deskmenu");
 	     AddToAction(a, ACTION_SHOW_MENU, duplicate(s));
-	     a = CreateAction(EVENT_MOUSE_DOWN, 0, 0, 0, 2, 0, NULL, NULL);
+	     a = CreateAction(EVENT_MOUSE_DOWN, 0, 0, 0, 2, 0, 0, NULL, NULL);
 	     AddAction(ac, a);
 	     Esnprintf(s, sizeof(s), "taskmenu");
 	     AddToAction(a, ACTION_SHOW_MENU, duplicate(s));
@@ -1092,7 +1092,7 @@
 	  {
 	     ac2 = CreateAclass(s);
 	     AddItem(ac2, ac2->name, 0, LIST_TYPE_ACLASS);
-	     a = CreateAction(EVENT_MOUSE_UP, 1, 0, 1, 0, 0, NULL, NULL);
+	     a = CreateAction(EVENT_MOUSE_UP, 1, 0, 1, 0, 0, 0, NULL, NULL);
 	     AddAction(ac2, a);
 	     param = Emalloc(3);
 	     Esnprintf(param, 3, "%i", i);
@@ -1108,7 +1108,7 @@
 	  {
 	     ac3 = CreateAclass(s);
 	     AddItem(ac3, ac3->name, 0, LIST_TYPE_ACLASS);
-	     a = CreateAction(EVENT_MOUSE_UP, 1, 0, 1, 0, 0, NULL, NULL);
+	     a = CreateAction(EVENT_MOUSE_UP, 1, 0, 1, 0, 0, 0, NULL, NULL);
 	     AddAction(ac3, a);
 	     param = Emalloc(3);
 	     Esnprintf(param, 3, "%i", i);
diff -ruwN e.orig/src/globals.c e.chains/src/globals.c
--- e.orig/src/globals.c	2003-10-27 02:38:45.000000000 -0500
+++ e.chains/src/globals.c	2003-10-27 07:45:37.000000000 -0500
@@ -76,6 +76,7 @@
 char               *badtheme = NULL;
 char               *badreason = NULL;
 char               *e_machine_name = NULL;
+int                 current_keymap = 0;
 
 #ifdef DEBUG
 int                 call_level;
diff -ruwN e.orig/src/init.c e.chains/src/init.c
--- e.orig/src/init.c	2003-10-27 02:38:45.000000000 -0500
+++ e.chains/src/init.c	2003-10-27 07:45:37.000000000 -0500
@@ -46,13 +46,13 @@
    /* create a default fallback actionclass for the fallback border */
    ac = CreateAclass("__FALLBACK_ACTION");
    AddItem(ac, ac->name, 0, LIST_TYPE_ACLASS);
-   a = CreateAction(EVENT_MOUSE_DOWN, 1, 0, 0, 1, 0, NULL, NULL);
+   a = CreateAction(EVENT_MOUSE_DOWN, 1, 0, 0, 1, 0, 0, NULL, NULL);
    AddAction(ac, a);
    AddToAction(a, ACTION_MOVE, NULL);
-   a = CreateAction(EVENT_MOUSE_DOWN, 1, 0, 0, 2, 0, NULL, NULL);
+   a = CreateAction(EVENT_MOUSE_DOWN, 1, 0, 0, 2, 0, 0, NULL, NULL);
    AddAction(ac, a);
    AddToAction(a, ACTION_KILL, NULL);
-   a = CreateAction(EVENT_MOUSE_DOWN, 1, 0, 0, 3, 0, NULL, NULL);
+   a = CreateAction(EVENT_MOUSE_DOWN, 1, 0, 0, 3, 0, 0, NULL, NULL);
    AddAction(ac, a);
    AddToAction(a, ACTION_RESIZE, NULL);
 
diff -ruwN e.orig/src/themes/configs/definitions e.chains/src/themes/configs/definitions
--- e.orig/src/themes/configs/definitions	2003-10-27 02:38:45.000000000 -0500
+++ e.chains/src/themes/configs/definitions	2003-10-27 02:40:36.000000000 -0500
@@ -338,6 +338,7 @@
 #define __A_NEVERFOCUS 101
 #define __A_SKIPLISTS 102
 #define __A_SWAPMOVE 103
+#define __A_BEGIN_CHAIN 104
 
 #define __MODIFIER_KEY 101
 #define __TYPE 102
@@ -349,6 +350,7 @@
 #define __ALLOW_ANY_KEY 931
 #define __NEXT_ACTION 105
 #define __TOOLTIP_ACTION_TEXT 107
+#define __KEYMAP 108
 
 #define __NONE 0
 #define __SHIFT 900

Reply via email to