Introduce base InputDevice class
The main motivation behind this change is to prepare input abstractions for virtual input devices so the wl_seat can properly advertise caps or the cursor getting properly mapped/unmapped when a fake pointer is added/removed on a system without a hardware mouse connected. With this, there are three abstractions - InputDevice, InputBackend, and InputRedirection. An InputDevice represents an input device such as a mouse, a keyboard, a tablet, etc. The InputBackend class notifies the InputRedirection about (dis-)connected devices. The InputRedirection manages the input devices. Such design allows to unify the event flow for real and virtual input devices. There can be several input backends active. For example, the libinput backend and an input backend that provides virtual input devices, e.g. libeis or org_kde_kwin_fake_input.
This commit is contained in:
parent
4206046f12
commit
ef72bae42f
44 changed files with 808 additions and 755 deletions
|
@ -1,6 +1,6 @@
|
|||
include_directories(${Libinput_INCLUDE_DIRS})
|
||||
|
||||
add_library(LibInputTestObjects STATIC ../../src/libinput/device.cpp ../../src/libinput/events.cpp mock_libinput.cpp)
|
||||
add_library(LibInputTestObjects STATIC ../../src/libinput/device.cpp ../../src/libinput/events.cpp ../../src/inputdevice.cpp mock_libinput.cpp)
|
||||
target_link_libraries(LibInputTestObjects Qt::Test Qt::Widgets Qt::DBus Qt::Gui KF5::ConfigCore)
|
||||
target_include_directories(LibInputTestObjects PUBLIC ${CMAKE_SOURCE_DIR}/src)
|
||||
|
||||
|
|
|
@ -936,3 +936,11 @@ libinput_device_group_get_user_data(struct libinput_device_group *group)
|
|||
Q_UNUSED(group);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
libinput_device_led_update(struct libinput_device *device,
|
||||
enum libinput_led leds)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
Q_UNUSED(leds)
|
||||
}
|
||||
|
|
|
@ -56,6 +56,8 @@ set(kwin_SRCS
|
|||
input.cpp
|
||||
input_event.cpp
|
||||
input_event_spy.cpp
|
||||
inputbackend.cpp
|
||||
inputdevice.cpp
|
||||
inputmethod.cpp
|
||||
inputpanelv1client.cpp
|
||||
inputpanelv1integration.cpp
|
||||
|
@ -74,6 +76,7 @@ set(kwin_SRCS
|
|||
libinput/device.cpp
|
||||
libinput/events.cpp
|
||||
libinput/libinput_logging.cpp
|
||||
libinput/libinputbackend.cpp
|
||||
linux_dmabuf.cpp
|
||||
main.cpp
|
||||
modifier_only_shortcuts.cpp
|
||||
|
|
|
@ -9,10 +9,9 @@
|
|||
#include "debug_console.h"
|
||||
#include "composite.h"
|
||||
#include "input_event.h"
|
||||
#include "inputdevice.h"
|
||||
#include "internal_client.h"
|
||||
#include "keyboard_input.h"
|
||||
#include "libinput/connection.h"
|
||||
#include "libinput/device.h"
|
||||
#include "main.h"
|
||||
#include "scene.h"
|
||||
#include "subsurfacemonitor.h"
|
||||
|
@ -147,7 +146,7 @@ static QString buttonToString(Qt::MouseButton button)
|
|||
}
|
||||
}
|
||||
|
||||
static QString deviceRow(LibInput::Device *device)
|
||||
static QString deviceRow(InputDevice *device)
|
||||
{
|
||||
if (!device) {
|
||||
return tableRow(i18n("Input Device"), i18nc("The input device of the event is not known", "Unknown"));
|
||||
|
@ -600,10 +599,8 @@ DebugConsole::DebugConsole()
|
|||
m_ui->surfacesView->setModel(new SurfaceTreeModel(this));
|
||||
m_ui->clipboardContent->setModel(new DataSourceModel(this));
|
||||
m_ui->primaryContent->setModel(new DataSourceModel(this));
|
||||
if (kwinApp()->usesLibinput()) {
|
||||
m_ui->inputDevicesView->setModel(new InputDeviceModel(this));
|
||||
m_ui->inputDevicesView->setItemDelegate(new DebugConsoleDelegate(this));
|
||||
}
|
||||
m_ui->inputDevicesView->setModel(new InputDeviceModel(this));
|
||||
m_ui->inputDevicesView->setItemDelegate(new DebugConsoleDelegate(this));
|
||||
m_ui->quitButton->setIcon(QIcon::fromTheme(QStringLiteral("application-exit")));
|
||||
m_ui->tabWidget->setTabIcon(0, QIcon::fromTheme(QStringLiteral("view-list-tree")));
|
||||
m_ui->tabWidget->setTabIcon(1, QIcon::fromTheme(QStringLiteral("view-list-tree")));
|
||||
|
@ -613,9 +610,6 @@ DebugConsole::DebugConsole()
|
|||
m_ui->tabWidget->setTabEnabled(2, false);
|
||||
m_ui->tabWidget->setTabEnabled(6, false);
|
||||
}
|
||||
if (!kwinApp()->usesLibinput()) {
|
||||
m_ui->tabWidget->setTabEnabled(3, false);
|
||||
}
|
||||
|
||||
connect(m_ui->quitButton, &QAbstractButton::clicked, this, &DebugConsole::deleteLater);
|
||||
connect(m_ui->tabWidget, &QTabWidget::currentChanged, this,
|
||||
|
@ -1486,22 +1480,22 @@ QVariant SurfaceTreeModel::data(const QModelIndex &index, int role) const
|
|||
|
||||
InputDeviceModel::InputDeviceModel(QObject *parent)
|
||||
: QAbstractItemModel(parent)
|
||||
, m_devices(LibInput::Connection::self()->devices())
|
||||
, m_devices(input()->devices())
|
||||
{
|
||||
for (auto it = m_devices.constBegin(); it != m_devices.constEnd(); ++it) {
|
||||
setupDeviceConnections(*it);
|
||||
}
|
||||
auto c = LibInput::Connection::self();
|
||||
connect(c, &LibInput::Connection::deviceAdded, this,
|
||||
[this] (LibInput::Device *d) {
|
||||
|
||||
connect(input(), &InputRedirection::deviceAdded, this,
|
||||
[this] (InputDevice *d) {
|
||||
beginInsertRows(QModelIndex(), m_devices.count(), m_devices.count());
|
||||
m_devices << d;
|
||||
setupDeviceConnections(d);
|
||||
endInsertRows();
|
||||
}
|
||||
);
|
||||
connect(c, &LibInput::Connection::deviceRemoved, this,
|
||||
[this] (LibInput::Device *d) {
|
||||
connect(input(), &InputRedirection::deviceRemoved, this,
|
||||
[this] (InputDevice *d) {
|
||||
const int index = m_devices.indexOf(d);
|
||||
if (index == -1) {
|
||||
return;
|
||||
|
@ -1528,17 +1522,16 @@ QVariant InputDeviceModel::data(const QModelIndex &index, int role) const
|
|||
return QVariant();
|
||||
}
|
||||
if (!index.parent().isValid() && index.column() == 0) {
|
||||
const auto devices = LibInput::Connection::self()->devices();
|
||||
if (index.row() >= devices.count()) {
|
||||
if (index.row() >= m_devices.count()) {
|
||||
return QVariant();
|
||||
}
|
||||
if (role == Qt::DisplayRole) {
|
||||
return devices.at(index.row())->name();
|
||||
return m_devices.at(index.row())->name();
|
||||
}
|
||||
}
|
||||
if (index.parent().isValid()) {
|
||||
if (role == Qt::DisplayRole) {
|
||||
const auto device = LibInput::Connection::self()->devices().at(index.parent().row());
|
||||
const auto device = m_devices.at(index.parent().row());
|
||||
const auto property = device->metaObject()->property(index.row());
|
||||
if (index.column() == 0) {
|
||||
return property.name();
|
||||
|
@ -1559,12 +1552,12 @@ QModelIndex InputDeviceModel::index(int row, int column, const QModelIndex &pare
|
|||
if (parent.internalId() & s_propertyBitMask) {
|
||||
return QModelIndex();
|
||||
}
|
||||
if (row >= LibInput::Connection::self()->devices().at(parent.row())->metaObject()->propertyCount()) {
|
||||
if (row >= m_devices.at(parent.row())->metaObject()->propertyCount()) {
|
||||
return QModelIndex();
|
||||
}
|
||||
return createIndex(row, column, quint32(row + 1) << 16 | parent.internalId());
|
||||
}
|
||||
if (row >= LibInput::Connection::self()->devices().count()) {
|
||||
if (row >= m_devices.count()) {
|
||||
return QModelIndex();
|
||||
}
|
||||
return createIndex(row, column, row + 1);
|
||||
|
@ -1573,13 +1566,13 @@ QModelIndex InputDeviceModel::index(int row, int column, const QModelIndex &pare
|
|||
int InputDeviceModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!parent.isValid()) {
|
||||
return LibInput::Connection::self()->devices().count();
|
||||
return m_devices.count();
|
||||
}
|
||||
if (parent.internalId() & s_propertyBitMask) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return LibInput::Connection::self()->devices().at(parent.row())->metaObject()->propertyCount();
|
||||
return m_devices.at(parent.row())->metaObject()->propertyCount();
|
||||
}
|
||||
|
||||
QModelIndex InputDeviceModel::parent(const QModelIndex &child) const
|
||||
|
@ -1593,7 +1586,7 @@ QModelIndex InputDeviceModel::parent(const QModelIndex &child) const
|
|||
|
||||
void InputDeviceModel::slotPropertyChanged()
|
||||
{
|
||||
const auto device = static_cast<LibInput::Device *>(sender());
|
||||
const auto device = static_cast<InputDevice *>(sender());
|
||||
|
||||
for (int i = 0; i < device->metaObject()->propertyCount(); ++i) {
|
||||
const QMetaProperty metaProperty = device->metaObject()->property(i);
|
||||
|
@ -1605,7 +1598,7 @@ void InputDeviceModel::slotPropertyChanged()
|
|||
}
|
||||
}
|
||||
|
||||
void InputDeviceModel::setupDeviceConnections(LibInput::Device *device)
|
||||
void InputDeviceModel::setupDeviceConnections(InputDevice *device)
|
||||
{
|
||||
QMetaMethod handler = metaObject()->method(metaObject()->indexOfMethod("slotPropertyChanged()"));
|
||||
for (int i = 0; i < device->metaObject()->propertyCount(); ++i) {
|
||||
|
|
|
@ -163,11 +163,6 @@ private:
|
|||
QTextEdit *m_textEdit;
|
||||
};
|
||||
|
||||
namespace LibInput
|
||||
{
|
||||
class Device;
|
||||
}
|
||||
|
||||
class InputDeviceModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -185,8 +180,8 @@ private Q_SLOTS:
|
|||
void slotPropertyChanged();
|
||||
|
||||
private:
|
||||
void setupDeviceConnections(LibInput::Device *device);
|
||||
QVector<LibInput::Device*> m_devices;
|
||||
void setupDeviceConnections(InputDevice *device);
|
||||
QList<InputDevice *> m_devices;
|
||||
};
|
||||
|
||||
class DataSourceModel : public QAbstractItemModel
|
||||
|
|
422
src/input.cpp
422
src/input.cpp
|
@ -14,6 +14,7 @@
|
|||
#include "globalshortcuts.h"
|
||||
#include "input_event.h"
|
||||
#include "input_event_spy.h"
|
||||
#include "inputbackend.h"
|
||||
#include "keyboard_input.h"
|
||||
#include "main.h"
|
||||
#include "pointer_input.h"
|
||||
|
@ -47,12 +48,14 @@
|
|||
#include <KWaylandServer/shmclientbuffer.h>
|
||||
#include <KWaylandServer/surface_interface.h>
|
||||
#include <KWaylandServer/tablet_v2_interface.h>
|
||||
#include <KWaylandServer/keyboard_interface.h>
|
||||
#include <decorations/decoratedclient.h>
|
||||
|
||||
//screenlocker
|
||||
#include <KScreenLocker/KsldApp>
|
||||
// Qt
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusPendingCall>
|
||||
#include <QKeyEvent>
|
||||
#include <QThread>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
@ -1634,6 +1637,12 @@ class TabletInputFilter : public QObject, public InputEventFilter
|
|||
public:
|
||||
TabletInputFilter()
|
||||
{
|
||||
const auto devices = input()->devices();
|
||||
for (InputDevice *device : devices) {
|
||||
integrateDevice(device);
|
||||
}
|
||||
connect(input(), &InputRedirection::deviceAdded, this, &TabletInputFilter::integrateDevice);
|
||||
connect(input(), &InputRedirection::deviceRemoved, this, &TabletInputFilter::removeDevice);
|
||||
}
|
||||
|
||||
static KWaylandServer::TabletSeatV2Interface *findTabletSeat()
|
||||
|
@ -1646,9 +1655,10 @@ public:
|
|||
return manager->seat(findSeat());
|
||||
}
|
||||
|
||||
void integrateDevice(LibInput::Device *device)
|
||||
void integrateDevice(InputDevice *inputDevice)
|
||||
{
|
||||
if (!device->isTabletTool() && !device->isTabletPad()) {
|
||||
auto device = qobject_cast<LibInput::Device *>(inputDevice);
|
||||
if (!device || (!device->isTabletTool() && !device->isTabletPad())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1678,19 +1688,20 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void removeDevice(LibInput::Device *device)
|
||||
void removeDevice(InputDevice *inputDevice)
|
||||
{
|
||||
auto deviceGroup = libinput_device_get_device_group(device->device());
|
||||
libinput_device_group_set_user_data(deviceGroup, nullptr);
|
||||
}
|
||||
auto device = qobject_cast<LibInput::Device *>(inputDevice);
|
||||
if (device) {
|
||||
auto deviceGroup = libinput_device_get_device_group(device->device());
|
||||
libinput_device_group_set_user_data(deviceGroup, nullptr);
|
||||
|
||||
void removeDeviceBySysName(const QString &sysname)
|
||||
{
|
||||
KWaylandServer::TabletSeatV2Interface *tabletSeat = findTabletSeat();
|
||||
if (tabletSeat)
|
||||
tabletSeat->removeDevice(sysname);
|
||||
else
|
||||
qCCritical(KWIN_CORE) << "Could not find tablet to remove" << sysname;
|
||||
KWaylandServer::TabletSeatV2Interface *tabletSeat = findTabletSeat();
|
||||
if (tabletSeat) {
|
||||
tabletSeat->removeDevice(device->sysName());
|
||||
} else {
|
||||
qCCritical(KWIN_CORE) << "Could not find tablet to remove" << device->sysName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KWaylandServer::TabletToolV2Interface::Type getType(const KWin::TabletToolId &tabletToolId) {
|
||||
|
@ -2140,21 +2151,15 @@ InputRedirection::InputRedirection(QObject *parent)
|
|||
qRegisterMetaType<KWin::InputRedirection::KeyboardKeyState>();
|
||||
qRegisterMetaType<KWin::InputRedirection::PointerButtonState>();
|
||||
qRegisterMetaType<KWin::InputRedirection::PointerAxis>();
|
||||
if (Application::usesLibinput()) {
|
||||
setupLibInput();
|
||||
}
|
||||
setupInputBackends();
|
||||
connect(kwinApp(), &Application::workspaceCreated, this, &InputRedirection::setupWorkspace);
|
||||
}
|
||||
|
||||
InputRedirection::~InputRedirection()
|
||||
{
|
||||
if (m_libInput) {
|
||||
m_libInput->deleteLater();
|
||||
|
||||
m_libInputThread->quit();
|
||||
m_libInputThread->wait();
|
||||
delete m_libInputThread;
|
||||
}
|
||||
qDeleteAll(m_inputBackends);
|
||||
m_inputBackends.clear();
|
||||
m_inputDevices.clear();
|
||||
|
||||
s_self = nullptr;
|
||||
qDeleteAll(m_filters);
|
||||
|
@ -2190,6 +2195,10 @@ void InputRedirection::uninstallInputEventSpy(InputEventSpy *spy)
|
|||
|
||||
void InputRedirection::init()
|
||||
{
|
||||
m_inputConfigWatcher = KConfigWatcher::create(InputConfig::self()->inputConfig());
|
||||
connect(m_inputConfigWatcher.data(), &KConfigWatcher::configChanged,
|
||||
this, &InputRedirection::handleInputConfigChanged);
|
||||
|
||||
m_shortcuts->init();
|
||||
}
|
||||
|
||||
|
@ -2298,6 +2307,9 @@ void InputRedirection::setupWorkspace()
|
|||
m_pointer->init();
|
||||
m_touch->init();
|
||||
m_tablet->init();
|
||||
|
||||
updateLeds(m_keyboard->xkb()->leds());
|
||||
connect(m_keyboard, &KeyboardInputRedirection::ledsChanged, this, &InputRedirection::updateLeds);
|
||||
}
|
||||
setupTouchpadShortcuts();
|
||||
setupInputFilters();
|
||||
|
@ -2489,178 +2501,211 @@ void InputRedirection::setupInputFilters()
|
|||
if (waylandServer()) {
|
||||
installInputEventFilter(new WindowActionInputFilter);
|
||||
installInputEventFilter(new ForwardInputFilter);
|
||||
|
||||
if (m_libInput) {
|
||||
m_tabletSupport = new TabletInputFilter;
|
||||
const QVector<LibInput::Device *> devices = m_libInput->devices();
|
||||
for (LibInput::Device *dev : devices) {
|
||||
m_tabletSupport->integrateDevice(dev);
|
||||
}
|
||||
connect(m_libInput, &LibInput::Connection::deviceAdded, m_tabletSupport, &TabletInputFilter::integrateDevice);
|
||||
connect(m_libInput, &LibInput::Connection::deviceRemoved, m_tabletSupport, &TabletInputFilter::removeDevice);
|
||||
|
||||
connect(m_libInput, &LibInput::Connection::deviceRemovedSysName, m_tabletSupport, &TabletInputFilter::removeDeviceBySysName);
|
||||
installInputEventFilter(m_tabletSupport);
|
||||
}
|
||||
installInputEventFilter(new TabletInputFilter);
|
||||
}
|
||||
}
|
||||
|
||||
void InputRedirection::handleInputConfigChanged(const KConfigGroup &group)
|
||||
{
|
||||
if (group.name() == QLatin1String("Keyboard")) {
|
||||
reconfigure();
|
||||
m_keyboard->reconfigure();
|
||||
}
|
||||
}
|
||||
|
||||
void InputRedirection::reconfigure()
|
||||
void InputRedirection::updateLeds(LEDs leds)
|
||||
{
|
||||
if (Application::usesLibinput()) {
|
||||
auto inputConfig = m_inputConfigWatcher->config();
|
||||
const auto config = inputConfig->group(QStringLiteral("Keyboard"));
|
||||
const int delay = config.readEntry("RepeatDelay", 660);
|
||||
const int rate = int(config.readEntry("RepeatRate", 25.0));
|
||||
const QString repeatMode = config.readEntry("KeyRepeat", "repeat");
|
||||
// when the clients will repeat the character or turn repeat key events into an accent character selection, we want
|
||||
// to tell the clients that we are indeed repeating keys.
|
||||
const bool enabled = repeatMode == QLatin1String("accent") || repeatMode == QLatin1String("repeat");
|
||||
if (m_leds != leds) {
|
||||
m_leds = leds;
|
||||
|
||||
waylandServer()->seat()->keyboard()->setRepeatInfo(enabled ? rate : 0, delay);
|
||||
for (InputDevice *device : qAsConst(m_inputDevices)) {
|
||||
device->setLeds(leds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputRedirection::setupLibInput()
|
||||
void InputRedirection::handleInputDeviceAdded(InputDevice *device)
|
||||
{
|
||||
if (!Application::usesLibinput()) {
|
||||
return;
|
||||
}
|
||||
if (m_libInput) {
|
||||
return;
|
||||
connect(device, &InputDevice::keyChanged, m_keyboard, &KeyboardInputRedirection::processKey);
|
||||
|
||||
connect(device, &InputDevice::pointerMotionAbsolute,
|
||||
m_pointer, &PointerInputRedirection::processMotionAbsolute);
|
||||
connect(device, &InputDevice::pointerMotion,
|
||||
m_pointer, &PointerInputRedirection::processMotion);
|
||||
connect(device, &InputDevice::pointerButtonChanged,
|
||||
m_pointer, &PointerInputRedirection::processButton);
|
||||
connect(device, &InputDevice::pointerAxisChanged,
|
||||
m_pointer, &PointerInputRedirection::processAxis);
|
||||
connect(device, &InputDevice::pinchGestureBegin,
|
||||
m_pointer, &PointerInputRedirection::processPinchGestureBegin);
|
||||
connect(device, &InputDevice::pinchGestureUpdate,
|
||||
m_pointer, &PointerInputRedirection::processPinchGestureUpdate);
|
||||
connect(device, &InputDevice::pinchGestureEnd,
|
||||
m_pointer, &PointerInputRedirection::processPinchGestureEnd);
|
||||
connect(device, &InputDevice::pinchGestureCancelled,
|
||||
m_pointer, &PointerInputRedirection::processPinchGestureCancelled);
|
||||
connect(device, &InputDevice::swipeGestureBegin,
|
||||
m_pointer, &PointerInputRedirection::processSwipeGestureBegin);
|
||||
connect(device, &InputDevice::swipeGestureUpdate,
|
||||
m_pointer, &PointerInputRedirection::processSwipeGestureUpdate);
|
||||
connect(device, &InputDevice::swipeGestureEnd,
|
||||
m_pointer, &PointerInputRedirection::processSwipeGestureEnd);
|
||||
connect(device, &InputDevice::swipeGestureCancelled,
|
||||
m_pointer, &PointerInputRedirection::processSwipeGestureCancelled);
|
||||
connect(device, &InputDevice::holdGestureBegin,
|
||||
m_pointer, &PointerInputRedirection::processHoldGestureBegin);
|
||||
connect(device, &InputDevice::holdGestureEnd,
|
||||
m_pointer, &PointerInputRedirection::processHoldGestureEnd);
|
||||
connect(device, &InputDevice::holdGestureCancelled,
|
||||
m_pointer, &PointerInputRedirection::processHoldGestureCancelled);
|
||||
|
||||
connect(device, &InputDevice::touchDown, m_touch, &TouchInputRedirection::processDown);
|
||||
connect(device, &InputDevice::touchUp, m_touch, &TouchInputRedirection::processUp);
|
||||
connect(device, &InputDevice::touchMotion, m_touch, &TouchInputRedirection::processMotion);
|
||||
connect(device, &InputDevice::touchCanceled, m_touch, &TouchInputRedirection::cancel);
|
||||
connect(device, &InputDevice::touchFrame, m_touch, &TouchInputRedirection::frame);
|
||||
|
||||
auto handleSwitchEvent = [this] (SwitchEvent::State state, quint32 time, quint64 timeMicroseconds, InputDevice *device) {
|
||||
SwitchEvent event(state, time, timeMicroseconds, device);
|
||||
processSpies(std::bind(&InputEventSpy::switchEvent, std::placeholders::_1, &event));
|
||||
processFilters(std::bind(&InputEventFilter::switchEvent, std::placeholders::_1, &event));
|
||||
};
|
||||
connect(device, &InputDevice::switchToggledOn, this,
|
||||
std::bind(handleSwitchEvent, SwitchEvent::State::On, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
connect(device, &InputDevice::switchToggledOff, this,
|
||||
std::bind(handleSwitchEvent, SwitchEvent::State::Off, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
|
||||
connect(device, &InputDevice::tabletToolEvent,
|
||||
m_tablet, &TabletInputRedirection::tabletToolEvent);
|
||||
connect(device, &InputDevice::tabletToolButtonEvent,
|
||||
m_tablet, &TabletInputRedirection::tabletToolButtonEvent);
|
||||
connect(device, &InputDevice::tabletPadButtonEvent,
|
||||
m_tablet, &TabletInputRedirection::tabletPadButtonEvent);
|
||||
connect(device, &InputDevice::tabletPadRingEvent,
|
||||
m_tablet, &TabletInputRedirection::tabletPadRingEvent);
|
||||
connect(device, &InputDevice::tabletPadStripEvent,
|
||||
m_tablet, &TabletInputRedirection::tabletPadStripEvent);
|
||||
|
||||
device->setLeds(m_leds);
|
||||
|
||||
m_inputDevices.append(device);
|
||||
Q_EMIT deviceAdded(device);
|
||||
|
||||
updateAvailableInputDevices();
|
||||
}
|
||||
|
||||
void InputRedirection::handleInputDeviceRemoved(InputDevice *device)
|
||||
{
|
||||
m_inputDevices.removeOne(device);
|
||||
Q_EMIT deviceRemoved(device);
|
||||
|
||||
updateAvailableInputDevices();
|
||||
}
|
||||
|
||||
void InputRedirection::updateAvailableInputDevices()
|
||||
{
|
||||
const bool hasKeyboard = std::any_of(m_inputDevices.constBegin(), m_inputDevices.constEnd(), [](InputDevice *device) {
|
||||
return device->isKeyboard();
|
||||
});
|
||||
if (m_hasKeyboard != hasKeyboard) {
|
||||
m_hasKeyboard = hasKeyboard;
|
||||
Q_EMIT hasKeyboardChanged(hasKeyboard);
|
||||
}
|
||||
|
||||
m_libInputThread = new QThread();
|
||||
m_libInputThread->setObjectName(QStringLiteral("libinput-connection"));
|
||||
m_libInputThread->start();
|
||||
const bool hasAlphaNumericKeyboard = std::any_of(m_inputDevices.constBegin(), m_inputDevices.constEnd(), [](InputDevice *device) {
|
||||
return device->isAlphaNumericKeyboard();
|
||||
});
|
||||
if (m_hasAlphaNumericKeyboard != hasAlphaNumericKeyboard) {
|
||||
m_hasAlphaNumericKeyboard = hasAlphaNumericKeyboard;
|
||||
Q_EMIT hasAlphaNumericKeyboardChanged(hasAlphaNumericKeyboard);
|
||||
}
|
||||
|
||||
LibInput::Connection *conn = LibInput::Connection::create(this);
|
||||
m_libInput = conn;
|
||||
m_libInput->moveToThread(m_libInputThread);
|
||||
const bool hasPointer = std::any_of(m_inputDevices.constBegin(), m_inputDevices.constEnd(), [](InputDevice *device) {
|
||||
return device->isPointer();
|
||||
});
|
||||
if (m_hasPointer != hasPointer) {
|
||||
m_hasPointer = hasPointer;
|
||||
Q_EMIT hasPointerChanged(hasPointer);
|
||||
}
|
||||
|
||||
if (conn) {
|
||||
conn->setInputConfig(InputConfig::self()->inputConfig());
|
||||
conn->updateLEDs(m_keyboard->xkb()->leds());
|
||||
waylandServer()->updateKeyState(m_keyboard->xkb()->leds());
|
||||
connect(m_keyboard, &KeyboardInputRedirection::ledsChanged, waylandServer(), &WaylandServer::updateKeyState);
|
||||
connect(m_keyboard, &KeyboardInputRedirection::ledsChanged, conn, &LibInput::Connection::updateLEDs);
|
||||
connect(conn, &LibInput::Connection::eventsRead, this,
|
||||
[this] {
|
||||
m_libInput->processEvents();
|
||||
}, Qt::QueuedConnection
|
||||
const bool hasTouch = std::any_of(m_inputDevices.constBegin(), m_inputDevices.constEnd(), [](InputDevice *device) {
|
||||
return device->isTouch();
|
||||
});
|
||||
if (m_hasTouch != hasTouch) {
|
||||
m_hasTouch = hasTouch;
|
||||
Q_EMIT hasTouchChanged(hasTouch);
|
||||
}
|
||||
|
||||
const bool hasTabletModeSwitch = std::any_of(m_inputDevices.constBegin(), m_inputDevices.constEnd(), [](InputDevice *device) {
|
||||
return device->isTabletModeSwitch();
|
||||
});
|
||||
if (m_hasTabletModeSwitch != hasTabletModeSwitch) {
|
||||
m_hasTabletModeSwitch = hasTabletModeSwitch;
|
||||
Q_EMIT hasTabletModeSwitchChanged(hasTabletModeSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void InputRedirection::toggleTouchpads()
|
||||
{
|
||||
bool changed = false;
|
||||
m_touchpadsEnabled = !m_touchpadsEnabled;
|
||||
for (InputDevice *device : qAsConst(m_inputDevices)) {
|
||||
if (!device->isTouchpad()) {
|
||||
continue;
|
||||
}
|
||||
const bool old = device->isEnabled();
|
||||
device->setEnabled(m_touchpadsEnabled);
|
||||
if (old != device->isEnabled()) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
// send OSD message
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.plasmashell"),
|
||||
QStringLiteral("/org/kde/osdService"),
|
||||
QStringLiteral("org.kde.osdService"),
|
||||
QStringLiteral("touchpadEnabledChanged")
|
||||
);
|
||||
conn->setup();
|
||||
connect(conn, &LibInput::Connection::pointerButtonChanged, m_pointer, &PointerInputRedirection::processButton);
|
||||
connect(conn, &LibInput::Connection::pointerAxisChanged, m_pointer, &PointerInputRedirection::processAxis);
|
||||
connect(conn, &LibInput::Connection::pinchGestureBegin, m_pointer, &PointerInputRedirection::processPinchGestureBegin);
|
||||
connect(conn, &LibInput::Connection::pinchGestureUpdate, m_pointer, &PointerInputRedirection::processPinchGestureUpdate);
|
||||
connect(conn, &LibInput::Connection::pinchGestureEnd, m_pointer, &PointerInputRedirection::processPinchGestureEnd);
|
||||
connect(conn, &LibInput::Connection::pinchGestureCancelled, m_pointer, &PointerInputRedirection::processPinchGestureCancelled);
|
||||
connect(conn, &LibInput::Connection::swipeGestureBegin, m_pointer, &PointerInputRedirection::processSwipeGestureBegin);
|
||||
connect(conn, &LibInput::Connection::swipeGestureUpdate, m_pointer, &PointerInputRedirection::processSwipeGestureUpdate);
|
||||
connect(conn, &LibInput::Connection::swipeGestureEnd, m_pointer, &PointerInputRedirection::processSwipeGestureEnd);
|
||||
connect(conn, &LibInput::Connection::swipeGestureCancelled, m_pointer, &PointerInputRedirection::processSwipeGestureCancelled);
|
||||
connect(conn, &LibInput::Connection::holdGestureBegin, m_pointer, &PointerInputRedirection::processHoldGestureBegin);
|
||||
connect(conn, &LibInput::Connection::holdGestureEnd, m_pointer, &PointerInputRedirection::processHoldGestureEnd);
|
||||
connect(conn, &LibInput::Connection::holdGestureCancelled, m_pointer, &PointerInputRedirection::processHoldGestureCancelled);
|
||||
connect(conn, &LibInput::Connection::keyChanged, m_keyboard, &KeyboardInputRedirection::processKey);
|
||||
connect(conn, &LibInput::Connection::pointerMotion, m_pointer, &PointerInputRedirection::processMotion);
|
||||
connect(conn, &LibInput::Connection::pointerMotionAbsolute, m_pointer, &PointerInputRedirection::processMotionAbsolute);
|
||||
connect(conn, &LibInput::Connection::touchDown, m_touch, &TouchInputRedirection::processDown);
|
||||
connect(conn, &LibInput::Connection::touchUp, m_touch, &TouchInputRedirection::processUp);
|
||||
connect(conn, &LibInput::Connection::touchMotion, m_touch, &TouchInputRedirection::processMotion);
|
||||
connect(conn, &LibInput::Connection::touchCanceled, m_touch, &TouchInputRedirection::cancel);
|
||||
connect(conn, &LibInput::Connection::touchFrame, m_touch, &TouchInputRedirection::frame);
|
||||
auto handleSwitchEvent = [this] (SwitchEvent::State state, quint32 time, quint64 timeMicroseconds, LibInput::Device *device) {
|
||||
SwitchEvent event(state, time, timeMicroseconds, device);
|
||||
processSpies(std::bind(&InputEventSpy::switchEvent, std::placeholders::_1, &event));
|
||||
processFilters(std::bind(&InputEventFilter::switchEvent, std::placeholders::_1, &event));
|
||||
};
|
||||
connect(conn, &LibInput::Connection::switchToggledOn, this,
|
||||
std::bind(handleSwitchEvent, SwitchEvent::State::On, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
connect(conn, &LibInput::Connection::switchToggledOff, this,
|
||||
std::bind(handleSwitchEvent, SwitchEvent::State::Off, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
msg.setArguments({m_touchpadsEnabled});
|
||||
QDBusConnection::sessionBus().asyncCall(msg);
|
||||
}
|
||||
}
|
||||
|
||||
connect(conn, &LibInput::Connection::tabletToolEvent,
|
||||
m_tablet, &TabletInputRedirection::tabletToolEvent);
|
||||
connect(conn, &LibInput::Connection::tabletToolButtonEvent,
|
||||
m_tablet, &TabletInputRedirection::tabletToolButtonEvent);
|
||||
connect(conn, &LibInput::Connection::tabletPadButtonEvent,
|
||||
m_tablet, &TabletInputRedirection::tabletPadButtonEvent);
|
||||
connect(conn, &LibInput::Connection::tabletPadRingEvent,
|
||||
m_tablet, &TabletInputRedirection::tabletPadRingEvent);
|
||||
connect(conn, &LibInput::Connection::tabletPadStripEvent,
|
||||
m_tablet, &TabletInputRedirection::tabletPadStripEvent);
|
||||
void InputRedirection::enableTouchpads()
|
||||
{
|
||||
if (!m_touchpadsEnabled) {
|
||||
toggleTouchpads();
|
||||
}
|
||||
}
|
||||
|
||||
if (screens()) {
|
||||
setupLibInputWithScreens();
|
||||
} else {
|
||||
connect(kwinApp(), &Application::screensCreated, this, &InputRedirection::setupLibInputWithScreens);
|
||||
}
|
||||
if (auto s = findSeat()) {
|
||||
// Workaround for QTBUG-54371: if there is no real keyboard Qt doesn't request virtual keyboard
|
||||
s->setHasKeyboard(true);
|
||||
s->setHasPointer(conn->hasPointer());
|
||||
s->setHasTouch(conn->hasTouch());
|
||||
connect(conn, &LibInput::Connection::hasAlphaNumericKeyboardChanged, this,
|
||||
[this] (bool set) {
|
||||
if (m_libInput->isSuspended()) {
|
||||
return;
|
||||
}
|
||||
// TODO: this should update the seat, only workaround for QTBUG-54371
|
||||
Q_EMIT hasAlphaNumericKeyboardChanged(set);
|
||||
}
|
||||
);
|
||||
connect(conn, &LibInput::Connection::hasTabletModeSwitchChanged, this,
|
||||
[this] (bool set) {
|
||||
if (m_libInput->isSuspended()) {
|
||||
return;
|
||||
}
|
||||
Q_EMIT hasTabletModeSwitchChanged(set);
|
||||
}
|
||||
);
|
||||
connect(conn, &LibInput::Connection::hasPointerChanged, this,
|
||||
[this, s] (bool set) {
|
||||
if (m_libInput->isSuspended()) {
|
||||
return;
|
||||
}
|
||||
s->setHasPointer(set);
|
||||
}
|
||||
);
|
||||
connect(conn, &LibInput::Connection::hasTouchChanged, this,
|
||||
[this, s] (bool set) {
|
||||
if (m_libInput->isSuspended()) {
|
||||
return;
|
||||
}
|
||||
s->setHasTouch(set);
|
||||
}
|
||||
);
|
||||
}
|
||||
connect(kwinApp()->platform()->session(), &Session::activeChanged, m_libInput, [this](bool active) {
|
||||
if (!active) {
|
||||
m_libInput->deactivate();
|
||||
}
|
||||
});
|
||||
void InputRedirection::disableTouchpads()
|
||||
{
|
||||
if (m_touchpadsEnabled) {
|
||||
toggleTouchpads();
|
||||
}
|
||||
}
|
||||
|
||||
m_inputConfigWatcher = KConfigWatcher::create(InputConfig::self()->inputConfig());
|
||||
connect(m_inputConfigWatcher.data(), &KConfigWatcher::configChanged,
|
||||
this, &InputRedirection::handleInputConfigChanged);
|
||||
reconfigure();
|
||||
void InputRedirection::addInputBackend(InputBackend *inputBackend)
|
||||
{
|
||||
Q_ASSERT(!m_inputBackends.contains(inputBackend));
|
||||
m_inputBackends.append(inputBackend);
|
||||
|
||||
connect(inputBackend, &InputBackend::deviceAdded, this, &InputRedirection::handleInputDeviceAdded);
|
||||
connect(inputBackend, &InputBackend::deviceRemoved, this, &InputRedirection::handleInputDeviceRemoved);
|
||||
|
||||
inputBackend->setConfig(InputConfig::self()->inputConfig());
|
||||
inputBackend->initialize();
|
||||
}
|
||||
|
||||
void InputRedirection::setupInputBackends()
|
||||
{
|
||||
InputBackend *inputBackend = kwinApp()->platform()->createInputBackend();
|
||||
if (inputBackend) {
|
||||
addInputBackend(inputBackend);
|
||||
}
|
||||
}
|
||||
|
||||
void InputRedirection::setupTouchpadShortcuts()
|
||||
{
|
||||
if (!m_libInput) {
|
||||
return;
|
||||
}
|
||||
QAction *touchpadToggleAction = new QAction(this);
|
||||
QAction *touchpadOnAction = new QAction(this);
|
||||
QAction *touchpadOffAction = new QAction(this);
|
||||
|
@ -2687,40 +2732,29 @@ void InputRedirection::setupTouchpadShortcuts()
|
|||
registerShortcut(Qt::Key_TouchpadOn, touchpadOnAction);
|
||||
registerShortcut(Qt::Key_TouchpadOff, touchpadOffAction);
|
||||
#endif
|
||||
connect(touchpadToggleAction, &QAction::triggered, m_libInput, &LibInput::Connection::toggleTouchpads);
|
||||
connect(touchpadOnAction, &QAction::triggered, m_libInput, &LibInput::Connection::enableTouchpads);
|
||||
connect(touchpadOffAction, &QAction::triggered, m_libInput, &LibInput::Connection::disableTouchpads);
|
||||
connect(touchpadToggleAction, &QAction::triggered, this, &InputRedirection::toggleTouchpads);
|
||||
connect(touchpadOnAction, &QAction::triggered, this, &InputRedirection::enableTouchpads);
|
||||
connect(touchpadOffAction, &QAction::triggered, this, &InputRedirection::disableTouchpads);
|
||||
}
|
||||
|
||||
bool InputRedirection::hasAlphaNumericKeyboard()
|
||||
{
|
||||
if (m_libInput) {
|
||||
return m_libInput->hasAlphaNumericKeyboard();
|
||||
}
|
||||
return true;
|
||||
return m_hasAlphaNumericKeyboard;
|
||||
}
|
||||
|
||||
bool InputRedirection::hasPointer() const
|
||||
{
|
||||
return m_hasPointer;
|
||||
}
|
||||
|
||||
bool InputRedirection::hasTouch() const
|
||||
{
|
||||
return m_hasTouch;
|
||||
}
|
||||
|
||||
bool InputRedirection::hasTabletModeSwitch()
|
||||
{
|
||||
if (m_libInput) {
|
||||
return m_libInput->hasTabletModeSwitch();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void InputRedirection::setupLibInputWithScreens()
|
||||
{
|
||||
if (!screens() || !m_libInput) {
|
||||
return;
|
||||
}
|
||||
m_libInput->setScreenSize(screens()->size());
|
||||
m_libInput->updateScreens();
|
||||
connect(screens(), &Screens::sizeChanged, this,
|
||||
[this] {
|
||||
m_libInput->setScreenSize(screens()->size());
|
||||
}
|
||||
);
|
||||
connect(screens(), &Screens::changed, m_libInput, &LibInput::Connection::updateScreens);
|
||||
return m_hasTabletModeSwitch;
|
||||
}
|
||||
|
||||
Qt::MouseButtons InputRedirection::qtButtonStates() const
|
||||
|
|
48
src/input.h
48
src/input.h
|
@ -42,7 +42,6 @@ class TouchInputRedirection;
|
|||
class WindowSelectorFilter;
|
||||
class SwitchEvent;
|
||||
class TabletEvent;
|
||||
class TabletInputFilter;
|
||||
class TabletToolId;
|
||||
class TabletPadId;
|
||||
|
||||
|
@ -51,11 +50,8 @@ namespace Decoration
|
|||
class DecoratedClientImpl;
|
||||
}
|
||||
|
||||
namespace LibInput
|
||||
{
|
||||
class Connection;
|
||||
class Device;
|
||||
}
|
||||
class InputBackend;
|
||||
class InputDevice;
|
||||
|
||||
/**
|
||||
* @brief This class is responsible for redirecting incoming input to the surface which currently
|
||||
|
@ -221,14 +217,24 @@ public:
|
|||
return m_touch;
|
||||
}
|
||||
|
||||
QList<InputDevice *> devices() const;
|
||||
|
||||
bool hasAlphaNumericKeyboard();
|
||||
bool hasPointer() const;
|
||||
bool hasTouch() const;
|
||||
bool hasTabletModeSwitch();
|
||||
|
||||
void startInteractiveWindowSelection(std::function<void(KWin::Toplevel*)> callback, const QByteArray &cursorName);
|
||||
void startInteractivePositionSelection(std::function<void(const QPoint &)> callback);
|
||||
bool isSelectingWindow() const;
|
||||
|
||||
void toggleTouchpads();
|
||||
void enableTouchpads();
|
||||
void disableTouchpads();
|
||||
|
||||
Q_SIGNALS:
|
||||
void deviceAdded(InputDevice *device);
|
||||
void deviceRemoved(InputDevice *device);
|
||||
/**
|
||||
* @brief Emitted when the global pointer position changed
|
||||
*
|
||||
|
@ -267,30 +273,35 @@ Q_SIGNALS:
|
|||
*/
|
||||
void keyStateChanged(quint32 keyCode, InputRedirection::KeyboardKeyState state);
|
||||
|
||||
void hasKeyboardChanged(bool set);
|
||||
void hasAlphaNumericKeyboardChanged(bool set);
|
||||
void hasPointerChanged(bool set);
|
||||
void hasTouchChanged(bool set);
|
||||
void hasTabletModeSwitchChanged(bool set);
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleInputConfigChanged(const KConfigGroup &group);
|
||||
void handleInputDeviceAdded(InputDevice *device);
|
||||
void handleInputDeviceRemoved(InputDevice *device);
|
||||
|
||||
private:
|
||||
void setupLibInput();
|
||||
void setupInputBackends();
|
||||
void setupTouchpadShortcuts();
|
||||
void setupLibInputWithScreens();
|
||||
void setupWorkspace();
|
||||
void reconfigure();
|
||||
void setupInputFilters();
|
||||
void installInputEventFilter(InputEventFilter *filter);
|
||||
void updateLeds(LEDs leds);
|
||||
void updateAvailableInputDevices();
|
||||
void addInputBackend(InputBackend *inputBackend);
|
||||
KeyboardInputRedirection *m_keyboard;
|
||||
PointerInputRedirection *m_pointer;
|
||||
TabletInputRedirection *m_tablet;
|
||||
TouchInputRedirection *m_touch;
|
||||
TabletInputFilter *m_tabletSupport = nullptr;
|
||||
|
||||
GlobalShortcutsManager *m_shortcuts;
|
||||
|
||||
LibInput::Connection *m_libInput = nullptr;
|
||||
QThread *m_libInputThread = nullptr;
|
||||
QList<InputBackend *> m_inputBackends;
|
||||
QList<InputDevice *> m_inputDevices;
|
||||
|
||||
WindowSelectorFilter *m_windowSelector = nullptr;
|
||||
|
||||
|
@ -298,6 +309,14 @@ private:
|
|||
QVector<InputEventSpy*> m_spies;
|
||||
KConfigWatcher::Ptr m_inputConfigWatcher;
|
||||
|
||||
LEDs m_leds;
|
||||
bool m_hasKeyboard = false;
|
||||
bool m_hasAlphaNumericKeyboard = false;
|
||||
bool m_hasPointer = false;
|
||||
bool m_hasTouch = false;
|
||||
bool m_hasTabletModeSwitch = false;
|
||||
bool m_touchpadsEnabled = true;
|
||||
|
||||
KWIN_SINGLETON(InputRedirection)
|
||||
friend InputRedirection *input();
|
||||
friend class DecorationEventFilter;
|
||||
|
@ -491,6 +510,11 @@ InputRedirection *input()
|
|||
return InputRedirection::s_self;
|
||||
}
|
||||
|
||||
inline QList<InputDevice *> InputRedirection::devices() const
|
||||
{
|
||||
return m_inputDevices;
|
||||
}
|
||||
|
||||
template <typename T, typename Slot>
|
||||
inline
|
||||
void InputRedirection::registerShortcut(const QKeySequence &shortcut, QAction *action, T *receiver, Slot slot) {
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace KWin
|
|||
MouseEvent::MouseEvent(QEvent::Type type, const QPointF &pos, Qt::MouseButton button,
|
||||
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
|
||||
quint32 timestamp, const QSizeF &delta, const QSizeF &deltaNonAccelerated,
|
||||
quint64 timestampMicroseconds, LibInput::Device *device)
|
||||
quint64 timestampMicroseconds, InputDevice *device)
|
||||
: QMouseEvent(type, pos, pos, button, buttons, modifiers)
|
||||
, m_delta(delta)
|
||||
, m_deltaUnccelerated(deltaNonAccelerated)
|
||||
|
@ -26,7 +26,7 @@ MouseEvent::MouseEvent(QEvent::Type type, const QPointF &pos, Qt::MouseButton bu
|
|||
|
||||
WheelEvent::WheelEvent(const QPointF &pos, qreal delta, qint32 discreteDelta, Qt::Orientation orientation,
|
||||
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, InputRedirection::PointerAxisSource source,
|
||||
quint32 timestamp, LibInput::Device *device)
|
||||
quint32 timestamp, InputDevice *device)
|
||||
: QWheelEvent(pos, pos, QPoint(), (orientation == Qt::Horizontal) ? QPoint(delta, 0) : QPoint(0, delta), delta, orientation, buttons, modifiers)
|
||||
, m_device(device)
|
||||
, m_orientation(orientation)
|
||||
|
@ -38,14 +38,14 @@ WheelEvent::WheelEvent(const QPointF &pos, qreal delta, qint32 discreteDelta, Qt
|
|||
}
|
||||
|
||||
KeyEvent::KeyEvent(QEvent::Type type, Qt::Key key, Qt::KeyboardModifiers modifiers, quint32 code, quint32 keysym,
|
||||
const QString &text, bool autorepeat, quint32 timestamp, LibInput::Device *device)
|
||||
const QString &text, bool autorepeat, quint32 timestamp, InputDevice *device)
|
||||
: QKeyEvent(type, key, modifiers, code, keysym, 0, text, autorepeat)
|
||||
, m_device(device)
|
||||
{
|
||||
setTimestamp(timestamp);
|
||||
}
|
||||
|
||||
SwitchEvent::SwitchEvent(State state, quint32 timestamp, quint64 timestampMicroseconds, LibInput::Device* device)
|
||||
SwitchEvent::SwitchEvent(State state, quint32 timestamp, quint64 timestampMicroseconds, InputDevice* device)
|
||||
: QInputEvent(QEvent::User)
|
||||
, m_state(state)
|
||||
, m_timestampMicroseconds(timestampMicroseconds)
|
||||
|
|
|
@ -16,10 +16,7 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
namespace LibInput
|
||||
{
|
||||
class Device;
|
||||
}
|
||||
class InputDevice;
|
||||
|
||||
class MouseEvent : public QMouseEvent
|
||||
{
|
||||
|
@ -27,7 +24,7 @@ public:
|
|||
explicit MouseEvent(QEvent::Type type, const QPointF &pos, Qt::MouseButton button, Qt::MouseButtons buttons,
|
||||
Qt::KeyboardModifiers modifiers, quint32 timestamp,
|
||||
const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 timestampMicroseconds,
|
||||
LibInput::Device *device);
|
||||
InputDevice *device);
|
||||
|
||||
QSizeF delta() const {
|
||||
return m_delta;
|
||||
|
@ -41,7 +38,7 @@ public:
|
|||
return m_timestampMicroseconds;
|
||||
}
|
||||
|
||||
LibInput::Device *device() const {
|
||||
InputDevice *device() const {
|
||||
return m_device;
|
||||
}
|
||||
|
||||
|
@ -65,7 +62,7 @@ private:
|
|||
QSizeF m_delta;
|
||||
QSizeF m_deltaUnccelerated;
|
||||
quint64 m_timestampMicroseconds;
|
||||
LibInput::Device *m_device;
|
||||
InputDevice *m_device;
|
||||
Qt::KeyboardModifiers m_modifiersRelevantForShortcuts = Qt::KeyboardModifiers();
|
||||
quint32 m_nativeButton = 0;
|
||||
};
|
||||
|
@ -76,7 +73,7 @@ class WheelEvent : public QWheelEvent
|
|||
public:
|
||||
explicit WheelEvent(const QPointF &pos, qreal delta, qint32 discreteDelta, Qt::Orientation orientation,
|
||||
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, InputRedirection::PointerAxisSource source,
|
||||
quint32 timestamp, LibInput::Device *device);
|
||||
quint32 timestamp, InputDevice *device);
|
||||
|
||||
Qt::Orientation orientation() const {
|
||||
return m_orientation;
|
||||
|
@ -94,7 +91,7 @@ public:
|
|||
return m_source;
|
||||
}
|
||||
|
||||
LibInput::Device *device() const {
|
||||
InputDevice *device() const {
|
||||
return m_device;
|
||||
}
|
||||
|
||||
|
@ -107,7 +104,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
LibInput::Device *m_device;
|
||||
InputDevice *m_device;
|
||||
Qt::Orientation m_orientation;
|
||||
qreal m_delta;
|
||||
qint32 m_discreteDelta;
|
||||
|
@ -119,9 +116,9 @@ class KeyEvent : public QKeyEvent
|
|||
{
|
||||
public:
|
||||
explicit KeyEvent(QEvent::Type type, Qt::Key key, Qt::KeyboardModifiers modifiers, quint32 code, quint32 keysym,
|
||||
const QString &text, bool autorepeat, quint32 timestamp, LibInput::Device *device);
|
||||
const QString &text, bool autorepeat, quint32 timestamp, InputDevice *device);
|
||||
|
||||
LibInput::Device *device() const {
|
||||
InputDevice *device() const {
|
||||
return m_device;
|
||||
}
|
||||
|
||||
|
@ -134,7 +131,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
LibInput::Device *m_device;
|
||||
InputDevice *m_device;
|
||||
Qt::KeyboardModifiers m_modifiersRelevantForShortcuts = Qt::KeyboardModifiers();
|
||||
};
|
||||
|
||||
|
@ -145,7 +142,7 @@ public:
|
|||
Off,
|
||||
On
|
||||
};
|
||||
explicit SwitchEvent(State state, quint32 timestamp, quint64 timestampMicroseconds, LibInput::Device *device);
|
||||
explicit SwitchEvent(State state, quint32 timestamp, quint64 timestampMicroseconds, InputDevice *device);
|
||||
|
||||
State state() const {
|
||||
return m_state;
|
||||
|
@ -155,14 +152,14 @@ public:
|
|||
return m_timestampMicroseconds;
|
||||
}
|
||||
|
||||
LibInput::Device *device() const {
|
||||
InputDevice *device() const {
|
||||
return m_device;
|
||||
}
|
||||
|
||||
private:
|
||||
State m_state;
|
||||
quint64 m_timestampMicroseconds;
|
||||
LibInput::Device *m_device;
|
||||
InputDevice *m_device;
|
||||
};
|
||||
|
||||
class TabletToolId
|
||||
|
|
27
src/inputbackend.cpp
Normal file
27
src/inputbackend.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "inputbackend.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
InputBackend::InputBackend(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
KSharedConfigPtr InputBackend::config() const
|
||||
{
|
||||
return m_config;
|
||||
}
|
||||
|
||||
void InputBackend::setConfig(KSharedConfigPtr config)
|
||||
{
|
||||
m_config = config;
|
||||
}
|
||||
|
||||
} // namespace KWin
|
40
src/inputbackend.h
Normal file
40
src/inputbackend.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kwin_export.h"
|
||||
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class InputDevice;
|
||||
|
||||
class KWIN_EXPORT InputBackend : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InputBackend(QObject *parent = nullptr);
|
||||
|
||||
KSharedConfigPtr config() const;
|
||||
void setConfig(KSharedConfigPtr config);
|
||||
|
||||
virtual void initialize() {}
|
||||
|
||||
Q_SIGNALS:
|
||||
void deviceAdded(InputDevice *device);
|
||||
void deviceRemoved(InputDevice *device);
|
||||
|
||||
private:
|
||||
KSharedConfigPtr m_config;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
17
src/inputdevice.cpp
Normal file
17
src/inputdevice.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "inputdevice.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
InputDevice::InputDevice(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace KWin
|
83
src/inputdevice.h
Normal file
83
src/inputdevice.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
|
||||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kwin_export.h"
|
||||
#include "input.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
/**
|
||||
* The InputDevice class represents an input device, e.g. a mouse, or a keyboard, etc.
|
||||
*/
|
||||
class KWIN_EXPORT InputDevice : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InputDevice(QObject *parent = nullptr);
|
||||
|
||||
virtual QString sysName() const = 0;
|
||||
virtual QString name() const = 0;
|
||||
|
||||
virtual bool isEnabled() const = 0;
|
||||
virtual void setEnabled(bool enabled) = 0;
|
||||
|
||||
virtual LEDs leds() const = 0;
|
||||
virtual void setLeds(LEDs leds) = 0;
|
||||
|
||||
virtual bool isKeyboard() const = 0;
|
||||
virtual bool isAlphaNumericKeyboard() const = 0;
|
||||
virtual bool isPointer() const = 0;
|
||||
virtual bool isTouchpad() const = 0;
|
||||
virtual bool isTouch() const = 0;
|
||||
virtual bool isTabletTool() const = 0;
|
||||
virtual bool isTabletPad() const = 0;
|
||||
virtual bool isTabletModeSwitch() const = 0;
|
||||
virtual bool isLidSwitch() const = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void keyChanged(quint32 key, InputRedirection::KeyboardKeyState, quint32 time, InputDevice *device);
|
||||
void pointerButtonChanged(quint32 button, InputRedirection::PointerButtonState state, quint32 time, InputDevice *device);
|
||||
void pointerMotionAbsolute(const QPointF &position, quint32 time, InputDevice *device);
|
||||
void pointerMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint32 time, quint64 timeMicroseconds, InputDevice *device);
|
||||
void pointerAxisChanged(InputRedirection::PointerAxis axis, qreal delta, qint32 discreteDelta,
|
||||
InputRedirection::PointerAxisSource source, quint32 time, InputDevice *device);
|
||||
void touchFrame(InputDevice *device);
|
||||
void touchCanceled(InputDevice *device);
|
||||
void touchDown(qint32 id, const QPointF &absolutePos, quint32 time, InputDevice *device);
|
||||
void touchUp(qint32 id, quint32 time, InputDevice *device);
|
||||
void touchMotion(qint32 id, const QPointF &absolutePos, quint32 time, InputDevice *device);
|
||||
void swipeGestureBegin(int fingerCount, quint32 time, InputDevice *device);
|
||||
void swipeGestureUpdate(const QSizeF &delta, quint32 time, InputDevice *device);
|
||||
void swipeGestureEnd(quint32 time, InputDevice *device);
|
||||
void swipeGestureCancelled(quint32 time, InputDevice *device);
|
||||
void pinchGestureBegin(int fingerCount, quint32 time, InputDevice *device);
|
||||
void pinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time, InputDevice *device);
|
||||
void pinchGestureEnd(quint32 time, InputDevice *device);
|
||||
void pinchGestureCancelled(quint32 time, InputDevice *device);
|
||||
void holdGestureBegin(int fingerCount, quint32 time, InputDevice *device);
|
||||
void holdGestureEnd(quint32 time, InputDevice *device);
|
||||
void holdGestureCancelled(quint32 time, InputDevice *device);
|
||||
void switchToggledOn(quint32 time, quint64 timeMicroseconds, InputDevice *device);
|
||||
void switchToggledOff(quint32 time, quint64 timeMicroseconds, InputDevice *device);
|
||||
|
||||
void tabletToolEvent(InputRedirection::TabletEventType type, const QPointF &pos,
|
||||
qreal pressure, int xTilt, int yTilt, qreal rotation, bool tipDown,
|
||||
bool tipNear, const TabletToolId &tabletToolId, quint32 time);
|
||||
void tabletToolButtonEvent(uint button, bool isPressed, const TabletToolId &tabletToolId);
|
||||
|
||||
void tabletPadButtonEvent(uint button, bool isPressed, const TabletPadId &tabletPadId);
|
||||
void tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
|
||||
void tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
|
||||
};
|
||||
|
||||
} // namespace KWin
|
|
@ -20,6 +20,7 @@
|
|||
#include "workspace.h"
|
||||
// KWayland
|
||||
#include <KWaylandServer/datadevice_interface.h>
|
||||
#include <KWaylandServer/keyboard_interface.h>
|
||||
#include <KWaylandServer/seat_interface.h>
|
||||
//screenlocker
|
||||
#include <KScreenLocker/KsldApp>
|
||||
|
@ -103,6 +104,11 @@ void KeyboardInputRedirection::init()
|
|||
m_xkb->setNumLockConfig(InputConfig::self()->inputConfig());
|
||||
m_xkb->setConfig(config);
|
||||
|
||||
// Workaround for QTBUG-54371: if there is no real keyboard Qt doesn't request virtual keyboard
|
||||
waylandServer()->seat()->setHasKeyboard(true);
|
||||
// connect(m_input, &InputRedirection::hasAlphaNumericKeyboardChanged,
|
||||
// waylandServer()->seat(), &KWaylandServer::SeatInterface::setHasKeyboard);
|
||||
|
||||
m_input->installInputEventSpy(new KeyStateChangedSpy(m_input));
|
||||
m_modifiersChangedSpy = new ModifiersChangedSpy(m_input);
|
||||
m_input->installInputEventSpy(m_modifiersChangedSpy);
|
||||
|
@ -135,6 +141,23 @@ void KeyboardInputRedirection::init()
|
|||
if (waylandServer()->hasScreenLockerIntegration()) {
|
||||
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &KeyboardInputRedirection::update);
|
||||
}
|
||||
|
||||
reconfigure();
|
||||
}
|
||||
|
||||
void KeyboardInputRedirection::reconfigure()
|
||||
{
|
||||
if (waylandServer()->seat()->keyboard()) {
|
||||
const auto config = InputConfig::self()->inputConfig()->group(QStringLiteral("Keyboard"));
|
||||
const int delay = config.readEntry("RepeatDelay", 660);
|
||||
const int rate = int(config.readEntry("RepeatRate", 25.0));
|
||||
const QString repeatMode = config.readEntry("KeyRepeat", "repeat");
|
||||
// when the clients will repeat the character or turn repeat key events into an accent character selection, we want
|
||||
// to tell the clients that we are indeed repeating keys.
|
||||
const bool enabled = repeatMode == QLatin1String("accent") || repeatMode == QLatin1String("repeat");
|
||||
|
||||
waylandServer()->seat()->keyboard()->setRepeatInfo(enabled ? rate : 0, delay);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardInputRedirection::update()
|
||||
|
@ -178,7 +201,7 @@ void KeyboardInputRedirection::update()
|
|||
}
|
||||
}
|
||||
|
||||
void KeyboardInputRedirection::processKey(uint32_t key, InputRedirection::KeyboardKeyState state, uint32_t time, LibInput::Device *device)
|
||||
void KeyboardInputRedirection::processKey(uint32_t key, InputRedirection::KeyboardKeyState state, uint32_t time, InputDevice *device)
|
||||
{
|
||||
QEvent::Type type;
|
||||
bool autoRepeat = false;
|
||||
|
|
|
@ -32,16 +32,12 @@ typedef uint32_t xkb_layout_index_t;
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class InputDevice;
|
||||
class InputRedirection;
|
||||
class KeyboardLayout;
|
||||
class ModifiersChangedSpy;
|
||||
class Toplevel;
|
||||
|
||||
namespace LibInput
|
||||
{
|
||||
class Device;
|
||||
}
|
||||
|
||||
class KWIN_EXPORT KeyboardInputRedirection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -50,13 +46,14 @@ public:
|
|||
~KeyboardInputRedirection() override;
|
||||
|
||||
void init();
|
||||
void reconfigure();
|
||||
|
||||
void update();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processKey(uint32_t key, InputRedirection::KeyboardKeyState state, uint32_t time, LibInput::Device *device = nullptr);
|
||||
void processKey(uint32_t key, InputRedirection::KeyboardKeyState state, uint32_t time, InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
@ -25,9 +25,7 @@
|
|||
#include "udev.h"
|
||||
#include "libinput_logging.h"
|
||||
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusPendingCall>
|
||||
#include <QMutexLocker>
|
||||
#include <QSocketNotifier>
|
||||
|
||||
|
@ -53,8 +51,12 @@ public:
|
|||
: QObject(con)
|
||||
, m_con(con)
|
||||
{
|
||||
connect(con, &Connection::deviceAddedSysName, this, &ConnectionAdaptor::deviceAdded);
|
||||
connect(con, &Connection::deviceRemovedSysName, this, &ConnectionAdaptor::deviceRemoved);
|
||||
connect(con, &Connection::deviceAdded, this, [this](LibInput::Device *inputDevice) {
|
||||
Q_EMIT deviceAdded(inputDevice->sysName());
|
||||
});
|
||||
connect(con, &Connection::deviceRemoved, this, [this](LibInput::Device *inputDevice) {
|
||||
Q_EMIT deviceRemoved(inputDevice->sysName());
|
||||
});
|
||||
|
||||
QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin/InputDevice"),
|
||||
QStringLiteral("org.kde.KWin.InputDeviceManager"),
|
||||
|
@ -81,21 +83,6 @@ Connection *Connection::s_self = nullptr;
|
|||
static ConnectionAdaptor *s_adaptor = nullptr;
|
||||
static Context *s_context = nullptr;
|
||||
|
||||
static quint32 toLibinputLEDS(LEDs leds)
|
||||
{
|
||||
quint32 libinputLeds = 0;
|
||||
if (leds.testFlag(LED::NumLock)) {
|
||||
libinputLeds = libinputLeds | LIBINPUT_LED_NUM_LOCK;
|
||||
}
|
||||
if (leds.testFlag(LED::CapsLock)) {
|
||||
libinputLeds = libinputLeds | LIBINPUT_LED_CAPS_LOCK;
|
||||
}
|
||||
if (leds.testFlag(LED::ScrollLock)) {
|
||||
libinputLeds = libinputLeds | LIBINPUT_LED_SCROLL_LOCK;
|
||||
}
|
||||
return libinputLeds;
|
||||
}
|
||||
|
||||
Connection::Connection(QObject *parent)
|
||||
: Connection(nullptr, parent)
|
||||
{
|
||||
|
@ -140,7 +127,6 @@ Connection::Connection(Context *input, QObject *parent)
|
|||
, m_input(input)
|
||||
, m_notifier(nullptr)
|
||||
, m_mutex(QMutex::Recursive)
|
||||
, m_leds()
|
||||
{
|
||||
Q_ASSERT(m_input);
|
||||
// need to connect to KGlobalSettings as the mouse KCM does not emit a dedicated signal
|
||||
|
@ -164,13 +150,6 @@ void Connection::setup()
|
|||
|
||||
void Connection::doSetup()
|
||||
{
|
||||
connect(s_self, &Connection::deviceAdded, s_self, [](Device* device) {
|
||||
Q_EMIT s_self->deviceAddedSysName(device->sysName());
|
||||
});
|
||||
connect(s_self, &Connection::deviceRemoved, s_self, [](Device* device) {
|
||||
Q_EMIT s_self->deviceRemovedSysName(device->sysName());
|
||||
});
|
||||
|
||||
Q_ASSERT(!m_notifier);
|
||||
m_notifier = new QSocketNotifier(m_input->fileDescriptor(), QSocketNotifier::Read, this);
|
||||
connect(m_notifier, &QSocketNotifier::activated, this, &Connection::handleEvent);
|
||||
|
@ -181,11 +160,11 @@ void Connection::doSetup()
|
|||
return;
|
||||
}
|
||||
m_input->resume();
|
||||
wasSuspended = true;
|
||||
} else {
|
||||
deactivate();
|
||||
}
|
||||
});
|
||||
connect(kwinApp()->platform(), &Platform::screensQueried, this, &Connection::updateScreens);
|
||||
handleEvent();
|
||||
}
|
||||
|
||||
|
@ -194,11 +173,6 @@ void Connection::deactivate()
|
|||
if (m_input->isSuspended()) {
|
||||
return;
|
||||
}
|
||||
m_keyboardBeforeSuspend = hasKeyboard();
|
||||
m_alphaNumericKeyboardBeforeSuspend = hasAlphaNumericKeyboard();
|
||||
m_pointerBeforeSuspend = hasPointer();
|
||||
m_touchBeforeSuspend = hasTouch();
|
||||
m_tabletModeSwitchBeforeSuspend = hasTabletModeSwitch();
|
||||
m_input->suspend();
|
||||
handleEvent();
|
||||
}
|
||||
|
@ -315,42 +289,10 @@ void Connection::processEvents()
|
|||
auto device = new Device(event->nativeDevice());
|
||||
device->moveToThread(thread());
|
||||
m_devices << device;
|
||||
if (device->isKeyboard()) {
|
||||
m_keyboard++;
|
||||
if (device->isAlphaNumericKeyboard()) {
|
||||
m_alphaNumericKeyboard++;
|
||||
if (m_alphaNumericKeyboard == 1) {
|
||||
Q_EMIT hasAlphaNumericKeyboardChanged(true);
|
||||
}
|
||||
}
|
||||
if (m_keyboard == 1) {
|
||||
Q_EMIT hasKeyboardChanged(true);
|
||||
}
|
||||
}
|
||||
if (device->isPointer()) {
|
||||
m_pointer++;
|
||||
if (m_pointer == 1) {
|
||||
Q_EMIT hasPointerChanged(true);
|
||||
}
|
||||
}
|
||||
if (device->isTouch()) {
|
||||
m_touch++;
|
||||
if (m_touch == 1) {
|
||||
Q_EMIT hasTouchChanged(true);
|
||||
}
|
||||
}
|
||||
if (device->isTabletModeSwitch()) {
|
||||
m_tabletModeSwitch++;
|
||||
if (m_tabletModeSwitch == 1) {
|
||||
Q_EMIT hasTabletModeSwitchChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
applyDeviceConfig(device);
|
||||
applyScreenToDevice(device);
|
||||
|
||||
// enable possible leds
|
||||
libinput_device_led_update(device->device(), static_cast<libinput_led>(toLibinputLEDS(m_leds)));
|
||||
|
||||
Q_EMIT deviceAdded(device);
|
||||
break;
|
||||
}
|
||||
|
@ -363,57 +305,26 @@ void Connection::processEvents()
|
|||
auto device = *it;
|
||||
m_devices.erase(it);
|
||||
Q_EMIT deviceRemoved(device);
|
||||
|
||||
if (device->isKeyboard()) {
|
||||
m_keyboard--;
|
||||
if (device->isAlphaNumericKeyboard()) {
|
||||
m_alphaNumericKeyboard--;
|
||||
if (m_alphaNumericKeyboard == 0) {
|
||||
Q_EMIT hasAlphaNumericKeyboardChanged(false);
|
||||
}
|
||||
}
|
||||
if (m_keyboard == 0) {
|
||||
Q_EMIT hasKeyboardChanged(false);
|
||||
}
|
||||
}
|
||||
if (device->isPointer()) {
|
||||
m_pointer--;
|
||||
if (m_pointer == 0) {
|
||||
Q_EMIT hasPointerChanged(false);
|
||||
}
|
||||
}
|
||||
if (device->isTouch()) {
|
||||
m_touch--;
|
||||
if (m_touch == 0) {
|
||||
Q_EMIT hasTouchChanged(false);
|
||||
}
|
||||
}
|
||||
if (device->isTabletModeSwitch()) {
|
||||
m_tabletModeSwitch--;
|
||||
if (m_tabletModeSwitch == 0) {
|
||||
Q_EMIT hasTabletModeSwitchChanged(false);
|
||||
}
|
||||
}
|
||||
device->deleteLater();
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_KEYBOARD_KEY: {
|
||||
KeyEvent *ke = static_cast<KeyEvent*>(event.data());
|
||||
Q_EMIT keyChanged(ke->key(), ke->state(), ke->time(), ke->device());
|
||||
Q_EMIT ke->device()->keyChanged(ke->key(), ke->state(), ke->time(), ke->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_POINTER_AXIS: {
|
||||
PointerEvent *pe = static_cast<PointerEvent*>(event.data());
|
||||
const auto axes = pe->axis();
|
||||
for (const InputRedirection::PointerAxis &axis : axes) {
|
||||
Q_EMIT pointerAxisChanged(axis, pe->axisValue(axis), pe->discreteAxisValue(axis),
|
||||
pe->axisSource(), pe->time(), pe->device());
|
||||
Q_EMIT pe->device()->pointerAxisChanged(axis, pe->axisValue(axis), pe->discreteAxisValue(axis),
|
||||
pe->axisSource(), pe->time(), pe->device());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_POINTER_BUTTON: {
|
||||
PointerEvent *pe = static_cast<PointerEvent*>(event.data());
|
||||
Q_EMIT pointerButtonChanged(pe->button(), pe->buttonState(), pe->time(), pe->device());
|
||||
Q_EMIT pe->device()->pointerButtonChanged(pe->button(), pe->buttonState(), pe->time(), pe->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_POINTER_MOTION: {
|
||||
|
@ -435,12 +346,12 @@ void Connection::processEvents()
|
|||
break;
|
||||
}
|
||||
}
|
||||
Q_EMIT pointerMotion(delta, deltaNonAccel, latestTime, latestTimeUsec, pe->device());
|
||||
Q_EMIT pe->device()->pointerMotion(delta, deltaNonAccel, latestTime, latestTimeUsec, pe->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: {
|
||||
PointerEvent *pe = static_cast<PointerEvent*>(event.data());
|
||||
Q_EMIT pointerMotionAbsolute(pe->absolutePos(m_size), pe->time(), pe->device());
|
||||
Q_EMIT pe->device()->pointerMotionAbsolute(pe->absolutePos(workspace()->geometry().size()), pe->time(), pe->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TOUCH_DOWN: {
|
||||
|
@ -450,13 +361,13 @@ void Connection::processEvents()
|
|||
const QPointF globalPos =
|
||||
devicePointToGlobalPosition(te->absolutePos(output->modeSize()),
|
||||
output);
|
||||
Q_EMIT touchDown(te->id(), globalPos, te->time(), te->device());
|
||||
Q_EMIT te->device()->touchDown(te->id(), globalPos, te->time(), te->device());
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
case LIBINPUT_EVENT_TOUCH_UP: {
|
||||
TouchEvent *te = static_cast<TouchEvent*>(event.data());
|
||||
Q_EMIT touchUp(te->id(), te->time(), te->device());
|
||||
Q_EMIT te->device()->touchUp(te->id(), te->time(), te->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TOUCH_MOTION: {
|
||||
|
@ -466,67 +377,67 @@ void Connection::processEvents()
|
|||
const QPointF globalPos =
|
||||
devicePointToGlobalPosition(te->absolutePos(output->modeSize()),
|
||||
output);
|
||||
Q_EMIT touchMotion(te->id(), globalPos, te->time(), te->device());
|
||||
Q_EMIT te->device()->touchMotion(te->id(), globalPos, te->time(), te->device());
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
case LIBINPUT_EVENT_TOUCH_CANCEL: {
|
||||
Q_EMIT touchCanceled(event->device());
|
||||
Q_EMIT event->device()->touchCanceled(event->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TOUCH_FRAME: {
|
||||
Q_EMIT touchFrame(event->device());
|
||||
Q_EMIT event->device()->touchFrame(event->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: {
|
||||
PinchGestureEvent *pe = static_cast<PinchGestureEvent*>(event.data());
|
||||
Q_EMIT pinchGestureBegin(pe->fingerCount(), pe->time(), pe->device());
|
||||
Q_EMIT pe->device()->pinchGestureBegin(pe->fingerCount(), pe->time(), pe->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: {
|
||||
PinchGestureEvent *pe = static_cast<PinchGestureEvent*>(event.data());
|
||||
Q_EMIT pinchGestureUpdate(pe->scale(), pe->angleDelta(), pe->delta(), pe->time(), pe->device());
|
||||
Q_EMIT pe->device()->pinchGestureUpdate(pe->scale(), pe->angleDelta(), pe->delta(), pe->time(), pe->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_END: {
|
||||
PinchGestureEvent *pe = static_cast<PinchGestureEvent*>(event.data());
|
||||
if (pe->isCancelled()) {
|
||||
Q_EMIT pinchGestureCancelled(pe->time(), pe->device());
|
||||
Q_EMIT pe->device()->pinchGestureCancelled(pe->time(), pe->device());
|
||||
} else {
|
||||
Q_EMIT pinchGestureEnd(pe->time(), pe->device());
|
||||
Q_EMIT pe->device()->pinchGestureEnd(pe->time(), pe->device());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN: {
|
||||
SwipeGestureEvent *se = static_cast<SwipeGestureEvent*>(event.data());
|
||||
Q_EMIT swipeGestureBegin(se->fingerCount(), se->time(), se->device());
|
||||
Q_EMIT se->device()->swipeGestureBegin(se->fingerCount(), se->time(), se->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: {
|
||||
SwipeGestureEvent *se = static_cast<SwipeGestureEvent*>(event.data());
|
||||
Q_EMIT swipeGestureUpdate(se->delta(), se->time(), se->device());
|
||||
Q_EMIT se->device()->swipeGestureUpdate(se->delta(), se->time(), se->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_SWIPE_END: {
|
||||
SwipeGestureEvent *se = static_cast<SwipeGestureEvent*>(event.data());
|
||||
if (se->isCancelled()) {
|
||||
Q_EMIT swipeGestureCancelled(se->time(), se->device());
|
||||
Q_EMIT se->device()->swipeGestureCancelled(se->time(), se->device());
|
||||
} else {
|
||||
Q_EMIT swipeGestureEnd(se->time(), se->device());
|
||||
Q_EMIT se->device()->swipeGestureEnd(se->time(), se->device());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN: {
|
||||
HoldGestureEvent *he = static_cast<HoldGestureEvent*>(event.data());
|
||||
Q_EMIT holdGestureBegin(he->fingerCount(), he->time(), he->device());
|
||||
Q_EMIT he->device()->holdGestureBegin(he->fingerCount(), he->time(), he->device());
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_HOLD_END: {
|
||||
HoldGestureEvent *he = static_cast<HoldGestureEvent*>(event.data());
|
||||
if (he->isCancelled()) {
|
||||
Q_EMIT holdGestureCancelled(he->time(), he->device());
|
||||
Q_EMIT he->device()->holdGestureCancelled(he->time(), he->device());
|
||||
} else {
|
||||
Q_EMIT holdGestureEnd(he->time(), he->device());
|
||||
Q_EMIT he->device()->holdGestureEnd(he->time(), he->device());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -534,10 +445,10 @@ void Connection::processEvents()
|
|||
SwitchEvent *se = static_cast<SwitchEvent*>(event.data());
|
||||
switch (se->state()) {
|
||||
case SwitchEvent::State::Off:
|
||||
Q_EMIT switchToggledOff(se->time(), se->timeMicroseconds(), se->device());
|
||||
Q_EMIT se->device()->switchToggledOff(se->time(), se->timeMicroseconds(), se->device());
|
||||
break;
|
||||
case SwitchEvent::State::On:
|
||||
Q_EMIT switchToggledOn(se->time(), se->timeMicroseconds(), se->device());
|
||||
Q_EMIT se->device()->switchToggledOn(se->time(), se->timeMicroseconds(), se->device());
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
|
@ -573,42 +484,42 @@ void Connection::processEvents()
|
|||
#else
|
||||
const QPointF globalPos;
|
||||
#endif
|
||||
Q_EMIT tabletToolEvent(tabletEventType,
|
||||
globalPos, tte->pressure(),
|
||||
tte->xTilt(), tte->yTilt(), tte->rotation(),
|
||||
tte->isTipDown(), tte->isNearby(), createTabletId(tte->tool(), event->device()->groupUserData()), tte->time());
|
||||
Q_EMIT event->device()->tabletToolEvent(tabletEventType,
|
||||
globalPos, tte->pressure(),
|
||||
tte->xTilt(), tte->yTilt(), tte->rotation(),
|
||||
tte->isTipDown(), tte->isNearby(), createTabletId(tte->tool(), event->device()->groupUserData()), tte->time());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: {
|
||||
auto *tabletEvent = static_cast<TabletToolButtonEvent *>(event.data());
|
||||
Q_EMIT tabletToolButtonEvent(tabletEvent->buttonId(),
|
||||
tabletEvent->isButtonPressed(),
|
||||
createTabletId(tabletEvent->tool(), event->device()->groupUserData()));
|
||||
Q_EMIT event->device()->tabletToolButtonEvent(tabletEvent->buttonId(),
|
||||
tabletEvent->isButtonPressed(),
|
||||
createTabletId(tabletEvent->tool(), event->device()->groupUserData()));
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_PAD_BUTTON: {
|
||||
auto *tabletEvent = static_cast<TabletPadButtonEvent *>(event.data());
|
||||
Q_EMIT tabletPadButtonEvent(tabletEvent->buttonId(),
|
||||
tabletEvent->isButtonPressed(),
|
||||
{ event->device()->groupUserData() });
|
||||
Q_EMIT event->device()->tabletPadButtonEvent(tabletEvent->buttonId(),
|
||||
tabletEvent->isButtonPressed(),
|
||||
{ event->device()->groupUserData() });
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_PAD_RING: {
|
||||
auto *tabletEvent = static_cast<TabletPadRingEvent *>(event.data());
|
||||
tabletEvent->position();
|
||||
Q_EMIT tabletPadRingEvent(tabletEvent->number(),
|
||||
tabletEvent->position(),
|
||||
tabletEvent->source() == LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
|
||||
{ event->device()->groupUserData() });
|
||||
Q_EMIT event->device()->tabletPadRingEvent(tabletEvent->number(),
|
||||
tabletEvent->position(),
|
||||
tabletEvent->source() == LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
|
||||
{ event->device()->groupUserData() });
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_PAD_STRIP: {
|
||||
auto *tabletEvent = static_cast<TabletPadStripEvent *>(event.data());
|
||||
Q_EMIT tabletPadStripEvent(tabletEvent->number(),
|
||||
tabletEvent->position(),
|
||||
tabletEvent->source() == LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
|
||||
{ event->device()->groupUserData() });
|
||||
Q_EMIT event->device()->tabletPadStripEvent(tabletEvent->number(),
|
||||
tabletEvent->position(),
|
||||
tabletEvent->source() == LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
|
||||
{ event->device()->groupUserData() });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -616,29 +527,6 @@ void Connection::processEvents()
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (wasSuspended) {
|
||||
if (m_keyboardBeforeSuspend && !m_keyboard) {
|
||||
Q_EMIT hasKeyboardChanged(false);
|
||||
}
|
||||
if (m_alphaNumericKeyboardBeforeSuspend && !m_alphaNumericKeyboard) {
|
||||
Q_EMIT hasAlphaNumericKeyboardChanged(false);
|
||||
}
|
||||
if (m_pointerBeforeSuspend && !m_pointer) {
|
||||
Q_EMIT hasPointerChanged(false);
|
||||
}
|
||||
if (m_touchBeforeSuspend && !m_touch) {
|
||||
Q_EMIT hasTouchChanged(false);
|
||||
}
|
||||
if (m_tabletModeSwitchBeforeSuspend && !m_tabletModeSwitch) {
|
||||
Q_EMIT hasTabletModeSwitchChanged(false);
|
||||
}
|
||||
wasSuspended = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::setScreenSize(const QSize &size)
|
||||
{
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
void Connection::updateScreens()
|
||||
|
@ -718,14 +606,6 @@ void Connection::applyScreenToDevice(Device *device)
|
|||
#endif
|
||||
}
|
||||
|
||||
bool Connection::isSuspended() const
|
||||
{
|
||||
if (!s_context) {
|
||||
return false;
|
||||
}
|
||||
return s_context->isSuspended();
|
||||
}
|
||||
|
||||
void Connection::applyDeviceConfig(Device *device)
|
||||
{
|
||||
// pass configuration to Device
|
||||
|
@ -745,63 +625,6 @@ void Connection::slotKGlobalSettingsNotifyChange(int type, int arg)
|
|||
}
|
||||
}
|
||||
|
||||
void Connection::toggleTouchpads()
|
||||
{
|
||||
bool changed = false;
|
||||
m_touchpadsEnabled = !m_touchpadsEnabled;
|
||||
for (auto it = m_devices.constBegin(); it != m_devices.constEnd(); ++it) {
|
||||
auto device = *it;
|
||||
if (!device->isTouchpad()) {
|
||||
continue;
|
||||
}
|
||||
const bool old = device->isEnabled();
|
||||
device->setEnabled(m_touchpadsEnabled);
|
||||
if (old != device->isEnabled()) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
// send OSD message
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(
|
||||
QStringLiteral("org.kde.plasmashell"),
|
||||
QStringLiteral("/org/kde/osdService"),
|
||||
QStringLiteral("org.kde.osdService"),
|
||||
QStringLiteral("touchpadEnabledChanged")
|
||||
);
|
||||
msg.setArguments({m_touchpadsEnabled});
|
||||
QDBusConnection::sessionBus().asyncCall(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::enableTouchpads()
|
||||
{
|
||||
if (m_touchpadsEnabled) {
|
||||
return;
|
||||
}
|
||||
toggleTouchpads();
|
||||
}
|
||||
|
||||
void Connection::disableTouchpads()
|
||||
{
|
||||
if (!m_touchpadsEnabled) {
|
||||
return;
|
||||
}
|
||||
toggleTouchpads();
|
||||
}
|
||||
|
||||
void Connection::updateLEDs(LEDs leds)
|
||||
{
|
||||
if (m_leds == leds) {
|
||||
return;
|
||||
}
|
||||
m_leds = leds;
|
||||
// update on devices
|
||||
const libinput_led l = static_cast<libinput_led>(toLibinputLEDS(leds));
|
||||
for (auto it = m_devices.constBegin(), end = m_devices.constEnd(); it != end; ++it) {
|
||||
libinput_device_led_update((*it)->device(), l);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList Connection::devicesSysNames() const {
|
||||
QStringList sl;
|
||||
Q_FOREACH (Device *d, m_devices) {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <kwinglobals.h>
|
||||
|
||||
#include "input.h"
|
||||
#include <KSharedConfig>
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
@ -44,91 +44,15 @@ public:
|
|||
}
|
||||
|
||||
void setup();
|
||||
/**
|
||||
* Sets the screen @p size. This is needed for mapping absolute pointer events to
|
||||
* the screen data.
|
||||
*/
|
||||
void setScreenSize(const QSize &size);
|
||||
|
||||
void updateScreens();
|
||||
|
||||
bool hasKeyboard() const {
|
||||
return m_keyboard > 0;
|
||||
}
|
||||
bool hasAlphaNumericKeyboard() const {
|
||||
return m_alphaNumericKeyboard > 0;
|
||||
}
|
||||
bool hasTouch() const {
|
||||
return m_touch > 0;
|
||||
}
|
||||
bool hasPointer() const {
|
||||
return m_pointer > 0;
|
||||
}
|
||||
bool hasTabletModeSwitch() const {
|
||||
return m_tabletModeSwitch > 0;
|
||||
}
|
||||
|
||||
bool isSuspended() const;
|
||||
|
||||
void deactivate();
|
||||
|
||||
void processEvents();
|
||||
|
||||
void toggleTouchpads();
|
||||
void enableTouchpads();
|
||||
void disableTouchpads();
|
||||
|
||||
QVector<Device*> devices() const {
|
||||
return m_devices;
|
||||
}
|
||||
|
||||
QStringList devicesSysNames() const;
|
||||
|
||||
void updateLEDs(KWin::LEDs leds);
|
||||
|
||||
Q_SIGNALS:
|
||||
void keyChanged(quint32 key, KWin::InputRedirection::KeyboardKeyState, quint32 time, KWin::LibInput::Device *device);
|
||||
void pointerButtonChanged(quint32 button, KWin::InputRedirection::PointerButtonState state, quint32 time, KWin::LibInput::Device *device);
|
||||
void pointerMotionAbsolute(const QPointF &position, quint32 time, KWin::LibInput::Device *device);
|
||||
void pointerMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint32 time, quint64 timeMicroseconds, KWin::LibInput::Device *device);
|
||||
void pointerAxisChanged(KWin::InputRedirection::PointerAxis axis, qreal delta, qint32 discreteDelta,
|
||||
KWin::InputRedirection::PointerAxisSource source, quint32 time, KWin::LibInput::Device *device);
|
||||
void touchFrame(KWin::LibInput::Device *device);
|
||||
void touchCanceled(KWin::LibInput::Device *device);
|
||||
void touchDown(qint32 id, const QPointF &absolutePos, quint32 time, KWin::LibInput::Device *device);
|
||||
void touchUp(qint32 id, quint32 time, KWin::LibInput::Device *device);
|
||||
void touchMotion(qint32 id, const QPointF &absolutePos, quint32 time, KWin::LibInput::Device *device);
|
||||
void hasKeyboardChanged(bool);
|
||||
void hasAlphaNumericKeyboardChanged(bool);
|
||||
void hasPointerChanged(bool);
|
||||
void hasTouchChanged(bool);
|
||||
void hasTabletModeSwitchChanged(bool);
|
||||
void deviceAdded(KWin::LibInput::Device *);
|
||||
void deviceRemoved(KWin::LibInput::Device *);
|
||||
void deviceAddedSysName(QString);
|
||||
void deviceRemovedSysName(QString);
|
||||
void swipeGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device);
|
||||
void swipeGestureUpdate(const QSizeF &delta, quint32 time, KWin::LibInput::Device *device);
|
||||
void swipeGestureEnd(quint32 time, KWin::LibInput::Device *device);
|
||||
void swipeGestureCancelled(quint32 time, KWin::LibInput::Device *device);
|
||||
void pinchGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device);
|
||||
void pinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time, KWin::LibInput::Device *device);
|
||||
void pinchGestureEnd(quint32 time, KWin::LibInput::Device *device);
|
||||
void pinchGestureCancelled(quint32 time, KWin::LibInput::Device *device);
|
||||
void holdGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device);
|
||||
void holdGestureEnd(quint32 time, KWin::LibInput::Device *device);
|
||||
void holdGestureCancelled(quint32 time, KWin::LibInput::Device *device);
|
||||
void switchToggledOn(quint32 time, quint64 timeMicroseconds, KWin::LibInput::Device *device);
|
||||
void switchToggledOff(quint32 time, quint64 timeMicroseconds, KWin::LibInput::Device *device);
|
||||
|
||||
void tabletToolEvent(KWin::InputRedirection::TabletEventType type, const QPointF &pos,
|
||||
qreal pressure, int xTilt, int yTilt, qreal rotation, bool tipDown,
|
||||
bool tipNear, const TabletToolId &tabletToolId, quint32 time);
|
||||
void tabletToolButtonEvent(uint button, bool isPressed, const TabletToolId &tabletToolId);
|
||||
|
||||
void tabletPadButtonEvent(uint button, bool isPressed, const TabletPadId &tabletPadId);
|
||||
void tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
|
||||
void tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
|
||||
|
||||
void eventsRead();
|
||||
|
||||
|
@ -143,24 +67,10 @@ private:
|
|||
void applyScreenToDevice(Device *device);
|
||||
Context *m_input;
|
||||
QSocketNotifier *m_notifier;
|
||||
QSize m_size;
|
||||
int m_keyboard = 0;
|
||||
int m_alphaNumericKeyboard = 0;
|
||||
int m_pointer = 0;
|
||||
int m_touch = 0;
|
||||
int m_tabletModeSwitch = 0;
|
||||
bool m_keyboardBeforeSuspend = false;
|
||||
bool m_alphaNumericKeyboardBeforeSuspend = false;
|
||||
bool m_pointerBeforeSuspend = false;
|
||||
bool m_touchBeforeSuspend = false;
|
||||
bool m_tabletModeSwitchBeforeSuspend = false;
|
||||
QMutex m_mutex;
|
||||
QVector<Event*> m_eventQueue;
|
||||
bool wasSuspended = false;
|
||||
QVector<Device*> m_devices;
|
||||
KSharedConfigPtr m_config;
|
||||
bool m_touchpadsEnabled = true;
|
||||
LEDs m_leds;
|
||||
|
||||
KWIN_SINGLETON(Connection)
|
||||
};
|
||||
|
|
|
@ -152,7 +152,7 @@ QMatrix4x4 defaultCalibrationMatrix(libinput_device *device)
|
|||
}
|
||||
|
||||
Device::Device(libinput_device *device, QObject *parent)
|
||||
: QObject(parent)
|
||||
: InputDevice(parent)
|
||||
, m_device(device)
|
||||
, m_keyboard(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_KEYBOARD))
|
||||
, m_pointer(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_POINTER))
|
||||
|
@ -555,5 +555,33 @@ void Device::setOutput(AbstractOutput *output)
|
|||
m_output = output;
|
||||
}
|
||||
|
||||
static libinput_led toLibinputLEDS(LEDs leds)
|
||||
{
|
||||
quint32 libinputLeds = 0;
|
||||
if (leds.testFlag(LED::NumLock)) {
|
||||
libinputLeds = libinputLeds | LIBINPUT_LED_NUM_LOCK;
|
||||
}
|
||||
if (leds.testFlag(LED::CapsLock)) {
|
||||
libinputLeds = libinputLeds | LIBINPUT_LED_CAPS_LOCK;
|
||||
}
|
||||
if (leds.testFlag(LED::ScrollLock)) {
|
||||
libinputLeds = libinputLeds | LIBINPUT_LED_SCROLL_LOCK;
|
||||
}
|
||||
return libinput_led(libinputLeds);
|
||||
}
|
||||
|
||||
LEDs Device::leds() const
|
||||
{
|
||||
return m_leds;
|
||||
}
|
||||
|
||||
void Device::setLeds(LEDs leds)
|
||||
{
|
||||
if (m_leds != leds) {
|
||||
m_leds = leds;
|
||||
libinput_device_led_update(m_device, toLibinputLEDS(m_leds));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#ifndef KWIN_LIBINPUT_DEVICE_H
|
||||
#define KWIN_LIBINPUT_DEVICE_H
|
||||
|
||||
#include "inputdevice.h"
|
||||
|
||||
#include <libinput.h>
|
||||
|
||||
#include <KConfigGroup>
|
||||
|
@ -18,7 +20,6 @@
|
|||
#include <QPointer>
|
||||
#include <QSizeF>
|
||||
#include <QVector>
|
||||
#include "kwin_export.h"
|
||||
|
||||
struct libinput_device;
|
||||
|
||||
|
@ -30,7 +31,7 @@ namespace LibInput
|
|||
{
|
||||
enum class ConfigKey;
|
||||
|
||||
class KWIN_EXPORT Device : public QObject
|
||||
class KWIN_EXPORT Device : public InputDevice
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.KWin.InputDevice")
|
||||
|
@ -137,16 +138,16 @@ public:
|
|||
explicit Device(libinput_device *device, QObject *parent = nullptr);
|
||||
~Device() override;
|
||||
|
||||
bool isKeyboard() const {
|
||||
bool isKeyboard() const override {
|
||||
return m_keyboard;
|
||||
}
|
||||
bool isAlphaNumericKeyboard() const {
|
||||
bool isAlphaNumericKeyboard() const override {
|
||||
return m_alphaNumericKeyboard;
|
||||
}
|
||||
bool isPointer() const {
|
||||
bool isPointer() const override {
|
||||
return m_pointer;
|
||||
}
|
||||
bool isTouchpad() const{
|
||||
bool isTouchpad() const override {
|
||||
return m_pointer &&
|
||||
// ignore all combined devices. E.g. a touchpad on a keyboard we don't want to toggle
|
||||
// as that would result in the keyboard going off as well
|
||||
|
@ -154,22 +155,22 @@ public:
|
|||
// is this a touch pad? We don't really know, let's do some assumptions
|
||||
(m_tapFingerCount > 0 || m_supportsDisableWhileTyping || m_supportsDisableEventsOnExternalMouse);
|
||||
}
|
||||
bool isTouch() const {
|
||||
bool isTouch() const override {
|
||||
return m_touch;
|
||||
}
|
||||
bool isTabletTool() const {
|
||||
bool isTabletTool() const override {
|
||||
return m_tabletTool;
|
||||
}
|
||||
bool isTabletPad() const {
|
||||
bool isTabletPad() const override {
|
||||
return m_tabletPad;
|
||||
}
|
||||
bool supportsGesture() const {
|
||||
return m_supportsGesture;
|
||||
}
|
||||
QString name() const {
|
||||
QString name() const override {
|
||||
return m_name;
|
||||
}
|
||||
QString sysName() const {
|
||||
QString sysName() const override {
|
||||
return m_sysName;
|
||||
}
|
||||
QString outputName() const {
|
||||
|
@ -424,10 +425,10 @@ public:
|
|||
return (quint32) m_defaultClickMethod;
|
||||
}
|
||||
|
||||
bool isEnabled() const {
|
||||
bool isEnabled() const override {
|
||||
return m_enabled;
|
||||
}
|
||||
void setEnabled(bool enabled);
|
||||
void setEnabled(bool enabled) override;
|
||||
|
||||
libinput_device *device() const {
|
||||
return m_device;
|
||||
|
@ -452,11 +453,11 @@ public:
|
|||
return m_switch;
|
||||
}
|
||||
|
||||
bool isLidSwitch() const {
|
||||
bool isLidSwitch() const override {
|
||||
return m_lidSwitch;
|
||||
}
|
||||
|
||||
bool isTabletModeSwitch() const {
|
||||
bool isTabletModeSwitch() const override {
|
||||
return m_tabletSwitch;
|
||||
}
|
||||
|
||||
|
@ -468,6 +469,9 @@ public:
|
|||
AbstractOutput *output() const;
|
||||
void setOutput(AbstractOutput *output);
|
||||
|
||||
LEDs leds() const override;
|
||||
void setLeds(LEDs leds) override;
|
||||
|
||||
/**
|
||||
* All created Devices
|
||||
*/
|
||||
|
@ -569,6 +573,7 @@ private:
|
|||
enum libinput_config_click_method m_defaultClickMethod;
|
||||
enum libinput_config_click_method m_clickMethod;
|
||||
|
||||
LEDs m_leds;
|
||||
static QVector<Device*> s_devices;
|
||||
};
|
||||
|
||||
|
|
51
src/libinput/libinputbackend.cpp
Normal file
51
src/libinput/libinputbackend.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "libinputbackend.h"
|
||||
#include "connection.h"
|
||||
#include "device.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
LibinputBackend::LibinputBackend(QObject *parent)
|
||||
: InputBackend(parent)
|
||||
{
|
||||
m_thread = new QThread();
|
||||
m_thread->setObjectName(QStringLiteral("libinput-connection"));
|
||||
m_thread->start();
|
||||
|
||||
m_connection = LibInput::Connection::create(this);
|
||||
m_connection->moveToThread(m_thread);
|
||||
|
||||
connect(m_connection, &LibInput::Connection::eventsRead, this, [this]() {
|
||||
m_connection->processEvents();
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
// Direct connection because the deviceAdded() and the deviceRemoved() signals are emitted
|
||||
// from the main thread.
|
||||
connect(m_connection, &LibInput::Connection::deviceAdded,
|
||||
this, &InputBackend::deviceAdded, Qt::DirectConnection);
|
||||
connect(m_connection, &LibInput::Connection::deviceRemoved,
|
||||
this, &InputBackend::deviceRemoved, Qt::DirectConnection);
|
||||
}
|
||||
|
||||
LibinputBackend::~LibinputBackend()
|
||||
{
|
||||
m_connection->deleteLater();
|
||||
|
||||
m_thread->quit();
|
||||
m_thread->wait();
|
||||
delete m_thread;
|
||||
}
|
||||
|
||||
void LibinputBackend::initialize()
|
||||
{
|
||||
m_connection->setInputConfig(config());
|
||||
m_connection->setup();
|
||||
}
|
||||
|
||||
} // namespace KWin
|
36
src/libinput/libinputbackend.h
Normal file
36
src/libinput/libinputbackend.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "inputbackend.h"
|
||||
|
||||
#include <QThread>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
namespace LibInput
|
||||
{
|
||||
class Connection;
|
||||
}
|
||||
|
||||
class KWIN_EXPORT LibinputBackend : public InputBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LibinputBackend(QObject *parent = nullptr);
|
||||
~LibinputBackend() override;
|
||||
|
||||
void initialize() override;
|
||||
|
||||
private:
|
||||
QThread *m_thread = nullptr;
|
||||
LibInput::Connection *m_connection = nullptr;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
23
src/main.cpp
23
src/main.cpp
|
@ -579,18 +579,6 @@ bool XcbEventFilter::nativeEventFilter(const QByteArray &eventType, void *messag
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool s_useLibinput = false;
|
||||
|
||||
void Application::setUseLibinput(bool use)
|
||||
{
|
||||
s_useLibinput = use;
|
||||
}
|
||||
|
||||
bool Application::usesLibinput()
|
||||
{
|
||||
return s_useLibinput;
|
||||
}
|
||||
|
||||
QProcessEnvironment Application::processStartupEnvironment() const
|
||||
{
|
||||
return QProcessEnvironment::systemEnvironment();
|
||||
|
@ -603,17 +591,6 @@ void Application::initPlatform(const KPluginMetaData &plugin)
|
|||
m_platform = qobject_cast<Platform *>(loader.instance());
|
||||
if (m_platform) {
|
||||
m_platform->setParent(this);
|
||||
// check whether it needs libinput
|
||||
const QJsonObject &metaData = plugin.rawData();
|
||||
auto it = metaData.find(QStringLiteral("input"));
|
||||
if (it != metaData.end()) {
|
||||
if ((*it).isBool()) {
|
||||
if (!(*it).toBool()) {
|
||||
qCDebug(KWIN_CORE) << "Platform does not support input, enforcing libinput support";
|
||||
setUseLibinput(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Q_EMIT platformCreated();
|
||||
} else {
|
||||
qCWarning(KWIN_CORE) << "Could not create plugin" << plugin.name() << "error:" << loader.errorString();
|
||||
|
|
|
@ -207,9 +207,6 @@ public:
|
|||
static void setupMalloc();
|
||||
static void setupLocalizedString();
|
||||
|
||||
static bool usesLibinput();
|
||||
static void setUseLibinput(bool use);
|
||||
|
||||
Q_SIGNALS:
|
||||
void x11ConnectionChanged();
|
||||
void x11ConnectionAboutToBeDestroyed();
|
||||
|
|
|
@ -509,9 +509,6 @@ int main(int argc, char * argv[])
|
|||
if (hasOutputCountOption) {
|
||||
parser.addOption(outputCountOption);
|
||||
}
|
||||
QCommandLineOption libinputOption(QStringLiteral("libinput"),
|
||||
i18n("Enable libinput support for input events processing. Note: never use in a nested session. (deprecated)"));
|
||||
parser.addOption(libinputOption);
|
||||
QCommandLineOption drmOption(QStringLiteral("drm"), i18n("Render through drm node."));
|
||||
if (hasDrmOption) {
|
||||
parser.addOption(drmOption);
|
||||
|
@ -579,8 +576,6 @@ int main(int argc, char * argv[])
|
|||
a.setSessionArgument(parser.value(exitWithSessionOption));
|
||||
}
|
||||
|
||||
KWin::Application::setUseLibinput(parser.isSet(libinputOption));
|
||||
|
||||
QString pluginName;
|
||||
QSize initialWindowSize;
|
||||
QByteArray deviceIdentifier;
|
||||
|
|
|
@ -76,6 +76,11 @@ void Platform::doShowCursor()
|
|||
{
|
||||
}
|
||||
|
||||
InputBackend *Platform::createInputBackend()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OpenGLBackend *Platform::createOpenGLBackend()
|
||||
{
|
||||
return nullptr;
|
||||
|
|
|
@ -31,6 +31,7 @@ class AbstractOutput;
|
|||
class Edge;
|
||||
class Compositor;
|
||||
class DmaBufTexture;
|
||||
class InputBackend;
|
||||
class OverlayWindow;
|
||||
class OpenGLBackend;
|
||||
class Outline;
|
||||
|
@ -61,6 +62,7 @@ public:
|
|||
|
||||
virtual Session *session() const = 0;
|
||||
virtual bool initialize() = 0;
|
||||
virtual InputBackend *createInputBackend();
|
||||
virtual OpenGLBackend *createOpenGLBackend();
|
||||
virtual QPainterBackend *createQPainterBackend();
|
||||
virtual DmaBufTexture *createDmaBufTexture(const QSize &size) {
|
||||
|
|
|
@ -86,6 +86,5 @@
|
|||
"Name[x-test]": "xxdrmxx",
|
||||
"Name[zh_CN]": "drm",
|
||||
"Name[zh_TW]": "drm"
|
||||
},
|
||||
"input": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
#include "drm_object_plane.h"
|
||||
#include "composite.h"
|
||||
#include "cursor.h"
|
||||
#include "libinput/libinputbackend.h"
|
||||
#include "logging.h"
|
||||
#include "main.h"
|
||||
#include "renderloop.h"
|
||||
#include "scene_qpainter_drm_backend.h"
|
||||
#include "session.h"
|
||||
#include "udev.h"
|
||||
#include "wayland_server.h"
|
||||
#include "drm_gpu.h"
|
||||
#include "egl_multi_backend.h"
|
||||
#include "drm_pipeline.h"
|
||||
|
@ -33,8 +33,6 @@
|
|||
#if HAVE_EGL_STREAMS
|
||||
#include "egl_stream_backend.h"
|
||||
#endif
|
||||
// KWayland
|
||||
#include <KWaylandServer/seat_interface.h>
|
||||
// KF5
|
||||
#include <KCoreAddons>
|
||||
#include <KLocalizedString>
|
||||
|
@ -69,6 +67,7 @@ DrmBackend::DrmBackend(QObject *parent)
|
|||
, m_explicitGpus(qEnvironmentVariable("KWIN_DRM_DEVICES").split(':', Qt::SkipEmptyParts))
|
||||
, m_dpmsFilter()
|
||||
{
|
||||
setSupportsPointerWarping(true);
|
||||
setSupportsGammaControl(true);
|
||||
setPerScreenRenderingEnabled(true);
|
||||
supportsOutputChanges();
|
||||
|
@ -528,21 +527,6 @@ void DrmBackend::initCursor()
|
|||
setSoftwareCursorForced(needsSoftwareCursor);
|
||||
#endif
|
||||
|
||||
if (waylandServer()->seat()->hasPointer()) {
|
||||
// The cursor is visible by default, do nothing.
|
||||
} else {
|
||||
hideCursor();
|
||||
}
|
||||
|
||||
connect(waylandServer()->seat(), &KWaylandServer::SeatInterface::hasPointerChanged, this,
|
||||
[this] {
|
||||
if (waylandServer()->seat()->hasPointer()) {
|
||||
showCursor();
|
||||
} else {
|
||||
hideCursor();
|
||||
}
|
||||
}
|
||||
);
|
||||
// now we have screens and can set cursors, so start tracking
|
||||
connect(Cursors::self(), &Cursors::currentCursorChanged, this, &DrmBackend::updateCursor);
|
||||
connect(Cursors::self(), &Cursors::positionChanged, this, &DrmBackend::moveCursor);
|
||||
|
@ -621,6 +605,11 @@ void DrmBackend::moveCursor()
|
|||
}
|
||||
}
|
||||
|
||||
InputBackend *DrmBackend::createInputBackend()
|
||||
{
|
||||
return new LibinputBackend();
|
||||
}
|
||||
|
||||
QPainterBackend *DrmBackend::createQPainterBackend()
|
||||
{
|
||||
return new DrmQPainterBackend(this, m_gpus.at(0));
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
explicit DrmBackend(QObject *parent = nullptr);
|
||||
~DrmBackend() override;
|
||||
|
||||
InputBackend *createInputBackend() override;
|
||||
QPainterBackend *createQPainterBackend() override;
|
||||
OpenGLBackend* createOpenGLBackend() override;
|
||||
DmaBufTexture *createDmaBufTexture(const QSize &size) override;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "fb_backend.h"
|
||||
|
||||
#include "composite.h"
|
||||
#include "libinput/libinputbackend.h"
|
||||
#include "logging.h"
|
||||
#include "main.h"
|
||||
#include "platform.h"
|
||||
|
@ -79,6 +80,7 @@ FramebufferBackend::FramebufferBackend(QObject *parent)
|
|||
, m_session(Session::create(this))
|
||||
{
|
||||
setPerScreenRenderingEnabled(true);
|
||||
setSupportsPointerWarping(true);
|
||||
}
|
||||
|
||||
FramebufferBackend::~FramebufferBackend()
|
||||
|
@ -89,6 +91,11 @@ FramebufferBackend::~FramebufferBackend()
|
|||
}
|
||||
}
|
||||
|
||||
InputBackend *FramebufferBackend::createInputBackend()
|
||||
{
|
||||
return new LibinputBackend(this);
|
||||
}
|
||||
|
||||
QPainterBackend *FramebufferBackend::createQPainterBackend()
|
||||
{
|
||||
return new FramebufferQPainterBackend(this);
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
explicit FramebufferBackend(QObject *parent = nullptr);
|
||||
~FramebufferBackend() override;
|
||||
|
||||
InputBackend *createInputBackend() override;
|
||||
QPainterBackend *createQPainterBackend() override;
|
||||
|
||||
QSize screenSize() const override;
|
||||
|
|
|
@ -86,6 +86,5 @@
|
|||
"Name[x-test]": "xxframebufferxx",
|
||||
"Name[zh_CN]": "framebuffer",
|
||||
"Name[zh_TW]": "framebuffer"
|
||||
},
|
||||
"input": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,6 +86,5 @@
|
|||
"Name[x-test]": "xxvirtualxx",
|
||||
"Name[zh_CN]": "virtual",
|
||||
"Name[zh_TW]": "虛擬"
|
||||
},
|
||||
"input": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,6 +84,5 @@
|
|||
"Name[x-test]": "xxwaylandxx",
|
||||
"Name[zh_CN]": "wayland",
|
||||
"Name[zh_TW]": "wayland"
|
||||
},
|
||||
"input": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -515,9 +515,6 @@ bool WaylandBackend::initialize()
|
|||
);
|
||||
connect(m_registry, &Registry::seatAnnounced, this,
|
||||
[this](quint32 name) {
|
||||
if (Application::usesLibinput()) {
|
||||
return;
|
||||
}
|
||||
m_seat = new WaylandSeat(m_registry->bindSeat(name, 2), this);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -83,6 +83,5 @@
|
|||
"Name[x-test]": "xxx11-standalonexx",
|
||||
"Name[zh_CN]": "x11-standalone",
|
||||
"Name[zh_TW]": "x11-standalone"
|
||||
},
|
||||
"input": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,6 +84,5 @@
|
|||
"Name[x-test]": "xxx11xx",
|
||||
"Name[zh_CN]": "x11",
|
||||
"Name[zh_TW]": "x11"
|
||||
},
|
||||
"input": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,6 @@ static QPointF confineToBoundingBox(const QPointF &pos, const QRectF &boundingBo
|
|||
PointerInputRedirection::PointerInputRedirection(InputRedirection* parent)
|
||||
: InputDeviceHandler(parent)
|
||||
, m_cursor(nullptr)
|
||||
, m_supportsWarping(Application::usesLibinput())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -113,10 +112,25 @@ PointerInputRedirection::~PointerInputRedirection() = default;
|
|||
void PointerInputRedirection::init()
|
||||
{
|
||||
Q_ASSERT(!inited());
|
||||
waylandServer()->seat()->setHasPointer(input()->hasPointer());
|
||||
connect(input(), &InputRedirection::hasPointerChanged,
|
||||
waylandServer()->seat(), &KWaylandServer::SeatInterface::setHasPointer);
|
||||
|
||||
m_cursor = new CursorImage(this);
|
||||
setInited(true);
|
||||
InputDeviceHandler::init();
|
||||
|
||||
if (!input()->hasPointer()) {
|
||||
kwinApp()->platform()->hideCursor();
|
||||
}
|
||||
connect(input(), &InputRedirection::hasPointerChanged, this, [this]() {
|
||||
if (input()->hasPointer()) {
|
||||
kwinApp()->platform()->showCursor();
|
||||
} else {
|
||||
kwinApp()->platform()->hideCursor();
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_cursor, &CursorImage::changed, Cursors::self()->mouse(), [this] {
|
||||
auto cursor = Cursors::self()->mouse();
|
||||
cursor->updateCursor(m_cursor->image(), m_cursor->hotSpot());
|
||||
|
@ -242,17 +256,17 @@ private:
|
|||
int PositionUpdateBlocker::s_counter = 0;
|
||||
QVector<PositionUpdateBlocker::ScheduledPosition> PositionUpdateBlocker::s_scheduledPositions;
|
||||
|
||||
void PointerInputRedirection::processMotionAbsolute(const QPointF &pos, uint32_t time, LibInput::Device *device)
|
||||
void PointerInputRedirection::processMotionAbsolute(const QPointF &pos, uint32_t time, InputDevice *device)
|
||||
{
|
||||
processMotionInternal(pos, QSizeF(), QSizeF(), time, 0, device);
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, LibInput::Device *device)
|
||||
void PointerInputRedirection::processMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, InputDevice *device)
|
||||
{
|
||||
processMotionInternal(m_pos + QPointF(delta.width(), delta.height()), delta, deltaNonAccelerated, time, timeUsec, device);
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processMotionInternal(const QPointF &pos, const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, LibInput::Device *device)
|
||||
void PointerInputRedirection::processMotionInternal(const QPointF &pos, const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
if (!inited()) {
|
||||
|
@ -275,7 +289,7 @@ void PointerInputRedirection::processMotionInternal(const QPointF &pos, const QS
|
|||
input()->processFilters(std::bind(&InputEventFilter::pointerEvent, std::placeholders::_1, &event, 0));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processButton(uint32_t button, InputRedirection::PointerButtonState state, uint32_t time, LibInput::Device *device)
|
||||
void PointerInputRedirection::processButton(uint32_t button, InputRedirection::PointerButtonState state, uint32_t time, InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
QEvent::Type type;
|
||||
|
@ -313,7 +327,7 @@ void PointerInputRedirection::processButton(uint32_t button, InputRedirection::P
|
|||
}
|
||||
|
||||
void PointerInputRedirection::processAxis(InputRedirection::PointerAxis axis, qreal delta, qint32 discreteDelta,
|
||||
InputRedirection::PointerAxisSource source, uint32_t time, LibInput::Device *device)
|
||||
InputRedirection::PointerAxisSource source, uint32_t time, InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
update();
|
||||
|
@ -333,7 +347,7 @@ void PointerInputRedirection::processAxis(InputRedirection::PointerAxis axis, qr
|
|||
input()->processFilters(std::bind(&InputEventFilter::wheelEvent, std::placeholders::_1, &wheelEvent));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processSwipeGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processSwipeGestureBegin(int fingerCount, quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
Q_UNUSED(device)
|
||||
|
@ -345,7 +359,7 @@ void PointerInputRedirection::processSwipeGestureBegin(int fingerCount, quint32
|
|||
input()->processFilters(std::bind(&InputEventFilter::swipeGestureBegin, std::placeholders::_1, fingerCount, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processSwipeGestureUpdate(const QSizeF &delta, quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processSwipeGestureUpdate(const QSizeF &delta, quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
Q_UNUSED(device)
|
||||
|
@ -358,7 +372,7 @@ void PointerInputRedirection::processSwipeGestureUpdate(const QSizeF &delta, qui
|
|||
input()->processFilters(std::bind(&InputEventFilter::swipeGestureUpdate, std::placeholders::_1, delta, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processSwipeGestureEnd(quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processSwipeGestureEnd(quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
Q_UNUSED(device)
|
||||
|
@ -371,7 +385,7 @@ void PointerInputRedirection::processSwipeGestureEnd(quint32 time, KWin::LibInpu
|
|||
input()->processFilters(std::bind(&InputEventFilter::swipeGestureEnd, std::placeholders::_1, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processSwipeGestureCancelled(quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processSwipeGestureCancelled(quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
Q_UNUSED(device)
|
||||
|
@ -384,7 +398,7 @@ void PointerInputRedirection::processSwipeGestureCancelled(quint32 time, KWin::L
|
|||
input()->processFilters(std::bind(&InputEventFilter::swipeGestureCancelled, std::placeholders::_1, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processPinchGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processPinchGestureBegin(int fingerCount, quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
Q_UNUSED(device)
|
||||
|
@ -397,7 +411,7 @@ void PointerInputRedirection::processPinchGestureBegin(int fingerCount, quint32
|
|||
input()->processFilters(std::bind(&InputEventFilter::pinchGestureBegin, std::placeholders::_1, fingerCount, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processPinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processPinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
Q_UNUSED(device)
|
||||
|
@ -410,7 +424,7 @@ void PointerInputRedirection::processPinchGestureUpdate(qreal scale, qreal angle
|
|||
input()->processFilters(std::bind(&InputEventFilter::pinchGestureUpdate, std::placeholders::_1, scale, angleDelta, delta, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processPinchGestureEnd(quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processPinchGestureEnd(quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
Q_UNUSED(device)
|
||||
|
@ -423,7 +437,7 @@ void PointerInputRedirection::processPinchGestureEnd(quint32 time, KWin::LibInpu
|
|||
input()->processFilters(std::bind(&InputEventFilter::pinchGestureEnd, std::placeholders::_1, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processPinchGestureCancelled(quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processPinchGestureCancelled(quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
m_lastEventTime = time;
|
||||
Q_UNUSED(device)
|
||||
|
@ -436,7 +450,7 @@ void PointerInputRedirection::processPinchGestureCancelled(quint32 time, KWin::L
|
|||
input()->processFilters(std::bind(&InputEventFilter::pinchGestureCancelled, std::placeholders::_1, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processHoldGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processHoldGestureBegin(int fingerCount, quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!inited()) {
|
||||
|
@ -448,7 +462,7 @@ void PointerInputRedirection::processHoldGestureBegin(int fingerCount, quint32 t
|
|||
input()->processFilters(std::bind(&InputEventFilter::holdGestureBegin, std::placeholders::_1, fingerCount, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processHoldGestureEnd(quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processHoldGestureEnd(quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!inited()) {
|
||||
|
@ -460,7 +474,7 @@ void PointerInputRedirection::processHoldGestureEnd(quint32 time, KWin::LibInput
|
|||
input()->processFilters(std::bind(&InputEventFilter::holdGestureEnd, std::placeholders::_1, time));
|
||||
}
|
||||
|
||||
void PointerInputRedirection::processHoldGestureCancelled(quint32 time, KWin::LibInput::Device *device)
|
||||
void PointerInputRedirection::processHoldGestureCancelled(quint32 time, KWin::InputDevice *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!inited()) {
|
||||
|
@ -946,13 +960,7 @@ bool PointerInputRedirection::supportsWarping() const
|
|||
if (!inited()) {
|
||||
return false;
|
||||
}
|
||||
if (m_supportsWarping) {
|
||||
return true;
|
||||
}
|
||||
if (kwinApp()->platform()->supportsPointerWarping()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return kwinApp()->platform()->supportsPointerWarping();
|
||||
}
|
||||
|
||||
void PointerInputRedirection::updateAfterScreenChange()
|
||||
|
|
|
@ -30,6 +30,7 @@ class SurfaceInterface;
|
|||
namespace KWin
|
||||
{
|
||||
class CursorImage;
|
||||
class InputDevice;
|
||||
class InputRedirection;
|
||||
class Toplevel;
|
||||
class CursorShape;
|
||||
|
@ -39,11 +40,6 @@ namespace Decoration
|
|||
class DecoratedClientImpl;
|
||||
}
|
||||
|
||||
namespace LibInput
|
||||
{
|
||||
class Device;
|
||||
}
|
||||
|
||||
uint32_t qtMouseButtonToButton(Qt::MouseButton button);
|
||||
|
||||
class KWIN_EXPORT PointerInputRedirection : public InputDeviceHandler
|
||||
|
@ -86,66 +82,66 @@ public:
|
|||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processMotionAbsolute(const QPointF &pos, uint32_t time, LibInput::Device *device = nullptr);
|
||||
void processMotionAbsolute(const QPointF &pos, uint32_t time, InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, LibInput::Device *device);
|
||||
void processMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, InputDevice *device);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processButton(uint32_t button, InputRedirection::PointerButtonState state, uint32_t time, LibInput::Device *device = nullptr);
|
||||
void processButton(uint32_t button, InputRedirection::PointerButtonState state, uint32_t time, InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processAxis(InputRedirection::PointerAxis axis, qreal delta, qint32 discreteDelta, InputRedirection::PointerAxisSource source, uint32_t time, LibInput::Device *device = nullptr);
|
||||
void processAxis(InputRedirection::PointerAxis axis, qreal delta, qint32 discreteDelta, InputRedirection::PointerAxisSource source, uint32_t time, InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processSwipeGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processSwipeGestureBegin(int fingerCount, quint32 time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processSwipeGestureUpdate(const QSizeF &delta, quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processSwipeGestureUpdate(const QSizeF &delta, quint32 time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processSwipeGestureEnd(quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processSwipeGestureEnd(quint32 time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processSwipeGestureCancelled(quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processSwipeGestureCancelled(quint32 time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processPinchGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processPinchGestureBegin(int fingerCount, quint32 time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processPinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processPinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processPinchGestureEnd(quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processPinchGestureEnd(quint32 time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processPinchGestureCancelled(quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processPinchGestureCancelled(quint32 time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processHoldGestureBegin(int fingerCount, quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processHoldGestureBegin(int fingerCount, quint32 time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processHoldGestureEnd(quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processHoldGestureEnd(quint32 time, KWin::InputDevice *device = nullptr);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void processHoldGestureCancelled(quint32 time, KWin::LibInput::Device *device = nullptr);
|
||||
void processHoldGestureCancelled(quint32 time, KWin::InputDevice *device = nullptr);
|
||||
|
||||
private:
|
||||
void processMotionInternal(const QPointF &pos, const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, LibInput::Device *device);
|
||||
void processMotionInternal(const QPointF &pos, const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, InputDevice *device);
|
||||
void cleanupInternalWindow(QWindow *old, QWindow *now) override;
|
||||
void cleanupDecoration(Decoration::DecoratedClientImpl *old, Decoration::DecoratedClientImpl *now) override;
|
||||
|
||||
|
@ -164,7 +160,6 @@ private:
|
|||
void disconnectPointerConstraintsConnection();
|
||||
void breakPointerConstraints(KWaylandServer::SurfaceInterface *surface);
|
||||
CursorImage *m_cursor;
|
||||
bool m_supportsWarping;
|
||||
QPointF m_pos;
|
||||
QHash<uint32_t, InputRedirection::PointerButtonState> m_buttons;
|
||||
Qt::MouseButtons m_qtButtons;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "decorations/decoratedclient.h"
|
||||
#include "input_event.h"
|
||||
#include "input_event_spy.h"
|
||||
#include "libinput/device.h"
|
||||
#include "pointer_input.h"
|
||||
#include "toplevel.h"
|
||||
#include "wayland_server.h"
|
||||
|
|
|
@ -7,13 +7,10 @@
|
|||
|
||||
#include "tabletmodemanager.h"
|
||||
#include "input.h"
|
||||
#include "inputdevice.h"
|
||||
#include "input_event.h"
|
||||
#include "input_event_spy.h"
|
||||
|
||||
#include "libinput/device.h"
|
||||
#include "libinput/connection.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QDBusConnection>
|
||||
|
||||
namespace KWin
|
||||
|
@ -60,31 +57,26 @@ public:
|
|||
: QObject(parent)
|
||||
, m_parent(parent)
|
||||
{
|
||||
auto c = LibInput::Connection::self();
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
connect(c, &LibInput::Connection::deviceAdded, this, &TabletModeTouchpadRemovedSpy::refresh);
|
||||
connect(c, &LibInput::Connection::deviceRemoved, this, &TabletModeTouchpadRemovedSpy::refresh);
|
||||
connect(input(), &InputRedirection::deviceAdded, this, &TabletModeTouchpadRemovedSpy::refresh);
|
||||
connect(input(), &InputRedirection::deviceRemoved, this, &TabletModeTouchpadRemovedSpy::refresh);
|
||||
|
||||
check();
|
||||
}
|
||||
|
||||
void refresh(LibInput::Device* d) {
|
||||
if (!d->isTouch() && !d->isPointer())
|
||||
return;
|
||||
check();
|
||||
void refresh(InputDevice *inputDevice)
|
||||
{
|
||||
if (inputDevice->isTouch() || inputDevice->isPointer()) {
|
||||
check();
|
||||
}
|
||||
}
|
||||
|
||||
void check() {
|
||||
if (!LibInput::Connection::self()) {
|
||||
return;
|
||||
}
|
||||
const auto devices = LibInput::Connection::self()->devices();
|
||||
const bool hasTouch = std::any_of(devices.constBegin(), devices.constEnd(), [](LibInput::Device* device){ return device->isTouch(); });
|
||||
void check()
|
||||
{
|
||||
const auto devices = input()->devices();
|
||||
const bool hasTouch = std::any_of(devices.constBegin(), devices.constEnd(), [](InputDevice *device) { return device->isTouch(); });
|
||||
m_parent->setTabletModeAvailable(hasTouch);
|
||||
|
||||
const bool hasPointer = std::any_of(devices.constBegin(), devices.constEnd(), [](LibInput::Device* device){ return device->isPointer(); });
|
||||
const bool hasPointer = std::any_of(devices.constBegin(), devices.constEnd(), [](InputDevice *device) { return device->isPointer(); });
|
||||
m_parent->setIsTablet(hasTouch && !hasPointer);
|
||||
}
|
||||
|
||||
|
@ -116,17 +108,12 @@ void KWin::TabletModeManager::hasTabletModeInputChanged(bool set)
|
|||
input()->installInputEventSpy(new TabletModeSwitchEventSpy(this));
|
||||
setTabletModeAvailable(true);
|
||||
} else {
|
||||
auto setupDetector = [this] {
|
||||
auto spy = new TabletModeTouchpadRemovedSpy(this);
|
||||
connect(input(), &InputRedirection::hasTabletModeSwitchChanged, spy, [spy](bool set){
|
||||
if (set)
|
||||
spy->deleteLater();
|
||||
});
|
||||
};
|
||||
if (LibInput::Connection::self())
|
||||
setupDetector();
|
||||
else
|
||||
QTimer::singleShot(2000, this, setupDetector);
|
||||
auto spy = new TabletModeTouchpadRemovedSpy(this);
|
||||
connect(input(), &InputRedirection::hasTabletModeSwitchChanged, spy, [spy](bool set) {
|
||||
if (set) {
|
||||
spy->deleteLater();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,10 @@ TouchInputRedirection::~TouchInputRedirection() = default;
|
|||
void TouchInputRedirection::init()
|
||||
{
|
||||
Q_ASSERT(!inited());
|
||||
waylandServer()->seat()->setHasTouch(input()->hasTouch());
|
||||
connect(input(), &InputRedirection::hasTouchChanged,
|
||||
waylandServer()->seat(), &KWaylandServer::SeatInterface::setHasTouch);
|
||||
|
||||
setInited(true);
|
||||
InputDeviceHandler::init();
|
||||
|
||||
|
@ -135,7 +139,7 @@ void TouchInputRedirection::cleanupDecoration(Decoration::DecoratedClientImpl *o
|
|||
// nothing to do
|
||||
}
|
||||
|
||||
void TouchInputRedirection::processDown(qint32 id, const QPointF &pos, quint32 time, LibInput::Device *device)
|
||||
void TouchInputRedirection::processDown(qint32 id, const QPointF &pos, quint32 time, InputDevice *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!inited()) {
|
||||
|
@ -153,7 +157,7 @@ void TouchInputRedirection::processDown(qint32 id, const QPointF &pos, quint32 t
|
|||
m_windowUpdatedInCycle = false;
|
||||
}
|
||||
|
||||
void TouchInputRedirection::processUp(qint32 id, quint32 time, LibInput::Device *device)
|
||||
void TouchInputRedirection::processUp(qint32 id, quint32 time, InputDevice *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!inited()) {
|
||||
|
@ -172,7 +176,7 @@ void TouchInputRedirection::processUp(qint32 id, quint32 time, LibInput::Device
|
|||
}
|
||||
}
|
||||
|
||||
void TouchInputRedirection::processMotion(qint32 id, const QPointF &pos, quint32 time, LibInput::Device *device)
|
||||
void TouchInputRedirection::processMotion(qint32 id, const QPointF &pos, quint32 time, InputDevice *device)
|
||||
{
|
||||
Q_UNUSED(device)
|
||||
if (!inited()) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class InputDevice;
|
||||
class InputRedirection;
|
||||
class Toplevel;
|
||||
|
||||
|
@ -27,11 +28,6 @@ namespace Decoration
|
|||
class DecoratedClientImpl;
|
||||
}
|
||||
|
||||
namespace LibInput
|
||||
{
|
||||
class Device;
|
||||
}
|
||||
|
||||
class TouchInputRedirection : public InputDeviceHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -43,9 +39,9 @@ public:
|
|||
bool focusUpdatesBlocked() override;
|
||||
void init() override;
|
||||
|
||||
void processDown(qint32 id, const QPointF &pos, quint32 time, LibInput::Device *device = nullptr);
|
||||
void processUp(qint32 id, quint32 time, LibInput::Device *device = nullptr);
|
||||
void processMotion(qint32 id, const QPointF &pos, quint32 time, LibInput::Device *device = nullptr);
|
||||
void processDown(qint32 id, const QPointF &pos, quint32 time, InputDevice *device = nullptr);
|
||||
void processUp(qint32 id, quint32 time, InputDevice *device = nullptr);
|
||||
void processMotion(qint32 id, const QPointF &pos, quint32 time, InputDevice *device = nullptr);
|
||||
void cancel();
|
||||
void frame();
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "composite.h"
|
||||
#include "idle_inhibition.h"
|
||||
#include "inputpanelv1integration.h"
|
||||
#include "keyboard_input.h"
|
||||
#include "screens.h"
|
||||
#include "layershellv1integration.h"
|
||||
#include "main.h"
|
||||
|
@ -538,6 +539,10 @@ void WaylandServer::shellClientShown(Toplevel *toplevel)
|
|||
|
||||
void WaylandServer::initWorkspace()
|
||||
{
|
||||
// TODO: Moe the keyboard leds somewhere else.
|
||||
updateKeyState(input()->keyboard()->xkb()->leds());
|
||||
connect(input()->keyboard(), &KeyboardInputRedirection::ledsChanged, this, &WaylandServer::updateKeyState);
|
||||
|
||||
VirtualDesktopManager::self()->setVirtualDesktopManagement(m_virtualDesktopManagement);
|
||||
|
||||
if (m_windowManagement) {
|
||||
|
|
Loading…
Reference in a new issue