implemented early keyboard grab for dmenu with a timeout for stdin data writers to prevent endless grabbings of the keyboard
32f7fe48
3 file(s) · +21 −4
| 8 | 8 | #define SELFGCOLOR "#eeeeee" |
|
| 9 | 9 | #define NORMBGCOLOR "#333333" |
|
| 10 | 10 | #define NORMFGCOLOR "#dddddd" |
|
| 11 | + | #define STDIN_TIMEOUT 3 /* seconds */ |
| 8 | 8 | #define SELFGCOLOR "#eeeeee" |
|
| 9 | 9 | #define NORMBGCOLOR "#333366" |
|
| 10 | 10 | #define NORMFGCOLOR "#cccccc" |
|
| 11 | + | #define STDIN_TIMEOUT 3 /* seconds */ |
| 11 | 11 | #include <stdio.h> |
|
| 12 | 12 | #include <string.h> |
|
| 13 | 13 | #include <unistd.h> |
|
| 14 | + | #include <sys/select.h> |
|
| 15 | + | #include <sys/time.h> |
|
| 14 | 16 | #include <X11/cursorfont.h> |
|
| 15 | 17 | #include <X11/Xutil.h> |
|
| 16 | 18 | #include <X11/keysym.h> |
|
| 290 | 292 | main(int argc, char *argv[]) |
|
| 291 | 293 | { |
|
| 292 | 294 | char *maxname; |
|
| 295 | + | fd_set rd; |
|
| 296 | + | struct timeval timeout; |
|
| 293 | 297 | Item *i; |
|
| 294 | 298 | XEvent ev; |
|
| 295 | 299 | XSetWindowAttributes wa; |
|
| 307 | 311 | screen = DefaultScreen(dpy); |
|
| 308 | 312 | root = RootWindow(dpy, screen); |
|
| 309 | 313 | ||
| 310 | - | maxname = readstdin(); |
|
| 311 | - | ||
| 312 | - | /* grab as early as possible, but after reading all items!!! */ |
|
| 314 | + | /* Note, the select() construction allows to grab all keypresses as |
|
| 315 | + | * early as possible, to not loose them. But if there is no standard |
|
| 316 | + | * input supplied, we will make sure to exit after MAX_WAIT_STDIN |
|
| 317 | + | * seconds. This is convenience behavior for rapid typers. |
|
| 318 | + | */ |
|
| 313 | 319 | while(XGrabKeyboard(dpy, root, True, GrabModeAsync, |
|
| 314 | 320 | GrabModeAsync, CurrentTime) != GrabSuccess) |
|
| 315 | 321 | usleep(1000); |
|
| 322 | + | ||
| 323 | + | timeout.tv_usec = 0; |
|
| 324 | + | timeout.tv_sec = STDIN_TIMEOUT; |
|
| 325 | + | FD_ZERO(&rd); |
|
| 326 | + | FD_SET(STDIN_FILENO, &rd); |
|
| 327 | + | if(select(ConnectionNumber(dpy) + 1, &rd, NULL, NULL, &timeout) < 1) |
|
| 328 | + | goto UninitializedEnd; |
|
| 329 | + | maxname = readstdin(); |
|
| 316 | 330 | ||
| 317 | 331 | /* style */ |
|
| 318 | 332 | dc.sel[ColBG] = getcolor(SELBGCOLOR); |
|
| 366 | 380 | } |
|
| 367 | 381 | } |
|
| 368 | 382 | ||
| 369 | - | XUngrabKeyboard(dpy, CurrentTime); |
|
| 370 | 383 | while(allitems) { |
|
| 371 | 384 | i = allitems->next; |
|
| 372 | 385 | free(allitems->text); |
|
| 380 | 393 | XFreePixmap(dpy, dc.drawable); |
|
| 381 | 394 | XFreeGC(dpy, dc.gc); |
|
| 382 | 395 | XDestroyWindow(dpy, win); |
|
| 396 | + | UninitializedEnd: |
|
| 397 | + | XUngrabKeyboard(dpy, CurrentTime); |
|
| 383 | 398 | XCloseDisplay(dpy); |
|
| 384 | 399 | ||
| 385 | 400 | return ret; |
|