Harden DWM plugins against X11 stacking/keyboard grab races and speed up QMI status
This commit is contained in:
+40
-10
@@ -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 ||
|
||||
|
||||
Reference in New Issue
Block a user