X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=13fd31142cbb676defa5caa78a9ccb26c19b3858;hb=096dad0c6c027100494ede811b33cb8558d32e25;hp=51cfc658c638a9db5128f4fd3a70d71216715acd;hpb=31f0c8c1ad8c9acf369ab8336765f4bf673b8e21;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index 51cfc658..13fd3114 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -56,9 +56,6 @@ #ifdef HAVE_UNISTD_H # include /* for usleep() */ #endif -#ifdef XKB -# include -#endif #ifdef USE_SM #include @@ -260,34 +257,14 @@ static void event_set_curtime(XEvent *e) static void event_hack_mods(XEvent *e) { -#ifdef XKB - XkbStateRec xkb_state; -#endif - switch (e->type) { case ButtonPress: 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 - /* If XKB is present, then the modifiers are all strange from its - magic. Our X core protocol stuff won't work, so we use this to - find what the modifier state is instead. */ - if (XkbGetState(obt_display, XkbUseCoreKbd, &xkb_state) == Success) - e->xkey.state = - obt_keyboard_only_modmasks(xkb_state.compat_state); - else -#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); @@ -661,6 +638,7 @@ static void event_process(const XEvent *ec, gpointer data) modifier map, and rebind all the key bindings as appropriate */ ob_debug("Keyboard map changed. Reloading keyboard bindings."); ob_set_state(OB_STATE_RECONFIGURING); + XRefreshKeyboardMapping(&e->xmapping); obt_keyboard_reload(); keyboard_rebind(); ob_set_state(OB_STATE_RUNNING); @@ -1786,28 +1764,33 @@ 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; - gunichar unikey; + guint mods; 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); 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) { + gunichar unikey; + KeySym sym; + frame->got_press = TRUE; + frame->press_keycode = ev->xkey.keycode; + frame->press_doexec = FALSE; + + sym = obt_keyboard_keypress_to_keysym(ev); - if (ob_keycode_match(keycode, OB_KEY_ESCAPE)) { + if (sym == XK_Escape) { menu_frame_hide_all(); ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_LEFT)) { + else if (sym == XK_Left) { /* Left goes to the parent menu */ if (frame->parent) { /* remove focus from the child */ @@ -1819,7 +1802,7 @@ static gboolean event_handle_menu_input(XEvent *ev) ret = TRUE; } - else if (ob_keycode_match(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) { @@ -1830,47 +1813,37 @@ static gboolean event_handle_menu_input(XEvent *ev) ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_UP)) { + else if (sym == XK_Up) { menu_frame_select_previous(frame); ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_DOWN)) { + else if (sym == XK_Down) { menu_frame_select_next(frame); ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_HOME)) { + else if (sym == XK_Home) { menu_frame_select_first(frame); ret = TRUE; } - else if (ob_keycode_match(keycode, OB_KEY_END)) { + else if (sym == XK_End) { menu_frame_select_last(frame); ret = TRUE; } - } - - /* 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 && - frame->entries && frame->got_press) - { - 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) - menu_frame_select_next(frame->child); - else if (frame->selected) - menu_entry_frame_execute(frame->selected, state); + else if (sym == XK_Return) { + frame->press_doexec = TRUE; ret = TRUE; } /* keyboard accelerator shortcuts. (if it was a valid key) */ - else if (unikey != 0) { + else if (frame->entries && + (unikey = + obt_keyboard_keypress_to_unichar(menu_frame_ic(frame), + ev))) + { GList *start; GList *it; ObMenuEntryFrame *found = NULL; @@ -1908,23 +1881,30 @@ static gboolean event_handle_menu_input(XEvent *ev) } while (it != start); if (found) { - if (found->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && - num_found == 1) - { - 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); - } else { - menu_frame_select(frame, found, TRUE); - if (num_found == 1) - menu_frame_select_next(frame->child); - } + menu_frame_select(frame, found, TRUE); + if (num_found == 1) + frame->press_doexec = TRUE; ret = TRUE; } } } + + /* 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 && (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); + } + } } return ret;