implemented early keyboard grab for dmenu with a timeout for stdin data writers to prevent endless grabbings of the keyboard 32f7fe48
Anselm R. Garbe · 2006-09-08 07:33 3 file(s) · +21 −4
config.arg.h +1 −0
8 8
#define SELFGCOLOR		"#eeeeee"
9 9
#define NORMBGCOLOR		"#333333"
10 10
#define NORMFGCOLOR		"#dddddd"
11 +
#define STDIN_TIMEOUT		3 /* seconds */
config.default.h +1 −0
8 8
#define SELFGCOLOR		"#eeeeee"
9 9
#define NORMBGCOLOR		"#333366"
10 10
#define NORMFGCOLOR		"#cccccc"
11 +
#define STDIN_TIMEOUT		3 /* seconds */
main.c +19 −4
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;