From 87a337ecdfb743767bb1ccec9d2dce127aa73c66 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Tue, 9 Jun 2026 07:10:32 +0000 Subject: [PATCH 1/2] Update tray.hpp --- include/modules/sni/tray.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/modules/sni/tray.hpp b/include/modules/sni/tray.hpp index 2996078a..f8b004ce 100644 --- a/include/modules/sni/tray.hpp +++ b/include/modules/sni/tray.hpp @@ -28,6 +28,7 @@ class Tray : public AModule { SNI::Watcher::singleton watcher_; std::vector ignore_list_; SNI::Host host_; + std::vector items_; }; } // namespace waybar::modules::SNI From 1facd4ef95f50d15bc45dcd41fe8d410178a0d1a Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Tue, 9 Jun 2026 07:13:04 +0000 Subject: [PATCH 2/2] Update tray.cpp --- src/modules/sni/tray.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/modules/sni/tray.cpp b/src/modules/sni/tray.cpp index 66c7da75..e4340f77 100644 --- a/src/modules/sni/tray.cpp +++ b/src/modules/sni/tray.cpp @@ -68,6 +68,7 @@ void Tray::onAdd(std::unique_ptr& item) { } else { box_.pack_start(item->event_box); } + items_.push_back(item.get()); spdlog::debug("Tray::onAdd deferred check - checking ignore list"); host_.checkIgnoreList(ignore_list_, std::bind(&Tray::onRemove, this, std::placeholders::_1)); @@ -79,6 +80,7 @@ void Tray::onAdd(std::unique_ptr& item) { void Tray::onRemove(std::unique_ptr& item) { box_.remove(item->event_box); + items_.erase(std::remove(items_.begin(), items_.end(), item.get()), items_.end()); dp.emit(); } @@ -89,9 +91,11 @@ auto Tray::update() -> void { host_.checkIgnoreList(ignore_list_, std::bind(&Tray::onRemove, this, std::placeholders::_1)); } - std::vector children = box_.get_children(); - event_box_.set_visible(std::any_of(children.begin(), children.end(), - [](Gtk::Widget* child) { return child->get_visible(); })); + // Show tray only when items are visible. Iterate the managed items_ list + // instead of box_.get_children() to avoid a use-after-free on raw widget + // pointers that may dangle after items are destroyed asynchronously. + event_box_.set_visible(std::any_of(items_.begin(), items_.end(), + [](Item* item) { return item->event_box.get_visible(); })); AModule::update(); }