}
}
+static gboolean chain_timeout(gpointer data)
+{
+ keyboard_reset_chains(0);
+ return FALSE; /* don't repeat */
+}
+
static gboolean popup_show_timeout(gpointer data)
{
gchar *text = data;
gchar *text = NULL;
GList *it;
- for (it = curpos->keylist; it; it = g_list_next(it))
- text = g_strconcat((text ? text : ""), it->data, "-", NULL);
+ for (it = curpos->keylist; it; it = g_list_next(it)) {
+ gchar *oldtext = text;
+ if (text == NULL)
+ text = g_strdup(it->data);
+ else
+ text = g_strconcat(text, " - ", it->data, NULL);
+ g_free(oldtext);
+ }
popup_position(popup, NorthWestGravity, 10, 10);
if (popup->mapped) {
g_free(text);
} else {
ob_main_loop_timeout_remove(ob_main_loop, popup_show_timeout);
- ob_main_loop_timeout_add(ob_main_loop, 1 * G_USEC_PER_SEC,
+ /* 1 second delay for the popup to show */
+ ob_main_loop_timeout_add(ob_main_loop, G_USEC_PER_SEC,
popup_show_timeout, text,
g_direct_equal, g_free);
}
}
}
-void keyboard_reset_chains()
+void keyboard_reset_chains(gint break_chroots)
{
- if (curpos)
- set_curpos(NULL);
+ KeyBindingTree *p;
+
+ for (p = curpos; p; p = p->parent) {
+ if (p->chroot) {
+ if (break_chroots == 0) break; /* stop here */
+ if (break_chroots > 0)
+ --break_chroots;
+ }
+ }
+ set_curpos(p);
}
void keyboard_unbind_all()
keyboard_firstnode = NULL;
}
+void keyboard_chroot(GList *keylist)
+{
+ /* try do it in the existing tree. if we can't that means it is an empty
+ chroot binding. so add it to the tree then. */
+ if (!tree_chroot(keyboard_firstnode, keylist)) {
+ KeyBindingTree *tree;
+ if (!(tree = tree_build(keylist)))
+ return;
+ tree_chroot(tree, keylist);
+ tree_assimilate(tree);
+ }
+}
+
gboolean keyboard_bind(GList *keylist, ObAction *action)
{
KeyBindingTree *tree, *t;
if (!interactive_states) {
grab_keyboard(FALSE);
grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
- keyboard_reset_chains();
}
}
if (e->xkey.keycode == config_keyboard_reset_keycode &&
e->xkey.state == config_keyboard_reset_state)
{
- keyboard_reset_chains();
+ ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
+ keyboard_reset_chains(-1);
return;
}
p->state == e->xkey.state)
{
if (p->first_child != NULL) { /* part of a chain */
+ ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
+ /* 3 second timeout for chains */
+ ob_main_loop_timeout_add(ob_main_loop, 3 * G_USEC_PER_SEC,
+ chain_timeout, NULL,
+ g_direct_equal, NULL);
set_curpos(p);
- } else {
-
- keyboard_reset_chains();
+ } else if (p->chroot) /* an empty chroot */
+ set_curpos(p);
+ else {
+ keyboard_reset_chains(0);
action_run_key(p->actions, client, e->xkey.state,
e->xkey.x_root, e->xkey.y_root,
g_slist_free(interactive_states);
interactive_states = NULL;
+ ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
ob_main_loop_timeout_remove(ob_main_loop, popup_show_timeout);
keyboard_unbind_all();