From f48fce57dc6f40d8b3992041a715776fe6072dd1 Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Fri, 6 Mar 2026 18:38:21 -0600 Subject: [PATCH] fix(menu): keep popup menus alive after builder teardown The popup menu was retrieved from GtkBuilder and stored in menu_, but the builder was unref'd immediately after construction. That left the later popup path operating on a builder-owned GtkMenu whose lifetime was no longer guaranteed, which matches the GTK_IS_WIDGET and GTK_IS_MENU assertions from the regression report. Take an owned reference to the built menu and release it in AModule teardown so popup menus stay valid without extending the lifetime of the whole builder. Signed-off-by: Austin Horstman --- src/ALabel.cpp | 2 ++ src/AModule.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/ALabel.cpp b/src/ALabel.cpp index fe87e098..795f87f1 100644 --- a/src/ALabel.cpp +++ b/src/ALabel.cpp @@ -100,6 +100,8 @@ ALabel::ALabel(const Json::Value& config, const std::string& name, const std::st g_object_unref(builder); throw std::runtime_error("Failed to get 'menu' object from GtkBuilder"); } + // Keep the menu alive after dropping the transient GtkBuilder. + g_object_ref(menu_); submenus_ = std::map(); menuActionsMap_ = std::map(); diff --git a/src/AModule.cpp b/src/AModule.cpp index 5f3a187a..a5ba69d3 100644 --- a/src/AModule.cpp +++ b/src/AModule.cpp @@ -88,6 +88,10 @@ AModule::~AModule() { killpg(pid, SIGTERM); } } + if (menu_ != nullptr) { + g_object_unref(menu_); + menu_ = nullptr; + } } auto AModule::update() -> void {