gpui: improve the window menu on macOS
This commit is contained in:
parent
70575d1115
commit
b724431256
4 changed files with 54 additions and 31 deletions
|
@ -26,14 +26,20 @@ fn main() {
|
||||||
// Register the `quit` function so it can be referenced by the `MenuItem::action` in the menu bar
|
// Register the `quit` function so it can be referenced by the `MenuItem::action` in the menu bar
|
||||||
cx.on_action(quit);
|
cx.on_action(quit);
|
||||||
// Add menu items
|
// Add menu items
|
||||||
cx.set_menus(vec![Menu {
|
cx.set_menus(vec![
|
||||||
name: "set_menus".into(),
|
Menu {
|
||||||
items: vec![
|
name: "set_menus".into(),
|
||||||
MenuItem::os_submenu("Services", SystemMenuType::Services),
|
items: vec![
|
||||||
MenuItem::separator(),
|
MenuItem::os_submenu("Services", SystemMenuType::Services),
|
||||||
MenuItem::action("Quit", Quit),
|
MenuItem::separator(),
|
||||||
],
|
MenuItem::action("Quit", Quit),
|
||||||
}]);
|
],
|
||||||
|
},
|
||||||
|
Menu {
|
||||||
|
name: "Window".into(),
|
||||||
|
items: vec![MenuItem::os_submenu("", SystemMenuType::Window)],
|
||||||
|
},
|
||||||
|
]);
|
||||||
cx.open_window(WindowOptions::default(), |_, cx| cx.new(|_| SetMenus {}))
|
cx.open_window(WindowOptions::default(), |_, cx| cx.new(|_| SetMenus {}))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
});
|
});
|
||||||
|
|
|
@ -46,6 +46,15 @@ impl OsMenu {
|
||||||
pub enum SystemMenuType {
|
pub enum SystemMenuType {
|
||||||
/// The 'Services' menu in the Application menu on macOS
|
/// The 'Services' menu in the Application menu on macOS
|
||||||
Services,
|
Services,
|
||||||
|
|
||||||
|
/// The 'Window' menu on macOS.
|
||||||
|
///
|
||||||
|
/// This item is a marker and will not display as a menu item.
|
||||||
|
/// If a menu begins with this item, it will be treated as the Window menu.
|
||||||
|
///
|
||||||
|
/// macOS will add window management items to this menu, such as
|
||||||
|
/// 'Fill', 'Center', 'Move to [Display]', and a list of windows.
|
||||||
|
Window,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The different kinds of items that can be in a menu
|
/// The different kinds of items that can be in a menu
|
||||||
|
|
|
@ -243,24 +243,29 @@ impl MacPlatform {
|
||||||
menu.setTitle_(menu_title);
|
menu.setTitle_(menu_title);
|
||||||
menu.setDelegate_(delegate);
|
menu.setDelegate_(delegate);
|
||||||
|
|
||||||
|
// Check the first item to see if it is window menu
|
||||||
|
if let Some(i) = menu_config.items.first()
|
||||||
|
&& matches!(
|
||||||
|
i,
|
||||||
|
MenuItem::SystemMenu(OsMenu {
|
||||||
|
menu_type: SystemMenuType::Window,
|
||||||
|
..
|
||||||
|
})
|
||||||
|
)
|
||||||
|
{
|
||||||
|
let app: id = msg_send![APP_CLASS, sharedApplication];
|
||||||
|
app.setWindowsMenu_(menu);
|
||||||
|
};
|
||||||
|
|
||||||
for item_config in &menu_config.items {
|
for item_config in &menu_config.items {
|
||||||
menu.addItem_(Self::create_menu_item(
|
Self::create_menu_item(item_config, delegate, actions, keymap)
|
||||||
item_config,
|
.map(|item| menu.addItem_(item));
|
||||||
delegate,
|
|
||||||
actions,
|
|
||||||
keymap,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let menu_item = NSMenuItem::new(nil).autorelease();
|
let menu_item = NSMenuItem::new(nil).autorelease();
|
||||||
menu_item.setTitle_(menu_title);
|
menu_item.setTitle_(menu_title);
|
||||||
menu_item.setSubmenu_(menu);
|
menu_item.setSubmenu_(menu);
|
||||||
application_menu.addItem_(menu_item);
|
application_menu.addItem_(menu_item);
|
||||||
|
|
||||||
if menu_config.name == "Window" {
|
|
||||||
let app: id = msg_send![APP_CLASS, sharedApplication];
|
|
||||||
app.setWindowsMenu_(menu);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
application_menu
|
application_menu
|
||||||
|
@ -278,12 +283,8 @@ impl MacPlatform {
|
||||||
let dock_menu = NSMenu::new(nil);
|
let dock_menu = NSMenu::new(nil);
|
||||||
dock_menu.setDelegate_(delegate);
|
dock_menu.setDelegate_(delegate);
|
||||||
for item_config in menu_items {
|
for item_config in menu_items {
|
||||||
dock_menu.addItem_(Self::create_menu_item(
|
Self::create_menu_item(&item_config, delegate, actions, keymap)
|
||||||
&item_config,
|
.map(|item| dock_menu.addItem_(item));
|
||||||
delegate,
|
|
||||||
actions,
|
|
||||||
keymap,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dock_menu
|
dock_menu
|
||||||
|
@ -295,12 +296,12 @@ impl MacPlatform {
|
||||||
delegate: id,
|
delegate: id,
|
||||||
actions: &mut Vec<Box<dyn Action>>,
|
actions: &mut Vec<Box<dyn Action>>,
|
||||||
keymap: &Keymap,
|
keymap: &Keymap,
|
||||||
) -> id {
|
) -> Option<id> {
|
||||||
static DEFAULT_CONTEXT: OnceLock<Vec<KeyContext>> = OnceLock::new();
|
static DEFAULT_CONTEXT: OnceLock<Vec<KeyContext>> = OnceLock::new();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
match item {
|
match item {
|
||||||
MenuItem::Separator => NSMenuItem::separatorItem(nil),
|
MenuItem::Separator => Some(NSMenuItem::separatorItem(nil)),
|
||||||
MenuItem::Action {
|
MenuItem::Action {
|
||||||
name,
|
name,
|
||||||
action,
|
action,
|
||||||
|
@ -402,18 +403,19 @@ impl MacPlatform {
|
||||||
let tag = actions.len() as NSInteger;
|
let tag = actions.len() as NSInteger;
|
||||||
let _: () = msg_send![item, setTag: tag];
|
let _: () = msg_send![item, setTag: tag];
|
||||||
actions.push(action.boxed_clone());
|
actions.push(action.boxed_clone());
|
||||||
item
|
Some(item)
|
||||||
}
|
}
|
||||||
MenuItem::Submenu(Menu { name, items }) => {
|
MenuItem::Submenu(Menu { name, items }) => {
|
||||||
let item = NSMenuItem::new(nil).autorelease();
|
let item = NSMenuItem::new(nil).autorelease();
|
||||||
let submenu = NSMenu::new(nil).autorelease();
|
let submenu = NSMenu::new(nil).autorelease();
|
||||||
submenu.setDelegate_(delegate);
|
submenu.setDelegate_(delegate);
|
||||||
for item in items {
|
for item in items {
|
||||||
submenu.addItem_(Self::create_menu_item(item, delegate, actions, keymap));
|
Self::create_menu_item(item, delegate, actions, keymap)
|
||||||
|
.map(|item| submenu.addItem_(item));
|
||||||
}
|
}
|
||||||
item.setSubmenu_(submenu);
|
item.setSubmenu_(submenu);
|
||||||
item.setTitle_(ns_string(name));
|
item.setTitle_(ns_string(name));
|
||||||
item
|
Some(item)
|
||||||
}
|
}
|
||||||
MenuItem::SystemMenu(OsMenu { name, menu_type }) => {
|
MenuItem::SystemMenu(OsMenu { name, menu_type }) => {
|
||||||
let item = NSMenuItem::new(nil).autorelease();
|
let item = NSMenuItem::new(nil).autorelease();
|
||||||
|
@ -427,9 +429,12 @@ impl MacPlatform {
|
||||||
let app: id = msg_send![APP_CLASS, sharedApplication];
|
let app: id = msg_send![APP_CLASS, sharedApplication];
|
||||||
app.setServicesMenu_(item);
|
app.setServicesMenu_(item);
|
||||||
}
|
}
|
||||||
|
SystemMenuType::Window => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
item
|
Some(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,9 @@ pub fn app_menus() -> Vec<Menu> {
|
||||||
Menu {
|
Menu {
|
||||||
name: "Window".into(),
|
name: "Window".into(),
|
||||||
items: vec![
|
items: vec![
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
MenuItem::os_submenu("", gpui::SystemMenuType::Window),
|
||||||
|
MenuItem::separator(),
|
||||||
MenuItem::action("Minimize", super::Minimize),
|
MenuItem::action("Minimize", super::Minimize),
|
||||||
MenuItem::action("Zoom", super::Zoom),
|
MenuItem::action("Zoom", super::Zoom),
|
||||||
MenuItem::separator(),
|
MenuItem::separator(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue