tablet_v2: Use libinput device groups to deduce the device's tablet

We can have pads without tools, tools without pads. This changes how we
figure out which tablet belongs to the input device.
icc-effect-5.26.4
Aleix Pol 2020-12-22 17:34:10 +01:00
parent 3b807e482d
commit 617651d93e
13 changed files with 105 additions and 84 deletions

View File

@ -506,46 +506,46 @@ void DebugConsoleFilter::tabletToolButtonEvent(uint button, bool pressed, const
QString text = s_hr + s_tableStart + tableHeaderRow(i18n("Tablet Tool Button"))
+ tableRow(i18n("Button"), button)
+ tableRow(i18n("Pressed"), pressed)
+ tableRow(i18n("Tablet"), tabletToolId.m_tabletSysName)
+ tableRow(i18n("Tablet"), qHash(tabletToolId.m_deviceGroupData))
+ s_tableEnd;
m_textEdit->insertHtml(text);
m_textEdit->ensureCursorVisible();
}
void DebugConsoleFilter::tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName)
void DebugConsoleFilter::tabletPadButtonEvent(uint button, bool pressed, const TabletPadId &tabletPadId)
{
QString text = s_hr + s_tableStart
+ tableHeaderRow(i18n("Tablet Pad Button"))
+ tableRow(i18n("Button"), button)
+ tableRow(i18n("Pressed"), pressed)
+ tableRow(i18n("Tablet"), deviceSysName)
+ tableRow(i18n("Tablet"), qHash(tabletPadId.data))
+ s_tableEnd;
m_textEdit->insertHtml(text);
m_textEdit->ensureCursorVisible();
}
void DebugConsoleFilter::tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName)
void DebugConsoleFilter::tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId)
{
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)
+ tableRow(i18n("Tablet"), qHash(tabletPadId.data))
+ s_tableEnd;
m_textEdit->insertHtml(text);
m_textEdit->ensureCursorVisible();
}
void DebugConsoleFilter::tabletPadRingEvent(int number, int position, bool isFinger, const QString &deviceSysName)
void DebugConsoleFilter::tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId)
{
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)
+ tableRow(i18n("Tablet"), qHash(tabletPadId.data))
+ s_tableEnd;
m_textEdit->insertHtml(text);

View File

@ -149,9 +149,9 @@ public:
void tabletToolEvent(TabletEvent *event) 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;
void tabletPadButtonEvent(uint button, bool pressed, const TabletPadId &tabletPadId) override;
void tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId) override;
void tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId) override;
private:
QTextEdit *m_textEdit;

View File

@ -183,29 +183,29 @@ bool InputEventFilter::tabletToolButtonEvent(uint button, bool pressed, const Ta
return false;
}
bool InputEventFilter::tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName)
bool InputEventFilter::tabletPadButtonEvent(uint button, bool pressed, const TabletPadId &tabletPadId)
{
Q_UNUSED(button)
Q_UNUSED(pressed)
Q_UNUSED(deviceSysName)
Q_UNUSED(tabletPadId)
return false;
}
bool InputEventFilter::tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName)
bool InputEventFilter::tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId)
{
Q_UNUSED(number)
Q_UNUSED(position)
Q_UNUSED(isFinger)
Q_UNUSED(deviceSysName)
Q_UNUSED(tabletPadId)
return false;
}
bool InputEventFilter::tabletPadRingEvent(int number, int position, bool isFinger, const QString &deviceSysName)
bool InputEventFilter::tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId)
{
Q_UNUSED(number)
Q_UNUSED(position)
Q_UNUSED(isFinger)
Q_UNUSED(deviceSysName)
Q_UNUSED(tabletPadId)
return false;
}
@ -1578,34 +1578,33 @@ public:
void integrateDevice(LibInput::Device *device)
{
if (device->isTabletTool()) {
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);
if (!device->isTabletTool() && !device->isTabletPad()) {
return;
}
tabletSeat->addTablet(device->vendor(), device->product(), device->sysName(), device->name(), {QString::fromUtf8(devnode)});
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);
auto deviceGroup = libinput_device_get_device_group(device->device());
auto tablet = static_cast<KWaylandServer::TabletV2Interface *>(libinput_device_group_get_user_data(deviceGroup));
if (!tablet) {
tablet = tabletSeat->addTablet(device->vendor(), device->product(), device->sysName(), device->name(), {QString::fromUtf8(devnode)});
libinput_device_group_set_user_data(deviceGroup, tablet);
}
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));
tabletSeat->addTabletPad(device->sysName(), device->name(), {QString::fromUtf8(devnode)}, buttonsCount, ringsCount, stripsCount, modes, libinput_tablet_pad_mode_group_get_mode(firstGroup), tablet);
}
}
void removeDevice(const QString &sysname)
@ -1729,7 +1728,7 @@ public:
tool = createTool(event->tabletId());
}
KWaylandServer::TabletV2Interface *tablet = tabletSeat->tabletByName(event->tabletId().m_tabletSysName);
auto tablet = static_cast<KWaylandServer::TabletV2Interface *>(event->tabletId().m_deviceGroupData);
Toplevel *toplevel = input()->findToplevel(event->globalPos());
if (!toplevel || !toplevel->surface()) {
@ -1816,7 +1815,7 @@ public:
return true;
}
KWaylandServer::TabletPadV2Interface *findPad(const QString &deviceSysName) const
KWaylandServer::TabletPadV2Interface *findAndAdoptPad(const TabletPadId &tabletPadId) const
{
Toplevel *toplevel = workspace()->activeClient();
auto seat = findTabletSeat();
@ -1824,15 +1823,19 @@ public:
return nullptr;
}
auto tablet = static_cast<KWaylandServer::TabletV2Interface *>(tabletPadId.data);
KWaylandServer::SurfaceInterface *surface = toplevel->surface();
auto pad = seat->padByName(deviceSysName);
pad->setCurrentSurface(surface);
auto pad = tablet->pad();
if (!pad) {
return nullptr;
}
pad->setCurrentSurface(surface, tablet);
return pad;
}
bool tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName) override
bool tabletPadButtonEvent(uint button, bool pressed, const TabletPadId &tabletPadId) override
{
auto pad = findPad(deviceSysName);
auto pad = findAndAdoptPad(tabletPadId);
if (!pad) {
return false;
}
@ -1840,9 +1843,9 @@ public:
return true;
}
bool tabletPadRingEvent(int number, int angle, bool isFinger, const QString &deviceSysName) override
bool tabletPadRingEvent(int number, int angle, bool isFinger, const TabletPadId &tabletPadId) override
{
auto pad = findPad(deviceSysName);
auto pad = findAndAdoptPad(tabletPadId);
if (!pad) {
return false;
}
@ -1856,9 +1859,9 @@ public:
return true;
}
bool tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName) override
bool tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId) override
{
auto pad = findPad(deviceSysName);
auto pad = findAndAdoptPad(tabletPadId);
if (!pad) {
return false;
}

View File

@ -44,6 +44,7 @@ class SwitchEvent;
class TabletEvent;
class TabletInputFilter;
class TabletToolId;
class TabletPadId;
namespace Decoration
{
@ -402,9 +403,9 @@ public:
virtual bool tabletToolEvent(TabletEvent *event);
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);
virtual bool tabletPadButtonEvent(uint button, bool pressed, const TabletPadId &tabletPadId);
virtual bool tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
virtual bool tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
protected:
void passToWaylandServer(QKeyEvent *event);

View File

@ -172,7 +172,13 @@ public:
const QVector<InputRedirection::Capability> m_capabilities;
const quint64 m_serialId;
const quint64 m_uniqueId;
const QString m_tabletSysName;
void *const m_deviceGroupData;
};
class TabletPadId
{
public:
void *data;
};
class TabletEvent : public QTabletEvent

View File

@ -122,26 +122,26 @@ void InputEventSpy::tabletToolButtonEvent(uint button, bool pressed, const Table
Q_UNUSED(tabletToolId)
}
void InputEventSpy::tabletPadButtonEvent(uint button, bool pressed, const QString &deviceSysName)
void InputEventSpy::tabletPadButtonEvent(uint button, bool pressed, const TabletPadId &tabletPadId)
{
Q_UNUSED(button)
Q_UNUSED(pressed)
Q_UNUSED(deviceSysName)
Q_UNUSED(tabletPadId)
}
void InputEventSpy::tabletPadStripEvent(int number, int position, bool isFinger, const QString &deviceSysName)
void InputEventSpy::tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId)
{
Q_UNUSED(number)
Q_UNUSED(position)
Q_UNUSED(isFinger)
Q_UNUSED(deviceSysName)
Q_UNUSED(tabletPadId)
}
void InputEventSpy::tabletPadRingEvent(int number, int position, bool isFinger, const QString &deviceSysName)
void InputEventSpy::tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId)
{
Q_UNUSED(number)
Q_UNUSED(position)
Q_UNUSED(isFinger)
Q_UNUSED(deviceSysName)
Q_UNUSED(tabletPadId)
}
}

View File

@ -24,6 +24,7 @@ class WheelEvent;
class SwitchEvent;
class TabletEvent;
class TabletToolId;
class TabletPadId;
/**
* Base class for spying on input events inside InputRedirection.
@ -77,9 +78,9 @@ public:
virtual void tabletToolEvent(TabletEvent *event);
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);
virtual void tabletPadButtonEvent(uint button, bool pressed, const TabletPadId &tabletPadId);
virtual void tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
virtual void tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
};

View File

@ -16,6 +16,8 @@
#include "../abstract_wayland_output.h"
#include "../main.h"
#include "../platform.h"
#include "../workspace.h"
#include "../abstract_client.h"
#include "../screens.h"
#endif
@ -271,7 +273,7 @@ QPointF devicePointToGlobalPosition(const QPointF &devicePos, const AbstractWayl
}
#endif
KWin::TabletToolId createTabletId(libinput_tablet_tool *tool, const QString &sysName)
KWin::TabletToolId createTabletId(libinput_tablet_tool *tool, void *userData)
{
auto serial = libinput_tablet_tool_get_serial(tool);
auto toolId = libinput_tablet_tool_get_tool_id(tool);
@ -324,7 +326,7 @@ KWin::TabletToolId createTabletId(libinput_tablet_tool *tool, const QString &sys
if (libinput_tablet_tool_has_wheel(tool)) {
capabilities << InputRedirection::Wheel;
}
return {toolType, capabilities, serial, toolId, sysName};
return {toolType, capabilities, serial, toolId, userData};
}
void Connection::processEvents()
@ -574,8 +576,9 @@ void Connection::processEvents()
}
#ifndef KWIN_BUILD_TESTING
auto client = workspace()->activeClient();
const auto *output = static_cast<AbstractWaylandOutput*>(
kwinApp()->platform()->enabledOutputs()[tte->device()->screenId()]);
kwinApp()->platform()->enabledOutputs()[client->screen()]);
const QPointF globalPos =
devicePointToGlobalPosition(tte->transformedPosition(output->modeSize()),
output);
@ -585,21 +588,21 @@ void Connection::processEvents()
emit tabletToolEvent(tabletEventType,
globalPos, tte->pressure(),
tte->xTilt(), tte->yTilt(), tte->rotation(),
tte->isTipDown(), tte->isNearby(), createTabletId(tte->tool(), event->device()->sysName()), tte->time());
tte->isTipDown(), tte->isNearby(), createTabletId(tte->tool(), event->device()->groupUserData()), tte->time());
break;
}
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: {
auto *tabletEvent = static_cast<TabletToolButtonEvent *>(event.data());
emit tabletToolButtonEvent(tabletEvent->buttonId(),
tabletEvent->isButtonPressed(),
createTabletId(tabletEvent->tool(), event->device()->sysName()));
createTabletId(tabletEvent->tool(), event->device()->groupUserData()));
break;
}
case LIBINPUT_EVENT_TABLET_PAD_BUTTON: {
auto *tabletEvent = static_cast<TabletPadButtonEvent *>(event.data());
emit tabletPadButtonEvent(tabletEvent->buttonId(),
tabletEvent->isButtonPressed(),
event->device()->sysName());
{ event->device()->groupUserData() });
break;
}
case LIBINPUT_EVENT_TABLET_PAD_RING: {
@ -607,18 +610,16 @@ void Connection::processEvents()
tabletEvent->position();
emit tabletPadRingEvent(tabletEvent->number(),
tabletEvent->position(),
tabletEvent->source() ==
LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
event->device()->sysName());
tabletEvent->source() == LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER,
{ event->device()->groupUserData() });
break;
}
case LIBINPUT_EVENT_TABLET_PAD_STRIP: {
auto *tabletEvent = static_cast<TabletPadStripEvent *>(event.data());
emit tabletPadStripEvent(tabletEvent->number(),
tabletEvent->position(),
tabletEvent->source() ==
LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
event->device()->sysName());
tabletEvent->source() == LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER,
{ event->device()->groupUserData() });
break;
}
default:

View File

@ -125,9 +125,9 @@ Q_SIGNALS:
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 tabletPadButtonEvent(uint button, bool isPressed, const TabletPadId &tabletPadId);
void tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
void tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
void eventsRead();

View File

@ -433,6 +433,13 @@ int Device::ringsCount() const
return libinput_device_tablet_pad_get_num_rings(m_device);
}
void *Device::groupUserData() const
{
auto deviceGroup = libinput_device_get_device_group(m_device);
return libinput_device_group_get_user_data(deviceGroup);
}
#define CONFIG(method, condition, function, variable, key) \
void Device::method(bool set) \
{ \

View File

@ -474,6 +474,8 @@ public:
int stripsCount() const;
int ringsCount() const;
void *groupUserData() const;
/**
* All created Devices
*/

View File

@ -95,30 +95,30 @@ void KWin::TabletInputRedirection::tabletToolButtonEvent(uint button, bool isPre
}
void KWin::TabletInputRedirection::tabletPadButtonEvent(uint button, bool isPressed,
const QString &deviceSysName)
const TabletPadId &tabletPadId)
{
input()->processSpies(std::bind( &InputEventSpy::tabletPadButtonEvent,
std::placeholders::_1, button, isPressed, deviceSysName));
std::placeholders::_1, button, isPressed, tabletPadId));
input()->processFilters(std::bind( &InputEventFilter::tabletPadButtonEvent,
std::placeholders::_1, button, isPressed, deviceSysName));
std::placeholders::_1, button, isPressed, tabletPadId));
}
void KWin::TabletInputRedirection::tabletPadStripEvent(int number, int position, bool isFinger,
const QString &deviceSysName)
const TabletPadId &tabletPadId)
{
input()->processSpies(std::bind( &InputEventSpy::tabletPadStripEvent,
std::placeholders::_1, number, position, isFinger, deviceSysName));
std::placeholders::_1, number, position, isFinger, tabletPadId));
input()->processFilters(std::bind( &InputEventFilter::tabletPadStripEvent,
std::placeholders::_1, number, position, isFinger, deviceSysName));
std::placeholders::_1, number, position, isFinger, tabletPadId));
}
void KWin::TabletInputRedirection::tabletPadRingEvent(int number, int position, bool isFinger,
const QString &deviceSysName)
const TabletPadId &tabletPadId)
{
input()->processSpies(std::bind( &InputEventSpy::tabletPadRingEvent,
std::placeholders::_1, number, position, isFinger, deviceSysName));
std::placeholders::_1, number, position, isFinger, tabletPadId));
input()->processFilters(std::bind( &InputEventFilter::tabletPadRingEvent,
std::placeholders::_1, number, position, isFinger, deviceSysName));
std::placeholders::_1, number, position, isFinger, tabletPadId));
}
void TabletInputRedirection::cleanupDecoration(Decoration::DecoratedClientImpl *old,

View File

@ -46,9 +46,9 @@ public:
quint32 time);
void tabletToolButtonEvent(uint button, bool isPressed, const TabletToolId &tabletToolId);
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);
void tabletPadButtonEvent(uint button, bool isPressed, const TabletPadId &tabletPadId);
void tabletPadStripEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
void tabletPadRingEvent(int number, int position, bool isFinger, const TabletPadId &tabletPadId);
bool positionValid() const override
{