diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0401110aa9..54d8387de4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -654,6 +654,9 @@ set(kwinLibs
)
add_library(kwin SHARED ${kwin_SRCS})
+if (Libinput_VERSION_STRING VERSION_GREATER 1.14)
+ target_compile_definitions(kwin PRIVATE -DLIBINPUT_HAS_TOTEM)
+endif ()
set_target_properties(kwin PROPERTIES
VERSION ${PROJECT_VERSION}
diff --git a/autotests/libinput/mock_libinput.cpp b/autotests/libinput/mock_libinput.cpp
index e3f3ace30b..5742f8f5ed 100644
--- a/autotests/libinput/mock_libinput.cpp
+++ b/autotests/libinput/mock_libinput.cpp
@@ -916,3 +916,21 @@ libinput_event_get_tablet_tool_event(struct libinput_event *event)
}
return nullptr;
}
+
+int
+libinput_device_tablet_pad_get_num_strips(struct libinput_device *device)
+{
+ return device->stripCount;
+}
+
+int
+libinput_device_tablet_pad_get_num_rings(struct libinput_device *device)
+{
+ return device->ringCount;
+}
+
+int
+libinput_device_tablet_pad_get_num_buttons(struct libinput_device *device)
+{
+ return device->buttonCount;
+}
diff --git a/autotests/libinput/mock_libinput.h b/autotests/libinput/mock_libinput.h
index 2ee7892975..6f6d126469 100644
--- a/autotests/libinput/mock_libinput.h
+++ b/autotests/libinput/mock_libinput.h
@@ -105,6 +105,9 @@ struct libinput_device {
enum libinput_config_click_method defaultClickMethod = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
enum libinput_config_click_method clickMethod = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
bool setClickMethodReturnValue = 0;
+ uint32_t buttonCount = 0;
+ uint32_t stripCount = 0;
+ uint32_t ringCount = 0;
};
struct libinput_event {
diff --git a/debug_console.cpp b/debug_console.cpp
index 17ccd045cf..1e759abaab 100644
--- a/debug_console.cpp
+++ b/debug_console.cpp
@@ -28,6 +28,7 @@ along with this program. If not, see .
#include "wayland_server.h"
#include "workspace.h"
#include "keyboard_input.h"
+#include "input_event.h"
#include "libinput/connection.h"
#include "libinput/device.h"
#include
@@ -486,7 +487,7 @@ void DebugConsoleFilter::switchEvent(SwitchEvent *event)
m_textEdit->ensureCursorVisible();
}
-void DebugConsoleFilter::tabletToolEvent(QTabletEvent *event)
+void DebugConsoleFilter::tabletToolEvent(TabletEvent *event)
{
QString typeString;
{
diff --git a/debug_console.h b/debug_console.h
index 29f61b171b..ba758c83ec 100644
--- a/debug_console.h
+++ b/debug_console.h
@@ -153,7 +153,7 @@ public:
void switchEvent(SwitchEvent *event) override;
- void tabletToolEvent(QTabletEvent *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;
diff --git a/input.cpp b/input.cpp
index 79cbd87218..09a83f6e74 100644
--- a/input.cpp
+++ b/input.cpp
@@ -36,24 +36,28 @@ along with this program. If not, see .
#ifdef KWIN_BUILD_TABBOX
#include "tabbox/tabbox.h"
#endif
-#include "unmanaged.h"
-#include "screenedge.h"
-#include "screens.h"
-#include "workspace.h"
+#include "internal_client.h"
#include "libinput/connection.h"
#include "libinput/device.h"
#include "platform.h"
#include "popup_input_filter.h"
+#include "screenedge.h"
+#include "screens.h"
+#include "unmanaged.h"
#include "wayland_server.h"
+#include "workspace.h"
+#include "xdgshellclient.h"
#include "xwl/xwayland_interface.h"
-#include "internal_client.h"
-#include
-#include
-#include
-#include
-#include
+#include "cursor.h"
#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
//screenlocker
#include
@@ -176,7 +180,7 @@ bool InputEventFilter::switchEvent(SwitchEvent *event)
return false;
}
-bool InputEventFilter::tabletToolEvent(QTabletEvent *event)
+bool InputEventFilter::tabletToolEvent(TabletEvent *event)
{
Q_UNUSED(event)
return false;
@@ -1531,17 +1535,174 @@ public:
}
};
+static KWayland::Server::SeatInterface *findSeat()
+{
+ auto server = waylandServer();
+ if (!server) {
+ return nullptr;
+ }
+ return server->seat();
+}
+
/**
* Useful when there's no proper tablet support on the clients
*/
-class FakeTabletInputFilter : public InputEventFilter
+class TabletInputFilter : public QObject, public InputEventFilter
{
public:
- FakeTabletInputFilter()
+ TabletInputFilter()
{
}
- bool tabletToolEvent(QTabletEvent *event) override
+ static KWayland::Server::TabletSeatInterface *findTabletSeat()
+ {
+ auto server = waylandServer();
+ if (!server) {
+ return nullptr;
+ }
+ KWayland::Server::TabletManagerInterface *manager = server->tabletManager();
+ return manager->seat(findSeat());
+ }
+
+ void integrateDevice(LibInput::Device *device)
+ {
+ if (device->isTabletTool()) {
+ KWayland::Server::TabletSeatInterface *tabletSeat = findTabletSeat();
+ struct udev_device *const udev_device = libinput_device_get_udev_device(device->device());
+ const char *devnode = udev_device_get_devnode(udev_device);
+ tabletSeat->addTablet(device->vendor(), device->product(), device->sysName(), device->name(), {QString::fromUtf8(devnode)});
+ }
+ }
+ void removeDevice(const QString &sysname)
+ {
+ KWayland::Server::TabletSeatInterface *tabletSeat = findTabletSeat();
+ tabletSeat->removeTablet(sysname);
+ }
+
+ bool tabletToolEvent(TabletEvent *event) override
+ {
+ if (!workspace()) {
+ return false;
+ }
+
+ KWayland::Server::TabletSeatInterface *tabletSeat = findTabletSeat();
+ auto tool = tabletSeat->toolByHardwareSerial(event->serialId());
+ if (!tool) {
+ using namespace KWayland::Server;
+
+ const QVector capabilities = event->capabilities();
+ const auto f = [](InputRedirection::Capability cap) {
+ switch (cap) {
+ case InputRedirection::Tilt:
+ return TabletToolInterface::Tilt;
+ case InputRedirection::Pressure:
+ return TabletToolInterface::Pressure;
+ case InputRedirection::Distance:
+ return TabletToolInterface::Distance;
+ case InputRedirection::Rotation:
+ return TabletToolInterface::Rotation;
+ case InputRedirection::Slider:
+ return TabletToolInterface::Slider;
+ case InputRedirection::Wheel:
+ return TabletToolInterface::Wheel;
+ }
+ return TabletToolInterface::Wheel;
+ };
+ QVector ifaceCapabilities;
+ ifaceCapabilities.resize(capabilities.size());
+ std::transform(capabilities.constBegin(), capabilities.constEnd(), ifaceCapabilities.begin(), f);
+
+ TabletToolInterface::Type toolType = TabletToolInterface::Type::Pen;
+ switch (event->toolType()) {
+ case InputRedirection::Pen:
+ toolType = TabletToolInterface::Type::Pen;
+ break;
+ case InputRedirection::Eraser:
+ toolType = TabletToolInterface::Type::Eraser;
+ break;
+ case InputRedirection::Brush:
+ toolType = TabletToolInterface::Type::Brush;
+ break;
+ case InputRedirection::Pencil:
+ toolType = TabletToolInterface::Type::Pencil;
+ break;
+ case InputRedirection::Airbrush:
+ toolType = TabletToolInterface::Type::Airbrush;
+ break;
+ case InputRedirection::Finger:
+ toolType = TabletToolInterface::Type::Finger;
+ break;
+ case InputRedirection::Mouse:
+ toolType = TabletToolInterface::Type::Mouse;
+ break;
+ case InputRedirection::Lens:
+ toolType = TabletToolInterface::Type::Lens;
+ break;
+ case InputRedirection::Totem:
+ toolType = TabletToolInterface::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->cursor(), &TabletCursor::changed, cursor, &Cursor::cursorChanged);
+ connect(tool->cursor(), &TabletCursor::changed, cursor, [cursor, tool] {
+// cursor->setImage(tool->cursor()->image());
+ QPixmap redRect(20, 20);
+ redRect.fill(Qt::red);
+ cursor->setImage(redRect.toImage());
+ cursor->setHotspot(tool->cursor()->hotspot());
+ });
+ emit cursor->cursorChanged();
+ }
+
+ KWayland::Server::TabletInterface *tablet = tabletSeat->tabletByName(event->tabletSysName());
+
+ Toplevel *toplevel = input()->findToplevel(event->globalPos());
+ if (!toplevel || !toplevel->surface()) {
+ return false;
+ }
+
+ KWayland::Server::SurfaceInterface *surface = toplevel->surface();
+ tool->setCurrentSurface(surface);
+
+ if (!tool->isClientSupported() || !tablet->isSurfaceSupported(surface)) {
+ return emulateTabletEvent(event);
+ }
+
+ switch (event->type()) {
+ case QEvent::TabletMove: {
+ const auto pos = event->globalPosF() - toplevel->pos();
+ tool->sendMotion(pos);
+ m_cursorByTool[tool]->setPos(pos.toPoint());
+ break;
+ } case QEvent::TabletEnterProximity: {
+ tool->sendProximityIn(tablet);
+ break;
+ } case QEvent::TabletLeaveProximity:
+ tool->sendProximityOut();
+ break;
+ case QEvent::TabletPress:
+ tool->sendDown();
+ break;
+ case QEvent::TabletRelease:
+ tool->sendUp();
+ break;
+ default:
+ qCWarning(KWIN_CORE) << "Unexpected tablet event type" << event;
+ break;
+ }
+ const quint32 MAX_VAL = 65535;
+ tool->sendPressure(MAX_VAL * event->pressure());
+ tool->sendFrame(event->timestamp());
+ waylandServer()->simulateUserActivity();
+ return true;
+ }
+
+ bool emulateTabletEvent(TabletEvent *event)
{
if (!workspace()) {
return false;
@@ -1569,6 +1730,7 @@ public:
waylandServer()->simulateUserActivity();
return true;
}
+ QHash m_cursorByTool;
};
class DragAndDropInputFilter : public InputEventFilter
@@ -1932,7 +2094,16 @@ void InputRedirection::setupInputFilters()
if (waylandServer()) {
installInputEventFilter(new WindowActionInputFilter);
installInputEventFilter(new ForwardInputFilter);
- installInputEventFilter(new FakeTabletInputFilter);
+
+ if (m_libInput) {
+ m_tabletSupport = new TabletInputFilter;
+ for (LibInput::Device *dev : m_libInput->devices()) {
+ m_tabletSupport->integrateDevice(dev);
+ }
+ connect(m_libInput, &LibInput::Connection::deviceAdded, m_tabletSupport, &TabletInputFilter::integrateDevice);
+ connect(m_libInput, &LibInput::Connection::deviceRemovedSysName, m_tabletSupport, &TabletInputFilter::removeDevice);
+ installInputEventFilter(m_tabletSupport);
+ }
}
}
@@ -1950,15 +2121,6 @@ void InputRedirection::reconfigure()
}
}
-static KWayland::Server::SeatInterface *findSeat()
-{
- auto server = waylandServer();
- if (!server) {
- return nullptr;
- }
- return server->seat();
-}
-
void InputRedirection::setupLibInput()
{
if (!Application::usesLibinput()) {
@@ -2087,6 +2249,7 @@ void InputRedirection::setupLibInput()
}
);
}
+
setupTouchpadShortcuts();
}
diff --git a/input.h b/input.h
index 3e983d4768..68ce308f34 100644
--- a/input.h
+++ b/input.h
@@ -51,6 +51,8 @@ class TabletInputRedirection;
class TouchInputRedirection;
class WindowSelectorFilter;
class SwitchEvent;
+class TabletEvent;
+class TabletInputFilter;
namespace Decoration
{
@@ -100,6 +102,26 @@ public:
Proximity,
Tip
};
+ enum TabletToolType {
+ Pen,
+ Eraser,
+ Brush,
+ Pencil,
+ Airbrush,
+ Finger,
+ Mouse,
+ Lens,
+ Totem,
+ };
+ enum Capability {
+ Tilt,
+ Pressure,
+ Distance,
+ Rotation,
+ Slider,
+ Wheel,
+ };
+
~InputRedirection() override;
void init();
@@ -297,6 +319,7 @@ private:
PointerInputRedirection *m_pointer;
TabletInputRedirection *m_tablet;
TouchInputRedirection *m_touch;
+ TabletInputFilter *m_tabletSupport = nullptr;
GlobalShortcutsManager *m_shortcuts;
@@ -382,7 +405,7 @@ public:
virtual bool switchEvent(SwitchEvent *event);
- virtual bool tabletToolEvent(QTabletEvent *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);
diff --git a/input_event.cpp b/input_event.cpp
index a5efeef4d5..83d3cdd9c8 100644
--- a/input_event.cpp
+++ b/input_event.cpp
@@ -65,4 +65,17 @@ SwitchEvent::SwitchEvent(State state, quint32 timestamp, quint64 timestampMicros
setTimestamp(timestamp);
}
+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)
+ : 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)
+{
+}
+
}
diff --git a/input_event.h b/input_event.h
index 8d2bc26483..b44e9d0a5d 100644
--- a/input_event.h
+++ b/input_event.h
@@ -176,6 +176,29 @@ private:
LibInput::Device *m_device;
};
+class TabletEvent : public QTabletEvent
+{
+public:
+ 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);
+
+ InputRedirection::TabletToolType toolType() const { return m_toolType; }
+ QVector capabilities() const { return m_capabilities; }
+ quint64 serialId() const { return m_serialId; }
+ QString tabletSysName() { return m_tabletSysName; }
+
+private:
+ const InputRedirection::TabletToolType m_toolType;
+ const QVector m_capabilities;
+ const quint64 m_serialId;
+ const QString m_tabletSysName;
+};
+
}
#endif
diff --git a/input_event_spy.cpp b/input_event_spy.cpp
index 85023d3498..35e94d9778 100644
--- a/input_event_spy.cpp
+++ b/input_event_spy.cpp
@@ -121,7 +121,7 @@ void InputEventSpy::switchEvent(SwitchEvent *event)
Q_UNUSED(event)
}
-void InputEventSpy::tabletToolEvent(QTabletEvent *event)
+void InputEventSpy::tabletToolEvent(TabletEvent *event)
{
Q_UNUSED(event)
}
diff --git a/input_event_spy.h b/input_event_spy.h
index fcd44aaa80..0b99f2d132 100644
--- a/input_event_spy.h
+++ b/input_event_spy.h
@@ -33,7 +33,7 @@ class KeyEvent;
class MouseEvent;
class WheelEvent;
class SwitchEvent;
-
+class TabletEvent;
/**
* Base class for spying on input events inside InputRedirection.
@@ -85,7 +85,7 @@ public:
virtual void switchEvent(SwitchEvent *event);
- virtual void tabletToolEvent(QTabletEvent *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);
diff --git a/libinput/connection.cpp b/libinput/connection.cpp
index 7bb3bcd1fb..0ce47967b4 100644
--- a/libinput/connection.cpp
+++ b/libinput/connection.cpp
@@ -528,12 +528,62 @@ void Connection::processEvents()
}
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;
+ }
emit tabletToolEvent(tabletEventType,
tte->transformedPosition(m_size), tte->pressure(),
tte->xTilt(), tte->yTilt(), tte->rotation(),
tte->isTipDown(), tte->isNearby(), serial,
- toolId, event->device());
+ toolId, toolType, capabilities, tte->time(),
+ event->device());
break;
}
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: {
diff --git a/libinput/connection.h b/libinput/connection.h
index f7133bc461..fba0b89232 100644
--- a/libinput/connection.h
+++ b/libinput/connection.h
@@ -133,7 +133,11 @@ 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, LibInput::Device *device);
+ 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);
diff --git a/libinput/device.cpp b/libinput/device.cpp
index 91f00134eb..a5f970ace0 100644
--- a/libinput/device.cpp
+++ b/libinput/device.cpp
@@ -158,12 +158,7 @@ Device::Device(libinput_device *device, QObject *parent)
, m_pointer(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_POINTER))
, m_touch(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_TOUCH))
, m_tabletTool(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_TABLET_TOOL))
-#if 0
- // next libinput version
, m_tabletPad(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_TABLET_PAD))
-#else
- , m_tabletPad(false)
-#endif
, m_supportsGesture(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_GESTURE))
, m_switch(libinput_device_has_capability(m_device, LIBINPUT_DEVICE_CAP_SWITCH))
, m_lidSwitch(m_switch ? libinput_device_switch_has_switch(m_device, LIBINPUT_SWITCH_LID) : false)
@@ -427,6 +422,16 @@ void Device::setLmrTapButtonMap(bool set)
}
}
+int Device::stripsCount() const
+{
+ return libinput_device_tablet_pad_get_num_strips(m_device);
+}
+
+int Device::ringsCount() const
+{
+ return libinput_device_tablet_pad_get_num_rings(m_device);
+}
+
#define CONFIG(method, condition, function, variable, key) \
void Device::method(bool set) \
{ \
diff --git a/libinput/device.h b/libinput/device.h
index 5c6b735f35..c72f8c1212 100644
--- a/libinput/device.h
+++ b/libinput/device.h
@@ -472,6 +472,9 @@ public:
return m_tabletSwitch;
}
+ int stripsCount() const;
+ int ringsCount() const;
+
/**
* All created Devices
*/
diff --git a/libinput/events.h b/libinput/events.h
index fb8742831f..afb0af9b96 100644
--- a/libinput/events.h
+++ b/libinput/events.h
@@ -196,6 +196,10 @@ class TabletToolEvent : public Event
public:
TabletToolEvent(libinput_event *event, libinput_event_type type);
+ uint32_t time() const
+ {
+ return libinput_event_tablet_tool_get_time(m_tabletToolEvent);
+ }
bool xHasChanged() const {
return libinput_event_tablet_tool_x_has_changed(m_tabletToolEvent);
}
diff --git a/modifier_only_shortcuts.cpp b/modifier_only_shortcuts.cpp
index cb47df4471..2ab3b69dee 100644
--- a/modifier_only_shortcuts.cpp
+++ b/modifier_only_shortcuts.cpp
@@ -59,7 +59,7 @@ void ModifierOnlyShortcuts::keyEvent(KeyEvent *event)
m_pressedKeys.remove(event->nativeScanCode());
if (m_pressedKeys.isEmpty() &&
event->modifiersRelevantForGlobalShortcuts() == Qt::NoModifier &&
- !workspace()->globalShortcutsDisabled()) {
+ workspace() && !workspace()->globalShortcutsDisabled()) {
if (m_modifier != Qt::NoModifier) {
const auto list = options->modifierOnlyDBusShortcut(m_modifier);
if (list.size() >= 4) {
diff --git a/tablet_input.cpp b/tablet_input.cpp
index 8c3ef420aa..be18ada445 100644
--- a/tablet_input.cpp
+++ b/tablet_input.cpp
@@ -21,6 +21,7 @@ along with this program. If not, see .
#include "abstract_client.h"
#include "decorations/decoratedclient.h"
#include "input.h"
+#include "input_event.h"
#include "input_event_spy.h"
#include "libinput/device.h"
#include "pointer_input.h"
@@ -60,10 +61,11 @@ void TabletInputRedirection::tabletToolEvent(KWin::InputRedirection::TabletEvent
const QPointF &pos, qreal pressure,
int xTilt, int yTilt, qreal rotation,
bool tipDown, bool tipNear, quint64 serialId,
- quint64 toolId, LibInput::Device *device)
+ quint64 toolId,
+ InputRedirection::TabletToolType toolType,
+ const QVector &capabilities,
+ quint32 time, LibInput::Device *device)
{
- Q_UNUSED(device)
- Q_UNUSED(toolId)
if (!inited()) {
return;
}
@@ -83,13 +85,14 @@ void TabletInputRedirection::tabletToolEvent(KWin::InputRedirection::TabletEvent
}
const auto button = m_tipDown ? Qt::LeftButton : Qt::NoButton;
- QTabletEvent ev(t, pos, pos, QTabletEvent::Stylus, QTabletEvent::Pen, pressure,
+ TabletEvent ev(t, pos, pos, QTabletEvent::Stylus, QTabletEvent::Pen, pressure,
xTilt, yTilt,
0, // tangentialPressure
rotation,
0, // z
- Qt::NoModifier, serialId, button, button);
+ Qt::NoModifier, toolId, button, button, toolType, capabilities, serialId, device->sysName());
+ ev.setTimestamp(time);
input()->processSpies(std::bind(&InputEventSpy::tabletToolEvent, std::placeholders::_1, &ev));
input()->processFilters(
std::bind(&InputEventFilter::tabletToolEvent, std::placeholders::_1, &ev));
diff --git a/tablet_input.h b/tablet_input.h
index 9607c8f3b8..bce594118f 100644
--- a/tablet_input.h
+++ b/tablet_input.h
@@ -26,11 +26,9 @@ along with this program. If not, see .
#include
#include
#include
-#include
namespace KWin
{
-class InputRedirection;
class Toplevel;
namespace Decoration
@@ -54,7 +52,9 @@ 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, LibInput::Device *device);
+ 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);
diff --git a/wayland_server.cpp b/wayland_server.cpp
index a93d50e8fa..0814396a00 100644
--- a/wayland_server.cpp
+++ b/wayland_server.cpp
@@ -315,6 +315,8 @@ bool WaylandServer::init(const QByteArray &socketName, InitializationFlags flags
}
);
+ m_tabletManager = m_display->createTabletManagerInterface(m_display);
+
m_xdgShell = m_display->createXdgShell(XdgShellInterfaceVersion::Stable, m_display);
m_xdgShell->create();
connect(m_xdgShell, &XdgShellInterface::surfaceCreated, this, &WaylandServer::createSurface);
diff --git a/wayland_server.h b/wayland_server.h
index e47608b214..d90e0119e3 100644
--- a/wayland_server.h
+++ b/wayland_server.h
@@ -69,6 +69,7 @@ class XdgOutputManagerInterface;
class KeyStateInterface;
class LinuxDmabufUnstableV1Interface;
class LinuxDmabufUnstableV1Buffer;
+class TabletManagerInterface;
}
}
@@ -105,6 +106,10 @@ public:
KWayland::Server::SeatInterface *seat() {
return m_seat;
}
+ KWayland::Server::TabletManagerInterface *tabletManager()
+ {
+ return m_tabletManager;
+ }
KWayland::Server::DataDeviceManagerInterface *dataDeviceManager() {
return m_dataDeviceManager;
}
@@ -246,6 +251,7 @@ private:
KWayland::Server::Display *m_display = nullptr;
KWayland::Server::CompositorInterface *m_compositor = nullptr;
KWayland::Server::SeatInterface *m_seat = nullptr;
+ KWayland::Server::TabletManagerInterface *m_tabletManager = nullptr;
KWayland::Server::DataDeviceManagerInterface *m_dataDeviceManager = nullptr;
KWayland::Server::XdgShellInterface *m_xdgShell = nullptr;
KWayland::Server::PlasmaShellInterface *m_plasmaShell = nullptr;