From 43d62990e407f409f76f60a405c529f9b15d33f6 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 11 Feb 2010 13:23:54 -0500 Subject: [PATCH] don't strip the state for keyboard events this allows translation of keys not in the base keyboard layout --- openbox/actions/cyclewindows.c | 12 ++++++-- openbox/actions/desktop.c | 14 ++++++++-- openbox/actions/directionalwindows.c | 13 +++++++-- openbox/event.c | 42 +++++++++++----------------- openbox/keyboard.c | 15 ++++++---- openbox/menuframe.c | 4 ++- openbox/prompt.c | 7 +++-- 7 files changed, 65 insertions(+), 42 deletions(-) diff --git a/openbox/actions/cyclewindows.c b/openbox/actions/cyclewindows.c index d1112242..6619b387 100644 --- a/openbox/actions/cyclewindows.c +++ b/openbox/actions/cyclewindows.c @@ -5,6 +5,7 @@ #include "openbox/focus_cycle.h" #include "openbox/openbox.h" #include "gettext.h" +#include "obt/keyboard.h" typedef struct { gboolean linear; @@ -172,6 +173,14 @@ static gboolean i_input_func(guint initial_state, gboolean *used) { Options *o = options; + guint mods; + + mods = obt_keyboard_only_modmasks(e->xkey.state); + if (e->type == KeyRelease) { + /* remove from the state the mask of the modifier key being + released, if it is a modifier key being released that is */ + mods &= ~obt_keyboard_keycode_to_modmask(e->xkey.keycode); + } if (e->type == KeyPress) { /* Escape cancels no matter what */ @@ -191,8 +200,7 @@ static gboolean i_input_func(guint initial_state, } } /* They released the modifiers */ - else if (e->type == KeyRelease && initial_state && - (e->xkey.state & initial_state) == 0) + else if (e->type == KeyRelease && initial_state && !(mods & initial_state)) { o->cancel = FALSE; o->state = e->xkey.state; diff --git a/openbox/actions/desktop.c b/openbox/actions/desktop.c index 5b0282cc..59aae832 100644 --- a/openbox/actions/desktop.c +++ b/openbox/actions/desktop.c @@ -2,7 +2,7 @@ #include "openbox/screen.h" #include "openbox/client.h" #include "openbox/openbox.h" -#include +#include "obt/keyboard.h" typedef enum { LAST, @@ -300,6 +300,15 @@ static gboolean i_input_func(guint initial_state, gpointer options, gboolean *used) { + guint mods; + + mods = obt_keyboard_only_modmasks(e->xkey.state); + if (e->type == KeyRelease) { + /* remove from the state the mask of the modifier key being + released, if it is a modifier key being released that is */ + mods &= ~obt_keyboard_keycode_to_modmask(e->xkey.keycode); + } + if (e->type == KeyPress) { /* Escape cancels no matter what */ if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) { @@ -314,8 +323,7 @@ static gboolean i_input_func(guint initial_state, } } /* They released the modifiers */ - else if (e->type == KeyRelease && initial_state && - (e->xkey.state & initial_state) == 0) + else if (e->type == KeyRelease && initial_state && !(mods & initial_state)) { return FALSE; } diff --git a/openbox/actions/directionalwindows.c b/openbox/actions/directionalwindows.c index 2cca450c..c5b908bb 100644 --- a/openbox/actions/directionalwindows.c +++ b/openbox/actions/directionalwindows.c @@ -6,6 +6,7 @@ #include "openbox/openbox.h" #include "openbox/misc.h" #include "gettext.h" +#include "obt/keyboard.h" typedef struct { gboolean interactive; @@ -256,6 +257,15 @@ static gboolean i_input_func(guint initial_state, gpointer options, gboolean *used) { + guint mods; + + mods = obt_keyboard_only_modmasks(e->xkey.state); + if (e->type == KeyRelease) { + /* remove from the state the mask of the modifier key being + released, if it is a modifier key being released that is */ + mods &= ~obt_keyboard_keycode_to_modmask(e->xkey.keycode); + } + if (e->type == KeyPress) { /* Escape cancels no matter what */ if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) { @@ -272,8 +282,7 @@ static gboolean i_input_func(guint initial_state, } } /* They released the modifiers */ - else if (e->type == KeyRelease && initial_state && - (e->xkey.state & initial_state) == 0) + else if (e->type == KeyRelease && initial_state && !(mods & initial_state)) { end_cycle(FALSE, e->xkey.state, options); return FALSE; diff --git a/openbox/event.c b/openbox/event.c index 378b0b4b..4b45cf69 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -263,18 +263,8 @@ static void event_hack_mods(XEvent *e) e->xbutton.state = obt_keyboard_only_modmasks(e->xbutton.state); break; case KeyPress: - e->xkey.state = obt_keyboard_only_modmasks(e->xkey.state); break; case KeyRelease: -#ifdef XKB - /* keep only the keyboard modifiers. xkb includes other things here. - (see XKBProto.pdf document: section 2.2.2) */ - e->xkey.state &= 0xf; -#endif - e->xkey.state = obt_keyboard_only_modmasks(e->xkey.state); - /* remove from the state the mask of the modifier key being - released, if it is a modifier key being released that is */ - e->xkey.state &= ~obt_keyboard_keycode_to_modmask(e->xkey.keycode); break; case MotionNotify: e->xmotion.state = obt_keyboard_only_modmasks(e->xmotion.state); @@ -1774,28 +1764,28 @@ static gboolean event_handle_menu_input(XEvent *ev) menu_frame_select(e->frame, e, FALSE); } else if (ev->type == KeyPress || ev->type == KeyRelease) { - guint keycode, state; + guint mods; gunichar unikey; ObMenuFrame *frame; - keycode = ev->xkey.keycode; - state = ev->xkey.state; - unikey = obt_keyboard_keycode_to_unichar(keycode); + /* get the modifiers */ + mods = obt_keyboard_only_modmasks(ev->xkey.state); + unikey = obt_keyboard_keycode_to_unichar(ev->xkey.keycode); frame = find_active_or_last_menu(); if (frame == NULL) g_assert_not_reached(); /* there is no active menu */ /* Allow control while going thru the menu */ - else if (ev->type == KeyPress && (state & ~ControlMask) == 0) { + else if (ev->type == KeyPress && (mods & ~ControlMask) == 0) { frame->got_press = TRUE; - if (ob_keycode_match(keycode, OB_KEY_ESCAPE)) { + if (ob_keycode_match(ev->xkey.keycode, OB_KEY_ESCAPE)) { menu_frame_hide_all(); ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_LEFT)) { + else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_LEFT)) { /* Left goes to the parent menu */ if (frame->parent) { /* remove focus from the child */ @@ -1807,7 +1797,7 @@ static gboolean event_handle_menu_input(XEvent *ev) ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_RIGHT)) { + else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_RIGHT)) { /* Right goes to the selected submenu */ if (frame->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) { @@ -1818,22 +1808,22 @@ static gboolean event_handle_menu_input(XEvent *ev) ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_UP)) { + else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_UP)) { menu_frame_select_previous(frame); ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_DOWN)) { + else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_DOWN)) { menu_frame_select_next(frame); ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_HOME)) { + else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_HOME)) { menu_frame_select_first(frame); ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_END)) { + else if (ob_keycode_match(ev->xkey.keycode, OB_KEY_END)) { menu_frame_select_last(frame); ret = TRUE; } @@ -1843,16 +1833,16 @@ 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 && (state & ~ControlMask) == 0 && + else if (ev->type == KeyRelease && (mods & ~ControlMask) == 0 && frame->entries && frame->got_press) { - if (ob_keycode_match(keycode, OB_KEY_RETURN)) { + 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. */ if (frame->child) menu_frame_select_next(frame->child); else if (frame->selected) - menu_entry_frame_execute(frame->selected, state); + menu_entry_frame_execute(frame->selected, ev->xkey.state); ret = TRUE; } @@ -1902,7 +1892,7 @@ static gboolean event_handle_menu_input(XEvent *ev) menu_frame_select(frame, found, TRUE); usleep(50000); /* highlight the item for a short bit so the user can see what happened */ - menu_entry_frame_execute(found, state); + menu_entry_frame_execute(found, ev->xkey.state); } else { menu_frame_select(frame, found, TRUE); if (num_found == 1) diff --git a/openbox/keyboard.c b/openbox/keyboard.c index 5f7531e3..92945ab0 100644 --- a/openbox/keyboard.c +++ b/openbox/keyboard.c @@ -33,6 +33,7 @@ #include "moveresize.h" #include "popup.h" #include "gettext.h" +#include "obt/keyboard.h" #include @@ -175,9 +176,12 @@ gboolean keyboard_process_interactive_grab(const XEvent *e, ObClient **client) gboolean handled = FALSE; gboolean done = FALSE; gboolean cancel = FALSE; + guint mods; + + mods = obt_keyboard_only_modmasks(ev->xkey.state); if (istate.active) { - if ((e->type == KeyRelease && !(istate.state & e->xkey.state))) { + if ((e->type == KeyRelease && !(istate.state & mods))) { done = TRUE; handled = TRUE; } else if (e->type == KeyPress) { @@ -208,6 +212,7 @@ gboolean keyboard_event(ObClient *client, const XEvent *e) { KeyBindingTree *p; gboolean used; + guint mods; if (e->type == KeyRelease) { grab_key_passive_count(-1); @@ -217,8 +222,10 @@ gboolean keyboard_event(ObClient *client, const XEvent *e) g_assert(e->type == KeyPress); grab_key_passive_count(1); + mods = obt_keyboard_only_modmasks(e->xkey.state); + if (e->xkey.keycode == config_keyboard_reset_keycode && - e->xkey.state == config_keyboard_reset_state) + mods == config_keyboard_reset_state) { obt_main_loop_timeout_remove(ob_main_loop, chain_timeout); keyboard_reset_chains(-1); @@ -231,9 +238,7 @@ gboolean keyboard_event(ObClient *client, const XEvent *e) else p = curpos->first_child; while (p) { - if (p->key == e->xkey.keycode && - p->state == e->xkey.state) - { + if (p->key == e->xkey.keycode && p->state == mods) { /* if we hit a key binding, then close any open menus and run it */ if (menu_frame_visible) menu_frame_hide_all(); diff --git a/openbox/menuframe.c b/openbox/menuframe.c index 4ee5d31e..b80bac91 100644 --- a/openbox/menuframe.c +++ b/openbox/menuframe.c @@ -27,6 +27,7 @@ #include "openbox.h" #include "config.h" #include "obt/prop.h" +#include "obt/keyboard.h" #include "obrender/theme.h" #define PADDING 2 @@ -1262,9 +1263,10 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state) GSList *acts = self->entry->data.normal.actions; ObClient *client = self->frame->client; ObMenuFrame *frame = self->frame; + guint mods = obt_keyboard_only_modmasks(state); /* release grabs before executing the shit */ - if (!(state & ControlMask)) { + if (!(mods & ControlMask)) { event_cancel_all_key_grabs(); frame = NULL; } diff --git a/openbox/prompt.c b/openbox/prompt.c index 4f8930d7..73536152 100644 --- a/openbox/prompt.c +++ b/openbox/prompt.c @@ -520,15 +520,16 @@ void prompt_hide(ObPrompt *self) gboolean prompt_key_event(ObPrompt *self, XEvent *e) { gboolean shift; - guint shift_mask; + guint shift_mask, mods; if (e->type != KeyPress) return FALSE; shift_mask = obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT); - shift = !!(e->xkey.state & shift_mask); + mods = obt_keyboard_only_modmasks(e->xkey.state); + shift = !!(mods & shift_mask); /* only accept shift */ - if (e->xkey.state != 0 && e->xkey.state != shift_mask) + if (mods != 0 && mods != shift_mask) return FALSE; if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) -- 2.45.2