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