tablet_v2: Support remaining controls

Adds support for tablet buttons, rings and strips.
icc-effect-5.26.4
Aleix Pol 2020-11-20 02:28:05 +01:00
parent 8f9fcd7eb3
commit 1a32c64603
13 changed files with 360 additions and 258 deletions

View File

@ -501,53 +501,51 @@ void DebugConsoleFilter::tabletToolEvent(TabletEvent *event)
m_textEdit->ensureCursorVisible();
}
void DebugConsoleFilter::tabletToolButtonEvent(const QSet<uint> &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<uint> &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);

View File

@ -148,10 +148,10 @@ public:
void switchEvent(SwitchEvent *event) override;
void tabletToolEvent(TabletEvent *event) override;
void tabletToolButtonEvent(const QSet<uint> &pressedButtons) override;
void tabletPadButtonEvent(const QSet<uint> &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;

303
input.cpp
View File

@ -175,31 +175,37 @@ bool InputEventFilter::tabletToolEvent(TabletEvent *event)
return false;
}
bool InputEventFilter::tabletToolButtonEvent(const QSet<uint> &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<uint> &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<TabletToolV2Interface::Capability> 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<InputRedirection::Capability> 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<TabletToolV2Interface::Capability> 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<KWaylandServer::TabletToolV2Interface*, Cursor*> m_cursorByTool;
};

View File

@ -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<uint> &buttons);
virtual bool tabletPadButtonEvent(const QSet<uint> &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);

View File

@ -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<InputRedirection::Capability> &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)
{
}

View File

@ -165,6 +165,16 @@ private:
LibInput::Device *m_device;
};
class TabletToolId
{
public:
const InputRedirection::TabletToolType m_toolType;
const QVector<InputRedirection::Capability> 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<InputRedirection::Capability> &capabilities,
quint64 serialId, const QString &tabletSysname);
Qt::MouseButton button, Qt::MouseButtons buttons, const TabletToolId &tabletId);
InputRedirection::TabletToolType toolType() const { return m_toolType; }
QVector<InputRedirection::Capability> 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<InputRedirection::Capability> m_capabilities;
const quint64 m_serialId;
const QString m_tabletSysName;
const TabletToolId m_id;
};
}

View File

@ -115,27 +115,33 @@ void InputEventSpy::tabletToolEvent(TabletEvent *event)
Q_UNUSED(event)
}
void InputEventSpy::tabletToolButtonEvent(const QSet<uint> &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<uint> &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)
}
}

View File

@ -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<uint> &pressedButtons);
virtual void tabletPadButtonEvent(const QSet<uint> &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);
};

View File

@ -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<InputRedirection::Capability> 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<InputRedirection::Capability> 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<AbstractWaylandOutput*>(
@ -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<TabletToolButtonEvent *>(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<TabletPadButtonEvent *>(event.data());
emit tabletPadButtonEvent(tabletEvent->buttonId(),
tabletEvent->isButtonPressed());
tabletEvent->isButtonPressed(),
event->device()->sysName());
break;
}
case LIBINPUT_EVENT_TABLET_PAD_RING: {
auto *tabletEvent = static_cast<TabletPadRingEvent *>(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:

View File

@ -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<InputRedirection::Capability> &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 &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();

View File

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

View File

@ -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<InputRedirection::Capability> &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,

View File

@ -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<InputRedirection::Capability> &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<uint> m_toolPressedButtons;
QSet<uint> m_padPressedButtons;
};
}