diff --git a/plugins/mousepad/CMakeLists.txt b/plugins/mousepad/CMakeLists.txt index 88716c719..ecfdbb7b2 100644 --- a/plugins/mousepad/CMakeLists.txt +++ b/plugins/mousepad/CMakeLists.txt @@ -6,9 +6,17 @@ find_package(XTest REQUIRED) find_package(X11 REQUIRED) find_package(LibFakeKey REQUIRED) find_package(Qt5X11Extras REQUIRED) +find_package(KF5Wayland) + +set(HAVE_WAYLAND ${KF5Wayland_FOUND}) +configure_file(config-mousepad.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-mousepad.h ) kdeconnect_add_plugin(kdeconnect_mousepad JSON kdeconnect_mousepad.json SOURCES ${kdeconnect_mousepad_SRCS}) include_directories(${XTEST_INCLUDE_DIRS} ${X11_INCLUDE_DIR} ${LibFakeKey_INCLUDE_DIRS}) -target_link_libraries(kdeconnect_mousepad kdeconnectcore Qt5::Gui Qt5::X11Extras ${X11_LIBRARIES} ${XTEST_LIBRARIES} ${LibFakeKey_LIBRARIES}) +target_link_libraries(kdeconnect_mousepad kdeconnectcore Qt5::Gui Qt5::X11Extras ${X11_LIBRARIES} ${XTEST_LIBRARIES} ${LibFakeKey_LIBRARIES} KF5::I18n) + +if(HAVE_WAYLAND) + target_link_libraries(kdeconnect_mousepad KF5::WaylandClient) +endif() diff --git a/plugins/mousepad/config-mousepad.h.cmake b/plugins/mousepad/config-mousepad.h.cmake new file mode 100644 index 000000000..e6830040c --- /dev/null +++ b/plugins/mousepad/config-mousepad.h.cmake @@ -0,0 +1 @@ +#cmakedefine01 HAVE_WAYLAND diff --git a/plugins/mousepad/mousepadplugin.cpp b/plugins/mousepad/mousepadplugin.cpp index 3d69959af..89ba532f1 100644 --- a/plugins/mousepad/mousepadplugin.cpp +++ b/plugins/mousepad/mousepadplugin.cpp @@ -1,5 +1,6 @@ /** * Copyright 2014 Ahmed I. Khalil + * Copyright 2015 Martin Gräßlin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -20,12 +21,20 @@ #include "mousepadplugin.h" #include +#include #include +#include #include #include #include #include +#if HAVE_WAYLAND +#include +#include +#include +#endif + K_PLUGIN_FACTORY_WITH_JSON( KdeConnectPluginFactory, "kdeconnect_mousepad.json", registerPlugin< MousepadPlugin >(); ) enum MouseButtons { @@ -78,8 +87,14 @@ size_t arraySize(T(&arr)[N]) { (void)arr; return N; } MousepadPlugin::MousepadPlugin(QObject* parent, const QVariantList& args) : KdeConnectPlugin(parent, args), m_fakekey(0), m_x11(QX11Info::isPlatformX11()) +#if HAVE_WAYLAND + , m_waylandInput(nullptr) + , m_waylandAuthenticationRequested(false) +#endif { - +#if HAVE_WAYLAND + setupWaylandIntegration(); +#endif } MousepadPlugin::~MousepadPlugin() @@ -91,6 +106,23 @@ MousepadPlugin::~MousepadPlugin() } bool MousepadPlugin::receivePackage(const NetworkPackage& np) +{ + if (m_x11) { + return handlePackageX11(np); + } +#if HAVE_WAYLAND + if (m_waylandInput) { + if (!m_waylandAuthenticationRequested) { + m_waylandInput->authenticate(i18n("KDE Connect"), i18n("Use your phone as a touchpad and keyboard")); + m_waylandAuthenticationRequested = true; + } + handPackageWayland(np); + } +#endif + return false; +} + +bool MousepadPlugin::handlePackageX11(const NetworkPackage &np) { //qDebug() << np.serialize(); @@ -110,10 +142,6 @@ bool MousepadPlugin::receivePackage(const NetworkPackage& np) int specialKey = np.get("specialKey", 0); if (isSingleClick || isDoubleClick || isMiddleClick || isRightClick || isSingleHold || isScroll || !key.isEmpty() || specialKey) { - - if (!m_x11) { - return false; - } Display *display = QX11Info::display(); if(!display) { return false; @@ -199,4 +227,72 @@ bool MousepadPlugin::receivePackage(const NetworkPackage& np) return true; } +#if HAVE_WAYLAND +void MousepadPlugin::setupWaylandIntegration() +{ + if (!QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) { + // not wayland + return; + } + using namespace KWayland::Client; + ConnectionThread *connection = ConnectionThread::fromApplication(this); + if (!connection) { + // failed to get the Connection from Qt + return; + } + Registry *registry = new Registry(this); + registry->create(connection); + connect(registry, &Registry::fakeInputAnnounced, this, + [this, registry] (quint32 name, quint32 version) { + m_waylandInput = registry->createFakeInput(name, version, this); + } + ); + registry->setup(); +} + +bool MousepadPlugin::handPackageWayland(const NetworkPackage &np) +{ + const float dx = np.get("dx", 0); + const float dy = np.get("dy", 0); + + const bool isSingleClick = np.get("singleclick", false); + const bool isDoubleClick = np.get("doubleclick", false); + const bool isMiddleClick = np.get("middleclick", false); + const bool isRightClick = np.get("rightclick", false); + const bool isSingleHold = np.get("singlehold", false); + const bool isSingleRelease = np.get("singlerelease", false); + const bool isScroll = np.get("scroll", false); + const QString key = np.get("key", ""); + const int specialKey = np.get("specialKey", 0); + + if (isSingleClick || isDoubleClick || isMiddleClick || isRightClick || isSingleHold || isScroll || !key.isEmpty() || specialKey) { + + if (isSingleClick) { + m_waylandInput->requestPointerButtonClick(Qt::LeftButton); + } else if (isDoubleClick) { + m_waylandInput->requestPointerButtonClick(Qt::LeftButton); + m_waylandInput->requestPointerButtonClick(Qt::LeftButton); + } else if (isMiddleClick) { + m_waylandInput->requestPointerButtonClick(Qt::MiddleButton); + } else if (isRightClick) { + m_waylandInput->requestPointerButtonClick(Qt::RightButton); + } else if (isSingleHold){ + //For drag'n drop + m_waylandInput->requestPointerButtonPress(Qt::LeftButton); + } else if (isSingleRelease){ + //For drag'n drop. NEVER USED (release is done by tapping, which actually triggers a isSingleClick). Kept here for future-proofnes. + m_waylandInput->requestPointerButtonRelease(Qt::LeftButton); + } else if (isScroll) { + m_waylandInput->requestPointerAxis(Qt::Vertical, dy); + } else if (!key.isEmpty() || specialKey) { + // TODO: implement key support + } + + } else { //Is a mouse move event + m_waylandInput->requestPointerMove(QSizeF(dx, dy)); + } + return true; +} +#endif + #include "mousepadplugin.moc" diff --git a/plugins/mousepad/mousepadplugin.h b/plugins/mousepad/mousepadplugin.h index b1ebcaae8..0c4998844 100644 --- a/plugins/mousepad/mousepadplugin.h +++ b/plugins/mousepad/mousepadplugin.h @@ -23,11 +23,22 @@ #include #include +#include #define PACKAGE_TYPE_MOUSEPAD QLatin1String("kdeconnect.mousepad") struct FakeKey; +#if HAVE_WAYLAND +namespace KWayland +{ +namespace Client +{ +class FakeInput; +} +} +#endif + class MousepadPlugin : public KdeConnectPlugin { @@ -41,9 +52,18 @@ public: virtual void connected() { } private: - FakeKey* m_fakekey; - bool m_x11; + bool handlePackageX11(const NetworkPackage& np); +#if HAVE_WAYLAND + void setupWaylandIntegration(); + bool handPackageWayland(const NetworkPackage& np); +#endif + FakeKey* m_fakekey; + const bool m_x11; +#if HAVE_WAYLAND + KWayland::Client::FakeInput *m_waylandInput; + bool m_waylandAuthenticationRequested; +#endif }; #endif