diff --git a/libweston/desktop/internal.h b/libweston/desktop/internal.h index afbe31adc..1170021c5 100644 --- a/libweston/desktop/internal.h +++ b/libweston/desktop/internal.h @@ -227,6 +227,12 @@ weston_desktop_surface_popup_ungrab(struct weston_desktop_surface *popup, void weston_desktop_surface_popup_dismiss(struct weston_desktop_surface *surface); +struct wl_list * +weston_desktop_surface_get_grab_seat_list(struct weston_desktop_surface *surface); + +void +weston_desktop_seat_end_grabs_on_seats(struct wl_list *list); + struct weston_desktop_surface * weston_desktop_seat_popup_grab_get_topmost_surface(struct weston_desktop_seat *seat); bool diff --git a/libweston/desktop/seat.c b/libweston/desktop/seat.c index b398e79fd..d45719de0 100644 --- a/libweston/desktop/seat.c +++ b/libweston/desktop/seat.c @@ -47,6 +47,7 @@ struct weston_desktop_seat { bool initial_up; struct wl_client *client; struct wl_list surfaces; + struct wl_list grab_surface_link; struct weston_desktop_surface *grab_surface; struct wl_listener grab_surface_destroy_listener; } popup_grab; @@ -387,6 +388,25 @@ weston_desktop_seat_popup_grab_get_topmost_surface(struct weston_desktop_seat *s return weston_desktop_surface_from_grab_link(grab_link); } +static void +weston_desktop_seat_set_grab_surface(struct weston_desktop_seat *seat, + struct weston_desktop_surface *surface) +{ + struct wl_list *list; + + list = weston_desktop_surface_get_grab_seat_list(surface); + wl_list_insert(list->prev, &seat->popup_grab.grab_surface_link); + seat->popup_grab.grab_surface = surface; +} + +static void +weston_desktop_seat_clear_grab_surface(struct weston_desktop_seat *seat) +{ + wl_list_remove(&seat->popup_grab.grab_surface_link); + wl_list_init(&seat->popup_grab.grab_surface_link); + seat->popup_grab.grab_surface = NULL; +} + static void popup_grab_grab_surface_destroy(struct wl_listener *listener, void *data) { @@ -394,7 +414,7 @@ popup_grab_grab_surface_destroy(struct wl_listener *listener, void *data) wl_container_of(listener, seat, popup_grab.grab_surface_destroy_listener); - seat->popup_grab.grab_surface = NULL; + weston_desktop_seat_clear_grab_surface(seat); } bool @@ -447,7 +467,7 @@ weston_desktop_seat_popup_grab_start(struct weston_desktop_seat *seat, struct weston_surface *parent_surface; weston_keyboard_start_grab(keyboard, &seat->popup_grab.keyboard); - seat->popup_grab.grab_surface = parent; + weston_desktop_seat_set_grab_surface(seat, parent); parent_surface = weston_desktop_surface_get_surface(parent); seat->popup_grab.grab_surface_destroy_listener.notify = @@ -516,7 +536,7 @@ weston_desktop_seat_popup_grab_end(struct weston_desktop_seat *seat) seat->popup_grab.client = NULL; if (seat->popup_grab.grab_surface) { - seat->popup_grab.grab_surface = NULL; + weston_desktop_seat_clear_grab_surface(seat); wl_list_remove(&seat->popup_grab.grab_surface_destroy_listener.link); } } @@ -573,3 +593,13 @@ weston_seat_break_desktop_grabs(struct weston_seat *wseat) weston_desktop_seat_popup_grab_end(seat); } + +void +weston_desktop_seat_end_grabs_on_seats(struct wl_list *list) +{ + struct weston_desktop_seat *seat, *next; + + wl_list_for_each_safe(seat, next, list, popup_grab.grab_surface_link) + weston_desktop_seat_popup_grab_end(seat); + +} diff --git a/libweston/desktop/surface.c b/libweston/desktop/surface.c index 44a33c306..28ef55cbe 100644 --- a/libweston/desktop/surface.c +++ b/libweston/desktop/surface.c @@ -75,6 +75,7 @@ struct weston_desktop_surface { struct { struct wl_list grab_link; }; + struct wl_list grabbing_seats; }; static void @@ -175,6 +176,8 @@ weston_desktop_surface_destroy(struct weston_desktop_surface *surface) wl_list_for_each_safe(view, next_view, &surface->view_list, link) weston_desktop_view_destroy(view); + weston_desktop_seat_end_grabs_on_seats(&surface->grabbing_seats); + free(surface->title); free(surface->app_id); @@ -304,6 +307,7 @@ weston_desktop_surface_create(struct weston_desktop *desktop, wl_list_init(&surface->children_link); wl_list_init(&surface->view_list); wl_list_init(&surface->grab_link); + wl_list_init(&surface->grabbing_seats); wl_signal_init(&surface->metadata_signal); @@ -884,6 +888,12 @@ weston_desktop_surface_popup_dismiss(struct weston_desktop_surface *surface) weston_desktop_surface_close(surface); } +struct wl_list * +weston_desktop_surface_get_grab_seat_list(struct weston_desktop_surface *surface) +{ + return &surface->grabbing_seats; +} + WL_EXPORT void weston_desktop_surface_foreach_child(struct weston_desktop_surface *surface, void (* callback)(struct weston_desktop_surface *child,