fix a crash from chroot of invalid keys, and make keybindings reload better

since invalid(not translated) keybindings are allowed in the tree, the tree's structure may actually need to change when reconfiguring.  actually, it could need to anyways.  so when re-translating all the keybindings, actually rebuild the keybinding tree.  also, make the chroot building code not fail when translate fails, to match the rest of the code and avoid segfaults with chroots on invalid keys.
This commit is contained in:
Dana Jansens 2008-02-02 00:59:59 -05:00
parent 6a3ac556b9
commit 3b0f41dc66
3 changed files with 47 additions and 19 deletions

View file

@ -265,9 +265,46 @@ void keyboard_event(ObClient *client, const XEvent *e)
}
}
static void node_rebind(KeyBindingTree *node)
{
if (node->first_child) {
/* find leaf nodes */
node_rebind(node->first_child);
/* for internal nodes, add them to the tree if they
are a chroot, but do this after adding their
children */
if (node->chroot)
keyboard_chroot(node->keylist);
}
else {
/* for leaf nodes, rebind each action assigned to it */
GSList *it;
while (node->actions) {
/* add each action, and remove them from the original tree so
they don't get free'd on us */
keyboard_bind(node->keylist, node->actions->data);
node->actions = g_slist_delete_link(node->actions, node->actions);
}
if (node->chroot)
keyboard_chroot(node->keylist);
}
/* go through each sibling */
if (node->next_sibling) node_rebind(node->next_sibling);
}
void keyboard_rebind(void)
{
tree_rebind(keyboard_firstnode);
KeyBindingTree *old;
old = keyboard_firstnode;
keyboard_firstnode = NULL;
node_rebind(old);
tree_destroy(old);
set_curpos(NULL);
grab_keys(TRUE);
}

View file

@ -68,13 +68,6 @@ KeyBindingTree *tree_build(GList *keylist)
return ret;
}
void tree_rebind(KeyBindingTree *node) {
GList *it = g_list_last(node->keylist);
translate_key(it->data, &node->state, &node->key);
if (node->next_sibling) tree_rebind(node->next_sibling);
if (node->first_child) tree_rebind(node->first_child);
}
void tree_assimilate(KeyBindingTree *node)
{
KeyBindingTree *a, *b, *tmp, *last;
@ -139,7 +132,7 @@ KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict)
gboolean tree_chroot(KeyBindingTree *tree, GList *keylist)
{
guint key, state;
if (translate_key(keylist->data, &state, &key)) {
translate_key(keylist->data, &state, &key);
while (tree != NULL && !(tree->state == state && tree->key == key))
tree = tree->next_sibling;
if (tree != NULL) {
@ -149,6 +142,5 @@ gboolean tree_chroot(KeyBindingTree *tree, GList *keylist)
} else
return tree_chroot(tree->first_child, keylist->next);
}
}
return FALSE;
}

View file

@ -41,7 +41,6 @@ KeyBindingTree *tree_build(GList *keylist);
void tree_assimilate(KeyBindingTree *node);
KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict);
gboolean tree_chroot(KeyBindingTree *tree, GList *keylist);
void tree_rebind(KeyBindingTree *node);
#endif