types/seat: Clear focus in wlr_seat_destroy()

This fixes use-after-free in surface destroy signal listeners.
This commit is contained in:
Andri Yngvason 2020-12-28 15:10:42 +00:00 committed by Simon Ser
parent 87e216b740
commit e136a4168b
2 changed files with 10 additions and 1 deletions

View file

@ -318,7 +318,8 @@ struct wlr_seat_keyboard_focus_change_event {
*/ */
struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name); struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name);
/** /**
* Destroys a wlr_seat and removes its wl_seat global. * Destroys a wlr_seat, removes its wl_seat global and clears focus for all
* devices belonging to the seat.
*/ */
void wlr_seat_destroy(struct wlr_seat *wlr_seat); void wlr_seat_destroy(struct wlr_seat *wlr_seat);
/** /**

View file

@ -159,6 +159,14 @@ void wlr_seat_destroy(struct wlr_seat *seat) {
return; return;
} }
wlr_seat_pointer_clear_focus(seat);
wlr_seat_keyboard_clear_focus(seat);
struct wlr_touch_point *point;
wl_list_for_each(point, &seat->touch_state.touch_points, link) {
wlr_seat_touch_point_clear_focus(seat, 0, point->touch_id);
}
wlr_signal_emit_safe(&seat->events.destroy, seat); wlr_signal_emit_safe(&seat->events.destroy, seat);
wl_list_remove(&seat->display_destroy.link); wl_list_remove(&seat->display_destroy.link);