fix(macos): manually retain/release NSMenu reference (#84)

* fix(macos): manually retain/release NSMenu reference

* Update src/platform_impl/macos/mod.rs

* retain submenu nsmenu

* remove unused
This commit is contained in:
Lucas Fernandes Nogueira 2023-08-03 06:32:43 -07:00 committed by GitHub
parent 50d388f929
commit 0bad3aca96
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 5 deletions

View file

@ -0,0 +1,5 @@
---
"muda": patch
---
Manually retain/release NSMenu reference.

View file

@ -47,20 +47,29 @@ extern "C" {
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
const NSAboutPanelOptionCopyright: &str = "Copyright"; const NSAboutPanelOptionCopyright: &str = "Copyright";
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct Menu { pub struct Menu {
id: u32, id: u32,
ns_menu: id, ns_menu: id,
children: Rc<RefCell<Vec<Rc<RefCell<MenuChild>>>>>, children: Rc<RefCell<Vec<Rc<RefCell<MenuChild>>>>>,
} }
impl Drop for Menu {
fn drop(&mut self) {
unsafe {
let _: () = msg_send![self.ns_menu, release];
}
}
}
impl Menu { impl Menu {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
id: COUNTER.next(), id: COUNTER.next(),
ns_menu: unsafe { ns_menu: unsafe {
let ns_menu = NSMenu::alloc(nil).autorelease(); let ns_menu = NSMenu::new(nil);
ns_menu.setAutoenablesItems(NO); ns_menu.setAutoenablesItems(NO);
let _: () = msg_send![ns_menu, retain];
ns_menu ns_menu
}, },
children: Rc::new(RefCell::new(Vec::new())), children: Rc::new(RefCell::new(Vec::new())),
@ -173,7 +182,18 @@ pub struct MenuChild {
// submenu fields // submenu fields
pub children: Option<Vec<Rc<RefCell<MenuChild>>>>, pub children: Option<Vec<Rc<RefCell<MenuChild>>>>,
ns_menus: HashMap<u32, Vec<id>>, ns_menus: HashMap<u32, Vec<id>>,
ns_menu: (u32, id), ns_menu: NsMenuRef,
}
#[derive(Debug)]
struct NsMenuRef(u32, id);
impl Drop for NsMenuRef {
fn drop(&mut self) {
unsafe {
let _: () = msg_send![self.1, release];
}
}
} }
impl Default for MenuChild { impl Default for MenuChild {
@ -191,7 +211,7 @@ impl Default for MenuChild {
native_icon: Default::default(), native_icon: Default::default(),
children: Default::default(), children: Default::default(),
ns_menus: Default::default(), ns_menus: Default::default(),
ns_menu: (0, 0 as _), ns_menu: NsMenuRef(0, 0 as _),
} }
} }
} }
@ -215,7 +235,11 @@ impl MenuChild {
text: strip_mnemonic(text), text: strip_mnemonic(text),
enabled, enabled,
children: Some(Vec::new()), children: Some(Vec::new()),
ns_menu: (COUNTER.next(), unsafe { NSMenu::alloc(nil).autorelease() }), ns_menu: NsMenuRef(COUNTER.next(), unsafe {
let menu = NSMenu::new(nil);
let _: () = msg_send![menu, retain];
menu
}),
..Default::default() ..Default::default()
} }
} }