Harden DWM plugins against X11 stacking/keyboard grab races and speed up QMI status
This commit is contained in:
@@ -333,6 +333,7 @@ int calllog_run_main(int argc, char** argv) {
|
||||
XSync(dpy, False);
|
||||
|
||||
auto showWindow = [&]() {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("calllog");
|
||||
bool themeChanged = theme.checkAndReload(
|
||||
dpy, screen, visual, cmap, layoutMain, layoutSmall, layoutIcon,
|
||||
@@ -348,13 +349,7 @@ int calllog_run_main(int argc, char** argv) {
|
||||
if (!themeChanged) {
|
||||
XCopyArea(dpy, pix, win, gc, 0, 0, kWinWidth, kWinHeight, 0, 0);
|
||||
}
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime) ==
|
||||
GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(2000);
|
||||
}
|
||||
grabPluginKeyboard(dpy, win);
|
||||
if (reloadLogsIfNeeded() || themeChanged || filterTab != 0 || selected != 0) {
|
||||
filterTab = 0;
|
||||
selected = 0;
|
||||
@@ -362,8 +357,9 @@ int calllog_run_main(int argc, char** argv) {
|
||||
render();
|
||||
}
|
||||
XFlush(dpy);
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
if (reloadLogsIfNeeded() || themeChanged) {
|
||||
render();
|
||||
}
|
||||
@@ -444,6 +440,15 @@ int calllog_run_main(int argc, char** argv) {
|
||||
if (ev.xexpose.count == 0) {
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == VisibilityNotify &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
if (isAnotherPluginActive("calllog")) {
|
||||
hideWindow(false);
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == KeyRelease) {
|
||||
KeySym sym = XLookupKeysym(&ev.xkey, 0);
|
||||
if (sym == XK_Menu || sym == XF86XK_KbdLcdMenu1 ||
|
||||
|
||||
@@ -926,6 +926,7 @@ int callscreen_run_main(int argc, char** argv) {
|
||||
XSync(dpy, False);
|
||||
|
||||
auto showWindow = [&]() {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("callscreen");
|
||||
wakeDisplayHardware(dpy);
|
||||
theme.checkAndReload(dpy, screen, visual, cmap, layoutMain, layoutSmall,
|
||||
@@ -942,17 +943,11 @@ int callscreen_run_main(int argc, char** argv) {
|
||||
visible = true;
|
||||
XMapRaised(dpy, win);
|
||||
render();
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime) ==
|
||||
GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(2000);
|
||||
}
|
||||
grabPluginKeyboard(dpy, win);
|
||||
XFlush(dpy);
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
} else {
|
||||
XMapRaised(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
render();
|
||||
}
|
||||
};
|
||||
@@ -1379,6 +1374,15 @@ int callscreen_run_main(int argc, char** argv) {
|
||||
if (ev.xexpose.count == 0) {
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == VisibilityNotify &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
if (isAnotherPluginActive("callscreen")) {
|
||||
hideWindow(false);
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == KeyRelease) {
|
||||
KeySym sym = XLookupKeysym(&ev.xkey, 0);
|
||||
if (sym == XK_Menu || sym == XF86XK_KbdLcdMenu1 ||
|
||||
|
||||
@@ -711,26 +711,19 @@ int runCameraApp(int argc, char** argv) {
|
||||
};
|
||||
|
||||
auto showWindow = [&](const std::string& argStr) {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("camera");
|
||||
countdownActive = false;
|
||||
torchOn = getTorchState();
|
||||
torchRestoredOnClose = !torchOn;
|
||||
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
if (!visible) {
|
||||
visible = true;
|
||||
XMapRaised(dpy, win);
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime) == GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(2000);
|
||||
}
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
}
|
||||
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
openStartMs = nowMs();
|
||||
startupIgnoreUntilMs = openStartMs + 180;
|
||||
initialSoftkeysReleased = (querySoftkeysDown(dpy) == 0);
|
||||
@@ -822,6 +815,15 @@ int runCameraApp(int argc, char** argv) {
|
||||
|
||||
if (ev.type == Expose && ev.xexpose.count == 0) {
|
||||
drawUI();
|
||||
} else if (ev.type == VisibilityNotify &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
if (isAnotherPluginActive("camera")) {
|
||||
hideWindow();
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
drawUI();
|
||||
}
|
||||
} else if (ev.type == KeyPress) {
|
||||
int64_t tNow = nowMs();
|
||||
unsigned int kc = ev.xkey.keycode;
|
||||
@@ -925,7 +927,9 @@ int runCameraApp(int argc, char** argv) {
|
||||
enterViewfinderMode();
|
||||
drawUI();
|
||||
} else {
|
||||
runAsyncArgv("feh", photos[selectedPhoto].fullPath.c_str());
|
||||
std::string path = photos[selectedPhoto].fullPath;
|
||||
hideWindow();
|
||||
runAsyncArgv("feh", path.c_str());
|
||||
}
|
||||
}
|
||||
} else if (mode == ViewMode::ConfirmDelete) {
|
||||
|
||||
@@ -765,6 +765,7 @@ int runContactsApp(int argc, char** argv) {
|
||||
};
|
||||
|
||||
auto showWindow = [&](const std::string& arg) {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("contacts");
|
||||
bool themeChanged = theme.checkAndReload(
|
||||
dpy, screen, visual, cmap, layoutMain, layoutSmall, layoutIcon,
|
||||
@@ -784,13 +785,7 @@ int runContactsApp(int argc, char** argv) {
|
||||
if (!openNewMode && !themeChanged) {
|
||||
XCopyArea(dpy, pix, win, gc, 0, 0, kWinWidth, kWinHeight, 0, 0);
|
||||
}
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime) ==
|
||||
GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(2000);
|
||||
}
|
||||
grabPluginKeyboard(dpy, win);
|
||||
bool reloaded = reloadContactsIfNeeded();
|
||||
if (openNewMode) {
|
||||
beginNewContact(prefill);
|
||||
@@ -804,8 +799,9 @@ int runContactsApp(int argc, char** argv) {
|
||||
render();
|
||||
}
|
||||
XFlush(dpy);
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
reloadContactsIfNeeded();
|
||||
if (openNewMode) {
|
||||
beginNewContact(prefill);
|
||||
@@ -914,9 +910,13 @@ int runContactsApp(int argc, char** argv) {
|
||||
render();
|
||||
int rc = 0;
|
||||
std::string out = runCaptureCmd(
|
||||
"doas /usr/libexec/msm-modem-uim-selection sim-contacts-import " +
|
||||
"doas -n /usr/libexec/msm-modem-uim-selection sim-contacts-import " +
|
||||
std::to_string(slotNum) + " 2>&1",
|
||||
&rc);
|
||||
if (visible) {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
}
|
||||
if (out.rfind("ERROR:", 0) == 0) {
|
||||
std::string err = trimStr(out.substr(6));
|
||||
setStatus(err.empty() ? "SIM import failed" : err, true);
|
||||
@@ -975,9 +975,13 @@ int runContactsApp(int argc, char** argv) {
|
||||
render();
|
||||
int rc = 0;
|
||||
std::string out = runCaptureCmd(
|
||||
"doas /usr/libexec/msm-modem-uim-selection sim-contacts-export " +
|
||||
"doas -n /usr/libexec/msm-modem-uim-selection sim-contacts-export " +
|
||||
std::to_string(slotNum) + " " + shellQuote(srcFile) + " 2>&1",
|
||||
&rc);
|
||||
if (visible) {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
}
|
||||
if (!tmpSingle.empty()) {
|
||||
::unlink(tmpSingle.c_str());
|
||||
}
|
||||
@@ -1015,7 +1019,11 @@ int runContactsApp(int argc, char** argv) {
|
||||
prevModeBeforeSim =
|
||||
(op == SimOp::ExportSingle) ? ViewMode::Detail : ViewMode::List;
|
||||
std::string st = runCaptureCmd(
|
||||
"doas /usr/libexec/msm-modem-uim-selection status 2>/dev/null");
|
||||
"doas -n /usr/libexec/msm-modem-uim-selection status 2>/dev/null");
|
||||
if (visible) {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
}
|
||||
bool s1Present = false;
|
||||
bool s2Present = false;
|
||||
int gwSlot = 1;
|
||||
@@ -1203,6 +1211,15 @@ int runContactsApp(int argc, char** argv) {
|
||||
if (ev.xexpose.count == 0) {
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == VisibilityNotify &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
if (isAnotherPluginActive("contacts")) {
|
||||
hideWindow(false);
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == KeyRelease) {
|
||||
KeySym sym = XLookupKeysym(&ev.xkey, 0);
|
||||
if (ev.xkey.keycode == 19 || sym == XK_0) {
|
||||
|
||||
@@ -509,10 +509,15 @@ int dialer_run_main(int argc, char** argv) {
|
||||
ussdReplyInput.clear();
|
||||
render();
|
||||
ussdResponse = sendModemUssd(codeOrReply, isReply, &ussdSessionActive);
|
||||
if (visible) {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
}
|
||||
render();
|
||||
};
|
||||
|
||||
auto showWindow = [&](const std::string& arg) {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("dialer");
|
||||
modal = DialerModal::Inactive;
|
||||
bool themeChanged = theme.checkAndReload(
|
||||
@@ -532,13 +537,7 @@ int dialer_run_main(int argc, char** argv) {
|
||||
if (cleanArg.empty() && !themeChanged) {
|
||||
XCopyArea(dpy, pix, win, gc, 0, 0, kWinWidth, kWinHeight, 0, 0);
|
||||
}
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime) ==
|
||||
GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(2000);
|
||||
}
|
||||
grabPluginKeyboard(dpy, win);
|
||||
bool reloaded = reloadContactsIfNeeded();
|
||||
if (cleanArg == "*#06#") {
|
||||
openImeiModal();
|
||||
@@ -549,8 +548,9 @@ int dialer_run_main(int argc, char** argv) {
|
||||
render();
|
||||
}
|
||||
XFlush(dpy);
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
} else if (!cleanArg.empty()) {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
if (nowMs() - openStartMs < 40 && number == cleanArg) {
|
||||
return;
|
||||
}
|
||||
@@ -675,6 +675,15 @@ int dialer_run_main(int argc, char** argv) {
|
||||
if (ev.xexpose.count == 0) {
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == VisibilityNotify &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
if (isAnotherPluginActive("dialer")) {
|
||||
hideWindow(false);
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == KeyRelease) {
|
||||
KeySym sym = XLookupKeysym(&ev.xkey, 0);
|
||||
if (ev.xkey.keycode == 19 || sym == XK_0) {
|
||||
|
||||
@@ -530,6 +530,16 @@ int runFilesApp(int argc, char** argv) {
|
||||
actionSelected = 0;
|
||||
};
|
||||
|
||||
auto hideWindow = [&]() {
|
||||
if (!visible) return;
|
||||
writeSoftkeySuppress(nowMs() + 450);
|
||||
XUngrabKeyboard(dpy, CurrentTime);
|
||||
XUnmapWindow(dpy, win);
|
||||
XFlush(dpy);
|
||||
visible = false;
|
||||
::unlink(activePidPath.c_str());
|
||||
};
|
||||
|
||||
auto openSelectedItem = [&]() {
|
||||
if (filteredItems.empty()) return;
|
||||
const FileItem item = filteredItems[selected];
|
||||
@@ -549,9 +559,9 @@ int runFilesApp(int argc, char** argv) {
|
||||
if (isImageExt(ext)) {
|
||||
openImageViewer(item);
|
||||
} else if (isMediaExt(ext)) {
|
||||
hideWindow();
|
||||
runAsyncArgv("sxmo_open.sh", item.fullPath.c_str());
|
||||
statusBanner = "Opening in media player...";
|
||||
statusBannerUntilMs = nowMs() + 1800;
|
||||
return;
|
||||
} else if (isLikelyTextFile(item.fullPath, item.size)) {
|
||||
openTextViewer(item);
|
||||
} else {
|
||||
@@ -889,24 +899,17 @@ int runFilesApp(int argc, char** argv) {
|
||||
};
|
||||
|
||||
auto showWindow = [&](const std::string& dirArg) {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("files");
|
||||
mode = ViewMode::Browser;
|
||||
loadDirectory(dirArg.empty() ? currentDir : dirArg);
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
if (!visible) {
|
||||
visible = true;
|
||||
XMapRaised(dpy, win);
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime) == GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(2000);
|
||||
}
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
}
|
||||
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
openStartMs = nowMs();
|
||||
startupIgnoreUntilMs = openStartMs + 180;
|
||||
initialSoftkeysReleased = (querySoftkeysDown(dpy) == 0);
|
||||
@@ -914,16 +917,6 @@ int runFilesApp(int argc, char** argv) {
|
||||
drawUI();
|
||||
};
|
||||
|
||||
auto hideWindow = [&]() {
|
||||
if (!visible) return;
|
||||
writeSoftkeySuppress(nowMs() + 450);
|
||||
XUngrabKeyboard(dpy, CurrentTime);
|
||||
XUnmapWindow(dpy, win);
|
||||
XFlush(dpy);
|
||||
visible = false;
|
||||
::unlink(activePidPath.c_str());
|
||||
};
|
||||
|
||||
auto commitModalTap = [&](int digit) {
|
||||
const char* chars = kMultiTapFile[digit];
|
||||
int len = static_cast<int>(std::strlen(chars));
|
||||
@@ -1157,6 +1150,15 @@ int runFilesApp(int argc, char** argv) {
|
||||
|
||||
if (ev.type == Expose && ev.xexpose.count == 0) {
|
||||
drawUI();
|
||||
} else if (ev.type == VisibilityNotify &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
if (isAnotherPluginActive("files")) {
|
||||
hideWindow();
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
drawUI();
|
||||
}
|
||||
} else if (ev.type == KeyPress) {
|
||||
int64_t tNow = nowMs();
|
||||
unsigned int kc = ev.xkey.keycode;
|
||||
|
||||
@@ -364,13 +364,26 @@ ModemStatusData queryModemAndSimStatus() {
|
||||
}
|
||||
|
||||
// 3. Query active SIM object if available
|
||||
static std::string cachedSimPath;
|
||||
static std::string cachedSimIccid;
|
||||
static std::string cachedSimOperator;
|
||||
if (!d.simDbusPath.empty()) {
|
||||
std::string simOut = runCaptureCmd(
|
||||
"mmcli -i " + shellQuote(d.simDbusPath) + " -K 2>/dev/null");
|
||||
std::unordered_map<std::string, std::string> simKv;
|
||||
parseKvLines(simOut, simKv, ':');
|
||||
d.simIccid = cleanMmVal(simKv["sim.properties.iccid"]);
|
||||
d.simOperatorName = cleanMmVal(simKv["sim.properties.operator-name"]);
|
||||
if (d.simDbusPath == cachedSimPath && !cachedSimIccid.empty()) {
|
||||
d.simIccid = cachedSimIccid;
|
||||
d.simOperatorName = cachedSimOperator;
|
||||
} else {
|
||||
std::string simOut = runCaptureCmd(
|
||||
"mmcli -i " + shellQuote(d.simDbusPath) + " -K 2>/dev/null");
|
||||
std::unordered_map<std::string, std::string> simKv;
|
||||
parseKvLines(simOut, simKv, ':');
|
||||
d.simIccid = cleanMmVal(simKv["sim.properties.iccid"]);
|
||||
d.simOperatorName = cleanMmVal(simKv["sim.properties.operator-name"]);
|
||||
if (!d.simIccid.empty()) {
|
||||
cachedSimPath = d.simDbusPath;
|
||||
cachedSimIccid = d.simIccid;
|
||||
cachedSimOperator = d.simOperatorName;
|
||||
}
|
||||
}
|
||||
if (d.operatorName.empty() && !d.simOperatorName.empty()) {
|
||||
d.operatorName = d.simOperatorName;
|
||||
}
|
||||
@@ -609,6 +622,10 @@ int runModemApp(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
lastRefreshMs = nowMs();
|
||||
if (visible && !isAnotherPluginActive("modem")) {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
}
|
||||
};
|
||||
|
||||
auto defaultActiveOrPresentSlot = [&]() -> int {
|
||||
@@ -1222,13 +1239,7 @@ int runModemApp(int argc, char** argv) {
|
||||
};
|
||||
|
||||
auto grabKeys = [&]() {
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime) == GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(15000);
|
||||
}
|
||||
grabPluginKeyboard(dpy, win);
|
||||
};
|
||||
|
||||
auto showWindow = [&](const std::string& arg = "") {
|
||||
@@ -1236,21 +1247,28 @@ int runModemApp(int argc, char** argv) {
|
||||
if (visible &&
|
||||
(modal == ModalMode::VerifyPin || modal == ModalMode::UnblockPuk) &&
|
||||
(a == "unlock" || a == "pin" || a == "puk")) {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("modem");
|
||||
XRaiseWindow(dpy, win);
|
||||
grabKeys();
|
||||
render();
|
||||
return;
|
||||
}
|
||||
closeOtherPlugins("modem");
|
||||
refreshData(true);
|
||||
applyOpenArg(arg);
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("modem");
|
||||
if (!visible) {
|
||||
XMapRaised(dpy, win);
|
||||
visible = true;
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
}
|
||||
grabKeys();
|
||||
render();
|
||||
refreshData(true);
|
||||
applyOpenArg(arg);
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("modem");
|
||||
XRaiseWindow(dpy, win);
|
||||
openStartMs = nowMs();
|
||||
startupIgnoreUntilMs = openStartMs + 180;
|
||||
initialSoftkeysReleased = (querySoftkeysDown(dpy) == 0);
|
||||
@@ -1446,6 +1464,10 @@ int runModemApp(int argc, char** argv) {
|
||||
if (ussdWaitingReply) {
|
||||
ussdInput.clear();
|
||||
}
|
||||
if (visible) {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabKeys();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1693,7 +1715,13 @@ int runModemApp(int argc, char** argv) {
|
||||
render();
|
||||
} else if (ev.type == VisibilityNotify && visible &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
XRaiseWindow(dpy, win);
|
||||
if (isAnotherPluginActive("modem")) {
|
||||
hideWindow();
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabKeys();
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == KeyRelease) {
|
||||
if (!initialSoftkeysReleased && querySoftkeysDown(dpy) == 0) {
|
||||
initialSoftkeysReleased = true;
|
||||
@@ -2033,14 +2061,14 @@ int runModemApp(int argc, char** argv) {
|
||||
timeoutMs = static_cast<int>(bRem);
|
||||
}
|
||||
}
|
||||
// Periodic 5-second status refresh while visible on SIM/Radio tabs
|
||||
// Periodic 10-second status refresh while visible on SIM/Radio tabs
|
||||
if (modal == ModalMode::None && activeTab != TabId::ModemLog &&
|
||||
activeTab != TabId::AtConsole) {
|
||||
int64_t rRem = (lastRefreshMs + 5000) - now;
|
||||
int64_t rRem = (lastRefreshMs + 10000) - now;
|
||||
if (rRem <= 0) {
|
||||
refreshData(false);
|
||||
render();
|
||||
rRem = 5000;
|
||||
rRem = 10000;
|
||||
}
|
||||
if (timeoutMs < 0 || rRem < timeoutMs) {
|
||||
timeoutMs = static_cast<int>(rRem);
|
||||
|
||||
@@ -923,25 +923,24 @@ int runNetworksApp(int argc, char** argv) {
|
||||
};
|
||||
|
||||
auto grabKeys = [&]() {
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime) == GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(15000);
|
||||
}
|
||||
grabPluginKeyboard(dpy, win);
|
||||
};
|
||||
|
||||
auto showWindow = [&](const std::string& arg = "") {
|
||||
closeOtherPlugins("networks");
|
||||
applyOpenArg(arg);
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("networks");
|
||||
if (!visible) {
|
||||
XMapRaised(dpy, win);
|
||||
visible = true;
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
}
|
||||
grabKeys();
|
||||
render();
|
||||
applyOpenArg(arg);
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("networks");
|
||||
XRaiseWindow(dpy, win);
|
||||
openStartMs = nowMs();
|
||||
startupIgnoreUntilMs = openStartMs + 180;
|
||||
initialSoftkeysReleased = (querySoftkeysDown(dpy) == 0);
|
||||
@@ -1256,7 +1255,13 @@ int runNetworksApp(int argc, char** argv) {
|
||||
render();
|
||||
} else if (ev.type == VisibilityNotify && visible &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
XRaiseWindow(dpy, win);
|
||||
if (isAnotherPluginActive("networks")) {
|
||||
hideWindow();
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabKeys();
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == KeyRelease) {
|
||||
if (!initialSoftkeysReleased && querySoftkeysDown(dpy) == 0) {
|
||||
initialSoftkeysReleased = true;
|
||||
|
||||
+103
-43
@@ -26,6 +26,7 @@
|
||||
#include <string>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
@@ -339,18 +340,24 @@ inline bool isKeycodeDown(Display* d, int keycode) {
|
||||
inline void runAsyncCmd(const std::string& cmd) {
|
||||
pid_t pid = ::fork();
|
||||
if (pid == 0) {
|
||||
::setsid();
|
||||
int nullfd = ::open("/dev/null", O_RDWR);
|
||||
if (nullfd >= 0) {
|
||||
::dup2(nullfd, STDIN_FILENO);
|
||||
::dup2(nullfd, STDOUT_FILENO);
|
||||
::dup2(nullfd, STDERR_FILENO);
|
||||
if (nullfd > 2) {
|
||||
::close(nullfd);
|
||||
if (::fork() == 0) {
|
||||
::setsid();
|
||||
int nullfd = ::open("/dev/null", O_RDWR);
|
||||
if (nullfd >= 0) {
|
||||
::dup2(nullfd, STDIN_FILENO);
|
||||
::dup2(nullfd, STDOUT_FILENO);
|
||||
::dup2(nullfd, STDERR_FILENO);
|
||||
if (nullfd > 2) {
|
||||
::close(nullfd);
|
||||
}
|
||||
}
|
||||
execl("/bin/sh", "sh", "-c", cmd.c_str(), static_cast<char*>(nullptr));
|
||||
_exit(0);
|
||||
}
|
||||
execl("/bin/sh", "sh", "-c", cmd.c_str(), static_cast<char*>(nullptr));
|
||||
_exit(0);
|
||||
} else if (pid > 0) {
|
||||
int st = 0;
|
||||
(void)::waitpid(pid, &st, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,42 +400,48 @@ inline void runAsyncArgv(const char* prog,
|
||||
const char* arg3 = nullptr) {
|
||||
pid_t pid = ::fork();
|
||||
if (pid == 0) {
|
||||
::setsid();
|
||||
int nullfd = ::open("/dev/null", O_RDWR);
|
||||
if (nullfd >= 0) {
|
||||
::dup2(nullfd, STDIN_FILENO);
|
||||
::dup2(nullfd, STDOUT_FILENO);
|
||||
::dup2(nullfd, STDERR_FILENO);
|
||||
if (nullfd > 2) {
|
||||
::close(nullfd);
|
||||
if (::fork() == 0) {
|
||||
::setsid();
|
||||
int nullfd = ::open("/dev/null", O_RDWR);
|
||||
if (nullfd >= 0) {
|
||||
::dup2(nullfd, STDIN_FILENO);
|
||||
::dup2(nullfd, STDOUT_FILENO);
|
||||
::dup2(nullfd, STDERR_FILENO);
|
||||
if (nullfd > 2) {
|
||||
::close(nullfd);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arg1 && arg2 && arg3) {
|
||||
execlp(prog, prog, arg1, arg2, arg3, static_cast<char*>(nullptr));
|
||||
std::string localBin = std::string("/home/user/.local/bin/") + prog;
|
||||
execl(localBin.c_str(), prog, arg1, arg2, arg3, static_cast<char*>(nullptr));
|
||||
std::string usrBin = std::string("/usr/bin/") + prog;
|
||||
execl(usrBin.c_str(), prog, arg1, arg2, arg3, static_cast<char*>(nullptr));
|
||||
} else if (arg1 && arg2) {
|
||||
execlp(prog, prog, arg1, arg2, static_cast<char*>(nullptr));
|
||||
std::string localBin = std::string("/home/user/.local/bin/") + prog;
|
||||
execl(localBin.c_str(), prog, arg1, arg2, static_cast<char*>(nullptr));
|
||||
std::string usrBin = std::string("/usr/bin/") + prog;
|
||||
execl(usrBin.c_str(), prog, arg1, arg2, static_cast<char*>(nullptr));
|
||||
} else if (arg1) {
|
||||
execlp(prog, prog, arg1, static_cast<char*>(nullptr));
|
||||
std::string localBin = std::string("/home/user/.local/bin/") + prog;
|
||||
execl(localBin.c_str(), prog, arg1, static_cast<char*>(nullptr));
|
||||
std::string usrBin = std::string("/usr/bin/") + prog;
|
||||
execl(usrBin.c_str(), prog, arg1, static_cast<char*>(nullptr));
|
||||
} else {
|
||||
execlp(prog, prog, static_cast<char*>(nullptr));
|
||||
std::string localBin = std::string("/home/user/.local/bin/") + prog;
|
||||
execl(localBin.c_str(), prog, static_cast<char*>(nullptr));
|
||||
std::string usrBin = std::string("/usr/bin/") + prog;
|
||||
execl(usrBin.c_str(), prog, static_cast<char*>(nullptr));
|
||||
if (arg1 && arg2 && arg3) {
|
||||
execlp(prog, prog, arg1, arg2, arg3, static_cast<char*>(nullptr));
|
||||
std::string localBin = std::string("/home/user/.local/bin/") + prog;
|
||||
execl(localBin.c_str(), prog, arg1, arg2, arg3, static_cast<char*>(nullptr));
|
||||
std::string usrBin = std::string("/usr/bin/") + prog;
|
||||
execl(usrBin.c_str(), prog, arg1, arg2, arg3, static_cast<char*>(nullptr));
|
||||
} else if (arg1 && arg2) {
|
||||
execlp(prog, prog, arg1, arg2, static_cast<char*>(nullptr));
|
||||
std::string localBin = std::string("/home/user/.local/bin/") + prog;
|
||||
execl(localBin.c_str(), prog, arg1, arg2, static_cast<char*>(nullptr));
|
||||
std::string usrBin = std::string("/usr/bin/") + prog;
|
||||
execl(usrBin.c_str(), prog, arg1, arg2, static_cast<char*>(nullptr));
|
||||
} else if (arg1) {
|
||||
execlp(prog, prog, arg1, static_cast<char*>(nullptr));
|
||||
std::string localBin = std::string("/home/user/.local/bin/") + prog;
|
||||
execl(localBin.c_str(), prog, arg1, static_cast<char*>(nullptr));
|
||||
std::string usrBin = std::string("/usr/bin/") + prog;
|
||||
execl(usrBin.c_str(), prog, arg1, static_cast<char*>(nullptr));
|
||||
} else {
|
||||
execlp(prog, prog, static_cast<char*>(nullptr));
|
||||
std::string localBin = std::string("/home/user/.local/bin/") + prog;
|
||||
execl(localBin.c_str(), prog, static_cast<char*>(nullptr));
|
||||
std::string usrBin = std::string("/usr/bin/") + prog;
|
||||
execl(usrBin.c_str(), prog, static_cast<char*>(nullptr));
|
||||
}
|
||||
_exit(0);
|
||||
}
|
||||
_exit(0);
|
||||
} else if (pid > 0) {
|
||||
int st = 0;
|
||||
(void)::waitpid(pid, &st, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1152,11 +1165,58 @@ inline void closeOtherPlugins(const char* selfPluginName) {
|
||||
sendPluginCommand(p.name, "CLOSE");
|
||||
}
|
||||
}
|
||||
if (::access("/tmp/dwm_plugin_dmenu.active", F_OK) == 0) {
|
||||
if ((!selfPluginName || std::strcmp(selfPluginName, "dmenu") != 0) &&
|
||||
::access("/tmp/dwm_plugin_dmenu.active", F_OK) == 0) {
|
||||
sendPluginCommand("dmenu", "CLOSE");
|
||||
}
|
||||
}
|
||||
|
||||
inline bool isAnotherPluginActive(const char* selfPluginName) {
|
||||
struct PluginRef {
|
||||
const char* pidFile;
|
||||
const char* name;
|
||||
};
|
||||
static const PluginRef kAllPlugins[] = {
|
||||
{"xdrawer.pid", "xdrawer"},
|
||||
{"xdialer.pid", "dialer"},
|
||||
{"xcalllog.pid", "calllog"},
|
||||
{"xcallscreen.pid", "callscreen"},
|
||||
{"xcontacts.pid", "contacts"},
|
||||
{"xsms.pid", "sms"},
|
||||
{"xfiles.pid", "files"},
|
||||
{"xcamera.pid", "camera"},
|
||||
{"xthemes.pid", "themes"},
|
||||
{"xmodem.pid", "modem"},
|
||||
{"xnetworks.pid", "networks"},
|
||||
{"xringtones.pid", "ringtones"},
|
||||
{"xwallpapers.pid", "wallpapers"},
|
||||
};
|
||||
for (const auto& p : kAllPlugins) {
|
||||
if (selfPluginName && std::strcmp(p.name, selfPluginName) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (isPidFileAlive(getRuntimeFile(p.pidFile))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ((!selfPluginName || std::strcmp(selfPluginName, "dmenu") != 0) &&
|
||||
::access("/tmp/dwm_plugin_dmenu.active", F_OK) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void grabPluginKeyboard(Display* dpy, Window win) {
|
||||
for (int i = 0; i < 40; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime) == GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
::usleep(3000);
|
||||
}
|
||||
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
|
||||
}
|
||||
|
||||
inline void broadcastThemeReload(const char* selfPluginName = nullptr) {
|
||||
static const char* kPlugins[] = {
|
||||
"dmenu",
|
||||
|
||||
@@ -576,6 +576,7 @@ int runRingtonesApp(int argc, char** argv) {
|
||||
};
|
||||
|
||||
auto showWindow = [&]() {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("ringtones");
|
||||
refreshData();
|
||||
for (size_t i = 0; i < tones.size(); ++i) {
|
||||
@@ -584,7 +585,6 @@ int runRingtonesApp(int argc, char** argv) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
if (!visible) {
|
||||
visible = true;
|
||||
XMapRaised(dpy, win);
|
||||
@@ -592,14 +592,7 @@ int runRingtonesApp(int argc, char** argv) {
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
}
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime) == GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(2000);
|
||||
}
|
||||
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
startupIgnoreUntilMs = nowMs() + 180;
|
||||
initialSoftkeysReleased = (querySoftkeysDown(dpy) == 0);
|
||||
softkeyPending = 0;
|
||||
@@ -688,7 +681,13 @@ int runRingtonesApp(int argc, char** argv) {
|
||||
render();
|
||||
} else if (ev.type == VisibilityNotify && visible &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
XRaiseWindow(dpy, win);
|
||||
if (isAnotherPluginActive("ringtones")) {
|
||||
hideWindow();
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == KeyRelease) {
|
||||
if (!initialSoftkeysReleased && querySoftkeysDown(dpy) == 0) {
|
||||
initialSoftkeysReleased = true;
|
||||
|
||||
@@ -862,6 +862,7 @@ int runSmsApp(int argc, char** argv) {
|
||||
};
|
||||
|
||||
auto showWindow = [&](const std::string& argStr) {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("sms");
|
||||
reloadAllData(true);
|
||||
lastTapDigit = -1;
|
||||
@@ -881,21 +882,13 @@ int runSmsApp(int argc, char** argv) {
|
||||
selectedThread = 0;
|
||||
}
|
||||
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
if (!visible) {
|
||||
visible = true;
|
||||
XMapRaised(dpy, win);
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime) == GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(2000);
|
||||
}
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
}
|
||||
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
openStartMs = nowMs();
|
||||
startupIgnoreUntilMs = openStartMs + 180;
|
||||
initialSoftkeysReleased = (querySoftkeysDown(dpy) == 0);
|
||||
@@ -1117,6 +1110,15 @@ int runSmsApp(int argc, char** argv) {
|
||||
|
||||
if (ev.type == Expose && ev.xexpose.count == 0) {
|
||||
drawUI();
|
||||
} else if (ev.type == VisibilityNotify &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
if (isAnotherPluginActive("sms")) {
|
||||
hideWindow();
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
drawUI();
|
||||
}
|
||||
} else if (ev.type == KeyRelease) {
|
||||
unsigned int kc = ev.xkey.keycode;
|
||||
KeySym sym = XLookupKeysym(&ev.xkey, 0);
|
||||
|
||||
@@ -871,24 +871,17 @@ int runThemesApp(int argc, char** argv) {
|
||||
};
|
||||
|
||||
auto showWindow = [&](const std::string& argStr) {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("themes");
|
||||
mode = ViewMode::Browser;
|
||||
refreshThemes(argStr);
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
if (!visible) {
|
||||
visible = true;
|
||||
XMapRaised(dpy, win);
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime) == GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(2000);
|
||||
}
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
}
|
||||
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
openStartMs = nowMs();
|
||||
startupIgnoreUntilMs = openStartMs + 180;
|
||||
initialSoftkeysReleased = (querySoftkeysDown(dpy) == 0);
|
||||
@@ -1132,6 +1125,15 @@ int runThemesApp(int argc, char** argv) {
|
||||
|
||||
if (ev.type == Expose && ev.xexpose.count == 0) {
|
||||
drawUI();
|
||||
} else if (ev.type == VisibilityNotify &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
if (isAnotherPluginActive("themes")) {
|
||||
hideWindow();
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
drawUI();
|
||||
}
|
||||
} else if (ev.type == KeyPress) {
|
||||
int64_t tNow = nowMs();
|
||||
unsigned int kc = ev.xkey.keycode;
|
||||
|
||||
@@ -504,6 +504,7 @@ int runWallpapersApp(int argc, char** argv) {
|
||||
};
|
||||
|
||||
auto showWindow = [&]() {
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
closeOtherPlugins("wallpapers");
|
||||
fullscreenPreview = false;
|
||||
refreshData();
|
||||
@@ -514,7 +515,6 @@ int runWallpapersApp(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
updatePreviewCache();
|
||||
writeIntFile(activePidPath, static_cast<int>(::getpid()));
|
||||
if (!visible) {
|
||||
visible = true;
|
||||
XMapRaised(dpy, win);
|
||||
@@ -522,14 +522,7 @@ int runWallpapersApp(int argc, char** argv) {
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
}
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime) == GrabSuccess) {
|
||||
break;
|
||||
}
|
||||
usleep(2000);
|
||||
}
|
||||
XSetInputFocus(dpy, win, RevertToPointerRoot, CurrentTime);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
startupIgnoreUntilMs = nowMs() + 180;
|
||||
initialSoftkeysReleased = (querySoftkeysDown(dpy) == 0);
|
||||
softkeyPending = 0;
|
||||
@@ -583,7 +576,13 @@ int runWallpapersApp(int argc, char** argv) {
|
||||
render();
|
||||
} else if (ev.type == VisibilityNotify && visible &&
|
||||
ev.xvisibility.state != VisibilityUnobscured) {
|
||||
XRaiseWindow(dpy, win);
|
||||
if (isAnotherPluginActive("wallpapers")) {
|
||||
hideWindow();
|
||||
} else {
|
||||
XRaiseWindow(dpy, win);
|
||||
grabPluginKeyboard(dpy, win);
|
||||
render();
|
||||
}
|
||||
} else if (ev.type == KeyRelease) {
|
||||
if (!initialSoftkeysReleased && querySoftkeysDown(dpy) == 0) {
|
||||
initialSoftkeysReleased = true;
|
||||
|
||||
Reference in New Issue
Block a user