diff --git a/autotests/integration/inputmethod_test.cpp b/autotests/integration/inputmethod_test.cpp index b9fc2966fb..7e0a20bee3 100644 --- a/autotests/integration/inputmethod_test.cpp +++ b/autotests/integration/inputmethod_test.cpp @@ -54,6 +54,7 @@ private Q_SLOTS: void testOpenClose(); void testEnableDisableV3(); void testEnableActive(); + void testHidePanel(); }; @@ -235,6 +236,46 @@ void InputMethodTest::testEnableActive() QVERIFY(Test::waitForWindowDestroyed(client)); } +void InputMethodTest::testHidePanel() +{ + QVERIFY(!InputMethod::self()->isActive()); + + QSignalSpy clientAddedSpy(workspace(), &Workspace::clientAdded); + QSignalSpy clientRemovedSpy(workspace(), &Workspace::clientRemoved); + QVERIFY(clientAddedSpy.isValid()); + + QSignalSpy activateSpy(InputMethod::self(), &InputMethod::activeChanged); + QScopedPointer textInput(Test::waylandTextInputManager()->createTextInput(Test::waylandSeat())); + textInput->showInputPanel(); + QVERIFY(clientAddedSpy.wait()); + + // Create an xdg_toplevel surface and wait for the compositor to catch up. + QScopedPointer surface(Test::createSurface()); + QScopedPointer shellSurface(Test::createXdgToplevelSurface(surface.data())); + AbstractClient *client = Test::renderAndWaitForShown(surface.data(), QSize(1280, 1024), Qt::red); + waylandServer()->seat()->setFocusedTextInputSurface(client->surface()); + + QCOMPARE(workspace()->activeClient(), client); + + QCOMPARE(clientAddedSpy.count(), 2); + QVERIFY(activateSpy.count() || activateSpy.wait()); + QVERIFY(InputMethod::self()->isActive()); + + auto keyboardClient = Test::inputPanelClient(); + auto ipsurface = Test::inputPanelSurface(); + QVERIFY(keyboardClient); + clientRemovedSpy.clear(); + delete ipsurface; + QVERIFY(InputMethod::self()->isVisible()); + QVERIFY(clientRemovedSpy.count() || clientRemovedSpy.wait()); + QVERIFY(!InputMethod::self()->isVisible()); + + // Destroy the test client. + shellSurface.reset(); + QVERIFY(Test::waitForWindowDestroyed(client)); + +} + WAYLANDTEST_MAIN(InputMethodTest) #include "inputmethod_test.moc" diff --git a/src/inputmethod.cpp b/src/inputmethod.cpp index 72f04d1089..0e64ee7f51 100644 --- a/src/inputmethod.cpp +++ b/src/inputmethod.cpp @@ -165,6 +165,10 @@ void InputMethod::clientAdded(AbstractClient *_client) connect(m_inputClient, &AbstractClient::frameGeometryChanged, this, &InputMethod::updateInputPanelState); connect(m_inputClient, &AbstractClient::windowHidden, this, &InputMethod::updateInputPanelState); connect(m_inputClient, &AbstractClient::windowClosed, this, &InputMethod::updateInputPanelState); + connect(m_inputClient, &AbstractClient::windowShown, this, &InputMethod::visibleChanged); + connect(m_inputClient, &AbstractClient::windowHidden, this, &InputMethod::visibleChanged); + connect(m_inputClient, &AbstractClient::windowClosed, this, &InputMethod::visibleChanged); + Q_EMIT visibleChanged(); updateInputPanelState(); } @@ -688,5 +692,9 @@ void InputMethod::installKeyboardGrab(KWaylandServer::InputMethodGrabV1 *keyboar }); } +bool InputMethod::isVisible() const +{ + return m_inputClient && m_inputClient->isShown(false); } +} diff --git a/src/inputmethod.h b/src/inputmethod.h index f891d52494..c598dffbb7 100644 --- a/src/inputmethod.h +++ b/src/inputmethod.h @@ -51,12 +51,14 @@ public: void setActive(bool active); void hide(); void show(); + bool isVisible() const; void setInputMethodCommand(const QString &path); Q_SIGNALS: void activeChanged(bool active); void enabledChanged(bool enabled); + void visibleChanged(); private Q_SLOTS: void clientAdded(AbstractClient* client); diff --git a/src/virtualkeyboard_dbus.cpp b/src/virtualkeyboard_dbus.cpp index 9a66cf7f2e..351feb3322 100644 --- a/src/virtualkeyboard_dbus.cpp +++ b/src/virtualkeyboard_dbus.cpp @@ -22,6 +22,7 @@ VirtualKeyboardDBus::VirtualKeyboardDBus(InputMethod *parent) QDBusConnection::ExportAllSlots); connect(parent, &InputMethod::activeChanged, this, &VirtualKeyboardDBus::activeChanged); connect(parent, &InputMethod::enabledChanged, this, &VirtualKeyboardDBus::enabledChanged); + connect(parent, &InputMethod::visibleChanged, this, &VirtualKeyboardDBus::visibleChanged); } VirtualKeyboardDBus::~VirtualKeyboardDBus() = default; @@ -46,4 +47,9 @@ bool VirtualKeyboardDBus::isEnabled() const return m_inputMethod->isEnabled(); } +bool VirtualKeyboardDBus::isVisible() const +{ + return m_inputMethod->isVisible(); +} + } diff --git a/src/virtualkeyboard_dbus.h b/src/virtualkeyboard_dbus.h index e07a7d6a62..f55a20a2e9 100644 --- a/src/virtualkeyboard_dbus.h +++ b/src/virtualkeyboard_dbus.h @@ -20,11 +20,13 @@ class KWIN_EXPORT VirtualKeyboardDBus : public QObject Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.VirtualKeyboard") Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged) + Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged) public: explicit VirtualKeyboardDBus(InputMethod *inputMethod); ~VirtualKeyboardDBus() override; bool isEnabled() const; + bool isVisible() const; bool isActive() const; void setEnabled(bool enabled); void setActive(bool active); @@ -32,6 +34,7 @@ public: Q_SIGNALS: Q_SCRIPTABLE void enabledChanged(); Q_SCRIPTABLE void activeChanged(); + Q_SCRIPTABLE void visibleChanged(); private: InputMethod *const m_inputMethod;