diff options
-rw-r--r-- | dmenu.c | 44 |
1 files changed, 19 insertions, 25 deletions
@@ -30,7 +30,7 @@ static char *cistrstr(const char *s, const char *sub); | |||
30 | static void drawmenu(void); | 30 | static void drawmenu(void); |
31 | static void grabkeyboard(void); | 31 | static void grabkeyboard(void); |
32 | static void insert(const char *s, ssize_t n); | 32 | static void insert(const char *s, ssize_t n); |
33 | static void keypress(XKeyEvent *e); | 33 | static void keypress(XKeyEvent *ev); |
34 | static void match(void); | 34 | static void match(void); |
35 | static void paste(void); | 35 | static void paste(void); |
36 | static void readstdin(void); | 36 | static void readstdin(void); |
@@ -73,8 +73,7 @@ appenditem(Item *item, Item **list, Item **last) { | |||
73 | } | 73 | } |
74 | 74 | ||
75 | void | 75 | void |
76 | calcoffsets(void) | 76 | calcoffsets(void) { |
77 | { | ||
78 | unsigned int h, i, n; | 77 | unsigned int h, i, n; |
79 | 78 | ||
80 | h = dc->font.height+2; | 79 | h = dc->font.height+2; |
@@ -104,26 +103,24 @@ cistrstr(const char *s, const char *sub) { | |||
104 | 103 | ||
105 | void | 104 | void |
106 | drawmenu(void) { | 105 | drawmenu(void) { |
106 | int curpos; | ||
107 | Item *item; | 107 | Item *item; |
108 | 108 | ||
109 | dc->x = 0; | 109 | dc->x = 0; |
110 | dc->y = 0; | 110 | dc->y = 0; |
111 | drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); | 111 | drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); |
112 | |||
113 | dc->h = dc->font.height + 2; | 112 | dc->h = dc->font.height + 2; |
114 | dc->y = topbar ? 0 : mh - dc->h; | 113 | dc->y = topbar ? 0 : mh - dc->h; |
115 | /* print prompt? */ | 114 | |
116 | if(prompt) { | 115 | if(prompt) { |
117 | dc->w = promptw; | 116 | dc->w = promptw; |
118 | drawtext(dc, prompt, selcol); | 117 | drawtext(dc, prompt, selcol); |
119 | dc->x = dc->w; | 118 | dc->x = dc->w; |
120 | } | 119 | } |
121 | dc->w = mw - dc->x; | 120 | dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; |
122 | /* print input field */ | ||
123 | if(matches && lines == 0 && textw(dc, text) <= inputw) | ||
124 | dc->w = inputw; | ||
125 | drawtext(dc, text, normcol); | 121 | drawtext(dc, text, normcol); |
126 | drawrect(dc, textnw(dc, text, cursor) + dc->h/2 - 2, 2, 1, dc->h - 4, FG(dc, normcol)); | 122 | if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) |
123 | drawrect(dc, curpos, 2, 1, dc->h - 4, FG(dc, normcol)); | ||
127 | 124 | ||
128 | if(lines > 0) { | 125 | if(lines > 0) { |
129 | dc->y = topbar ? dc->h : 0; | 126 | dc->y = topbar ? dc->h : 0; |
@@ -133,7 +130,7 @@ drawmenu(void) { | |||
133 | dc->y += dc->h; | 130 | dc->y += dc->h; |
134 | } | 131 | } |
135 | } | 132 | } |
136 | else if(curr && (dc->w == inputw || curr->next)) { | 133 | else if(matches) { |
137 | dc->x += inputw; | 134 | dc->x += inputw; |
138 | dc->w = textw(dc, "<"); | 135 | dc->w = textw(dc, "<"); |
139 | if(curr->left) | 136 | if(curr->left) |
@@ -173,15 +170,15 @@ insert(const char *s, ssize_t n) { | |||
173 | } | 170 | } |
174 | 171 | ||
175 | void | 172 | void |
176 | keypress(XKeyEvent *e) { | 173 | keypress(XKeyEvent *ev) { |
177 | char buf[sizeof text]; | 174 | char buf[32]; |
178 | int n; | 175 | int n; |
179 | size_t len; | 176 | size_t len; |
180 | KeySym ksym; | 177 | KeySym ksym; |
181 | 178 | ||
182 | len = strlen(text); | 179 | len = strlen(text); |
183 | XLookupString(e, buf, sizeof buf, &ksym, NULL); | 180 | XLookupString(ev, buf, sizeof buf, &ksym, NULL); |
184 | if(e->state & ControlMask) { | 181 | if(ev->state & ControlMask) { |
185 | switch(tolower(ksym)) { | 182 | switch(tolower(ksym)) { |
186 | default: | 183 | default: |
187 | return; | 184 | return; |
@@ -235,7 +232,6 @@ keypress(XKeyEvent *e) { | |||
235 | break; | 232 | break; |
236 | case XK_y: /* paste selection */ | 233 | case XK_y: /* paste selection */ |
237 | XConvertSelection(dc->dpy, XA_PRIMARY, utf8, None, win, CurrentTime); | 234 | XConvertSelection(dc->dpy, XA_PRIMARY, utf8, None, win, CurrentTime); |
238 | /* causes SelectionNotify event */ | ||
239 | return; | 235 | return; |
240 | } | 236 | } |
241 | } | 237 | } |
@@ -289,8 +285,7 @@ keypress(XKeyEvent *e) { | |||
289 | case XK_Up: | 285 | case XK_Up: |
290 | if(!sel || !sel->left) | 286 | if(!sel || !sel->left) |
291 | return; | 287 | return; |
292 | sel = sel->left; | 288 | if((sel = sel->left)->right == curr) { |
293 | if(sel->right == curr) { | ||
294 | curr = prev; | 289 | curr = prev; |
295 | calcoffsets(); | 290 | calcoffsets(); |
296 | } | 291 | } |
@@ -309,7 +304,7 @@ keypress(XKeyEvent *e) { | |||
309 | break; | 304 | break; |
310 | case XK_Return: | 305 | case XK_Return: |
311 | case XK_KP_Enter: | 306 | case XK_KP_Enter: |
312 | fputs((sel && !(e->state & ShiftMask)) ? sel->text : text, stdout); | 307 | fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); |
313 | fflush(stdout); | 308 | fflush(stdout); |
314 | exit(EXIT_SUCCESS); | 309 | exit(EXIT_SUCCESS); |
315 | case XK_Right: | 310 | case XK_Right: |
@@ -322,8 +317,7 @@ keypress(XKeyEvent *e) { | |||
322 | case XK_Down: | 317 | case XK_Down: |
323 | if(!sel || !sel->right) | 318 | if(!sel || !sel->right) |
324 | return; | 319 | return; |
325 | sel = sel->right; | 320 | if((sel = sel->right) == next) { |
326 | if(sel == next) { | ||
327 | curr = next; | 321 | curr = next; |
328 | calcoffsets(); | 322 | calcoffsets(); |
329 | } | 323 | } |
@@ -404,7 +398,7 @@ readstdin(void) { | |||
404 | if(!(new = malloc(sizeof *new))) | 398 | if(!(new = malloc(sizeof *new))) |
405 | eprintf("cannot malloc %u bytes\n", sizeof *new); | 399 | eprintf("cannot malloc %u bytes\n", sizeof *new); |
406 | if(!(new->text = strdup(buf))) | 400 | if(!(new->text = strdup(buf))) |
407 | eprintf("cannot strdup %u bytes\n", strlen(buf)); | 401 | eprintf("cannot strdup %u bytes\n", strlen(buf)+1); |
408 | inputw = MAX(inputw, textw(dc, new->text)); | 402 | inputw = MAX(inputw, textw(dc, new->text)); |
409 | new->next = new->left = new->right = NULL; | 403 | new->next = new->left = new->right = NULL; |
410 | if(item) | 404 | if(item) |
@@ -485,9 +479,9 @@ setup(void) { | |||
485 | wa.background_pixmap = ParentRelative; | 479 | wa.background_pixmap = ParentRelative; |
486 | wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; | 480 | wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; |
487 | win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, | 481 | win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, |
488 | DefaultDepth(dc->dpy, screen), CopyFromParent, | 482 | DefaultDepth(dc->dpy, screen), CopyFromParent, |
489 | DefaultVisual(dc->dpy, screen), | 483 | DefaultVisual(dc->dpy, screen), |
490 | CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); | 484 | CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); |
491 | 485 | ||
492 | grabkeyboard(); | 486 | grabkeyboard(); |
493 | setcanvas(dc, mw, mh); | 487 | setcanvas(dc, mw, mh); |