From: Joshua Ashton Date: Thu, 21 Apr 2022 23:33:44 +0000 (+0000) Subject: view: Refactor view destruction X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=d0b9680d00563cbb1c31f07696fdc6a99a0d66bd;p=proto%2Flabwc.git view: Refactor view destruction Consolidates all of the view destruction code for xwl + xdg into one function. Fixes several notable bugs along the way: - Fixes a crash when alt tabbing when a selected view gets destroyed. - Fixes the OSD not updating to reflect a view has been destroyed. --- diff --git a/include/labwc.h b/include/labwc.h index eaa84c6c..7446348e 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -404,6 +404,8 @@ void view_update_app_id(struct view *view); void view_impl_map(struct view *view); void view_adjust_size(struct view *view, int *w, int *h); +void view_handle_destroy(struct view *view); + void foreign_toplevel_handle_create(struct view *view); /* diff --git a/src/view.c b/src/view.c index d2933d19..6af744c0 100644 --- a/src/view.c +++ b/src/view.c @@ -651,3 +651,63 @@ view_update_app_id(struct view *view) wlr_foreign_toplevel_handle_v1_set_app_id( view->toplevel_handle, app_id); } + +void +view_handle_destroy(struct view *view) +{ + if (view->toplevel_handle) { + wlr_foreign_toplevel_handle_v1_destroy(view->toplevel_handle); + } + interactive_end(view); + + if (view->server->seat.active_view == view) { + view->server->seat.active_view = NULL; + } + + if (view->server->cycle_view == view) { + /* If we are the current OSD selected view, cycle + * to the next because we are dying. */ + view->server->cycle_view = desktop_cycle_view(view->server, + view->server->cycle_view, LAB_CYCLE_DIR_BACKWARD); + + /* If we cycled back to ourselves, then we have no windows. + * just remove it and close the osd for good. */ + if (view->server->cycle_view == view) { + view->server->cycle_view = NULL; + osd_finish(view->server); + } + } else if (view->server->cycle_view != NULL) { + /* If we have an OSD, but are not the cycled view, just + * update the OSD to reflect the view has now gone. */ + osd_update(view->server); + } + + if (view->type == LAB_XDG_SHELL_VIEW) { + view->xdg_surface = NULL; + } +#ifdef HAVE_XWAYLAND + if (view->type == LAB_XWAYLAND_VIEW) { + view->xwayland_surface = NULL; + } +#endif + + wl_list_remove(&view->link); + wl_list_remove(&view->destroy.link); +#ifdef HAVE_XWAYLAND + if (view->type == LAB_XWAYLAND_VIEW) { + wl_list_remove(&view->map.link); + wl_list_remove(&view->unmap.link); + wl_list_remove(&view->request_configure.link); + wl_list_remove(&view->request_maximize.link); + wl_list_remove(&view->request_fullscreen.link); + } +#endif + + if (view->scene_tree) { + ssd_destroy(view); + wlr_scene_node_destroy(&view->scene_tree->node); + view->scene_tree = NULL; + } + + free(view); +} diff --git a/src/xdg.c b/src/xdg.c index 0f11ec3e..e9f3179e 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -78,21 +78,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { struct view *view = wl_container_of(listener, view, destroy); - if (view->toplevel_handle) { - wlr_foreign_toplevel_handle_v1_destroy(view->toplevel_handle); - } - interactive_end(view); - if (view->server->seat.active_view == view) { - view->server->seat.active_view = NULL; - } - wl_list_remove(&view->link); - wl_list_remove(&view->destroy.link); - if (view->scene_tree) { - ssd_destroy(view); - wlr_scene_node_destroy(&view->scene_tree->node); - view->scene_tree = NULL; - } - free(view); + view_handle_destroy(view); } static void diff --git a/src/xwayland.c b/src/xwayland.c index c35f3c21..65b52696 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -96,27 +96,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { struct view *view = wl_container_of(listener, view, destroy); - if (view->toplevel_handle) { - wlr_foreign_toplevel_handle_v1_destroy(view->toplevel_handle); - } - interactive_end(view); - if (view->server->seat.active_view == view) { - view->server->seat.active_view = NULL; - } - view->xwayland_surface = NULL; - wl_list_remove(&view->link); - wl_list_remove(&view->map.link); - wl_list_remove(&view->unmap.link); - wl_list_remove(&view->destroy.link); - wl_list_remove(&view->request_configure.link); - wl_list_remove(&view->request_maximize.link); - wl_list_remove(&view->request_fullscreen.link); - if (view->scene_tree) { - ssd_destroy(view); - wlr_scene_node_destroy(&view->scene_tree->node); - view->scene_tree = NULL; - } - free(view); + view_handle_destroy(view); } static void