xwayland: Set unaccelerated pointer motion delta if available
If there was an relative pointer motion within the same frame as an absolute pointer motion, provide both the absolute coordinate and the unaccelerated delta when setting the valuator mask. If a frame contained only a relative motion, queue an absolute motion with an unchanged position, but still pass the unaccelerated motion event. If the wl_seat advertised by the compositor is not new enough, assume each relative and absolute pointer motion arrives within their own separate frames. Signed-off-by: Jonas Ådahl <jadahl@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
aa9634d03b
commit
b4644ce8d3
|
@ -347,30 +347,47 @@ pointer_handle_leave(void *data, struct wl_pointer *pointer,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dispatch_pointer_event(struct xwl_seat *xwl_seat)
|
dispatch_pointer_motion_event(struct xwl_seat *xwl_seat)
|
||||||
{
|
{
|
||||||
ValuatorMask mask;
|
ValuatorMask mask;
|
||||||
|
|
||||||
if (xwl_seat->pending_pointer_event.has_absolute) {
|
if (xwl_seat->pending_pointer_event.has_absolute ||
|
||||||
int sx;
|
xwl_seat->pending_pointer_event.has_relative) {
|
||||||
int sy;
|
int x;
|
||||||
int dx;
|
int y;
|
||||||
int dy;
|
|
||||||
|
|
||||||
sx = wl_fixed_to_int(xwl_seat->pending_pointer_event.x);
|
if (xwl_seat->pending_pointer_event.has_absolute) {
|
||||||
sy = wl_fixed_to_int(xwl_seat->pending_pointer_event.y);
|
int sx = wl_fixed_to_int(xwl_seat->pending_pointer_event.x);
|
||||||
dx = xwl_seat->focus_window->window->drawable.x;
|
int sy = wl_fixed_to_int(xwl_seat->pending_pointer_event.y);
|
||||||
dy = xwl_seat->focus_window->window->drawable.y;
|
int dx = xwl_seat->focus_window->window->drawable.x;
|
||||||
|
int dy = xwl_seat->focus_window->window->drawable.y;
|
||||||
|
|
||||||
|
x = dx + sx;
|
||||||
|
y = dy + sy;
|
||||||
|
} else {
|
||||||
|
miPointerGetPosition(xwl_seat->pointer, &x, &y);
|
||||||
|
}
|
||||||
|
|
||||||
valuator_mask_zero(&mask);
|
valuator_mask_zero(&mask);
|
||||||
valuator_mask_set(&mask, 0, dx + sx);
|
if (xwl_seat->pending_pointer_event.has_relative) {
|
||||||
valuator_mask_set(&mask, 1, dy + sy);
|
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_set(&mask, 0, x);
|
||||||
|
valuator_mask_set(&mask, 1, y);
|
||||||
|
}
|
||||||
|
|
||||||
QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0,
|
QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0,
|
||||||
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
|
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
xwl_seat->pending_pointer_event.has_absolute = FALSE;
|
xwl_seat->pending_pointer_event.has_absolute = FALSE;
|
||||||
|
xwl_seat->pending_pointer_event.has_relative = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -387,7 +404,7 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer,
|
||||||
xwl_seat->pending_pointer_event.y = sy_w;
|
xwl_seat->pending_pointer_event.y = sy_w;
|
||||||
|
|
||||||
if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5)
|
if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5)
|
||||||
dispatch_pointer_event(xwl_seat);
|
dispatch_pointer_motion_event(xwl_seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -452,7 +469,7 @@ pointer_handle_frame(void *data, struct wl_pointer *wl_pointer)
|
||||||
{
|
{
|
||||||
struct xwl_seat *xwl_seat = data;
|
struct xwl_seat *xwl_seat = data;
|
||||||
|
|
||||||
dispatch_pointer_event(xwl_seat);
|
dispatch_pointer_motion_event(xwl_seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -484,6 +501,32 @@ static const struct wl_pointer_listener pointer_listener = {
|
||||||
pointer_handle_axis_discrete,
|
pointer_handle_axis_discrete,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
relative_pointer_handle_relative_motion(void *data,
|
||||||
|
struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1,
|
||||||
|
uint32_t utime_hi,
|
||||||
|
uint32_t utime_lo,
|
||||||
|
wl_fixed_t dxf,
|
||||||
|
wl_fixed_t dyf,
|
||||||
|
wl_fixed_t dx_unaccelf,
|
||||||
|
wl_fixed_t dy_unaccelf)
|
||||||
|
{
|
||||||
|
struct xwl_seat *xwl_seat = data;
|
||||||
|
|
||||||
|
xwl_seat->pending_pointer_event.has_relative = TRUE;
|
||||||
|
xwl_seat->pending_pointer_event.dx = wl_fixed_to_double(dxf);
|
||||||
|
xwl_seat->pending_pointer_event.dy = wl_fixed_to_double(dyf);
|
||||||
|
xwl_seat->pending_pointer_event.dx_unaccel = wl_fixed_to_double(dx_unaccelf);
|
||||||
|
xwl_seat->pending_pointer_event.dy_unaccel = wl_fixed_to_double(dy_unaccelf);
|
||||||
|
|
||||||
|
if (wl_proxy_get_version((struct wl_proxy *) xwl_seat->wl_pointer) < 5)
|
||||||
|
dispatch_pointer_motion_event(xwl_seat);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
|
||||||
|
relative_pointer_handle_relative_motion,
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
|
keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
|
||||||
uint32_t time, uint32_t key, uint32_t state)
|
uint32_t time, uint32_t key, uint32_t state)
|
||||||
|
@ -905,6 +948,18 @@ release_pointer(struct xwl_seat *xwl_seat)
|
||||||
static void
|
static void
|
||||||
init_relative_pointer(struct xwl_seat *xwl_seat)
|
init_relative_pointer(struct xwl_seat *xwl_seat)
|
||||||
{
|
{
|
||||||
|
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager =
|
||||||
|
xwl_seat->xwl_screen->relative_pointer_manager;
|
||||||
|
|
||||||
|
if (relative_pointer_manager) {
|
||||||
|
xwl_seat->wp_relative_pointer =
|
||||||
|
zwp_relative_pointer_manager_v1_get_relative_pointer(
|
||||||
|
relative_pointer_manager, xwl_seat->wl_pointer);
|
||||||
|
zwp_relative_pointer_v1_add_listener(xwl_seat->wp_relative_pointer,
|
||||||
|
&relative_pointer_listener,
|
||||||
|
xwl_seat);
|
||||||
|
}
|
||||||
|
|
||||||
if (xwl_seat->relative_pointer == NULL) {
|
if (xwl_seat->relative_pointer == NULL) {
|
||||||
xwl_seat->relative_pointer =
|
xwl_seat->relative_pointer =
|
||||||
add_device(xwl_seat, "xwayland-relative-pointer",
|
add_device(xwl_seat, "xwayland-relative-pointer",
|
||||||
|
@ -917,6 +972,11 @@ init_relative_pointer(struct xwl_seat *xwl_seat)
|
||||||
static void
|
static void
|
||||||
release_relative_pointer(struct xwl_seat *xwl_seat)
|
release_relative_pointer(struct xwl_seat *xwl_seat)
|
||||||
{
|
{
|
||||||
|
if (xwl_seat->wp_relative_pointer) {
|
||||||
|
zwp_relative_pointer_v1_destroy(xwl_seat->wp_relative_pointer);
|
||||||
|
xwl_seat->wp_relative_pointer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (xwl_seat->relative_pointer)
|
if (xwl_seat->relative_pointer)
|
||||||
DisableDevice(xwl_seat->relative_pointer, TRUE);
|
DisableDevice(xwl_seat->relative_pointer, TRUE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@ struct xwl_seat {
|
||||||
struct xwl_screen *xwl_screen;
|
struct xwl_screen *xwl_screen;
|
||||||
struct wl_seat *seat;
|
struct wl_seat *seat;
|
||||||
struct wl_pointer *wl_pointer;
|
struct wl_pointer *wl_pointer;
|
||||||
|
struct zwp_relative_pointer_v1 *wp_relative_pointer;
|
||||||
struct wl_keyboard *wl_keyboard;
|
struct wl_keyboard *wl_keyboard;
|
||||||
struct wl_touch *wl_touch;
|
struct wl_touch *wl_touch;
|
||||||
struct wl_array keys;
|
struct wl_array keys;
|
||||||
|
@ -151,6 +152,12 @@ struct xwl_seat {
|
||||||
Bool has_absolute;
|
Bool has_absolute;
|
||||||
wl_fixed_t x;
|
wl_fixed_t x;
|
||||||
wl_fixed_t y;
|
wl_fixed_t y;
|
||||||
|
|
||||||
|
Bool has_relative;
|
||||||
|
double dx;
|
||||||
|
double dy;
|
||||||
|
double dx_unaccel;
|
||||||
|
double dy_unaccel;
|
||||||
} pending_pointer_event;
|
} pending_pointer_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user