diff --git a/.changes/fix-macos-special-menu-functions.md b/.changes/fix-macos-special-menu-functions.md new file mode 100644 index 00000000..4dff14b3 --- /dev/null +++ b/.changes/fix-macos-special-menu-functions.md @@ -0,0 +1,6 @@ +--- +"muda": patch +--- + + +Fix `set_as_windows_menu_for_nsapp()` and `set_as_help_menu_for_nsapp()` diff --git a/src/platform_impl/macos/mod.rs b/src/platform_impl/macos/mod.rs index 141378ad..ef20f90c 100644 --- a/src/platform_impl/macos/mod.rs +++ b/src/platform_impl/macos/mod.rs @@ -664,18 +664,41 @@ impl MenuChild { show_context_menu(&self.ns_menu.as_ref().unwrap().1, view, position) } - pub fn set_as_windows_menu_for_nsapp(&self) { - let menu = &self.ns_menu.as_ref().unwrap().1; - let mtm = MainThreadMarker::from(&**menu); + fn find_menu_in_hierarchy(&self) -> Option<&NsMenuRef> { + let ns_menus = self.ns_menus.as_ref()?; + + let mtm = MainThreadMarker::from(&*self.ns_menu.as_ref().unwrap().1); let app = NSApplication::sharedApplication(mtm); - unsafe { app.setWindowsMenu(Some(menu)) } + let main_menu = unsafe { app.mainMenu() }; + + // Find menu whose supermenu is the main menu, or use first available + ns_menus + .values() + .flatten() + .find(|ns_menu| { + main_menu.as_ref().is_some_and(|main| { + unsafe { ns_menu.1.supermenu() } + .as_ref() + .is_some_and(|super_| Retained::as_ptr(super_) == Retained::as_ptr(main)) + }) + }) + .or_else(|| ns_menus.values().flatten().next()) + } + + pub fn set_as_windows_menu_for_nsapp(&self) { + if let Some(ns_menu) = self.find_menu_in_hierarchy() { + let mtm = MainThreadMarker::from(&*ns_menu.1); + let app = NSApplication::sharedApplication(mtm); + unsafe { app.setWindowsMenu(Some(&ns_menu.1)) } + } } pub fn set_as_help_menu_for_nsapp(&self) { - let menu = &self.ns_menu.as_ref().unwrap().1; - let mtm = MainThreadMarker::from(&**menu); - let app = NSApplication::sharedApplication(mtm); - unsafe { app.setHelpMenu(Some(menu)) } + if let Some(ns_menu) = self.find_menu_in_hierarchy() { + let mtm = MainThreadMarker::from(&*ns_menu.1); + let app = NSApplication::sharedApplication(mtm); + unsafe { app.setHelpMenu(Some(&ns_menu.1)) } + } } pub fn ns_menu(&self) -> *mut std::ffi::c_void { diff --git a/src/platform_impl/mod.rs b/src/platform_impl/mod.rs index 17018a33..d3908f28 100644 --- a/src/platform_impl/mod.rs +++ b/src/platform_impl/mod.rs @@ -88,7 +88,7 @@ impl MenuItemKind { } } - pub(crate) fn child(&self) -> Ref { + pub(crate) fn child(&self) -> Ref<'_, MenuChild> { match self { MenuItemKind::MenuItem(i) => i.inner.borrow(), MenuItemKind::Submenu(i) => i.inner.borrow(), @@ -98,7 +98,7 @@ impl MenuItemKind { } } - pub(crate) fn child_mut(&self) -> RefMut { + pub(crate) fn child_mut(&self) -> RefMut<'_, MenuChild> { match self { MenuItemKind::MenuItem(i) => i.inner.borrow_mut(), MenuItemKind::Submenu(i) => i.inner.borrow_mut(),