summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorOlivier Fourdan <ofourdan@redhat.com>2021-02-09 13:04:59 +0100
committerOlivier Fourdan <ofourdan@redhat.com>2021-02-15 09:42:00 +0100
commitc5c5322ad69b0751f16c785a479b2989b8794235 (patch)
tree61d2711cdd9f545c6b802657cf32df8f8bee2540 /hw
parentebdb2e264676c3b27a708328348efe73e0d3c8c2 (diff)
xwayland: Use relative values for raw events
Xwayland supports relative motion events from the Wayland compositor via the relative-pointer protocol, and converts those to the absolute range in device units for raw events. Some X11 clients however wrongly assume relative values in the axis values even for devices explicitly labeled as absolute. While this is a bug in the client, such applications would work fine in plain Xorg but not with Xwayland. To avoid that issue, use the relative values for raw events without conversion, so that such application continue to work in Xwayland. Thanks Peter for figuring out the root cause. v2: Don't duplicate relative and absolute events (Peter) v3: Use POINTER_RAWONLY (Peter) Suggested-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
Diffstat (limited to 'hw')
-rw-r--r--hw/xwayland/xwayland-input.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 2e4b20024..48216c548 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -497,14 +497,33 @@ dispatch_pointer_motion_event(struct xwl_seat *xwl_seat)
dx_unaccel, dy_unaccel);
} else if (xwl_seat->pending_pointer_event.has_absolute ||
xwl_seat->pending_pointer_event.has_relative) {
- int x;
- int y;
+ if (xwl_seat->pending_pointer_event.has_relative) {
+ double dx, dx_unaccel;
+ double dy, dy_unaccel;
+
+ dx = xwl_seat->pending_pointer_event.dx;
+ dy = xwl_seat->pending_pointer_event.dy;
+ dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
+ dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
+
+ valuator_mask_zero(&mask);
+ valuator_mask_set_unaccelerated(&mask, 0, dx, dx_unaccel);
+ valuator_mask_set_unaccelerated(&mask, 1, dy, dy_unaccel);
+
+ QueuePointerEvents(xwl_seat->relative_pointer, MotionNotify, 0,
+ POINTER_RAWONLY, &mask);
+ }
if (xwl_seat->pending_pointer_event.has_absolute) {
+ ValuatorMask mask;
+ DeviceIntPtr device;
+ int flags;
int sx = wl_fixed_to_int(xwl_seat->pending_pointer_event.x);
int sy = wl_fixed_to_int(xwl_seat->pending_pointer_event.y);
int dx = xwl_seat->focus_window->window->drawable.x;
int dy = xwl_seat->focus_window->window->drawable.y;
+ int x;
+ int y;
if (xwl_window_has_viewport_enabled(xwl_seat->focus_window)) {
sx *= xwl_seat->focus_window->scale_x;
@@ -513,26 +532,21 @@ dispatch_pointer_motion_event(struct xwl_seat *xwl_seat)
x = dx + sx;
y = dy + sy;
- } else {
- miPointerGetPosition(xwl_seat->pointer, &x, &y);
- }
- valuator_mask_zero(&mask);
- if (xwl_seat->pending_pointer_event.has_relative) {
- double dx_unaccel;
- double dy_unaccel;
-
- dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
- dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
- valuator_mask_set_absolute_unaccelerated(&mask, 0, x, dx_unaccel);
- valuator_mask_set_absolute_unaccelerated(&mask, 1, y, dy_unaccel);
- } else {
+ valuator_mask_zero(&mask);
valuator_mask_set(&mask, 0, x);
valuator_mask_set(&mask, 1, y);
- }
- QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0,
- POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
+ if (xwl_seat->pending_pointer_event.has_relative) {
+ flags = POINTER_ABSOLUTE | POINTER_SCREEN | POINTER_NORAW;
+ device = xwl_seat->relative_pointer;
+ } else {
+ flags = POINTER_ABSOLUTE | POINTER_SCREEN;
+ device = xwl_seat->pointer;
+ }
+
+ QueuePointerEvents(device, MotionNotify, 0, flags, &mask);
+ }
}
xwl_seat->pending_pointer_event.has_absolute = FALSE;