Skip to content

Commit f7fd47a

Browse files
committed
Improve cleanup of menu and tray icon references on macOS
1 parent 02ed21d commit f7fd47a

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

src/platform/macos/menu_macos.mm

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ - (void)menuDidClose:(NSMenu *)menu {
164164
}
165165

166166
~Impl() {
167+
// First, clean up submenu reference
168+
if (submenu_) {
169+
submenu_.reset();
170+
}
171+
167172
if (target_) {
168173
// Remove target and action to prevent callbacks after destruction
169174
[ns_menu_item_ setTarget:nil];
@@ -221,8 +226,11 @@ - (void)menuDidClose:(NSMenu *)menu {
221226
}
222227

223228
MenuItem::~MenuItem() {
224-
// Unregister from event registry
225-
g_menu_item_registry.erase(id);
229+
// Safely remove from global registry
230+
auto it = g_menu_item_registry.find(id);
231+
if (it != g_menu_item_registry.end()) {
232+
g_menu_item_registry.erase(it);
233+
}
226234
}
227235

228236
MenuItemType MenuItem::GetType() const {
@@ -445,6 +453,9 @@ - (void)menuDidClose:(NSMenu *)menu {
445453
}
446454

447455
~Impl() {
456+
// First, clear all menu item references
457+
items_.clear();
458+
448459
if (delegate_) {
449460
// Remove delegate to prevent callbacks after destruction
450461
[ns_menu_ setDelegate:nil];
@@ -480,8 +491,11 @@ - (void)menuDidClose:(NSMenu *)menu {
480491
}
481492

482493
Menu::~Menu() {
483-
// Unregister from event registry
484-
g_menu_registry.erase(id);
494+
// Safely remove from global registry
495+
auto it = g_menu_registry.find(id);
496+
if (it != g_menu_registry.end()) {
497+
g_menu_registry.erase(it);
498+
}
485499
}
486500

487501
void Menu::AddItem(std::shared_ptr<MenuItem> item) {

src/platform/macos/tray_icon_macos.mm

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ - (void)statusItemRightClicked:(id)sender;
3939
}
4040

4141
~Impl() {
42+
// First, safely clean up context_menu_
43+
if (context_menu_) {
44+
context_menu_.reset(); // Explicitly reset shared_ptr
45+
}
46+
4247
if (ns_status_item_) {
4348
// Remove target and action to prevent callbacks after destruction
4449
if (ns_status_item_.button) {
@@ -156,6 +161,14 @@ - (void)statusItemRightClicked:(id)sender;
156161
}
157162

158163
void TrayIcon::SetContextMenu(std::shared_ptr<Menu> menu) {
164+
// First, clean up old menu reference
165+
if (pimpl_->context_menu_) {
166+
if (pimpl_->ns_status_item_) {
167+
[pimpl_->ns_status_item_ setMenu:nil];
168+
}
169+
pimpl_->context_menu_.reset();
170+
}
171+
159172
pimpl_->context_menu_ = menu;
160173

161174
// Set the menu as the status item's menu for right-click
@@ -165,9 +178,6 @@ - (void)statusItemRightClicked:(id)sender;
165178
if (nsMenu) {
166179
[pimpl_->ns_status_item_ setMenu:nsMenu];
167180
}
168-
} else if (pimpl_->ns_status_item_) {
169-
// Remove the menu if null is passed
170-
[pimpl_->ns_status_item_ setMenu:nil];
171181
}
172182
}
173183

src/platform/macos/tray_manager_macos.mm

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@
2222

2323
TrayManager::~TrayManager() {
2424
std::lock_guard<std::mutex> lock(mutex_);
25-
// Clean up all managed tray icons
25+
26+
// First, clean up all tray icon menu references to prevent circular references
2627
for (auto& pair : trays_) {
2728
auto tray = pair.second;
2829
if (tray) {
29-
// The TrayIcon destructor will handle cleanup of the NSStatusItem
30+
// Explicitly clear menu references
31+
tray->SetContextMenu(nullptr);
3032
}
3133
}
34+
35+
// Then clear the container
3236
trays_.clear();
3337
}
3438

0 commit comments

Comments
 (0)