diff --git a/Cargo.toml b/Cargo.toml index 264eec8c..7f5a8ae0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,12 +74,38 @@ ndk-sys = "0.4.0" [target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies] core-foundation = "0.9.3" -objc2 = ">=0.3.0-beta.3, <0.3.0-beta.4" # Allow `0.3.0-beta.3.patch-leaks` +objc2 = "0.4.0" [target.'cfg(target_os = "macos")'.dependencies] core-graphics = "0.22.3" dispatch = "0.2.0" +[target.'cfg(target_os = "macos")'.dependencies.icrate] +version = "0.0.3" +features = [ + "Foundation", + "Foundation_NSArray", + "Foundation_NSAttributedString", + "Foundation_NSMutableAttributedString", + "Foundation_NSData", + "Foundation_NSDictionary", + "Foundation_NSString", + "Foundation_NSProcessInfo", + "Foundation_NSThread", + "Foundation_NSNumber", +] + +[target.'cfg(target_os = "ios")'.dependencies.icrate] +version = "0.0.3" +features = [ + "Foundation", + "Foundation_NSArray", + "Foundation_NSString", + "Foundation_NSProcessInfo", + "Foundation_NSThread", + "Foundation_NSSet", +] + [target.'cfg(target_os = "windows")'.dependencies] unicode-segmentation = "1.7.1" diff --git a/src/platform_impl/ios/app_state.rs b/src/platform_impl/ios/app_state.rs index b34ebddb..7b22e7ef 100644 --- a/src/platform_impl/ios/app_state.rs +++ b/src/platform_impl/ios/app_state.rs @@ -15,8 +15,8 @@ use core_foundation::runloop::{ kCFRunLoopCommonModes, CFRunLoopAddTimer, CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate, CFRunLoopTimerInvalidate, CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate, }; -use objc2::foundation::{CGRect, CGSize, NSInteger, NSProcessInfo}; -use objc2::rc::{Id, Shared}; +use icrate::Foundation::{CGRect, CGSize, NSInteger, NSProcessInfo}; +use objc2::rc::Id; use objc2::runtime::Object; use objc2::{msg_send, sel}; use once_cell::sync::Lazy; @@ -68,25 +68,25 @@ impl Event<'static, Never> { #[must_use = "dropping `AppStateImpl` without inspecting it is probably a bug"] enum AppStateImpl { NotLaunched { - queued_windows: Vec>, + queued_windows: Vec>, queued_events: Vec, - queued_gpu_redraws: HashSet>, + queued_gpu_redraws: HashSet>, }, Launching { - queued_windows: Vec>, + queued_windows: Vec>, queued_events: Vec, queued_event_handler: Box, - queued_gpu_redraws: HashSet>, + queued_gpu_redraws: HashSet>, }, ProcessingEvents { event_handler: Box, - queued_gpu_redraws: HashSet>, + queued_gpu_redraws: HashSet>, active_control_flow: ControlFlow, }, // special state to deal with reentrancy and prevent mutable aliasing. InUserCallback { queued_events: Vec, - queued_gpu_redraws: HashSet>, + queued_gpu_redraws: HashSet>, }, ProcessingRedraws { event_handler: Box, @@ -204,9 +204,7 @@ impl AppState { }); } - fn did_finish_launching_transition( - &mut self, - ) -> (Vec>, Vec) { + fn did_finish_launching_transition(&mut self) -> (Vec>, Vec) { let (windows, events, event_handler, queued_gpu_redraws) = match self.take_state() { AppStateImpl::Launching { queued_windows, @@ -363,7 +361,7 @@ impl AppState { } } - fn main_events_cleared_transition(&mut self) -> HashSet> { + fn main_events_cleared_transition(&mut self) -> HashSet> { let (event_handler, queued_gpu_redraws, active_control_flow) = match self.take_state() { AppStateImpl::ProcessingEvents { event_handler, @@ -451,7 +449,7 @@ impl AppState { // requires main thread and window is a UIWindow // retains window -pub(crate) unsafe fn set_key_window(window: &Id) { +pub(crate) unsafe fn set_key_window(window: &Id) { let mut this = AppState::get_mut(); match this.state_mut() { &mut AppStateImpl::NotLaunched { @@ -474,7 +472,7 @@ pub(crate) unsafe fn set_key_window(window: &Id) { // requires main thread and window is a UIWindow // retains window -pub(crate) unsafe fn queue_gl_or_metal_redraw(window: Id) { +pub(crate) unsafe fn queue_gl_or_metal_redraw(window: Id) { let mut this = AppState::get_mut(); match this.state_mut() { &mut AppStateImpl::NotLaunched { @@ -807,7 +805,7 @@ fn handle_hidpi_proxy( mut control_flow: ControlFlow, suggested_size: LogicalSize, scale_factor: f64, - window: Id, + window: Id, ) { let mut size = suggested_size.to_physical(scale_factor); let new_inner_size = &mut size; @@ -827,7 +825,7 @@ fn handle_hidpi_proxy( view.setFrame(new_frame); } -fn get_view_and_screen_frame(window: &WinitUIWindow) -> (Id, CGRect) { +fn get_view_and_screen_frame(window: &WinitUIWindow) -> (Id, CGRect) { let view_controller = window.rootViewController().unwrap(); let view = view_controller.view().unwrap(); let bounds = window.bounds(); @@ -963,7 +961,7 @@ impl NSOperatingSystemVersion { pub fn os_capabilities() -> OSCapabilities { static OS_CAPABILITIES: Lazy = Lazy::new(|| { let version: NSOperatingSystemVersion = unsafe { - let process_info = NSProcessInfo::process_info(); + let process_info = NSProcessInfo::processInfo(); let atleast_ios_8: bool = msg_send![ &process_info, respondsToSelector: sel!(operatingSystemVersion) diff --git a/src/platform_impl/ios/event_loop.rs b/src/platform_impl/ios/event_loop.rs index 5db6a662..f2e77e1a 100644 --- a/src/platform_impl/ios/event_loop.rs +++ b/src/platform_impl/ios/event_loop.rs @@ -14,8 +14,8 @@ use core_foundation::runloop::{ CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext, CFRunLoopSourceCreate, CFRunLoopSourceInvalidate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp, }; -use objc2::foundation::{MainThreadMarker, NSString}; -use objc2::rc::{Id, Shared}; +use icrate::Foundation::{MainThreadMarker, NSString}; +use objc2::rc::Id; use objc2::ClassType; use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle}; @@ -40,7 +40,7 @@ pub(crate) enum EventWrapper { #[derive(Debug, PartialEq)] pub(crate) enum EventProxy { DpiChangedProxy { - window: Id, + window: Id, suggested_size: LogicalSize, scale_factor: f64, }, diff --git a/src/platform_impl/ios/ffi.rs b/src/platform_impl/ios/ffi.rs index b684de50..69db70fc 100644 --- a/src/platform_impl/ios/ffi.rs +++ b/src/platform_impl/ios/ffi.rs @@ -2,8 +2,8 @@ use std::convert::TryInto; +use icrate::Foundation::{NSInteger, NSUInteger}; use objc2::encode::{Encode, Encoding}; -use objc2::foundation::{NSInteger, NSUInteger}; use crate::platform::ios::{Idiom, ScreenEdge}; diff --git a/src/platform_impl/ios/mod.rs b/src/platform_impl/ios/mod.rs index 0e1d2b4f..d70bce56 100644 --- a/src/platform_impl/ios/mod.rs +++ b/src/platform_impl/ios/mod.rs @@ -63,7 +63,7 @@ // window size/position. macro_rules! assert_main_thread { ($($t:tt)*) => { - if !::objc2::foundation::is_main_thread() { + if !::icrate::Foundation::is_main_thread() { panic!($($t)*); } }; diff --git a/src/platform_impl/ios/monitor.rs b/src/platform_impl/ios/monitor.rs index f5273ebd..baa1e3be 100644 --- a/src/platform_impl/ios/monitor.rs +++ b/src/platform_impl/ios/monitor.rs @@ -6,8 +6,8 @@ use std::{ ops::{Deref, DerefMut}, }; -use objc2::foundation::{MainThreadMarker, NSInteger}; -use objc2::rc::{Id, Shared}; +use icrate::Foundation::{MainThreadMarker, NSInteger}; +use objc2::rc::Id; use super::uikit::{UIScreen, UIScreenMode}; use crate::{ @@ -18,7 +18,7 @@ use crate::{ // TODO(madsmtm): Remove or refactor this #[derive(Debug, PartialEq, Eq, Hash, Clone)] -pub(crate) struct ScreenModeSendSync(pub(crate) Id); +pub(crate) struct ScreenModeSendSync(pub(crate) Id); unsafe impl Send for ScreenModeSendSync {} unsafe impl Sync for ScreenModeSendSync {} @@ -33,7 +33,7 @@ pub struct VideoMode { } impl VideoMode { - fn new(uiscreen: Id, screen_mode: Id) -> VideoMode { + fn new(uiscreen: Id, screen_mode: Id) -> VideoMode { assert_main_thread!("`VideoMode` can only be created on the main thread on iOS"); let refresh_rate_millihertz = refresh_rate_millihertz(&uiscreen); let size = screen_mode.size(); @@ -65,7 +65,7 @@ impl VideoMode { #[derive(Clone, PartialEq, Eq, Hash)] pub struct Inner { - uiscreen: Id, + uiscreen: Id, } #[derive(Clone, PartialEq, Eq, Hash)] @@ -135,7 +135,7 @@ impl fmt::Debug for MonitorHandle { } impl MonitorHandle { - pub(crate) fn new(uiscreen: Id) -> Self { + pub(crate) fn new(uiscreen: Id) -> Self { assert_main_thread!("`MonitorHandle` can only be created on the main thread on iOS"); Self { inner: Inner { uiscreen }, @@ -182,13 +182,8 @@ impl Inner { .uiscreen .availableModes() .into_iter() - .map(|mode| { - let mode: *const UIScreenMode = mode; - let mode = unsafe { Id::retain(mode as *mut UIScreenMode).unwrap() }; - - RootVideoMode { - video_mode: VideoMode::new(self.uiscreen.clone(), mode), - } + .map(|mode| RootVideoMode { + video_mode: VideoMode::new(self.uiscreen.clone(), mode), }) .collect(); @@ -222,7 +217,7 @@ fn refresh_rate_millihertz(uiscreen: &UIScreen) -> u32 { // MonitorHandleExtIOS impl Inner { - pub(crate) fn ui_screen(&self) -> &Id { + pub(crate) fn ui_screen(&self) -> &Id { &self.uiscreen } @@ -237,10 +232,6 @@ impl Inner { pub fn uiscreens(mtm: MainThreadMarker) -> VecDeque { UIScreen::screens(mtm) .into_iter() - .map(|screen| { - let screen: *const UIScreen = screen; - let screen = unsafe { Id::retain(screen as *mut UIScreen).unwrap() }; - MonitorHandle::new(screen) - }) + .map(MonitorHandle::new) .collect() } diff --git a/src/platform_impl/ios/uikit/application.rs b/src/platform_impl/ios/uikit/application.rs index 319a6b03..fe64dec8 100644 --- a/src/platform_impl/ios/uikit/application.rs +++ b/src/platform_impl/ios/uikit/application.rs @@ -1,6 +1,6 @@ -use objc2::foundation::{CGRect, MainThreadMarker, NSArray, NSObject}; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use icrate::Foundation::{CGRect, MainThreadMarker, NSArray, NSObject}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType}; use super::{UIResponder, UIWindow}; @@ -11,20 +11,21 @@ extern_class!( unsafe impl ClassType for UIApplication { #[inherits(NSObject)] type Super = UIResponder; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl UIApplication { - pub fn shared(_mtm: MainThreadMarker) -> Option> { + pub fn shared(_mtm: MainThreadMarker) -> Option> { unsafe { msg_send_id![Self::class(), sharedApplication] } } - pub fn windows(&self) -> Id, Shared> { + pub fn windows(&self) -> Id> { unsafe { msg_send_id![self, windows] } } - #[sel(statusBarFrame)] + #[method(statusBarFrame)] pub fn statusBarFrame(&self) -> CGRect; } ); diff --git a/src/platform_impl/ios/uikit/coordinate_space.rs b/src/platform_impl/ios/uikit/coordinate_space.rs index d4d1c06e..790c4756 100644 --- a/src/platform_impl/ios/uikit/coordinate_space.rs +++ b/src/platform_impl/ios/uikit/coordinate_space.rs @@ -1,5 +1,5 @@ -use objc2::foundation::NSObject; -use objc2::{extern_class, ClassType}; +use icrate::Foundation::NSObject; +use objc2::{extern_class, mutability, ClassType}; extern_class!( #[derive(Debug, PartialEq, Eq, Hash)] @@ -7,5 +7,6 @@ extern_class!( unsafe impl ClassType for UICoordinateSpace { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); diff --git a/src/platform_impl/ios/uikit/device.rs b/src/platform_impl/ios/uikit/device.rs index 9910025a..c663d658 100644 --- a/src/platform_impl/ios/uikit/device.rs +++ b/src/platform_impl/ios/uikit/device.rs @@ -1,6 +1,6 @@ -use objc2::foundation::{MainThreadMarker, NSObject}; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use icrate::Foundation::{MainThreadMarker, NSObject}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType}; use super::super::ffi::UIUserInterfaceIdiom; @@ -10,16 +10,17 @@ extern_class!( unsafe impl ClassType for UIDevice { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl UIDevice { - pub fn current(_mtm: MainThreadMarker) -> Id { + pub fn current(_mtm: MainThreadMarker) -> Id { unsafe { msg_send_id![Self::class(), currentDevice] } } - #[sel(userInterfaceIdiom)] + #[method(userInterfaceIdiom)] pub fn userInterfaceIdiom(&self) -> UIUserInterfaceIdiom; } ); diff --git a/src/platform_impl/ios/uikit/event.rs b/src/platform_impl/ios/uikit/event.rs index 9ce24261..fbaccf60 100644 --- a/src/platform_impl/ios/uikit/event.rs +++ b/src/platform_impl/ios/uikit/event.rs @@ -1,5 +1,5 @@ -use objc2::foundation::NSObject; -use objc2::{extern_class, ClassType}; +use icrate::Foundation::NSObject; +use objc2::{extern_class, mutability, ClassType}; extern_class!( #[derive(Debug, PartialEq, Eq, Hash)] @@ -7,5 +7,6 @@ extern_class!( unsafe impl ClassType for UIEvent { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); diff --git a/src/platform_impl/ios/uikit/mod.rs b/src/platform_impl/ios/uikit/mod.rs index d4243748..42b7e1ed 100644 --- a/src/platform_impl/ios/uikit/mod.rs +++ b/src/platform_impl/ios/uikit/mod.rs @@ -4,7 +4,7 @@ use std::os::raw::{c_char, c_int}; -use objc2::foundation::NSString; +use icrate::Foundation::NSString; mod application; mod coordinate_space; diff --git a/src/platform_impl/ios/uikit/responder.rs b/src/platform_impl/ios/uikit/responder.rs index 2a3cdb0a..fc5563f7 100644 --- a/src/platform_impl/ios/uikit/responder.rs +++ b/src/platform_impl/ios/uikit/responder.rs @@ -1,5 +1,5 @@ -use objc2::foundation::NSObject; -use objc2::{extern_class, ClassType}; +use icrate::Foundation::NSObject; +use objc2::{extern_class, mutability, ClassType}; extern_class!( #[derive(Debug, PartialEq, Eq, Hash)] @@ -7,5 +7,6 @@ extern_class!( unsafe impl ClassType for UIResponder { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); diff --git a/src/platform_impl/ios/uikit/screen.rs b/src/platform_impl/ios/uikit/screen.rs index 770b9237..94a55b16 100644 --- a/src/platform_impl/ios/uikit/screen.rs +++ b/src/platform_impl/ios/uikit/screen.rs @@ -1,7 +1,7 @@ +use icrate::Foundation::{CGFloat, CGRect, MainThreadMarker, NSArray, NSInteger, NSObject}; use objc2::encode::{Encode, Encoding}; -use objc2::foundation::{CGFloat, CGRect, MainThreadMarker, NSArray, NSInteger, NSObject}; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType}; use super::{UICoordinateSpace, UIScreenMode}; @@ -11,53 +11,54 @@ extern_class!( unsafe impl ClassType for UIScreen { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl UIScreen { - pub fn main(_mtm: MainThreadMarker) -> Id { + pub fn main(_mtm: MainThreadMarker) -> Id { unsafe { msg_send_id![Self::class(), mainScreen] } } - pub fn screens(_mtm: MainThreadMarker) -> Id, Shared> { + pub fn screens(_mtm: MainThreadMarker) -> Id> { unsafe { msg_send_id![Self::class(), screens] } } - #[sel(bounds)] + #[method(bounds)] pub fn bounds(&self) -> CGRect; - #[sel(scale)] + #[method(scale)] pub fn scale(&self) -> CGFloat; - #[sel(nativeBounds)] + #[method(nativeBounds)] pub fn nativeBounds(&self) -> CGRect; - #[sel(nativeScale)] + #[method(nativeScale)] pub fn nativeScale(&self) -> CGFloat; - #[sel(maximumFramesPerSecond)] + #[method(maximumFramesPerSecond)] pub fn maximumFramesPerSecond(&self) -> NSInteger; - pub fn mirroredScreen(&self) -> Id { + pub fn mirroredScreen(&self) -> Id { unsafe { msg_send_id![Self::class(), mirroredScreen] } } - pub fn preferredMode(&self) -> Option> { + pub fn preferredMode(&self) -> Option> { unsafe { msg_send_id![self, preferredMode] } } - #[sel(setCurrentMode:)] + #[method(setCurrentMode:)] pub fn setCurrentMode(&self, mode: Option<&UIScreenMode>); - pub fn availableModes(&self) -> Id, Shared> { + pub fn availableModes(&self) -> Id> { unsafe { msg_send_id![self, availableModes] } } - #[sel(setOverscanCompensation:)] + #[method(setOverscanCompensation:)] pub fn setOverscanCompensation(&self, overscanCompensation: UIScreenOverscanCompensation); - pub fn coordinateSpace(&self) -> Id { + pub fn coordinateSpace(&self) -> Id { unsafe { msg_send_id![self, coordinateSpace] } } } diff --git a/src/platform_impl/ios/uikit/screen_mode.rs b/src/platform_impl/ios/uikit/screen_mode.rs index 1ef1a3dc..096cae49 100644 --- a/src/platform_impl/ios/uikit/screen_mode.rs +++ b/src/platform_impl/ios/uikit/screen_mode.rs @@ -1,5 +1,5 @@ -use objc2::foundation::{CGSize, NSObject}; -use objc2::{extern_class, extern_methods, ClassType}; +use icrate::Foundation::{CGSize, NSObject}; +use objc2::{extern_class, extern_methods, mutability, ClassType}; extern_class!( #[derive(Debug, PartialEq, Eq, Hash)] @@ -7,12 +7,13 @@ extern_class!( unsafe impl ClassType for UIScreenMode { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl UIScreenMode { - #[sel(size)] + #[method(size)] pub fn size(&self) -> CGSize; } ); diff --git a/src/platform_impl/ios/uikit/touch.rs b/src/platform_impl/ios/uikit/touch.rs index d0c7c2c7..bff0e8fb 100644 --- a/src/platform_impl/ios/uikit/touch.rs +++ b/src/platform_impl/ios/uikit/touch.rs @@ -1,6 +1,6 @@ +use icrate::Foundation::{CGFloat, CGPoint, NSInteger, NSObject}; use objc2::encode::{Encode, Encoding}; -use objc2::foundation::{CGFloat, CGPoint, NSInteger, NSObject}; -use objc2::{extern_class, extern_methods, ClassType}; +use objc2::{extern_class, extern_methods, mutability, ClassType}; use super::UIView; @@ -10,27 +10,28 @@ extern_class!( unsafe impl ClassType for UITouch { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl UITouch { - #[sel(locationInView:)] + #[method(locationInView:)] pub fn locationInView(&self, view: Option<&UIView>) -> CGPoint; - #[sel(type)] + #[method(type)] pub fn type_(&self) -> UITouchType; - #[sel(force)] + #[method(force)] pub fn force(&self) -> CGFloat; - #[sel(maximumPossibleForce)] + #[method(maximumPossibleForce)] pub fn maximumPossibleForce(&self) -> CGFloat; - #[sel(altitudeAngle)] + #[method(altitudeAngle)] pub fn altitudeAngle(&self) -> CGFloat; - #[sel(phase)] + #[method(phase)] pub fn phase(&self) -> UITouchPhase; } ); diff --git a/src/platform_impl/ios/uikit/trait_collection.rs b/src/platform_impl/ios/uikit/trait_collection.rs index 7ae58d2d..b6af7c9d 100644 --- a/src/platform_impl/ios/uikit/trait_collection.rs +++ b/src/platform_impl/ios/uikit/trait_collection.rs @@ -1,6 +1,6 @@ +use icrate::Foundation::{NSInteger, NSObject}; use objc2::encode::{Encode, Encoding}; -use objc2::foundation::{NSInteger, NSObject}; -use objc2::{extern_class, extern_methods, ClassType}; +use objc2::{extern_class, extern_methods, mutability, ClassType}; extern_class!( #[derive(Debug, PartialEq, Eq, Hash)] @@ -8,12 +8,13 @@ extern_class!( unsafe impl ClassType for UITraitCollection { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl UITraitCollection { - #[sel(forceTouchCapability)] + #[method(forceTouchCapability)] pub fn forceTouchCapability(&self) -> UIForceTouchCapability; } ); diff --git a/src/platform_impl/ios/uikit/view.rs b/src/platform_impl/ios/uikit/view.rs index 05c22956..216db016 100644 --- a/src/platform_impl/ios/uikit/view.rs +++ b/src/platform_impl/ios/uikit/view.rs @@ -1,7 +1,7 @@ +use icrate::Foundation::{CGFloat, CGRect, NSObject}; use objc2::encode::{Encode, Encoding}; -use objc2::foundation::{CGFloat, CGRect, NSObject}; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType}; use super::{UICoordinateSpace, UIResponder, UIViewController}; @@ -12,57 +12,58 @@ extern_class!( unsafe impl ClassType for UIView { #[inherits(NSObject)] type Super = UIResponder; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl UIView { - #[sel(bounds)] + #[method(bounds)] pub fn bounds(&self) -> CGRect; - #[sel(setBounds:)] + #[method(setBounds:)] pub fn setBounds(&self, value: CGRect); - #[sel(frame)] + #[method(frame)] pub fn frame(&self) -> CGRect; - #[sel(setFrame:)] + #[method(setFrame:)] pub fn setFrame(&self, value: CGRect); - #[sel(contentScaleFactor)] + #[method(contentScaleFactor)] pub fn contentScaleFactor(&self) -> CGFloat; - #[sel(setContentScaleFactor:)] + #[method(setContentScaleFactor:)] pub fn setContentScaleFactor(&self, val: CGFloat); - #[sel(setMultipleTouchEnabled:)] + #[method(setMultipleTouchEnabled:)] pub fn setMultipleTouchEnabled(&self, val: bool); - pub fn rootViewController(&self) -> Option> { + pub fn rootViewController(&self) -> Option> { unsafe { msg_send_id![self, rootViewController] } } - #[sel(setRootViewController:)] + #[method(setRootViewController:)] pub fn setRootViewController(&self, rootViewController: Option<&UIViewController>); - #[sel(convertRect:toCoordinateSpace:)] + #[method(convertRect:toCoordinateSpace:)] pub fn convertRect_toCoordinateSpace( &self, rect: CGRect, coordinateSpace: &UICoordinateSpace, ) -> CGRect; - #[sel(convertRect:fromCoordinateSpace:)] + #[method(convertRect:fromCoordinateSpace:)] pub fn convertRect_fromCoordinateSpace( &self, rect: CGRect, coordinateSpace: &UICoordinateSpace, ) -> CGRect; - #[sel(safeAreaInsets)] + #[method(safeAreaInsets)] pub fn safeAreaInsets(&self) -> UIEdgeInsets; - #[sel(setNeedsDisplay)] + #[method(setNeedsDisplay)] pub fn setNeedsDisplay(&self); } ); diff --git a/src/platform_impl/ios/uikit/view_controller.rs b/src/platform_impl/ios/uikit/view_controller.rs index 03f0e166..515d71b0 100644 --- a/src/platform_impl/ios/uikit/view_controller.rs +++ b/src/platform_impl/ios/uikit/view_controller.rs @@ -1,7 +1,7 @@ +use icrate::Foundation::{NSObject, NSUInteger}; use objc2::encode::{Encode, Encoding}; -use objc2::foundation::{NSObject, NSUInteger}; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType}; use super::{UIResponder, UIView}; @@ -12,28 +12,29 @@ extern_class!( unsafe impl ClassType for UIViewController { #[inherits(NSObject)] type Super = UIResponder; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl UIViewController { - #[sel(attemptRotationToDeviceOrientation)] + #[method(attemptRotationToDeviceOrientation)] pub fn attemptRotationToDeviceOrientation(); - #[sel(setNeedsStatusBarAppearanceUpdate)] + #[method(setNeedsStatusBarAppearanceUpdate)] pub fn setNeedsStatusBarAppearanceUpdate(&self); - #[sel(setNeedsUpdateOfHomeIndicatorAutoHidden)] + #[method(setNeedsUpdateOfHomeIndicatorAutoHidden)] pub fn setNeedsUpdateOfHomeIndicatorAutoHidden(&self); - #[sel(setNeedsUpdateOfScreenEdgesDeferringSystemGestures)] + #[method(setNeedsUpdateOfScreenEdgesDeferringSystemGestures)] pub fn setNeedsUpdateOfScreenEdgesDeferringSystemGestures(&self); - pub fn view(&self) -> Option> { + pub fn view(&self) -> Option> { unsafe { msg_send_id![self, view] } } - #[sel(setView:)] + #[method(setView:)] pub fn setView(&self, view: Option<&UIView>); } ); diff --git a/src/platform_impl/ios/uikit/window.rs b/src/platform_impl/ios/uikit/window.rs index ed78e56f..b99e96d4 100644 --- a/src/platform_impl/ios/uikit/window.rs +++ b/src/platform_impl/ios/uikit/window.rs @@ -1,6 +1,6 @@ -use objc2::foundation::NSObject; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use icrate::Foundation::NSObject; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType}; use super::{UIResponder, UIScreen, UIView}; @@ -11,25 +11,26 @@ extern_class!( unsafe impl ClassType for UIWindow { #[inherits(UIResponder, NSObject)] type Super = UIView; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl UIWindow { - pub fn screen(&self) -> Id { + pub fn screen(&self) -> Id { unsafe { msg_send_id![self, screen] } } - #[sel(setScreen:)] + #[method(setScreen:)] pub fn setScreen(&self, screen: &UIScreen); - #[sel(setHidden:)] + #[method(setHidden:)] pub fn setHidden(&self, flag: bool); - #[sel(makeKeyAndVisible)] + #[method(makeKeyAndVisible)] pub fn makeKeyAndVisible(&self); - #[sel(isKeyWindow)] + #[method(isKeyWindow)] pub fn isKeyWindow(&self) -> bool; } ); diff --git a/src/platform_impl/ios/view.rs b/src/platform_impl/ios/view.rs index 12955f1d..6e2ad3bb 100644 --- a/src/platform_impl/ios/view.rs +++ b/src/platform_impl/ios/view.rs @@ -2,11 +2,11 @@ use std::cell::Cell; use std::ptr::NonNull; +use icrate::Foundation::{CGFloat, CGRect, MainThreadMarker, NSObject, NSObjectProtocol, NSSet}; use objc2::declare::{Ivar, IvarDrop}; -use objc2::foundation::{CGFloat, CGRect, MainThreadMarker, NSObject, NSSet}; -use objc2::rc::{Id, Shared}; +use objc2::rc::Id; use objc2::runtime::Class; -use objc2::{declare_class, extern_methods, msg_send, msg_send_id, ClassType}; +use objc2::{declare_class, extern_methods, msg_send, msg_send_id, mutability, ClassType}; use super::uikit::{ UIApplication, UIDevice, UIEvent, UIForceTouchCapability, UIInterfaceOrientationMask, @@ -29,16 +29,17 @@ use crate::{ }; declare_class!( - pub(crate) struct WinitView {} + pub(crate) struct WinitView; unsafe impl ClassType for WinitView { #[inherits(UIResponder, NSObject)] type Super = UIView; + type Mutability = mutability::InteriorMutable; const NAME: &'static str = "WinitUIView"; } unsafe impl WinitView { - #[sel(drawRect:)] + #[method(drawRect:)] fn draw_rect(&self, rect: CGRect) { let window = self.window().unwrap(); unsafe { @@ -49,7 +50,7 @@ declare_class!( let _: () = unsafe { msg_send![super(self), drawRect: rect] }; } - #[sel(layoutSubviews)] + #[method(layoutSubviews)] fn layout_subviews(&self) { let _: () = unsafe { msg_send![super(self), layoutSubviews] }; @@ -81,7 +82,7 @@ declare_class!( } } - #[sel(setContentScaleFactor:)] + #[method(setContentScaleFactor:)] fn set_content_scale_factor(&self, untrusted_scale_factor: CGFloat) { let _: () = unsafe { msg_send![super(self), setContentScaleFactor: untrusted_scale_factor] }; @@ -131,22 +132,22 @@ declare_class!( } } - #[sel(touchesBegan:withEvent:)] + #[method(touchesBegan:withEvent:)] fn touches_began(&self, touches: &NSSet, _event: Option<&UIEvent>) { self.handle_touches(touches) } - #[sel(touchesMoved:withEvent:)] + #[method(touchesMoved:withEvent:)] fn touches_moved(&self, touches: &NSSet, _event: Option<&UIEvent>) { self.handle_touches(touches) } - #[sel(touchesEnded:withEvent:)] + #[method(touchesEnded:withEvent:)] fn touches_ended(&self, touches: &NSSet, _event: Option<&UIEvent>) { self.handle_touches(touches) } - #[sel(touchesCancelled:withEvent:)] + #[method(touchesCancelled:withEvent:)] fn touches_cancelled(&self, touches: &NSSet, _event: Option<&UIEvent>) { self.handle_touches(touches) } @@ -156,16 +157,16 @@ declare_class!( extern_methods!( #[allow(non_snake_case)] unsafe impl WinitView { - fn window(&self) -> Option> { + fn window(&self) -> Option> { unsafe { msg_send_id![self, window] } } - unsafe fn traitCollection(&self) -> Id { + unsafe fn traitCollection(&self) -> Id { msg_send_id![self, traitCollection] } // TODO: Allow the user to customize this - #[sel(layerClass)] + #[method(layerClass)] pub(crate) fn layerClass() -> &'static Class; } ); @@ -176,9 +177,8 @@ impl WinitView { _window_attributes: &WindowAttributes, platform_attributes: &PlatformSpecificWindowBuilderAttributes, frame: CGRect, - ) -> Id { - let this: Id = - unsafe { msg_send_id![msg_send_id![Self::class(), alloc], initWithFrame: frame] }; + ) -> Id { + let this: Id = unsafe { msg_send_id![Self::alloc(), initWithFrame: frame] }; this.setMultipleTouchEnabled(true); @@ -258,7 +258,7 @@ impl WinitView { } } -struct ViewControllerState { +pub struct ViewControllerState { prefers_status_bar_hidden: Cell, prefers_home_indicator_auto_hidden: Cell, supported_orientations: Cell, @@ -267,19 +267,22 @@ struct ViewControllerState { declare_class!( pub(crate) struct WinitViewController { - state: IvarDrop>, + state: IvarDrop, "_state">, } + mod view_controller_ivars; + unsafe impl ClassType for WinitViewController { #[inherits(UIResponder, NSObject)] type Super = UIViewController; + type Mutability = mutability::InteriorMutable; const NAME: &'static str = "WinitUIViewController"; } unsafe impl WinitViewController { - #[sel(init)] - fn init(&mut self) -> Option> { - let this: Option<&mut Self> = unsafe { msg_send![super(self), init] }; + #[method(init)] + unsafe fn init(this: *mut Self) -> Option> { + let this: Option<&mut Self> = msg_send![super(this), init]; this.map(|this| { // These are set in WinitViewController::new, it's just to set them // to _something_. @@ -300,27 +303,27 @@ declare_class!( } unsafe impl WinitViewController { - #[sel(shouldAutorotate)] + #[method(shouldAutorotate)] fn should_autorotate(&self) -> bool { true } - #[sel(prefersStatusBarHidden)] + #[method(prefersStatusBarHidden)] fn prefers_status_bar_hidden(&self) -> bool { self.state.prefers_status_bar_hidden.get() } - #[sel(prefersHomeIndicatorAutoHidden)] + #[method(prefersHomeIndicatorAutoHidden)] fn prefers_home_indicator_auto_hidden(&self) -> bool { self.state.prefers_home_indicator_auto_hidden.get() } - #[sel(supportedInterfaceOrientations)] + #[method(supportedInterfaceOrientations)] fn supported_orientations(&self) -> UIInterfaceOrientationMask { self.state.supported_orientations.get() } - #[sel(preferredScreenEdgesDeferringSystemGestures)] + #[method(preferredScreenEdgesDeferringSystemGestures)] fn preferred_screen_edges_deferring_system_gestures(&self) -> UIRectEdge { self.state .preferred_screen_edges_deferring_system_gestures @@ -388,9 +391,8 @@ impl WinitViewController { _window_attributes: &WindowAttributes, platform_attributes: &PlatformSpecificWindowBuilderAttributes, view: &UIView, - ) -> Id { - let this: Id = - unsafe { msg_send_id![msg_send_id![Self::class(), alloc], init] }; + ) -> Id { + let this: Id = unsafe { msg_send_id![Self::alloc(), init] }; this.set_prefers_status_bar_hidden(platform_attributes.prefers_status_bar_hidden); @@ -414,15 +416,17 @@ impl WinitViewController { declare_class!( #[derive(Debug, PartialEq, Eq, Hash)] - pub(crate) struct WinitUIWindow {} + pub(crate) struct WinitUIWindow; unsafe impl ClassType for WinitUIWindow { #[inherits(UIResponder, NSObject)] type Super = UIWindow; + type Mutability = mutability::InteriorMutable; + const NAME: &'static str = "WinitUIWindow"; } unsafe impl WinitUIWindow { - #[sel(becomeKeyWindow)] + #[method(becomeKeyWindow)] fn become_key_window(&self) { unsafe { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::WindowEvent { @@ -433,7 +437,7 @@ declare_class!( let _: () = unsafe { msg_send![super(self), becomeKeyWindow] }; } - #[sel(resignKeyWindow)] + #[method(resignKeyWindow)] fn resign_key_window(&self) { unsafe { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::WindowEvent { @@ -453,9 +457,8 @@ impl WinitUIWindow { _platform_attributes: &PlatformSpecificWindowBuilderAttributes, frame: CGRect, view_controller: &UIViewController, - ) -> Id { - let this: Id = - unsafe { msg_send_id![msg_send_id![Self::class(), alloc], initWithFrame: frame] }; + ) -> Id { + let this: Id = unsafe { msg_send_id![Self::alloc(), initWithFrame: frame] }; this.setRootViewController(Some(view_controller)); @@ -482,15 +485,17 @@ impl WinitUIWindow { } declare_class!( - pub struct WinitApplicationDelegate {} + pub struct WinitApplicationDelegate; unsafe impl ClassType for WinitApplicationDelegate { type Super = NSObject; + type Mutability = mutability::InteriorMutable; + const NAME: &'static str = "WinitApplicationDelegate"; } // UIApplicationDelegate protocol unsafe impl WinitApplicationDelegate { - #[sel(application:didFinishLaunchingWithOptions:)] + #[method(application:didFinishLaunchingWithOptions:)] fn did_finish_launching(&self, _application: &UIApplication, _: *mut NSObject) -> bool { unsafe { app_state::did_finish_launching(); @@ -498,22 +503,23 @@ declare_class!( true } - #[sel(applicationDidBecomeActive:)] + #[method(applicationDidBecomeActive:)] fn did_become_active(&self, _application: &UIApplication) { unsafe { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::Resumed)) } } - #[sel(applicationWillResignActive:)] + #[method(applicationWillResignActive:)] fn will_resign_active(&self, _application: &UIApplication) { unsafe { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::Suspended)) } } - #[sel(applicationWillEnterForeground:)] + #[method(applicationWillEnterForeground:)] fn will_enter_foreground(&self, _application: &UIApplication) {} - #[sel(applicationDidEnterBackground:)] + + #[method(applicationDidEnterBackground:)] fn did_enter_background(&self, _application: &UIApplication) {} - #[sel(applicationWillTerminate:)] + #[method(applicationWillTerminate:)] fn will_terminate(&self, application: &UIApplication) { let mut events = Vec::new(); for window in application.windows().iter() { diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index 72735645..71875be6 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -6,8 +6,8 @@ use std::{ ops::{Deref, DerefMut}, }; -use objc2::foundation::{CGFloat, CGPoint, CGRect, CGSize, MainThreadMarker}; -use objc2::rc::{Id, Shared}; +use icrate::Foundation::{CGFloat, CGPoint, CGRect, CGSize, MainThreadMarker}; +use objc2::rc::Id; use objc2::runtime::Object; use objc2::{class, msg_send}; use raw_window_handle::{RawDisplayHandle, RawWindowHandle, UiKitDisplayHandle, UiKitWindowHandle}; @@ -32,9 +32,9 @@ use crate::{ }; pub struct Inner { - pub(crate) window: Id, - pub(crate) view_controller: Id, - pub(crate) view: Id, + pub(crate) window: Id, + pub(crate) view_controller: Id, + pub(crate) view: Id, gl_or_metal_backed: bool, } diff --git a/src/platform_impl/macos/app.rs b/src/platform_impl/macos/app.rs index 864cabd3..8a56b77b 100644 --- a/src/platform_impl/macos/app.rs +++ b/src/platform_impl/macos/app.rs @@ -1,7 +1,7 @@ #![allow(clippy::unnecessary_cast)] -use objc2::foundation::NSObject; -use objc2::{declare_class, msg_send, ClassType}; +use icrate::Foundation::NSObject; +use objc2::{declare_class, msg_send, mutability, ClassType}; use super::appkit::{NSApplication, NSEvent, NSEventModifierFlags, NSEventType, NSResponder}; use super::{app_state::AppState, event::EventWrapper, DEVICE_ID}; @@ -9,18 +9,20 @@ use crate::event::{DeviceEvent, ElementState, Event}; declare_class!( #[derive(Debug, PartialEq, Eq, Hash)] - pub(super) struct WinitApplication {} + pub(super) struct WinitApplication; unsafe impl ClassType for WinitApplication { #[inherits(NSResponder, NSObject)] type Super = NSApplication; + type Mutability = mutability::InteriorMutable; + const NAME: &'static str = "WinitApplication"; } unsafe impl WinitApplication { // Normally, holding Cmd + any key never sends us a `keyUp` event for that key. // Overriding `sendEvent:` like this fixes that. (https://stackoverflow.com/a/15294196) // Fun fact: Firefox still has this bug! (https://bugzilla.mozilla.org/show_bug.cgi?id=1299553) - #[sel(sendEvent:)] + #[method(sendEvent:)] fn send_event(&self, event: &NSEvent) { // For posterity, there are some undocumented event types // (https://github.com/servo/cocoa-rs/issues/155) diff --git a/src/platform_impl/macos/app_delegate.rs b/src/platform_impl/macos/app_delegate.rs index 7a57bf8c..4b3be65f 100644 --- a/src/platform_impl/macos/app_delegate.rs +++ b/src/platform_impl/macos/app_delegate.rs @@ -1,9 +1,10 @@ use std::ptr::NonNull; -use objc2::foundation::NSObject; -use objc2::rc::{Id, Shared}; +use icrate::Foundation::NSObject; +use objc2::declare::{IvarBool, IvarEncode}; +use objc2::rc::Id; use objc2::runtime::Object; -use objc2::{declare_class, msg_send, msg_send_id, ClassType}; +use objc2::{declare_class, msg_send, msg_send_id, mutability, ClassType}; use super::app_state::AppState; use super::appkit::NSApplicationActivationPolicy; @@ -11,25 +12,28 @@ use super::appkit::NSApplicationActivationPolicy; declare_class!( #[derive(Debug)] pub(super) struct ApplicationDelegate { - activation_policy: NSApplicationActivationPolicy, - default_menu: bool, - activate_ignoring_other_apps: bool, + activation_policy: IvarEncode, + default_menu: IvarBool<"_default_menu">, + activate_ignoring_other_apps: IvarBool<"_activate_ignoring_other_apps">, } + mod ivars; + unsafe impl ClassType for ApplicationDelegate { type Super = NSObject; + type Mutability = mutability::InteriorMutable; const NAME: &'static str = "WinitApplicationDelegate"; } unsafe impl ApplicationDelegate { - #[sel(initWithActivationPolicy:defaultMenu:activateIgnoringOtherApps:)] + #[method(initWithActivationPolicy:defaultMenu:activateIgnoringOtherApps:)] unsafe fn init( - &mut self, + this: *mut Self, activation_policy: NSApplicationActivationPolicy, default_menu: bool, activate_ignoring_other_apps: bool, ) -> Option> { - let this: Option<&mut Self> = unsafe { msg_send![super(self), init] }; + let this: Option<&mut Self> = unsafe { msg_send![super(this), init] }; this.map(|this| { *this.activation_policy = activation_policy; *this.default_menu = default_menu; @@ -38,8 +42,8 @@ declare_class!( }) } - #[sel(applicationDidFinishLaunching:)] - fn did_finish_launching(&self, _sender: *const Object) { + #[method(applicationDidFinishLaunching:)] + fn did_finish_launching(&self, _sender: Option<&Object>) { trace_scope!("applicationDidFinishLaunching:"); AppState::launched( *self.activation_policy, @@ -48,8 +52,8 @@ declare_class!( ); } - #[sel(applicationWillTerminate:)] - fn will_terminate(&self, _sender: *const Object) { + #[method(applicationWillTerminate:)] + fn will_terminate(&self, _sender: Option<&Object>) { trace_scope!("applicationWillTerminate:"); // TODO: Notify every window that it will be destroyed, like done in iOS? AppState::exit(); @@ -62,10 +66,10 @@ impl ApplicationDelegate { activation_policy: NSApplicationActivationPolicy, default_menu: bool, activate_ignoring_other_apps: bool, - ) -> Id { + ) -> Id { unsafe { msg_send_id![ - msg_send_id![Self::class(), alloc], + Self::alloc(), initWithActivationPolicy: activation_policy, defaultMenu: default_menu, activateIgnoringOtherApps: activate_ignoring_other_apps, diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 175324ac..1d49d22f 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -12,7 +12,7 @@ use std::{ }; use core_foundation::runloop::{CFRunLoopGetMain, CFRunLoopWakeUp}; -use objc2::foundation::{is_main_thread, NSSize}; +use icrate::Foundation::{is_main_thread, NSSize}; use objc2::rc::autoreleasepool; use once_cell::sync::Lazy; diff --git a/src/platform_impl/macos/appkit/appearance.rs b/src/platform_impl/macos/appkit/appearance.rs index c13abbff..6db7c6d0 100644 --- a/src/platform_impl/macos/appkit/appearance.rs +++ b/src/platform_impl/macos/appkit/appearance.rs @@ -1,6 +1,6 @@ -use objc2::foundation::{NSArray, NSObject, NSString}; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use icrate::Foundation::{NSArray, NSObject, NSString}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, mutability, ClassType}; extern_class!( #[derive(Debug, PartialEq, Eq, Hash)] @@ -8,6 +8,7 @@ extern_class!( unsafe impl ClassType for NSAppearance { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); @@ -15,15 +16,13 @@ type NSAppearanceName = NSString; extern_methods!( unsafe impl NSAppearance { - pub fn appearanceNamed(name: &NSAppearanceName) -> Id { - unsafe { msg_send_id![Self::class(), appearanceNamed: name] } - } + #[method_id(appearanceNamed:)] + pub fn appearanceNamed(name: &NSAppearanceName) -> Id; + #[method_id(bestMatchFromAppearancesWithNames:)] pub fn bestMatchFromAppearancesWithNames( &self, appearances: &NSArray, - ) -> Id { - unsafe { msg_send_id![self, bestMatchFromAppearancesWithNames: appearances,] } - } + ) -> Id; } ); diff --git a/src/platform_impl/macos/appkit/application.rs b/src/platform_impl/macos/appkit/application.rs index 27183423..952f49d1 100644 --- a/src/platform_impl/macos/appkit/application.rs +++ b/src/platform_impl/macos/appkit/application.rs @@ -1,7 +1,7 @@ -use objc2::foundation::{MainThreadMarker, NSArray, NSInteger, NSObject, NSUInteger}; -use objc2::rc::{Id, Shared}; +use icrate::Foundation::{MainThreadMarker, NSArray, NSInteger, NSObject, NSUInteger}; +use objc2::rc::Id; use objc2::runtime::Object; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType}; use objc2::{Encode, Encoding}; use super::{NSAppearance, NSEvent, NSMenu, NSResponder, NSWindow}; @@ -13,10 +13,11 @@ extern_class!( unsafe impl ClassType for NSApplication { #[inherits(NSObject)] type Super = NSResponder; + type Mutability = mutability::InteriorMutable; } ); -pub(crate) fn NSApp() -> Id { +pub(crate) fn NSApp() -> Id { // TODO: Only allow access from main thread NSApplication::shared(unsafe { MainThreadMarker::new_unchecked() }) } @@ -26,70 +27,66 @@ extern_methods!( /// This can only be called on the main thread since it may initialize /// the application and since it's parameters may be changed by the main /// thread at any time (hence it is only safe to access on the main thread). - pub fn shared(_mtm: MainThreadMarker) -> Id { + pub fn shared(_mtm: MainThreadMarker) -> Id { let app: Option<_> = unsafe { msg_send_id![Self::class(), sharedApplication] }; // SAFETY: `sharedApplication` always initializes the app if it isn't already unsafe { app.unwrap_unchecked() } } - pub fn currentEvent(&self) -> Option> { - unsafe { msg_send_id![self, currentEvent] } - } + #[method_id(currentEvent)] + pub fn currentEvent(&self) -> Option>; - #[sel(postEvent:atStart:)] + #[method(postEvent:atStart:)] pub fn postEvent_atStart(&self, event: &NSEvent, front_of_queue: bool); - #[sel(presentationOptions)] + #[method(presentationOptions)] pub fn presentationOptions(&self) -> NSApplicationPresentationOptions; - pub fn windows(&self) -> Id, Shared> { - unsafe { msg_send_id![self, windows] } - } + #[method_id(windows)] + pub fn windows(&self) -> Id>; - pub fn keyWindow(&self) -> Option> { - unsafe { msg_send_id![self, keyWindow] } - } + #[method_id(keyWindow)] + pub fn keyWindow(&self) -> Option>; // TODO: NSApplicationDelegate - #[sel(setDelegate:)] + #[method(setDelegate:)] pub fn setDelegate(&self, delegate: &Object); - #[sel(setPresentationOptions:)] + #[method(setPresentationOptions:)] pub fn setPresentationOptions(&self, options: NSApplicationPresentationOptions); - #[sel(hide:)] + #[method(hide:)] pub fn hide(&self, sender: Option<&Object>); - #[sel(orderFrontCharacterPalette:)] + #[method(orderFrontCharacterPalette:)] #[allow(dead_code)] pub fn orderFrontCharacterPalette(&self, sender: Option<&Object>); - #[sel(hideOtherApplications:)] + #[method(hideOtherApplications:)] pub fn hideOtherApplications(&self, sender: Option<&Object>); - #[sel(stop:)] + #[method(stop:)] pub fn stop(&self, sender: Option<&Object>); - #[sel(activateIgnoringOtherApps:)] + #[method(activateIgnoringOtherApps:)] pub fn activateIgnoringOtherApps(&self, ignore: bool); - #[sel(requestUserAttention:)] + #[method(requestUserAttention:)] pub fn requestUserAttention(&self, type_: NSRequestUserAttentionType) -> NSInteger; - #[sel(setActivationPolicy:)] + #[method(setActivationPolicy:)] pub fn setActivationPolicy(&self, policy: NSApplicationActivationPolicy) -> bool; - #[sel(setMainMenu:)] + #[method(setMainMenu:)] pub fn setMainMenu(&self, menu: &NSMenu); - pub fn effectiveAppearance(&self) -> Id { - unsafe { msg_send_id![self, effectiveAppearance] } - } + #[method_id(effectiveAppearance)] + pub fn effectiveAppearance(&self) -> Id; - #[sel(setAppearance:)] + #[method(setAppearance:)] pub fn setAppearance(&self, appearance: Option<&NSAppearance>); - #[sel(run)] + #[method(run)] pub unsafe fn run(&self); } ); diff --git a/src/platform_impl/macos/appkit/button.rs b/src/platform_impl/macos/appkit/button.rs index c4a61ca1..eb3c57a5 100644 --- a/src/platform_impl/macos/appkit/button.rs +++ b/src/platform_impl/macos/appkit/button.rs @@ -1,5 +1,5 @@ -use objc2::foundation::NSObject; -use objc2::{extern_class, ClassType}; +use icrate::Foundation::NSObject; +use objc2::{extern_class, mutability, ClassType}; use super::{NSControl, NSResponder, NSView}; @@ -10,5 +10,6 @@ extern_class!( unsafe impl ClassType for NSButton { #[inherits(NSView, NSResponder, NSObject)] type Super = NSControl; + type Mutability = mutability::InteriorMutable; } ); diff --git a/src/platform_impl/macos/appkit/color.rs b/src/platform_impl/macos/appkit/color.rs index 59399731..b5477a1e 100644 --- a/src/platform_impl/macos/appkit/color.rs +++ b/src/platform_impl/macos/appkit/color.rs @@ -1,6 +1,6 @@ -use objc2::foundation::NSObject; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use icrate::Foundation::NSObject; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, mutability, ClassType}; extern_class!( /// An object that stores color data and sometimes opacity (alpha value). @@ -11,6 +11,7 @@ extern_class!( unsafe impl ClassType for NSColor { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); @@ -21,8 +22,7 @@ unsafe impl Sync for NSColor {} extern_methods!( unsafe impl NSColor { - pub fn clear() -> Id { - unsafe { msg_send_id![Self::class(), clearColor] } - } + #[method_id(clearColor)] + pub fn clear() -> Id; } ); diff --git a/src/platform_impl/macos/appkit/control.rs b/src/platform_impl/macos/appkit/control.rs index 1ca52195..d38f4b10 100644 --- a/src/platform_impl/macos/appkit/control.rs +++ b/src/platform_impl/macos/appkit/control.rs @@ -1,5 +1,5 @@ -use objc2::foundation::NSObject; -use objc2::{extern_class, extern_methods, ClassType}; +use icrate::Foundation::NSObject; +use objc2::{extern_class, extern_methods, mutability, ClassType}; use super::{NSResponder, NSView}; @@ -10,15 +10,16 @@ extern_class!( unsafe impl ClassType for NSControl { #[inherits(NSResponder, NSObject)] type Super = NSView; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl NSControl { - #[sel(setEnabled:)] + #[method(setEnabled:)] pub fn setEnabled(&self, enabled: bool); - #[sel(isEnabled)] + #[method(isEnabled)] pub fn isEnabled(&self) -> bool; } ); diff --git a/src/platform_impl/macos/appkit/cursor.rs b/src/platform_impl/macos/appkit/cursor.rs index dd86026c..6377ad42 100644 --- a/src/platform_impl/macos/appkit/cursor.rs +++ b/src/platform_impl/macos/appkit/cursor.rs @@ -1,9 +1,12 @@ use once_cell::sync::Lazy; -use objc2::foundation::{NSData, NSDictionary, NSNumber, NSObject, NSPoint, NSString}; -use objc2::rc::{DefaultId, Id, Shared}; +use icrate::ns_string; +use icrate::Foundation::{ + NSData, NSDictionary, NSNumber, NSObject, NSObjectProtocol, NSPoint, NSString, +}; +use objc2::rc::{DefaultId, Id}; use objc2::runtime::Sel; -use objc2::{extern_class, extern_methods, msg_send_id, ns_string, sel, ClassType}; +use objc2::{extern_class, extern_methods, msg_send_id, mutability, sel, ClassType}; use super::NSImage; use crate::window::CursorIcon; @@ -15,6 +18,7 @@ extern_class!( unsafe impl ClassType for NSCursor { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); @@ -29,7 +33,7 @@ macro_rules! def_cursor { pub fn $name:ident(); )*} => {$( $(#[$($m)*])* - pub fn $name() -> Id { + pub fn $name() -> Id { unsafe { msg_send_id![Self::class(), $name] } } )*}; @@ -41,7 +45,7 @@ macro_rules! def_undocumented_cursor { pub fn $name:ident(); )*} => {$( $(#[$($m)*])* - pub fn $name() -> Id { + pub fn $name() -> Id { unsafe { Self::from_selector(sel!($name)).unwrap_or_else(|| Default::default()) } } )*}; @@ -71,12 +75,11 @@ extern_methods!( ); // Creating cursors should be thread-safe, though using them for anything probably isn't. - pub fn new(image: &NSImage, hotSpot: NSPoint) -> Id { - let this = unsafe { msg_send_id![Self::class(), alloc] }; - unsafe { msg_send_id![this, initWithImage: image, hotSpot: hotSpot] } + pub fn new(image: &NSImage, hotSpot: NSPoint) -> Id { + unsafe { msg_send_id![Self::alloc(), initWithImage: image, hotSpot: hotSpot] } } - pub fn invisible() -> Id { + pub fn invisible() -> Id { // 16x16 GIF data for invisible cursor // You can reproduce this via ImageMagick. // $ convert -size 16x16 xc:none cursor.gif @@ -87,7 +90,7 @@ extern_methods!( 0xCB, 0xED, 0x0F, 0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B, ]; - static CURSOR: Lazy> = Lazy::new(|| { + static CURSOR: Lazy> = Lazy::new(|| { // TODO: Consider using `dataWithBytesNoCopy:` let data = NSData::with_bytes(CURSOR_BYTES); let image = NSImage::new_with_data(&data); @@ -100,14 +103,13 @@ extern_methods!( /// Undocumented cursors unsafe impl NSCursor { - #[sel(respondsToSelector:)] + #[method(respondsToSelector:)] fn class_responds_to(sel: Sel) -> bool; - unsafe fn from_selector_unchecked(sel: Sel) -> Id { - unsafe { msg_send_id![Self::class(), performSelector: sel] } - } + #[method_id(performSelector:)] + unsafe fn from_selector_unchecked(sel: Sel) -> Id; - unsafe fn from_selector(sel: Sel) -> Option> { + unsafe fn from_selector(sel: Sel) -> Option> { if Self::class_responds_to(sel) { Some(unsafe { Self::from_selector_unchecked(sel) }) } else { @@ -143,20 +145,20 @@ extern_methods!( unsafe impl NSCursor { // Note that loading `busybutclickable` with this code won't animate // the frames; instead you'll just get them all in a column. - unsafe fn load_webkit_cursor(name: &NSString) -> Id { + unsafe fn load_webkit_cursor(name: &NSString) -> Id { // Snatch a cursor from WebKit; They fit the style of the native // cursors, and will seem completely standard to macOS users. // // https://stackoverflow.com/a/21786835/5435443 let root = ns_string!("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/Resources/cursors"); - let cursor_path = root.join_path(name); + let cursor_path = root.stringByAppendingPathComponent(name); - let pdf_path = cursor_path.join_path(ns_string!("cursor.pdf")); + let pdf_path = cursor_path.stringByAppendingPathComponent(ns_string!("cursor.pdf")); let image = NSImage::new_by_referencing_file(&pdf_path); // TODO: Handle PLists better - let info_path = cursor_path.join_path(ns_string!("info.plist")); - let info: Id, Shared> = unsafe { + let info_path = cursor_path.stringByAppendingPathComponent(ns_string!("info.plist")); + let info: Id> = unsafe { msg_send_id![ >::class(), dictionaryWithContentsOfFile: &*info_path, @@ -183,18 +185,18 @@ extern_methods!( Self::new(&image, hotspot) } - pub fn moveCursor() -> Id { + pub fn moveCursor() -> Id { unsafe { Self::load_webkit_cursor(ns_string!("move")) } } - pub fn cellCursor() -> Id { + pub fn cellCursor() -> Id { unsafe { Self::load_webkit_cursor(ns_string!("cell")) } } } ); impl NSCursor { - pub fn from_icon(icon: CursorIcon) -> Id { + pub fn from_icon(icon: CursorIcon) -> Id { match icon { CursorIcon::Default => Default::default(), CursorIcon::Pointer => Self::pointingHandCursor(), @@ -233,9 +235,7 @@ impl NSCursor { } impl DefaultId for NSCursor { - type Ownership = Shared; - - fn default_id() -> Id { + fn default_id() -> Id { Self::arrowCursor() } } diff --git a/src/platform_impl/macos/appkit/event.rs b/src/platform_impl/macos/appkit/event.rs index 5952c43c..f7496399 100644 --- a/src/platform_impl/macos/appkit/event.rs +++ b/src/platform_impl/macos/appkit/event.rs @@ -1,11 +1,11 @@ use std::os::raw::c_ushort; -use objc2::encode::{Encode, Encoding}; -use objc2::foundation::{ +use icrate::Foundation::{ CGFloat, NSCopying, NSInteger, NSObject, NSPoint, NSString, NSTimeInterval, NSUInteger, }; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use objc2::encode::{Encode, Encoding}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, mutability, ClassType}; extern_class!( #[derive(Debug, PartialEq, Eq, Hash)] @@ -13,6 +13,7 @@ extern_class!( unsafe impl ClassType for NSEvent { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); @@ -24,6 +25,17 @@ extern_class!( extern_methods!( unsafe impl NSEvent { + #[method_id( + otherEventWithType: + location: + modifierFlags: + timestamp: + windowNumber: + context: + subtype: + data1: + data2: + )] unsafe fn otherEventWithType( type_: NSEventType, location: NSPoint, @@ -34,24 +46,9 @@ extern_methods!( subtype: NSEventSubtype, data1: NSInteger, data2: NSInteger, - ) -> Id { - unsafe { - msg_send_id![ - Self::class(), - otherEventWithType: type_, - location: location, - modifierFlags: flags, - timestamp: time, - windowNumber: window_num, - context: context, - subtype: subtype, - data1: data1, - data2: data2, - ] - } - } + ) -> Id; - pub fn dummy() -> Id { + pub fn dummy() -> Id { unsafe { Self::otherEventWithType( NSEventType::NSApplicationDefined, @@ -67,6 +64,18 @@ extern_methods!( } } + #[method_id( + keyEventWithType: + location: + modifierFlags: + timestamp: + windowNumber: + context: + characters: + charactersIgnoringModifiers: + isARepeat: + keyCode: + )] pub fn keyEventWithType( type_: NSEventType, location: NSPoint, @@ -78,92 +87,74 @@ extern_methods!( characters_ignoring_modifiers: &NSString, is_a_repeat: bool, scancode: c_ushort, - ) -> Id { - unsafe { - msg_send_id![ - Self::class(), - keyEventWithType: type_, - location: location, - modifierFlags: modifier_flags, - timestamp: timestamp, - windowNumber: window_num, - context: context, - characters: characters, - charactersIgnoringModifiers: characters_ignoring_modifiers, - isARepeat: is_a_repeat, - keyCode: scancode, - ] - } - } + ) -> Id; - #[sel(locationInWindow)] + #[method(locationInWindow)] pub fn locationInWindow(&self) -> NSPoint; // TODO: MainThreadMarker - #[sel(pressedMouseButtons)] + #[method(pressedMouseButtons)] pub fn pressedMouseButtons() -> NSUInteger; - #[sel(modifierFlags)] + #[method(modifierFlags)] pub fn modifierFlags(&self) -> NSEventModifierFlags; - #[sel(type)] + #[method(type)] pub fn type_(&self) -> NSEventType; - #[sel(keyCode)] + #[method(keyCode)] pub fn key_code(&self) -> c_ushort; - #[sel(magnification)] + #[method(magnification)] pub fn magnification(&self) -> CGFloat; - #[sel(phase)] + #[method(phase)] pub fn phase(&self) -> NSEventPhase; - #[sel(momentumPhase)] + #[method(momentumPhase)] pub fn momentumPhase(&self) -> NSEventPhase; - #[sel(deltaX)] + #[method(deltaX)] pub fn deltaX(&self) -> CGFloat; - #[sel(deltaY)] + #[method(deltaY)] pub fn deltaY(&self) -> CGFloat; - #[sel(buttonNumber)] + #[method(buttonNumber)] pub fn buttonNumber(&self) -> NSInteger; - #[sel(scrollingDeltaX)] + #[method(scrollingDeltaX)] pub fn scrollingDeltaX(&self) -> CGFloat; - #[sel(scrollingDeltaY)] + #[method(scrollingDeltaY)] pub fn scrollingDeltaY(&self) -> CGFloat; - #[sel(hasPreciseScrollingDeltas)] + #[method(hasPreciseScrollingDeltas)] pub fn hasPreciseScrollingDeltas(&self) -> bool; - #[sel(rotation)] + #[method(rotation)] pub fn rotation(&self) -> f32; - #[sel(pressure)] + #[method(pressure)] pub fn pressure(&self) -> f32; - #[sel(stage)] + #[method(stage)] pub fn stage(&self) -> NSInteger; - #[sel(isARepeat)] + #[method(isARepeat)] pub fn is_a_repeat(&self) -> bool; - #[sel(windowNumber)] + #[method(windowNumber)] pub fn window_number(&self) -> NSInteger; - #[sel(timestamp)] + #[method(timestamp)] pub fn timestamp(&self) -> NSTimeInterval; - pub fn characters(&self) -> Option> { - unsafe { msg_send_id![self, characters] } - } + #[method_id(characters)] + pub fn characters(&self) -> Option>; - pub fn charactersIgnoringModifiers(&self) -> Option> { - unsafe { msg_send_id![self, charactersIgnoringModifiers] } - } + #[method_id(charactersIgnoringModifiers)] + pub fn charactersIgnoringModifiers(&self) -> Option>; pub fn lshift_pressed(&self) -> bool { let raw_modifiers = self.modifierFlags().bits() as u32; @@ -207,10 +198,7 @@ extern_methods!( } ); -unsafe impl NSCopying for NSEvent { - type Ownership = Shared; - type Output = NSEvent; -} +unsafe impl NSCopying for NSEvent {} // The values are from the https://github.com/apple-oss-distributions/IOHIDFamily/blob/19666c840a6d896468416ff0007040a10b7b46b8/IOHIDSystem/IOKit/hidsystem/IOLLEvent.h#L258-L259 const NX_DEVICELCTLKEYMASK: u32 = 0x00000001; diff --git a/src/platform_impl/macos/appkit/image.rs b/src/platform_impl/macos/appkit/image.rs index af5674d3..0b5944c3 100644 --- a/src/platform_impl/macos/appkit/image.rs +++ b/src/platform_impl/macos/appkit/image.rs @@ -1,6 +1,6 @@ -use objc2::foundation::{NSData, NSObject, NSString}; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use icrate::Foundation::{NSData, NSObject, NSString}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType}; extern_class!( // TODO: Can this be mutable? @@ -9,6 +9,7 @@ extern_class!( unsafe impl ClassType for NSImage { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); @@ -24,14 +25,12 @@ unsafe impl Sync for NSImage {} extern_methods!( unsafe impl NSImage { - pub fn new_by_referencing_file(path: &NSString) -> Id { - let this = unsafe { msg_send_id![Self::class(), alloc] }; - unsafe { msg_send_id![this, initByReferencingFile: path] } + pub fn new_by_referencing_file(path: &NSString) -> Id { + unsafe { msg_send_id![Self::alloc(), initByReferencingFile: path] } } - pub fn new_with_data(data: &NSData) -> Id { - let this = unsafe { msg_send_id![Self::class(), alloc] }; - unsafe { msg_send_id![this, initWithData: data] } + pub fn new_with_data(data: &NSData) -> Id { + unsafe { msg_send_id![Self::alloc(), initWithData: data] } } } ); diff --git a/src/platform_impl/macos/appkit/menu.rs b/src/platform_impl/macos/appkit/menu.rs index cb8b47fa..e03ec959 100644 --- a/src/platform_impl/macos/appkit/menu.rs +++ b/src/platform_impl/macos/appkit/menu.rs @@ -1,6 +1,6 @@ -use objc2::foundation::NSObject; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use icrate::Foundation::NSObject; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, mutability, ClassType}; use super::NSMenuItem; @@ -10,16 +10,16 @@ extern_class!( unsafe impl ClassType for NSMenu { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl NSMenu { - pub fn new() -> Id { - unsafe { msg_send_id![Self::class(), new] } - } + #[method_id(new)] + pub fn new() -> Id; - #[sel(addItem:)] + #[method(addItem:)] pub fn addItem(&self, item: &NSMenuItem); } ); diff --git a/src/platform_impl/macos/appkit/menu_item.rs b/src/platform_impl/macos/appkit/menu_item.rs index 6daed88e..63c9a501 100644 --- a/src/platform_impl/macos/appkit/menu_item.rs +++ b/src/platform_impl/macos/appkit/menu_item.rs @@ -1,7 +1,7 @@ -use objc2::foundation::{NSObject, NSString}; -use objc2::rc::{Id, Shared}; +use icrate::Foundation::{NSObject, NSString}; +use objc2::rc::Id; use objc2::runtime::Sel; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType}; use super::{NSEventModifierFlags, NSMenu}; @@ -11,23 +11,19 @@ extern_class!( unsafe impl ClassType for NSMenuItem { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl NSMenuItem { - pub fn new() -> Id { - unsafe { msg_send_id![Self::class(), new] } - } + #[method_id(new)] + pub fn new() -> Id; - pub fn newWithTitle( - title: &NSString, - action: Sel, - key_equivalent: &NSString, - ) -> Id { + pub fn newWithTitle(title: &NSString, action: Sel, key_equivalent: &NSString) -> Id { unsafe { msg_send_id![ - msg_send_id![Self::class(), alloc], + Self::alloc(), initWithTitle: title, action: action, keyEquivalent: key_equivalent, @@ -35,14 +31,13 @@ extern_methods!( } } - pub fn separatorItem() -> Id { - unsafe { msg_send_id![Self::class(), separatorItem] } - } + #[method_id(separatorItem)] + pub fn separatorItem() -> Id; - #[sel(setKeyEquivalentModifierMask:)] + #[method(setKeyEquivalentModifierMask:)] pub fn setKeyEquivalentModifierMask(&self, mask: NSEventModifierFlags); - #[sel(setSubmenu:)] + #[method(setSubmenu:)] pub fn setSubmenu(&self, submenu: &NSMenu); } ); diff --git a/src/platform_impl/macos/appkit/mod.rs b/src/platform_impl/macos/appkit/mod.rs index faebaa30..832fc149 100644 --- a/src/platform_impl/macos/appkit/mod.rs +++ b/src/platform_impl/macos/appkit/mod.rs @@ -25,6 +25,7 @@ mod pasteboard; mod responder; mod screen; mod tab_group; +mod text_input_client; mod text_input_context; mod version; mod view; @@ -51,6 +52,7 @@ pub(crate) use self::responder::NSResponder; #[allow(unused_imports)] pub(crate) use self::screen::{NSDeviceDescriptionKey, NSScreen}; pub(crate) use self::tab_group::NSWindowTabGroup; +pub(crate) use self::text_input_client::NSTextInputClient; pub(crate) use self::text_input_context::NSTextInputContext; pub(crate) use self::version::NSAppKitVersion; pub(crate) use self::view::{NSTrackingRectTag, NSView}; diff --git a/src/platform_impl/macos/appkit/pasteboard.rs b/src/platform_impl/macos/appkit/pasteboard.rs index 6564540d..01a94089 100644 --- a/src/platform_impl/macos/appkit/pasteboard.rs +++ b/src/platform_impl/macos/appkit/pasteboard.rs @@ -1,6 +1,6 @@ -use objc2::foundation::{NSObject, NSString}; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use icrate::Foundation::{NSObject, NSString}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, mutability, ClassType}; extern_class!( #[derive(Debug, PartialEq, Eq, Hash)] @@ -8,14 +8,14 @@ extern_class!( unsafe impl ClassType for NSPasteboard { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl NSPasteboard { - pub fn propertyListForType(&self, type_: &NSPasteboardType) -> Id { - unsafe { msg_send_id![self, propertyListForType: type_] } - } + #[method_id(propertyListForType:)] + pub fn propertyListForType(&self, type_: &NSPasteboardType) -> Id; } ); diff --git a/src/platform_impl/macos/appkit/responder.rs b/src/platform_impl/macos/appkit/responder.rs index 8aa49a3d..11f3bddf 100644 --- a/src/platform_impl/macos/appkit/responder.rs +++ b/src/platform_impl/macos/appkit/responder.rs @@ -1,15 +1,15 @@ -use objc2::foundation::{NSArray, NSObject}; -use objc2::rc::Shared; -use objc2::{extern_class, extern_methods, ClassType}; +use icrate::Foundation::{NSArray, NSObject}; +use objc2::{extern_class, extern_methods, mutability, ClassType}; use super::NSEvent; extern_class!( #[derive(Debug, PartialEq, Eq, Hash)] - pub(crate) struct NSResponder; + pub struct NSResponder; unsafe impl ClassType for NSResponder { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); @@ -17,7 +17,7 @@ extern_class!( extern_methods!( unsafe impl NSResponder { - #[sel(interpretKeyEvents:)] - pub unsafe fn interpretKeyEvents(&self, events: &NSArray); + #[method(interpretKeyEvents:)] + pub(crate) unsafe fn interpretKeyEvents(&self, events: &NSArray); } ); diff --git a/src/platform_impl/macos/appkit/screen.rs b/src/platform_impl/macos/appkit/screen.rs index 7eb8b2a7..8dfe570d 100644 --- a/src/platform_impl/macos/appkit/screen.rs +++ b/src/platform_impl/macos/appkit/screen.rs @@ -1,7 +1,8 @@ -use objc2::foundation::{CGFloat, NSArray, NSDictionary, NSNumber, NSObject, NSRect, NSString}; -use objc2::rc::{Id, Shared}; +use icrate::ns_string; +use icrate::Foundation::{CGFloat, NSArray, NSDictionary, NSNumber, NSObject, NSRect, NSString}; +use objc2::rc::Id; use objc2::runtime::Object; -use objc2::{extern_class, extern_methods, msg_send_id, ns_string, ClassType}; +use objc2::{extern_class, extern_methods, mutability, ClassType}; extern_class!( #[derive(Debug, PartialEq, Eq, Hash)] @@ -9,6 +10,7 @@ extern_class!( unsafe impl ClassType for NSScreen { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); @@ -17,26 +19,21 @@ extern_class!( extern_methods!( unsafe impl NSScreen { /// The application object must have been created. - pub fn main() -> Option> { - unsafe { msg_send_id![Self::class(), mainScreen] } - } + #[method_id(mainScreen)] + pub fn main() -> Option>; /// The application object must have been created. - pub fn screens() -> Id, Shared> { - unsafe { msg_send_id![Self::class(), screens] } - } + #[method_id(screens)] + pub fn screens() -> Id>; - #[sel(frame)] + #[method(frame)] pub fn frame(&self) -> NSRect; - #[sel(visibleFrame)] + #[method(visibleFrame)] pub fn visibleFrame(&self) -> NSRect; - pub fn deviceDescription( - &self, - ) -> Id, Shared> { - unsafe { msg_send_id![self, deviceDescription] } - } + #[method_id(deviceDescription)] + pub fn deviceDescription(&self) -> Id>; pub fn display_id(&self) -> u32 { let key = ns_string!("NSScreenNumber"); @@ -60,7 +57,7 @@ extern_methods!( }) } - #[sel(backingScaleFactor)] + #[method(backingScaleFactor)] pub fn backingScaleFactor(&self) -> CGFloat; } ); diff --git a/src/platform_impl/macos/appkit/tab_group.rs b/src/platform_impl/macos/appkit/tab_group.rs index d45d2dec..8a86e3c0 100644 --- a/src/platform_impl/macos/appkit/tab_group.rs +++ b/src/platform_impl/macos/appkit/tab_group.rs @@ -1,6 +1,6 @@ -use objc2::foundation::{NSArray, NSObject}; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use icrate::Foundation::{NSArray, NSObject}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, mutability, ClassType}; use super::NSWindow; @@ -10,19 +10,22 @@ extern_class!( unsafe impl ClassType for NSWindowTabGroup { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl NSWindowTabGroup { - #[sel(selectNextTab)] + #[method(selectNextTab)] pub fn selectNextTab(&self); - #[sel(selectPreviousTab)] + + #[method(selectPreviousTab)] pub fn selectPreviousTab(&self); - pub fn tabbedWindows(&self) -> Id, Shared> { - unsafe { msg_send_id![self, windows] } - } - #[sel(setSelectedWindow:)] + + #[method_id(windows)] + pub fn tabbedWindows(&self) -> Id>; + + #[method(setSelectedWindow:)] pub fn setSelectedWindow(&self, window: &NSWindow); } ); diff --git a/src/platform_impl/macos/appkit/text_input_client.rs b/src/platform_impl/macos/appkit/text_input_client.rs new file mode 100644 index 00000000..12d03fcb --- /dev/null +++ b/src/platform_impl/macos/appkit/text_input_client.rs @@ -0,0 +1,9 @@ +use objc2::{extern_protocol, ProtocolType}; + +extern_protocol!( + pub(crate) unsafe trait NSTextInputClient { + // TODO: Methods + } + + unsafe impl ProtocolType for dyn NSTextInputClient {} +); diff --git a/src/platform_impl/macos/appkit/text_input_context.rs b/src/platform_impl/macos/appkit/text_input_context.rs index 79a9611b..ee720798 100644 --- a/src/platform_impl/macos/appkit/text_input_context.rs +++ b/src/platform_impl/macos/appkit/text_input_context.rs @@ -1,6 +1,6 @@ -use objc2::foundation::{NSObject, NSString}; -use objc2::rc::{Id, Shared}; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use icrate::Foundation::{NSObject, NSString}; +use objc2::rc::Id; +use objc2::{extern_class, extern_methods, mutability, ClassType}; type NSTextInputSourceIdentifier = NSString; @@ -11,21 +11,19 @@ extern_class!( unsafe impl ClassType for NSTextInputContext { type Super = NSObject; + type Mutability = mutability::InteriorMutable; } ); extern_methods!( unsafe impl NSTextInputContext { - #[sel(invalidateCharacterCoordinates)] + #[method(invalidateCharacterCoordinates)] pub fn invalidateCharacterCoordinates(&self); - #[sel(discardMarkedText)] + #[method(discardMarkedText)] pub fn discardMarkedText(&self); - pub fn selectedKeyboardInputSource( - &self, - ) -> Option> { - unsafe { msg_send_id![self, selectedKeyboardInputSource] } - } + #[method_id(selectedKeyboardInputSource)] + pub fn selectedKeyboardInputSource(&self) -> Option>; } ); diff --git a/src/platform_impl/macos/appkit/view.rs b/src/platform_impl/macos/appkit/view.rs index f883c3e4..049bf61f 100644 --- a/src/platform_impl/macos/appkit/view.rs +++ b/src/platform_impl/macos/appkit/view.rs @@ -2,10 +2,10 @@ use std::ffi::c_void; use std::num::NonZeroIsize; use std::ptr; -use objc2::foundation::{NSObject, NSPoint, NSRect}; -use objc2::rc::{Id, Shared}; +use icrate::Foundation::{NSObject, NSPoint, NSRect}; +use objc2::rc::Id; use objc2::runtime::Object; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use objc2::{extern_class, extern_methods, mutability, ClassType}; use super::{NSCursor, NSResponder, NSTextInputContext, NSWindow}; @@ -16,6 +16,7 @@ extern_class!( unsafe impl ClassType for NSView { #[inherits(NSObject)] type Super = NSResponder; + type Mutability = mutability::InteriorMutable; } ); @@ -31,47 +32,45 @@ extern_class!( extern_methods!( /// Getter methods unsafe impl NSView { - #[sel(frame)] + #[method(frame)] pub fn frame(&self) -> NSRect; - #[sel(bounds)] + #[method(bounds)] pub fn bounds(&self) -> NSRect; + #[method_id(inputContext)] pub fn inputContext( &self, // _mtm: MainThreadMarker, - ) -> Option> { - unsafe { msg_send_id![self, inputContext] } - } + ) -> Option>; - #[sel(visibleRect)] + #[method(visibleRect)] pub fn visibleRect(&self) -> NSRect; - #[sel(hasMarkedText)] + #[method(hasMarkedText)] pub fn hasMarkedText(&self) -> bool; - #[sel(convertPoint:fromView:)] + #[method(convertPoint:fromView:)] pub fn convertPoint_fromView(&self, point: NSPoint, view: Option<&NSView>) -> NSPoint; - pub fn window(&self) -> Option> { - unsafe { msg_send_id![self, window] } - } + #[method_id(window)] + pub fn window(&self) -> Option>; } unsafe impl NSView { - #[sel(setWantsBestResolutionOpenGLSurface:)] + #[method(setWantsBestResolutionOpenGLSurface:)] pub fn setWantsBestResolutionOpenGLSurface(&self, value: bool); - #[sel(setWantsLayer:)] + #[method(setWantsLayer:)] pub fn setWantsLayer(&self, wants_layer: bool); - #[sel(setPostsFrameChangedNotifications:)] + #[method(setPostsFrameChangedNotifications:)] pub fn setPostsFrameChangedNotifications(&self, value: bool); - #[sel(removeTrackingRect:)] + #[method(removeTrackingRect:)] pub fn removeTrackingRect(&self, tag: NSTrackingRectTag); - #[sel(addTrackingRect:owner:userData:assumeInside:)] + #[method(addTrackingRect:owner:userData:assumeInside:)] unsafe fn inner_addTrackingRect( &self, rect: NSRect, @@ -86,11 +85,11 @@ extern_methods!( .expect("failed creating tracking rect") } - #[sel(addCursorRect:cursor:)] + #[method(addCursorRect:cursor:)] // NSCursor safe to take by shared reference since it is already immutable pub fn addCursorRect(&self, rect: NSRect, cursor: &NSCursor); - #[sel(setHidden:)] + #[method(setHidden:)] pub fn setHidden(&self, hidden: bool); } ); diff --git a/src/platform_impl/macos/appkit/window.rs b/src/platform_impl/macos/appkit/window.rs index 139197a5..33ad316b 100644 --- a/src/platform_impl/macos/appkit/window.rs +++ b/src/platform_impl/macos/appkit/window.rs @@ -1,10 +1,10 @@ -use objc2::encode::{Encode, Encoding}; -use objc2::foundation::{ +use icrate::Foundation::{ CGFloat, NSArray, NSInteger, NSObject, NSPoint, NSRect, NSSize, NSString, NSUInteger, }; -use objc2::rc::{Id, Shared}; +use objc2::encode::{Encode, Encoding}; +use objc2::rc::Id; use objc2::runtime::Object; -use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; +use objc2::{extern_class, extern_methods, mutability, ClassType}; use super::{ NSButton, NSColor, NSEvent, NSPasteboardType, NSResponder, NSScreen, NSView, NSWindowTabGroup, @@ -13,11 +13,12 @@ use super::{ extern_class!( /// Main-Thread-Only! #[derive(Debug, PartialEq, Eq, Hash)] - pub(crate) struct NSWindow; + pub struct NSWindow; unsafe impl ClassType for NSWindow { #[inherits(NSObject)] type Super = NSResponder; + type Mutability = mutability::InteriorMutable; } ); @@ -32,221 +33,214 @@ extern_class!( extern_methods!( unsafe impl NSWindow { - #[sel(frame)] - pub fn frame(&self) -> NSRect; + #[method(frame)] + pub(crate) fn frame(&self) -> NSRect; - #[sel(backingScaleFactor)] - pub fn backingScaleFactor(&self) -> CGFloat; + #[method(backingScaleFactor)] + pub(crate) fn backingScaleFactor(&self) -> CGFloat; - pub fn contentView(&self) -> Id { - unsafe { msg_send_id![self, contentView] } - } + #[method_id(contentView)] + pub(crate) fn contentView(&self) -> Id; - #[sel(setContentView:)] - pub fn setContentView(&self, view: &NSView); + #[method(setContentView:)] + pub(crate) fn setContentView(&self, view: &NSView); - #[sel(setInitialFirstResponder:)] - pub fn setInitialFirstResponder(&self, view: &NSView); + #[method(setInitialFirstResponder:)] + pub(crate) fn setInitialFirstResponder(&self, view: &NSView); - #[sel(makeFirstResponder:)] + #[method(makeFirstResponder:)] #[must_use] - pub fn makeFirstResponder(&self, responder: Option<&NSResponder>) -> bool; + pub(crate) fn makeFirstResponder(&self, responder: Option<&NSResponder>) -> bool; - #[sel(contentRectForFrameRect:)] - pub fn contentRectForFrameRect(&self, windowFrame: NSRect) -> NSRect; + #[method(contentRectForFrameRect:)] + pub(crate) fn contentRectForFrameRect(&self, windowFrame: NSRect) -> NSRect; - pub fn screen(&self) -> Option> { - unsafe { msg_send_id![self, screen] } - } + #[method_id(screen)] + pub(crate) fn screen(&self) -> Option>; - #[sel(setContentSize:)] - pub fn setContentSize(&self, contentSize: NSSize); + #[method(setContentSize:)] + pub(crate) fn setContentSize(&self, contentSize: NSSize); - #[sel(setFrameTopLeftPoint:)] - pub fn setFrameTopLeftPoint(&self, point: NSPoint); + #[method(setFrameTopLeftPoint:)] + pub(crate) fn setFrameTopLeftPoint(&self, point: NSPoint); - #[sel(setMinSize:)] - pub fn setMinSize(&self, minSize: NSSize); + #[method(setMinSize:)] + pub(crate) fn setMinSize(&self, minSize: NSSize); - #[sel(setMaxSize:)] - pub fn setMaxSize(&self, maxSize: NSSize); + #[method(setMaxSize:)] + pub(crate) fn setMaxSize(&self, maxSize: NSSize); - #[sel(setResizeIncrements:)] - pub fn setResizeIncrements(&self, increments: NSSize); + #[method(setResizeIncrements:)] + pub(crate) fn setResizeIncrements(&self, increments: NSSize); - #[sel(contentResizeIncrements)] - pub fn contentResizeIncrements(&self) -> NSSize; + #[method(contentResizeIncrements)] + pub(crate) fn contentResizeIncrements(&self) -> NSSize; - #[sel(setContentResizeIncrements:)] - pub fn setContentResizeIncrements(&self, increments: NSSize); + #[method(setContentResizeIncrements:)] + pub(crate) fn setContentResizeIncrements(&self, increments: NSSize); - #[sel(setFrame:display:)] - pub fn setFrame_display(&self, frameRect: NSRect, flag: bool); + #[method(setFrame:display:)] + pub(crate) fn setFrame_display(&self, frameRect: NSRect, flag: bool); - #[sel(setMovable:)] - pub fn setMovable(&self, movable: bool); + #[method(setMovable:)] + pub(crate) fn setMovable(&self, movable: bool); - #[sel(setSharingType:)] - pub fn setSharingType(&self, sharingType: NSWindowSharingType); + #[method(setSharingType:)] + pub(crate) fn setSharingType(&self, sharingType: NSWindowSharingType); - #[sel(setTabbingMode:)] - pub fn setTabbingMode(&self, tabbingMode: NSWindowTabbingMode); + #[method(setTabbingMode:)] + pub(crate) fn setTabbingMode(&self, tabbingMode: NSWindowTabbingMode); - #[sel(setOpaque:)] - pub fn setOpaque(&self, opaque: bool); + #[method(setOpaque:)] + pub(crate) fn setOpaque(&self, opaque: bool); - #[sel(hasShadow)] - pub fn hasShadow(&self) -> bool; + #[method(hasShadow)] + pub(crate) fn hasShadow(&self) -> bool; - #[sel(setHasShadow:)] - pub fn setHasShadow(&self, has_shadow: bool); + #[method(setHasShadow:)] + pub(crate) fn setHasShadow(&self, has_shadow: bool); - #[sel(setIgnoresMouseEvents:)] - pub fn setIgnoresMouseEvents(&self, ignores: bool); + #[method(setIgnoresMouseEvents:)] + pub(crate) fn setIgnoresMouseEvents(&self, ignores: bool); - #[sel(setBackgroundColor:)] - pub fn setBackgroundColor(&self, color: &NSColor); + #[method(setBackgroundColor:)] + pub(crate) fn setBackgroundColor(&self, color: &NSColor); - #[sel(styleMask)] - pub fn styleMask(&self) -> NSWindowStyleMask; + #[method(styleMask)] + pub(crate) fn styleMask(&self) -> NSWindowStyleMask; - #[sel(setStyleMask:)] - pub fn setStyleMask(&self, mask: NSWindowStyleMask); + #[method(setStyleMask:)] + pub(crate) fn setStyleMask(&self, mask: NSWindowStyleMask); - #[sel(registerForDraggedTypes:)] - pub fn registerForDraggedTypes(&self, types: &NSArray); + #[method(registerForDraggedTypes:)] + pub(crate) fn registerForDraggedTypes(&self, types: &NSArray); - #[sel(makeKeyAndOrderFront:)] - pub fn makeKeyAndOrderFront(&self, sender: Option<&Object>); + #[method(makeKeyAndOrderFront:)] + pub(crate) fn makeKeyAndOrderFront(&self, sender: Option<&Object>); - #[sel(orderFront:)] - pub fn orderFront(&self, sender: Option<&Object>); + #[method(orderFront:)] + pub(crate) fn orderFront(&self, sender: Option<&Object>); - #[sel(miniaturize:)] - pub fn miniaturize(&self, sender: Option<&Object>); + #[method(miniaturize:)] + pub(crate) fn miniaturize(&self, sender: Option<&Object>); - #[sel(sender:)] - pub fn deminiaturize(&self, sender: Option<&Object>); + #[method(sender:)] + pub(crate) fn deminiaturize(&self, sender: Option<&Object>); - #[sel(toggleFullScreen:)] - pub fn toggleFullScreen(&self, sender: Option<&Object>); + #[method(toggleFullScreen:)] + pub(crate) fn toggleFullScreen(&self, sender: Option<&Object>); - #[sel(orderOut:)] - pub fn orderOut(&self, sender: Option<&Object>); + #[method(orderOut:)] + pub(crate) fn orderOut(&self, sender: Option<&Object>); - #[sel(zoom:)] - pub fn zoom(&self, sender: Option<&Object>); + #[method(zoom:)] + pub(crate) fn zoom(&self, sender: Option<&Object>); - #[sel(selectNextKeyView:)] - pub fn selectNextKeyView(&self, sender: Option<&Object>); + #[method(selectNextKeyView:)] + pub(crate) fn selectNextKeyView(&self, sender: Option<&Object>); - #[sel(selectPreviousKeyView:)] - pub fn selectPreviousKeyView(&self, sender: Option<&Object>); + #[method(selectPreviousKeyView:)] + pub(crate) fn selectPreviousKeyView(&self, sender: Option<&Object>); - pub fn firstResponder(&self) -> Option> { - unsafe { msg_send_id![self, firstResponder] } - } + #[method_id(firstResponder)] + pub(crate) fn firstResponder(&self) -> Option>; - pub fn standardWindowButton(&self, kind: NSWindowButton) -> Option> { - unsafe { msg_send_id![self, standardWindowButton: kind] } - } + #[method_id(standardWindowButton:)] + pub(crate) fn standardWindowButton(&self, kind: NSWindowButton) -> Option>; - #[sel(setTitle:)] - pub fn setTitle(&self, title: &NSString); + #[method(setTitle:)] + pub(crate) fn setTitle(&self, title: &NSString); - pub fn title_(&self) -> Id { - unsafe { msg_send_id![self, title] } - } + #[method_id(title)] + pub(crate) fn title_(&self) -> Id; - #[sel(setReleasedWhenClosed:)] - pub fn setReleasedWhenClosed(&self, val: bool); + #[method(setReleasedWhenClosed:)] + pub(crate) fn setReleasedWhenClosed(&self, val: bool); - #[sel(setAcceptsMouseMovedEvents:)] - pub fn setAcceptsMouseMovedEvents(&self, val: bool); + #[method(setAcceptsMouseMovedEvents:)] + pub(crate) fn setAcceptsMouseMovedEvents(&self, val: bool); - #[sel(setTitlebarAppearsTransparent:)] - pub fn setTitlebarAppearsTransparent(&self, val: bool); + #[method(setTitlebarAppearsTransparent:)] + pub(crate) fn setTitlebarAppearsTransparent(&self, val: bool); - #[sel(setTitleVisibility:)] - pub fn setTitleVisibility(&self, visibility: NSWindowTitleVisibility); + #[method(setTitleVisibility:)] + pub(crate) fn setTitleVisibility(&self, visibility: NSWindowTitleVisibility); - #[sel(setMovableByWindowBackground:)] - pub fn setMovableByWindowBackground(&self, val: bool); + #[method(setMovableByWindowBackground:)] + pub(crate) fn setMovableByWindowBackground(&self, val: bool); - #[sel(setLevel:)] - pub fn setLevel(&self, level: NSWindowLevel); + #[method(setLevel:)] + pub(crate) fn setLevel(&self, level: NSWindowLevel); - #[sel(setAllowsAutomaticWindowTabbing:)] - pub fn setAllowsAutomaticWindowTabbing(val: bool); + #[method(setAllowsAutomaticWindowTabbing:)] + pub(crate) fn setAllowsAutomaticWindowTabbing(val: bool); - #[sel(setTabbingIdentifier:)] - pub fn setTabbingIdentifier(&self, identifier: &NSString); + #[method(setTabbingIdentifier:)] + pub(crate) fn setTabbingIdentifier(&self, identifier: &NSString); - #[sel(setDocumentEdited:)] - pub fn setDocumentEdited(&self, val: bool); + #[method(setDocumentEdited:)] + pub(crate) fn setDocumentEdited(&self, val: bool); - #[sel(occlusionState)] - pub fn occlusionState(&self) -> NSWindowOcclusionState; + #[method(occlusionState)] + pub(crate) fn occlusionState(&self) -> NSWindowOcclusionState; - #[sel(center)] - pub fn center(&self); + #[method(center)] + pub(crate) fn center(&self); - #[sel(isResizable)] - pub fn isResizable(&self) -> bool; + #[method(isResizable)] + pub(crate) fn isResizable(&self) -> bool; - #[sel(isMiniaturizable)] - pub fn isMiniaturizable(&self) -> bool; + #[method(isMiniaturizable)] + pub(crate) fn isMiniaturizable(&self) -> bool; - #[sel(hasCloseBox)] - pub fn hasCloseBox(&self) -> bool; + #[method(hasCloseBox)] + pub(crate) fn hasCloseBox(&self) -> bool; - #[sel(isMiniaturized)] - pub fn isMiniaturized(&self) -> bool; + #[method(isMiniaturized)] + pub(crate) fn isMiniaturized(&self) -> bool; - #[sel(isVisible)] - pub fn isVisible(&self) -> bool; + #[method(isVisible)] + pub(crate) fn isVisible(&self) -> bool; - #[sel(isKeyWindow)] - pub fn isKeyWindow(&self) -> bool; + #[method(isKeyWindow)] + pub(crate) fn isKeyWindow(&self) -> bool; - #[sel(isZoomed)] - pub fn isZoomed(&self) -> bool; + #[method(isZoomed)] + pub(crate) fn isZoomed(&self) -> bool; - #[sel(allowsAutomaticWindowTabbing)] - pub fn allowsAutomaticWindowTabbing() -> bool; + #[method(allowsAutomaticWindowTabbing)] + pub(crate) fn allowsAutomaticWindowTabbing() -> bool; - #[sel(selectNextTab)] - pub fn selectNextTab(&self); + #[method(selectNextTab)] + pub(crate) fn selectNextTab(&self); - pub fn tabbingIdentifier(&self) -> Id { - unsafe { msg_send_id![self, tabbingIdentifier] } - } + #[method_id(tabbingIdentifier)] + pub(crate) fn tabbingIdentifier(&self) -> Id; - pub fn tabGroup(&self) -> Id { - unsafe { msg_send_id![self, tabGroup] } - } + #[method_id(tabGroup)] + pub(crate) fn tabGroup(&self) -> Id; - #[sel(isDocumentEdited)] - pub fn isDocumentEdited(&self) -> bool; + #[method(isDocumentEdited)] + pub(crate) fn isDocumentEdited(&self) -> bool; - #[sel(close)] - pub fn close(&self); + #[method(close)] + pub(crate) fn close(&self); - #[sel(performWindowDragWithEvent:)] + #[method(performWindowDragWithEvent:)] // TODO: Can this actually accept NULL? - pub fn performWindowDragWithEvent(&self, event: Option<&NSEvent>); + pub(crate) fn performWindowDragWithEvent(&self, event: Option<&NSEvent>); - #[sel(invalidateCursorRectsForView:)] - pub fn invalidateCursorRectsForView(&self, view: &NSView); + #[method(invalidateCursorRectsForView:)] + pub(crate) fn invalidateCursorRectsForView(&self, view: &NSView); - #[sel(setDelegate:)] - pub fn setDelegate(&self, delegate: Option<&NSObject>); + #[method(setDelegate:)] + pub(crate) fn setDelegate(&self, delegate: Option<&NSObject>); - #[sel(sendEvent:)] - pub unsafe fn sendEvent(&self, event: &NSEvent); + #[method(sendEvent:)] + pub(crate) unsafe fn sendEvent(&self, event: &NSEvent); - #[sel(addChildWindow:ordered:)] - pub unsafe fn addChildWindow(&self, child: &NSWindow, ordered: NSWindowOrderingMode); + #[method(addChildWindow:ordered:)] + pub(crate) unsafe fn addChildWindow(&self, child: &NSWindow, ordered: NSWindowOrderingMode); } ); diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index 785647e3..867b9482 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -4,7 +4,7 @@ use core_foundation::{ base::CFRelease, data::{CFDataGetBytePtr, CFDataRef}, }; -use objc2::rc::{Id, Shared}; +use objc2::rc::Id; use smol_str::SmolStr; use super::appkit::{NSEvent, NSEventModifierFlags}; @@ -31,7 +31,7 @@ pub(crate) enum EventWrapper { #[derive(Debug)] pub(crate) enum EventProxy { DpiChangedProxy { - window: Id, + window: Id, suggested_size: LogicalSize, scale_factor: f64, }, diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index 176c90e7..8726cf76 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -17,8 +17,8 @@ use core_foundation::runloop::{ kCFRunLoopCommonModes, CFRunLoopAddSource, CFRunLoopGetMain, CFRunLoopSourceContext, CFRunLoopSourceCreate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp, }; -use objc2::foundation::is_main_thread; -use objc2::rc::{autoreleasepool, Id, Shared}; +use icrate::Foundation::is_main_thread; +use objc2::rc::{autoreleasepool, Id}; use objc2::{msg_send_id, ClassType}; use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle}; @@ -116,7 +116,7 @@ impl EventLoopWindowTarget { pub struct EventLoop { /// The delegate is only weakly referenced by NSApplication, so we keep /// it around here as well. - _delegate: Id, + _delegate: Id, window_target: Rc>, panic_info: Rc, @@ -157,7 +157,7 @@ impl EventLoop { // `sharedApplication`) is called anywhere else, or we'll end up // with the wrong `NSApplication` class and the wrong thread could // be marked as main. - let app: Id = + let app: Id = unsafe { msg_send_id![WinitApplication::class(), sharedApplication] }; use NSApplicationActivationPolicy::*; diff --git a/src/platform_impl/macos/menu.rs b/src/platform_impl/macos/menu.rs index f7ad2df0..8e69cbbb 100644 --- a/src/platform_impl/macos/menu.rs +++ b/src/platform_impl/macos/menu.rs @@ -1,7 +1,8 @@ -use objc2::foundation::{NSProcessInfo, NSString}; -use objc2::rc::{Id, Shared}; +use icrate::ns_string; +use icrate::Foundation::{NSProcessInfo, NSString}; +use objc2::rc::Id; use objc2::runtime::Sel; -use objc2::{ns_string, sel}; +use objc2::sel; use super::appkit::{NSApp, NSEventModifierFlags, NSMenu, NSMenuItem}; @@ -16,17 +17,17 @@ pub fn initialize() { menubar.addItem(&app_menu_item); let app_menu = NSMenu::new(); - let process_name = NSProcessInfo::process_info().process_name(); + let process_name = NSProcessInfo::processInfo().processName(); // About menu item - let about_item_title = ns_string!("About ").concat(&process_name); + let about_item_title = ns_string!("About ").stringByAppendingString(&process_name); let about_item = menu_item(&about_item_title, sel!(orderFrontStandardAboutPanel:), None); // Seperator menu item let sep_first = NSMenuItem::separatorItem(); // Hide application menu item - let hide_item_title = ns_string!("Hide ").concat(&process_name); + let hide_item_title = ns_string!("Hide ").stringByAppendingString(&process_name); let hide_item = menu_item( &hide_item_title, sel!(hide:), @@ -57,7 +58,7 @@ pub fn initialize() { let sep = NSMenuItem::separatorItem(); // Quit application menu item - let quit_item_title = ns_string!("Quit ").concat(&process_name); + let quit_item_title = ns_string!("Quit ").stringByAppendingString(&process_name); let quit_item = menu_item( &quit_item_title, sel!(terminate:), @@ -84,7 +85,7 @@ fn menu_item( title: &NSString, selector: Sel, key_equivalent: Option>, -) -> Id { +) -> Id { let (key, masks) = match key_equivalent { Some(ke) => (ke.key, ke.masks), None => (ns_string!(""), None), diff --git a/src/platform_impl/macos/mod.rs b/src/platform_impl/macos/mod.rs index 141f03e6..c12f7281 100644 --- a/src/platform_impl/macos/mod.rs +++ b/src/platform_impl/macos/mod.rs @@ -32,7 +32,7 @@ pub(crate) use self::{ use crate::{ error::OsError as RootOsError, event::DeviceId as RootDeviceId, window::WindowAttributes, }; -use objc2::rc::{autoreleasepool, Id, Shared}; +use objc2::rc::{autoreleasepool, Id}; pub(crate) use crate::icon::NoIcon as PlatformIcon; pub(crate) use crate::platform_impl::Fullscreen; @@ -50,9 +50,9 @@ impl DeviceId { pub(crate) const DEVICE_ID: RootDeviceId = RootDeviceId(DeviceId); pub(crate) struct Window { - pub(crate) window: Id, + pub(crate) window: Id, // We keep this around so that it doesn't get dropped until the window does. - _delegate: Id, + _delegate: Id, } impl Drop for Window { diff --git a/src/platform_impl/macos/monitor.rs b/src/platform_impl/macos/monitor.rs index 54a99040..bc9992d4 100644 --- a/src/platform_impl/macos/monitor.rs +++ b/src/platform_impl/macos/monitor.rs @@ -8,7 +8,7 @@ use core_foundation::{ string::CFString, }; use core_graphics::display::{CGDirectDisplayID, CGDisplay, CGDisplayBounds}; -use objc2::rc::{Id, Shared}; +use objc2::rc::Id; use super::appkit::NSScreen; use super::ffi; @@ -295,19 +295,14 @@ impl MonitorHandle { } } - pub(crate) fn ns_screen(&self) -> Option> { + pub(crate) fn ns_screen(&self) -> Option> { let uuid = unsafe { ffi::CGDisplayCreateUUIDFromDisplayID(self.0) }; - NSScreen::screens() - .into_iter() - .find(|screen| { - let other_native_id = screen.display_id(); - let other_uuid = unsafe { - ffi::CGDisplayCreateUUIDFromDisplayID(other_native_id as CGDirectDisplayID) - }; - uuid == other_uuid - }) - .map(|screen| unsafe { - Id::retain(screen as *const NSScreen as *mut NSScreen).unwrap() - }) + NSScreen::screens().into_iter().find(|screen| { + let other_native_id = screen.display_id(); + let other_uuid = unsafe { + ffi::CGDisplayCreateUUIDFromDisplayID(other_native_id as CGDirectDisplayID) + }; + uuid == other_uuid + }) } } diff --git a/src/platform_impl/macos/util/async.rs b/src/platform_impl/macos/util/async.rs index 494e2b6c..6f430361 100644 --- a/src/platform_impl/macos/util/async.rs +++ b/src/platform_impl/macos/util/async.rs @@ -1,7 +1,7 @@ use std::ops::Deref; use dispatch::Queue; -use objc2::foundation::{is_main_thread, CGFloat, NSPoint, NSSize, NSString}; +use icrate::Foundation::{is_main_thread, CGFloat, NSPoint, NSSize, NSString}; use objc2::rc::autoreleasepool; use crate::{ diff --git a/src/platform_impl/macos/util/mod.rs b/src/platform_impl/macos/util/mod.rs index 2cfdc47e..bca2643e 100644 --- a/src/platform_impl/macos/util/mod.rs +++ b/src/platform_impl/macos/util/mod.rs @@ -5,7 +5,7 @@ mod r#async; pub(crate) use self::r#async::*; use core_graphics::display::CGDisplay; -use objc2::foundation::{CGFloat, NSNotFound, NSPoint, NSRange, NSRect, NSUInteger}; +use icrate::Foundation::{CGFloat, NSNotFound, NSPoint, NSRange, NSRect, NSUInteger}; use crate::dpi::LogicalPosition; diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index d1fd18ce..391089ea 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -1,23 +1,23 @@ #![allow(clippy::unnecessary_cast)] - use std::boxed::Box; use std::cell::{Cell, RefCell}; use std::collections::{HashMap, VecDeque}; -use std::os::raw::*; -use std::ptr::{self, NonNull}; -use std::str; +use std::ptr::NonNull; -use objc2::declare::{Ivar, IvarDrop}; -use objc2::foundation::{ +use icrate::Foundation::{ NSArray, NSAttributedString, NSAttributedStringKey, NSCopying, NSMutableAttributedString, - NSObject, NSPoint, NSRange, NSRect, NSSize, NSString, NSUInteger, + NSObject, NSObjectProtocol, NSPoint, NSRange, NSRect, NSSize, NSString, NSUInteger, }; -use objc2::rc::{Id, Owned, Shared, WeakId}; +use objc2::declare::{Ivar, IvarDrop}; +use objc2::rc::{Id, WeakId}; use objc2::runtime::{Object, Sel}; -use objc2::{class, declare_class, msg_send, msg_send_id, sel, ClassType}; +use objc2::{class, declare_class, msg_send, msg_send_id, mutability, sel, ClassType}; use super::{ - appkit::{NSApp, NSCursor, NSEvent, NSEventPhase, NSResponder, NSTrackingRectTag, NSView}, + appkit::{ + NSApp, NSCursor, NSEvent, NSEventPhase, NSResponder, NSTextInputClient, NSTrackingRectTag, + NSView, + }, event::{code_to_key, code_to_location}, }; use crate::{ @@ -42,7 +42,7 @@ use crate::{ #[derive(Debug)] struct CursorState { visible: bool, - cursor: Id, + cursor: Id, } impl Default for CursorState { @@ -119,7 +119,7 @@ fn get_left_modifier_code(key: &Key) -> KeyCode { } #[derive(Debug, Default)] -struct ViewState { +pub struct ViewState { cursor_state: RefCell, ime_position: Cell>, ime_size: Cell>, @@ -138,7 +138,7 @@ struct ViewState { /// to the application, even during IME forward_key_to_app: Cell, - marked_text: RefCell>, + marked_text: RefCell>, accepts_first_mouse: bool, } @@ -147,23 +147,27 @@ declare_class!( #[allow(non_snake_case)] pub(super) struct WinitView { // Weak reference because the window keeps a strong reference to the view - _ns_window: IvarDrop>>, - state: IvarDrop>, + _ns_window: IvarDrop>, "__ns_window">, + state: IvarDrop, "_state">, } + mod ivars; + unsafe impl ClassType for WinitView { #[inherits(NSResponder, NSObject)] type Super = NSView; + type Mutability = mutability::InteriorMutable; + const NAME: &'static str = "WinitView"; } unsafe impl WinitView { - #[sel(initWithId:acceptsFirstMouse:)] + #[method(initWithId:acceptsFirstMouse:)] unsafe fn init_with_id( - &mut self, + this: *mut Self, window: &WinitWindow, accepts_first_mouse: bool, ) -> Option> { - let this: Option<&mut Self> = unsafe { msg_send![super(self), init] }; + let this: Option<&mut Self> = unsafe { msg_send![super(this), init] }; this.map(|this| { let state = ViewState { accepts_first_mouse, @@ -201,7 +205,7 @@ declare_class!( } unsafe impl WinitView { - #[sel(viewDidMoveToWindow)] + #[method(viewDidMoveToWindow)] fn view_did_move_to_window(&self) { trace_scope!("viewDidMoveToWindow"); if let Some(tracking_rect) = self.state.tracking_rect.take() { @@ -213,7 +217,7 @@ declare_class!( self.state.tracking_rect.set(Some(tracking_rect)); } - #[sel(frameDidChange:)] + #[method(frameDidChange:)] fn frame_did_change(&self, _event: &NSEvent) { trace_scope!("frameDidChange:"); if let Some(tracking_rect) = self.state.tracking_rect.take() { @@ -232,7 +236,7 @@ declare_class!( self.queue_event(WindowEvent::Resized(size)); } - #[sel(drawRect:)] + #[method(drawRect:)] fn draw_rect(&self, rect: NSRect) { trace_scope!("drawRect:"); @@ -247,7 +251,7 @@ declare_class!( } } - #[sel(acceptsFirstResponder)] + #[method(acceptsFirstResponder)] fn accepts_first_responder(&self) -> bool { trace_scope!("acceptsFirstResponder"); true @@ -256,13 +260,13 @@ declare_class!( // This is necessary to prevent a beefy terminal error on MacBook Pros: // IMKInputSession [0x7fc573576ff0 presentFunctionRowItemTextInputViewWithEndpoint:completionHandler:] : [self textInputContext]=0x7fc573558e10 *NO* NSRemoteViewController to client, NSError=Error Domain=NSCocoaErrorDomain Code=4099 "The connection from pid 0 was invalidated from this process." UserInfo={NSDebugDescription=The connection from pid 0 was invalidated from this process.}, com.apple.inputmethod.EmojiFunctionRowItem // TODO: Add an API extension for using `NSTouchBar` - #[sel(touchBar)] - fn touch_bar(&self) -> bool { + #[method_id(touchBar)] + fn touch_bar(&self) -> Option> { trace_scope!("touchBar"); - false + None } - #[sel(resetCursorRects)] + #[method(resetCursorRects)] fn reset_cursor_rects(&self) { trace_scope!("resetCursorRects"); let bounds = self.bounds(); @@ -276,17 +280,17 @@ declare_class!( } } - unsafe impl Protocol for WinitView { - #[sel(hasMarkedText)] + unsafe impl NSTextInputClient for WinitView { + #[method(hasMarkedText)] fn has_marked_text(&self) -> bool { trace_scope!("hasMarkedText"); - self.state.marked_text.borrow().len_utf16() > 0 + self.state.marked_text.borrow().length() > 0 } - #[sel(markedRange)] + #[method(markedRange)] fn marked_range(&self) -> NSRange { trace_scope!("markedRange"); - let length = self.state.marked_text.borrow().len_utf16(); + let length = self.state.marked_text.borrow().length(); if length > 0 { NSRange::new(0, length) } else { @@ -294,13 +298,13 @@ declare_class!( } } - #[sel(selectedRange)] + #[method(selectedRange)] fn selected_range(&self) -> NSRange { trace_scope!("selectedRange"); util::EMPTY_RANGE } - #[sel(setMarkedText:selectedRange:replacementRange:)] + #[method(setMarkedText:selectedRange:replacementRange:)] fn set_marked_text( &self, string: &NSObject, @@ -356,7 +360,7 @@ declare_class!( self.queue_event(WindowEvent::Ime(Ime::Preedit(preedit_string, cursor_range))); } - #[sel(unmarkText)] + #[method(unmarkText)] fn unmark_text(&self) { trace_scope!("unmarkText"); *self.state.marked_text.borrow_mut() = NSMutableAttributedString::new(); @@ -373,33 +377,33 @@ declare_class!( } } - #[sel(validAttributesForMarkedText)] - fn valid_attributes_for_marked_text(&self) -> *const NSArray { + #[method_id(validAttributesForMarkedText)] + fn valid_attributes_for_marked_text(&self) -> Id> { trace_scope!("validAttributesForMarkedText"); - Id::autorelease_return(NSArray::new()) + NSArray::new() } - #[sel(attributedSubstringForProposedRange:actualRange:)] + #[method_id(attributedSubstringForProposedRange:actualRange:)] fn attributed_substring_for_proposed_range( &self, _range: NSRange, - _actual_range: *mut c_void, // *mut NSRange - ) -> *const NSAttributedString { + _actual_range: *mut NSRange, + ) -> Option> { trace_scope!("attributedSubstringForProposedRange:actualRange:"); - ptr::null() + None } - #[sel(characterIndexForPoint:)] + #[method(characterIndexForPoint:)] fn character_index_for_point(&self, _point: NSPoint) -> NSUInteger { trace_scope!("characterIndexForPoint:"); 0 } - #[sel(firstRectForCharacterRange:actualRange:)] + #[method(firstRectForCharacterRange:actualRange:)] fn first_rect_for_character_range( &self, _range: NSRange, - _actual_range: *mut c_void, // *mut NSRange + _actual_range: *mut NSRange, ) -> NSRect { trace_scope!("firstRectForCharacterRange:actualRange:"); let window = self.window(); @@ -412,7 +416,7 @@ declare_class!( NSRect::new(NSPoint::new(x as _, y as _), NSSize::new(width, height)) } - #[sel(insertText:replacementRange:)] + #[method(insertText:replacementRange:)] fn insert_text(&self, string: &NSObject, _replacement_range: NSRange) { trace_scope!("insertText:replacementRange:"); @@ -439,7 +443,7 @@ declare_class!( // Basically, we're sent this message whenever a keyboard event that doesn't generate a "human // readable" character happens, i.e. newlines, tabs, and Ctrl+C. - #[sel(doCommandBySelector:)] + #[method(doCommandBySelector:)] fn do_command_by_selector(&self, _command: Sel) { trace_scope!("doCommandBySelector:"); // We shouldn't forward any character from just commited text, since we'll end up sending @@ -459,7 +463,7 @@ declare_class!( } unsafe impl WinitView { - #[sel(keyDown:)] + #[method(keyDown:)] fn key_down(&self, event: &NSEvent) { trace_scope!("keyDown:"); { @@ -485,7 +489,7 @@ declare_class!( // `doCommandBySelector`. (doCommandBySelector means that the keyboard input // is not handled by IME and should be handled by the application) if self.state.ime_allowed.get() { - let events_for_nsview = NSArray::from_slice(&[event.copy()]); + let events_for_nsview = NSArray::from_slice(&[&*event]); unsafe { self.interpretKeyEvents(&events_for_nsview) }; // If the text was commited we must treat the next keyboard event as IME related. @@ -518,7 +522,7 @@ declare_class!( } } - #[sel(keyUp:)] + #[method(keyUp:)] fn key_up(&self, event: &NSEvent) { trace_scope!("keyUp:"); @@ -538,15 +542,15 @@ declare_class!( } } - #[sel(flagsChanged:)] - fn flags_changed(&self, ns_event: &NSEvent) { + #[method(flagsChanged:)] + fn flags_changed(&self, event: &NSEvent) { trace_scope!("flagsChanged:"); - self.update_modifiers(ns_event, true); + self.update_modifiers(event, true); } - #[sel(insertTab:)] - fn insert_tab(&self, _sender: *const Object) { + #[method(insertTab:)] + fn insert_tab(&self, _sender: Option<&Object>) { trace_scope!("insertTab:"); let window = self.window(); if let Some(first_responder) = window.firstResponder() { @@ -556,8 +560,8 @@ declare_class!( } } - #[sel(insertBackTab:)] - fn insert_back_tab(&self, _sender: *const Object) { + #[method(insertBackTab:)] + fn insert_back_tab(&self, _sender: Option<&Object>) { trace_scope!("insertBackTab:"); let window = self.window(); if let Some(first_responder) = window.firstResponder() { @@ -569,8 +573,8 @@ declare_class!( // Allows us to receive Cmd-. (the shortcut for closing a dialog) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=300620#c6 - #[sel(cancelOperation:)] - fn cancel_operation(&self, _sender: *const Object) { + #[method(cancelOperation:)] + fn cancel_operation(&self, _sender: Option<&Object>) { trace_scope!("cancelOperation:"); let event = NSApp() @@ -587,42 +591,42 @@ declare_class!( }); } - #[sel(mouseDown:)] + #[method(mouseDown:)] fn mouse_down(&self, event: &NSEvent) { trace_scope!("mouseDown:"); self.mouse_motion(event); self.mouse_click(event, ElementState::Pressed); } - #[sel(mouseUp:)] + #[method(mouseUp:)] fn mouse_up(&self, event: &NSEvent) { trace_scope!("mouseUp:"); self.mouse_motion(event); self.mouse_click(event, ElementState::Released); } - #[sel(rightMouseDown:)] + #[method(rightMouseDown:)] fn right_mouse_down(&self, event: &NSEvent) { trace_scope!("rightMouseDown:"); self.mouse_motion(event); self.mouse_click(event, ElementState::Pressed); } - #[sel(rightMouseUp:)] + #[method(rightMouseUp:)] fn right_mouse_up(&self, event: &NSEvent) { trace_scope!("rightMouseUp:"); self.mouse_motion(event); self.mouse_click(event, ElementState::Released); } - #[sel(otherMouseDown:)] + #[method(otherMouseDown:)] fn other_mouse_down(&self, event: &NSEvent) { trace_scope!("otherMouseDown:"); self.mouse_motion(event); self.mouse_click(event, ElementState::Pressed); } - #[sel(otherMouseUp:)] + #[method(otherMouseUp:)] fn other_mouse_up(&self, event: &NSEvent) { trace_scope!("otherMouseUp:"); self.mouse_motion(event); @@ -631,27 +635,27 @@ declare_class!( // No tracing on these because that would be overly verbose - #[sel(mouseMoved:)] + #[method(mouseMoved:)] fn mouse_moved(&self, event: &NSEvent) { self.mouse_motion(event); } - #[sel(mouseDragged:)] + #[method(mouseDragged:)] fn mouse_dragged(&self, event: &NSEvent) { self.mouse_motion(event); } - #[sel(rightMouseDragged:)] + #[method(rightMouseDragged:)] fn right_mouse_dragged(&self, event: &NSEvent) { self.mouse_motion(event); } - #[sel(otherMouseDragged:)] + #[method(otherMouseDragged:)] fn other_mouse_dragged(&self, event: &NSEvent) { self.mouse_motion(event); } - #[sel(mouseEntered:)] + #[method(mouseEntered:)] fn mouse_entered(&self, _event: &NSEvent) { trace_scope!("mouseEntered:"); self.queue_event(WindowEvent::CursorEntered { @@ -659,7 +663,7 @@ declare_class!( }); } - #[sel(mouseExited:)] + #[method(mouseExited:)] fn mouse_exited(&self, _event: &NSEvent) { trace_scope!("mouseExited:"); @@ -668,7 +672,7 @@ declare_class!( }); } - #[sel(scrollWheel:)] + #[method(scrollWheel:)] fn scroll_wheel(&self, event: &NSEvent) { trace_scope!("scrollWheel:"); @@ -716,7 +720,7 @@ declare_class!( }); } - #[sel(magnifyWithEvent:)] + #[method(magnifyWithEvent:)] fn magnify_with_event(&self, event: &NSEvent) { trace_scope!("magnifyWithEvent:"); @@ -735,7 +739,7 @@ declare_class!( }); } - #[sel(smartMagnifyWithEvent:)] + #[method(smartMagnifyWithEvent:)] fn smart_magnify_with_event(&self, _event: &NSEvent) { trace_scope!("smartMagnifyWithEvent:"); @@ -744,7 +748,7 @@ declare_class!( }); } - #[sel(rotateWithEvent:)] + #[method(rotateWithEvent:)] fn rotate_with_event(&self, event: &NSEvent) { trace_scope!("rotateWithEvent:"); @@ -763,7 +767,7 @@ declare_class!( }); } - #[sel(pressureChangeWithEvent:)] + #[method(pressureChangeWithEvent:)] fn pressure_change_with_event(&self, event: &NSEvent) { trace_scope!("pressureChangeWithEvent:"); @@ -779,13 +783,13 @@ declare_class!( // Allows us to receive Ctrl-Tab and Ctrl-Esc. // Note that this *doesn't* help with any missing Cmd inputs. // https://github.com/chromium/chromium/blob/a86a8a6bcfa438fa3ac2eba6f02b3ad1f8e0756f/ui/views/cocoa/bridged_content_view.mm#L816 - #[sel(_wantsKeyDownForEvent:)] + #[method(_wantsKeyDownForEvent:)] fn wants_key_down_for_event(&self, _event: &NSEvent) -> bool { trace_scope!("_wantsKeyDownForEvent:"); true } - #[sel(acceptsFirstMouse:)] + #[method(acceptsFirstMouse:)] fn accepts_first_mouse(&self, _event: &NSEvent) -> bool { trace_scope!("acceptsFirstMouse:"); self.state.accepts_first_mouse @@ -794,17 +798,17 @@ declare_class!( ); impl WinitView { - pub(super) fn new(window: &WinitWindow, accepts_first_mouse: bool) -> Id { + pub(super) fn new(window: &WinitWindow, accepts_first_mouse: bool) -> Id { unsafe { msg_send_id![ - msg_send_id![Self::class(), alloc], + Self::alloc(), initWithId: window, acceptsFirstMouse: accepts_first_mouse, ] } } - fn window(&self) -> Id { + fn window(&self) -> Id { // TODO: Simply use `window` property on `NSView`. // That only returns a window _after_ the view has been attached though! // (which is incompatible with `frameDidChange:`) @@ -849,7 +853,7 @@ impl WinitView { .unwrap_or_else(String::new) } - pub(super) fn set_cursor_icon(&self, icon: Id) { + pub(super) fn set_cursor_icon(&self, icon: Id) { let mut cursor_state = self.state.cursor_state.borrow_mut(); cursor_state.cursor = icon; } @@ -1072,7 +1076,7 @@ fn mouse_button(event: &NSEvent) -> MouseButton { // NOTE: to get option as alt working we need to rewrite events // we're getting from the operating system, which makes it // impossible to provide such events as extra in `KeyEvent`. -fn replace_event(event: &NSEvent, option_as_alt: OptionAsAlt) -> Id { +fn replace_event(event: &NSEvent, option_as_alt: OptionAsAlt) -> Id { let ev_mods = event_mods(event).state; let ignore_alt_characters = match option_as_alt { OptionAsAlt::OnlyLeft if event.lalt_pressed() => true, diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 86d7cee9..f174753a 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -35,13 +35,13 @@ use crate::{ }, }; use core_graphics::display::{CGDisplay, CGPoint}; -use objc2::declare::{Ivar, IvarDrop}; -use objc2::foundation::{ +use icrate::Foundation::{ is_main_thread, CGFloat, NSArray, NSCopying, NSInteger, NSObject, NSPoint, NSRect, NSSize, NSString, }; -use objc2::rc::{autoreleasepool, Id, Shared}; -use objc2::{declare_class, msg_send, msg_send_id, sel, ClassType}; +use objc2::declare::{Ivar, IvarDrop}; +use objc2::rc::{autoreleasepool, Id}; +use objc2::{declare_class, msg_send, msg_send_id, mutability, sel, ClassType}; use super::appkit::{ NSApp, NSAppKitVersion, NSAppearance, NSApplicationPresentationOptions, NSBackingStoreType, @@ -107,27 +107,31 @@ impl Default for PlatformSpecificWindowBuilderAttributes { declare_class!( #[derive(Debug)] - pub(crate) struct WinitWindow { + pub struct WinitWindow { // TODO: Fix unnecessary boxing here - shared_state: IvarDrop>>, + shared_state: IvarDrop>, "_shared_state">, } + mod ivars; + unsafe impl ClassType for WinitWindow { #[inherits(NSResponder, NSObject)] type Super = NSWindow; + type Mutability = mutability::InteriorMutable; + const NAME: &'static str = "WinitWindow"; } unsafe impl WinitWindow { - #[sel(initWithContentRect:styleMask:state:)] + #[method(initWithContentRect:styleMask:state:)] unsafe fn init( - &mut self, + this: *mut Self, frame: NSRect, mask: NSWindowStyleMask, state: *mut c_void, ) -> Option> { let this: Option<&mut Self> = unsafe { msg_send![ - super(self), + super(this), initWithContentRect: frame, styleMask: mask, backing: NSBackingStoreType::NSBackingStoreBuffered, @@ -152,13 +156,13 @@ declare_class!( } unsafe impl WinitWindow { - #[sel(canBecomeMainWindow)] + #[method(canBecomeMainWindow)] fn can_become_main_window(&self) -> bool { trace_scope!("canBecomeMainWindow"); true } - #[sel(canBecomeKeyWindow)] + #[method(canBecomeKeyWindow)] fn can_become_key_window(&self) -> bool { trace_scope!("canBecomeKeyWindow"); true @@ -249,7 +253,7 @@ impl WinitWindow { pub(crate) fn new( attrs: WindowAttributes, pl_attrs: PlatformSpecificWindowBuilderAttributes, - ) -> Result<(Id, Id), RootOsError> { + ) -> Result<(Id, Id), RootOsError> { trace_scope!("WinitWindow::new"); if !is_main_thread() { @@ -334,9 +338,9 @@ impl WinitWindow { // Pass the state through FFI to the method declared on the class let state_ptr: *mut c_void = Box::into_raw(Box::new(Mutex::new(state))).cast(); - let this: Option> = unsafe { + let this: Option> = unsafe { msg_send_id![ - msg_send_id![WinitWindow::class(), alloc], + WinitWindow::alloc(), initWithContentRect: frame, styleMask: masks, state: state_ptr, @@ -413,27 +417,26 @@ impl WinitWindow { match attrs.parent_window { Some(RawWindowHandle::AppKit(handle)) => { // SAFETY: Caller ensures the pointer is valid or NULL - let parent: Id = - match unsafe { Id::retain(handle.ns_window.cast()) } { - Some(window) => window, - None => { - // SAFETY: Caller ensures the pointer is valid or NULL - let parent_view: Id = - match unsafe { Id::retain(handle.ns_view.cast()) } { - Some(view) => view, - None => { - return Err(os_error!(OsError::CreationError( - "raw window handle should be non-empty" - ))) - } - }; - parent_view.window().ok_or_else(|| { - os_error!(OsError::CreationError( - "parent view should be installed in a window" - )) - })? - } - }; + let parent: Id = match unsafe { Id::retain(handle.ns_window.cast()) } { + Some(window) => window, + None => { + // SAFETY: Caller ensures the pointer is valid or NULL + let parent_view: Id = + match unsafe { Id::retain(handle.ns_view.cast()) } { + Some(view) => view, + None => { + return Err(os_error!(OsError::CreationError( + "raw window handle should be non-empty" + ))) + } + }; + parent_view.window().ok_or_else(|| { + os_error!(OsError::CreationError( + "parent view should be installed in a window" + )) + })? + } + }; // SAFETY: We know that there are no parent -> child -> parent cycles since the only place in `winit` // where we allow making a window a child window is right here, just after it's been created. unsafe { parent.addChildWindow(&this, NSWindowOrderingMode::NSWindowAbove) }; @@ -477,7 +480,7 @@ impl WinitWindow { this.set_window_level(attrs.window_level); // register for drag and drop operations. - this.registerForDraggedTypes(&NSArray::from_slice(&[ + this.registerForDraggedTypes(&NSArray::from_id_slice(&[ unsafe { NSFilenamesPboardType }.copy() ])); @@ -521,13 +524,7 @@ impl WinitWindow { Ok((this, delegate)) } - pub(super) fn retain(&self) -> Id { - // SAFETY: The pointer is valid, and the window is always `Shared` - // TODO(madsmtm): Remove the need for unsafety here - unsafe { Id::retain(self as *const Self as *mut Self).unwrap() } - } - - pub(super) fn view(&self) -> Id { + pub(super) fn view(&self) -> Id { // SAFETY: The view inside WinitWindow is always `WinitView` unsafe { Id::cast(self.contentView()) } } @@ -1462,7 +1459,7 @@ pub(super) fn get_ns_theme() -> Theme { return Theme::Light; } let appearance = app.effectiveAppearance(); - let name = appearance.bestMatchFromAppearancesWithNames(&NSArray::from_slice(&[ + let name = appearance.bestMatchFromAppearancesWithNames(&NSArray::from_id_slice(&[ NSString::from_str("NSAppearanceNameAqua"), NSString::from_str("NSAppearanceNameDarkAqua"), ])); diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 0b50de82..16f0d91d 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -2,11 +2,11 @@ use std::cell::Cell; use std::ptr::{self, NonNull}; +use icrate::Foundation::{NSArray, NSObject, NSSize, NSString}; use objc2::declare::{Ivar, IvarDrop}; -use objc2::foundation::{NSArray, NSObject, NSSize, NSString}; -use objc2::rc::{autoreleasepool, Id, Shared}; +use objc2::rc::{autoreleasepool, Id}; use objc2::runtime::Object; -use objc2::{class, declare_class, msg_send, msg_send_id, sel, ClassType}; +use objc2::{class, declare_class, msg_send, msg_send_id, mutability, sel, ClassType}; use super::appkit::{ NSApplicationPresentationOptions, NSFilenamesPboardType, NSPasteboard, NSWindowOcclusionState, @@ -25,7 +25,7 @@ use crate::{ }; #[derive(Debug)] -struct State { +pub struct State { // This is set when WindowBuilder::with_fullscreen was set, // see comments of `window_did_fail_to_enter_fullscreen` initial_fullscreen: Cell, @@ -40,26 +40,30 @@ struct State { declare_class!( #[derive(Debug)] pub(crate) struct WinitWindowDelegate { - window: IvarDrop>, + window: IvarDrop, "_window">, // TODO: It may be possible for delegate methods to be called // asynchronously, causing data races panics? // TODO: Remove unnecessary boxing here - state: IvarDrop>, + state: IvarDrop, "_state">, } + mod ivars; + unsafe impl ClassType for WinitWindowDelegate { type Super = NSObject; + type Mutability = mutability::InteriorMutable; + const NAME: &'static str = "WinitWindowDelegate"; } unsafe impl WinitWindowDelegate { - #[sel(initWithWindow:initialFullscreen:)] + #[method(initWithWindow:initialFullscreen:)] unsafe fn init_with_winit( - &mut self, + this: *mut Self, window: &WinitWindow, initial_fullscreen: bool, ) -> Option> { - let this: Option<&mut Self> = unsafe { msg_send![super(self), init] }; + let this: Option<&mut Self> = unsafe { msg_send![super(this), init] }; this.map(|this| { let scale_factor = window.scale_factor(); @@ -79,7 +83,7 @@ declare_class!( this.window.setDelegate(Some(this)); // Enable theme change event - let notification_center: Id = + let notification_center: Id = unsafe { msg_send_id![class!(NSDistributedNotificationCenter), defaultCenter] }; let notification_name = NSString::from_str("AppleInterfaceThemeChangedNotification"); @@ -100,14 +104,14 @@ declare_class!( // NSWindowDelegate + NSDraggingDestination protocols unsafe impl WinitWindowDelegate { - #[sel(windowShouldClose:)] + #[method(windowShouldClose:)] fn window_should_close(&self, _: Option<&Object>) -> bool { trace_scope!("windowShouldClose:"); self.queue_event(WindowEvent::CloseRequested); false } - #[sel(windowWillClose:)] + #[method(windowWillClose:)] fn window_will_close(&self, _: Option<&Object>) { trace_scope!("windowWillClose:"); // `setDelegate:` retains the previous value and then autoreleases it @@ -119,14 +123,14 @@ declare_class!( self.queue_event(WindowEvent::Destroyed); } - #[sel(windowDidResize:)] + #[method(windowDidResize:)] fn window_did_resize(&self, _: Option<&Object>) { trace_scope!("windowDidResize:"); // NOTE: WindowEvent::Resized is reported in frameDidChange. self.emit_move_event(); } - #[sel(windowWillStartLiveResize:)] + #[method(windowWillStartLiveResize:)] fn window_will_start_live_resize(&self, _: Option<&Object>) { trace_scope!("windowWillStartLiveResize:"); @@ -137,26 +141,26 @@ declare_class!( self.window.set_resize_increments_inner(increments); } - #[sel(windowDidEndLiveResize:)] + #[method(windowDidEndLiveResize:)] fn window_did_end_live_resize(&self, _: Option<&Object>) { trace_scope!("windowDidEndLiveResize:"); self.window.set_resize_increments_inner(NSSize::new(1., 1.)); } // This won't be triggered if the move was part of a resize. - #[sel(windowDidMove:)] + #[method(windowDidMove:)] fn window_did_move(&self, _: Option<&Object>) { trace_scope!("windowDidMove:"); self.emit_move_event(); } - #[sel(windowDidChangeBackingProperties:)] + #[method(windowDidChangeBackingProperties:)] fn window_did_change_backing_properties(&self, _: Option<&Object>) { trace_scope!("windowDidChangeBackingProperties:"); self.queue_static_scale_factor_changed_event(); } - #[sel(windowDidBecomeKey:)] + #[method(windowDidBecomeKey:)] fn window_did_become_key(&self, _: Option<&Object>) { trace_scope!("windowDidBecomeKey:"); // TODO: center the cursor if the window had mouse grab when it @@ -164,7 +168,7 @@ declare_class!( self.queue_event(WindowEvent::Focused(true)); } - #[sel(windowDidResignKey:)] + #[method(windowDidResignKey:)] fn window_did_resign_key(&self, _: Option<&Object>) { trace_scope!("windowDidResignKey:"); // It happens rather often, e.g. when the user is Cmd+Tabbing, that the @@ -180,15 +184,15 @@ declare_class!( } /// Invoked when the dragged image enters destination bounds or frame - #[sel(draggingEntered:)] - fn dragging_entered(&self, sender: *mut Object) -> bool { + #[method(draggingEntered:)] + fn dragging_entered(&self, sender: &NSObject) -> bool { trace_scope!("draggingEntered:"); use std::path::PathBuf; - let pb: Id = unsafe { msg_send_id![sender, draggingPasteboard] }; + let pb: Id = unsafe { msg_send_id![sender, draggingPasteboard] }; let filenames = pb.propertyListForType(unsafe { NSFilenamesPboardType }); - let filenames: Id, Shared> = unsafe { Id::cast(filenames) }; + let filenames: Id> = unsafe { Id::cast(filenames) }; filenames.into_iter().for_each(|file| { let path = PathBuf::from(file.to_string()); @@ -199,22 +203,22 @@ declare_class!( } /// Invoked when the image is released - #[sel(prepareForDragOperation:)] - fn prepare_for_drag_operation(&self, _: Option<&Object>) -> bool { + #[method(prepareForDragOperation:)] + fn prepare_for_drag_operation(&self, _sender: &NSObject) -> bool { trace_scope!("prepareForDragOperation:"); true } /// Invoked after the released image has been removed from the screen - #[sel(performDragOperation:)] - fn perform_drag_operation(&self, sender: *mut Object) -> bool { + #[method(performDragOperation:)] + fn perform_drag_operation(&self, sender: &NSObject) -> bool { trace_scope!("performDragOperation:"); use std::path::PathBuf; - let pb: Id = unsafe { msg_send_id![sender, draggingPasteboard] }; + let pb: Id = unsafe { msg_send_id![sender, draggingPasteboard] }; let filenames = pb.propertyListForType(unsafe { NSFilenamesPboardType }); - let filenames: Id, Shared> = unsafe { Id::cast(filenames) }; + let filenames: Id> = unsafe { Id::cast(filenames) }; filenames.into_iter().for_each(|file| { let path = PathBuf::from(file.to_string()); @@ -225,20 +229,20 @@ declare_class!( } /// Invoked when the dragging operation is complete - #[sel(concludeDragOperation:)] - fn conclude_drag_operation(&self, _: Option<&Object>) { + #[method(concludeDragOperation:)] + fn conclude_drag_operation(&self, _sender: Option<&NSObject>) { trace_scope!("concludeDragOperation:"); } /// Invoked when the dragging operation is cancelled - #[sel(draggingExited:)] - fn dragging_exited(&self, _: Option<&Object>) { + #[method(draggingExited:)] + fn dragging_exited(&self, _sender: Option<&NSObject>) { trace_scope!("draggingExited:"); self.queue_event(WindowEvent::HoveredFileCancelled); } /// Invoked when before enter fullscreen - #[sel(windowWillEnterFullScreen:)] + #[method(windowWillEnterFullScreen:)] fn window_will_enter_fullscreen(&self, _: Option<&Object>) { trace_scope!("windowWillEnterFullScreen:"); @@ -267,7 +271,7 @@ declare_class!( } /// Invoked when before exit fullscreen - #[sel(windowWillExitFullScreen:)] + #[method(windowWillExitFullScreen:)] fn window_will_exit_fullscreen(&self, _: Option<&Object>) { trace_scope!("windowWillExitFullScreen:"); @@ -275,7 +279,7 @@ declare_class!( shared_state.in_fullscreen_transition = true; } - #[sel(window:willUseFullScreenPresentationOptions:)] + #[method(window:willUseFullScreenPresentationOptions:)] fn window_will_use_fullscreen_presentation_options( &self, _: Option<&Object>, @@ -304,7 +308,7 @@ declare_class!( } /// Invoked when entered fullscreen - #[sel(windowDidEnterFullScreen:)] + #[method(windowDidEnterFullScreen:)] fn window_did_enter_fullscreen(&self, _: Option<&Object>) { trace_scope!("windowDidEnterFullScreen:"); self.state.initial_fullscreen.set(false); @@ -318,7 +322,7 @@ declare_class!( } /// Invoked when exited fullscreen - #[sel(windowDidExitFullScreen:)] + #[method(windowDidExitFullScreen:)] fn window_did_exit_fullscreen(&self, _: Option<&Object>) { trace_scope!("windowDidExitFullScreen:"); @@ -348,7 +352,7 @@ declare_class!( /// due to being in the midst of handling some other animation or user gesture. /// This method indicates that there was an error, and you should clean up any /// work you may have done to prepare to enter full-screen mode. - #[sel(windowDidFailToEnterFullScreen:)] + #[method(windowDidFailToEnterFullScreen:)] fn window_did_fail_to_enter_fullscreen(&self, _: Option<&Object>) { trace_scope!("windowDidFailToEnterFullScreen:"); let mut shared_state = self @@ -372,7 +376,7 @@ declare_class!( } // Invoked when the occlusion state of the window changes - #[sel(windowDidChangeOcclusionState:)] + #[method(windowDidChangeOcclusionState:)] fn window_did_change_occlusion_state(&self, _: Option<&Object>) { trace_scope!("windowDidChangeOcclusionState:"); self.queue_event(WindowEvent::Occluded( @@ -384,7 +388,7 @@ declare_class!( } // Observe theme change - #[sel(effectiveAppearanceDidChange:)] + #[method(effectiveAppearanceDidChange:)] fn effective_appearance_did_change(&self, sender: Option<&Object>) { trace_scope!("Triggered `effectiveAppearanceDidChange:`"); unsafe { @@ -397,7 +401,7 @@ declare_class!( } } - #[sel(effectiveAppearanceDidChangedOnMainThread:)] + #[method(effectiveAppearanceDidChangedOnMainThread:)] fn effective_appearance_did_changed_on_main_thread(&self, _: Option<&Object>) { let theme = get_ns_theme(); let mut shared_state = self @@ -411,7 +415,7 @@ declare_class!( } } - #[sel(windowDidChangeScreen:)] + #[method(windowDidChangeScreen:)] fn window_did_change_screen(&self, _: Option<&Object>) { trace_scope!("windowDidChangeScreen:"); let is_simple_fullscreen = self @@ -428,10 +432,10 @@ declare_class!( ); impl WinitWindowDelegate { - pub fn new(window: &WinitWindow, initial_fullscreen: bool) -> Id { + pub fn new(window: &WinitWindow, initial_fullscreen: bool) -> Id { unsafe { msg_send_id![ - msg_send_id![Self::class(), alloc], + Self::alloc(), initWithWindow: window, initialFullscreen: initial_fullscreen, ]