diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/actions.c | 44 | ||||
-rw-r--r-- | src/conf.h | 3 | ||||
-rw-r--r-- | src/events.c | 55 | ||||
-rw-r--r-- | src/globals.c | 4 | ||||
-rw-r--r-- | src/globals.h | 2 | ||||
-rw-r--r-- | src/input.c | 2 | ||||
-rw-r--r-- | src/manage.c | 61 | ||||
-rw-r--r-- | src/manage.h | 6 |
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; } @@ -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); |