From 62f8a5c49b852047bf6cc199d2d0c9add41d35a9 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 11 Feb 2010 13:59:15 -0500 Subject: [PATCH] make the menu use the new obt stuff when reading keyboard input so it can handle input from the non-base group and composed input --- openbox/event.c | 70 +++++++++++++++++++++++---------------------- openbox/menuframe.h | 4 +++ 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/openbox/event.c b/openbox/event.c index 4b45cf69..f813d3f5 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -1765,12 +1765,10 @@ static gboolean event_handle_menu_input(XEvent *ev) } else if (ev->type == KeyPress || ev->type == KeyRelease) { guint mods; - gunichar unikey; ObMenuFrame *frame; /* 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) @@ -1778,7 +1776,11 @@ 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; + frame->got_press = TRUE; + frame->press_keycode = ev->xkey.keycode; + frame->press_doexec = FALSE; if (ob_keycode_match(ev->xkey.keycode, OB_KEY_ESCAPE)) { menu_frame_hide_all(); @@ -1827,28 +1829,9 @@ static gboolean event_handle_menu_input(XEvent *ev) 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 && (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. */ - if (frame->child) - menu_frame_select_next(frame->child); - else if (frame->selected) - menu_entry_frame_execute(frame->selected, ev->xkey.state); - - ret = TRUE; - } /* keyboard accelerator shortcuts. (if it was a valid key) */ - else if (unikey != 0) { + else if ((unikey = obt_keyboard_keypress_to_unichar(&ev->xkey))) { GList *start; GList *it; ObMenuEntryFrame *found = NULL; @@ -1886,23 +1869,42 @@ 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, ev->xkey.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 && + 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. */ + 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); + } + } } return ret; diff --git a/openbox/menuframe.h b/openbox/menuframe.h index aa32b211..8f124ed6 100644 --- a/openbox/menuframe.h +++ b/openbox/menuframe.h @@ -81,6 +81,10 @@ struct _ObMenuFrame menu until it has seen a KeyPress. this is to avoid having the keybinding used to show the menu end up running something inside the menu */ + guint press_keycode; /* the KeyCode that was used in the last KeyPress */ + gboolean press_doexec; /* if the upcoming KeyRelease should be used to + execute the menu item that was selected by the + KeyPress */ }; struct _ObMenuEntryFrame -- 2.45.2