diff --git a/.kde-ci.yml b/.kde-ci.yml index 6048f65f1..67e618bb8 100644 --- a/.kde-ci.yml +++ b/.kde-ci.yml @@ -27,3 +27,4 @@ Dependencies: 'frameworks/kwayland': '@stable' 'frameworks/kpackage': '@stable' 'libraries/pulseaudio-qt/': '@stable' + 'libraries/plasma-wayland-protocols': '@stable' diff --git a/CMakeLists.txt b/CMakeLists.txt index 90c7b01c9..590282702 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,10 @@ else() if(UNIX AND NOT APPLE) find_package(KF5Package REQUIRED) find_package(KF5PulseAudioQt) + find_package(QtWaylandScanner REQUIRED) + find_package(Wayland 1.9 REQUIRED Client) + find_package(Qt5 REQUIRED COMPONENTS WaylandClient) + find_package(PlasmaWaylandProtocols REQUIRED) endif() find_package(KF5PeopleVCard) diff --git a/plugins/mousepad/CMakeLists.txt b/plugins/mousepad/CMakeLists.txt index dad07fae5..39a9e70df 100644 --- a/plugins/mousepad/CMakeLists.txt +++ b/plugins/mousepad/CMakeLists.txt @@ -1,7 +1,6 @@ kdeconnect_add_plugin(kdeconnect_mousepad SOURCES mousepadplugin.cpp abstractremoteinput.cpp) if(UNIX AND NOT APPLE) - find_package(KF5 ${KF5_MIN_VERSION} QUIET OPTIONAL_COMPONENTS Wayland) find_package(LibFakeKey QUIET) set_package_properties(LibFakeKey PROPERTIES DESCRIPTION "fake key events" @@ -9,6 +8,17 @@ if(UNIX AND NOT APPLE) TYPE OPTIONAL PURPOSE "Needed for the remote mousepad plugin" ) + + ecm_add_qtwayland_client_protocol(wayland_SRCS + PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/fake-input.xml + BASENAME fake-input + ) + + target_sources(kdeconnect_mousepad PRIVATE ${wayland_SRCS}) + target_link_libraries(kdeconnect_mousepad Wayland::Client Qt5::WaylandClient) + target_sources(kdeconnect_mousepad PUBLIC waylandremoteinput.cpp) + set(HAVE_WAYLAND TRUE) + if (LibFakeKey_FOUND) find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS X11Extras) find_package(XTest REQUIRED) @@ -19,7 +29,6 @@ endif() set(HAVE_WINDOWS ${WIN32}) set(HAVE_X11 ${LibFakeKey_FOUND}) -set(HAVE_WAYLAND ${KF5Wayland_FOUND}) set(HAVE_MACOS ${APPLE}) configure_file(config-mousepad.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-mousepad.h ) @@ -29,11 +38,6 @@ if (HAVE_WINDOWS) target_sources(kdeconnect_mousepad PUBLIC windowsremoteinput.cpp) endif() -if(HAVE_WAYLAND) - target_sources(kdeconnect_mousepad PUBLIC waylandremoteinput.cpp) - target_link_libraries(kdeconnect_mousepad KF5::WaylandClient) -endif() - if(HAVE_X11) target_sources(kdeconnect_mousepad PUBLIC x11remoteinput.cpp) target_link_libraries(kdeconnect_mousepad Qt5::X11Extras ${X11_LIBRARIES} ${XTEST_LIBRARIES} ${LibFakeKey_LIBRARIES}) diff --git a/plugins/mousepad/waylandremoteinput.cpp b/plugins/mousepad/waylandremoteinput.cpp index 8787c3fb9..926e2ad69 100644 --- a/plugins/mousepad/waylandremoteinput.cpp +++ b/plugins/mousepad/waylandremoteinput.cpp @@ -10,40 +10,42 @@ #include #include -#include -#include -#include + +#include +#include "qwayland-fake-input.h" + +#include + +class FakeInput : public QWaylandClientExtensionTemplate, public QtWayland::org_kde_kwin_fake_input +{ +public: + FakeInput() + : QWaylandClientExtensionTemplate(4) + { + } +}; + WaylandRemoteInput::WaylandRemoteInput(QObject* parent) : AbstractRemoteInput(parent) - , m_waylandInput(nullptr) , m_waylandAuthenticationRequested(false) { - using namespace KWayland::Client; - ConnectionThread* connection = ConnectionThread::fromApplication(this); - if (!connection) { - qDebug() << "failed to get the Connection from Qt, Wayland remote input will not work"; - 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); - } - ); - connect(registry, &Registry::fakeInputRemoved, m_waylandInput, &QObject::deleteLater); - registry->setup(); + m_fakeInput = new FakeInput; +} + +WaylandRemoteInput::~WaylandRemoteInput() +{ + delete m_fakeInput; } bool WaylandRemoteInput::handlePacket(const NetworkPacket& np) { - if (!m_waylandInput) { - return false; + if (!m_fakeInput->isActive()) { + return true; } if (!m_waylandAuthenticationRequested) { - m_waylandInput->authenticate(i18n("KDE Connect"), i18n("Use your phone as a touchpad and keyboard")); + m_fakeInput->authenticate(i18n("KDE Connect"), i18n("Use your phone as a touchpad and keyboard")); m_waylandAuthenticationRequested = true; } @@ -63,28 +65,36 @@ bool WaylandRemoteInput::handlePacket(const NetworkPacket& np) if (isSingleClick || isDoubleClick || isMiddleClick || isRightClick || isSingleHold || isSingleRelease || isScroll || !key.isEmpty() || specialKey) { if (isSingleClick) { - m_waylandInput->requestPointerButtonClick(Qt::LeftButton); + m_fakeInput->button(BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); + m_fakeInput->button(BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); + } else if (isDoubleClick) { - m_waylandInput->requestPointerButtonClick(Qt::LeftButton); - m_waylandInput->requestPointerButtonClick(Qt::LeftButton); + m_fakeInput->button(BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); + m_fakeInput->button(BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); + + m_fakeInput->button(BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); + m_fakeInput->button(BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); } else if (isMiddleClick) { - m_waylandInput->requestPointerButtonClick(Qt::MiddleButton); + m_fakeInput->button(BTN_MIDDLE, WL_POINTER_BUTTON_STATE_PRESSED); + m_fakeInput->button(BTN_MIDDLE, WL_POINTER_BUTTON_STATE_RELEASED); } else if (isRightClick) { - m_waylandInput->requestPointerButtonClick(Qt::RightButton); + m_fakeInput->button(BTN_RIGHT, WL_POINTER_BUTTON_STATE_PRESSED); + m_fakeInput->button(BTN_RIGHT, WL_POINTER_BUTTON_STATE_RELEASED); } else if (isSingleHold){ //For drag'n drop - m_waylandInput->requestPointerButtonPress(Qt::LeftButton); + m_fakeInput->button(BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); } else if (isSingleRelease){ //For drag'n drop. NEVER USED (release is done by tapping, which actually triggers a isSingleClick). Kept here for future-proofness. - m_waylandInput->requestPointerButtonRelease(Qt::LeftButton); + m_fakeInput->button(BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); } else if (isScroll) { - m_waylandInput->requestPointerAxis(Qt::Vertical, -dy); + m_fakeInput->axis(WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_double(-dy)); + } else if (!key.isEmpty() || specialKey) { // TODO: implement key support } } else { //Is a mouse move event - m_waylandInput->requestPointerMove(QSizeF(dx, dy)); + m_fakeInput->pointer_motion(wl_fixed_from_double(dx), wl_fixed_from_double(dy)); } return true; } diff --git a/plugins/mousepad/waylandremoteinput.h b/plugins/mousepad/waylandremoteinput.h index 3f5c26f18..9c805879a 100644 --- a/plugins/mousepad/waylandremoteinput.h +++ b/plugins/mousepad/waylandremoteinput.h @@ -7,16 +7,9 @@ #ifndef WAYLANDREMOTEINPUT_H #define WAYLANDREMOTEINPUT_H -#include #include "abstractremoteinput.h" -namespace KWayland -{ - namespace Client - { - class FakeInput; - } -} +class FakeInput; class WaylandRemoteInput : public AbstractRemoteInput @@ -25,13 +18,14 @@ class WaylandRemoteInput public: explicit WaylandRemoteInput(QObject* parent); + ~WaylandRemoteInput(); bool handlePacket(const NetworkPacket& np) override; private: void setupWaylandIntegration(); - QPointer m_waylandInput; + FakeInput *m_fakeInput; bool m_waylandAuthenticationRequested; };