wayland: Port fake input integration to InputDevice

This ensures that the cursor will be properly shown/hidden when a fake
pointer is added on a system with no physical pointer connected.
This commit is contained in:
Vlad Zahorodnii 2021-10-27 11:38:19 +03:00
parent ef72bae42f
commit 7f72e5627e
6 changed files with 302 additions and 99 deletions

View file

@ -46,6 +46,8 @@ set(kwin_SRCS
effects.cpp
egl_context_attribute_builder.cpp
events.cpp
fakeinput/fakeinputbackend.cpp
fakeinput/fakeinputdevice.cpp
focuschain.cpp
ftrace.cpp
geometrytip.cpp

View file

@ -0,0 +1,36 @@
/*
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "fakeinputbackend.h"
#include "fakeinputdevice.h"
#include "wayland_server.h"
#include <KWaylandServer/fakeinput_interface.h>
namespace KWin
{
FakeInputBackend::FakeInputBackend(QObject *parent)
: InputBackend(parent)
{
}
void FakeInputBackend::initialize()
{
auto fakeInput = new KWaylandServer::FakeInputInterface(waylandServer()->display(), this);
connect(fakeInput, &KWaylandServer::FakeInputInterface::deviceCreated, this,
[this] (KWaylandServer::FakeInputDevice *fakeDevice) {
auto device = new FakeInputDevice(fakeDevice, this);
Q_EMIT deviceAdded(device);
connect(fakeDevice, &QObject::destroyed, this, [this, device]() {
Q_EMIT deviceRemoved(device);
});
}
);
}
} // namespace KWin

View file

@ -0,0 +1,24 @@
/*
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "inputbackend.h"
namespace KWin
{
class FakeInputBackend : public InputBackend
{
Q_OBJECT
public:
explicit FakeInputBackend(QObject *parent = nullptr);
void initialize() override;
};
} // namespace KWin

View file

@ -0,0 +1,187 @@
/*
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "fakeinputdevice.h"
#include <KWaylandServer/fakeinput_interface.h>
namespace KWin
{
static int s_lastDeviceId = 0;
FakeInputDevice::FakeInputDevice(KWaylandServer::FakeInputDevice *device, QObject *parent)
: InputDevice(parent)
, m_name(QStringLiteral("Fake Input Device %1").arg(++s_lastDeviceId))
{
connect(device, &KWaylandServer::FakeInputDevice::authenticationRequested, this,
[device] (const QString &application, const QString &reason) {
Q_UNUSED(application)
Q_UNUSED(reason)
// TODO: make secure
device->setAuthentication(true);
}
);
connect(device, &KWaylandServer::FakeInputDevice::pointerMotionRequested, this,
[this] (const QSizeF &delta) {
// TODO: Fix time
Q_EMIT pointerMotion(delta, delta, 0, 0, this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::pointerMotionAbsoluteRequested, this,
[this] (const QPointF &pos) {
// TODO: Fix time
Q_EMIT pointerMotionAbsolute(pos, 0, this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::pointerButtonPressRequested, this,
[this] (quint32 button) {
// TODO: Fix time
Q_EMIT pointerButtonChanged(button, InputRedirection::PointerButtonPressed, 0, this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::pointerButtonReleaseRequested, this,
[this] (quint32 button) {
// TODO: Fix time
Q_EMIT pointerButtonChanged(button, InputRedirection::PointerButtonReleased, 0, this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::pointerAxisRequested, this,
[this] (Qt::Orientation orientation, qreal delta) {
// TODO: Fix time
InputRedirection::PointerAxis axis;
switch (orientation) {
case Qt::Horizontal:
axis = InputRedirection::PointerAxisHorizontal;
break;
case Qt::Vertical:
axis = InputRedirection::PointerAxisVertical;
break;
default:
Q_UNREACHABLE();
break;
}
// TODO: Fix time
Q_EMIT pointerAxisChanged(axis, delta, 0, InputRedirection::PointerAxisSourceUnknown, 0, this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::touchDownRequested, this,
[this] (qint32 id, const QPointF &pos) {
// TODO: Fix time
Q_EMIT touchDown(id, pos, 0, this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::touchMotionRequested, this,
[this] (qint32 id, const QPointF &pos) {
// TODO: Fix time
Q_EMIT touchMotion(id, pos, 0, this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::touchUpRequested, this,
[this] (qint32 id) {
// TODO: Fix time
Q_EMIT touchUp(id, 0, this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::touchCancelRequested, this,
[this] () {
Q_EMIT touchCanceled(this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::touchFrameRequested, this,
[this] () {
Q_EMIT touchFrame(this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::keyboardKeyPressRequested, this,
[this] (quint32 button) {
// TODO: Fix time
Q_EMIT keyChanged(button, InputRedirection::KeyboardKeyPressed, 0, this);
}
);
connect(device, &KWaylandServer::FakeInputDevice::keyboardKeyReleaseRequested, this,
[this] (quint32 button) {
// TODO: Fix time
Q_EMIT keyChanged(button, InputRedirection::KeyboardKeyReleased, 0, this);
}
);
}
QString FakeInputDevice::sysName() const
{
return QString();
}
QString FakeInputDevice::name() const
{
return m_name;
}
bool FakeInputDevice::isEnabled() const
{
return true;
}
void FakeInputDevice::setEnabled(bool enabled)
{
Q_UNUSED(enabled)
}
LEDs FakeInputDevice::leds() const
{
return LEDs();
}
void FakeInputDevice::setLeds(LEDs leds)
{
Q_UNUSED(leds)
}
bool FakeInputDevice::isKeyboard() const
{
return true;
}
bool FakeInputDevice::isAlphaNumericKeyboard() const
{
return true;
}
bool FakeInputDevice::isPointer() const
{
return true;
}
bool FakeInputDevice::isTouchpad() const
{
return false;
}
bool FakeInputDevice::isTouch() const
{
return true;
}
bool FakeInputDevice::isTabletTool() const
{
return false;
}
bool FakeInputDevice::isTabletPad() const
{
return false;
}
bool FakeInputDevice::isTabletModeSwitch() const
{
return false;
}
bool FakeInputDevice::isLidSwitch() const
{
return false;
}
} // namespace KWin

View file

@ -0,0 +1,49 @@
/*
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "inputdevice.h"
namespace KWaylandServer
{
class FakeInputDevice;
}
namespace KWin
{
class FakeInputDevice : public InputDevice
{
Q_OBJECT
public:
explicit FakeInputDevice(KWaylandServer::FakeInputDevice *device, QObject *parent = nullptr);
QString sysName() const override;
QString name() const override;
bool isEnabled() const override;
void setEnabled(bool enabled) override;
LEDs leds() const override;
void setLeds(LEDs leds) override;
bool isKeyboard() const override;
bool isAlphaNumericKeyboard() const override;
bool isPointer() const override;
bool isTouchpad() const override;
bool isTouch() const override;
bool isTabletTool() const override;
bool isTabletPad() const override;
bool isTabletModeSwitch() const override;
bool isLidSwitch() const override;
private:
QString m_name;
};
} // namespace KWin

View file

@ -10,6 +10,7 @@
*/
#include "input.h"
#include "effects.h"
#include "fakeinput/fakeinputbackend.h"
#include "gestures.h"
#include "globalshortcuts.h"
#include "input_event.h"
@ -43,7 +44,6 @@
#include <KGlobalAccel>
#include <KLocalizedString>
#include <KWaylandServer/display.h>
#include <KWaylandServer/fakeinput_interface.h>
#include <KWaylandServer/seat_interface.h>
#include <KWaylandServer/shmclientbuffer.h>
#include <KWaylandServer/surface_interface.h>
@ -2205,104 +2205,6 @@ void InputRedirection::init()
void InputRedirection::setupWorkspace()
{
if (waylandServer()) {
using namespace KWaylandServer;
FakeInputInterface *fakeInput = new FakeInputInterface(waylandServer()->display(), this);
connect(fakeInput, &FakeInputInterface::deviceCreated, this,
[this] (FakeInputDevice *device) {
connect(device, &FakeInputDevice::authenticationRequested, this,
[device] (const QString &application, const QString &reason) {
Q_UNUSED(application)
Q_UNUSED(reason)
// TODO: make secure
device->setAuthentication(true);
}
);
connect(device, &FakeInputDevice::pointerMotionRequested, this,
[this] (const QSizeF &delta) {
// TODO: Fix time
m_pointer->processMotionAbsolute(globalPointer() + QPointF(delta.width(), delta.height()), 0);
}
);
connect(device, &FakeInputDevice::pointerMotionAbsoluteRequested, this,
[this] (const QPointF &pos) {
// TODO: Fix time
m_pointer->processMotionAbsolute(pos, 0);
}
);
connect(device, &FakeInputDevice::pointerButtonPressRequested, this,
[this] (quint32 button) {
// TODO: Fix time
m_pointer->processButton(button, InputRedirection::PointerButtonPressed, 0);
}
);
connect(device, &FakeInputDevice::pointerButtonReleaseRequested, this,
[this] (quint32 button) {
// TODO: Fix time
m_pointer->processButton(button, InputRedirection::PointerButtonReleased, 0);
}
);
connect(device, &FakeInputDevice::pointerAxisRequested, this,
[this] (Qt::Orientation orientation, qreal delta) {
// TODO: Fix time
InputRedirection::PointerAxis axis;
switch (orientation) {
case Qt::Horizontal:
axis = InputRedirection::PointerAxisHorizontal;
break;
case Qt::Vertical:
axis = InputRedirection::PointerAxisVertical;
break;
default:
Q_UNREACHABLE();
break;
}
// TODO: Fix time
m_pointer->processAxis(axis, delta, 0, InputRedirection::PointerAxisSourceUnknown, 0);
}
);
connect(device, &FakeInputDevice::touchDownRequested, this,
[this] (qint32 id, const QPointF &pos) {
// TODO: Fix time
m_touch->processDown(id, pos, 0);
}
);
connect(device, &FakeInputDevice::touchMotionRequested, this,
[this] (qint32 id, const QPointF &pos) {
// TODO: Fix time
m_touch->processMotion(id, pos, 0);
}
);
connect(device, &FakeInputDevice::touchUpRequested, this,
[this] (qint32 id) {
// TODO: Fix time
m_touch->processUp(id, 0);
}
);
connect(device, &FakeInputDevice::touchCancelRequested, this,
[this] () {
m_touch->cancel();
}
);
connect(device, &FakeInputDevice::touchFrameRequested, this,
[this] () {
m_touch->frame();
}
);
connect(device, &FakeInputDevice::keyboardKeyPressRequested, this,
[this] (quint32 button) {
// TODO: Fix time
m_keyboard->processKey(button, InputRedirection::KeyboardKeyPressed, 0);
}
);
connect(device, &FakeInputDevice::keyboardKeyReleaseRequested, this,
[this] (quint32 button) {
// TODO: Fix time
m_keyboard->processKey(button, InputRedirection::KeyboardKeyReleased, 0);
}
);
}
);
m_keyboard->init();
m_pointer->init();
m_touch->init();
@ -2702,6 +2604,9 @@ void InputRedirection::setupInputBackends()
if (inputBackend) {
addInputBackend(inputBackend);
}
if (waylandServer()) {
addInputBackend(new FakeInputBackend());
}
}
void InputRedirection::setupTouchpadShortcuts()