From 47e79a78ad1a7cca70f264f76f3b71944dc73272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= Date: Mon, 20 Sep 2021 19:47:38 +0200 Subject: [PATCH] seat: support hi-res clients using hi-res backends When the selected backend supports high-resolution scroll, wlroots will emit the axis_value120 signal. Add the required APIs so wlroots compositors can handle this new events and the default handler implemetion. For the moment, the default implementation does NOT handle clients that don't support high-scroll resolution. --- include/wlr/types/wlr_seat.h | 20 ++++++++++++ types/seat/wlr_seat_pointer.c | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 631b7dd3d..a4c386e09 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -88,6 +88,9 @@ struct wlr_pointer_grab_interface { void (*axis)(struct wlr_seat_pointer_grab *grab, uint32_t time_msec, enum wlr_axis_orientation orientation, double value, int32_t value_discrete, enum wlr_axis_source source); + void (*axis_value120)(struct wlr_seat_pointer_grab *grab, + uint32_t time_msec, enum wlr_axis_orientation orientation, + double delta, int32_t delta_value120, enum wlr_axis_source source); void (*frame)(struct wlr_seat_pointer_grab *grab); void (*cancel)(struct wlr_seat_pointer_grab *grab); }; @@ -394,6 +397,15 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time_msec, enum wlr_axis_orientation orientation, double value, int32_t value_discrete, enum wlr_axis_source source); +/** + * Send a high-resolution axis event to the surface with pointer focus. This + * function does not respect pointer grabs: you probably want + * `wlr_seat_pointer_notify_axis_value120()` instead. + */ +void wlr_seat_pointer_send_axis_value120(struct wlr_seat *wlr_seat, + uint32_t time_msec, enum wlr_axis_orientation orientation, double delta, + int32_t delta_value120, enum wlr_axis_source source); + /** * Send a frame event to the surface with pointer focus. This function does not * respect pointer grabs: you probably want `wlr_seat_pointer_notify_frame()` @@ -445,6 +457,14 @@ void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time_msec, enum wlr_axis_orientation orientation, double value, int32_t value_discrete, enum wlr_axis_source source); +/** + * Notify the seat of a high-resolution axis event. Defers to any grab of the + * pointer. + */ +void wlr_seat_pointer_notify_axis_value120(struct wlr_seat *wlr_seat, + uint32_t time_msec, enum wlr_axis_orientation orientation, double delta, + int32_t delta_value120, enum wlr_axis_source source); + /** * Notify the seat of a frame event. Frame events are sent to end a group of * events that logically belong together. Motion, button and axis events should diff --git a/types/seat/wlr_seat_pointer.c b/types/seat/wlr_seat_pointer.c index c20c52a89..c79ab2e45 100644 --- a/types/seat/wlr_seat_pointer.c +++ b/types/seat/wlr_seat_pointer.c @@ -36,6 +36,13 @@ static void default_pointer_axis(struct wlr_seat_pointer_grab *grab, value_discrete, source); } +static void default_pointer_axis_value120(struct wlr_seat_pointer_grab *grab, + uint32_t time, enum wlr_axis_orientation orientation, double delta, + int32_t delta_value120, enum wlr_axis_source source) { + wlr_seat_pointer_send_axis_value120(grab->seat, time, orientation, delta, + delta_value120, source); +} + static void default_pointer_frame(struct wlr_seat_pointer_grab *grab) { wlr_seat_pointer_send_frame(grab->seat); } @@ -50,6 +57,7 @@ const struct wlr_pointer_grab_interface default_pointer_grab_impl = { .motion = default_pointer_motion, .button = default_pointer_button, .axis = default_pointer_axis, + .axis_value120 = default_pointer_axis_value120, .frame = default_pointer_frame, .cancel = default_pointer_cancel, }; @@ -316,6 +324,50 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time, } } +void wlr_seat_pointer_send_axis_value120(struct wlr_seat *wlr_seat, + uint32_t time, enum wlr_axis_orientation orientation, double delta, + int32_t delta_value120, enum wlr_axis_source source) { + struct wlr_seat_client *client = wlr_seat->pointer_state.focused_client; + if (client == NULL) { + return; + } + + bool send_source = false; + if (wlr_seat->pointer_state.sent_axis_source) { + assert(wlr_seat->pointer_state.cached_axis_source == source); + } else { + wlr_seat->pointer_state.sent_axis_source = true; + wlr_seat->pointer_state.cached_axis_source = source; + send_source = true; + } + + struct wl_resource *resource; + wl_resource_for_each(resource, &client->pointers) { + if (wlr_seat_client_from_pointer_resource(resource) == NULL) { + continue; + } + + uint32_t version = wl_resource_get_version(resource); + + if (send_source && version >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION) { + wl_pointer_send_axis_source(resource, source); + } + if (delta) { + if (delta_value120) { + if (version >= WL_POINTER_AXIS_VALUE120_SINCE_VERSION) { + wl_pointer_send_axis_value120(resource, orientation, + delta_value120); + } + } + + wl_pointer_send_axis(resource, time, orientation, + wl_fixed_from_double(delta)); + } else if (version >= WL_POINTER_AXIS_STOP_SINCE_VERSION) { + wl_pointer_send_axis_stop(resource, time, orientation); + } + } +} + void wlr_seat_pointer_send_frame(struct wlr_seat *wlr_seat) { struct wlr_seat_client *client = wlr_seat->pointer_state.focused_client; if (client == NULL) { @@ -414,6 +466,15 @@ void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time, source); } +void wlr_seat_pointer_notify_axis_value120(struct wlr_seat *wlr_seat, + uint32_t time, enum wlr_axis_orientation orientation, double delta, + int32_t delta_value120, enum wlr_axis_source source) { + clock_gettime(CLOCK_MONOTONIC, &wlr_seat->last_event); + struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab; + grab->interface->axis_value120(grab, time, orientation, delta, + delta_value120, source); +} + void wlr_seat_pointer_notify_frame(struct wlr_seat *wlr_seat) { clock_gettime(CLOCK_MONOTONIC, &wlr_seat->last_event); struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab;