From d2142d82c375915b487b85cd6b08d0319283a9f1 Mon Sep 17 00:00:00 2001 From: Mark Murphy Date: Thu, 27 Jun 2024 16:41:28 -0400 Subject: [PATCH 1/4] Add quit shortcut to macos menu bar --- src/native/macos.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/native/macos.rs b/src/native/macos.rs index e5f5604d..13a7c623 100644 --- a/src/native/macos.rs +++ b/src/native/macos.rs @@ -901,6 +901,37 @@ unsafe fn set_icon(ns_app: ObjcId, icon: &Icon) { CGImageRelease(image); } +/// Initialize the system menu bar for this application +/// - ns_app: This NSApplication +#[no_mangle] +unsafe fn initialize_menu_bar(ns_app: ObjcId) { + // Adapted from Winit `menu::initialize` + + // System menu bar + let menu_bar: ObjcId = msg_send![class!(NSMenu), new]; + // Entry for the app menu dropdown in the menu bar + let app_menu_item: ObjcId = msg_send![class!(NSMenuItem), new]; + let app_menu: ObjcId = msg_send![class!(NSMenu), new]; + + // Hook up the menu components to the application + let () = msg_send![app_menu_item, setSubmenu: app_menu]; + let () = msg_send![menu_bar, addItem: app_menu_item]; + let () = msg_send![ns_app, setMainMenu: menu_bar]; + + // Add quit menu entry with shortcut command-q + let process_info: ObjcId = msg_send![class!(NSProcessInfo), processInfo]; + let process_name: ObjcId = msg_send![process_info, processName]; + let quit_item_title = str_to_nsstring(&format!("Quit {}", nsstring_to_string(process_name))); + let quit_item: ObjcId = msg_send![class!(NSMenuItem), alloc]; + let quit_item: ObjcId = msg_send![ + quit_item, + initWithTitle: quit_item_title + action: sel!(terminate:) + keyEquivalent: str_to_nsstring("q") + ]; + () = msg_send![app_menu, addItem: quit_item]; +} + pub unsafe fn run(conf: crate::conf::Conf, f: F) where F: 'static + FnOnce() -> Box, @@ -946,6 +977,8 @@ where set_icon(ns_app, icon); } + initialize_menu_bar(ns_app); + let window_masks = NSWindowStyleMask::NSTitledWindowMask as u64 | NSWindowStyleMask::NSClosableWindowMask as u64 | NSWindowStyleMask::NSMiniaturizableWindowMask as u64 From 546cad3bde12ca2474e77deebf51f7ec000ae68f Mon Sep 17 00:00:00 2001 From: Mark Murphy Date: Sat, 29 Jun 2024 15:39:46 -0400 Subject: [PATCH 2/4] Use application name for osx quit shortcut --- src/native/macos.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/native/macos.rs b/src/native/macos.rs index 13a7c623..45357274 100644 --- a/src/native/macos.rs +++ b/src/native/macos.rs @@ -919,9 +919,12 @@ unsafe fn initialize_menu_bar(ns_app: ObjcId) { let () = msg_send![ns_app, setMainMenu: menu_bar]; // Add quit menu entry with shortcut command-q - let process_info: ObjcId = msg_send![class!(NSProcessInfo), processInfo]; - let process_name: ObjcId = msg_send![process_info, processName]; - let quit_item_title = str_to_nsstring(&format!("Quit {}", nsstring_to_string(process_name))); + // It uses NSRunningApplication.localizedName, which will try to use the localized name, + // and will go through a chain of fallbacks based on what name strings are set in + // the Application bundle files, ending with the executable name. + let running_application: ObjcId = msg_send![class!(NSRunningApplication), currentApplication]; + let application_name: ObjcId = msg_send![running_application, localizedName]; + let quit_item_title = str_to_nsstring(&format!("Quit {}", nsstring_to_string(application_name))); let quit_item: ObjcId = msg_send![class!(NSMenuItem), alloc]; let quit_item: ObjcId = msg_send![ quit_item, From e2bc99bbf8d50a7831bd7d687feb33b10142dc20 Mon Sep 17 00:00:00 2001 From: Mark Murphy Date: Sat, 29 Jun 2024 17:45:16 -0400 Subject: [PATCH 3/4] Remove unnecessary #[no_mangle] attribute --- src/native/macos.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/native/macos.rs b/src/native/macos.rs index 45357274..5e365af0 100644 --- a/src/native/macos.rs +++ b/src/native/macos.rs @@ -903,7 +903,6 @@ unsafe fn set_icon(ns_app: ObjcId, icon: &Icon) { /// Initialize the system menu bar for this application /// - ns_app: This NSApplication -#[no_mangle] unsafe fn initialize_menu_bar(ns_app: ObjcId) { // Adapted from Winit `menu::initialize` From 74f18900c91aeae7fe5888301bdc7ec5be83768e Mon Sep 17 00:00:00 2001 From: Mark Murphy Date: Sat, 29 Jun 2024 17:46:25 -0400 Subject: [PATCH 4/4] Use `msg_send_!` macro to infer `ObjcId` types --- src/native/macos.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/native/macos.rs b/src/native/macos.rs index 5e365af0..8b0814d7 100644 --- a/src/native/macos.rs +++ b/src/native/macos.rs @@ -907,31 +907,31 @@ unsafe fn initialize_menu_bar(ns_app: ObjcId) { // Adapted from Winit `menu::initialize` // System menu bar - let menu_bar: ObjcId = msg_send![class!(NSMenu), new]; + let menu_bar = msg_send_![class!(NSMenu), new]; // Entry for the app menu dropdown in the menu bar - let app_menu_item: ObjcId = msg_send![class!(NSMenuItem), new]; - let app_menu: ObjcId = msg_send![class!(NSMenu), new]; + let app_menu_item = msg_send_![class!(NSMenuItem), new]; + let app_menu = msg_send_![class!(NSMenu), new]; // Hook up the menu components to the application - let () = msg_send![app_menu_item, setSubmenu: app_menu]; - let () = msg_send![menu_bar, addItem: app_menu_item]; - let () = msg_send![ns_app, setMainMenu: menu_bar]; + msg_send_![app_menu_item, setSubmenu: app_menu]; + msg_send_![menu_bar, addItem: app_menu_item]; + msg_send_![ns_app, setMainMenu: menu_bar]; // Add quit menu entry with shortcut command-q // It uses NSRunningApplication.localizedName, which will try to use the localized name, // and will go through a chain of fallbacks based on what name strings are set in // the Application bundle files, ending with the executable name. - let running_application: ObjcId = msg_send![class!(NSRunningApplication), currentApplication]; - let application_name: ObjcId = msg_send![running_application, localizedName]; + let running_application = msg_send_![class!(NSRunningApplication), currentApplication]; + let application_name = msg_send_![running_application, localizedName]; let quit_item_title = str_to_nsstring(&format!("Quit {}", nsstring_to_string(application_name))); - let quit_item: ObjcId = msg_send![class!(NSMenuItem), alloc]; - let quit_item: ObjcId = msg_send![ + let quit_item = msg_send_![class!(NSMenuItem), alloc]; + let quit_item = msg_send_![ quit_item, initWithTitle: quit_item_title action: sel!(terminate:) keyEquivalent: str_to_nsstring("q") ]; - () = msg_send![app_menu, addItem: quit_item]; + msg_send_![app_menu, addItem: quit_item]; } pub unsafe fn run(conf: crate::conf::Conf, f: F)