From 69ffa4437cc16563601303e5032be768f4b460c7 Mon Sep 17 00:00:00 2001 From: Louis Goyard Date: Tue, 12 Mar 2024 00:10:21 +0900 Subject: [PATCH] tablet: add tablet tool scroll support --- include/sway/input/cursor.h | 1 + include/sway/input/seat.h | 6 ++++++ sway/input/cursor.c | 35 +++++++++++++++++++++++++++++++++++ sway/input/seat.c | 8 ++++++++ sway/input/seatop_default.c | 19 ++++++++++++++++++- sway/input/seatop_down.c | 17 +++++++++++++++++ 6 files changed, 85 insertions(+), 1 deletion(-) diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index 527d0350..10cac12b 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h @@ -63,6 +63,7 @@ struct sway_cursor { struct wl_listener tool_tip; struct wl_listener tool_proximity; struct wl_listener tool_button; + struct wl_listener tool_axis_scroll; bool simulating_pointer_from_tool_tip; bool simulating_pointer_from_tool_button; uint32_t tool_buttons; diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index 475753d8..eb78cea2 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -48,6 +48,8 @@ struct sway_seatop_impl { struct wlr_touch_cancel_event *event); void (*tablet_tool_motion)(struct sway_seat *seat, struct sway_tablet_tool *tool, uint32_t time_msec); + void (*tablet_tool_axis_scroll)(struct sway_seat *seat, + struct sway_tablet_tool *tool, struct wlr_tablet_tool_axis_scroll_event *event); void (*tablet_tool_tip)(struct sway_seat *seat, struct sway_tablet_tool *tool, uint32_t time_msec, enum wlr_tablet_tool_tip_state state); void (*end)(struct sway_seat *seat); @@ -299,6 +301,10 @@ void seatop_pointer_motion(struct sway_seat *seat, uint32_t time_msec); void seatop_pointer_axis(struct sway_seat *seat, struct wlr_pointer_axis_event *event); +void seatop_tablet_tool_axis_scroll(struct sway_seat *seat, + struct sway_tablet_tool *tool, + struct wlr_tablet_tool_axis_scroll_event *event); + void seatop_tablet_tool_tip(struct sway_seat *seat, struct sway_tablet_tool *tool, uint32_t time_msec, enum wlr_tablet_tool_tip_state state); diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 3d04826c..6b828206 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -724,6 +724,38 @@ static void handle_tool_proximity(struct wl_listener *listener, void *data) { 0, 0, event->time_msec); } +static void handle_tool_axis_scroll(struct wl_listener *listener, void *data) { + struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_axis_scroll); + struct wlr_tablet_tool_axis_scroll_event *event = data; + cursor_handle_activity_from_device(cursor, &event->tablet->base); + + struct sway_tablet_tool *sway_tool = event->tool->data; + struct wlr_tablet_v2_tablet *tablet_v2 = sway_tool->tablet->tablet_v2; + struct sway_seat *seat = cursor->seat; + + + double sx, sy; + struct wlr_surface *surface = NULL; + node_at_coords(seat, cursor->cursor->x, cursor->cursor->y, + &surface, &sx, &sy); + + if (surface && wlr_surface_accepts_tablet_v2(tablet_v2, surface)) { + sway_log(SWAY_DEBUG, "axis_scroll, accepts tablet"); + seatop_tablet_tool_axis_scroll(cursor->seat, sway_tool, event); + } else { + struct wlr_pointer_axis_event simulated_pointer_event = { + .pointer = NULL, // FIXME + .time_msec = event->time_msec, + .source = event->source, + .orientation = event->orientation, + .delta = event->delta, + .delta_discrete = 0, + }; + seatop_pointer_axis(cursor->seat, &simulated_pointer_event); + sway_log(SWAY_DEBUG, "axis_scroll, simulating"); + } +} + static void handle_tool_button(struct wl_listener *listener, void *data) { struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_button); struct wlr_tablet_tool_button_event *event = data; @@ -1140,6 +1172,9 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) { wl_signal_add(&wlr_cursor->events.tablet_tool_proximity, &cursor->tool_proximity); cursor->tool_proximity.notify = handle_tool_proximity; + wl_signal_add(&wlr_cursor->events.tablet_tool_axis_scroll, &cursor->tool_axis_scroll); + cursor->tool_axis_scroll.notify = handle_tool_axis_scroll; + wl_signal_add(&wlr_cursor->events.tablet_tool_button, &cursor->tool_button); cursor->tool_button.notify = handle_tool_button; diff --git a/sway/input/seat.c b/sway/input/seat.c index f2486893..df640794 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -1576,6 +1576,14 @@ void seatop_pointer_axis(struct sway_seat *seat, } } +void seatop_tablet_tool_axis_scroll(struct sway_seat *seat, + struct sway_tablet_tool *tool, + struct wlr_tablet_tool_axis_scroll_event *event) { + if (seat->seatop_impl->tablet_tool_axis_scroll) { + seat->seatop_impl->tablet_tool_axis_scroll(seat, tool, event); + } +} + void seatop_touch_motion(struct sway_seat *seat, struct wlr_touch_motion_event *event, double lx, double ly) { if (seat->seatop_impl->touch_motion) { diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c index 0c6f7c5e..2e007ce9 100644 --- a/sway/input/seatop_default.c +++ b/sway/input/seatop_default.c @@ -795,12 +795,28 @@ static void handle_pointer_axis(struct sway_seat *seat, if (!handled) { wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec, - event->orientation, scroll_factor * event->delta, + event->orientation, scroll_factor * event->delta, roundf(scroll_factor * event->delta_discrete), event->source, event->relative_direction); } } +static void handle_tablet_tool_axis_scroll(struct sway_seat *seat, + struct sway_tablet_tool *tool, struct wlr_tablet_tool_axis_scroll_event *event) { + // FIXME: Do nothing except pass it to clients for now + struct sway_input_device *input_device = + event->tablet ? event->tablet->base.data : NULL; + struct input_config *ic = + input_device ? input_device_get_config(input_device) : NULL; + float scroll_factor = + (ic == NULL || ic->scroll_factor == FLT_MIN) ? 1.0f : ic->scroll_factor; + + wlr_tablet_v2_tablet_tool_notify_scroll(tool->tablet_v2_tool, event->time_msec, + event->orientation, scroll_factor * event->delta, + event->source, + event->relative_direction); +} + /*------------------------------------\ * Functions used by gesture support / *----------------------------------*/ @@ -1128,6 +1144,7 @@ static const struct sway_seatop_impl seatop_impl = { .pointer_axis = handle_pointer_axis, .tablet_tool_tip = handle_tablet_tool_tip, .tablet_tool_motion = handle_tablet_tool_motion, + .tablet_tool_axis_scroll = handle_tablet_tool_axis_scroll, .hold_begin = handle_hold_begin, .hold_end = handle_hold_end, .pinch_begin = handle_pinch_begin, diff --git a/sway/input/seatop_down.c b/sway/input/seatop_down.c index 35fd3bcb..91e0274c 100644 --- a/sway/input/seatop_down.c +++ b/sway/input/seatop_down.c @@ -140,6 +140,22 @@ static void handle_pointer_axis(struct sway_seat *seat, event->relative_direction); } +static void handle_tablet_tool_axis_scroll(struct sway_seat *seat, + struct sway_tablet_tool *tool, struct wlr_tablet_tool_axis_scroll_event *event) { + struct sway_input_device *input_device = + event->tablet ? event->tablet->base.data : NULL; + struct input_config *ic = + input_device ? input_device_get_config(input_device) : NULL; + float scroll_factor = + (ic == NULL || ic->scroll_factor == FLT_MIN) ? 1.0f : ic->scroll_factor; + + wlr_tablet_v2_tablet_tool_notify_scroll(tool->tablet_v2_tool, event->time_msec, + event->orientation, scroll_factor * event->delta, + event->source, + event->relative_direction); + seatop_begin_default(seat); +} + static void handle_button(struct sway_seat *seat, uint32_t time_msec, struct wlr_input_device *device, uint32_t button, enum wl_pointer_button_state state) { @@ -208,6 +224,7 @@ static const struct sway_seatop_impl seatop_impl = { .pointer_axis = handle_pointer_axis, .tablet_tool_tip = handle_tablet_tool_tip, .tablet_tool_motion = handle_tablet_tool_motion, + .tablet_tool_axis_scroll = handle_tablet_tool_axis_scroll, .touch_motion = handle_touch_motion, .touch_up = handle_touch_up, .touch_down = handle_touch_down,