diff --git a/overlay/rootfs/usr/lib/dwm/plugins/calllog.so b/overlay/rootfs/usr/lib/dwm/plugins/calllog.so index eab3d7f..d24c14e 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/calllog.so and b/overlay/rootfs/usr/lib/dwm/plugins/calllog.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/callscreen.so b/overlay/rootfs/usr/lib/dwm/plugins/callscreen.so index 07a3cb6..b0bbacf 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/callscreen.so and b/overlay/rootfs/usr/lib/dwm/plugins/callscreen.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/camera.so b/overlay/rootfs/usr/lib/dwm/plugins/camera.so index 002e755..cd22e27 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/camera.so and b/overlay/rootfs/usr/lib/dwm/plugins/camera.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/contacts.so b/overlay/rootfs/usr/lib/dwm/plugins/contacts.so index b3c9f89..bf638a5 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/contacts.so and b/overlay/rootfs/usr/lib/dwm/plugins/contacts.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/dialer.so b/overlay/rootfs/usr/lib/dwm/plugins/dialer.so index 838980b..c788fde 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/dialer.so and b/overlay/rootfs/usr/lib/dwm/plugins/dialer.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/dmenu.so b/overlay/rootfs/usr/lib/dwm/plugins/dmenu.so index 2fcaa97..cda8920 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/dmenu.so and b/overlay/rootfs/usr/lib/dwm/plugins/dmenu.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/files.so b/overlay/rootfs/usr/lib/dwm/plugins/files.so index d6fec41..ce001d6 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/files.so and b/overlay/rootfs/usr/lib/dwm/plugins/files.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/modem.so b/overlay/rootfs/usr/lib/dwm/plugins/modem.so index 320ea0a..07c212d 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/modem.so and b/overlay/rootfs/usr/lib/dwm/plugins/modem.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/networks.so b/overlay/rootfs/usr/lib/dwm/plugins/networks.so index 9c35911..b346e60 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/networks.so and b/overlay/rootfs/usr/lib/dwm/plugins/networks.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/ringtones.so b/overlay/rootfs/usr/lib/dwm/plugins/ringtones.so index 3440c43..99f492c 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/ringtones.so and b/overlay/rootfs/usr/lib/dwm/plugins/ringtones.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/sms.so b/overlay/rootfs/usr/lib/dwm/plugins/sms.so index 90d5cdc..e56ded6 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/sms.so and b/overlay/rootfs/usr/lib/dwm/plugins/sms.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/themes.so b/overlay/rootfs/usr/lib/dwm/plugins/themes.so index 18d27d0..8a2014e 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/themes.so and b/overlay/rootfs/usr/lib/dwm/plugins/themes.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/wallpapers.so b/overlay/rootfs/usr/lib/dwm/plugins/wallpapers.so index 4f97441..20fe616 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/wallpapers.so and b/overlay/rootfs/usr/lib/dwm/plugins/wallpapers.so differ diff --git a/overlay/rootfs/usr/lib/dwm/plugins/xdrawer.so b/overlay/rootfs/usr/lib/dwm/plugins/xdrawer.so index 3a6e4d0..9719707 100755 Binary files a/overlay/rootfs/usr/lib/dwm/plugins/xdrawer.so and b/overlay/rootfs/usr/lib/dwm/plugins/xdrawer.so differ diff --git a/overlay/rootfs/usr/libexec/msm-modem-uim-selection b/overlay/rootfs/usr/libexec/msm-modem-uim-selection index 87985dd..8f9cdfc 100755 --- a/overlay/rootfs/usr/libexec/msm-modem-uim-selection +++ b/overlay/rootfs/usr/libexec/msm-modem-uim-selection @@ -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)" diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/calllog.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/calllog.so index eab3d7f..d24c14e 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/calllog.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/calllog.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/callscreen.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/callscreen.so index 07a3cb6..b0bbacf 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/callscreen.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/callscreen.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/camera.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/camera.so index 002e755..cd22e27 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/camera.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/camera.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/contacts.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/contacts.so index b3c9f89..bf638a5 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/contacts.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/contacts.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/dialer.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/dialer.so index 838980b..c788fde 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/dialer.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/dialer.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/dmenu.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/dmenu.so index 2fcaa97..cda8920 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/dmenu.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/dmenu.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/files.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/files.so index d6fec41..ce001d6 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/files.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/files.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/modem.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/modem.so index 320ea0a..07c212d 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/modem.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/modem.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/networks.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/networks.so index 9c35911..b346e60 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/networks.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/networks.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/ringtones.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/ringtones.so index 3440c43..99f492c 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/ringtones.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/ringtones.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/sms.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/sms.so index 90d5cdc..e56ded6 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/sms.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/sms.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/themes.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/themes.so index 18d27d0..8a2014e 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/themes.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/themes.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/wallpapers.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/wallpapers.so index 4f97441..20fe616 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/wallpapers.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/wallpapers.so differ diff --git a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/xdrawer.so b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/xdrawer.so index 3a6e4d0..9719707 100755 Binary files a/prebuilt/sxmo-x11/usr/lib/dwm/plugins/xdrawer.so and b/prebuilt/sxmo-x11/usr/lib/dwm/plugins/xdrawer.so differ diff --git a/src/dwm-plugins/calllog_plugin.cpp b/src/dwm-plugins/calllog_plugin.cpp index 93d316b..0494380 100644 --- a/src/dwm-plugins/calllog_plugin.cpp +++ b/src/dwm-plugins/calllog_plugin.cpp @@ -333,6 +333,7 @@ int calllog_run_main(int argc, char** argv) { XSync(dpy, False); auto showWindow = [&]() { + writeIntFile(activePidPath, static_cast(::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(::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 || diff --git a/src/dwm-plugins/callscreen_plugin.cpp b/src/dwm-plugins/callscreen_plugin.cpp index 16acc05..da1cb69 100644 --- a/src/dwm-plugins/callscreen_plugin.cpp +++ b/src/dwm-plugins/callscreen_plugin.cpp @@ -926,6 +926,7 @@ int callscreen_run_main(int argc, char** argv) { XSync(dpy, False); auto showWindow = [&]() { + writeIntFile(activePidPath, static_cast(::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(::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 || diff --git a/src/dwm-plugins/camera_plugin.cpp b/src/dwm-plugins/camera_plugin.cpp index 9136b53..0c52aa9 100644 --- a/src/dwm-plugins/camera_plugin.cpp +++ b/src/dwm-plugins/camera_plugin.cpp @@ -711,26 +711,19 @@ int runCameraApp(int argc, char** argv) { }; auto showWindow = [&](const std::string& argStr) { + writeIntFile(activePidPath, static_cast(::getpid())); closeOtherPlugins("camera"); countdownActive = false; torchOn = getTorchState(); torchRestoredOnClose = !torchOn; - writeIntFile(activePidPath, static_cast(::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) { diff --git a/src/dwm-plugins/contacts_plugin.cpp b/src/dwm-plugins/contacts_plugin.cpp index 7a03f6f..6a6f03c 100644 --- a/src/dwm-plugins/contacts_plugin.cpp +++ b/src/dwm-plugins/contacts_plugin.cpp @@ -765,6 +765,7 @@ int runContactsApp(int argc, char** argv) { }; auto showWindow = [&](const std::string& arg) { + writeIntFile(activePidPath, static_cast(::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(::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) { diff --git a/src/dwm-plugins/dialer_plugin.cpp b/src/dwm-plugins/dialer_plugin.cpp index 2f834c9..0188797 100644 --- a/src/dwm-plugins/dialer_plugin.cpp +++ b/src/dwm-plugins/dialer_plugin.cpp @@ -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(::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(::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) { diff --git a/src/dwm-plugins/files_plugin.cpp b/src/dwm-plugins/files_plugin.cpp index 10422c9..4c71519 100644 --- a/src/dwm-plugins/files_plugin.cpp +++ b/src/dwm-plugins/files_plugin.cpp @@ -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(::getpid())); closeOtherPlugins("files"); mode = ViewMode::Browser; loadDirectory(dirArg.empty() ? currentDir : dirArg); - writeIntFile(activePidPath, static_cast(::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(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; diff --git a/src/dwm-plugins/modem_plugin.cpp b/src/dwm-plugins/modem_plugin.cpp index a651657..6b85a7d 100644 --- a/src/dwm-plugins/modem_plugin.cpp +++ b/src/dwm-plugins/modem_plugin.cpp @@ -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 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 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(::getpid())); + closeOtherPlugins("modem"); XRaiseWindow(dpy, win); grabKeys(); render(); return; } - closeOtherPlugins("modem"); - refreshData(true); - applyOpenArg(arg); writeIntFile(activePidPath, static_cast(::getpid())); + closeOtherPlugins("modem"); if (!visible) { XMapRaised(dpy, win); visible = true; } else { XRaiseWindow(dpy, win); } + grabKeys(); + render(); + refreshData(true); + applyOpenArg(arg); + writeIntFile(activePidPath, static_cast(::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(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(rRem); diff --git a/src/dwm-plugins/networks_plugin.cpp b/src/dwm-plugins/networks_plugin.cpp index 0891792..00e6112 100644 --- a/src/dwm-plugins/networks_plugin.cpp +++ b/src/dwm-plugins/networks_plugin.cpp @@ -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(::getpid())); + closeOtherPlugins("networks"); if (!visible) { XMapRaised(dpy, win); visible = true; } else { XRaiseWindow(dpy, win); } + grabKeys(); + render(); + applyOpenArg(arg); + writeIntFile(activePidPath, static_cast(::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; diff --git a/src/dwm-plugins/phone_data.h b/src/dwm-plugins/phone_data.h index c0ce983..37c9a88 100644 --- a/src/dwm-plugins/phone_data.h +++ b/src/dwm-plugins/phone_data.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -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(nullptr)); + _exit(0); } - execl("/bin/sh", "sh", "-c", cmd.c_str(), static_cast(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(nullptr)); - std::string localBin = std::string("/home/user/.local/bin/") + prog; - execl(localBin.c_str(), prog, arg1, arg2, arg3, static_cast(nullptr)); - std::string usrBin = std::string("/usr/bin/") + prog; - execl(usrBin.c_str(), prog, arg1, arg2, arg3, static_cast(nullptr)); - } else if (arg1 && arg2) { - execlp(prog, prog, arg1, arg2, static_cast(nullptr)); - std::string localBin = std::string("/home/user/.local/bin/") + prog; - execl(localBin.c_str(), prog, arg1, arg2, static_cast(nullptr)); - std::string usrBin = std::string("/usr/bin/") + prog; - execl(usrBin.c_str(), prog, arg1, arg2, static_cast(nullptr)); - } else if (arg1) { - execlp(prog, prog, arg1, static_cast(nullptr)); - std::string localBin = std::string("/home/user/.local/bin/") + prog; - execl(localBin.c_str(), prog, arg1, static_cast(nullptr)); - std::string usrBin = std::string("/usr/bin/") + prog; - execl(usrBin.c_str(), prog, arg1, static_cast(nullptr)); - } else { - execlp(prog, prog, static_cast(nullptr)); - std::string localBin = std::string("/home/user/.local/bin/") + prog; - execl(localBin.c_str(), prog, static_cast(nullptr)); - std::string usrBin = std::string("/usr/bin/") + prog; - execl(usrBin.c_str(), prog, static_cast(nullptr)); + if (arg1 && arg2 && arg3) { + execlp(prog, prog, arg1, arg2, arg3, static_cast(nullptr)); + std::string localBin = std::string("/home/user/.local/bin/") + prog; + execl(localBin.c_str(), prog, arg1, arg2, arg3, static_cast(nullptr)); + std::string usrBin = std::string("/usr/bin/") + prog; + execl(usrBin.c_str(), prog, arg1, arg2, arg3, static_cast(nullptr)); + } else if (arg1 && arg2) { + execlp(prog, prog, arg1, arg2, static_cast(nullptr)); + std::string localBin = std::string("/home/user/.local/bin/") + prog; + execl(localBin.c_str(), prog, arg1, arg2, static_cast(nullptr)); + std::string usrBin = std::string("/usr/bin/") + prog; + execl(usrBin.c_str(), prog, arg1, arg2, static_cast(nullptr)); + } else if (arg1) { + execlp(prog, prog, arg1, static_cast(nullptr)); + std::string localBin = std::string("/home/user/.local/bin/") + prog; + execl(localBin.c_str(), prog, arg1, static_cast(nullptr)); + std::string usrBin = std::string("/usr/bin/") + prog; + execl(usrBin.c_str(), prog, arg1, static_cast(nullptr)); + } else { + execlp(prog, prog, static_cast(nullptr)); + std::string localBin = std::string("/home/user/.local/bin/") + prog; + execl(localBin.c_str(), prog, static_cast(nullptr)); + std::string usrBin = std::string("/usr/bin/") + prog; + execl(usrBin.c_str(), prog, static_cast(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", diff --git a/src/dwm-plugins/ringtones_plugin.cpp b/src/dwm-plugins/ringtones_plugin.cpp index 0ac76b5..e479ad8 100644 --- a/src/dwm-plugins/ringtones_plugin.cpp +++ b/src/dwm-plugins/ringtones_plugin.cpp @@ -576,6 +576,7 @@ int runRingtonesApp(int argc, char** argv) { }; auto showWindow = [&]() { + writeIntFile(activePidPath, static_cast(::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(::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; diff --git a/src/dwm-plugins/sms_plugin.cpp b/src/dwm-plugins/sms_plugin.cpp index 2acec93..34a8811 100644 --- a/src/dwm-plugins/sms_plugin.cpp +++ b/src/dwm-plugins/sms_plugin.cpp @@ -862,6 +862,7 @@ int runSmsApp(int argc, char** argv) { }; auto showWindow = [&](const std::string& argStr) { + writeIntFile(activePidPath, static_cast(::getpid())); closeOtherPlugins("sms"); reloadAllData(true); lastTapDigit = -1; @@ -881,21 +882,13 @@ int runSmsApp(int argc, char** argv) { selectedThread = 0; } - writeIntFile(activePidPath, static_cast(::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); diff --git a/src/dwm-plugins/themes_plugin.cpp b/src/dwm-plugins/themes_plugin.cpp index 5ee11bf..70e93d0 100644 --- a/src/dwm-plugins/themes_plugin.cpp +++ b/src/dwm-plugins/themes_plugin.cpp @@ -871,24 +871,17 @@ int runThemesApp(int argc, char** argv) { }; auto showWindow = [&](const std::string& argStr) { + writeIntFile(activePidPath, static_cast(::getpid())); closeOtherPlugins("themes"); mode = ViewMode::Browser; refreshThemes(argStr); - writeIntFile(activePidPath, static_cast(::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; diff --git a/src/dwm-plugins/wallpapers_plugin.cpp b/src/dwm-plugins/wallpapers_plugin.cpp index 36cc9ac..15b7d3f 100644 --- a/src/dwm-plugins/wallpapers_plugin.cpp +++ b/src/dwm-plugins/wallpapers_plugin.cpp @@ -504,6 +504,7 @@ int runWallpapersApp(int argc, char** argv) { }; auto showWindow = [&]() { + writeIntFile(activePidPath, static_cast(::getpid())); closeOtherPlugins("wallpapers"); fullscreenPreview = false; refreshData(); @@ -514,7 +515,6 @@ int runWallpapersApp(int argc, char** argv) { } } updatePreviewCache(); - writeIntFile(activePidPath, static_cast(::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; diff --git a/src/sxmo-dmenu/dmenu.c b/src/sxmo-dmenu/dmenu.c index d9c1332..d4bac4c 100644 --- a/src/sxmo-dmenu/dmenu.c +++ b/src/sxmo-dmenu/dmenu.c @@ -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); diff --git a/src/xdrawer/xdrawer.cpp b/src/xdrawer/xdrawer.cpp index b571341..5d7ee0c 100644 --- a/src/xdrawer/xdrawer.cpp +++ b/src/xdrawer/xdrawer.cpp @@ -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(::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(::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 ||