diff options
-rw-r--r-- | dmenu.c | 99 |
1 files changed, 40 insertions, 59 deletions
@@ -25,12 +25,9 @@ struct Item { | |||
25 | }; | 25 | }; |
26 | 26 | ||
27 | static void appenditem(Item *item, Item **list, Item **last); | 27 | static void appenditem(Item *item, Item **list, Item **last); |
28 | static void calcoffsetsh(void); | 28 | static void calcoffsets(void); |
29 | static void calcoffsetsv(void); | ||
30 | static char *cistrstr(const char *s, const char *sub); | 29 | static char *cistrstr(const char *s, const char *sub); |
31 | static void drawmenu(void); | 30 | static void drawmenu(void); |
32 | static void drawmenuh(void); | ||
33 | static void drawmenuv(void); | ||
34 | static void grabkeyboard(void); | 31 | static void grabkeyboard(void); |
35 | static void insert(const char *s, ssize_t n); | 32 | static void insert(const char *s, ssize_t n); |
36 | static void keypress(XKeyEvent *e); | 33 | static void keypress(XKeyEvent *e); |
@@ -63,7 +60,6 @@ static Window root, win; | |||
63 | 60 | ||
64 | static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; | 61 | static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; |
65 | static char *(*fstrstr)(const char *, const char *) = strstr; | 62 | static char *(*fstrstr)(const char *, const char *) = strstr; |
66 | static void (*calcoffsets)(void) = calcoffsetsh; | ||
67 | 63 | ||
68 | void | 64 | void |
69 | appenditem(Item *item, Item **list, Item **last) { | 65 | appenditem(Item *item, Item **list, Item **last) { |
@@ -77,29 +73,25 @@ appenditem(Item *item, Item **list, Item **last) { | |||
77 | } | 73 | } |
78 | 74 | ||
79 | void | 75 | void |
80 | calcoffsetsh(void) { | 76 | calcoffsets(void) |
81 | unsigned int w, x; | 77 | { |
78 | unsigned int h, i, n; | ||
82 | 79 | ||
83 | w = promptw + inputw + textw(dc, "<") + textw(dc, ">"); | 80 | h = dc->font.height+2; |
84 | for(x = w, next = curr; next; next = next->right) | 81 | if(lines > 0) |
85 | if((x += MIN(textw(dc, next->text), mw / 3)) > mw) | 82 | n = lines * h; |
83 | else | ||
84 | n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">")); | ||
85 | |||
86 | prev = next = curr; | ||
87 | for(i = 0; next; next = next->right) | ||
88 | if((i += (lines > 0) ? h : MIN(textw(dc, next->text), mw/3)) > n) | ||
86 | break; | 89 | break; |
87 | for(x = w, prev = curr; prev && prev->left; prev = prev->left) | 90 | for(i = 0; prev && prev->left; prev = prev->left) |
88 | if((x += MIN(textw(dc, prev->left->text), mw / 3)) > mw) | 91 | if((i += (lines > 0) ? h : MIN(textw(dc, prev->left->text), mw/3)) > n) |
89 | break; | 92 | break; |
90 | } | 93 | } |
91 | 94 | ||
92 | void | ||
93 | calcoffsetsv(void) { | ||
94 | unsigned int i; | ||
95 | |||
96 | next = prev = curr; | ||
97 | for(i = 0; i < lines && next; i++) | ||
98 | next = next->right; | ||
99 | for(i = 0; i < lines && prev && prev->left; i++) | ||
100 | prev = prev->left; | ||
101 | } | ||
102 | |||
103 | char * | 95 | char * |
104 | cistrstr(const char *s, const char *sub) { | 96 | cistrstr(const char *s, const char *sub) { |
105 | size_t len; | 97 | size_t len; |
@@ -112,6 +104,8 @@ cistrstr(const char *s, const char *sub) { | |||
112 | 104 | ||
113 | void | 105 | void |
114 | drawmenu(void) { | 106 | drawmenu(void) { |
107 | Item *item; | ||
108 | |||
115 | dc->x = 0; | 109 | dc->x = 0; |
116 | dc->y = 0; | 110 | dc->y = 0; |
117 | drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); | 111 | drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); |
@@ -129,42 +123,31 @@ drawmenu(void) { | |||
129 | dc->w = inputw; | 123 | dc->w = inputw; |
130 | drawtext(dc, text, normcol); | 124 | drawtext(dc, text, normcol); |
131 | drawrect(dc, textnw(dc, text, cursor) + dc->h/2 - 2, 2, 1, dc->h - 4, FG(dc, normcol)); | 125 | drawrect(dc, textnw(dc, text, cursor) + dc->h/2 - 2, 2, 1, dc->h - 4, FG(dc, normcol)); |
132 | if(lines > 0) | ||
133 | drawmenuv(); | ||
134 | else if(curr && (dc->w == inputw || curr->next)) | ||
135 | drawmenuh(); | ||
136 | commitdraw(dc, win); | ||
137 | } | ||
138 | |||
139 | void | ||
140 | drawmenuh(void) { | ||
141 | Item *item; | ||
142 | 126 | ||
143 | dc->x += inputw; | 127 | if(lines > 0) { |
144 | dc->w = textw(dc, "<"); | 128 | dc->y = topbar ? dc->h : 0; |
145 | if(curr->left) | 129 | dc->w = mw - dc->x; |
146 | drawtext(dc, "<", normcol); | 130 | for(item = curr; item != next; item = item->right) { |
147 | for(item = curr; item != next; item = item->right) { | 131 | drawtext(dc, item->text, (item == sel) ? selcol : normcol); |
148 | dc->x += dc->w; | 132 | dc->y += dc->h; |
149 | dc->w = MIN(textw(dc, item->text), mw / 3); | 133 | } |
150 | drawtext(dc, item->text, (item == sel) ? selcol : normcol); | ||
151 | } | 134 | } |
152 | dc->w = textw(dc, ">"); | 135 | else if(curr && (dc->w == inputw || curr->next)) { |
153 | dc->x = mw - dc->w; | 136 | dc->x += inputw; |
154 | if(next) | 137 | dc->w = textw(dc, "<"); |
155 | drawtext(dc, ">", normcol); | 138 | if(prev) |
156 | } | 139 | drawtext(dc, "<", normcol); |
157 | 140 | for(item = curr; item != next; item = item->right) { | |
158 | void | 141 | dc->x += dc->w; |
159 | drawmenuv(void) { | 142 | dc->w = MIN(textw(dc, item->text), mw/3); |
160 | Item *item; | 143 | drawtext(dc, item->text, (item == sel) ? selcol : normcol); |
161 | 144 | } | |
162 | dc->y = topbar ? dc->h : 0; | 145 | dc->w = textw(dc, ">"); |
163 | dc->w = mw - dc->x; | 146 | dc->x = mw - dc->w; |
164 | for(item = curr; item != next; item = item->right) { | 147 | if(next) |
165 | drawtext(dc, item->text, (item == sel) ? selcol : normcol); | 148 | drawtext(dc, ">", normcol); |
166 | dc->y += dc->h; | ||
167 | } | 149 | } |
150 | commitdraw(dc, win); | ||
168 | } | 151 | } |
169 | 152 | ||
170 | void | 153 | void |
@@ -494,7 +477,6 @@ setup(void) { | |||
494 | y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; | 477 | y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; |
495 | mw = DisplayWidth(dc->dpy, screen); | 478 | mw = DisplayWidth(dc->dpy, screen); |
496 | } | 479 | } |
497 | |||
498 | /* input window */ | 480 | /* input window */ |
499 | wa.override_redirect = True; | 481 | wa.override_redirect = True; |
500 | wa.background_pixmap = ParentRelative; | 482 | wa.background_pixmap = ParentRelative; |
@@ -543,8 +525,7 @@ main(int argc, char *argv[]) { | |||
543 | usage(); | 525 | usage(); |
544 | /* double flags */ | 526 | /* double flags */ |
545 | else if(!strcmp(argv[i], "-l")) { | 527 | else if(!strcmp(argv[i], "-l")) { |
546 | if((lines = atoi(argv[++i])) > 0) | 528 | lines = atoi(argv[++i]); |
547 | calcoffsets = calcoffsetsv; | ||
548 | } | 529 | } |
549 | else if(!strcmp(argv[i], "-p")) | 530 | else if(!strcmp(argv[i], "-p")) |
550 | prompt = argv[++i]; | 531 | prompt = argv[++i]; |