Add support for Home and End keys for moving
authorphillbush <phillbush@cock.li>
Thu, 17 Sep 2020 00:48:46 +0000 (21:48 -0300)
committerphillbush <phillbush@cock.li>
Thu, 17 Sep 2020 00:48:46 +0000 (21:48 -0300)
xmenu.c
xmenu.h

diff --git a/xmenu.c b/xmenu.c
index d557f6d..2a8de09 100644 (file)
--- a/xmenu.c
+++ b/xmenu.c
@@ -1150,38 +1150,53 @@ getitem(struct Menu *menu, int y)
 static struct Item *
 itemcycle(struct Menu *currmenu, int direction)
 {
 static struct Item *
 itemcycle(struct Menu *currmenu, int direction)
 {
-       struct Item *item;
+       struct Item *item = NULL;
        struct Item *lastitem;
 
        struct Item *lastitem;
 
-       item = NULL;
+       for (lastitem = currmenu->list; lastitem && lastitem->next; lastitem = lastitem->next)
+               ;
 
 
-       if (direction == ITEMNEXT) {
+       /* select item (either separator or labeled item) in given direction */
+       switch (direction) {
+       case ITEMNEXT:
                if (currmenu->selected == NULL)
                        item = currmenu->list;
                else if (currmenu->selected->next != NULL)
                        item = currmenu->selected->next;
                if (currmenu->selected == NULL)
                        item = currmenu->list;
                else if (currmenu->selected->next != NULL)
                        item = currmenu->selected->next;
-
-               while (item != NULL && item->label == NULL)
-                       item = item->next;
-
-               if (item == NULL)
-                       item = currmenu->list;
-       } else {
-               for (lastitem = currmenu->list;
-                    lastitem != NULL && lastitem->next != NULL;
-                    lastitem = lastitem->next)
-                       ;
-
+               break;
+       case ITEMPREV:
                if (currmenu->selected == NULL)
                        item = lastitem;
                else if (currmenu->selected->prev != NULL)
                        item = currmenu->selected->prev;
                if (currmenu->selected == NULL)
                        item = lastitem;
                else if (currmenu->selected->prev != NULL)
                        item = currmenu->selected->prev;
+               break;
+       case ITEMFIRST:
+               item = currmenu->list;
+               break;
+       case ITEMLAST:
+               item = lastitem;
+               break;
+       }
 
 
+       /*
+        * the selected item can be a separator
+        * let's select the closest labeled item (ie., one that isn't a separator)
+        */
+       switch (direction) {
+       case ITEMNEXT:
+       case ITEMFIRST:
+               while (item != NULL && item->label == NULL)
+                       item = item->next;
+               if (item == NULL)
+                       item = currmenu->list;
+               break;
+       case ITEMPREV:
+       case ITEMLAST:
                while (item != NULL && item->label == NULL)
                        item = item->prev;
                while (item != NULL && item->label == NULL)
                        item = item->prev;
-
                if (item == NULL)
                        item = lastitem;
                if (item == NULL)
                        item = lastitem;
+               break;
        }
 
        return item;
        }
 
        return item;
@@ -1257,7 +1272,11 @@ selectitem:
 
                        /* cycle through menu */
                        item = NULL;
 
                        /* cycle through menu */
                        item = NULL;
-                       if (ksym == XK_ISO_Left_Tab || ksym == XK_Up) {
+                       if (ksym == XK_Home) {
+                               item = itemcycle(currmenu, ITEMFIRST);
+                       } else if (ksym == XK_End) {
+                               item = itemcycle(currmenu, ITEMLAST);
+                       } else if (ksym == XK_ISO_Left_Tab || ksym == XK_Up) {
                                item = itemcycle(currmenu, ITEMPREV);
                        } else if (ksym == XK_Tab || ksym == XK_Down) {
                                item = itemcycle(currmenu, ITEMNEXT);
                                item = itemcycle(currmenu, ITEMPREV);
                        } else if (ksym == XK_Tab || ksym == XK_Down) {
                                item = itemcycle(currmenu, ITEMNEXT);
diff --git a/xmenu.h b/xmenu.h
index a85b44c..e29df02 100644 (file)
--- a/xmenu.h
+++ b/xmenu.h
@@ -1,8 +1,7 @@
 #define PROGNAME "xmenu"
 
 #define PROGNAME "xmenu"
 
-/* macros for keyboard menu navigation */
-#define ITEMPREV 0
-#define ITEMNEXT 1
+/* enum for keyboard menu navigation */
+enum { ITEMPREV, ITEMNEXT, ITEMFIRST, ITEMLAST };
 
 /* macros */
 #define LEN(x)              (sizeof (x) / sizeof (x[0]))
 
 /* macros */
 #define LEN(x)              (sizeof (x) / sizeof (x[0]))