From dcdc325f5c8c946df696d17a6da329aeac149586 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 29 Aug 2003 08:44:55 +0000 Subject: [PATCH] ultra-keyboard-controlled-menus --- openbox/event.c | 38 +++++++++++++++++++++++++++++++++++++ openbox/menu.c | 2 ++ openbox/menuframe.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ openbox/menuframe.h | 2 ++ 4 files changed, 88 insertions(+) diff --git a/openbox/event.c b/openbox/event.c index f71fdf57..8d1380d4 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -1147,6 +1147,19 @@ static void event_handle_dockapp(ObDockApp *app, XEvent *e) } } +ObMenuFrame* find_active_menu() +{ + GList *it; + ObMenuFrame *f; + + for (it = menu_frame_visible; it; it = g_list_next(it)) { + f = it->data; + if (f->selected) + break; + } + return it ? it->data : NULL; +} + static void event_handle_menu(XEvent *ev) { ObMenuFrame *f; @@ -1173,5 +1186,30 @@ static void event_handle_menu(XEvent *ev) menu_frame_select(f, e); } break; + case KeyPress: + if (ev->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) + menu_frame_hide_all(); + else if (ev->xkey.keycode == ob_keycode(OB_KEY_RETURN)) { + ObMenuFrame *f; + if ((f = find_active_menu())) + menu_entry_frame_execute(f->selected, + !(ev->xkey.state & ControlMask)); + } else if (ev->xkey.keycode == ob_keycode(OB_KEY_LEFT)) { + ObMenuFrame *f; + if ((f = find_active_menu()) && f->parent) + menu_frame_select(f, NULL); + } else if (ev->xkey.keycode == ob_keycode(OB_KEY_RIGHT)) { + ObMenuFrame *f; + if ((f = find_active_menu()) && f->child && f->child->entries) + menu_frame_select(f->child, f->child->entries->data); + } else if (ev->xkey.keycode == ob_keycode(OB_KEY_UP)) { + ObMenuFrame *f; + if ((f = find_active_menu())) + menu_frame_select_previous(f); + } else if (ev->xkey.keycode == ob_keycode(OB_KEY_DOWN)) { + ObMenuFrame *f; + if ((f = find_active_menu())) + menu_frame_select_next(f); + } } } diff --git a/openbox/menu.c b/openbox/menu.c index 464011c8..84af99fd 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -215,6 +215,8 @@ void menu_show(gchar *name, gint x, gint y, ObClient *client) frame = menu_frame_new(self, client); menu_frame_move(frame, x, y); menu_frame_show(frame, NULL); + if (frame->entries) + menu_frame_select_next(frame); } static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type, gint id) diff --git a/openbox/menuframe.c b/openbox/menuframe.c index a1b06e10..0b90df6e 100644 --- a/openbox/menuframe.c +++ b/openbox/menuframe.c @@ -627,3 +627,49 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide) } } } + +void menu_frame_select_previous(ObMenuFrame *self) +{ + GList *it = NULL, *start; + + if (self->entries) { + start = it = g_list_find(self->entries, self->selected); + while (TRUE) { + ObMenuEntryFrame *e; + + it = it ? g_list_previous(it) : g_list_last(self->entries); + if (it == start) + break; + + if (it) { + e = it->data; + if (e->entry->type != OB_MENU_ENTRY_TYPE_SEPARATOR) + break; + } + } + } + menu_frame_select(self, it ? it->data : NULL); +} + +void menu_frame_select_next(ObMenuFrame *self) +{ + GList *it = NULL, *start; + + if (self->entries) { + start = it = g_list_find(self->entries, self->selected); + while (TRUE) { + ObMenuEntryFrame *e; + + it = it ? g_list_next(it) : self->entries; + if (it == start) + break; + + if (it) { + e = it->data; + if (e->entry->type != OB_MENU_ENTRY_TYPE_SEPARATOR) + break; + } + } + } + menu_frame_select(self, it ? it->data : NULL); +} diff --git a/openbox/menuframe.h b/openbox/menuframe.h index 7c744fee..40b9f844 100644 --- a/openbox/menuframe.h +++ b/openbox/menuframe.h @@ -88,6 +88,8 @@ void menu_frame_hide_all(); void menu_frame_hide_all_client(struct _ObClient *client); void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry); +void menu_frame_select_previous(ObMenuFrame *self); +void menu_frame_select_next(ObMenuFrame *self); ObMenuFrame* menu_frame_under(gint x, gint y); ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y); -- 2.45.2