From 096dad0c6c027100494ede811b33cb8558d32e25 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 11 Feb 2010 15:05:16 -0500 Subject: [PATCH] make control keys work in menus/dialogs/etc with the new obt code, using XLookup stuff --- obt/keyboard.c | 28 +++++++++++--- obt/keyboard.h | 7 +++- openbox/actions/cyclewindows.c | 8 ++-- openbox/actions/desktop.c | 10 ++--- openbox/actions/directionalwindows.c | 8 ++-- openbox/event.c | 51 ++++++++++++------------ openbox/misc.h | 15 ------- openbox/moveresize.c | 58 ++++++++++++++-------------- openbox/openbox.c | 38 ------------------ openbox/openbox.h | 3 -- openbox/prompt.c | 18 ++++----- 11 files changed, 101 insertions(+), 143 deletions(-) diff --git a/obt/keyboard.c b/obt/keyboard.c index 82161e59..5e218429 100644 --- a/obt/keyboard.c +++ b/obt/keyboard.c @@ -281,7 +281,7 @@ KeyCode* obt_keyboard_keysym_to_keycode(KeySym sym) return ret; } -gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XKeyPressedEvent *ev) +gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XEvent *ev) { gunichar unikey = 0; KeySym sym; @@ -290,6 +290,8 @@ gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XKeyPressedEvent *ev) gint len, bufsz; gboolean got_string = FALSE; + g_return_val_if_fail(ev->type == KeyPress, 0); + if (!ic) g_warning("Using obt_keyboard_keypress_to_unichar() without an " "Input Context. No i18n support!"); @@ -299,9 +301,9 @@ gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XKeyPressedEvent *ev) bufsz = sizeof(fixbuf); #ifdef X_HAVE_UTF8_STRING - len = Xutf8LookupString(ic->xic, ev, buf, bufsz, &sym, &status); + len = Xutf8LookupString(ic->xic, &ev->xkey, buf, bufsz, &sym, &status); #else - len = XmbLookupString(ic->xic, ev, buf, bufsz, &sym, &status); + len = XmbLookupString(ic->xic, &ev->xkey, buf, bufsz, &sym, &status); #endif if (status == XBufferOverflow) { @@ -309,9 +311,11 @@ gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XKeyPressedEvent *ev) bufsz = len; #ifdef X_HAVE_UTF8_STRING - len = Xutf8LookupString(ic->xic, ev, buf, bufsz, &sym, &status); + len = Xutf8LookupString(ic->xic, &ev->xkey, buf, bufsz, &sym, + &status); #else - len = XmbLookupString(ic->xic, ev, buf, bufsz, &sym, &status); + len = XmbLookupString(ic->xic, &ev->xkey, buf, bufsz, &sym, + &status); #endif } @@ -338,7 +342,7 @@ gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XKeyPressedEvent *ev) else { buf = fixbuf; bufsz = sizeof(fixbuf); - len = XLookupString(ev, buf, bufsz, &sym, NULL); + len = XLookupString(&ev->xkey, buf, bufsz, &sym, NULL); if ((guchar)buf[0] >= 32) /* not an ascii control character */ got_string = TRUE; } @@ -354,6 +358,18 @@ gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XKeyPressedEvent *ev) return unikey; } +KeySym obt_keyboard_keypress_to_keysym(XEvent *ev) +{ + KeySym sym; + gint r; + + g_return_val_if_fail(ev->type == KeyPress, None); + + sym = None; + r = XLookupString(&ev->xkey, NULL, 0, &sym, NULL); + return sym; +} + void obt_keyboard_context_renew(ObtIC *ic) { if (ic->xic) { diff --git a/obt/keyboard.h b/obt/keyboard.h index 902f95b8..143921ff 100644 --- a/obt/keyboard.h +++ b/obt/keyboard.h @@ -21,6 +21,7 @@ #include #include +#include G_BEGIN_DECLS @@ -60,7 +61,11 @@ guint obt_keyboard_modkey_to_modmask(ObtModkeysKey key); KeyCode* obt_keyboard_keysym_to_keycode(KeySym sym); /*! Translate a KeyPress event to the unicode character it represents */ -gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XKeyPressedEvent *ev); +gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XEvent *ev); + +/*! Translate a KeyPress event to the KeySym that it represents. Use this + for control keys, not for getting text input! */ +KeySym obt_keyboard_keypress_to_keysym(XEvent *ev); /*! Create an input context for a window. @client The top-level client window for the input context. diff --git a/openbox/actions/cyclewindows.c b/openbox/actions/cyclewindows.c index 782a4c60..52349091 100644 --- a/openbox/actions/cyclewindows.c +++ b/openbox/actions/cyclewindows.c @@ -185,17 +185,17 @@ static gboolean i_input_func(guint initial_state, } if (e->type == KeyPress) { + KeySym sym = obt_keyboard_keypress_to_keysym(e); + /* Escape cancels no matter what */ - if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) { + if (sym == XK_Escape) { o->cancel = TRUE; o->state = e->xkey.state; return FALSE; } /* There were no modifiers and they pressed enter */ - else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) && - !initial_state) - { + else if (sym == XK_Return && !initial_state) { o->cancel = FALSE; o->state = e->xkey.state; return FALSE; diff --git a/openbox/actions/desktop.c b/openbox/actions/desktop.c index a2d4be29..6c30d56d 100644 --- a/openbox/actions/desktop.c +++ b/openbox/actions/desktop.c @@ -312,17 +312,15 @@ static gboolean i_input_func(guint initial_state, } if (e->type == KeyPress) { + KeySym sym = obt_keyboard_keypress_to_keysym(e); + /* Escape cancels no matter what */ - if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) { + if (sym == XK_Escape) return FALSE; - } /* There were no modifiers and they pressed enter */ - else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) && - !initial_state) - { + else if (sym == XK_Return && !initial_state) return FALSE; - } } /* They released the modifiers */ else if (e->type == KeyRelease && initial_state && !(mods & initial_state)) diff --git a/openbox/actions/directionalwindows.c b/openbox/actions/directionalwindows.c index e8410c96..7ede3333 100644 --- a/openbox/actions/directionalwindows.c +++ b/openbox/actions/directionalwindows.c @@ -269,16 +269,16 @@ static gboolean i_input_func(guint initial_state, } if (e->type == KeyPress) { + KeySym sym = obt_keyboard_keypress_to_keysym(e); + /* Escape cancels no matter what */ - if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) { + if (sym == XK_Escape) { end_cycle(TRUE, e->xkey.state, options); return FALSE; } /* There were no modifiers and they pressed enter */ - else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) && - !initial_state) - { + else if (sym == XK_Return && !initial_state) { end_cycle(FALSE, e->xkey.state, options); return FALSE; } diff --git a/openbox/event.c b/openbox/event.c index a4943f46..13fd3114 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -1777,20 +1777,20 @@ static gboolean event_handle_menu_input(XEvent *ev) /* Allow control while going thru the menu */ else if (ev->type == KeyPress && (mods & ~ControlMask) == 0) { gunichar unikey; + KeySym sym; frame->got_press = TRUE; frame->press_keycode = ev->xkey.keycode; frame->press_doexec = FALSE; - unikey = obt_keyboard_keypress_to_unichar(menu_frame_ic(frame), - &ev->xkey); + sym = obt_keyboard_keypress_to_keysym(ev); - if (ob_keycode_match(ev->xkey.keycode, OB_KEY_ESCAPE)) { + if (sym == XK_Escape) { menu_frame_hide_all(); ret = TRUE; } - else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_LEFT)) { + else if (sym == XK_Left) { /* Left goes to the parent menu */ if (frame->parent) { /* remove focus from the child */ @@ -1802,7 +1802,7 @@ static gboolean event_handle_menu_input(XEvent *ev) ret = TRUE; } - else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_RIGHT)) { + else if (sym == XK_Right) { /* Right goes to the selected submenu */ if (frame->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) { @@ -1813,28 +1813,37 @@ static gboolean event_handle_menu_input(XEvent *ev) ret = TRUE; } - else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_UP)) { + else if (sym == XK_Up) { menu_frame_select_previous(frame); ret = TRUE; } - else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_DOWN)) { + else if (sym == XK_Down) { menu_frame_select_next(frame); ret = TRUE; } - else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_HOME)) { + else if (sym == XK_Home) { menu_frame_select_first(frame); ret = TRUE; } - else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_END)) { + else if (sym == XK_End) { menu_frame_select_last(frame); ret = TRUE; } + else if (sym == XK_Return) { + frame->press_doexec = TRUE; + ret = TRUE; + } + /* keyboard accelerator shortcuts. (if it was a valid key) */ - else if (unikey) { + else if (frame->entries && + (unikey = + obt_keyboard_keypress_to_unichar(menu_frame_ic(frame), + ev))) + { GList *start; GList *it; ObMenuEntryFrame *found = NULL; @@ -1885,27 +1894,15 @@ static gboolean event_handle_menu_input(XEvent *ev) doesn't get sent to the focused application. Allow ControlMask only, and don't bother if the menu is empty */ - else if (ev->type == KeyRelease && (mods & ~ControlMask) == 0 && - frame->entries && frame->got_press) - { - if (ob_keycode_match(ev->xkey.keycode, OB_KEY_RETURN)) { - /* Enter runs the active item or goes into the submenu. - Control-Enter runs it without closing the menu. */ + else if (ev->type == KeyRelease && (mods & ~ControlMask) == 0) { + if (frame->press_keycode == ev->xkey.keycode && + frame->got_press && + frame->press_doexec) + { if (frame->child) menu_frame_select_next(frame->child); else if (frame->selected) menu_entry_frame_execute(frame->selected, ev->xkey.state); - - ret = TRUE; - } - - if (frame->press_keycode == ev->xkey.keycode && - frame->press_doexec) - { - if (frame->selected->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) - menu_entry_frame_execute(frame->selected, ev->xkey.state); - else - menu_frame_select_next(frame->child); } } } diff --git a/openbox/misc.h b/openbox/misc.h index 68403f49..750dddd7 100644 --- a/openbox/misc.h +++ b/openbox/misc.h @@ -43,21 +43,6 @@ typedef enum OB_NUM_CURSORS } ObCursor; -typedef enum -{ - OB_KEY_RETURN, - OB_KEY_ESCAPE, - OB_KEY_LEFT, - OB_KEY_RIGHT, - OB_KEY_UP, - OB_KEY_DOWN, - OB_KEY_TAB, - OB_KEY_SPACE, - OB_KEY_HOME, - OB_KEY_END, - OB_NUM_KEYS -} ObKey; - typedef enum { OB_STATE_STARTING, diff --git a/openbox/moveresize.c b/openbox/moveresize.c index ec9cb103..90e06c36 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -594,24 +594,25 @@ static void cancel_edge_warp(void) obt_main_loop_timeout_remove(ob_main_loop, edge_warp_delay_func); } -static void move_with_keys(gint keycode, gint state) +static void move_with_keys(KeySym sym, guint state) { gint dx = 0, dy = 0, ox = cur_x, oy = cur_y; gint opx, px, opy, py; gint dist = 0; /* shift means jump to edge */ - if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT)) { + if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT)) + { gint x, y; ObDirection dir; - if (ob_keycode_match(keycode, OB_KEY_RIGHT)) + if (sym == XK_Right) dir = OB_DIRECTION_EAST; - else if (ob_keycode_match(keycode, OB_KEY_LEFT)) + else if (sym == XK_Left) dir = OB_DIRECTION_WEST; - else if (ob_keycode_match(keycode, OB_KEY_DOWN)) + else if (sym == XK_Down) dir = OB_DIRECTION_SOUTH; - else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */ + else /* sym == XK_Up */ dir = OB_DIRECTION_NORTH; client_find_move_directional(moveresize_client, dir, &x, &y); @@ -627,13 +628,13 @@ static void move_with_keys(gint keycode, gint state) else dist = KEY_DIST; - if (ob_keycode_match(keycode, OB_KEY_RIGHT)) + if (sym == XK_Right) dx = dist; - else if (ob_keycode_match(keycode, OB_KEY_LEFT)) + else if (sym == XK_Left) dx = -dist; - else if (ob_keycode_match(keycode, OB_KEY_DOWN)) + else if (sym == XK_Down) dy = dist; - else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */ + else /* if (sym == XK_Up) */ dy = -dist; } @@ -659,14 +660,14 @@ static void move_with_keys(gint keycode, gint state) start_y += (py - opy) - (cur_y - oy); } -static void resize_with_keys(gint keycode, gint state) +static void resize_with_keys(KeySym sym, guint state) { gint dw = 0, dh = 0, pdx = 0, pdy = 0, opx, opy, px, py; gint resist = 0; ObDirection dir; /* pick the edge if it needs to move */ - if (ob_keycode_match(keycode, OB_KEY_RIGHT)) { + if (sym == XK_Right) { dir = OB_DIRECTION_EAST; if (key_resize_edge != OB_DIRECTION_WEST && key_resize_edge != OB_DIRECTION_EAST) @@ -674,7 +675,7 @@ static void resize_with_keys(gint keycode, gint state) key_resize_edge = OB_DIRECTION_EAST; return; } - } else if (ob_keycode_match(keycode, OB_KEY_LEFT)) { + } else if (sym == XK_Left) { dir = OB_DIRECTION_WEST; if (key_resize_edge != OB_DIRECTION_WEST && key_resize_edge != OB_DIRECTION_EAST) @@ -682,7 +683,7 @@ static void resize_with_keys(gint keycode, gint state) key_resize_edge = OB_DIRECTION_WEST; return; } - } else if (ob_keycode_match(keycode, OB_KEY_UP)) { + } else if (sym == XK_Up) { dir = OB_DIRECTION_NORTH; if (key_resize_edge != OB_DIRECTION_NORTH && key_resize_edge != OB_DIRECTION_SOUTH) @@ -690,7 +691,7 @@ static void resize_with_keys(gint keycode, gint state) key_resize_edge = OB_DIRECTION_NORTH; return; } - } else /* if (ob_keycode_match(keycode, OB_KEY_DOWN)) */ { + } else /* if (sym == XK_Down) */ { dir = OB_DIRECTION_SOUTH; if (key_resize_edge != OB_DIRECTION_NORTH && key_resize_edge != OB_DIRECTION_SOUTH) @@ -701,16 +702,17 @@ static void resize_with_keys(gint keycode, gint state) } /* shift means jump to edge */ - if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT)) { + if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT)) + { gint x, y, w, h; - if (ob_keycode_match(keycode, OB_KEY_RIGHT)) + if (sym == XK_Right) dir = OB_DIRECTION_EAST; - else if (ob_keycode_match(keycode, OB_KEY_LEFT)) + else if (sym == XK_Left) dir = OB_DIRECTION_WEST; - else if (ob_keycode_match(keycode, OB_KEY_DOWN)) + else if (sym == XK_Down) dir = OB_DIRECTION_SOUTH; - else /* if (ob_keycode_match(keycode, OB_KEY_UP)) */ + else /* if (sym == XK_Up)) */ dir = OB_DIRECTION_NORTH; client_find_resize_directional(moveresize_client, key_resize_edge, @@ -912,24 +914,24 @@ gboolean moveresize_event(XEvent *e) } used = TRUE; } else if (e->type == KeyPress) { - if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) { + KeySym sym = obt_keyboard_keypress_to_keysym(e); + + if (sym == XK_Escape) { moveresize_end(TRUE); used = TRUE; - } else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN)) { + } else if (sym == XK_Return) { moveresize_end(FALSE); used = TRUE; - } 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)) + } else if (sym == XK_Right || sym == XK_Left || + sym == XK_Up || sym == XK_Down) { if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD)) { - resize_with_keys(e->xkey.keycode, e->xkey.state); + resize_with_keys(sym, e->xkey.state); used = TRUE; } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD)) { - move_with_keys(e->xkey.keycode, e->xkey.state); + move_with_keys(sym, e->xkey.state); used = TRUE; } } diff --git a/openbox/openbox.c b/openbox/openbox.c index d2b66b5b..0f9fb179 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -80,9 +80,6 @@ #include #endif -#include -#include - RrInstance *ob_rr_inst; RrImageCache *ob_rr_icons; RrTheme *ob_rr_theme; @@ -101,7 +98,6 @@ 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 gint exitcode = 0; static guint remote_control = 0; static gboolean being_replaced = FALSE; @@ -217,18 +213,6 @@ gint main(gint argc, gchar **argv) if (reconfigure) obt_keyboard_reload(); - /* get the keycodes for keys we use */ - keys[OB_KEY_RETURN] = obt_keyboard_keysym_to_keycode(XK_Return); - keys[OB_KEY_ESCAPE] = obt_keyboard_keysym_to_keycode(XK_Escape); - keys[OB_KEY_LEFT] = obt_keyboard_keysym_to_keycode(XK_Left); - keys[OB_KEY_RIGHT] = obt_keyboard_keysym_to_keycode(XK_Right); - keys[OB_KEY_UP] = obt_keyboard_keysym_to_keycode(XK_Up); - keys[OB_KEY_DOWN] = obt_keyboard_keysym_to_keycode(XK_Down); - keys[OB_KEY_TAB] = obt_keyboard_keysym_to_keycode(XK_Tab); - keys[OB_KEY_SPACE] = obt_keyboard_keysym_to_keycode(XK_space); - keys[OB_KEY_HOME] = obt_keyboard_keysym_to_keycode(XK_Home); - keys[OB_KEY_END] = obt_keyboard_keysym_to_keycode(XK_End); - { ObtXmlInst *i; @@ -405,18 +389,6 @@ 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]); - g_free(keys[OB_KEY_HOME]); - g_free(keys[OB_KEY_END]); } while (reconfigure); } @@ -737,16 +709,6 @@ Cursor ob_cursor(ObCursor cursor) return cursors[cursor]; } -gboolean ob_keycode_match(KeyCode code, ObKey key) -{ - KeyCode *k; - - g_assert(key < OB_NUM_KEYS); - for (k = keys[key]; *k; ++k) - if (*k == code) return TRUE; - return FALSE; -} - ObState ob_state(void) { return state; diff --git a/openbox/openbox.h b/openbox/openbox.h index c43f0a61..9eaee553 100644 --- a/openbox/openbox.h +++ b/openbox/openbox.h @@ -27,7 +27,6 @@ #include "obt/display.h" #include -#include extern RrInstance *ob_rr_inst; extern RrImageCache *ob_rr_icons; @@ -62,6 +61,4 @@ void ob_exit_with_error(const gchar *msg) G_GNUC_NORETURN; Cursor ob_cursor(ObCursor cursor); -gboolean ob_keycode_match(KeyCode code, ObKey key); - #endif diff --git a/openbox/prompt.c b/openbox/prompt.c index 9fd56773..b10d8a18 100644 --- a/openbox/prompt.c +++ b/openbox/prompt.c @@ -525,6 +525,7 @@ gboolean prompt_key_event(ObPrompt *self, XEvent *e) { gboolean shift; guint shift_mask, mods; + KeySym sym; if (e->type != KeyPress) return FALSE; @@ -536,23 +537,18 @@ gboolean prompt_key_event(ObPrompt *self, XEvent *e) if (mods != 0 && mods != shift_mask) return FALSE; - if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) + sym = obt_keyboard_keypress_to_keysym(e); + + if (sym == XK_Escape) prompt_cancel(self); - else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) || - ob_keycode_match(e->xkey.keycode, OB_KEY_SPACE)) - { + else if (sym == XK_Return || sym == XK_space) prompt_run_callback(self, self->focus->result); - } - 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)) - { + else if (sym == XK_Tab || sym == XK_Left || sym == XK_Right) { gint i; gboolean left; ObPromptElement *oldfocus; - left = ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) || - (ob_keycode_match(e->xkey.keycode, OB_KEY_TAB) && shift); + left = (sym == XK_Left) || ((sym == XK_Tab) && shift); oldfocus = self->focus; for (i = 0; i < self->n_buttons; ++i)