66
77#import < Cocoa/Cocoa.h>
88#import < Foundation/Foundation.h>
9+ #import < objc/runtime.h>
910
1011// Note: This file assumes ARC (Automatic Reference Counting) is enabled
1112// for proper memory management of Objective-C objects.
1516typedef void (^TrayIconRightClickedBlock)(nativeapi::TrayIconId tray_icon_id);
1617typedef void (^TrayIconDoubleClickedBlock)(nativeapi::TrayIconId tray_icon_id);
1718
19+ // Key for associated object to store tray icon ID
20+ static const void * kTrayIconIdKey = &kTrayIconIdKey ;
21+
1822@interface NSStatusBarButtonTarget : NSObject
19- @property (nonatomic , assign ) nativeapi::TrayIcon* trayIcon;
2023@property (nonatomic , copy ) TrayIconClickedBlock leftClickedBlock;
2124@property (nonatomic , copy ) TrayIconRightClickedBlock rightClickedBlock;
2225@property (nonatomic , copy ) TrayIconDoubleClickedBlock doubleClickedBlock;
26+ @property (nonatomic , assign ) nativeapi::TrayIcon* trayIcon;
2327- (void )statusItemClicked : (id )sender ;
2428@end
2529
@@ -33,6 +37,18 @@ - (void)statusItemClicked:(id)sender;
3337 ns_status_bar_button_target_ (nil ),
3438 menu_closed_listener_id_(0 ) {
3539 if (status_item) {
40+ // Check if ID already exists in the associated object
41+ NSNumber * allocatedId = objc_getAssociatedObject (status_item, kTrayIconIdKey );
42+ if (allocatedId) {
43+ // Reuse allocated ID
44+ id_ = [allocatedId longValue ];
45+ } else {
46+ // Allocate new ID and store it
47+ id_ = IdAllocator::Allocate<TrayIcon>();
48+ objc_setAssociatedObject (status_item, kTrayIconIdKey , [NSNumber numberWithLong: id_],
49+ OBJC_ASSOCIATION_RETAIN_NONATOMIC );
50+ }
51+
3652 // Create and set up button target
3753 ns_status_bar_button_target_ = [[NSStatusBarButtonTarget alloc ] init ];
3854 ns_status_bar_button_target_.trayIcon = nullptr ; // Will be set later
@@ -71,6 +87,11 @@ - (void)statusItemClicked:(id)sender;
7187 }
7288 // Clear menu reference
7389 ns_status_item_.menu = nil ;
90+
91+ // Clean up associated object
92+ objc_setAssociatedObject (ns_status_item_, kTrayIconIdKey , nil ,
93+ OBJC_ASSOCIATION_RETAIN_NONATOMIC );
94+
7495 [[NSStatusBar systemStatusBar ] removeStatusItem: ns_status_item_];
7596 ns_status_item_ = nil ;
7697 }
@@ -83,15 +104,15 @@ - (void)statusItemClicked:(id)sender;
83104
84105 NSStatusItem * ns_status_item_;
85106 NSStatusBarButtonTarget* ns_status_bar_button_target_;
107+
108+ TrayIconId id_;
86109 std::shared_ptr<Menu> context_menu_;
87110 size_t menu_closed_listener_id_;
88111};
89112
90113TrayIcon::TrayIcon () : TrayIcon(nullptr ) {}
91114
92115TrayIcon::TrayIcon (void * tray) {
93- id = IdAllocator::Allocate<TrayIcon>();
94-
95116 NSStatusItem * status_item = nullptr ;
96117
97118 if (tray == nullptr ) {
@@ -143,6 +164,10 @@ - (void)statusItemClicked:(id)sender;
143164 }
144165}
145166
167+ TrayIconId TrayIcon::GetId () {
168+ return pimpl_->id_ ;
169+ }
170+
146171void TrayIcon::SetIcon (std::string icon) {
147172 if (!pimpl_->ns_status_item_ || !pimpl_->ns_status_item_ .button ) {
148173 return ;
@@ -354,11 +379,11 @@ @implementation NSStatusBarButtonTarget
354379
355380- (void )statusItemClicked : (id )sender {
356381 // Check if trayIcon is still valid before proceeding
357- if (!_trayIcon )
382+ if (!self. trayIcon )
358383 return ;
359384
360385 // Create a local reference to prevent race conditions
361- nativeapi::TrayIcon* trayIcon = _trayIcon ;
386+ nativeapi::TrayIcon* trayIcon = self. trayIcon ;
362387 if (!trayIcon)
363388 return ;
364389
@@ -372,17 +397,17 @@ - (void)statusItemClicked:(id)sender {
372397 (event.modifierFlags & NSEventModifierFlagControl))) {
373398 // Right click or Ctrl+Left click
374399 if (_rightClickedBlock) {
375- _rightClickedBlock (trayIcon->id );
400+ _rightClickedBlock (trayIcon->GetId () );
376401 }
377402 } else if (event.type == NSEventTypeLeftMouseUp) {
378403 // Check for double click
379404 if (event.clickCount == 2 ) {
380405 if (_doubleClickedBlock) {
381- _doubleClickedBlock (trayIcon->id );
406+ _doubleClickedBlock (trayIcon->GetId () );
382407 }
383408 } else {
384409 if (_leftClickedBlock) {
385- _leftClickedBlock (trayIcon->id , " left" );
410+ _leftClickedBlock (trayIcon->GetId () , " left" );
386411 }
387412 }
388413 }
0 commit comments