From 47c3c2d143967849170c178cdba14728e90bd14f Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Wed, 26 Oct 2022 19:23:45 +0200 Subject: [PATCH] libinput: Support switching the targetted output with a shortcut I was told it's how artists are used to using these tablets so it makes sense to support the workflow. --- src/backends/libinput/device.h | 4 ++-- src/core/inputdevice.h | 9 ++++++++ src/input.cpp | 41 ++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/backends/libinput/device.h b/src/backends/libinput/device.h index 5a7bbfb405..9e27f20c1e 100644 --- a/src/backends/libinput/device.h +++ b/src/backends/libinput/device.h @@ -191,7 +191,7 @@ public: { return m_sysName; } - QString outputName() const + QString outputName() const override { return m_outputName; } @@ -586,7 +586,7 @@ public: /** * Used to deserialize monitor data from KConfig when initializing a device */ - void setOutputName(const QString &uuid); + void setOutputName(const QString &uuid) override; QString defaultOutputName() const { return {}; diff --git a/src/core/inputdevice.h b/src/core/inputdevice.h index a244f9a11a..2677bc1365 100644 --- a/src/core/inputdevice.h +++ b/src/core/inputdevice.h @@ -44,6 +44,15 @@ public: virtual bool isTabletModeSwitch() const = 0; virtual bool isLidSwitch() const = 0; + virtual QString outputName() const + { + return {}; + } + virtual void setOutputName(const QString &outputName) + { + Q_UNUSED(outputName) + } + Q_SIGNALS: void keyChanged(quint32 key, InputRedirection::KeyboardKeyState, quint32 time, InputDevice *device); void pointerButtonChanged(quint32 button, InputRedirection::PointerButtonState state, quint32 time, InputDevice *device); diff --git a/src/input.cpp b/src/input.cpp index 771a4164be..fd286df113 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -71,6 +71,7 @@ #include +#include "osd.h" #include namespace KWin @@ -2060,6 +2061,13 @@ public: } connect(input(), &InputRedirection::deviceAdded, this, &TabletInputFilter::integrateDevice); connect(input(), &InputRedirection::deviceRemoved, this, &TabletInputFilter::removeDevice); + + auto tabletNextOutput = new QAction(this); + tabletNextOutput->setProperty("componentName", QStringLiteral(KWIN_NAME)); + tabletNextOutput->setText(i18n("Move the tablet to the next output")); + tabletNextOutput->setObjectName(QStringLiteral("Move Tablet to Next Output")); + KGlobalAccel::setGlobalShortcut(tabletNextOutput, QList()); + connect(tabletNextOutput, &QAction::triggered, this, &TabletInputFilter::trackNextOutput); } static KWaylandServer::TabletSeatV2Interface *findTabletSeat() @@ -2105,6 +2113,39 @@ public: } } + static void trackNextOutput() + { + const auto outputs = workspace()->outputs(); + if (outputs.isEmpty()) { + return; + } + + int tabletToolCount = 0; + InputDevice *changedDevice = nullptr; + const auto devices = input()->devices(); + for (const auto device : devices) { + if (!device->isTabletTool()) { + continue; + } + + tabletToolCount++; + if (device->outputName().isEmpty()) { + device->setOutputName(outputs.constFirst()->name()); + changedDevice = device; + continue; + } + + auto it = std::find_if(outputs.begin(), outputs.end(), [device](const auto &output) { + return output->name() == device->outputName(); + }); + ++it; + auto nextOutput = it == outputs.end() ? outputs.first() : *it; + device->setOutputName(nextOutput->name()); + changedDevice = device; + } + OSD::show(i18np("Tablet moved to %2", "Tablets switched outputs", tabletToolCount, changedDevice->outputName()), QStringLiteral("input-tablet"), 5000); + } + void removeDevice(InputDevice *inputDevice) { auto device = qobject_cast(inputDevice);