diff --git a/qml/Main.qml b/qml/Main.qml index 8803474..4e01631 100644 --- a/qml/Main.qml +++ b/qml/Main.qml @@ -36,6 +36,9 @@ Window { visible: false color: "transparent" + // Alt+F4 or the task manager would hide it behind the visibility + // controller's back; the dismiss key and the tray toggle hide it instead. + onClosing: close => close.accepted = false onInputRegionChanged: placement?.setInputRegion(inputRegion) onBlurRegionChanged: placement?.setBlurRegion(blurRegion, Theme.windowRadius) // For CollapseController. diff --git a/src/main.cpp b/src/main.cpp index c9ac594..2d4cb59 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -157,6 +157,8 @@ int main(int argc, char *argv[]) // libwayland unsets it once connected. const bool launchedByKWin = qEnvironmentVariableIsSet("WAYLAND_SOCKET"); QGuiApplication app(argc, argv); + // KWin relaunches it only after a crash: a closed window mustn't quit it. + QGuiApplication::setQuitOnLastWindowClosed(false); quitOnSignal(); QGuiApplication::setApplicationName(QStringLiteral("sloposk")); QGuiApplication::setOrganizationName(QStringLiteral("sloposk")); // ~/.config/sloposk/sloposk.conf diff --git a/src/window/VisibilityController.cpp b/src/window/VisibilityController.cpp index 31240d5..062e836 100644 --- a/src/window/VisibilityController.cpp +++ b/src/window/VisibilityController.cpp @@ -26,6 +26,13 @@ void VisibilityController::setAlwaysVisible(bool always) update(); } +void VisibilityController::setEnabled(bool enabled) +{ + m_enabled = enabled; + m_override.reset(); + update(); +} + void VisibilityController::show() { m_override = true; @@ -46,7 +53,8 @@ void VisibilityController::toggle() void VisibilityController::update() { - const bool visible = m_override.value_or(m_alwaysVisible || m_standalone || (m_fieldActive && m_showOnField)); + const bool visible = + m_enabled && m_override.value_or(m_alwaysVisible || m_standalone || (m_fieldActive && m_showOnField)); if (visible == m_visible) return; m_visible = visible; diff --git a/src/window/VisibilityController.h b/src/window/VisibilityController.h index a32020d..d72862b 100644 --- a/src/window/VisibilityController.h +++ b/src/window/VisibilityController.h @@ -9,6 +9,7 @@ // standalone (no input-method connection) // - show()/hide()/toggle() override that until the focus changes, also // from one field straight to another +// - never while the system's virtual keyboard toggle is off class VisibilityController : public QObject { Q_OBJECT @@ -24,6 +25,8 @@ public: void setShowOnField(bool show); void setStandalone(bool standalone); void setAlwaysVisible(bool always); + // The system toggle (KWin's tray icon); off hides it whatever else says. + void setEnabled(bool enabled); void show(); void hide(); @@ -39,6 +42,7 @@ private: bool m_showOnField = true; bool m_standalone = false; bool m_alwaysVisible = false; + bool m_enabled = true; std::optional m_override; bool m_visible = false; }; diff --git a/tests/tst_visibility.cpp b/tests/tst_visibility.cpp index c37c836..693e84d 100644 --- a/tests/tst_visibility.cpp +++ b/tests/tst_visibility.cpp @@ -70,6 +70,19 @@ private Q_SLOTS: QVERIFY(!v.isVisible()); } + void systemToggleGatesEverything() + { + VisibilityController v; + v.setAlwaysVisible(true); + v.setEnabled(false); + QVERIFY(!v.isVisible()); + v.show(); + QVERIFY(!v.isVisible()); + v.hide(); + v.setEnabled(true); // turning it back on forgets the dismiss + QVERIFY(v.isVisible()); + } + void standaloneAlwaysVisible() { VisibilityController v;