From d55f4b41c6ebf00e36a5e91ddc962a753f6c9ef8 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 14 Dec 2009 15:40:09 -0500 Subject: [PATCH] Allow the user to bind more than one keycode to a keysym for Ob Menus/Move/Resize If the user has escape bound to more than one keycode then they can use any of them to close a menu. This change applies to the hardcoded keys in openbox, which are used for the menus and for move/resize, and maybe other places. --- openbox/actions/cyclewindows.c | 4 ++-- openbox/actions/directionalwindows.c | 4 ++-- openbox/event.c | 12 +++++----- openbox/modkeys.c | 18 +++++++++++---- openbox/modkeys.h | 5 ++-- openbox/moveresize.c | 44 ++++++++++++++++++------------------ openbox/openbox.c | 21 ++++++++++++++--- openbox/openbox.h | 2 +- openbox/prompt.c | 16 ++++++------- 9 files changed, 74 insertions(+), 52 deletions(-) diff --git a/openbox/actions/cyclewindows.c b/openbox/actions/cyclewindows.c index 6fba17ff..32d6a453 100644 --- a/openbox/actions/cyclewindows.c +++ b/openbox/actions/cyclewindows.c @@ -146,13 +146,13 @@ static gboolean i_input_func(guint initial_state, { if (e->type == KeyPress) { /* Escape cancels no matter what */ - if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) { + if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) { end_cycle(TRUE, e->xkey.state, options); return FALSE; } /* There were no modifiers and they pressed enter */ - else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) && + else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) && !initial_state) { end_cycle(FALSE, e->xkey.state, options); diff --git a/openbox/actions/directionalwindows.c b/openbox/actions/directionalwindows.c index d9f24d61..6559e44c 100644 --- a/openbox/actions/directionalwindows.c +++ b/openbox/actions/directionalwindows.c @@ -169,13 +169,13 @@ static gboolean i_input_func(guint initial_state, { if (e->type == KeyPress) { /* Escape cancels no matter what */ - if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) { + if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) { end_cycle(TRUE, e->xkey.state, options); return FALSE; } /* There were no modifiers and they pressed enter */ - else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) && + else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) && !initial_state) { end_cycle(FALSE, e->xkey.state, options); diff --git a/openbox/event.c b/openbox/event.c index b4bd8270..881c9f8f 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -1693,30 +1693,30 @@ static gboolean event_handle_menu_keyboard(XEvent *ev) else if (ev->type == KeyPress && (state & ~ControlMask) == 0) { frame->got_press = TRUE; - if (keycode == ob_keycode(OB_KEY_ESCAPE)) { + if (ob_keycode_match(keycode, OB_KEY_ESCAPE)) { menu_frame_hide_all(); ret = TRUE; } - else if (keycode == ob_keycode(OB_KEY_LEFT)) { + else if (ob_keycode_match(keycode, OB_KEY_LEFT)) { /* Left goes to the parent menu */ if (frame->parent) menu_frame_select(frame, NULL, TRUE); ret = TRUE; } - else if (keycode == ob_keycode(OB_KEY_RIGHT)) { + else if (ob_keycode_match(keycode, OB_KEY_RIGHT)) { /* Right goes to the selected submenu */ if (frame->child) menu_frame_select_next(frame->child); ret = TRUE; } - else if (keycode == ob_keycode(OB_KEY_UP)) { + else if (ob_keycode_match(keycode, OB_KEY_UP)) { menu_frame_select_previous(frame); ret = TRUE; } - else if (keycode == ob_keycode(OB_KEY_DOWN)) { + else if (ob_keycode_match(keycode, OB_KEY_DOWN)) { menu_frame_select_next(frame); ret = TRUE; } @@ -1729,7 +1729,7 @@ static gboolean event_handle_menu_keyboard(XEvent *ev) else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 && frame->entries && frame->got_press) { - if (keycode == ob_keycode(OB_KEY_RETURN)) { + if (ob_keycode_match(keycode, OB_KEY_RETURN)) { /* Enter runs the active item or goes into the submenu. Control-Enter runs it without closing the menu. */ if (frame->child) diff --git a/openbox/modkeys.c b/openbox/modkeys.c index c52cbef1..e897ccb3 100644 --- a/openbox/modkeys.c +++ b/openbox/modkeys.c @@ -176,14 +176,22 @@ static void set_modkey_mask(guchar mask, KeySym sym) /* CapsLock, Shift, and Control are special and hard-coded */ } -KeyCode modkeys_sym_to_code(KeySym sym) +KeyCode* modkeys_sym_to_code(KeySym sym) { - gint i, j; + KeyCode *ret; + gint i, j, n; + + ret = g_new(KeyCode, 1); + n = 0; + ret[n] = 0; /* go through each keycode and look for the keysym */ for (i = min_keycode; i <= max_keycode; ++i) for (j = 0; j < keysyms_per_keycode; ++j) - if (sym == keymap[(i-min_keycode) * keysyms_per_keycode + j]) - return i; - return 0; + if (sym == keymap[(i-min_keycode) * keysyms_per_keycode + j]) { + ret = g_renew(KeyCode, ret, ++n); + ret[n-1] = i; + ret[n] = 0; + } + return ret; } diff --git a/openbox/modkeys.h b/openbox/modkeys.h index dc72f28e..8e795f78 100644 --- a/openbox/modkeys.h +++ b/openbox/modkeys.h @@ -53,8 +53,7 @@ guint modkeys_only_modifier_masks(guint mask); right keys when there are both. */ guint modkeys_key_to_mask(ObModkeysKey key); -/*! Convert a KeySym to a KeyCode, because the X function is terrible - says - valgrind. */ -KeyCode modkeys_sym_to_code(KeySym sym); +/*! Convert a KeySym to all the KeyCodes which generate it. */ +KeyCode* modkeys_sym_to_code(KeySym sym); #endif diff --git a/openbox/moveresize.c b/openbox/moveresize.c index f324818d..95d64734 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -601,13 +601,13 @@ static void move_with_keys(gint keycode, gint state) gint x, y; ObDirection dir; - if (keycode == ob_keycode(OB_KEY_RIGHT)) + if (ob_keycode_match(keycode, OB_KEY_RIGHT)) dir = OB_DIRECTION_EAST; - else if (keycode == ob_keycode(OB_KEY_LEFT)) + else if (ob_keycode_match(keycode, OB_KEY_LEFT)) dir = OB_DIRECTION_WEST; - else if (keycode == ob_keycode(OB_KEY_DOWN)) + else if (ob_keycode_match(keycode, OB_KEY_DOWN)) dir = OB_DIRECTION_SOUTH; - else /* if (keycode == ob_keycode(OB_KEY_UP)) */ + else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */ dir = OB_DIRECTION_NORTH; client_find_move_directional(moveresize_client, dir, &x, &y); @@ -620,13 +620,13 @@ static void move_with_keys(gint keycode, gint state) else dist = KEY_DIST; - if (keycode == ob_keycode(OB_KEY_RIGHT)) + if (ob_keycode_match(keycode, OB_KEY_RIGHT)) dx = dist; - else if (keycode == ob_keycode(OB_KEY_LEFT)) + else if (ob_keycode_match(keycode, OB_KEY_LEFT)) dx = -dist; - else if (keycode == ob_keycode(OB_KEY_DOWN)) + else if (ob_keycode_match(keycode, OB_KEY_DOWN)) dy = dist; - else /* if (keycode == ob_keycode(OB_KEY_UP)) */ + else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */ dy = -dist; } @@ -659,7 +659,7 @@ static void resize_with_keys(gint keycode, gint state) ObDirection dir; /* pick the edge if it needs to move */ - if (keycode == ob_keycode(OB_KEY_RIGHT)) { + if (ob_keycode_match(keycode, OB_KEY_RIGHT)) { dir = OB_DIRECTION_EAST; if (key_resize_edge != OB_DIRECTION_WEST && key_resize_edge != OB_DIRECTION_EAST) @@ -668,7 +668,7 @@ static void resize_with_keys(gint keycode, gint state) return; } } - if (keycode == ob_keycode(OB_KEY_LEFT)) { + if (ob_keycode_match(keycode, OB_KEY_LEFT)) { dir = OB_DIRECTION_WEST; if (key_resize_edge != OB_DIRECTION_WEST && key_resize_edge != OB_DIRECTION_EAST) @@ -677,7 +677,7 @@ static void resize_with_keys(gint keycode, gint state) return; } } - if (keycode == ob_keycode(OB_KEY_UP)) { + if (ob_keycode_match(keycode, OB_KEY_UP)) { dir = OB_DIRECTION_NORTH; if (key_resize_edge != OB_DIRECTION_NORTH && key_resize_edge != OB_DIRECTION_SOUTH) @@ -686,7 +686,7 @@ static void resize_with_keys(gint keycode, gint state) return; } } - if (keycode == ob_keycode(OB_KEY_DOWN)) { + if (ob_keycode_match(keycode, OB_KEY_DOWN)) { dir = OB_DIRECTION_SOUTH; if (key_resize_edge != OB_DIRECTION_NORTH && key_resize_edge != OB_DIRECTION_SOUTH) @@ -700,13 +700,13 @@ static void resize_with_keys(gint keycode, gint state) if (state & modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT)) { gint x, y, w, h; - if (keycode == ob_keycode(OB_KEY_RIGHT)) + if (ob_keycode_match(keycode, OB_KEY_RIGHT)) dir = OB_DIRECTION_EAST; - else if (keycode == ob_keycode(OB_KEY_LEFT)) + else if (ob_keycode_match(keycode, OB_KEY_LEFT)) dir = OB_DIRECTION_WEST; - else if (keycode == ob_keycode(OB_KEY_DOWN)) + else if (ob_keycode_match(keycode, OB_KEY_DOWN)) dir = OB_DIRECTION_SOUTH; - else /* if (keycode == ob_keycode(OB_KEY_UP)) */ + else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */ dir = OB_DIRECTION_NORTH; client_find_resize_directional(moveresize_client, key_resize_edge, @@ -901,16 +901,16 @@ gboolean moveresize_event(XEvent *e) } used = TRUE; } else if (e->type == KeyPress) { - if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) { + if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) { moveresize_end(TRUE); used = TRUE; - } else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN)) { + } else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN)) { moveresize_end(FALSE); used = TRUE; - } else if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT) || - e->xkey.keycode == ob_keycode(OB_KEY_LEFT) || - e->xkey.keycode == ob_keycode(OB_KEY_DOWN) || - e->xkey.keycode == ob_keycode(OB_KEY_UP)) + } else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RIGHT) || + ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) || + ob_keycode_match(e->xkey.keycode, OB_KEY_DOWN) || + ob_keycode_match(e->xkey.keycode, OB_KEY_UP)) { if (corner == prop_atoms.net_wm_moveresize_size_keyboard) { resize_with_keys(e->xkey.keycode, e->xkey.state); diff --git a/openbox/openbox.c b/openbox/openbox.c index 60e147c3..0e339782 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -104,7 +104,7 @@ static gboolean reconfigure = FALSE; static gboolean restart = FALSE; static gchar *restart_path = NULL; static Cursor cursors[OB_NUM_CURSORS]; -static KeyCode keys[OB_NUM_KEYS]; +static KeyCode *keys[OB_NUM_KEYS]; static gint exitcode = 0; static guint remote_control = 0; static gboolean being_replaced = FALSE; @@ -417,6 +417,17 @@ gint main(gint argc, gchar **argv) event_shutdown(reconfigure); config_shutdown(); actions_shutdown(reconfigure); + + /* Free the key codes for built in keys */ + g_free(keys[OB_KEY_RETURN]); + g_free(keys[OB_KEY_ESCAPE]); + g_free(keys[OB_KEY_LEFT]); + g_free(keys[OB_KEY_RIGHT]); + g_free(keys[OB_KEY_UP]); + g_free(keys[OB_KEY_DOWN]); + g_free(keys[OB_KEY_TAB]); + g_free(keys[OB_KEY_SPACE]); + modkeys_shutdown(reconfigure); } while (reconfigure); } @@ -732,10 +743,14 @@ Cursor ob_cursor(ObCursor cursor) return cursors[cursor]; } -KeyCode ob_keycode(ObKey key) +gboolean ob_keycode_match(KeyCode code, ObKey key) { + KeyCode *k; + g_assert(key < OB_NUM_KEYS); - return keys[key]; + for (k = keys[key]; *k; ++k) + if (*k == code) return TRUE; + return FALSE; } ObState ob_state() diff --git a/openbox/openbox.h b/openbox/openbox.h index 06d38297..76b04ea2 100644 --- a/openbox/openbox.h +++ b/openbox/openbox.h @@ -65,6 +65,6 @@ void ob_exit_with_error(const gchar *msg); Cursor ob_cursor(ObCursor cursor); -KeyCode ob_keycode(ObKey key); +gboolean ob_keycode_match(KeyCode code, ObKey key); #endif diff --git a/openbox/prompt.c b/openbox/prompt.c index 53ed2d7d..bef06a74 100644 --- a/openbox/prompt.c +++ b/openbox/prompt.c @@ -532,23 +532,23 @@ gboolean prompt_key_event(ObPrompt *self, XEvent *e) if (e->xkey.state != 0 && e->xkey.state != shift_mask) return FALSE; - if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) + if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) prompt_cancel(self); - else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) || - e->xkey.keycode == ob_keycode(OB_KEY_SPACE)) + else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) || + ob_keycode_match(e->xkey.keycode, OB_KEY_SPACE)) { prompt_run_callback(self, self->focus->result); } - else if (e->xkey.keycode == ob_keycode(OB_KEY_TAB) || - e->xkey.keycode == ob_keycode(OB_KEY_LEFT) || - e->xkey.keycode == ob_keycode(OB_KEY_RIGHT)) + else if (ob_keycode_match(e->xkey.keycode, OB_KEY_TAB) || + ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) || + ob_keycode_match(e->xkey.keycode, OB_KEY_RIGHT)) { gint i; gboolean left; ObPromptElement *oldfocus; - left = e->xkey.keycode == ob_keycode(OB_KEY_LEFT) || - (e->xkey.keycode == ob_keycode(OB_KEY_TAB) && shift); + left = ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) || + (ob_keycode_match(e->xkey.keycode, OB_KEY_TAB) && shift); oldfocus = self->focus; for (i = 0; i < self->n_buttons; ++i) -- 2.11.4.GIT