diff --git a/debug_console.cpp b/debug_console.cpp index a3d7e4673d..a90985e912 100644 --- a/debug_console.cpp +++ b/debug_console.cpp @@ -501,53 +501,51 @@ void DebugConsoleFilter::tabletToolEvent(TabletEvent *event) m_textEdit->ensureCursorVisible(); } -void DebugConsoleFilter::tabletToolButtonEvent(const QSet &pressedButtons) +void DebugConsoleFilter::tabletToolButtonEvent(uint button, bool pressed, const TabletToolId &tabletToolId) { - QString buttons; - for (uint b : pressedButtons) { - buttons += QString::number(b) + ' '; - } QString text = s_hr + s_tableStart + tableHeaderRow(i18n("Tablet Tool Button")) - + tableRow(i18n("Pressed Buttons"), buttons) + + tableRow(i18n("Button"), button) + + tableRow(i18n("Pressed"), pressed) + + tableRow(i18n("Tablet"), tabletToolId.m_tabletSysName) + s_tableEnd; m_textEdit->insertHtml(text); m_textEdit->ensureCursorVisible(); } -void DebugConsoleFilter::tabletPadButtonEvent(const QSet &pressedButtons) +void DebugConsoleFilter::tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName) { - QString buttons; - for (uint b : pressedButtons) { - buttons += QString::number(b) + ' '; - } QString text = s_hr + s_tableStart + tableHeaderRow(i18n("Tablet Pad Button")) - + tableRow(i18n("Pressed Buttons"), buttons) + + tableRow(i18n("Button"), button) + + tableRow(i18n("Pressed"), pressed) + + tableRow(i18n("Tablet"), deviceSysName) + s_tableEnd; m_textEdit->insertHtml(text); m_textEdit->ensureCursorVisible(); } -void DebugConsoleFilter::tabletPadStripEvent(int number, int position, bool isFinger) +void DebugConsoleFilter::tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName) { QString text = s_hr + s_tableStart + tableHeaderRow(i18n("Tablet Pad Strip")) + tableRow(i18n("Number"), number) + tableRow(i18n("Position"), position) + tableRow(i18n("isFinger"), isFinger) + + tableRow(i18n("Tablet"), deviceSysName) + s_tableEnd; m_textEdit->insertHtml(text); m_textEdit->ensureCursorVisible(); } -void DebugConsoleFilter::tabletPadRingEvent(int number, int position, bool isFinger) +void DebugConsoleFilter::tabletPadRingEvent(int number, int position, bool isFinger, const QString &deviceSysName) { QString text = s_hr + s_tableStart + tableHeaderRow(i18n("Tablet Pad Ring")) + tableRow(i18n("Number"), number) + tableRow(i18n("Position"), position) + tableRow(i18n("isFinger"), isFinger) + + tableRow(i18n("Tablet"), deviceSysName) + s_tableEnd; m_textEdit->insertHtml(text); diff --git a/debug_console.h b/debug_console.h index a2d9b1df4c..fc02af8a95 100644 --- a/debug_console.h +++ b/debug_console.h @@ -148,10 +148,10 @@ public: void switchEvent(SwitchEvent *event) override; void tabletToolEvent(TabletEvent *event) override; - void tabletToolButtonEvent(const QSet &pressedButtons) override; - void tabletPadButtonEvent(const QSet &pressedButtons) override; - void tabletPadStripEvent(int number, int position, bool isFinger) override; - void tabletPadRingEvent(int number, int position, bool isFinger) override; + void tabletToolButtonEvent(uint button, bool pressed, const TabletToolId &tabletToolId) override; + void tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName) override; + void tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName) override; + void tabletPadRingEvent(int number, int position, bool isFinger, const QString &deviceSysName) override; private: QTextEdit *m_textEdit; diff --git a/input.cpp b/input.cpp index 5fe96cb2c5..f2847ad397 100644 --- a/input.cpp +++ b/input.cpp @@ -175,31 +175,37 @@ bool InputEventFilter::tabletToolEvent(TabletEvent *event) return false; } -bool InputEventFilter::tabletToolButtonEvent(const QSet &pressedButtons) +bool InputEventFilter::tabletToolButtonEvent(uint button, bool pressed, const TabletToolId &tabletId) { - Q_UNUSED(pressedButtons) + Q_UNUSED(button) + Q_UNUSED(pressed) + Q_UNUSED(tabletId) return false; } -bool InputEventFilter::tabletPadButtonEvent(const QSet &pressedButtons) +bool InputEventFilter::tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName) { - Q_UNUSED(pressedButtons) + Q_UNUSED(button) + Q_UNUSED(pressed) + Q_UNUSED(deviceSysName) return false; } -bool InputEventFilter::tabletPadStripEvent(int number, int position, bool isFinger) +bool InputEventFilter::tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName) { Q_UNUSED(number) Q_UNUSED(position) Q_UNUSED(isFinger) + Q_UNUSED(deviceSysName) return false; } -bool InputEventFilter::tabletPadRingEvent(int number, int position, bool isFinger) +bool InputEventFilter::tabletPadRingEvent(int number, int position, bool isFinger, const QString &deviceSysName) { Q_UNUSED(number) Q_UNUSED(position) Q_UNUSED(isFinger) + Q_UNUSED(deviceSysName) return false; } @@ -1575,23 +1581,138 @@ public: if (device->isTabletTool()) { KWaylandServer::TabletSeatV2Interface *tabletSeat = findTabletSeat(); if (!tabletSeat) { - qCCritical(KWIN_CORE) << "Could not find tablet manager"; + qCCritical(KWIN_CORE) << "Could not find tablet seat"; return; } struct udev_device *const udev_device = libinput_device_get_udev_device(device->device()); - const char *devnode = udev_device_get_devnode(udev_device); + const char *devnode = udev_device_get_syspath(udev_device); + tabletSeat->addTablet(device->vendor(), device->product(), device->sysName(), device->name(), {QString::fromUtf8(devnode)}); } + + if (device->isTabletPad()) { + KWaylandServer::TabletSeatV2Interface *tabletSeat = findTabletSeat(); + if (!tabletSeat) { + qCCritical(KWIN_CORE) << "Could not find tablet seat"; + return; + } + struct udev_device *const udev_device = libinput_device_get_udev_device(device->device()); + const char *devnode = udev_device_get_syspath(udev_device); + + const int buttonsCount = libinput_device_tablet_pad_get_num_buttons(device->device()); + const int ringsCount = libinput_device_tablet_pad_get_num_rings(device->device()); + const int stripsCount = libinput_device_tablet_pad_get_num_strips(device->device()); + const int modes = libinput_device_tablet_pad_get_num_mode_groups(device->device()); + + auto firstGroup = libinput_device_tablet_pad_get_mode_group(device->device(), 0); + tabletSeat->addTabletPad(device->sysName(), device->name(), {QString::fromUtf8(devnode)}, buttonsCount, ringsCount, stripsCount, modes, libinput_tablet_pad_mode_group_get_mode(firstGroup)); + } } void removeDevice(const QString &sysname) { KWaylandServer::TabletSeatV2Interface *tabletSeat = findTabletSeat(); if (tabletSeat) - tabletSeat->removeTablet(sysname); + tabletSeat->removeDevice(sysname); else qCCritical(KWIN_CORE) << "Could not find tablet to remove" << sysname; } + KWaylandServer::TabletToolV2Interface *createTool(const KWin::TabletToolId &tabletToolId) + { + using namespace KWaylandServer; + KWaylandServer::TabletSeatV2Interface *tabletSeat = findTabletSeat(); + + const auto f = [](InputRedirection::Capability cap) { + switch (cap) { + case InputRedirection::Tilt: + return TabletToolV2Interface::Tilt; + case InputRedirection::Pressure: + return TabletToolV2Interface::Pressure; + case InputRedirection::Distance: + return TabletToolV2Interface::Distance; + case InputRedirection::Rotation: + return TabletToolV2Interface::Rotation; + case InputRedirection::Slider: + return TabletToolV2Interface::Slider; + case InputRedirection::Wheel: + return TabletToolV2Interface::Wheel; + } + return TabletToolV2Interface::Wheel; + }; + QVector ifaceCapabilities; + ifaceCapabilities.resize(tabletToolId.m_capabilities.size()); + std::transform(tabletToolId.m_capabilities.constBegin(), tabletToolId.m_capabilities.constEnd(), ifaceCapabilities.begin(), f); + + TabletToolV2Interface::Type toolType = TabletToolV2Interface::Type::Pen; + switch (tabletToolId.m_toolType) { + case InputRedirection::Pen: + toolType = TabletToolV2Interface::Type::Pen; + break; + case InputRedirection::Eraser: + toolType = TabletToolV2Interface::Type::Eraser; + break; + case InputRedirection::Brush: + toolType = TabletToolV2Interface::Type::Brush; + break; + case InputRedirection::Pencil: + toolType = TabletToolV2Interface::Type::Pencil; + break; + case InputRedirection::Airbrush: + toolType = TabletToolV2Interface::Type::Airbrush; + break; + case InputRedirection::Finger: + toolType = TabletToolV2Interface::Type::Finger; + break; + case InputRedirection::Mouse: + toolType = TabletToolV2Interface::Type::Mouse; + break; + case InputRedirection::Lens: + toolType = TabletToolV2Interface::Type::Lens; + break; + case InputRedirection::Totem: + toolType = TabletToolV2Interface::Type::Totem; + break; + } + TabletToolV2Interface *tool = tabletSeat->addTool(toolType, tabletToolId.m_serialId, tabletToolId.m_uniqueId, ifaceCapabilities); + + const auto cursor = new Cursor(tool); + Cursors::self()->addCursor(cursor); + m_cursorByTool[tool] = cursor; + + connect(tool, &TabletToolV2Interface::cursorChanged, cursor, &Cursor::cursorChanged); + connect(tool, &TabletToolV2Interface::cursorChanged, cursor, [cursor] (TabletCursorV2 *tcursor) { + static const auto createDefaultCursor = [] { + WaylandCursorImage defaultCursor; + WaylandCursorImage::Image ret; + defaultCursor.loadThemeCursor(CursorShape(Qt::CrossCursor), &ret); + return ret; + }; + static const auto defaultCursor = createDefaultCursor(); + if (!tcursor) { + cursor->updateCursor(defaultCursor.image, defaultCursor.hotspot); + return; + } + auto cursorSurface = tcursor->surface(); + if (!cursorSurface) { + cursor->updateCursor(defaultCursor.image, defaultCursor.hotspot); + return; + } + auto buffer = cursorSurface->buffer(); + if (!buffer) { + cursor->updateCursor(defaultCursor.image, defaultCursor.hotspot); + return; + } + + QImage cursorImage; + cursorImage = buffer->data().copy(); + cursorImage.setDevicePixelRatio(cursorSurface->bufferScale()); + + cursor->updateCursor(cursorImage, tcursor->hotspot()); + }); + emit cursor->cursorChanged(); + return tool; + } + bool tabletToolEvent(TabletEvent *event) override { if (!workspace()) { @@ -1603,102 +1724,12 @@ public: qCCritical(KWIN_CORE) << "Could not find tablet manager"; return false; } - auto tool = tabletSeat->toolByHardwareSerial(event->serialId()); + auto tool = tabletSeat->toolByHardwareSerial(event->tabletId().m_serialId); if (!tool) { - using namespace KWaylandServer; - - const QVector capabilities = event->capabilities(); - const auto f = [](InputRedirection::Capability cap) { - switch (cap) { - case InputRedirection::Tilt: - return TabletToolV2Interface::Tilt; - case InputRedirection::Pressure: - return TabletToolV2Interface::Pressure; - case InputRedirection::Distance: - return TabletToolV2Interface::Distance; - case InputRedirection::Rotation: - return TabletToolV2Interface::Rotation; - case InputRedirection::Slider: - return TabletToolV2Interface::Slider; - case InputRedirection::Wheel: - return TabletToolV2Interface::Wheel; - } - return TabletToolV2Interface::Wheel; - }; - QVector ifaceCapabilities; - ifaceCapabilities.resize(capabilities.size()); - std::transform(capabilities.constBegin(), capabilities.constEnd(), ifaceCapabilities.begin(), f); - - TabletToolV2Interface::Type toolType = TabletToolV2Interface::Type::Pen; - switch (event->toolType()) { - case InputRedirection::Pen: - toolType = TabletToolV2Interface::Type::Pen; - break; - case InputRedirection::Eraser: - toolType = TabletToolV2Interface::Type::Eraser; - break; - case InputRedirection::Brush: - toolType = TabletToolV2Interface::Type::Brush; - break; - case InputRedirection::Pencil: - toolType = TabletToolV2Interface::Type::Pencil; - break; - case InputRedirection::Airbrush: - toolType = TabletToolV2Interface::Type::Airbrush; - break; - case InputRedirection::Finger: - toolType = TabletToolV2Interface::Type::Finger; - break; - case InputRedirection::Mouse: - toolType = TabletToolV2Interface::Type::Mouse; - break; - case InputRedirection::Lens: - toolType = TabletToolV2Interface::Type::Lens; - break; - case InputRedirection::Totem: - toolType = TabletToolV2Interface::Type::Totem; - break; - } - tool = tabletSeat->addTool(toolType, event->serialId(), event->uniqueId(), ifaceCapabilities); - - const auto cursor = new Cursor(tool); - Cursors::self()->addCursor(cursor); - m_cursorByTool[tool] = cursor; - - connect(tool, &TabletToolV2Interface::cursorChanged, cursor, &Cursor::cursorChanged); - connect(tool, &TabletToolV2Interface::cursorChanged, cursor, [cursor] (TabletCursorV2 *tcursor) { - static const auto createDefaultCursor = [] { - WaylandCursorImage defaultCursor; - WaylandCursorImage::Image ret; - defaultCursor.loadThemeCursor(CursorShape(Qt::CrossCursor), &ret); - return ret; - }; - static const auto defaultCursor = createDefaultCursor(); - if (!tcursor) { - cursor->updateCursor(defaultCursor.image, defaultCursor.hotspot); - return; - } - auto cursorSurface = tcursor->surface(); - if (!cursorSurface) { - cursor->updateCursor(defaultCursor.image, defaultCursor.hotspot); - return; - } - auto buffer = cursorSurface->buffer(); - if (!buffer) { - cursor->updateCursor(defaultCursor.image, defaultCursor.hotspot); - return; - } - - QImage cursorImage; - cursorImage = buffer->data().copy(); - cursorImage.setDevicePixelRatio(cursorSurface->bufferScale()); - - cursor->updateCursor(cursorImage, tcursor->hotspot()); - }); - emit cursor->cursorChanged(); + tool = createTool(event->tabletId()); } - KWaylandServer::TabletV2Interface *tablet = tabletSeat->tabletByName(event->tabletSysName()); + KWaylandServer::TabletV2Interface *tablet = tabletSeat->tabletByName(event->tabletId().m_tabletSysName); Toplevel *toplevel = input()->findToplevel(event->globalPos()); if (!toplevel || !toplevel->surface()) { @@ -1773,6 +1804,74 @@ public: waylandServer()->simulateUserActivity(); return true; } + + bool tabletToolButtonEvent(uint button, bool pressed, const TabletToolId &tabletToolId) override + { + KWaylandServer::TabletSeatV2Interface *tabletSeat = findTabletSeat(); + auto tool = tabletSeat->toolByHardwareSerial(tabletToolId.m_serialId); + if (!tool) { + tool = createTool(tabletToolId); + } + tool->sendButton(button, pressed); + return true; + } + + KWaylandServer::TabletPadV2Interface *findPad(const QString &deviceSysName) const + { + Toplevel *toplevel = workspace()->activeClient(); + auto seat = findTabletSeat(); + if (!toplevel || !toplevel->surface() || !seat->isClientSupported(toplevel->surface()->client())) { + return nullptr; + } + + KWaylandServer::SurfaceInterface *surface = toplevel->surface(); + auto pad = seat->padByName(deviceSysName); + pad->setCurrentSurface(surface); + return pad; + } + + bool tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName) override + { + auto pad = findPad(deviceSysName); + if (!pad) { + return false; + } + pad->sendButton(QDateTime::currentMSecsSinceEpoch(), button, pressed); + return true; + } + + bool tabletPadRingEvent(int number, int angle, bool isFinger, const QString &deviceSysName) override + { + auto pad = findPad(deviceSysName); + if (!pad) { + return false; + } + auto ring = pad->ring(number); + + ring->sendAngle(angle); + if (isFinger) { + ring->sendSource(KWaylandServer::TabletPadRingV2Interface::SourceFinger); + } + ring->sendFrame(QDateTime::currentMSecsSinceEpoch()); + return true; + } + + bool tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName) override + { + auto pad = findPad(deviceSysName); + if (!pad) { + return false; + } + auto strip = pad->strip(number); + + strip->sendPosition(position); + if (isFinger) { + strip->sendSource(KWaylandServer::TabletPadStripV2Interface::SourceFinger); + } + strip->sendFrame(QDateTime::currentMSecsSinceEpoch()); + return true; + } + QHash m_cursorByTool; }; diff --git a/input.h b/input.h index 8ab4d859f7..213f73906c 100644 --- a/input.h +++ b/input.h @@ -43,6 +43,7 @@ class WindowSelectorFilter; class SwitchEvent; class TabletEvent; class TabletInputFilter; +class TabletToolId; namespace Decoration { @@ -400,10 +401,10 @@ public: virtual bool switchEvent(SwitchEvent *event); virtual bool tabletToolEvent(TabletEvent *event); - virtual bool tabletToolButtonEvent(const QSet &buttons); - virtual bool tabletPadButtonEvent(const QSet &buttons); - virtual bool tabletPadStripEvent(int number, int position, bool isFinger); - virtual bool tabletPadRingEvent(int number, int position, bool isFinger); + virtual bool tabletToolButtonEvent(uint button, bool pressed, const TabletToolId &tabletToolId); + virtual bool tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName); + virtual bool tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName); + virtual bool tabletPadRingEvent(int number, int position, bool isFinger, const QString &deviceSysName); protected: void passToWaylandServer(QKeyEvent *event); diff --git a/input_event.cpp b/input_event.cpp index e6047a1f18..c1603c66fb 100644 --- a/input_event.cpp +++ b/input_event.cpp @@ -58,12 +58,9 @@ TabletEvent::TabletEvent(Type t, const QPointF &pos, const QPointF &globalPos, int device, int pointerType, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, Qt::KeyboardModifiers keyState, qint64 uniqueID, - Qt::MouseButton button, Qt::MouseButtons buttons, InputRedirection::TabletToolType toolType, const QVector &capabilities, quint64 serialId, const QString &tabletSysName) + Qt::MouseButton button, Qt::MouseButtons buttons, const TabletToolId &tabletId) : QTabletEvent(t, pos, globalPos, device, pointerType, pressure, xTilt, yTilt, tangentialPressure, rotation, z, keyState, uniqueID, button, buttons) - , m_toolType(toolType) - , m_capabilities(capabilities) - , m_serialId(serialId) - , m_tabletSysName(tabletSysName) + , m_id(tabletId) { } diff --git a/input_event.h b/input_event.h index 8261f39a97..e122569a95 100644 --- a/input_event.h +++ b/input_event.h @@ -165,6 +165,16 @@ private: LibInput::Device *m_device; }; +class TabletToolId +{ +public: + const InputRedirection::TabletToolType m_toolType; + const QVector m_capabilities; + const quint64 m_serialId; + const quint64 m_uniqueId; + const QString m_tabletSysName; +}; + class TabletEvent : public QTabletEvent { public: @@ -172,20 +182,14 @@ public: int device, int pointerType, qreal pressure, int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, int z, Qt::KeyboardModifiers keyState, qint64 uniqueID, - Qt::MouseButton button, Qt::MouseButtons buttons, InputRedirection::TabletToolType toolType, - const QVector &capabilities, - quint64 serialId, const QString &tabletSysname); + Qt::MouseButton button, Qt::MouseButtons buttons, const TabletToolId &tabletId); - InputRedirection::TabletToolType toolType() const { return m_toolType; } - QVector capabilities() const { return m_capabilities; } - quint64 serialId() const { return m_serialId; } - QString tabletSysName() { return m_tabletSysName; } + const TabletToolId &tabletId() const { + return m_id; + } private: - const InputRedirection::TabletToolType m_toolType; - const QVector m_capabilities; - const quint64 m_serialId; - const QString m_tabletSysName; + const TabletToolId m_id; }; } diff --git a/input_event_spy.cpp b/input_event_spy.cpp index a143aa754b..6dfb1d0d43 100644 --- a/input_event_spy.cpp +++ b/input_event_spy.cpp @@ -115,27 +115,33 @@ void InputEventSpy::tabletToolEvent(TabletEvent *event) Q_UNUSED(event) } -void InputEventSpy::tabletToolButtonEvent(const QSet &pressedButtons) +void InputEventSpy::tabletToolButtonEvent(uint button, bool pressed, const TabletToolId &tabletToolId) { - Q_UNUSED(pressedButtons) + Q_UNUSED(button) + Q_UNUSED(pressed) + Q_UNUSED(tabletToolId) } -void InputEventSpy::tabletPadButtonEvent(const QSet &pressedButtons) +void InputEventSpy::tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName) { - Q_UNUSED(pressedButtons) + Q_UNUSED(button) + Q_UNUSED(pressed) + Q_UNUSED(deviceSysName) } -void InputEventSpy::tabletPadStripEvent(int number, int position, bool isFinger) +void InputEventSpy::tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName) { Q_UNUSED(number) Q_UNUSED(position) Q_UNUSED(isFinger) + Q_UNUSED(deviceSysName) } -void InputEventSpy::tabletPadRingEvent(int number, int position, bool isFinger) +void InputEventSpy::tabletPadRingEvent(int number, int position, bool isFinger, const QString &deviceSysName) { Q_UNUSED(number) Q_UNUSED(position) Q_UNUSED(isFinger) + Q_UNUSED(deviceSysName) } } diff --git a/input_event_spy.h b/input_event_spy.h index 6015d6bb01..bac6a52df8 100644 --- a/input_event_spy.h +++ b/input_event_spy.h @@ -23,6 +23,7 @@ class MouseEvent; class WheelEvent; class SwitchEvent; class TabletEvent; +class TabletToolId; /** * Base class for spying on input events inside InputRedirection. @@ -75,10 +76,10 @@ public: virtual void switchEvent(SwitchEvent *event); virtual void tabletToolEvent(TabletEvent *event); - virtual void tabletToolButtonEvent(const QSet &pressedButtons); - virtual void tabletPadButtonEvent(const QSet &pressedButtons); - virtual void tabletPadStripEvent(int number, int position, bool isFinger); - virtual void tabletPadRingEvent(int number, int position, bool isFinger); + virtual void tabletToolButtonEvent(uint button, bool pressed, const TabletToolId &tabletToolId); + virtual void tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName); + virtual void tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName); + virtual void tabletPadRingEvent(int number, int position, bool isFinger, const QString &deviceSysName); }; diff --git a/libinput/connection.cpp b/libinput/connection.cpp index d66d3618a1..c86d632737 100644 --- a/libinput/connection.cpp +++ b/libinput/connection.cpp @@ -19,6 +19,7 @@ #include "../screens.h" #endif +#include "../input_event.h" #include "../logind.h" #include "../udev.h" #include "libinput_logging.h" @@ -270,6 +271,62 @@ QPointF devicePointToGlobalPosition(const QPointF &devicePos, const AbstractWayl } #endif +KWin::TabletToolId createTabletId(libinput_tablet_tool *tool, const QString &sysName) +{ + auto serial = libinput_tablet_tool_get_serial(tool); + auto toolId = libinput_tablet_tool_get_tool_id(tool); + auto type = libinput_tablet_tool_get_type(tool); + InputRedirection::TabletToolType toolType; + switch (type) { + case LIBINPUT_TABLET_TOOL_TYPE_PEN: + toolType = InputRedirection::Pen; + break; + case LIBINPUT_TABLET_TOOL_TYPE_ERASER: + toolType = InputRedirection::Eraser; + break; + case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: + toolType = InputRedirection::Brush; + break; + case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: + toolType = InputRedirection::Pencil; + break; + case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: + toolType = InputRedirection::Airbrush; + break; + case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: + toolType = InputRedirection::Mouse; + break; + case LIBINPUT_TABLET_TOOL_TYPE_LENS: + toolType = InputRedirection::Lens; + break; +#ifdef LIBINPUT_HAS_TOTEM + case LIBINPUT_TABLET_TOOL_TYPE_TOTEM: + toolType = InputRedirection::Totem; + break; +#endif + } + QVector capabilities; + if (libinput_tablet_tool_has_pressure(tool)) { + capabilities << InputRedirection::Pressure; + } + if (libinput_tablet_tool_has_distance(tool)) { + capabilities << InputRedirection::Distance; + } + if (libinput_tablet_tool_has_rotation(tool)) { + capabilities << InputRedirection::Rotation; + } + if (libinput_tablet_tool_has_tilt(tool)) { + capabilities << InputRedirection::Tilt; + } + if (libinput_tablet_tool_has_slider(tool)) { + capabilities << InputRedirection::Slider; + } + if (libinput_tablet_tool_has_wheel(tool)) { + capabilities << InputRedirection::Wheel; + } + return {toolType, capabilities, serial, toolId, sysName}; +} + void Connection::processEvents() { QMutexLocker locker(&m_mutex); @@ -515,57 +572,6 @@ void Connection::processEvents() tabletEventType = KWin::InputRedirection::Tip; break; } - auto serial = libinput_tablet_tool_get_serial(tte->tool()); - auto toolId = libinput_tablet_tool_get_tool_id(tte->tool()); - auto type = libinput_tablet_tool_get_type(tte->tool()); - InputRedirection::TabletToolType toolType; - switch (type) { - case LIBINPUT_TABLET_TOOL_TYPE_PEN: - toolType = InputRedirection::Pen; - break; - case LIBINPUT_TABLET_TOOL_TYPE_ERASER: - toolType = InputRedirection::Eraser; - break; - case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: - toolType = InputRedirection::Brush; - break; - case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: - toolType = InputRedirection::Pencil; - break; - case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: - toolType = InputRedirection::Airbrush; - break; - case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: - toolType = InputRedirection::Mouse; - break; - case LIBINPUT_TABLET_TOOL_TYPE_LENS: - toolType = InputRedirection::Lens; - break; -#ifdef LIBINPUT_HAS_TOTEM - case LIBINPUT_TABLET_TOOL_TYPE_TOTEM: - toolType = InputRedirection::Totem; - break; -#endif - } - QVector capabilities; - if (libinput_tablet_tool_has_pressure(tte->tool())) { - capabilities << InputRedirection::Pressure; - } - if (libinput_tablet_tool_has_distance(tte->tool())) { - capabilities << InputRedirection::Distance; - } - if (libinput_tablet_tool_has_rotation(tte->tool())) { - capabilities << InputRedirection::Rotation; - } - if (libinput_tablet_tool_has_tilt(tte->tool())) { - capabilities << InputRedirection::Tilt; - } - if (libinput_tablet_tool_has_slider(tte->tool())) { - capabilities << InputRedirection::Slider; - } - if (libinput_tablet_tool_has_wheel(tte->tool())) { - capabilities << InputRedirection::Wheel; - } #ifndef KWIN_BUILD_TESTING const auto *output = static_cast( @@ -579,29 +585,31 @@ void Connection::processEvents() emit tabletToolEvent(tabletEventType, globalPos, tte->pressure(), tte->xTilt(), tte->yTilt(), tte->rotation(), - tte->isTipDown(), tte->isNearby(), serial, - toolId, toolType, capabilities, tte->time(), - event->device()); + tte->isTipDown(), tte->isNearby(), createTabletId(tte->tool(), event->device()->sysName()), tte->time()); break; } case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: { auto *tabletEvent = static_cast(event.data()); emit tabletToolButtonEvent(tabletEvent->buttonId(), - tabletEvent->isButtonPressed()); + tabletEvent->isButtonPressed(), + createTabletId(tabletEvent->tool(), event->device()->sysName())); break; } case LIBINPUT_EVENT_TABLET_PAD_BUTTON: { auto *tabletEvent = static_cast(event.data()); emit tabletPadButtonEvent(tabletEvent->buttonId(), - tabletEvent->isButtonPressed()); + tabletEvent->isButtonPressed(), + event->device()->sysName()); break; } case LIBINPUT_EVENT_TABLET_PAD_RING: { auto *tabletEvent = static_cast(event.data()); + tabletEvent->position(); emit tabletPadRingEvent(tabletEvent->number(), tabletEvent->position(), tabletEvent->source() == - LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER); + LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER, + event->device()->sysName()); break; } case LIBINPUT_EVENT_TABLET_PAD_STRIP: { @@ -609,7 +617,8 @@ void Connection::processEvents() emit tabletPadStripEvent(tabletEvent->number(), tabletEvent->position(), tabletEvent->source() == - LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER); + LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER, + event->device()->sysName()); break; } default: diff --git a/libinput/connection.h b/libinput/connection.h index 06505a411f..ba2de82f60 100644 --- a/libinput/connection.h +++ b/libinput/connection.h @@ -122,16 +122,12 @@ Q_SIGNALS: void tabletToolEvent(KWin::InputRedirection::TabletEventType type, const QPointF &pos, qreal pressure, int xTilt, int yTilt, qreal rotation, bool tipDown, - bool tipNear, quint64 serialId, quint64 toolId, - InputRedirection::TabletToolType toolType, - const QVector &capabilities, - quint32 time, - LibInput::Device *device); - void tabletToolButtonEvent(uint button, bool isPressed); - - void tabletPadButtonEvent(uint button, bool isPressed); - void tabletPadStripEvent(int number, int position, bool isFinger); - void tabletPadRingEvent(int number, int position, bool isFinger); + bool tipNear, const TabletToolId &tabletToolId, quint32 time); + void tabletToolButtonEvent(uint button, bool isPressed, const TabletToolId &tabletToolId); + + void tabletPadButtonEvent(uint button, bool isPressed, const QString &sysName); + void tabletPadStripEvent(int number, int position, bool isFinger, const QString &sysName); + void tabletPadRingEvent(int number, int position, bool isFinger, const QString &sysName); void eventsRead(); diff --git a/libinput/events.h b/libinput/events.h index a5b3b27e74..1fdb2082fe 100644 --- a/libinput/events.h +++ b/libinput/events.h @@ -296,6 +296,10 @@ public: return state == LIBINPUT_BUTTON_STATE_PRESSED; } + struct libinput_tablet_tool *tool() { + return libinput_event_tablet_tool_get_tool(m_tabletToolEvent); + } + private: libinput_event_tablet_tool *m_tabletToolEvent; }; diff --git a/tablet_input.cpp b/tablet_input.cpp index 4af28fdae7..5222071dc7 100644 --- a/tablet_input.cpp +++ b/tablet_input.cpp @@ -45,14 +45,10 @@ void TabletInputRedirection::init() connect(waylandServer(), &QObject::destroyed, this, [this] { setInited(false); }); } -void TabletInputRedirection::tabletToolEvent(KWin::InputRedirection::TabletEventType type, - const QPointF &pos, qreal pressure, - int xTilt, int yTilt, qreal rotation, - bool tipDown, bool tipNear, quint64 serialId, - quint64 toolId, - InputRedirection::TabletToolType toolType, - const QVector &capabilities, - quint32 time, LibInput::Device *device) +void TabletInputRedirection::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) { if (!inited()) { return; @@ -78,7 +74,7 @@ void TabletInputRedirection::tabletToolEvent(KWin::InputRedirection::TabletEvent 0, // tangentialPressure rotation, 0, // z - Qt::NoModifier, toolId, button, button, toolType, capabilities, serialId, device->sysName()); + Qt::NoModifier, tabletToolId.m_uniqueId, button, button, tabletToolId); ev.setTimestamp(time); input()->processSpies(std::bind(&InputEventSpy::tabletToolEvent, std::placeholders::_1, &ev)); @@ -89,47 +85,40 @@ void TabletInputRedirection::tabletToolEvent(KWin::InputRedirection::TabletEvent m_tipNear = tipNear; } -void KWin::TabletInputRedirection::tabletToolButtonEvent(uint button, bool isPressed) +void KWin::TabletInputRedirection::tabletToolButtonEvent(uint button, bool isPressed, + const TabletToolId &tabletToolId) { - if (isPressed) - m_toolPressedButtons.insert(button); - else - m_toolPressedButtons.remove(button); - input()->processSpies(std::bind(&InputEventSpy::tabletToolButtonEvent, - std::placeholders::_1, m_toolPressedButtons)); + std::placeholders::_1, button, isPressed, tabletToolId)); input()->processFilters(std::bind( &InputEventFilter::tabletToolButtonEvent, - std::placeholders::_1, m_toolPressedButtons)); + std::placeholders::_1, button, isPressed, tabletToolId)); } -void KWin::TabletInputRedirection::tabletPadButtonEvent(uint button, bool isPressed) +void KWin::TabletInputRedirection::tabletPadButtonEvent(uint button, bool isPressed, + const QString &deviceSysName) { - if (isPressed) { - m_padPressedButtons.insert(button); - } else { - m_padPressedButtons.remove(button); - } - input()->processSpies(std::bind( &InputEventSpy::tabletPadButtonEvent, - std::placeholders::_1, m_padPressedButtons)); + std::placeholders::_1, button, isPressed, deviceSysName)); input()->processFilters(std::bind( &InputEventFilter::tabletPadButtonEvent, - std::placeholders::_1, m_padPressedButtons)); + std::placeholders::_1, button, isPressed, deviceSysName)); } -void KWin::TabletInputRedirection::tabletPadStripEvent(int number, int position, bool isFinger) +void KWin::TabletInputRedirection::tabletPadStripEvent(int number, int position, bool isFinger, + const QString &deviceSysName) { input()->processSpies(std::bind( &InputEventSpy::tabletPadStripEvent, - std::placeholders::_1, number, position, isFinger)); + std::placeholders::_1, number, position, isFinger, deviceSysName)); input()->processFilters(std::bind( &InputEventFilter::tabletPadStripEvent, - std::placeholders::_1, number, position, isFinger)); + std::placeholders::_1, number, position, isFinger, deviceSysName)); } -void KWin::TabletInputRedirection::tabletPadRingEvent(int number, int position, bool isFinger) +void KWin::TabletInputRedirection::tabletPadRingEvent(int number, int position, bool isFinger, + const QString &deviceSysName) { input()->processSpies(std::bind( &InputEventSpy::tabletPadRingEvent, - std::placeholders::_1, number, position, isFinger)); + std::placeholders::_1, number, position, isFinger, deviceSysName)); input()->processFilters(std::bind( &InputEventFilter::tabletPadRingEvent, - std::placeholders::_1, number, position, isFinger)); + std::placeholders::_1, number, position, isFinger, deviceSysName)); } void TabletInputRedirection::cleanupDecoration(Decoration::DecoratedClientImpl *old, diff --git a/tablet_input.h b/tablet_input.h index 7668eb9d9a..6c49b9bc5a 100644 --- a/tablet_input.h +++ b/tablet_input.h @@ -19,6 +19,7 @@ namespace KWin { class Toplevel; +class TabletToolId; namespace Decoration { @@ -41,14 +42,13 @@ public: void tabletToolEvent(KWin::InputRedirection::TabletEventType type, const QPointF &pos, qreal pressure, int xTilt, int yTilt, qreal rotation, bool tipDown, - bool tipNear, quint64 serialId, quint64 toolId, - InputRedirection::TabletToolType toolType, const QVector &capabilities, - quint32 time, LibInput::Device *device); - void tabletToolButtonEvent(uint button, bool isPressed); + bool tipNear, const TabletToolId &tabletToolId, + quint32 time); + void tabletToolButtonEvent(uint button, bool isPressed, const TabletToolId &tabletToolId); - void tabletPadButtonEvent(uint button, bool isPressed); - void tabletPadStripEvent(int number, int position, bool isFinger); - void tabletPadRingEvent(int number, int position, bool isFinger); + void tabletPadButtonEvent(uint button, bool isPressed, const QString &deviceSysName); + void tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName); + void tabletPadRingEvent(int number, int position, bool isFinger, const QString &deviceSysName); bool positionValid() const override { @@ -71,8 +71,6 @@ private: bool m_tipNear = false; QPointF m_lastPosition; - QSet m_toolPressedButtons; - QSet m_padPressedButtons; }; }