From b934fbaf046126705b96e5253551ccab64a72320 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 30 Jun 2021 13:09:45 +0200 Subject: [PATCH] seat: add wlr_seat_touch_{send,notify}_frame The wl_touch.frame event is used to group multiple touch events together. Instead of sending it immediately after each touch event, rely on the backend to send it (and on the compositor to relay it). This is a breaking change because compositors now need to manually send touch frame events instead of relying on wlr_seat to do it. --- include/wlr/types/wlr_seat.h | 8 +++++++- types/seat/wlr_seat_touch.c | 36 ++++++++++++++++++++++++++++++--- types/xdg_shell/wlr_xdg_popup.c | 5 +++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index b34d4a72..6ee9e44d 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -52,11 +52,12 @@ struct wlr_seat_client { // set of serials which were sent to the client on this seat // for use by wlr_seat_client_{next_serial,validate_event_serial} struct wlr_serial_ringset serials; + bool needs_touch_frame; }; struct wlr_touch_point { int32_t touch_id; - struct wlr_surface *surface; + struct wlr_surface *surface; // may be NULL if destroyed struct wlr_seat_client *client; struct wlr_surface *focus_surface; @@ -116,6 +117,7 @@ struct wlr_touch_grab_interface { struct wlr_touch_point *point); void (*enter)(struct wlr_seat_touch_grab *grab, uint32_t time_msec, struct wlr_touch_point *point); + void (*frame)(struct wlr_seat_touch_grab *grab); // XXX this will conflict with the actual touch cancel which is different so // we need to rename this void (*cancel)(struct wlr_seat_touch_grab *grab); @@ -607,6 +609,8 @@ void wlr_seat_touch_send_up(struct wlr_seat *seat, uint32_t time_msec, void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time_msec, int32_t touch_id, double sx, double sy); +void wlr_seat_touch_send_frame(struct wlr_seat *seat); + /** * Notify the seat of a touch down on the given surface. Defers to any grab of * the touch device. @@ -631,6 +635,8 @@ void wlr_seat_touch_notify_up(struct wlr_seat *seat, uint32_t time_msec, void wlr_seat_touch_notify_motion(struct wlr_seat *seat, uint32_t time_msec, int32_t touch_id, double sx, double sy); +void wlr_seat_touch_notify_frame(struct wlr_seat *seat); + /** * How many touch points are currently down for the seat. */ diff --git a/types/seat/wlr_seat_touch.c b/types/seat/wlr_seat_touch.c index 2142a83b..195928a3 100644 --- a/types/seat/wlr_seat_touch.c +++ b/types/seat/wlr_seat_touch.c @@ -33,6 +33,10 @@ static void default_touch_enter(struct wlr_seat_touch_grab *grab, // not handled by default } +static void default_touch_frame(struct wlr_seat_touch_grab *grab) { + wlr_seat_touch_send_frame(grab->seat); +} + static void default_touch_cancel(struct wlr_seat_touch_grab *grab) { // cannot be cancelled } @@ -42,6 +46,7 @@ const struct wlr_touch_grab_interface default_touch_grab_impl = { .up = default_touch_up, .motion = default_touch_motion, .enter = default_touch_enter, + .frame = default_touch_frame, .cancel = default_touch_cancel, }; @@ -226,6 +231,13 @@ void wlr_seat_touch_notify_motion(struct wlr_seat *seat, uint32_t time, grab->interface->motion(grab, time, point); } +void wlr_seat_touch_notify_frame(struct wlr_seat *seat) { + struct wlr_seat_touch_grab *grab = seat->touch_state.grab; + if (grab->interface->frame) { + grab->interface->frame(grab); + } +} + static void handle_point_focus_destroy(struct wl_listener *listener, void *data) { struct wlr_touch_point *point = @@ -303,9 +315,10 @@ uint32_t wlr_seat_touch_send_down(struct wlr_seat *seat, } wl_touch_send_down(resource, serial, time, surface->resource, touch_id, wl_fixed_from_double(sx), wl_fixed_from_double(sy)); - wl_touch_send_frame(resource); } + point->client->needs_touch_frame = true; + return serial; } @@ -323,8 +336,9 @@ void wlr_seat_touch_send_up(struct wlr_seat *seat, uint32_t time, int32_t touch_ continue; } wl_touch_send_up(resource, serial, time, touch_id); - wl_touch_send_frame(resource); } + + point->client->needs_touch_frame = true; } void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time, int32_t touch_id, @@ -342,7 +356,23 @@ void wlr_seat_touch_send_motion(struct wlr_seat *seat, uint32_t time, int32_t to } wl_touch_send_motion(resource, time, touch_id, wl_fixed_from_double(sx), wl_fixed_from_double(sy)); - wl_touch_send_frame(resource); + } + + point->client->needs_touch_frame = true; +} + +void wlr_seat_touch_send_frame(struct wlr_seat *seat) { + struct wlr_seat_client *seat_client; + wl_list_for_each(seat_client, &seat->clients, link) { + if (!seat_client->needs_touch_frame) { + continue; + } + + struct wl_resource *resource; + wl_resource_for_each(resource, &seat_client->touches) { + wl_touch_send_frame(resource); + } + seat_client->needs_touch_frame = false; } } diff --git a/types/xdg_shell/wlr_xdg_popup.c b/types/xdg_shell/wlr_xdg_popup.c index 69b4cfe1..460cfbc7 100644 --- a/types/xdg_shell/wlr_xdg_popup.c +++ b/types/xdg_shell/wlr_xdg_popup.c @@ -131,6 +131,10 @@ static void xdg_touch_grab_enter(struct wlr_seat_touch_grab *grab, uint32_t time, struct wlr_touch_point *point) { } +static void xdg_touch_grab_frame(struct wlr_seat_touch_grab *grab) { + wlr_seat_touch_send_frame(grab->seat); +} + static void xdg_touch_grab_cancel(struct wlr_seat_touch_grab *grab) { wlr_seat_touch_end_grab(grab->seat); } @@ -140,6 +144,7 @@ static const struct wlr_touch_grab_interface xdg_touch_grab_impl = { .up = xdg_touch_grab_up, .motion = xdg_touch_grab_motion, .enter = xdg_touch_grab_enter, + .frame = xdg_touch_grab_frame, .cancel = xdg_touch_grab_cancel };