foreign-toplevel: disconnect internal signals from handle_handle_destroy()

If the handle gets destroyed from the wlroots side before the view
is destroyed, the internal signals (emitted from the view) are not
disconnected and will assert() if invoked.
This commit is contained in:
John Lindgren 2025-08-07 15:27:12 -04:00
parent e530f43708
commit 90df5269dc
2 changed files with 24 additions and 20 deletions

View file

@ -15,6 +15,14 @@ handle_handle_destroy(struct wl_listener *listener, void *data)
/* Client side requests */ /* Client side requests */
wl_list_remove(&ext_toplevel->on.handle_destroy.link); wl_list_remove(&ext_toplevel->on.handle_destroy.link);
/* Compositor side state changes */
wl_list_remove(&ext_toplevel->on_view.new_app_id.link);
wl_list_remove(&ext_toplevel->on_view.new_title.link);
/* Internal signals */
wl_list_remove(&ext_toplevel->on_foreign_toplevel.toplevel_destroy.link);
ext_toplevel->handle = NULL; ext_toplevel->handle = NULL;
} }
@ -60,14 +68,8 @@ handle_toplevel_destroy(struct wl_listener *listener, void *data)
return; return;
} }
/* invokes handle_handle_destroy() which does more cleanup */
wlr_ext_foreign_toplevel_handle_v1_destroy(ext_toplevel->handle); wlr_ext_foreign_toplevel_handle_v1_destroy(ext_toplevel->handle);
/* Compositor side state changes */
wl_list_remove(&ext_toplevel->on_view.new_app_id.link);
wl_list_remove(&ext_toplevel->on_view.new_title.link);
/* Internal signals */
wl_list_remove(&ext_toplevel->on_foreign_toplevel.toplevel_destroy.link);
} }
/* Internal API */ /* Internal API */

View file

@ -72,6 +72,20 @@ handle_handle_destroy(struct wl_listener *listener, void *data)
wl_list_remove(&wlr_toplevel->on.request_activate.link); wl_list_remove(&wlr_toplevel->on.request_activate.link);
wl_list_remove(&wlr_toplevel->on.request_close.link); wl_list_remove(&wlr_toplevel->on.request_close.link);
wl_list_remove(&wlr_toplevel->on.handle_destroy.link); wl_list_remove(&wlr_toplevel->on.handle_destroy.link);
/* Compositor side state changes */
wl_list_remove(&wlr_toplevel->on_view.new_app_id.link);
wl_list_remove(&wlr_toplevel->on_view.new_title.link);
wl_list_remove(&wlr_toplevel->on_view.new_outputs.link);
wl_list_remove(&wlr_toplevel->on_view.maximized.link);
wl_list_remove(&wlr_toplevel->on_view.minimized.link);
wl_list_remove(&wlr_toplevel->on_view.fullscreened.link);
wl_list_remove(&wlr_toplevel->on_view.activated.link);
/* Internal signals */
wl_list_remove(&wlr_toplevel->on_foreign_toplevel.toplevel_parent.link);
wl_list_remove(&wlr_toplevel->on_foreign_toplevel.toplevel_destroy.link);
wlr_toplevel->handle = NULL; wlr_toplevel->handle = NULL;
} }
@ -203,20 +217,8 @@ handle_toplevel_destroy(struct wl_listener *listener, void *data)
listener, wlr_toplevel, on_foreign_toplevel.toplevel_destroy); listener, wlr_toplevel, on_foreign_toplevel.toplevel_destroy);
assert(wlr_toplevel->handle); assert(wlr_toplevel->handle);
/* invokes handle_handle_destroy() which does more cleanup */
wlr_foreign_toplevel_handle_v1_destroy(wlr_toplevel->handle); wlr_foreign_toplevel_handle_v1_destroy(wlr_toplevel->handle);
/* Compositor side state changes */
wl_list_remove(&wlr_toplevel->on_view.new_app_id.link);
wl_list_remove(&wlr_toplevel->on_view.new_title.link);
wl_list_remove(&wlr_toplevel->on_view.new_outputs.link);
wl_list_remove(&wlr_toplevel->on_view.maximized.link);
wl_list_remove(&wlr_toplevel->on_view.minimized.link);
wl_list_remove(&wlr_toplevel->on_view.fullscreened.link);
wl_list_remove(&wlr_toplevel->on_view.activated.link);
/* Internal signals */
wl_list_remove(&wlr_toplevel->on_foreign_toplevel.toplevel_parent.link);
wl_list_remove(&wlr_toplevel->on_foreign_toplevel.toplevel_destroy.link);
} }
/* Internal API */ /* Internal API */