ultra-keyboard-controlled-menus
authorDana Jansens <danakj@orodu.net>
Fri, 29 Aug 2003 08:44:55 +0000 (08:44 +0000)
committerDana Jansens <danakj@orodu.net>
Fri, 29 Aug 2003 08:44:55 +0000 (08:44 +0000)
openbox/event.c
openbox/menu.c
openbox/menuframe.c
openbox/menuframe.h

index f71fdf5..8d1380d 100644 (file)
@@ -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);
+        }
     }
 }
index 464011c..84af99f 100644 (file)
@@ -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)
index a1b06e1..0b90df6 100644 (file)
@@ -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);
+}
index 7c744fe..40b9f84 100644 (file)
@@ -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);