From 55b495f3981aab0b0af825cca594324a2f24fbb2 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Thu, 7 Aug 2025 15:27:12 -0400 Subject: [PATCH] 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. --- src/foreign-toplevel/ext-foreign.c | 16 +++++++++------- src/foreign-toplevel/wlr-foreign.c | 28 +++++++++++++++------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/foreign-toplevel/ext-foreign.c b/src/foreign-toplevel/ext-foreign.c index e959b626..e6c27fef 100644 --- a/src/foreign-toplevel/ext-foreign.c +++ b/src/foreign-toplevel/ext-foreign.c @@ -15,6 +15,14 @@ handle_handle_destroy(struct wl_listener *listener, void *data) /* Client side requests */ 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; } @@ -60,14 +68,8 @@ handle_toplevel_destroy(struct wl_listener *listener, void *data) return; } + /* invokes handle_handle_destroy() which does more cleanup */ 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 */ diff --git a/src/foreign-toplevel/wlr-foreign.c b/src/foreign-toplevel/wlr-foreign.c index 7c915ac4..8252abf3 100644 --- a/src/foreign-toplevel/wlr-foreign.c +++ b/src/foreign-toplevel/wlr-foreign.c @@ -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_close.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; } @@ -203,20 +217,8 @@ handle_toplevel_destroy(struct wl_listener *listener, void *data) listener, wlr_toplevel, on_foreign_toplevel.toplevel_destroy); assert(wlr_toplevel->handle); + /* invokes handle_handle_destroy() which does more cleanup */ 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 */