Harden DWM plugins against X11 stacking/keyboard grab races and speed up QMI status
This commit is contained in:
+63
-6
@@ -475,19 +475,21 @@ grabfocus(void)
|
||||
static void
|
||||
grabkeyboard(void)
|
||||
{
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 2000000 };
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 3000000 };
|
||||
Window grabwin;
|
||||
int i;
|
||||
|
||||
if (embed || managed)
|
||||
return;
|
||||
grabwin = daemon_mode ? win : DefaultRootWindow(dpy);
|
||||
for (i = 0; i < 25; i++) {
|
||||
for (i = 0; i < 40; i++) {
|
||||
if (XGrabKeyboard(dpy, grabwin, True, GrabModeAsync,
|
||||
GrabModeAsync, CurrentTime) == GrabSuccess)
|
||||
return;
|
||||
break;
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
if (win)
|
||||
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2385,6 +2387,46 @@ open_builtin_menu(const char *menu_name, int keep_idx)
|
||||
show_menu();
|
||||
}
|
||||
|
||||
static int
|
||||
any_other_plugin_active(void)
|
||||
{
|
||||
static const char *pid_files[] = {
|
||||
"xdrawer.pid",
|
||||
"xdialer.pid",
|
||||
"xcalllog.pid",
|
||||
"xcallscreen.pid",
|
||||
"xcontacts.pid",
|
||||
"xsms.pid",
|
||||
"xfiles.pid",
|
||||
"xcamera.pid",
|
||||
"xthemes.pid",
|
||||
"xmodem.pid",
|
||||
"xnetworks.pid",
|
||||
"xringtones.pid",
|
||||
"xwallpapers.pid",
|
||||
};
|
||||
const char *rdir = getenv("XDG_RUNTIME_DIR");
|
||||
const char *base = (rdir && rdir[0]) ? rdir : "/run/user/10000";
|
||||
for (size_t i = 0; i < LENGTH(pid_files); i++) {
|
||||
char ppath[256];
|
||||
snprintf(ppath, sizeof(ppath), "%s/%s", base, pid_files[i]);
|
||||
if (access(ppath, F_OK) != 0)
|
||||
snprintf(ppath, sizeof(ppath), "/tmp/%s", pid_files[i]);
|
||||
if (access(ppath, F_OK) == 0) {
|
||||
FILE *pf = fopen(ppath, "r");
|
||||
if (pf) {
|
||||
int pid = -1;
|
||||
if (fscanf(pf, "%d", &pid) == 1 && pid > 0 && kill(pid, 0) == 0) {
|
||||
fclose(pf);
|
||||
return 1;
|
||||
}
|
||||
fclose(pf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
close_other_active_plugins(void)
|
||||
{
|
||||
@@ -2639,6 +2681,8 @@ show_menu(void)
|
||||
soft_deadline = 0;
|
||||
|
||||
if (!menu_active) {
|
||||
menu_active = 1;
|
||||
mark_menu_active(1);
|
||||
close_other_active_plugins();
|
||||
prevfocuswin = None;
|
||||
Window fw = None;
|
||||
@@ -2654,8 +2698,6 @@ show_menu(void)
|
||||
read_softkey_state(&init_soft_mask, &init_soft_ms);
|
||||
start_ignore = dmenu_now_ms() + 180;
|
||||
initial_released = (query_trigger_keys_down() == 0);
|
||||
menu_active = 1;
|
||||
mark_menu_active(1);
|
||||
drawmenu();
|
||||
XMapRaised(dpy, win);
|
||||
drawmenu();
|
||||
@@ -2666,11 +2708,13 @@ show_menu(void)
|
||||
XSetICFocus(xic);
|
||||
XFlush(dpy);
|
||||
} else {
|
||||
close_other_active_plugins();
|
||||
init_soft_mask = 0;
|
||||
init_soft_ms = 0;
|
||||
start_ignore = dmenu_now_ms() + 60;
|
||||
initial_released = (query_trigger_keys_down() == 0);
|
||||
XRaiseWindow(dpy, win);
|
||||
grabkeyboard();
|
||||
drawmenu();
|
||||
if (xic && engage_ime)
|
||||
XSetICFocus(xic);
|
||||
@@ -2975,6 +3019,19 @@ process_x11_events(void)
|
||||
if (ev.xexpose.count == 0 && (menu_active || !daemon_mode))
|
||||
drw_map(drw, win, 0, 0, mw, mh);
|
||||
break;
|
||||
case VisibilityNotify:
|
||||
if (ev.xvisibility.state != VisibilityUnobscured &&
|
||||
(menu_active || !daemon_mode)) {
|
||||
if (any_other_plugin_active()) {
|
||||
if (daemon_mode)
|
||||
cancel_session();
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabkeyboard();
|
||||
drw_map(drw, win, 0, 0, mw, mh);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FocusIn:
|
||||
if (menu_active || !daemon_mode) {
|
||||
if (!daemon_mode && ev.xfocus.window != win)
|
||||
@@ -3186,7 +3243,7 @@ setup(int map_immediately)
|
||||
|
||||
swa.override_redirect = managed ? False : True;
|
||||
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
|
||||
swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask;
|
||||
swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | VisibilityChangeMask;
|
||||
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width,
|
||||
CopyFromParent, CopyFromParent, CopyFromParent,
|
||||
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
|
||||
|
||||
Reference in New Issue
Block a user