diff options
author | Reza Jelveh <[email protected]> | 2024-04-15 13:39:41 +0800 |
---|---|---|
committer | GitHub <[email protected]> | 2024-04-15 01:39:41 -0400 |
commit | fb86ed6b0588dfdebfb66ce875bc63cfa0a897f6 (patch) | |
tree | 29857a1769107adc58696f08d379f608aa4e29a2 /sway/input/seatop_down.c | |
parent | a5e79676c4bd22fc5902182acf0667907202a465 (diff) |
feat: 1.9 merge (#277)
Co-authored-by: William McKinnon <[email protected]>
Co-authored-by: Erik Reider <[email protected]>
Diffstat (limited to 'sway/input/seatop_down.c')
-rw-r--r-- | sway/input/seatop_down.c | 131 |
1 files changed, 126 insertions, 5 deletions
diff --git a/sway/input/seatop_down.c b/sway/input/seatop_down.c index b40773d0..36f9bb60 100644 --- a/sway/input/seatop_down.c +++ b/sway/input/seatop_down.c @@ -2,12 +2,20 @@ #include <float.h> #include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_tablet_v2.h> +#include <wlr/types/wlr_touch.h> #include "sway/input/cursor.h" #include "sway/input/seat.h" #include "sway/tree/view.h" #include "sway/desktop/transaction.h" #include "log.h" +struct seatop_touch_point_event { + double ref_lx, ref_ly; // touch's x/y at start of op + double ref_con_lx, ref_con_ly; // container's x/y at start of op + int32_t touch_id; + struct wl_list link; +}; + struct seatop_down_event { struct sway_container *con; struct sway_seat *seat; @@ -15,8 +23,109 @@ struct seatop_down_event { struct wlr_surface *surface; double ref_lx, ref_ly; // cursor's x/y at start of op double ref_con_lx, ref_con_ly; // container's x/y at start of op + struct wl_list point_events; // seatop_touch_point_event::link }; +static void handle_touch_motion(struct sway_seat *seat, + struct wlr_touch_motion_event *event, double lx, double ly) { + struct seatop_down_event *e = seat->seatop_data; + + struct seatop_touch_point_event *point_event; + bool found = false; + wl_list_for_each(point_event, &e->point_events, link) { + if (point_event->touch_id == event->touch_id) { + found = true; + break; + } + } + if (!found) { + return; // Probably not a point_event from this seatop_down + } + + double moved_x = lx - point_event->ref_lx; + double moved_y = ly - point_event->ref_ly; + double sx = point_event->ref_con_lx + moved_x; + double sy = point_event->ref_con_ly + moved_y; + + wlr_seat_touch_notify_motion(seat->wlr_seat, event->time_msec, + event->touch_id, sx, sy); +} + +static void handle_touch_up(struct sway_seat *seat, + struct wlr_touch_up_event *event) { + struct seatop_down_event *e = seat->seatop_data; + struct seatop_touch_point_event *point_event, *tmp; + + wl_list_for_each_safe(point_event, tmp, &e->point_events, link) { + if (point_event->touch_id == event->touch_id) { + wl_list_remove(&point_event->link); + free(point_event); + break; + } + } + + wlr_seat_touch_notify_up(seat->wlr_seat, event->time_msec, event->touch_id); + + if (wl_list_empty(&e->point_events)) { + seatop_begin_default(seat); + } +} + +static void handle_touch_down(struct sway_seat *seat, + struct wlr_touch_down_event *event, double lx, double ly) { + struct seatop_down_event *e = seat->seatop_data; + double sx, sy; + struct wlr_surface *surface = NULL; + struct sway_node *focused_node = node_at_coords(seat, seat->touch_x, + seat->touch_y, &surface, &sx, &sy); + + if (!surface || surface != e->surface) { // Must start from the initial surface + return; + } + + struct seatop_touch_point_event *point_event = + calloc(1, sizeof(struct seatop_touch_point_event)); + if (!sway_assert(point_event, "Unable to allocate point_event")) { + return; + } + point_event->touch_id = event->touch_id; + point_event->ref_lx = lx; + point_event->ref_ly = ly; + point_event->ref_con_lx = sx; + point_event->ref_con_ly = sy; + + wl_list_insert(&e->point_events, &point_event->link); + + wlr_seat_touch_notify_down(seat->wlr_seat, surface, event->time_msec, + event->touch_id, sx, sy); + + if (focused_node) { + seat_set_focus(seat, focused_node); + } +} + +static void handle_touch_cancel(struct sway_seat *seat, + struct wlr_touch_cancel_event *event) { + struct seatop_down_event *e = seat->seatop_data; + struct seatop_touch_point_event *point_event, *tmp; + + wl_list_for_each_safe(point_event, tmp, &e->point_events, link) { + if (point_event->touch_id == event->touch_id) { + wl_list_remove(&point_event->link); + free(point_event); + break; + } + } + + if (e->surface) { + wlr_seat_touch_notify_cancel(seat->wlr_seat, e->surface); + } + + if (wl_list_empty(&e->point_events)) { + seatop_begin_default(seat); + } +} + static void handle_pointer_axis(struct sway_seat *seat, struct wlr_pointer_axis_event *event) { struct sway_input_device *input_device = @@ -28,7 +137,7 @@ static void handle_pointer_axis(struct sway_seat *seat, wlr_seat_pointer_notify_axis(seat->wlr_seat, event->time_msec, event->orientation, scroll_factor * event->delta, - round(scroll_factor * event->delta_discrete), event->source); + roundf(scroll_factor * event->delta_discrete), event->source); } static void handle_button(struct sway_seat *seat, uint32_t time_msec, @@ -99,14 +208,18 @@ 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, + .touch_motion = handle_touch_motion, + .touch_up = handle_touch_up, + .touch_down = handle_touch_down, + .touch_cancel = handle_touch_cancel, .unref = handle_unref, .end = handle_end, .allow_set_cursor = true, }; void seatop_begin_down(struct sway_seat *seat, struct sway_container *con, - uint32_t time_msec, double sx, double sy) { - seatop_begin_down_on_surface(seat, con->view->surface, time_msec, sx, sy); + double sx, double sy) { + seatop_begin_down_on_surface(seat, con->view->surface, sx, sy); struct seatop_down_event *e = seat->seatop_data; e->con = con; @@ -114,13 +227,20 @@ void seatop_begin_down(struct sway_seat *seat, struct sway_container *con, transaction_commit_dirty(); } +void seatop_begin_touch_down(struct sway_seat *seat, + struct wlr_surface *surface, struct wlr_touch_down_event *event, + double sx, double sy, double lx, double ly) { + seatop_begin_down_on_surface(seat, surface, sx, sy); + handle_touch_down(seat, event, lx, ly); +} + void seatop_begin_down_on_surface(struct sway_seat *seat, - struct wlr_surface *surface, uint32_t time_msec, double sx, double sy) { + struct wlr_surface *surface, double sx, double sy) { seatop_end(seat); struct seatop_down_event *e = calloc(1, sizeof(struct seatop_down_event)); - if (!e) { + if (!sway_assert(e, "Unable to allocate e")) { return; } e->con = NULL; @@ -132,6 +252,7 @@ void seatop_begin_down_on_surface(struct sway_seat *seat, e->ref_ly = seat->cursor->cursor->y; e->ref_con_lx = sx; e->ref_con_ly = sy; + wl_list_init(&e->point_events); seat->seatop_impl = &seatop_impl; seat->seatop_data = e; |