add chrooting. use chroot="true" on the chroot location
This commit is contained in:
parent
1ee98f4a47
commit
b6d2529acb
5 changed files with 107 additions and 46 deletions
|
@ -273,47 +273,59 @@ static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
||||||
GList *keylist)
|
GList *keylist)
|
||||||
{
|
{
|
||||||
gchar *key;
|
gchar *key;
|
||||||
ObAction *action;
|
xmlNodePtr n;
|
||||||
xmlNodePtr n, nact;
|
gboolean is_chroot = FALSE;
|
||||||
GList *it;
|
|
||||||
|
|
||||||
if ((n = parse_find_node("chainQuitKey", node))) {
|
if (!parse_attr_string("key", node, &key))
|
||||||
|
return;
|
||||||
|
parse_attr_bool("chroot", node, &is_chroot);
|
||||||
|
|
||||||
|
keylist = g_list_append(keylist, key);
|
||||||
|
|
||||||
|
/* a node either contains actions or key bindings */
|
||||||
|
if ((n = parse_find_node("keybind", node->children))) {
|
||||||
|
while (n) {
|
||||||
|
parse_key(i, doc, n, keylist);
|
||||||
|
n = parse_find_node("keybind", n->next);
|
||||||
|
}
|
||||||
|
} else if ((n = parse_find_node("action", node->children))) {
|
||||||
|
while (n) {
|
||||||
|
ObAction *action;
|
||||||
|
|
||||||
|
action = action_parse(i, doc, n, OB_USER_ACTION_KEYBOARD_KEY);
|
||||||
|
if (action)
|
||||||
|
keyboard_bind(keylist, action);
|
||||||
|
n = parse_find_node("action", n->next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_chroot)
|
||||||
|
keyboard_chroot(keylist);
|
||||||
|
|
||||||
|
g_free(key);
|
||||||
|
keylist = g_list_delete_link(keylist, g_list_last(keylist));
|
||||||
|
|
||||||
|
/* go to next sibling */
|
||||||
|
if (node->next) parse_key(i, doc, node->next, keylist);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
||||||
|
gpointer d)
|
||||||
|
{
|
||||||
|
xmlNodePtr n;
|
||||||
|
gchar *key;
|
||||||
|
|
||||||
|
keyboard_unbind_all();
|
||||||
|
|
||||||
|
if ((n = parse_find_node("chainQuitKey", node->children))) {
|
||||||
key = parse_string(doc, n);
|
key = parse_string(doc, n);
|
||||||
translate_key(key, &config_keyboard_reset_state,
|
translate_key(key, &config_keyboard_reset_state,
|
||||||
&config_keyboard_reset_keycode);
|
&config_keyboard_reset_keycode);
|
||||||
g_free(key);
|
g_free(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
n = parse_find_node("keybind", node);
|
if ((n = parse_find_node("keybind", node->children)))
|
||||||
while (n) {
|
parse_key(i, doc, n, NULL);
|
||||||
if (parse_attr_string("key", n, &key)) {
|
|
||||||
keylist = g_list_append(keylist, key);
|
|
||||||
|
|
||||||
parse_key(i, doc, n->children, keylist);
|
|
||||||
|
|
||||||
it = g_list_last(keylist);
|
|
||||||
g_free(it->data);
|
|
||||||
keylist = g_list_delete_link(keylist, it);
|
|
||||||
}
|
|
||||||
n = parse_find_node("keybind", n->next);
|
|
||||||
}
|
|
||||||
if (keylist) {
|
|
||||||
nact = parse_find_node("action", node);
|
|
||||||
while (nact) {
|
|
||||||
if ((action = action_parse(i, doc, nact,
|
|
||||||
OB_USER_ACTION_KEYBOARD_KEY)))
|
|
||||||
keyboard_bind(keylist, action);
|
|
||||||
nact = parse_find_node("action", nact->next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
|
||||||
gpointer d)
|
|
||||||
{
|
|
||||||
keyboard_unbind_all();
|
|
||||||
|
|
||||||
parse_key(i, doc, node->children, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -106,10 +106,18 @@ static void set_curpos(KeyBindingTree *newpos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_reset_chains()
|
void keyboard_reset_chains(gint break_chroots)
|
||||||
{
|
{
|
||||||
if (curpos)
|
KeyBindingTree *p;
|
||||||
set_curpos(NULL);
|
|
||||||
|
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()
|
void keyboard_unbind_all()
|
||||||
|
@ -118,6 +126,19 @@ void keyboard_unbind_all()
|
||||||
keyboard_firstnode = NULL;
|
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)
|
gboolean keyboard_bind(GList *keylist, ObAction *action)
|
||||||
{
|
{
|
||||||
KeyBindingTree *tree, *t;
|
KeyBindingTree *tree, *t;
|
||||||
|
@ -206,7 +227,6 @@ void keyboard_interactive_end(ObInteractiveState *s,
|
||||||
if (!interactive_states) {
|
if (!interactive_states) {
|
||||||
grab_keyboard(FALSE);
|
grab_keyboard(FALSE);
|
||||||
grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
|
grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
|
||||||
keyboard_reset_chains();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +287,7 @@ void keyboard_event(ObClient *client, const XEvent *e)
|
||||||
if (e->xkey.keycode == config_keyboard_reset_keycode &&
|
if (e->xkey.keycode == config_keyboard_reset_keycode &&
|
||||||
e->xkey.state == config_keyboard_reset_state)
|
e->xkey.state == config_keyboard_reset_state)
|
||||||
{
|
{
|
||||||
keyboard_reset_chains();
|
keyboard_reset_chains(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,11 +299,12 @@ void keyboard_event(ObClient *client, const XEvent *e)
|
||||||
if (p->key == e->xkey.keycode &&
|
if (p->key == e->xkey.keycode &&
|
||||||
p->state == e->xkey.state)
|
p->state == e->xkey.state)
|
||||||
{
|
{
|
||||||
if (p->first_child != NULL) { /* part of a chain */
|
if (p->first_child != NULL) /* part of a chain */
|
||||||
set_curpos(p);
|
set_curpos(p);
|
||||||
} else {
|
else if (p->chroot) /* an empty chroot */
|
||||||
|
set_curpos(p);
|
||||||
keyboard_reset_chains();
|
else {
|
||||||
|
keyboard_reset_chains(0);
|
||||||
|
|
||||||
action_run_key(p->actions, client, e->xkey.state,
|
action_run_key(p->actions, client, e->xkey.state,
|
||||||
e->xkey.x_root, e->xkey.y_root,
|
e->xkey.x_root, e->xkey.y_root,
|
||||||
|
|
|
@ -34,11 +34,14 @@ extern KeyBindingTree *keyboard_firstnode;
|
||||||
void keyboard_startup(gboolean reconfig);
|
void keyboard_startup(gboolean reconfig);
|
||||||
void keyboard_shutdown(gboolean reconfig);
|
void keyboard_shutdown(gboolean reconfig);
|
||||||
|
|
||||||
|
void keyboard_chroot(GList *keylist);
|
||||||
gboolean keyboard_bind(GList *keylist, ObAction *action);
|
gboolean keyboard_bind(GList *keylist, ObAction *action);
|
||||||
void keyboard_unbind_all();
|
void keyboard_unbind_all();
|
||||||
|
|
||||||
void keyboard_event(struct _ObClient *client, const XEvent *e);
|
void keyboard_event(struct _ObClient *client, const XEvent *e);
|
||||||
void keyboard_reset_chains();
|
/*! @param break_chroots how many chroots to break. -1 means to break them ALL!
|
||||||
|
*/
|
||||||
|
void keyboard_reset_chains(gint break_chroots);
|
||||||
|
|
||||||
gboolean keyboard_interactive_grab(guint state, struct _ObClient *client,
|
gboolean keyboard_interactive_grab(guint state, struct _ObClient *client,
|
||||||
struct _ObAction *action);
|
struct _ObAction *action);
|
||||||
|
|
|
@ -61,6 +61,7 @@ KeyBindingTree *tree_build(GList *keylist)
|
||||||
ret->keylist = g_list_prepend(ret->keylist,
|
ret->keylist = g_list_prepend(ret->keylist,
|
||||||
g_strdup(kit->data)); /* deep copy */
|
g_strdup(kit->data)); /* deep copy */
|
||||||
ret->first_child = p;
|
ret->first_child = p;
|
||||||
|
if (p != NULL) p->parent = ret;
|
||||||
if (!translate_key(it->data, &ret->state, &ret->key)) {
|
if (!translate_key(it->data, &ret->state, &ret->key)) {
|
||||||
tree_destroy(ret);
|
tree_destroy(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -91,10 +92,12 @@ void tree_assimilate(KeyBindingTree *node)
|
||||||
a = a->first_child;
|
a = a->first_child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(last->state == b->state && last->key == b->key))
|
if (!(last->state == b->state && last->key == b->key)) {
|
||||||
last->next_sibling = b;
|
last->next_sibling = b;
|
||||||
else {
|
b->parent = last->parent;
|
||||||
|
} else {
|
||||||
last->first_child = b->first_child;
|
last->first_child = b->first_child;
|
||||||
|
last->first_child->parent = last;
|
||||||
g_free(b);
|
g_free(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,3 +130,20 @@ KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict)
|
||||||
}
|
}
|
||||||
return NULL; /* it just isn't in here */
|
return NULL; /* it just isn't in here */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean tree_chroot(KeyBindingTree *tree, GList *keylist)
|
||||||
|
{
|
||||||
|
if (keylist == NULL) {
|
||||||
|
tree->chroot = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
guint key, state;
|
||||||
|
if (translate_key(keylist->data, &state, &key)) {
|
||||||
|
while (tree != NULL && !(tree->state == state && tree->key == key))
|
||||||
|
tree = tree->next_sibling;
|
||||||
|
if (tree != NULL)
|
||||||
|
return tree_chroot(tree, keylist->next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
|
@ -28,7 +28,10 @@ typedef struct KeyBindingTree {
|
||||||
guint key;
|
guint key;
|
||||||
GList *keylist;
|
GList *keylist;
|
||||||
GSList *actions; /* list of Action pointers */
|
GSList *actions; /* list of Action pointers */
|
||||||
|
gboolean chroot;
|
||||||
|
|
||||||
|
/* the level up in the tree */
|
||||||
|
struct KeyBindingTree *parent;
|
||||||
/* the next binding in the tree at the same level */
|
/* the next binding in the tree at the same level */
|
||||||
struct KeyBindingTree *next_sibling;
|
struct KeyBindingTree *next_sibling;
|
||||||
/* the first child of this binding (next binding in a chained sequence).*/
|
/* the first child of this binding (next binding in a chained sequence).*/
|
||||||
|
@ -39,5 +42,7 @@ void tree_destroy(KeyBindingTree *tree);
|
||||||
KeyBindingTree *tree_build(GList *keylist);
|
KeyBindingTree *tree_build(GList *keylist);
|
||||||
void tree_assimilate(KeyBindingTree *node);
|
void tree_assimilate(KeyBindingTree *node);
|
||||||
KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict);
|
KeyBindingTree *tree_find(KeyBindingTree *search, gboolean *conflict);
|
||||||
|
gboolean tree_chroot(KeyBindingTree *tree, GList *keylist);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue