Harden DWM plugins against X11 stacking/keyboard grab races and speed up QMI status
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -65,10 +65,7 @@ detect_qmicli_modem() {
|
||||
if ! command -v qmicli >/dev/null 2>&1; then
|
||||
return 1
|
||||
fi
|
||||
if timeout 3 qmicli --silent -pd qrtr://0 --uim-noop >/dev/null 2>&1; then
|
||||
QMICLI_MODEM="timeout 4 qmicli --silent -pd qrtr://0"
|
||||
return 0
|
||||
elif [ -e "/dev/wwan0qmi0" ]; then
|
||||
if [ -e "/dev/wwan0qmi0" ]; then
|
||||
if timeout 3 qmicli --silent -pd /dev/wwan0qmi0 --device-open-qmi --uim-noop >/dev/null 2>&1; then
|
||||
QMICLI_MODEM="timeout 4 qmicli --silent -pd /dev/wwan0qmi0 --device-open-qmi"
|
||||
return 0
|
||||
@@ -76,6 +73,10 @@ detect_qmicli_modem() {
|
||||
QMICLI_MODEM="timeout 4 qmicli --silent -d /dev/wwan0qmi0 --device-open-qmi"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
if timeout 3 qmicli --silent -pd qrtr://0 --uim-noop >/dev/null 2>&1; then
|
||||
QMICLI_MODEM="timeout 4 qmicli --silent -pd qrtr://0"
|
||||
return 0
|
||||
elif [ -e "/dev/modem" ]; then
|
||||
if timeout 3 qmicli --silent -pd /dev/modem --uim-noop >/dev/null 2>&1; then
|
||||
QMICLI_MODEM="timeout 4 qmicli --silent -pd /dev/modem"
|
||||
@@ -636,26 +637,23 @@ case "$cmd" in
|
||||
;;
|
||||
|
||||
status)
|
||||
if ! detect_qmicli_modem; then
|
||||
echo "MODEM_AVAILABLE=0"
|
||||
echo "PREFERRED_SLOT=$PREFERRED_SIM_SLOT"
|
||||
exit 0
|
||||
QMI_CARDS=""
|
||||
if command -v qmicli >/dev/null 2>&1; then
|
||||
if [ -e "/dev/wwan0qmi0" ]; then
|
||||
QMI_CARDS="$(timeout 3 qmicli --silent -pd /dev/wwan0qmi0 --device-open-qmi --uim-get-card-status 2>/dev/null || true)"
|
||||
if [ -n "$QMI_CARDS" ]; then
|
||||
QMICLI_MODEM="timeout 3 qmicli --silent -pd /dev/wwan0qmi0 --device-open-qmi"
|
||||
fi
|
||||
fi
|
||||
if [ -z "$QMI_CARDS" ] && detect_qmicli_modem; then
|
||||
QMI_CARDS="$($QMICLI_MODEM --uim-get-card-status 2>/dev/null || true)"
|
||||
fi
|
||||
fi
|
||||
QMI_CARDS="$($QMICLI_MODEM --uim-get-card-status 2>/dev/null || true)"
|
||||
if [ -z "$QMI_CARDS" ]; then
|
||||
echo "MODEM_AVAILABLE=0"
|
||||
echo "PREFERRED_SLOT=$PREFERRED_SIM_SLOT"
|
||||
exit 0
|
||||
fi
|
||||
eval "$(parse_uim_card_status "$QMI_CARDS" "$PREFERRED_SIM_SLOT")"
|
||||
if [ "$PRIMARY_GW_SLOT" = "0" ] && { [ "$SLOT1_STATE" = "present" ] || [ "$SLOT2_STATE" = "present" ]; }; then
|
||||
SIM_WAIT_TIME=1
|
||||
provision_slot "$PREFERRED_SIM_SLOT" 2 >/dev/null 2>&1 || true
|
||||
QMI_CARDS_NEW="$($QMICLI_MODEM --uim-get-card-status 2>/dev/null || true)"
|
||||
if [ -n "$QMI_CARDS_NEW" ]; then
|
||||
QMI_CARDS="$QMI_CARDS_NEW"
|
||||
fi
|
||||
fi
|
||||
echo "MODEM_AVAILABLE=1"
|
||||
parse_uim_card_status "$QMI_CARDS" "$PREFERRED_SIM_SLOT"
|
||||
QMI_NAS="$($QMICLI_MODEM --nas-get-serving-system 2>/dev/null || true)"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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;
|
||||
|
||||
+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);
|
||||
|
||||
+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