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", ¤t_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