Reintroduce menu-related platform callbacks

This commit is contained in:
Nathan Sobo 2023-12-05 09:23:24 -07:00
parent 30725d6a17
commit dffe0ea058
3 changed files with 73 additions and 59 deletions

View file

@ -5,7 +5,7 @@ mod mac;
mod test; mod test;
use crate::{ use crate::{
point, size, AnyWindowHandle, BackgroundExecutor, Bounds, DevicePixels, Font, FontId, point, size, Action, AnyWindowHandle, BackgroundExecutor, Bounds, DevicePixels, Font, FontId,
FontMetrics, FontRun, ForegroundExecutor, GlobalPixels, GlyphId, InputEvent, LineLayout, FontMetrics, FontRun, ForegroundExecutor, GlobalPixels, GlyphId, InputEvent, LineLayout,
Pixels, Point, RenderGlyphParams, RenderImageParams, RenderSvgParams, Result, Scene, Pixels, Point, RenderGlyphParams, RenderImageParams, RenderSvgParams, Result, Scene,
SharedString, Size, TaskLabel, SharedString, Size, TaskLabel,
@ -90,6 +90,10 @@ pub trait Platform: 'static {
fn on_reopen(&self, callback: Box<dyn FnMut()>); fn on_reopen(&self, callback: Box<dyn FnMut()>);
fn on_event(&self, callback: Box<dyn FnMut(InputEvent) -> bool>); fn on_event(&self, callback: Box<dyn FnMut(InputEvent) -> bool>);
fn on_menu_command(&self, callback: Box<dyn FnMut(&dyn Action)>);
fn on_will_open_menu(&self, callback: Box<dyn FnMut()>);
fn on_validate_menu_command(&self, callback: Box<dyn FnMut(&dyn Action) -> bool>);
fn os_name(&self) -> &'static str; fn os_name(&self) -> &'static str;
fn os_version(&self) -> Result<SemanticVersion>; fn os_version(&self) -> Result<SemanticVersion>;
fn app_version(&self) -> Result<SemanticVersion>; fn app_version(&self) -> Result<SemanticVersion>;

View file

@ -1,9 +1,9 @@
use super::BoolExt; use super::BoolExt;
use crate::{ use crate::{
AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId, ForegroundExecutor, Action, AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId,
InputEvent, MacDispatcher, MacDisplay, MacDisplayLinker, MacTextSystem, MacWindow, ForegroundExecutor, InputEvent, MacDispatcher, MacDisplay, MacDisplayLinker, MacTextSystem,
PathPromptOptions, Platform, PlatformDisplay, PlatformTextSystem, PlatformWindow, Result, MacWindow, PathPromptOptions, Platform, PlatformDisplay, PlatformTextSystem, PlatformWindow,
SemanticVersion, VideoTimestamp, WindowOptions, Result, SemanticVersion, VideoTimestamp, WindowOptions,
}; };
use anyhow::anyhow; use anyhow::anyhow;
use block::ConcreteBlock; use block::ConcreteBlock;
@ -155,12 +155,12 @@ pub struct MacPlatformState {
reopen: Option<Box<dyn FnMut()>>, reopen: Option<Box<dyn FnMut()>>,
quit: Option<Box<dyn FnMut()>>, quit: Option<Box<dyn FnMut()>>,
event: Option<Box<dyn FnMut(InputEvent) -> bool>>, event: Option<Box<dyn FnMut(InputEvent) -> bool>>,
// menu_command: Option<Box<dyn FnMut(&dyn Action)>>, menu_command: Option<Box<dyn FnMut(&dyn Action)>>,
// validate_menu_command: Option<Box<dyn FnMut(&dyn Action) -> bool>>, validate_menu_command: Option<Box<dyn FnMut(&dyn Action) -> bool>>,
will_open_menu: Option<Box<dyn FnMut()>>, will_open_menu: Option<Box<dyn FnMut()>>,
menu_actions: Vec<Box<dyn Action>>,
open_urls: Option<Box<dyn FnMut(Vec<String>)>>, open_urls: Option<Box<dyn FnMut(Vec<String>)>>,
finish_launching: Option<Box<dyn FnOnce()>>, finish_launching: Option<Box<dyn FnOnce()>>,
// menu_actions: Vec<Box<dyn Action>>,
} }
impl MacPlatform { impl MacPlatform {
@ -179,12 +179,12 @@ impl MacPlatform {
reopen: None, reopen: None,
quit: None, quit: None,
event: None, event: None,
menu_command: None,
validate_menu_command: None,
will_open_menu: None, will_open_menu: None,
menu_actions: Default::default(),
open_urls: None, open_urls: None,
finish_launching: None, finish_launching: None,
// menu_command: None,
// validate_menu_command: None,
// menu_actions: Default::default(),
})) }))
} }
@ -681,17 +681,17 @@ impl Platform for MacPlatform {
} }
} }
// fn on_menu_command(&self, callback: Box<dyn FnMut(&dyn Action)>) { fn on_menu_command(&self, callback: Box<dyn FnMut(&dyn Action)>) {
// self.0.lock().menu_command = Some(callback); self.0.lock().menu_command = Some(callback);
// } }
// fn on_will_open_menu(&self, callback: Box<dyn FnMut()>) { fn on_will_open_menu(&self, callback: Box<dyn FnMut()>) {
// self.0.lock().will_open_menu = Some(callback); self.0.lock().will_open_menu = Some(callback);
// } }
// fn on_validate_menu_command(&self, callback: Box<dyn FnMut(&dyn Action) -> bool>) { fn on_validate_menu_command(&self, callback: Box<dyn FnMut(&dyn Action) -> bool>) {
// self.0.lock().validate_menu_command = Some(callback); self.0.lock().validate_menu_command = Some(callback);
// } }
// fn set_menus(&self, menus: Vec<Menu>, keystroke_matcher: &KeymapMatcher) { // fn set_menus(&self, menus: Vec<Menu>, keystroke_matcher: &KeymapMatcher) {
// unsafe { // unsafe {
@ -956,7 +956,7 @@ unsafe fn path_from_objc(path: id) -> PathBuf {
PathBuf::from(path) PathBuf::from(path)
} }
unsafe fn get_foreground_platform(object: &mut Object) -> &MacPlatform { unsafe fn get_mac_platform(object: &mut Object) -> &MacPlatform {
let platform_ptr: *mut c_void = *object.get_ivar(MAC_PLATFORM_IVAR); let platform_ptr: *mut c_void = *object.get_ivar(MAC_PLATFORM_IVAR);
assert!(!platform_ptr.is_null()); assert!(!platform_ptr.is_null());
&*(platform_ptr as *const MacPlatform) &*(platform_ptr as *const MacPlatform)
@ -965,7 +965,7 @@ unsafe fn get_foreground_platform(object: &mut Object) -> &MacPlatform {
extern "C" fn send_event(this: &mut Object, _sel: Sel, native_event: id) { extern "C" fn send_event(this: &mut Object, _sel: Sel, native_event: id) {
unsafe { unsafe {
if let Some(event) = InputEvent::from_native(native_event, None) { if let Some(event) = InputEvent::from_native(native_event, None) {
let platform = get_foreground_platform(this); let platform = get_mac_platform(this);
if let Some(callback) = platform.0.lock().event.as_mut() { if let Some(callback) = platform.0.lock().event.as_mut() {
if !callback(event) { if !callback(event) {
return; return;
@ -981,7 +981,7 @@ extern "C" fn did_finish_launching(this: &mut Object, _: Sel, _: id) {
let app: id = msg_send![APP_CLASS, sharedApplication]; let app: id = msg_send![APP_CLASS, sharedApplication];
app.setActivationPolicy_(NSApplicationActivationPolicyRegular); app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
let platform = get_foreground_platform(this); let platform = get_mac_platform(this);
let callback = platform.0.lock().finish_launching.take(); let callback = platform.0.lock().finish_launching.take();
if let Some(callback) = callback { if let Some(callback) = callback {
callback(); callback();
@ -991,7 +991,7 @@ extern "C" fn did_finish_launching(this: &mut Object, _: Sel, _: id) {
extern "C" fn should_handle_reopen(this: &mut Object, _: Sel, _: id, has_open_windows: bool) { extern "C" fn should_handle_reopen(this: &mut Object, _: Sel, _: id, has_open_windows: bool) {
if !has_open_windows { if !has_open_windows {
let platform = unsafe { get_foreground_platform(this) }; let platform = unsafe { get_mac_platform(this) };
if let Some(callback) = platform.0.lock().reopen.as_mut() { if let Some(callback) = platform.0.lock().reopen.as_mut() {
callback(); callback();
} }
@ -999,21 +999,21 @@ extern "C" fn should_handle_reopen(this: &mut Object, _: Sel, _: id, has_open_wi
} }
extern "C" fn did_become_active(this: &mut Object, _: Sel, _: id) { extern "C" fn did_become_active(this: &mut Object, _: Sel, _: id) {
let platform = unsafe { get_foreground_platform(this) }; let platform = unsafe { get_mac_platform(this) };
if let Some(callback) = platform.0.lock().become_active.as_mut() { if let Some(callback) = platform.0.lock().become_active.as_mut() {
callback(); callback();
} }
} }
extern "C" fn did_resign_active(this: &mut Object, _: Sel, _: id) { extern "C" fn did_resign_active(this: &mut Object, _: Sel, _: id) {
let platform = unsafe { get_foreground_platform(this) }; let platform = unsafe { get_mac_platform(this) };
if let Some(callback) = platform.0.lock().resign_active.as_mut() { if let Some(callback) = platform.0.lock().resign_active.as_mut() {
callback(); callback();
} }
} }
extern "C" fn will_terminate(this: &mut Object, _: Sel, _: id) { extern "C" fn will_terminate(this: &mut Object, _: Sel, _: id) {
let platform = unsafe { get_foreground_platform(this) }; let platform = unsafe { get_mac_platform(this) };
if let Some(callback) = platform.0.lock().quit.as_mut() { if let Some(callback) = platform.0.lock().quit.as_mut() {
callback(); callback();
} }
@ -1035,49 +1035,47 @@ extern "C" fn open_urls(this: &mut Object, _: Sel, _: id, urls: id) {
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
}; };
let platform = unsafe { get_foreground_platform(this) }; let platform = unsafe { get_mac_platform(this) };
if let Some(callback) = platform.0.lock().open_urls.as_mut() { if let Some(callback) = platform.0.lock().open_urls.as_mut() {
callback(urls); callback(urls);
} }
} }
extern "C" fn handle_menu_item(__this: &mut Object, _: Sel, __item: id) { extern "C" fn handle_menu_item(this: &mut Object, _: Sel, item: id) {
todo!() unsafe {
// unsafe { let platform = get_mac_platform(this);
// let platform = get_foreground_platform(this); let mut platform = platform.0.lock();
// let mut platform = platform.0.lock(); if let Some(mut callback) = platform.menu_command.take() {
// if let Some(mut callback) = platform.menu_command.take() { let tag: NSInteger = msg_send![item, tag];
// let tag: NSInteger = msg_send![item, tag]; let index = tag as usize;
// let index = tag as usize; if let Some(action) = platform.menu_actions.get(index) {
// if let Some(action) = platform.menu_actions.get(index) { callback(action.as_ref());
// callback(action.as_ref()); }
// } platform.menu_command = Some(callback);
// platform.menu_command = Some(callback); }
// } }
// }
} }
extern "C" fn validate_menu_item(__this: &mut Object, _: Sel, __item: id) -> bool { extern "C" fn validate_menu_item(this: &mut Object, _: Sel, item: id) -> bool {
todo!() unsafe {
// unsafe { let mut result = false;
// let mut result = false; let platform = get_mac_platform(this);
// let platform = get_foreground_platform(this); let mut platform = platform.0.lock();
// let mut platform = platform.0.lock(); if let Some(mut callback) = platform.validate_menu_command.take() {
// if let Some(mut callback) = platform.validate_menu_command.take() { let tag: NSInteger = msg_send![item, tag];
// let tag: NSInteger = msg_send![item, tag]; let index = tag as usize;
// let index = tag as usize; if let Some(action) = platform.menu_actions.get(index) {
// if let Some(action) = platform.menu_actions.get(index) { result = callback(action.as_ref());
// result = callback(action.as_ref()); }
// } platform.validate_menu_command = Some(callback);
// platform.validate_menu_command = Some(callback); }
// } result
// result }
// }
} }
extern "C" fn menu_will_open(this: &mut Object, _: Sel, _: id) { extern "C" fn menu_will_open(this: &mut Object, _: Sel, _: id) {
unsafe { unsafe {
let platform = get_foreground_platform(this); let platform = get_mac_platform(this);
let mut platform = platform.0.lock(); let mut platform = platform.0.lock();
if let Some(mut callback) = platform.will_open_menu.take() { if let Some(mut callback) = platform.will_open_menu.take() {
callback(); callback();

View file

@ -205,6 +205,18 @@ impl Platform for TestPlatform {
unimplemented!() unimplemented!()
} }
fn on_menu_command(&self, _callback: Box<dyn FnMut(&dyn crate::Action)>) {
unimplemented!()
}
fn on_will_open_menu(&self, _callback: Box<dyn FnMut()>) {
unimplemented!()
}
fn on_validate_menu_command(&self, _callback: Box<dyn FnMut(&dyn crate::Action) -> bool>) {
unimplemented!()
}
fn os_name(&self) -> &'static str { fn os_name(&self) -> &'static str {
"test" "test"
} }