diff --git a/KWinDBusInterfaceConfig.cmake.in b/KWinDBusInterfaceConfig.cmake.in index 1a3960b641..b05964806d 100644 --- a/KWinDBusInterfaceConfig.cmake.in +++ b/KWinDBusInterfaceConfig.cmake.in @@ -3,4 +3,5 @@ set(KWIN_INTERFACE "@PACKAGE_KDE_INSTALL_DBUSINTERFACEDIR@/org.kde.KWin.xml") set(KWIN_COMPOSITING_INTERFACE "@PACKAGE_KDE_INSTALL_DBUSINTERFACEDIR@/org.kde.kwin.Compositing.xml") set(KWIN_EFFECTS_INTERFACE "@PACKAGE_KDE_INSTALL_DBUSINTERFACEDIR@/org.kde.kwin.Effects.xml") +set(KWIN_VIRTUALKEYBOARD_INTERFACE "@PACKAGE_KDE_INSTALL_DBUSINTERFACEDIR@/org.kde.kwin.VirtualKeyboard.xml") set(KWIN_WAYLAND_BIN_PATH "@CMAKE_INSTALL_FULL_BINDIR@/kwin_wayland") diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 5cd5ef2eac..edae496480 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -380,7 +380,9 @@ if (HAVE_GBM) ecm_mark_as_test(testGbmSurface) endif() -add_executable(testVirtualKeyboardDBus test_virtualkeyboard_dbus.cpp ../src/virtualkeyboard_dbus.cpp) +qt5_add_dbus_interfaces(DBUS_SRCS ${CMAKE_BINARY_DIR}/src/org.kde.kwin.VirtualKeyboard.xml) +add_executable(testVirtualKeyboardDBus test_virtualkeyboard_dbus.cpp ../src/virtualkeyboard_dbus.cpp ${DBUS_SRCS}) + target_link_libraries(testVirtualKeyboardDBus Qt::DBus Qt::Test diff --git a/autotests/test_virtualkeyboard_dbus.cpp b/autotests/test_virtualkeyboard_dbus.cpp index 3803562d28..4cc84b6b2f 100644 --- a/autotests/test_virtualkeyboard_dbus.cpp +++ b/autotests/test_virtualkeyboard_dbus.cpp @@ -12,6 +12,7 @@ #include #include +#include #include "virtualkeyboard_dbus.h" using KWin::VirtualKeyboardDBus; @@ -26,32 +27,6 @@ private Q_SLOTS: void testRequestEnabled(); }; -class DbusPropertyHelper : public QObject -{ - Q_OBJECT -public: - DbusPropertyHelper() - : QObject(nullptr) - { - QDBusConnection::sessionBus().connect( - QStringLiteral("org.kde.kwin.testvirtualkeyboard"), - QStringLiteral("/VirtualKeyboard"), - QStringLiteral("org.kde.kwin.VirtualKeyboard"), - QStringLiteral("enabledChanged"), - this, - SLOT(slotEnabledChanged())); - } - ~DbusPropertyHelper() override = default; - -Q_SIGNALS: - void enabledChanged(); - -private Q_SLOTS: - void slotEnabledChanged() { - emit enabledChanged(); - } -}; - void VirtualKeyboardDBusTest::initTestCase() { QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.kwin.testvirtualkeyboard")); @@ -60,8 +35,8 @@ void VirtualKeyboardDBusTest::initTestCase() void VirtualKeyboardDBusTest::testEnabled() { VirtualKeyboardDBus dbus; - DbusPropertyHelper helper; - QSignalSpy helperChangedSpy(&helper, &DbusPropertyHelper::enabledChanged); + OrgKdeKwinVirtualKeyboardInterface iface(QStringLiteral("org.kde.kwin.testvirtualkeyboard"), QStringLiteral("/VirtualKeyboard"), QDBusConnection::sessionBus()); + QSignalSpy helperChangedSpy(&iface, &OrgKdeKwinVirtualKeyboardInterface::enabledChanged); QVERIFY(helperChangedSpy.isValid()); QCOMPARE(dbus.isEnabled(), false); @@ -69,17 +44,8 @@ void VirtualKeyboardDBusTest::testEnabled() QSignalSpy enabledChangedSpy(&dbus, &VirtualKeyboardDBus::enabledChanged); QVERIFY(enabledChangedSpy.isValid()); - auto readProperty = [] (bool enabled) { - const QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kwin.testvirtualkeyboard"), - QStringLiteral("/VirtualKeyboard"), - QStringLiteral("org.kde.kwin.VirtualKeyboard"), - QStringLiteral("isEnabled")); - const auto reply = QDBusConnection::sessionBus().call(message); - QCOMPARE(reply.type(), QDBusMessage::ReplyMessage); - QCOMPARE(reply.arguments().count(), 1); - QCOMPARE(reply.arguments().first().toBool(), enabled); - }; - readProperty(false); + QVERIFY(iface.isValid()); + QCOMPARE(iface.enabled(), false); dbus.setEnabled(true); QCOMPARE(enabledChangedSpy.count(), 1); @@ -87,7 +53,7 @@ void VirtualKeyboardDBusTest::testEnabled() QCOMPARE(helperChangedSpy.count(), 1); QCOMPARE(dbus.isEnabled(), true); QCOMPARE(dbus.property("enabled").toBool(), true); - readProperty(true); + QCOMPARE(iface.enabled(), true); // setting again to enabled should not change anything dbus.setEnabled(true); @@ -100,7 +66,7 @@ void VirtualKeyboardDBusTest::testEnabled() QCOMPARE(helperChangedSpy.count(), 2); QCOMPARE(dbus.isEnabled(), false); QCOMPARE(dbus.property("enabled").toBool(), false); - readProperty(false); + QCOMPARE(iface.enabled(), false); } void VirtualKeyboardDBusTest::testRequestEnabled_data() @@ -108,23 +74,28 @@ void VirtualKeyboardDBusTest::testRequestEnabled_data() QTest::addColumn("method"); QTest::addColumn("expectedResult"); - QTest::newRow("enable") << QStringLiteral("enable") << true; - QTest::newRow("disable") << QStringLiteral("disable") << false; + QTest::newRow("enable") << QStringLiteral("requestEnabled") << true; + QTest::newRow("disable") << QStringLiteral("requestEnabled") << false; } void VirtualKeyboardDBusTest::testRequestEnabled() { + QFETCH(QString, method); + QFETCH(bool, expectedResult); + VirtualKeyboardDBus dbus; - QSignalSpy activateRequestedSpy(&dbus, &VirtualKeyboardDBus::activateRequested); + dbus.setEnabled(!expectedResult); + connect(&dbus, &VirtualKeyboardDBus::enableRequested, &dbus, &VirtualKeyboardDBus::setEnabled); + QSignalSpy activateRequestedSpy(&dbus, &VirtualKeyboardDBus::enabledChanged); QVERIFY(activateRequestedSpy.isValid()); - QFETCH(QString, method); - const QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kwin.testvirtualkeyboard"), - QStringLiteral("/VirtualKeyboard"), - QStringLiteral("org.kde.kwin.VirtualKeyboard"), - method); - QDBusConnection::sessionBus().asyncCall(message); - QTRY_COMPARE(activateRequestedSpy.count(), 1); - QTEST(activateRequestedSpy.first().first().toBool(), "expectedResult"); + OrgKdeKwinVirtualKeyboardInterface iface(QStringLiteral("org.kde.kwin.testvirtualkeyboard"), QStringLiteral("/VirtualKeyboard"), QDBusConnection::sessionBus()); + + auto pending = iface.requestEnabled(expectedResult); + QVERIFY(!pending.isError()); +// activateRequestedSpy.wait(); + QCOMPARE(activateRequestedSpy.count(), 1); + QCOMPARE(dbus.isEnabled(), expectedResult); + QCOMPARE(iface.enabled(), expectedResult); } QTEST_GUILESS_MAIN(VirtualKeyboardDBusTest) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index febafc765e..6424ae8a82 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -264,6 +264,8 @@ if (KWIN_BUILD_TABBOX) target_link_libraries(kwin Qt::GuiPrivate) endif() +qt5_generate_dbus_interface(virtualkeyboard_dbus.h org.kde.kwin.VirtualKeyboard.xml OPTIONS -P -s -M) + generate_export_header(kwin EXPORT_FILE_NAME kwin_export.h) if(CMAKE_SYSTEM MATCHES "FreeBSD") @@ -339,6 +341,12 @@ target_link_libraries(kwin_wayland KF5IdleTimeKWinPlugin ) +add_custom_target( + KWinDBusInterfaces + ALL + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kwin.VirtualKeyboard.xml +) + if (PipeWire_FOUND) target_link_libraries(kwin_wayland KWinScreencastPlugin) endif() @@ -352,6 +360,7 @@ install( org.kde.kwin.Compositing.xml org.kde.kwin.Effects.xml org.kde.KWin.Plugins.xml + ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kwin.VirtualKeyboard.xml DESTINATION ${KDE_INSTALL_DBUSINTERFACEDIR} ) diff --git a/src/inputmethod.cpp b/src/inputmethod.cpp index 9f8f848cb8..14b3cc896e 100644 --- a/src/inputmethod.cpp +++ b/src/inputmethod.cpp @@ -82,7 +82,9 @@ void InputMethod::init() auto dbus = new VirtualKeyboardDBus(this); qCDebug(KWIN_VIRTUALKEYBOARD) << "Registering the DBus interface"; dbus->setEnabled(m_enabled); - connect(dbus, &VirtualKeyboardDBus::activateRequested, this, &InputMethod::setEnabled); + connect(dbus, &VirtualKeyboardDBus::enableRequested, this, &InputMethod::setEnabled); + connect(dbus, &VirtualKeyboardDBus::hideRequested, this, &InputMethod::hide); + connect(this, &InputMethod::visibleChanged, dbus, &VirtualKeyboardDBus::setActive); connect(this, &InputMethod::enabledChanged, dbus, &VirtualKeyboardDBus::setEnabled); connect(input(), &InputRedirection::keyStateChanged, this, &InputMethod::hide); @@ -114,25 +116,37 @@ void InputMethod::init() void InputMethod::show() { - if (m_shown) { + setVisible(true); +} + +void InputMethod::hide() +{ + setVisible(false); +} + +void InputMethod::setVisible(bool visible) +{ + if (m_visible) { waylandServer()->inputMethod()->sendDeactivate(); } - if (!m_enabled) { - return; - } - waylandServer()->inputMethod()->sendActivate(); - if (m_shown) { - adoptInputMethodContext(); + if (visible) { + if (!m_enabled) { + return; + } + + waylandServer()->inputMethod()->sendActivate(); + if (m_visible) { + adoptInputMethodContext(); + } + } else { + updateInputPanelState(); } - m_shown = true; -} -void InputMethod::hide() -{ - waylandServer()->inputMethod()->sendDeactivate(); - updateInputPanelState(); - m_shown = false; + if (m_visible != visible) { + m_visible = visible; + Q_EMIT visibleChanged(visible); + } } void InputMethod::clientAdded(AbstractClient* client) @@ -172,10 +186,10 @@ void InputMethod::handleFocusedSurfaceChanged() } m_trackedClient = focusedClient; } + updateInputPanelState(); } else { - waylandServer()->inputMethod()->sendDeactivate(); + setVisible(false); } - updateInputPanelState(); } void InputMethod::surroundingTextChanged() @@ -248,7 +262,6 @@ void InputMethod::textInputInterfaceV2EnabledChanged() waylandServer()->inputMethod()->sendActivate(); adoptInputMethodContext(); } else { - waylandServer()->inputMethod()->sendDeactivate(); hide(); } } diff --git a/src/inputmethod.h b/src/inputmethod.h index f4a11ed2ed..63508f838d 100644 --- a/src/inputmethod.h +++ b/src/inputmethod.h @@ -37,6 +37,7 @@ public: void show(); Q_SIGNALS: + void visibleChanged(bool shown); void enabledChanged(bool enabled); private Q_SLOTS: @@ -56,6 +57,7 @@ private Q_SLOTS: void setPreeditCursor(qint32 index); private: + void setVisible(bool shown); void setEnabled(bool enable); void updateSni(); void updateInputPanelState(); @@ -68,7 +70,7 @@ private: } preedit; bool m_enabled = false; - bool m_shown = false; + bool m_visible = false; KStatusNotifierItem *m_sni = nullptr; QPointer m_inputClient; QPointer m_trackedClient; diff --git a/src/virtualkeyboard_dbus.cpp b/src/virtualkeyboard_dbus.cpp index bbc9115d55..c4319c7569 100644 --- a/src/virtualkeyboard_dbus.cpp +++ b/src/virtualkeyboard_dbus.cpp @@ -16,11 +16,48 @@ VirtualKeyboardDBus::VirtualKeyboardDBus(QObject *parent) : QObject(parent) { QDBusConnection::sessionBus().registerObject(QStringLiteral("/VirtualKeyboard"), this, - QDBusConnection::ExportAllInvokables | - QDBusConnection::ExportScriptableSignals | + QDBusConnection::ExportAllProperties | + QDBusConnection::ExportScriptableSignals | //qdbuscpp2xml doesn't support yet properties with NOTIFY QDBusConnection::ExportAllSlots); } VirtualKeyboardDBus::~VirtualKeyboardDBus() = default; +bool VirtualKeyboardDBus::isActive() const +{ + return m_active; +} + +void VirtualKeyboardDBus::requestEnabled(bool enabled) +{ + emit enableRequested(enabled); +} + +void VirtualKeyboardDBus::setActive(bool active) +{ + if (m_active != active) { + m_active = active; + Q_EMIT activeChanged(); + } +} + +void VirtualKeyboardDBus::hide() +{ + Q_EMIT hideRequested(); +} + +bool VirtualKeyboardDBus::isEnabled() const +{ + return m_enabled; +} + +void VirtualKeyboardDBus::setEnabled(bool enabled) +{ + if (m_enabled == enabled) { + return; + } + m_enabled = enabled; + emit enabledChanged(); +} + } diff --git a/src/virtualkeyboard_dbus.h b/src/virtualkeyboard_dbus.h index ac3b117098..16b4e7b69a 100644 --- a/src/virtualkeyboard_dbus.h +++ b/src/virtualkeyboard_dbus.h @@ -18,34 +18,29 @@ class VirtualKeyboardDBus : public QObject Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.VirtualKeyboard") Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabledChanged) + Q_PROPERTY(bool active READ isActive NOTIFY activeChanged) public: explicit VirtualKeyboardDBus(QObject *parent = nullptr); ~VirtualKeyboardDBus() override; - Q_INVOKABLE bool isEnabled() const { - return m_enabled; - } - void setEnabled(bool enabled) { - if (m_enabled == enabled) { - return; - } - m_enabled = enabled; - emit enabledChanged(); - } + bool isEnabled() const; + void setEnabled(bool enabled); + + void setActive(bool active); + bool isActive() const; public Q_SLOTS: - void enable() { - emit activateRequested(true); - } - void disable() { - emit activateRequested(false); - } + void requestEnabled(bool enabled); + void hide(); Q_SIGNALS: Q_SCRIPTABLE void enabledChanged(); - void activateRequested(bool requested); + Q_SCRIPTABLE void activeChanged(); + void hideRequested(); + void enableRequested(bool requested); private: bool m_enabled = false; + bool m_active = false; }; }