summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions.c44
-rw-r--r--src/conf.h3
-rw-r--r--src/events.c55
-rw-r--r--src/globals.c4
-rw-r--r--src/globals.h2
-rw-r--r--src/input.c2
-rw-r--r--src/manage.c61
-rw-r--r--src/manage.h6
8 files changed, 130 insertions, 47 deletions
diff --git a/src/actions.c b/src/actions.c
index 79e290e..e74a7f6 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -362,11 +362,14 @@ add_alias (char *name, char *alias)
void
initialize_default_keybindings (void)
{
- rp_keymap *map;
+ rp_keymap *map, *top;
map = keymap_new (ROOT_KEYMAP);
list_add (&map->node, &rp_keymaps);
+ top = keymap_new (TOP_KEYMAP);
+ list_add (&top->node, &rp_keymaps);
+
/* Initialive the alias list. */
alias_list_size = 5;
alias_list_last = 0;
@@ -375,6 +378,9 @@ initialize_default_keybindings (void)
prefix_key.sym = KEY_PREFIX;
prefix_key.state = MODIFIER_PREFIX;
+ /* Add the prefix key to the top-level map. */
+ add_keybinding (prefix_key.sym, prefix_key.state, "readkey " ROOT_KEYMAP, top);
+
add_keybinding (prefix_key.sym, prefix_key.state, "other", map);
add_keybinding (prefix_key.sym, 0, "meta", map);
add_keybinding (XK_g, RP_CONTROL_MASK, "abort", map);
@@ -697,6 +703,11 @@ cmd_definekey (int interactive, char *data)
free (tmp);
}
+ /* If we're updating the top level map, we'll need to update the
+ keys grabbed. */
+ if (map == find_keymap (TOP_KEYMAP))
+ ungrab_keys_all_wins ();
+
if (!cmd || !*cmd)
{
/* If no comand is specified, then unbind the key. */
@@ -713,6 +724,11 @@ cmd_definekey (int interactive, char *data)
add_keybinding (key->sym, key->state, cmd, map);
}
+ /* Update the grabbed keys. */
+ if (map == find_keymap (TOP_KEYMAP))
+ grab_keys_all_wins ();
+ XSync (dpy, False);
+
free (keydesc);
if (cmd)
free (cmd);
@@ -1504,11 +1520,11 @@ cmd_redisplay (int interactive, char *data)
char *
cmd_escape (int interactive, char *data)
{
- rp_window *cur;
struct rp_key *key;
rp_action *action;
- rp_keymap *map;
+ rp_keymap *map, *top;
+ top = find_keymap (TOP_KEYMAP);
map = find_keymap (ROOT_KEYMAP);
key = parse_keydesc (data);
@@ -1531,19 +1547,21 @@ cmd_escape (int interactive, char *data)
}
/* Remove the grab on the current prefix key */
- list_for_each_entry (cur, &rp_mapped_window, node)
+ ungrab_keys_all_wins();
+
+ action = find_keybinding(prefix_key.sym, prefix_key.state, top);
+ if (action != NULL && !strcmp (action->data, "readkey " ROOT_KEYMAP))
{
- ungrab_prefix_key (cur->w);
+ action->key = key->sym;
+ action->state = key->state;
}
+ /* Add the grab for the new prefix key */
+ grab_keys_all_wins();
+
+ /* Finally, keep track of the current prefix. */
prefix_key.sym = key->sym;
prefix_key.state = key->state;
-
- /* Add the grab for the new prefix key */
- list_for_each_entry (cur,&rp_mapped_window,node)
- {
- grab_prefix_key (cur->w);
- }
}
else
{
@@ -4126,9 +4144,9 @@ cmd_delkmap (int interactive, char *data)
return NULL;
}
- if (!strcmp (data, ROOT_KEYMAP))
+ if (!strcmp (data, ROOT_KEYMAP) || !strcmp (data, TOP_KEYMAP))
{
- message (" delkmap: Cannot delete '" ROOT_KEYMAP "' keymap ");
+ marked_message_printf (0, 0, " delkmap: Cannot delete '%s' keymap ", data);
return NULL;
}
diff --git a/src/conf.h b/src/conf.h
index 32d0f8e..a6128f0 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -112,4 +112,7 @@
/* The name of the root keymap */
#define ROOT_KEYMAP "root"
+/* The name of the top level keymap */
+#define TOP_KEYMAP "top"
+
#endif /* !_ _RATPOISON_CONF_H */
diff --git a/src/events.c b/src/events.c
index 2498be2..d4520ca 100644
--- a/src/events.c
+++ b/src/events.c
@@ -362,8 +362,17 @@ client_msg (XClientMessageEvent *ev)
}
static void
-handle_key (rp_screen *s)
+handle_key (KeySym ks, unsigned int mod, rp_screen *s)
{
+ rp_action *key_action;
+ rp_keymap *map = find_keymap (TOP_KEYMAP);
+
+ if (map == NULL)
+ {
+ PRINT_ERROR (("Unable to find " TOP_KEYMAP " keymap\n"));
+ return;
+ }
+
PRINT_DEBUG (("handling key...\n"));
/* All functions hide the program bar and the frame indicator. */
@@ -374,12 +383,26 @@ handle_key (rp_screen *s)
alarm (0);
alarm_signalled = 0;
- /* Call the prefix hook. */
- hook_run (&rp_prefix_hook);
+ /* Call the top level key pressed hook. */
+ hook_run (&rp_key_hook);
+
+ PRINT_DEBUG (("handle_key\n"));
/* Read a key and execute the command associated with it on the
- default keymap. */
- cmd_readkey (1, ROOT_KEYMAP);
+ default keymap. Ignore the key if it doesn't have a binding. */
+ if ((key_action = find_keybinding (ks, x11_mask_to_rp_mask (mod), map)))
+ {
+ char *result;
+ result = command (1, key_action->data);
+
+ /* Gobble the result. */
+ if (result)
+ free (result);
+ }
+ else
+ {
+ PRINT_ERROR(("Impossible: No matching key\n"));
+ }
}
static void
@@ -403,21 +426,7 @@ key_press (XEvent *ev)
modifier = ev->xkey.state;
cook_keycode ( &ev->xkey, &ks, &modifier, NULL, 0, 1);
- if (ks == prefix_key.sym && (x11_mask_to_rp_mask (modifier) == prefix_key.state))
- {
- handle_key (s);
- }
- else
- {
- if (current_window())
- {
- ignore_badwindow++;
- ev->xkey.window = current_window()->w;
- XSendEvent (dpy, current_window()->w, False, KeyPressMask, ev);
- XSync (dpy, False);
- ignore_badwindow--;
- }
- }
+ handle_key (ks, modifier, s);
}
/* Read a command off the window and execute it. Some commands return
@@ -630,7 +639,7 @@ focus_change (XFocusChangeEvent *ev)
if (win != NULL)
{
PRINT_DEBUG (("Re-grabbing prefix key\n"));
- grab_prefix_key (win->w);
+ grab_top_level_keys (win->w);
}
}
@@ -642,7 +651,7 @@ mapping_notify (XMappingEvent *ev)
/* Remove the grab on the current prefix key */
list_for_each_entry (cur,&rp_mapped_window,node)
{
- ungrab_prefix_key (cur->w);
+ ungrab_top_level_keys (cur->w);
}
switch (ev->request)
@@ -658,7 +667,7 @@ mapping_notify (XMappingEvent *ev)
/* Add the grab on the current prefix key */
list_for_each_entry (cur, &rp_mapped_window,node)
{
- grab_prefix_key (cur->w);
+ grab_top_level_keys (cur->w);
}
}
diff --git a/src/globals.c b/src/globals.c
index c9c02cc..f23eb9c 100644
--- a/src/globals.c
+++ b/src/globals.c
@@ -72,7 +72,7 @@ struct numset *rp_frame_numset;
/* The hook dictionary globals. */
-LIST_HEAD (rp_prefix_hook);
+LIST_HEAD (rp_key_hook);
LIST_HEAD (rp_switch_win_hook);
LIST_HEAD (rp_switch_frame_hook);
LIST_HEAD (rp_switch_group_hook);
@@ -80,7 +80,7 @@ LIST_HEAD (rp_quit_hook);
LIST_HEAD (rp_restart_hook);
struct rp_hook_db_entry rp_hook_db[]=
- {{"prefix", &rp_prefix_hook},
+ {{"key", &rp_key_hook},
{"switchwin", &rp_switch_win_hook},
{"switchframe", &rp_switch_frame_hook},
{"switchgroup", &rp_switch_group_hook},
diff --git a/src/globals.h b/src/globals.h
index 4cd6ae4..063abc3 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -129,7 +129,7 @@ extern char *rp_error_msg;
/* Number sets for windows. */
extern struct numset *rp_window_numset;
-extern struct list_head rp_prefix_hook;
+extern struct list_head rp_key_hook;
extern struct list_head rp_switch_win_hook;
extern struct list_head rp_switch_frame_hook;
extern struct list_head rp_switch_group_hook;
diff --git a/src/input.c b/src/input.c
index ab52931..5b94c78 100644
--- a/src/input.c
+++ b/src/input.c
@@ -66,7 +66,7 @@ rp_mask_to_x11_mask (unsigned int mask)
result |= mask & RP_HYPER_MASK ? rp_modifier_info.hyper_mod_mask:0;
result |= mask & RP_SUPER_MASK ? rp_modifier_info.super_mod_mask:0;
- PRINT_DEBUG (("x11 mask = %x\n", mask));
+ PRINT_DEBUG (("x11 mask = %x\n", result));
return result;
}
diff --git a/src/manage.c b/src/manage.c
index d7ed545..46e174e 100644
--- a/src/manage.c
+++ b/src/manage.c
@@ -103,25 +103,76 @@ add_unmanaged_window (char *name)
extern Atom wm_state;
void
-grab_prefix_key (Window w)
+grab_top_level_keys (Window w)
{
#ifdef HIDE_MOUSE
XGrabKey(dpy, AnyKey, AnyModifier, w, True,
GrabModeAsync, GrabModeAsync);
#else
- grab_key (XKeysymToKeycode (dpy, prefix_key.sym), prefix_key.state, w);
+ rp_keymap *map = find_keymap (TOP_KEYMAP);
+ int i;
+
+ if (map == NULL)
+ {
+ PRINT_ERROR (("Unable to find " TOP_KEYMAP " keymap\n"));
+ return;
+ }
+
+ PRINT_DEBUG(("grabbing top level key\n"));
+ for (i=0; i<map->actions_last; i++)
+ {
+ PRINT_DEBUG(("%d\n", i));
+ grab_key (XKeysymToKeycode (dpy, map->actions[i].key), map->actions[i].state, w);
+ }
#endif
}
void
-ungrab_prefix_key (Window w)
+ungrab_top_level_keys (Window w)
{
#ifdef HIDE_MOUSE
#else
- XUngrabKey(dpy, XKeysymToKeycode (dpy, prefix_key.sym), AnyModifier, w);
+ rp_keymap *map = find_keymap (TOP_KEYMAP);
+ int i;
+
+ if (map == NULL)
+ {
+ PRINT_ERROR (("Unable to find " TOP_KEYMAP " keymap\n"));
+ return;
+ }
+
+ for (i=0; i<map->actions_last; i++)
+ {
+ PRINT_DEBUG(("%d\n", i));
+ XUngrabKey(dpy, XKeysymToKeycode (dpy, map->actions[i].key), AnyModifier, w);
+ }
#endif
}
+void
+ungrab_keys_all_wins ()
+{
+ rp_window *cur;
+
+ /* Remove the grab on the current prefix key */
+ list_for_each_entry (cur, &rp_mapped_window, node)
+ {
+ ungrab_top_level_keys (cur->w);
+ }
+}
+
+void
+grab_keys_all_wins ()
+{
+ rp_window *cur;
+
+ /* Remove the grab on the current prefix key */
+ list_for_each_entry (cur, &rp_mapped_window, node)
+ {
+ grab_top_level_keys (cur->w);
+ }
+}
+
rp_screen*
current_screen ()
{
@@ -735,7 +786,7 @@ map_window (rp_window *win)
/* Fill in the necessary data about the window */
update_window_information (win);
win->number = numset_request (rp_window_numset);
- grab_prefix_key (win->w);
+ grab_top_level_keys (win->w);
/* Put win in the mapped window list */
list_del (&win->node);
diff --git a/src/manage.h b/src/manage.h
index 3d51ebf..cfd44ed 100644
--- a/src/manage.h
+++ b/src/manage.h
@@ -44,8 +44,10 @@ void map_window (rp_window *win);
void maximize (rp_window *win);
void force_maximize (rp_window *win);
-void grab_prefix_key (Window w);
-void ungrab_prefix_key (Window w);
+void grab_top_level_keys (Window w);
+void ungrab_top_level_keys (Window w);
+void ungrab_keys_all_wins ();
+void grab_keys_all_wins ();
void hide_window (rp_window *win);
void unhide_window (rp_window *win);