[plugins/mousepad] Port away from KWayland

Use QtWaylandScanner to implement the protocol directly
This commit is contained in:
Nicolas Fella 2022-04-12 16:31:08 +02:00
parent 1fff89b7f3
commit 7704726857
5 changed files with 60 additions and 47 deletions

View file

@ -27,3 +27,4 @@ Dependencies:
'frameworks/kwayland': '@stable'
'frameworks/kpackage': '@stable'
'libraries/pulseaudio-qt/': '@stable'
'libraries/plasma-wayland-protocols': '@stable'

View file

@ -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)

View file

@ -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})

View file

@ -10,40 +10,42 @@
#include <QDebug>
#include <KLocalizedString>
#include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/fakeinput.h>
#include <KWayland/Client/registry.h>
#include <QtWaylandClient/qwaylandclientextension.h>
#include "qwayland-fake-input.h"
#include <linux/input.h>
class FakeInput : public QWaylandClientExtensionTemplate<FakeInput>, public QtWayland::org_kde_kwin_fake_input
{
public:
FakeInput()
: QWaylandClientExtensionTemplate<FakeInput>(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;
m_fakeInput = new FakeInput;
}
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();
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;
}

View file

@ -7,16 +7,9 @@
#ifndef WAYLANDREMOTEINPUT_H
#define WAYLANDREMOTEINPUT_H
#include <QPointer>
#include "abstractremoteinput.h"
namespace KWayland
{
namespace Client
{
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<KWayland::Client::FakeInput> m_waylandInput;
FakeInput *m_fakeInput;
bool m_waylandAuthenticationRequested;
};