projects
/
xmenu
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
tags
|
clone url
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
7bdb3b0
)
make tab cycle through matched items
author
phillbush
<phillbush@cock.li>
Thu, 31 Dec 2020 07:58:05 +0000
(
04:58
-0300)
committer
phillbush
<phillbush@cock.li>
Thu, 31 Dec 2020 07:58:05 +0000
(
04:58
-0300)
xmenu.c
patch
|
blob
|
blame
|
history
xmenu.h
patch
|
blob
|
blame
|
history
diff --git
a/xmenu.c
b/xmenu.c
index
f597aeb
..
61e154c
100644
(file)
--- a/
xmenu.c
+++ b/
xmenu.c
@@
-1158,19
+1158,53
@@
append(char *text, char *buf, size_t textsize, size_t buflen)
return 1;
}
return 1;
}
-/* get item in menu matching text */
+/* get item in menu matching text
from given direction (or from beginning, if dir = 0)
*/
static struct Item *
static struct Item *
-matchitem(struct Menu *menu, char *text)
+matchitem(struct Menu *menu, char *text
, int dir
)
{
{
- struct Item *item;
+ struct Item *item
, *lastitem
;
char *s;
size_t textlen;
char *s;
size_t textlen;
+ for (lastitem = menu->list; lastitem && lastitem->next; lastitem = lastitem->next)
+ ;
textlen = strlen(text);
textlen = strlen(text);
- for (item = menu->list; item; item = item->next)
+ if (dir < 0) {
+ if (menu->selected && menu->selected->prev)
+ item = menu->selected->prev;
+ else
+ item = lastitem;
+ } else if (dir > 0) {
+ if (menu->selected && menu->selected->next)
+ item = menu->selected->next;
+ else
+ item = menu->list;
+ } else {
+ item = menu->list;
+ }
+ /* find next item from selected item */
+ for ( ; item; item = (dir < 0) ? item->prev : item->next)
for (s = item->label; s && *s; s++)
if (strncasecmp(s, text, textlen) == 0)
return item;
for (s = item->label; s && *s; s++)
if (strncasecmp(s, text, textlen) == 0)
return item;
+ /* if not found, try to find from the beginning/end of list */
+ if (dir > 0) {
+ for (item = menu->list ; item; item = item->next) {
+ for (s = item->label; s && *s; s++) {
+ if (strncasecmp(s, text, textlen) == 0) {
+ return item;
+ }
+ }
+ }
+ } else {
+ for (item = lastitem ; item; item = item->prev) {
+ for (s = item->label; s && *s; s++) {
+ if (strncasecmp(s, text, textlen) == 0) {
+ return item;
+ }
+ }
+ }
+ }
return NULL;
}
return NULL;
}
@@
-1214,7
+1248,7
@@
run(struct Menu *currmenu)
} else {
currmenu = menu;
}
} else {
currmenu = menu;
}
- action = ACTION_SELECT | ACTION_MAP | ACTION_DRAW;
+ action = ACTION_
CLEAR | ACTION_
SELECT | ACTION_MAP | ACTION_DRAW;
break;
case ButtonRelease:
if (!isclickbutton(ev.xbutton.button))
break;
case ButtonRelease:
if (!isclickbutton(ev.xbutton.button))
@@
-1233,7
+1267,7
@@
enteritem:
return;
}
select = currmenu->list;
return;
}
select = currmenu->list;
- action = ACTION_SELECT | ACTION_MAP | ACTION_DRAW;
+ action = ACTION_
CLEAR | ACTION_
SELECT | ACTION_MAP | ACTION_DRAW;
break;
case ButtonPress:
menu = getmenu(currmenu, ev.xbutton.window);
break;
case ButtonPress:
menu = getmenu(currmenu, ev.xbutton.window);
@@
-1264,12
+1298,24
@@
enteritem:
item = NULL;
if (ksym == XK_Home || ksym == KSYMFIRST) {
item = itemcycle(currmenu, ITEMFIRST);
item = NULL;
if (ksym == XK_Home || ksym == KSYMFIRST) {
item = itemcycle(currmenu, ITEMFIRST);
+ action = ACTION_CLEAR;
} else if (ksym == XK_End || ksym == KSYMLAST) {
item = itemcycle(currmenu, ITEMLAST);
} else if (ksym == XK_End || ksym == KSYMLAST) {
item = itemcycle(currmenu, ITEMLAST);
+ action = ACTION_CLEAR;
} else if (ksym == XK_ISO_Left_Tab || ksym == XK_Up || ksym == KSYMUP) {
} else if (ksym == XK_ISO_Left_Tab || ksym == XK_Up || ksym == KSYMUP) {
- item = itemcycle(currmenu, ITEMPREV);
+ if (*text) {
+ item = matchitem(currmenu, text, -1);
+ } else {
+ item = itemcycle(currmenu, ITEMPREV);
+ action = ACTION_CLEAR;
+ }
} else if (ksym == XK_Tab || ksym == XK_Down || ksym == KSYMDOWN) {
} else if (ksym == XK_Tab || ksym == XK_Down || ksym == KSYMDOWN) {
- item = itemcycle(currmenu, ITEMNEXT);
+ if (*text) {
+ item = matchitem(currmenu, text, 1);
+ } else {
+ item = itemcycle(currmenu, ITEMNEXT);
+ action = ACTION_CLEAR;
+ }
} else if (ksym >= XK_1 && ksym <= XK_9){
item = itemcycle(currmenu, ITEMFIRST);
lastitem = itemcycle(currmenu, ITEMLAST);
} else if (ksym >= XK_1 && ksym <= XK_9){
item = itemcycle(currmenu, ITEMFIRST);
lastitem = itemcycle(currmenu, ITEMLAST);
@@
-1277,6
+1323,7
@@
enteritem:
currmenu->selected = item;
item = itemcycle(currmenu, ITEMNEXT);
}
currmenu->selected = item;
item = itemcycle(currmenu, ITEMNEXT);
}
+ action = ACTION_CLEAR;
} else if ((ksym == XK_Return || ksym == XK_Right || ksym == KSYMRIGHT) &&
currmenu->selected != NULL) {
item = currmenu->selected;
} else if ((ksym == XK_Return || ksym == XK_Right || ksym == KSYMRIGHT) &&
currmenu->selected != NULL) {
item = currmenu->selected;
@@
-1285,18
+1332,19
@@
enteritem:
currmenu->parent != NULL) {
item = currmenu->parent->selected;
currmenu = currmenu->parent;
currmenu->parent != NULL) {
item = currmenu->parent->selected;
currmenu = currmenu->parent;
- action = ACTION_MAP;
+ action = ACTION_CLEAR | ACTION_MAP;
+ } else if (ksym == XK_BackSpace || ksym == XK_Clear || ksym == XK_Delete) {
+ action = ACTION_CLEAR;
+ break;
} else {
append:
if (append(text, buf, sizeof text, len)) {
} else {
append:
if (append(text, buf, sizeof text, len)) {
- if ((currmenu->selected = matchitem(currmenu, text))) {
- action = ACTION_DRAW;
- break;
+ if (!(item = matchitem(currmenu, text, 0))) {
+ item = NULL;
}
}
+ } else if (len == 0) {
+ break; /* we may have pressed a dead key */
}
}
- select = NULL;
- action = ACTION_SELECT | ACTION_DRAW;
- break;
}
select = item;
action |= ACTION_SELECT | ACTION_DRAW;
}
select = item;
action |= ACTION_SELECT | ACTION_DRAW;
@@
-1304,7
+1352,7
@@
append:
case LeaveNotify:
previtem = NULL;
select = NULL;
case LeaveNotify:
previtem = NULL;
select = NULL;
- action = ACTION_SELECT | ACTION_DRAW;
+ action = ACTION_
CLEAR | ACTION_
SELECT | ACTION_DRAW;
break;
case ConfigureNotify:
menu = getmenu(currmenu, ev.xconfigure.window);
break;
case ConfigureNotify:
menu = getmenu(currmenu, ev.xconfigure.window);
@@
-1324,10
+1372,10
@@
append:
action = ACTION_MAP;
break;
}
action = ACTION_MAP;
break;
}
- if (action & ACTION_SELECT) {
- currmenu->selected = select;
+ if (action & ACTION_CLEAR)
text[0] = '\0';
text[0] = '\0';
- }
+ if (action & ACTION_SELECT)
+ currmenu->selected = select;
if (action & ACTION_MAP)
mapmenu(currmenu);
if (action & ACTION_DRAW)
if (action & ACTION_MAP)
mapmenu(currmenu);
if (action & ACTION_DRAW)
diff --git
a/xmenu.h
b/xmenu.h
index
bccc39e
..
b5f1556
100644
(file)
--- a/
xmenu.h
+++ b/
xmenu.h
@@
-2,9
+2,10
@@
/* Actions for the main loop */
#define ACTION_NOP 0
/* Actions for the main loop */
#define ACTION_NOP 0
-#define ACTION_SELECT 1<<0 /* select item and clear text */
-#define ACTION_MAP 1<<1 /* remap menu windows */
-#define ACTION_DRAW 1<<2 /* redraw menu windows */
+#define ACTION_CLEAR 1<<0 /* clear text */
+#define ACTION_SELECT 1<<1 /* select item */
+#define ACTION_MAP 1<<2 /* remap menu windows */
+#define ACTION_DRAW 1<<3 /* redraw menu windows */
/* enum for keyboard menu navigation */
enum { ITEMPREV, ITEMNEXT, ITEMFIRST, ITEMLAST };
/* enum for keyboard menu navigation */
enum { ITEMPREV, ITEMNEXT, ITEMFIRST, ITEMLAST };