tablet_v2: Support remaining controls
Adds support for tablet buttons, rings and strips.icc-effect-5.26.4
parent
8f9fcd7eb3
commit
1a32c64603
|
@ -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);
|
||||
|
|
|
@ -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
303
input.cpp
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
9
input.h
9
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<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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue