diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index b34d4a722..6ee9e44d5 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 2142a83b4..195928a3b 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 69b4cfe19..460cfbc7f 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 };