Harden DWM plugins against X11 stacking/keyboard grab races and speed up QMI status

This commit is contained in:
Luxferre
2026-10-25 14:14:21 +02:00
parent b2216c186f
commit e77be498bf
44 changed files with 432 additions and 211 deletions
+40 -10
View File
@@ -771,12 +771,32 @@ static int xdrawer_run_main(int argc, char** argv) {
}
};
auto isOtherPluginActive = [&]() {
static const char* kPids[] = {
"xdialer.pid", "xcalllog.pid", "xcallscreen.pid", "xcontacts.pid",
"xsms.pid", "xfiles.pid", "xcamera.pid", "xthemes.pid",
"xmodem.pid", "xnetworks.pid", "xringtones.pid", "xwallpapers.pid",
};
for (const char* pf : kPids) {
int p = readIntFile(getRuntimeFile(pf), -1);
if (p > 0 && ::kill(p, 0) == 0) {
return true;
}
}
if (::access("/tmp/dwm_plugin_dmenu.active", F_OK) == 0) {
return true;
}
return false;
};
auto showWindow = [&]() {
if (visible) {
return;
}
writeIntFile(pidPath, static_cast<int>(::getpid()));
closeOtherPlugin("xdialer.pid", "/tmp/dwm_plugin_dialer.fifo");
closeOtherPlugin("xcalllog.pid", "/tmp/dwm_plugin_calllog.fifo");
closeOtherPlugin("xcallscreen.pid", "/tmp/dwm_plugin_callscreen.fifo");
closeOtherPlugin("xcontacts.pid", "/tmp/dwm_plugin_contacts.fifo");
closeOtherPlugin("xsms.pid", "/tmp/dwm_plugin_sms.fifo");
closeOtherPlugin("xfiles.pid", "/tmp/dwm_plugin_files.fifo");
@@ -786,6 +806,13 @@ static int xdrawer_run_main(int argc, char** argv) {
closeOtherPlugin("xnetworks.pid", "/tmp/dwm_plugin_networks.fifo");
closeOtherPlugin("xringtones.pid", "/tmp/dwm_plugin_ringtones.fifo");
closeOtherPlugin("xwallpapers.pid", "/tmp/dwm_plugin_wallpapers.fifo");
if (::access("/tmp/dwm_plugin_dmenu.active", F_OK) == 0) {
int dfd = ::open("/tmp/dwm_plugin_dmenu.fifo", O_WRONLY | O_NONBLOCK | O_CLOEXEC);
if (dfd >= 0) {
(void)::write(dfd, "CLOSE\n", 6);
::close(dfd);
}
}
theme.checkAndReload(dpy, screen, visual, cmap, layoutMain, layoutSmall,
layoutIcon, nullptr, win);
openStartMs = nowMs();
@@ -794,24 +821,17 @@ static int xdrawer_run_main(int argc, char** argv) {
visible = true;
XMapRaised(dpy, win);
XCopyArea(dpy, pix, win, gc, 0, 0, kWinWidth, kWinHeight, 0, 0);
for (int i = 0; i < 20; ++i) {
for (int i = 0; i < 40; ++i) {
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime) ==
GrabSuccess) {
break;
}
usleep(2000);
usleep(3000);
}
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
XFlush(dpy);
writeIntFile(pidPath, static_cast<int>(::getpid()));
controller.refreshAll();
render();
if (::access("/tmp/dwm_plugin_dmenu.active", F_OK) == 0) {
int dfd = ::open("/tmp/dwm_plugin_dmenu.fifo", O_WRONLY | O_NONBLOCK | O_CLOEXEC);
if (dfd >= 0) {
(void)::write(dfd, "CLOSE\n", 6);
::close(dfd);
}
}
};
auto hideWindow = [&](bool drainSoftkeys) {
@@ -889,6 +909,16 @@ static int xdrawer_run_main(int argc, char** argv) {
if (ev.xexpose.count == 0) {
render();
}
} else if (ev.type == VisibilityNotify &&
ev.xvisibility.state != VisibilityUnobscured) {
if (isOtherPluginActive()) {
hideWindow(false);
} else {
XRaiseWindow(dpy, win);
XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
render();
}
} else if (ev.type == KeyRelease) {
KeySym sym = XLookupKeysym(&ev.xkey, 0);
if (sym == XK_Menu || sym == XF86XK_KbdLcdMenu1 ||