diff --git a/CMakeLists.txt b/CMakeLists.txt index 854964006a..cec69e5045 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -457,6 +457,7 @@ set(kwin_KDEINIT_SRCS wayland_server.cpp wayland_cursor_theme.cpp virtualkeyboard.cpp + virtualkeyboard_dbus.cpp appmenu.cpp modifier_only_shortcuts.cpp xkb.cpp diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index ab5b5d716b..f15229b485 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -411,3 +411,12 @@ if(HAVE_GBM) add_test(kwin-testGbmSurface testGbmSurface) ecm_mark_as_test(testGbmSurface) endif() + +add_executable(testVirtualKeyboardDBus test_virtualkeyboard_dbus.cpp ../virtualkeyboard_dbus.cpp) +target_link_libraries(testVirtualKeyboardDBus + Qt5::Test + Qt5::DBus +) +add_test(kwin-testVirtualKeyboardDBus testVirtualKeyboardDBus) +ecm_mark_as_test(testVirtualKeyboardDBus) + diff --git a/autotests/test_virtualkeyboard_dbus.cpp b/autotests/test_virtualkeyboard_dbus.cpp new file mode 100644 index 0000000000..7bb4377f17 --- /dev/null +++ b/autotests/test_virtualkeyboard_dbus.cpp @@ -0,0 +1,142 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include +#include +#include +#include +#include + +#include "../virtualkeyboard_dbus.h" + +using KWin::VirtualKeyboardDBus; + +class VirtualKeyboardDBusTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + void testEnabled(); + void testRequestEnabled_data(); + 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() = default; + +Q_SIGNALS: + void enabledChanged(); + +private Q_SLOTS: + void slotEnabledChanged() { + emit enabledChanged(); + } +}; + +void VirtualKeyboardDBusTest::initTestCase() +{ + QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.kwin.testvirtualkeyboard")); +} + +void VirtualKeyboardDBusTest::testEnabled() +{ + VirtualKeyboardDBus dbus; + DbusPropertyHelper helper; + QSignalSpy helperChangedSpy(&helper, &DbusPropertyHelper::enabledChanged); + QVERIFY(helperChangedSpy.isValid()); + + QCOMPARE(dbus.isEnabled(), false); + QCOMPARE(dbus.property("enabled").toBool(), false); + 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); + + dbus.setEnabled(true); + QCOMPARE(enabledChangedSpy.count(), 1); + QVERIFY(helperChangedSpy.wait()); + QCOMPARE(helperChangedSpy.count(), 1); + QCOMPARE(dbus.isEnabled(), true); + QCOMPARE(dbus.property("enabled").toBool(), true); + readProperty(true); + + // setting again to enabled should not change anything + dbus.setEnabled(true); + QCOMPARE(enabledChangedSpy.count(), 1); + + // back to false + dbus.setEnabled(false); + QCOMPARE(enabledChangedSpy.count(), 2); + QVERIFY(helperChangedSpy.wait()); + QCOMPARE(helperChangedSpy.count(), 2); + QCOMPARE(dbus.isEnabled(), false); + QCOMPARE(dbus.property("enabled").toBool(), false); + readProperty(false); +} + +void VirtualKeyboardDBusTest::testRequestEnabled_data() +{ + QTest::addColumn("method"); + QTest::addColumn("expectedResult"); + + QTest::newRow("enable") << QStringLiteral("enable") << true; + QTest::newRow("disable") << QStringLiteral("disable") << false; +} + +void VirtualKeyboardDBusTest::testRequestEnabled() +{ + VirtualKeyboardDBus dbus; + QSignalSpy activateRequestedSpy(&dbus, &VirtualKeyboardDBus::activateRequested); + 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"); +} + +QTEST_GUILESS_MAIN(VirtualKeyboardDBusTest) +#include "test_virtualkeyboard_dbus.moc" diff --git a/virtualkeyboard.cpp b/virtualkeyboard.cpp index bbba2fcf4e..f0c9cf7710 100644 --- a/virtualkeyboard.cpp +++ b/virtualkeyboard.cpp @@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #include "virtualkeyboard.h" +#include "virtualkeyboard_dbus.h" #include "input.h" #include "keyboard_input.h" #include "utils.h" @@ -98,6 +99,12 @@ void VirtualKeyboard::init() setEnabled(!m_enabled); } ); + connect(this, &VirtualKeyboard::enabledChanged, this, &VirtualKeyboard::updateSni); + + auto dbus = new VirtualKeyboardDBus(this); + dbus->setEnabled(m_enabled); + connect(dbus, &VirtualKeyboardDBus::activateRequested, this, &VirtualKeyboard::setEnabled); + connect(this, &VirtualKeyboard::enabledChanged, dbus, &VirtualKeyboardDBus::setEnabled); if (waylandServer()) { // we can announce support for the text input interface @@ -186,8 +193,7 @@ void VirtualKeyboard::setEnabled(bool enabled) } m_enabled = enabled; qApp->inputMethod()->update(Qt::ImQueryAll); - - updateSni(); + emit enabledChanged(m_enabled); // send OSD message QDBusMessage msg = QDBusMessage::createMethodCall( diff --git a/virtualkeyboard.h b/virtualkeyboard.h index 2990be2812..9240e99175 100644 --- a/virtualkeyboard.h +++ b/virtualkeyboard.h @@ -45,6 +45,9 @@ public: QWindow *inputPanel() const; +Q_SIGNALS: + void enabledChanged(bool enabled); + private: void show(); void hide(); diff --git a/virtualkeyboard_dbus.cpp b/virtualkeyboard_dbus.cpp new file mode 100644 index 0000000000..f54b31063b --- /dev/null +++ b/virtualkeyboard_dbus.cpp @@ -0,0 +1,37 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "virtualkeyboard_dbus.h" +#include + +namespace KWin +{ + +VirtualKeyboardDBus::VirtualKeyboardDBus(QObject *parent) + : QObject(parent) +{ + QDBusConnection::sessionBus().registerObject(QStringLiteral("/VirtualKeyboard"), this, + QDBusConnection::ExportAllInvokables | + QDBusConnection::ExportScriptableSignals | + QDBusConnection::ExportAllSlots); +} + +VirtualKeyboardDBus::~VirtualKeyboardDBus() = default; + +} diff --git a/virtualkeyboard_dbus.h b/virtualkeyboard_dbus.h new file mode 100644 index 0000000000..64c2a63ef9 --- /dev/null +++ b/virtualkeyboard_dbus.h @@ -0,0 +1,62 @@ +/******************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2017 Martin Flöser + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#pragma once + +#include + +namespace KWin +{ + +class VirtualKeyboardDBus : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.kwin.VirtualKeyboard") + Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabledChanged) +public: + explicit VirtualKeyboardDBus(QObject *parent = nullptr); + ~VirtualKeyboardDBus(); + Q_INVOKABLE bool isEnabled() const { + return m_enabled; + } + void setEnabled(bool enabled) { + if (m_enabled == enabled) { + return; + } + m_enabled = enabled; + emit enabledChanged(); + } + +public Q_SLOTS: + void enable() { + emit activateRequested(true); + } + void disable() { + emit activateRequested(false); + } + +Q_SIGNALS: + Q_SCRIPTABLE void enabledChanged(); + void activateRequested(bool requested); + +private: + bool m_enabled = false; +}; + +}