@@ -30,6 +30,11 @@ class MenuItem
3030 static bool _callbacksInitialized = false ;
3131
3232 late final native_menu_item_t _nativeHandle;
33+
34+ // Store listener IDs for cleanup
35+ int ? _clickedListenerId;
36+ int ? _submenuOpenedListenerId;
37+ int ? _submenuClosedListenerId;
3338
3439 MenuItem (String label, [MenuItemType type = MenuItemType .normal]) {
3540 final labelPtr = label.toNativeUtf8 ().cast <Char >();
@@ -39,6 +44,12 @@ class MenuItem
3944 );
4045 ffi.calloc.free (labelPtr);
4146
47+ // Store instance in static map using handle address as key
48+ _instances[_nativeHandle.address] = this ;
49+ }
50+
51+ @override
52+ void startEventListening () {
4253 // Initialize callbacks once
4354 if (! _callbacksInitialized) {
4455 _clickedCallback =
@@ -56,30 +67,53 @@ class MenuItem
5667 _callbacksInitialized = true ;
5768 }
5869
59- // Store instance in static map using handle address as key
60- _instances[_nativeHandle.address] = this ;
61-
62- // Register listeners for each event type with native callbacks
63- bindings.native_menu_item_add_listener (
70+ // Register listeners for each event type with native callbacks and store IDs
71+ _clickedListenerId = bindings.native_menu_item_add_listener (
6472 _nativeHandle,
6573 native_menu_item_event_type_t.NATIVE_MENU_ITEM_EVENT_CLICKED ,
6674 _clickedCallback.nativeFunction,
6775 _nativeHandle,
6876 );
69- bindings.native_menu_item_add_listener (
77+ _submenuOpenedListenerId = bindings.native_menu_item_add_listener (
7078 _nativeHandle,
7179 native_menu_item_event_type_t.NATIVE_MENU_ITEM_EVENT_SUBMENU_OPENED ,
7280 _submenuOpenedCallback.nativeFunction,
7381 _nativeHandle,
7482 );
75- bindings.native_menu_item_add_listener (
83+ _submenuClosedListenerId = bindings.native_menu_item_add_listener (
7684 _nativeHandle,
7785 native_menu_item_event_type_t.NATIVE_MENU_ITEM_EVENT_SUBMENU_CLOSED ,
7886 _submenuClosedCallback.nativeFunction,
7987 _nativeHandle,
8088 );
8189 }
8290
91+ @override
92+ void stopEventListening () {
93+ // Remove native listeners using stored IDs
94+ if (_clickedListenerId != null ) {
95+ bindings.native_menu_item_remove_listener (
96+ _nativeHandle,
97+ _clickedListenerId! ,
98+ );
99+ _clickedListenerId = null ;
100+ }
101+ if (_submenuOpenedListenerId != null ) {
102+ bindings.native_menu_item_remove_listener (
103+ _nativeHandle,
104+ _submenuOpenedListenerId! ,
105+ );
106+ _submenuOpenedListenerId = null ;
107+ }
108+ if (_submenuClosedListenerId != null ) {
109+ bindings.native_menu_item_remove_listener (
110+ _nativeHandle,
111+ _submenuClosedListenerId! ,
112+ );
113+ _submenuClosedListenerId = null ;
114+ }
115+ }
116+
83117 // Static callback functions for FFI
84118 static void _nativeOnClickedEvent (
85119 Pointer <Void > event,
@@ -199,24 +233,7 @@ class MenuItem
199233 // Remove instance from static map
200234 _instances.remove (_nativeHandle.address);
201235
202- // // Remove native listeners
203- // bindings.native_menu_item_remove_listener(
204- // _nativeHandle,
205- // native_menu_item_event_type_t.NATIVE_MENU_ITEM_EVENT_CLICKED,
206- // _clickedCallback.nativeFunction,
207- // );
208- // bindings.native_menu_item_remove_listener(
209- // _nativeHandle,
210- // native_menu_item_event_type_t.NATIVE_MENU_ITEM_EVENT_SUBMENU_OPENED,
211- // _submenuOpenedCallback.nativeFunction,
212- // );
213- // bindings.native_menu_item_remove_listener(
214- // _nativeHandle,
215- // native_menu_item_event_type_t.NATIVE_MENU_ITEM_EVENT_SUBMENU_CLOSED,
216- // _submenuClosedCallback.nativeFunction,
217- // );
218-
219- // Dispose event emitter
236+ // Dispose event emitter (will call stopEventListening if needed)
220237 disposeEventEmitter ();
221238
222239 // Destroy native handle
@@ -239,10 +256,20 @@ class Menu
239256 _closedCallback;
240257
241258 static bool _callbacksInitialized = false ;
259+
260+ // Store listener IDs for cleanup
261+ int ? _openedListenerId;
262+ int ? _closedListenerId;
242263
243264 Menu ([native_menu_t? nativeHandle]) {
244265 _nativeHandle = nativeHandle ?? bindings.native_menu_create ();
245266
267+ // Store instance in static map using handle address as key
268+ _instances[_nativeHandle.address] = this ;
269+ }
270+
271+ @override
272+ void startEventListening () {
246273 // Initialize callbacks once
247274 if (! _callbacksInitialized) {
248275 _openedCallback =
@@ -256,24 +283,40 @@ class Menu
256283 _callbacksInitialized = true ;
257284 }
258285
259- // Store instance in static map using handle address as key
260- _instances[_nativeHandle.address] = this ;
261-
262- // Register listeners for each event type with native callbacks
263- bindings.native_menu_add_listener (
286+ // Register listeners for each event type with native callbacks and store IDs
287+ _openedListenerId = bindings.native_menu_add_listener (
264288 _nativeHandle,
265289 native_menu_event_type_t.NATIVE_MENU_EVENT_OPENED ,
266290 _openedCallback.nativeFunction,
267291 _nativeHandle,
268292 );
269- bindings.native_menu_add_listener (
293+ _closedListenerId = bindings.native_menu_add_listener (
270294 _nativeHandle,
271295 native_menu_event_type_t.NATIVE_MENU_EVENT_CLOSED ,
272296 _closedCallback.nativeFunction,
273297 _nativeHandle,
274298 );
275299 }
276300
301+ @override
302+ void stopEventListening () {
303+ // Remove native listeners using stored IDs
304+ if (_openedListenerId != null ) {
305+ bindings.native_menu_remove_listener (
306+ _nativeHandle,
307+ _openedListenerId! ,
308+ );
309+ _openedListenerId = null ;
310+ }
311+ if (_closedListenerId != null ) {
312+ bindings.native_menu_remove_listener (
313+ _nativeHandle,
314+ _closedListenerId! ,
315+ );
316+ _closedListenerId = null ;
317+ }
318+ }
319+
277320 // Static callback functions for FFI
278321 static void _nativeOnOpenedEvent (
279322 Pointer <Void > event,
@@ -374,13 +417,7 @@ class Menu
374417 // Remove instance from static map
375418 _instances.remove (_nativeHandle.address);
376419
377- // // Remove native listeners
378- // bindings.native_menu_remove_listener(
379- // _nativeHandle,
380- // _openedCallback.nativeFunction,
381- // );
382-
383- // Dispose event emitter
420+ // Dispose event emitter (will call stopEventListening if needed)
384421 disposeEventEmitter ();
385422
386423 // Destroy native handle
0 commit comments