don't strip the state for keyboard events this allows translation of keys not in the base keyboard layout
@@ -5,6 +5,7 @@ #include "openbox/event.h"
#include "openbox/focus_cycle.h" #include "openbox/openbox.h" #include "gettext.h" +#include "obt/keyboard.h" typedef struct { gboolean linear;@@ -172,6 +173,14 @@ gpointer options,
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 @@ return FALSE;
} } /* 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;
@@ -2,7 +2,7 @@ #include "openbox/actions.h"
#include "openbox/screen.h" #include "openbox/client.h" #include "openbox/openbox.h" -#include <glib.h> +#include "obt/keyboard.h" typedef enum { LAST,@@ -300,6 +300,15 @@ XEvent *e,
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 @@ return FALSE;
} } /* 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; }
@@ -6,6 +6,7 @@ #include "openbox/focus_cycle.h"
#include "openbox/openbox.h" #include "openbox/misc.h" #include "gettext.h" +#include "obt/keyboard.h" typedef struct { gboolean interactive;@@ -256,6 +257,15 @@ XEvent *e,
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 @@ return FALSE;
} } /* 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;
@@ -263,18 +263,8 @@ case ButtonRelease:
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 @@ f->child == e->frame)
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 @@ }
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 @@ }
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 @@ /* Use KeyRelease events for running things so that the key release
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 @@ {
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)
@@ -33,6 +33,7 @@ #include "translate.h"
#include "moveresize.h" #include "popup.h" #include "gettext.h" +#include "obt/keyboard.h" #include <glib.h>@@ -175,9 +176,12 @@ {
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 @@
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 @@ p = keyboard_firstnode;
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();
@@ -520,15 +520,16 @@
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))