mirror of
https://github.com/cage-kiosk/cage.git
synced 2026-03-22 05:34:01 -04:00
fix segfault when exitting cage with a child still present
This commit is contained in:
parent
dcd64ae48b
commit
e32200c9c0
2 changed files with 22 additions and 1 deletions
22
view.c
22
view.c
|
|
@ -112,17 +112,31 @@ view_position_all(struct cg_server *server)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_surface_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct cg_view *view = wl_container_of(listener, view, surface_destroy);
|
||||||
|
/* wlroots is about to free scene_tree via the subsurface tree listener
|
||||||
|
* (registered before us). Null it out so view_unmap() skips the destroy. */
|
||||||
|
view->scene_tree = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
view_unmap(struct cg_view *view)
|
view_unmap(struct cg_view *view)
|
||||||
{
|
{
|
||||||
wl_list_remove(&view->link);
|
wl_list_remove(&view->link);
|
||||||
|
/* Always registered in view_map() before any unmap can fire. */
|
||||||
|
wl_list_remove(&view->surface_destroy.link);
|
||||||
|
|
||||||
wl_list_remove(&view->request_activate.link);
|
wl_list_remove(&view->request_activate.link);
|
||||||
wl_list_remove(&view->request_close.link);
|
wl_list_remove(&view->request_close.link);
|
||||||
wlr_foreign_toplevel_handle_v1_destroy(view->foreign_toplevel_handle);
|
wlr_foreign_toplevel_handle_v1_destroy(view->foreign_toplevel_handle);
|
||||||
view->foreign_toplevel_handle = NULL;
|
view->foreign_toplevel_handle = NULL;
|
||||||
|
|
||||||
wlr_scene_node_destroy(&view->scene_tree->node);
|
if (view->scene_tree) {
|
||||||
|
wlr_scene_node_destroy(&view->scene_tree->node);
|
||||||
|
view->scene_tree = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
view->wlr_surface->data = NULL;
|
view->wlr_surface->data = NULL;
|
||||||
view->wlr_surface = NULL;
|
view->wlr_surface = NULL;
|
||||||
|
|
@ -152,6 +166,12 @@ view_map(struct cg_view *view, struct wlr_surface *surface)
|
||||||
goto fail;
|
goto fail;
|
||||||
view->scene_tree->node.data = view;
|
view->scene_tree->node.data = view;
|
||||||
|
|
||||||
|
/* Register after wlr_scene_subsurface_tree_create() so our listener fires
|
||||||
|
* after wlroots' internal one, which frees scene_tree on surface destroy.
|
||||||
|
* This lets us null scene_tree before view_unmap() tries to use it. */
|
||||||
|
view->surface_destroy.notify = handle_surface_destroy;
|
||||||
|
wl_signal_add(&surface->events.destroy, &view->surface_destroy);
|
||||||
|
|
||||||
view->wlr_surface = surface;
|
view->wlr_surface = surface;
|
||||||
surface->data = view;
|
surface->data = view;
|
||||||
|
|
||||||
|
|
|
||||||
1
view.h
1
view.h
|
|
@ -26,6 +26,7 @@ struct cg_view {
|
||||||
struct wl_list link; // server::views
|
struct wl_list link; // server::views
|
||||||
struct wlr_surface *wlr_surface;
|
struct wlr_surface *wlr_surface;
|
||||||
struct wlr_scene_tree *scene_tree;
|
struct wlr_scene_tree *scene_tree;
|
||||||
|
struct wl_listener surface_destroy; /* nullifies scene_tree when wlroots frees it */
|
||||||
|
|
||||||
/* The view has a position in layout coordinates. */
|
/* The view has a position in layout coordinates. */
|
||||||
int lx, ly;
|
int lx, ly;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue