File U_xwayland_Dispatch_tablet_tool_tip_events.patch of Package xwayland
From 69e440a282ceb8d9d093fd69cf1fc5389c46a784 Mon Sep 17 00:00:00 2001
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Date: Fri, 20 Jun 2025 15:59:55 +0300
Subject: [PATCH] xwayland: Dispatch tablet tool tip events after frame events
Xwayland dispatches tablet tool tip events immediately when they arrive.
With compositors such as mutter and sway, it is not an issue because
their libinput backends synthetize axis events before tip events. In
other words, axis data and the tip status belong to different frames.
On the other hand, kwin sends axis and tip events in a single frame
(its libinput backend generates a single tip event with axis data
attached to it). Since the tip events are dispatched immediately,
they can have wrong information associated with them, for example tool
position or pressure. It results in undesired "streaks" when the user
presses the tablet tool against the tablet.
See also https://bugs.kde.org/show_bug.cgi?id=479856.
Signed-off-by: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
(cherry picked from commit 60f0bfe852b988b3c4351483720e3c72c75f7405)
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2041>
---
hw/xwayland/xwayland-input.c | 26 +++++++++++++-------------
hw/xwayland/xwayland-input.h | 5 +++--
2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 53cc5144bb..d5bce37835 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -2183,22 +2183,17 @@ tablet_tool_down(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial)
{
struct xwl_tablet_tool *xwl_tablet_tool = data;
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
- ValuatorMask mask;
+ xwl_tablet_tool->tip = TRUE;
xwl_seat->xwl_screen->serial = serial;
-
- valuator_mask_zero(&mask);
- QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonPress, 1, 0, &mask);
}
static void
tablet_tool_up(void *data, struct zwp_tablet_tool_v2 *tool)
{
struct xwl_tablet_tool *xwl_tablet_tool = data;
- ValuatorMask mask;
- valuator_mask_zero(&mask);
- QueuePointerEvents(xwl_tablet_tool->xdevice, ButtonRelease, 1, 0, &mask);
+ xwl_tablet_tool->tip = FALSE;
}
static void
@@ -2321,7 +2316,7 @@ tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool,
{
struct xwl_tablet_tool *xwl_tablet_tool = data;
struct xwl_seat *xwl_seat = xwl_tablet_tool->seat;
- uint32_t *mask = &xwl_tablet_tool->buttons_now;
+ uint32_t *mask = &xwl_tablet_tool->buttons;
int xbtn = 0;
/* BTN_0 .. BTN_9 */
@@ -2386,7 +2381,7 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time)
{
struct xwl_tablet_tool *xwl_tablet_tool = data;
ValuatorMask mask;
- uint32_t released, pressed, diff;
+ uint32_t effective_buttons, released, pressed, diff;
int button;
valuator_mask_zero(&mask);
@@ -2402,9 +2397,14 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time)
valuator_mask_zero(&mask);
- diff = xwl_tablet_tool->buttons_prev ^ xwl_tablet_tool->buttons_now;
- released = diff & ~xwl_tablet_tool->buttons_now;
- pressed = diff & xwl_tablet_tool->buttons_now;
+ effective_buttons = xwl_tablet_tool->buttons;
+ if (xwl_tablet_tool->tip) {
+ SetBit(&effective_buttons, 0);
+ }
+
+ diff = effective_buttons ^ xwl_tablet_tool->effective_buttons;
+ released = diff & ~effective_buttons;
+ pressed = diff & effective_buttons;
button = 1;
while (released) {
@@ -2424,7 +2424,7 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time)
pressed >>= 1;
}
- xwl_tablet_tool->buttons_prev = xwl_tablet_tool->buttons_now;
+ xwl_tablet_tool->effective_buttons = effective_buttons;
while (xwl_tablet_tool->wheel_clicks) {
if (xwl_tablet_tool->wheel_clicks < 0) {
diff --git a/hw/xwayland/xwayland-input.h b/hw/xwayland/xwayland-input.h
index d40bca08a4..0a742f0179 100644
--- a/hw/xwayland/xwayland-input.h
+++ b/hw/xwayland/xwayland-input.h
@@ -148,8 +148,9 @@ struct xwl_tablet_tool {
double rotation;
double slider;
- uint32_t buttons_now,
- buttons_prev;
+ uint32_t buttons;
+ Bool tip;
+ uint32_t effective_buttons;
int32_t wheel_clicks;
--
GitLab