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;