Update objc2 version (#2936)

* Upgrade to objc2 v0.4.0 and icrate v0.0.3

* Fix `touchBar` method

* Use ClassType::alloc

* Use #[method_id(...)] functionality in declare_class!
This commit is contained in:
Mads Marquart 2023-07-29 00:33:03 +02:00 committed by GitHub
parent ae7497e18f
commit e33d2bee6c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 815 additions and 793 deletions

View file

@ -74,12 +74,38 @@ ndk-sys = "0.4.0"
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies] [target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
core-foundation = "0.9.3" 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] [target.'cfg(target_os = "macos")'.dependencies]
core-graphics = "0.22.3" core-graphics = "0.22.3"
dispatch = "0.2.0" 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] [target.'cfg(target_os = "windows")'.dependencies]
unicode-segmentation = "1.7.1" unicode-segmentation = "1.7.1"

View file

@ -15,8 +15,8 @@ use core_foundation::runloop::{
kCFRunLoopCommonModes, CFRunLoopAddTimer, CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate, kCFRunLoopCommonModes, CFRunLoopAddTimer, CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate,
CFRunLoopTimerInvalidate, CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate, CFRunLoopTimerInvalidate, CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate,
}; };
use objc2::foundation::{CGRect, CGSize, NSInteger, NSProcessInfo}; use icrate::Foundation::{CGRect, CGSize, NSInteger, NSProcessInfo};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::runtime::Object; use objc2::runtime::Object;
use objc2::{msg_send, sel}; use objc2::{msg_send, sel};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@ -68,25 +68,25 @@ impl Event<'static, Never> {
#[must_use = "dropping `AppStateImpl` without inspecting it is probably a bug"] #[must_use = "dropping `AppStateImpl` without inspecting it is probably a bug"]
enum AppStateImpl { enum AppStateImpl {
NotLaunched { NotLaunched {
queued_windows: Vec<Id<WinitUIWindow, Shared>>, queued_windows: Vec<Id<WinitUIWindow>>,
queued_events: Vec<EventWrapper>, queued_events: Vec<EventWrapper>,
queued_gpu_redraws: HashSet<Id<WinitUIWindow, Shared>>, queued_gpu_redraws: HashSet<Id<WinitUIWindow>>,
}, },
Launching { Launching {
queued_windows: Vec<Id<WinitUIWindow, Shared>>, queued_windows: Vec<Id<WinitUIWindow>>,
queued_events: Vec<EventWrapper>, queued_events: Vec<EventWrapper>,
queued_event_handler: Box<dyn EventHandler>, queued_event_handler: Box<dyn EventHandler>,
queued_gpu_redraws: HashSet<Id<WinitUIWindow, Shared>>, queued_gpu_redraws: HashSet<Id<WinitUIWindow>>,
}, },
ProcessingEvents { ProcessingEvents {
event_handler: Box<dyn EventHandler>, event_handler: Box<dyn EventHandler>,
queued_gpu_redraws: HashSet<Id<WinitUIWindow, Shared>>, queued_gpu_redraws: HashSet<Id<WinitUIWindow>>,
active_control_flow: ControlFlow, active_control_flow: ControlFlow,
}, },
// special state to deal with reentrancy and prevent mutable aliasing. // special state to deal with reentrancy and prevent mutable aliasing.
InUserCallback { InUserCallback {
queued_events: Vec<EventWrapper>, queued_events: Vec<EventWrapper>,
queued_gpu_redraws: HashSet<Id<WinitUIWindow, Shared>>, queued_gpu_redraws: HashSet<Id<WinitUIWindow>>,
}, },
ProcessingRedraws { ProcessingRedraws {
event_handler: Box<dyn EventHandler>, event_handler: Box<dyn EventHandler>,
@ -204,9 +204,7 @@ impl AppState {
}); });
} }
fn did_finish_launching_transition( fn did_finish_launching_transition(&mut self) -> (Vec<Id<WinitUIWindow>>, Vec<EventWrapper>) {
&mut self,
) -> (Vec<Id<WinitUIWindow, Shared>>, Vec<EventWrapper>) {
let (windows, events, event_handler, queued_gpu_redraws) = match self.take_state() { let (windows, events, event_handler, queued_gpu_redraws) = match self.take_state() {
AppStateImpl::Launching { AppStateImpl::Launching {
queued_windows, queued_windows,
@ -363,7 +361,7 @@ impl AppState {
} }
} }
fn main_events_cleared_transition(&mut self) -> HashSet<Id<WinitUIWindow, Shared>> { fn main_events_cleared_transition(&mut self) -> HashSet<Id<WinitUIWindow>> {
let (event_handler, queued_gpu_redraws, active_control_flow) = match self.take_state() { let (event_handler, queued_gpu_redraws, active_control_flow) = match self.take_state() {
AppStateImpl::ProcessingEvents { AppStateImpl::ProcessingEvents {
event_handler, event_handler,
@ -451,7 +449,7 @@ impl AppState {
// requires main thread and window is a UIWindow // requires main thread and window is a UIWindow
// retains window // retains window
pub(crate) unsafe fn set_key_window(window: &Id<WinitUIWindow, Shared>) { pub(crate) unsafe fn set_key_window(window: &Id<WinitUIWindow>) {
let mut this = AppState::get_mut(); let mut this = AppState::get_mut();
match this.state_mut() { match this.state_mut() {
&mut AppStateImpl::NotLaunched { &mut AppStateImpl::NotLaunched {
@ -474,7 +472,7 @@ pub(crate) unsafe fn set_key_window(window: &Id<WinitUIWindow, Shared>) {
// requires main thread and window is a UIWindow // requires main thread and window is a UIWindow
// retains window // retains window
pub(crate) unsafe fn queue_gl_or_metal_redraw(window: Id<WinitUIWindow, Shared>) { pub(crate) unsafe fn queue_gl_or_metal_redraw(window: Id<WinitUIWindow>) {
let mut this = AppState::get_mut(); let mut this = AppState::get_mut();
match this.state_mut() { match this.state_mut() {
&mut AppStateImpl::NotLaunched { &mut AppStateImpl::NotLaunched {
@ -807,7 +805,7 @@ fn handle_hidpi_proxy(
mut control_flow: ControlFlow, mut control_flow: ControlFlow,
suggested_size: LogicalSize<f64>, suggested_size: LogicalSize<f64>,
scale_factor: f64, scale_factor: f64,
window: Id<WinitUIWindow, Shared>, window: Id<WinitUIWindow>,
) { ) {
let mut size = suggested_size.to_physical(scale_factor); let mut size = suggested_size.to_physical(scale_factor);
let new_inner_size = &mut size; let new_inner_size = &mut size;
@ -827,7 +825,7 @@ fn handle_hidpi_proxy(
view.setFrame(new_frame); view.setFrame(new_frame);
} }
fn get_view_and_screen_frame(window: &WinitUIWindow) -> (Id<UIView, Shared>, CGRect) { fn get_view_and_screen_frame(window: &WinitUIWindow) -> (Id<UIView>, CGRect) {
let view_controller = window.rootViewController().unwrap(); let view_controller = window.rootViewController().unwrap();
let view = view_controller.view().unwrap(); let view = view_controller.view().unwrap();
let bounds = window.bounds(); let bounds = window.bounds();
@ -963,7 +961,7 @@ impl NSOperatingSystemVersion {
pub fn os_capabilities() -> OSCapabilities { pub fn os_capabilities() -> OSCapabilities {
static OS_CAPABILITIES: Lazy<OSCapabilities> = Lazy::new(|| { static OS_CAPABILITIES: Lazy<OSCapabilities> = Lazy::new(|| {
let version: NSOperatingSystemVersion = unsafe { let version: NSOperatingSystemVersion = unsafe {
let process_info = NSProcessInfo::process_info(); let process_info = NSProcessInfo::processInfo();
let atleast_ios_8: bool = msg_send![ let atleast_ios_8: bool = msg_send![
&process_info, &process_info,
respondsToSelector: sel!(operatingSystemVersion) respondsToSelector: sel!(operatingSystemVersion)

View file

@ -14,8 +14,8 @@ use core_foundation::runloop::{
CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext, CFRunLoopSourceCreate, CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext, CFRunLoopSourceCreate,
CFRunLoopSourceInvalidate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp, CFRunLoopSourceInvalidate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp,
}; };
use objc2::foundation::{MainThreadMarker, NSString}; use icrate::Foundation::{MainThreadMarker, NSString};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::ClassType; use objc2::ClassType;
use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle}; use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle};
@ -40,7 +40,7 @@ pub(crate) enum EventWrapper {
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub(crate) enum EventProxy { pub(crate) enum EventProxy {
DpiChangedProxy { DpiChangedProxy {
window: Id<WinitUIWindow, Shared>, window: Id<WinitUIWindow>,
suggested_size: LogicalSize<f64>, suggested_size: LogicalSize<f64>,
scale_factor: f64, scale_factor: f64,
}, },

View file

@ -2,8 +2,8 @@
use std::convert::TryInto; use std::convert::TryInto;
use icrate::Foundation::{NSInteger, NSUInteger};
use objc2::encode::{Encode, Encoding}; use objc2::encode::{Encode, Encoding};
use objc2::foundation::{NSInteger, NSUInteger};
use crate::platform::ios::{Idiom, ScreenEdge}; use crate::platform::ios::{Idiom, ScreenEdge};

View file

@ -63,7 +63,7 @@
// window size/position. // window size/position.
macro_rules! assert_main_thread { macro_rules! assert_main_thread {
($($t:tt)*) => { ($($t:tt)*) => {
if !::objc2::foundation::is_main_thread() { if !::icrate::Foundation::is_main_thread() {
panic!($($t)*); panic!($($t)*);
} }
}; };

View file

@ -6,8 +6,8 @@ use std::{
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
}; };
use objc2::foundation::{MainThreadMarker, NSInteger}; use icrate::Foundation::{MainThreadMarker, NSInteger};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use super::uikit::{UIScreen, UIScreenMode}; use super::uikit::{UIScreen, UIScreenMode};
use crate::{ use crate::{
@ -18,7 +18,7 @@ use crate::{
// TODO(madsmtm): Remove or refactor this // TODO(madsmtm): Remove or refactor this
#[derive(Debug, PartialEq, Eq, Hash, Clone)] #[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub(crate) struct ScreenModeSendSync(pub(crate) Id<UIScreenMode, Shared>); pub(crate) struct ScreenModeSendSync(pub(crate) Id<UIScreenMode>);
unsafe impl Send for ScreenModeSendSync {} unsafe impl Send for ScreenModeSendSync {}
unsafe impl Sync for ScreenModeSendSync {} unsafe impl Sync for ScreenModeSendSync {}
@ -33,7 +33,7 @@ pub struct VideoMode {
} }
impl VideoMode { impl VideoMode {
fn new(uiscreen: Id<UIScreen, Shared>, screen_mode: Id<UIScreenMode, Shared>) -> VideoMode { fn new(uiscreen: Id<UIScreen>, screen_mode: Id<UIScreenMode>) -> VideoMode {
assert_main_thread!("`VideoMode` can only be created on the main thread on iOS"); assert_main_thread!("`VideoMode` can only be created on the main thread on iOS");
let refresh_rate_millihertz = refresh_rate_millihertz(&uiscreen); let refresh_rate_millihertz = refresh_rate_millihertz(&uiscreen);
let size = screen_mode.size(); let size = screen_mode.size();
@ -65,7 +65,7 @@ impl VideoMode {
#[derive(Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]
pub struct Inner { pub struct Inner {
uiscreen: Id<UIScreen, Shared>, uiscreen: Id<UIScreen>,
} }
#[derive(Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]
@ -135,7 +135,7 @@ impl fmt::Debug for MonitorHandle {
} }
impl MonitorHandle { impl MonitorHandle {
pub(crate) fn new(uiscreen: Id<UIScreen, Shared>) -> Self { pub(crate) fn new(uiscreen: Id<UIScreen>) -> Self {
assert_main_thread!("`MonitorHandle` can only be created on the main thread on iOS"); assert_main_thread!("`MonitorHandle` can only be created on the main thread on iOS");
Self { Self {
inner: Inner { uiscreen }, inner: Inner { uiscreen },
@ -182,13 +182,8 @@ impl Inner {
.uiscreen .uiscreen
.availableModes() .availableModes()
.into_iter() .into_iter()
.map(|mode| { .map(|mode| RootVideoMode {
let mode: *const UIScreenMode = mode; video_mode: VideoMode::new(self.uiscreen.clone(), mode),
let mode = unsafe { Id::retain(mode as *mut UIScreenMode).unwrap() };
RootVideoMode {
video_mode: VideoMode::new(self.uiscreen.clone(), mode),
}
}) })
.collect(); .collect();
@ -222,7 +217,7 @@ fn refresh_rate_millihertz(uiscreen: &UIScreen) -> u32 {
// MonitorHandleExtIOS // MonitorHandleExtIOS
impl Inner { impl Inner {
pub(crate) fn ui_screen(&self) -> &Id<UIScreen, Shared> { pub(crate) fn ui_screen(&self) -> &Id<UIScreen> {
&self.uiscreen &self.uiscreen
} }
@ -237,10 +232,6 @@ impl Inner {
pub fn uiscreens(mtm: MainThreadMarker) -> VecDeque<MonitorHandle> { pub fn uiscreens(mtm: MainThreadMarker) -> VecDeque<MonitorHandle> {
UIScreen::screens(mtm) UIScreen::screens(mtm)
.into_iter() .into_iter()
.map(|screen| { .map(MonitorHandle::new)
let screen: *const UIScreen = screen;
let screen = unsafe { Id::retain(screen as *mut UIScreen).unwrap() };
MonitorHandle::new(screen)
})
.collect() .collect()
} }

View file

@ -1,6 +1,6 @@
use objc2::foundation::{CGRect, MainThreadMarker, NSArray, NSObject}; use icrate::Foundation::{CGRect, MainThreadMarker, NSArray, NSObject};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
use super::{UIResponder, UIWindow}; use super::{UIResponder, UIWindow};
@ -11,20 +11,21 @@ extern_class!(
unsafe impl ClassType for UIApplication { unsafe impl ClassType for UIApplication {
#[inherits(NSObject)] #[inherits(NSObject)]
type Super = UIResponder; type Super = UIResponder;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl UIApplication { unsafe impl UIApplication {
pub fn shared(_mtm: MainThreadMarker) -> Option<Id<Self, Shared>> { pub fn shared(_mtm: MainThreadMarker) -> Option<Id<Self>> {
unsafe { msg_send_id![Self::class(), sharedApplication] } unsafe { msg_send_id![Self::class(), sharedApplication] }
} }
pub fn windows(&self) -> Id<NSArray<UIWindow, Shared>, Shared> { pub fn windows(&self) -> Id<NSArray<UIWindow>> {
unsafe { msg_send_id![self, windows] } unsafe { msg_send_id![self, windows] }
} }
#[sel(statusBarFrame)] #[method(statusBarFrame)]
pub fn statusBarFrame(&self) -> CGRect; pub fn statusBarFrame(&self) -> CGRect;
} }
); );

View file

@ -1,5 +1,5 @@
use objc2::foundation::NSObject; use icrate::Foundation::NSObject;
use objc2::{extern_class, ClassType}; use objc2::{extern_class, mutability, ClassType};
extern_class!( extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -7,5 +7,6 @@ extern_class!(
unsafe impl ClassType for UICoordinateSpace { unsafe impl ClassType for UICoordinateSpace {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );

View file

@ -1,6 +1,6 @@
use objc2::foundation::{MainThreadMarker, NSObject}; use icrate::Foundation::{MainThreadMarker, NSObject};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
use super::super::ffi::UIUserInterfaceIdiom; use super::super::ffi::UIUserInterfaceIdiom;
@ -10,16 +10,17 @@ extern_class!(
unsafe impl ClassType for UIDevice { unsafe impl ClassType for UIDevice {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl UIDevice { unsafe impl UIDevice {
pub fn current(_mtm: MainThreadMarker) -> Id<Self, Shared> { pub fn current(_mtm: MainThreadMarker) -> Id<Self> {
unsafe { msg_send_id![Self::class(), currentDevice] } unsafe { msg_send_id![Self::class(), currentDevice] }
} }
#[sel(userInterfaceIdiom)] #[method(userInterfaceIdiom)]
pub fn userInterfaceIdiom(&self) -> UIUserInterfaceIdiom; pub fn userInterfaceIdiom(&self) -> UIUserInterfaceIdiom;
} }
); );

View file

@ -1,5 +1,5 @@
use objc2::foundation::NSObject; use icrate::Foundation::NSObject;
use objc2::{extern_class, ClassType}; use objc2::{extern_class, mutability, ClassType};
extern_class!( extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -7,5 +7,6 @@ extern_class!(
unsafe impl ClassType for UIEvent { unsafe impl ClassType for UIEvent {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );

View file

@ -4,7 +4,7 @@
use std::os::raw::{c_char, c_int}; use std::os::raw::{c_char, c_int};
use objc2::foundation::NSString; use icrate::Foundation::NSString;
mod application; mod application;
mod coordinate_space; mod coordinate_space;

View file

@ -1,5 +1,5 @@
use objc2::foundation::NSObject; use icrate::Foundation::NSObject;
use objc2::{extern_class, ClassType}; use objc2::{extern_class, mutability, ClassType};
extern_class!( extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -7,5 +7,6 @@ extern_class!(
unsafe impl ClassType for UIResponder { unsafe impl ClassType for UIResponder {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );

View file

@ -1,7 +1,7 @@
use icrate::Foundation::{CGFloat, CGRect, MainThreadMarker, NSArray, NSInteger, NSObject};
use objc2::encode::{Encode, Encoding}; use objc2::encode::{Encode, Encoding};
use objc2::foundation::{CGFloat, CGRect, MainThreadMarker, NSArray, NSInteger, NSObject}; use objc2::rc::Id;
use objc2::rc::{Id, Shared}; use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
use super::{UICoordinateSpace, UIScreenMode}; use super::{UICoordinateSpace, UIScreenMode};
@ -11,53 +11,54 @@ extern_class!(
unsafe impl ClassType for UIScreen { unsafe impl ClassType for UIScreen {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl UIScreen { unsafe impl UIScreen {
pub fn main(_mtm: MainThreadMarker) -> Id<Self, Shared> { pub fn main(_mtm: MainThreadMarker) -> Id<Self> {
unsafe { msg_send_id![Self::class(), mainScreen] } unsafe { msg_send_id![Self::class(), mainScreen] }
} }
pub fn screens(_mtm: MainThreadMarker) -> Id<NSArray<Self, Shared>, Shared> { pub fn screens(_mtm: MainThreadMarker) -> Id<NSArray<Self>> {
unsafe { msg_send_id![Self::class(), screens] } unsafe { msg_send_id![Self::class(), screens] }
} }
#[sel(bounds)] #[method(bounds)]
pub fn bounds(&self) -> CGRect; pub fn bounds(&self) -> CGRect;
#[sel(scale)] #[method(scale)]
pub fn scale(&self) -> CGFloat; pub fn scale(&self) -> CGFloat;
#[sel(nativeBounds)] #[method(nativeBounds)]
pub fn nativeBounds(&self) -> CGRect; pub fn nativeBounds(&self) -> CGRect;
#[sel(nativeScale)] #[method(nativeScale)]
pub fn nativeScale(&self) -> CGFloat; pub fn nativeScale(&self) -> CGFloat;
#[sel(maximumFramesPerSecond)] #[method(maximumFramesPerSecond)]
pub fn maximumFramesPerSecond(&self) -> NSInteger; pub fn maximumFramesPerSecond(&self) -> NSInteger;
pub fn mirroredScreen(&self) -> Id<Self, Shared> { pub fn mirroredScreen(&self) -> Id<Self> {
unsafe { msg_send_id![Self::class(), mirroredScreen] } unsafe { msg_send_id![Self::class(), mirroredScreen] }
} }
pub fn preferredMode(&self) -> Option<Id<UIScreenMode, Shared>> { pub fn preferredMode(&self) -> Option<Id<UIScreenMode>> {
unsafe { msg_send_id![self, preferredMode] } unsafe { msg_send_id![self, preferredMode] }
} }
#[sel(setCurrentMode:)] #[method(setCurrentMode:)]
pub fn setCurrentMode(&self, mode: Option<&UIScreenMode>); pub fn setCurrentMode(&self, mode: Option<&UIScreenMode>);
pub fn availableModes(&self) -> Id<NSArray<UIScreenMode, Shared>, Shared> { pub fn availableModes(&self) -> Id<NSArray<UIScreenMode>> {
unsafe { msg_send_id![self, availableModes] } unsafe { msg_send_id![self, availableModes] }
} }
#[sel(setOverscanCompensation:)] #[method(setOverscanCompensation:)]
pub fn setOverscanCompensation(&self, overscanCompensation: UIScreenOverscanCompensation); pub fn setOverscanCompensation(&self, overscanCompensation: UIScreenOverscanCompensation);
pub fn coordinateSpace(&self) -> Id<UICoordinateSpace, Shared> { pub fn coordinateSpace(&self) -> Id<UICoordinateSpace> {
unsafe { msg_send_id![self, coordinateSpace] } unsafe { msg_send_id![self, coordinateSpace] }
} }
} }

View file

@ -1,5 +1,5 @@
use objc2::foundation::{CGSize, NSObject}; use icrate::Foundation::{CGSize, NSObject};
use objc2::{extern_class, extern_methods, ClassType}; use objc2::{extern_class, extern_methods, mutability, ClassType};
extern_class!( extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -7,12 +7,13 @@ extern_class!(
unsafe impl ClassType for UIScreenMode { unsafe impl ClassType for UIScreenMode {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl UIScreenMode { unsafe impl UIScreenMode {
#[sel(size)] #[method(size)]
pub fn size(&self) -> CGSize; pub fn size(&self) -> CGSize;
} }
); );

View file

@ -1,6 +1,6 @@
use icrate::Foundation::{CGFloat, CGPoint, NSInteger, NSObject};
use objc2::encode::{Encode, Encoding}; use objc2::encode::{Encode, Encoding};
use objc2::foundation::{CGFloat, CGPoint, NSInteger, NSObject}; use objc2::{extern_class, extern_methods, mutability, ClassType};
use objc2::{extern_class, extern_methods, ClassType};
use super::UIView; use super::UIView;
@ -10,27 +10,28 @@ extern_class!(
unsafe impl ClassType for UITouch { unsafe impl ClassType for UITouch {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl UITouch { unsafe impl UITouch {
#[sel(locationInView:)] #[method(locationInView:)]
pub fn locationInView(&self, view: Option<&UIView>) -> CGPoint; pub fn locationInView(&self, view: Option<&UIView>) -> CGPoint;
#[sel(type)] #[method(type)]
pub fn type_(&self) -> UITouchType; pub fn type_(&self) -> UITouchType;
#[sel(force)] #[method(force)]
pub fn force(&self) -> CGFloat; pub fn force(&self) -> CGFloat;
#[sel(maximumPossibleForce)] #[method(maximumPossibleForce)]
pub fn maximumPossibleForce(&self) -> CGFloat; pub fn maximumPossibleForce(&self) -> CGFloat;
#[sel(altitudeAngle)] #[method(altitudeAngle)]
pub fn altitudeAngle(&self) -> CGFloat; pub fn altitudeAngle(&self) -> CGFloat;
#[sel(phase)] #[method(phase)]
pub fn phase(&self) -> UITouchPhase; pub fn phase(&self) -> UITouchPhase;
} }
); );

View file

@ -1,6 +1,6 @@
use icrate::Foundation::{NSInteger, NSObject};
use objc2::encode::{Encode, Encoding}; use objc2::encode::{Encode, Encoding};
use objc2::foundation::{NSInteger, NSObject}; use objc2::{extern_class, extern_methods, mutability, ClassType};
use objc2::{extern_class, extern_methods, ClassType};
extern_class!( extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -8,12 +8,13 @@ extern_class!(
unsafe impl ClassType for UITraitCollection { unsafe impl ClassType for UITraitCollection {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl UITraitCollection { unsafe impl UITraitCollection {
#[sel(forceTouchCapability)] #[method(forceTouchCapability)]
pub fn forceTouchCapability(&self) -> UIForceTouchCapability; pub fn forceTouchCapability(&self) -> UIForceTouchCapability;
} }
); );

View file

@ -1,7 +1,7 @@
use icrate::Foundation::{CGFloat, CGRect, NSObject};
use objc2::encode::{Encode, Encoding}; use objc2::encode::{Encode, Encoding};
use objc2::foundation::{CGFloat, CGRect, NSObject}; use objc2::rc::Id;
use objc2::rc::{Id, Shared}; use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
use super::{UICoordinateSpace, UIResponder, UIViewController}; use super::{UICoordinateSpace, UIResponder, UIViewController};
@ -12,57 +12,58 @@ extern_class!(
unsafe impl ClassType for UIView { unsafe impl ClassType for UIView {
#[inherits(NSObject)] #[inherits(NSObject)]
type Super = UIResponder; type Super = UIResponder;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl UIView { unsafe impl UIView {
#[sel(bounds)] #[method(bounds)]
pub fn bounds(&self) -> CGRect; pub fn bounds(&self) -> CGRect;
#[sel(setBounds:)] #[method(setBounds:)]
pub fn setBounds(&self, value: CGRect); pub fn setBounds(&self, value: CGRect);
#[sel(frame)] #[method(frame)]
pub fn frame(&self) -> CGRect; pub fn frame(&self) -> CGRect;
#[sel(setFrame:)] #[method(setFrame:)]
pub fn setFrame(&self, value: CGRect); pub fn setFrame(&self, value: CGRect);
#[sel(contentScaleFactor)] #[method(contentScaleFactor)]
pub fn contentScaleFactor(&self) -> CGFloat; pub fn contentScaleFactor(&self) -> CGFloat;
#[sel(setContentScaleFactor:)] #[method(setContentScaleFactor:)]
pub fn setContentScaleFactor(&self, val: CGFloat); pub fn setContentScaleFactor(&self, val: CGFloat);
#[sel(setMultipleTouchEnabled:)] #[method(setMultipleTouchEnabled:)]
pub fn setMultipleTouchEnabled(&self, val: bool); pub fn setMultipleTouchEnabled(&self, val: bool);
pub fn rootViewController(&self) -> Option<Id<UIViewController, Shared>> { pub fn rootViewController(&self) -> Option<Id<UIViewController>> {
unsafe { msg_send_id![self, rootViewController] } unsafe { msg_send_id![self, rootViewController] }
} }
#[sel(setRootViewController:)] #[method(setRootViewController:)]
pub fn setRootViewController(&self, rootViewController: Option<&UIViewController>); pub fn setRootViewController(&self, rootViewController: Option<&UIViewController>);
#[sel(convertRect:toCoordinateSpace:)] #[method(convertRect:toCoordinateSpace:)]
pub fn convertRect_toCoordinateSpace( pub fn convertRect_toCoordinateSpace(
&self, &self,
rect: CGRect, rect: CGRect,
coordinateSpace: &UICoordinateSpace, coordinateSpace: &UICoordinateSpace,
) -> CGRect; ) -> CGRect;
#[sel(convertRect:fromCoordinateSpace:)] #[method(convertRect:fromCoordinateSpace:)]
pub fn convertRect_fromCoordinateSpace( pub fn convertRect_fromCoordinateSpace(
&self, &self,
rect: CGRect, rect: CGRect,
coordinateSpace: &UICoordinateSpace, coordinateSpace: &UICoordinateSpace,
) -> CGRect; ) -> CGRect;
#[sel(safeAreaInsets)] #[method(safeAreaInsets)]
pub fn safeAreaInsets(&self) -> UIEdgeInsets; pub fn safeAreaInsets(&self) -> UIEdgeInsets;
#[sel(setNeedsDisplay)] #[method(setNeedsDisplay)]
pub fn setNeedsDisplay(&self); pub fn setNeedsDisplay(&self);
} }
); );

View file

@ -1,7 +1,7 @@
use icrate::Foundation::{NSObject, NSUInteger};
use objc2::encode::{Encode, Encoding}; use objc2::encode::{Encode, Encoding};
use objc2::foundation::{NSObject, NSUInteger}; use objc2::rc::Id;
use objc2::rc::{Id, Shared}; use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
use objc2::{extern_class, extern_methods, msg_send_id, ClassType};
use super::{UIResponder, UIView}; use super::{UIResponder, UIView};
@ -12,28 +12,29 @@ extern_class!(
unsafe impl ClassType for UIViewController { unsafe impl ClassType for UIViewController {
#[inherits(NSObject)] #[inherits(NSObject)]
type Super = UIResponder; type Super = UIResponder;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl UIViewController { unsafe impl UIViewController {
#[sel(attemptRotationToDeviceOrientation)] #[method(attemptRotationToDeviceOrientation)]
pub fn attemptRotationToDeviceOrientation(); pub fn attemptRotationToDeviceOrientation();
#[sel(setNeedsStatusBarAppearanceUpdate)] #[method(setNeedsStatusBarAppearanceUpdate)]
pub fn setNeedsStatusBarAppearanceUpdate(&self); pub fn setNeedsStatusBarAppearanceUpdate(&self);
#[sel(setNeedsUpdateOfHomeIndicatorAutoHidden)] #[method(setNeedsUpdateOfHomeIndicatorAutoHidden)]
pub fn setNeedsUpdateOfHomeIndicatorAutoHidden(&self); pub fn setNeedsUpdateOfHomeIndicatorAutoHidden(&self);
#[sel(setNeedsUpdateOfScreenEdgesDeferringSystemGestures)] #[method(setNeedsUpdateOfScreenEdgesDeferringSystemGestures)]
pub fn setNeedsUpdateOfScreenEdgesDeferringSystemGestures(&self); pub fn setNeedsUpdateOfScreenEdgesDeferringSystemGestures(&self);
pub fn view(&self) -> Option<Id<UIView, Shared>> { pub fn view(&self) -> Option<Id<UIView>> {
unsafe { msg_send_id![self, view] } unsafe { msg_send_id![self, view] }
} }
#[sel(setView:)] #[method(setView:)]
pub fn setView(&self, view: Option<&UIView>); pub fn setView(&self, view: Option<&UIView>);
} }
); );

View file

@ -1,6 +1,6 @@
use objc2::foundation::NSObject; use icrate::Foundation::NSObject;
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
use super::{UIResponder, UIScreen, UIView}; use super::{UIResponder, UIScreen, UIView};
@ -11,25 +11,26 @@ extern_class!(
unsafe impl ClassType for UIWindow { unsafe impl ClassType for UIWindow {
#[inherits(UIResponder, NSObject)] #[inherits(UIResponder, NSObject)]
type Super = UIView; type Super = UIView;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl UIWindow { unsafe impl UIWindow {
pub fn screen(&self) -> Id<UIScreen, Shared> { pub fn screen(&self) -> Id<UIScreen> {
unsafe { msg_send_id![self, screen] } unsafe { msg_send_id![self, screen] }
} }
#[sel(setScreen:)] #[method(setScreen:)]
pub fn setScreen(&self, screen: &UIScreen); pub fn setScreen(&self, screen: &UIScreen);
#[sel(setHidden:)] #[method(setHidden:)]
pub fn setHidden(&self, flag: bool); pub fn setHidden(&self, flag: bool);
#[sel(makeKeyAndVisible)] #[method(makeKeyAndVisible)]
pub fn makeKeyAndVisible(&self); pub fn makeKeyAndVisible(&self);
#[sel(isKeyWindow)] #[method(isKeyWindow)]
pub fn isKeyWindow(&self) -> bool; pub fn isKeyWindow(&self) -> bool;
} }
); );

View file

@ -2,11 +2,11 @@
use std::cell::Cell; use std::cell::Cell;
use std::ptr::NonNull; use std::ptr::NonNull;
use icrate::Foundation::{CGFloat, CGRect, MainThreadMarker, NSObject, NSObjectProtocol, NSSet};
use objc2::declare::{Ivar, IvarDrop}; use objc2::declare::{Ivar, IvarDrop};
use objc2::foundation::{CGFloat, CGRect, MainThreadMarker, NSObject, NSSet}; use objc2::rc::Id;
use objc2::rc::{Id, Shared};
use objc2::runtime::Class; 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::{ use super::uikit::{
UIApplication, UIDevice, UIEvent, UIForceTouchCapability, UIInterfaceOrientationMask, UIApplication, UIDevice, UIEvent, UIForceTouchCapability, UIInterfaceOrientationMask,
@ -29,16 +29,17 @@ use crate::{
}; };
declare_class!( declare_class!(
pub(crate) struct WinitView {} pub(crate) struct WinitView;
unsafe impl ClassType for WinitView { unsafe impl ClassType for WinitView {
#[inherits(UIResponder, NSObject)] #[inherits(UIResponder, NSObject)]
type Super = UIView; type Super = UIView;
type Mutability = mutability::InteriorMutable;
const NAME: &'static str = "WinitUIView"; const NAME: &'static str = "WinitUIView";
} }
unsafe impl WinitView { unsafe impl WinitView {
#[sel(drawRect:)] #[method(drawRect:)]
fn draw_rect(&self, rect: CGRect) { fn draw_rect(&self, rect: CGRect) {
let window = self.window().unwrap(); let window = self.window().unwrap();
unsafe { unsafe {
@ -49,7 +50,7 @@ declare_class!(
let _: () = unsafe { msg_send![super(self), drawRect: rect] }; let _: () = unsafe { msg_send![super(self), drawRect: rect] };
} }
#[sel(layoutSubviews)] #[method(layoutSubviews)]
fn layout_subviews(&self) { fn layout_subviews(&self) {
let _: () = unsafe { msg_send![super(self), layoutSubviews] }; 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) { fn set_content_scale_factor(&self, untrusted_scale_factor: CGFloat) {
let _: () = let _: () =
unsafe { msg_send![super(self), setContentScaleFactor: untrusted_scale_factor] }; 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<UITouch>, _event: Option<&UIEvent>) { fn touches_began(&self, touches: &NSSet<UITouch>, _event: Option<&UIEvent>) {
self.handle_touches(touches) self.handle_touches(touches)
} }
#[sel(touchesMoved:withEvent:)] #[method(touchesMoved:withEvent:)]
fn touches_moved(&self, touches: &NSSet<UITouch>, _event: Option<&UIEvent>) { fn touches_moved(&self, touches: &NSSet<UITouch>, _event: Option<&UIEvent>) {
self.handle_touches(touches) self.handle_touches(touches)
} }
#[sel(touchesEnded:withEvent:)] #[method(touchesEnded:withEvent:)]
fn touches_ended(&self, touches: &NSSet<UITouch>, _event: Option<&UIEvent>) { fn touches_ended(&self, touches: &NSSet<UITouch>, _event: Option<&UIEvent>) {
self.handle_touches(touches) self.handle_touches(touches)
} }
#[sel(touchesCancelled:withEvent:)] #[method(touchesCancelled:withEvent:)]
fn touches_cancelled(&self, touches: &NSSet<UITouch>, _event: Option<&UIEvent>) { fn touches_cancelled(&self, touches: &NSSet<UITouch>, _event: Option<&UIEvent>) {
self.handle_touches(touches) self.handle_touches(touches)
} }
@ -156,16 +157,16 @@ declare_class!(
extern_methods!( extern_methods!(
#[allow(non_snake_case)] #[allow(non_snake_case)]
unsafe impl WinitView { unsafe impl WinitView {
fn window(&self) -> Option<Id<WinitUIWindow, Shared>> { fn window(&self) -> Option<Id<WinitUIWindow>> {
unsafe { msg_send_id![self, window] } unsafe { msg_send_id![self, window] }
} }
unsafe fn traitCollection(&self) -> Id<UITraitCollection, Shared> { unsafe fn traitCollection(&self) -> Id<UITraitCollection> {
msg_send_id![self, traitCollection] msg_send_id![self, traitCollection]
} }
// TODO: Allow the user to customize this // TODO: Allow the user to customize this
#[sel(layerClass)] #[method(layerClass)]
pub(crate) fn layerClass() -> &'static Class; pub(crate) fn layerClass() -> &'static Class;
} }
); );
@ -176,9 +177,8 @@ impl WinitView {
_window_attributes: &WindowAttributes, _window_attributes: &WindowAttributes,
platform_attributes: &PlatformSpecificWindowBuilderAttributes, platform_attributes: &PlatformSpecificWindowBuilderAttributes,
frame: CGRect, frame: CGRect,
) -> Id<Self, Shared> { ) -> Id<Self> {
let this: Id<Self, Shared> = let this: Id<Self> = unsafe { msg_send_id![Self::alloc(), initWithFrame: frame] };
unsafe { msg_send_id![msg_send_id![Self::class(), alloc], initWithFrame: frame] };
this.setMultipleTouchEnabled(true); this.setMultipleTouchEnabled(true);
@ -258,7 +258,7 @@ impl WinitView {
} }
} }
struct ViewControllerState { pub struct ViewControllerState {
prefers_status_bar_hidden: Cell<bool>, prefers_status_bar_hidden: Cell<bool>,
prefers_home_indicator_auto_hidden: Cell<bool>, prefers_home_indicator_auto_hidden: Cell<bool>,
supported_orientations: Cell<UIInterfaceOrientationMask>, supported_orientations: Cell<UIInterfaceOrientationMask>,
@ -267,19 +267,22 @@ struct ViewControllerState {
declare_class!( declare_class!(
pub(crate) struct WinitViewController { pub(crate) struct WinitViewController {
state: IvarDrop<Box<ViewControllerState>>, state: IvarDrop<Box<ViewControllerState>, "_state">,
} }
mod view_controller_ivars;
unsafe impl ClassType for WinitViewController { unsafe impl ClassType for WinitViewController {
#[inherits(UIResponder, NSObject)] #[inherits(UIResponder, NSObject)]
type Super = UIViewController; type Super = UIViewController;
type Mutability = mutability::InteriorMutable;
const NAME: &'static str = "WinitUIViewController"; const NAME: &'static str = "WinitUIViewController";
} }
unsafe impl WinitViewController { unsafe impl WinitViewController {
#[sel(init)] #[method(init)]
fn init(&mut self) -> Option<NonNull<Self>> { unsafe fn init(this: *mut Self) -> Option<NonNull<Self>> {
let this: Option<&mut Self> = unsafe { msg_send![super(self), init] }; let this: Option<&mut Self> = msg_send![super(this), init];
this.map(|this| { this.map(|this| {
// These are set in WinitViewController::new, it's just to set them // These are set in WinitViewController::new, it's just to set them
// to _something_. // to _something_.
@ -300,27 +303,27 @@ declare_class!(
} }
unsafe impl WinitViewController { unsafe impl WinitViewController {
#[sel(shouldAutorotate)] #[method(shouldAutorotate)]
fn should_autorotate(&self) -> bool { fn should_autorotate(&self) -> bool {
true true
} }
#[sel(prefersStatusBarHidden)] #[method(prefersStatusBarHidden)]
fn prefers_status_bar_hidden(&self) -> bool { fn prefers_status_bar_hidden(&self) -> bool {
self.state.prefers_status_bar_hidden.get() self.state.prefers_status_bar_hidden.get()
} }
#[sel(prefersHomeIndicatorAutoHidden)] #[method(prefersHomeIndicatorAutoHidden)]
fn prefers_home_indicator_auto_hidden(&self) -> bool { fn prefers_home_indicator_auto_hidden(&self) -> bool {
self.state.prefers_home_indicator_auto_hidden.get() self.state.prefers_home_indicator_auto_hidden.get()
} }
#[sel(supportedInterfaceOrientations)] #[method(supportedInterfaceOrientations)]
fn supported_orientations(&self) -> UIInterfaceOrientationMask { fn supported_orientations(&self) -> UIInterfaceOrientationMask {
self.state.supported_orientations.get() self.state.supported_orientations.get()
} }
#[sel(preferredScreenEdgesDeferringSystemGestures)] #[method(preferredScreenEdgesDeferringSystemGestures)]
fn preferred_screen_edges_deferring_system_gestures(&self) -> UIRectEdge { fn preferred_screen_edges_deferring_system_gestures(&self) -> UIRectEdge {
self.state self.state
.preferred_screen_edges_deferring_system_gestures .preferred_screen_edges_deferring_system_gestures
@ -388,9 +391,8 @@ impl WinitViewController {
_window_attributes: &WindowAttributes, _window_attributes: &WindowAttributes,
platform_attributes: &PlatformSpecificWindowBuilderAttributes, platform_attributes: &PlatformSpecificWindowBuilderAttributes,
view: &UIView, view: &UIView,
) -> Id<Self, Shared> { ) -> Id<Self> {
let this: Id<Self, Shared> = let this: Id<Self> = unsafe { msg_send_id![Self::alloc(), init] };
unsafe { msg_send_id![msg_send_id![Self::class(), alloc], init] };
this.set_prefers_status_bar_hidden(platform_attributes.prefers_status_bar_hidden); this.set_prefers_status_bar_hidden(platform_attributes.prefers_status_bar_hidden);
@ -414,15 +416,17 @@ impl WinitViewController {
declare_class!( declare_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
pub(crate) struct WinitUIWindow {} pub(crate) struct WinitUIWindow;
unsafe impl ClassType for WinitUIWindow { unsafe impl ClassType for WinitUIWindow {
#[inherits(UIResponder, NSObject)] #[inherits(UIResponder, NSObject)]
type Super = UIWindow; type Super = UIWindow;
type Mutability = mutability::InteriorMutable;
const NAME: &'static str = "WinitUIWindow";
} }
unsafe impl WinitUIWindow { unsafe impl WinitUIWindow {
#[sel(becomeKeyWindow)] #[method(becomeKeyWindow)]
fn become_key_window(&self) { fn become_key_window(&self) {
unsafe { unsafe {
app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::WindowEvent { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::WindowEvent {
@ -433,7 +437,7 @@ declare_class!(
let _: () = unsafe { msg_send![super(self), becomeKeyWindow] }; let _: () = unsafe { msg_send![super(self), becomeKeyWindow] };
} }
#[sel(resignKeyWindow)] #[method(resignKeyWindow)]
fn resign_key_window(&self) { fn resign_key_window(&self) {
unsafe { unsafe {
app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::WindowEvent { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::WindowEvent {
@ -453,9 +457,8 @@ impl WinitUIWindow {
_platform_attributes: &PlatformSpecificWindowBuilderAttributes, _platform_attributes: &PlatformSpecificWindowBuilderAttributes,
frame: CGRect, frame: CGRect,
view_controller: &UIViewController, view_controller: &UIViewController,
) -> Id<Self, Shared> { ) -> Id<Self> {
let this: Id<Self, Shared> = let this: Id<Self> = unsafe { msg_send_id![Self::alloc(), initWithFrame: frame] };
unsafe { msg_send_id![msg_send_id![Self::class(), alloc], initWithFrame: frame] };
this.setRootViewController(Some(view_controller)); this.setRootViewController(Some(view_controller));
@ -482,15 +485,17 @@ impl WinitUIWindow {
} }
declare_class!( declare_class!(
pub struct WinitApplicationDelegate {} pub struct WinitApplicationDelegate;
unsafe impl ClassType for WinitApplicationDelegate { unsafe impl ClassType for WinitApplicationDelegate {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
const NAME: &'static str = "WinitApplicationDelegate";
} }
// UIApplicationDelegate protocol // UIApplicationDelegate protocol
unsafe impl WinitApplicationDelegate { unsafe impl WinitApplicationDelegate {
#[sel(application:didFinishLaunchingWithOptions:)] #[method(application:didFinishLaunchingWithOptions:)]
fn did_finish_launching(&self, _application: &UIApplication, _: *mut NSObject) -> bool { fn did_finish_launching(&self, _application: &UIApplication, _: *mut NSObject) -> bool {
unsafe { unsafe {
app_state::did_finish_launching(); app_state::did_finish_launching();
@ -498,22 +503,23 @@ declare_class!(
true true
} }
#[sel(applicationDidBecomeActive:)] #[method(applicationDidBecomeActive:)]
fn did_become_active(&self, _application: &UIApplication) { fn did_become_active(&self, _application: &UIApplication) {
unsafe { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::Resumed)) } unsafe { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::Resumed)) }
} }
#[sel(applicationWillResignActive:)] #[method(applicationWillResignActive:)]
fn will_resign_active(&self, _application: &UIApplication) { fn will_resign_active(&self, _application: &UIApplication) {
unsafe { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::Suspended)) } unsafe { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::Suspended)) }
} }
#[sel(applicationWillEnterForeground:)] #[method(applicationWillEnterForeground:)]
fn will_enter_foreground(&self, _application: &UIApplication) {} fn will_enter_foreground(&self, _application: &UIApplication) {}
#[sel(applicationDidEnterBackground:)]
#[method(applicationDidEnterBackground:)]
fn did_enter_background(&self, _application: &UIApplication) {} fn did_enter_background(&self, _application: &UIApplication) {}
#[sel(applicationWillTerminate:)] #[method(applicationWillTerminate:)]
fn will_terminate(&self, application: &UIApplication) { fn will_terminate(&self, application: &UIApplication) {
let mut events = Vec::new(); let mut events = Vec::new();
for window in application.windows().iter() { for window in application.windows().iter() {

View file

@ -6,8 +6,8 @@ use std::{
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
}; };
use objc2::foundation::{CGFloat, CGPoint, CGRect, CGSize, MainThreadMarker}; use icrate::Foundation::{CGFloat, CGPoint, CGRect, CGSize, MainThreadMarker};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::runtime::Object; use objc2::runtime::Object;
use objc2::{class, msg_send}; use objc2::{class, msg_send};
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, UiKitDisplayHandle, UiKitWindowHandle}; use raw_window_handle::{RawDisplayHandle, RawWindowHandle, UiKitDisplayHandle, UiKitWindowHandle};
@ -32,9 +32,9 @@ use crate::{
}; };
pub struct Inner { pub struct Inner {
pub(crate) window: Id<WinitUIWindow, Shared>, pub(crate) window: Id<WinitUIWindow>,
pub(crate) view_controller: Id<WinitViewController, Shared>, pub(crate) view_controller: Id<WinitViewController>,
pub(crate) view: Id<WinitView, Shared>, pub(crate) view: Id<WinitView>,
gl_or_metal_backed: bool, gl_or_metal_backed: bool,
} }

View file

@ -1,7 +1,7 @@
#![allow(clippy::unnecessary_cast)] #![allow(clippy::unnecessary_cast)]
use objc2::foundation::NSObject; use icrate::Foundation::NSObject;
use objc2::{declare_class, msg_send, ClassType}; use objc2::{declare_class, msg_send, mutability, ClassType};
use super::appkit::{NSApplication, NSEvent, NSEventModifierFlags, NSEventType, NSResponder}; use super::appkit::{NSApplication, NSEvent, NSEventModifierFlags, NSEventType, NSResponder};
use super::{app_state::AppState, event::EventWrapper, DEVICE_ID}; use super::{app_state::AppState, event::EventWrapper, DEVICE_ID};
@ -9,18 +9,20 @@ use crate::event::{DeviceEvent, ElementState, Event};
declare_class!( declare_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
pub(super) struct WinitApplication {} pub(super) struct WinitApplication;
unsafe impl ClassType for WinitApplication { unsafe impl ClassType for WinitApplication {
#[inherits(NSResponder, NSObject)] #[inherits(NSResponder, NSObject)]
type Super = NSApplication; type Super = NSApplication;
type Mutability = mutability::InteriorMutable;
const NAME: &'static str = "WinitApplication";
} }
unsafe impl WinitApplication { unsafe impl WinitApplication {
// Normally, holding Cmd + any key never sends us a `keyUp` event for that key. // 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) // 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) // 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) { fn send_event(&self, event: &NSEvent) {
// For posterity, there are some undocumented event types // For posterity, there are some undocumented event types
// (https://github.com/servo/cocoa-rs/issues/155) // (https://github.com/servo/cocoa-rs/issues/155)

View file

@ -1,9 +1,10 @@
use std::ptr::NonNull; use std::ptr::NonNull;
use objc2::foundation::NSObject; use icrate::Foundation::NSObject;
use objc2::rc::{Id, Shared}; use objc2::declare::{IvarBool, IvarEncode};
use objc2::rc::Id;
use objc2::runtime::Object; 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::app_state::AppState;
use super::appkit::NSApplicationActivationPolicy; use super::appkit::NSApplicationActivationPolicy;
@ -11,25 +12,28 @@ use super::appkit::NSApplicationActivationPolicy;
declare_class!( declare_class!(
#[derive(Debug)] #[derive(Debug)]
pub(super) struct ApplicationDelegate { pub(super) struct ApplicationDelegate {
activation_policy: NSApplicationActivationPolicy, activation_policy: IvarEncode<NSApplicationActivationPolicy, "_activation_policy">,
default_menu: bool, default_menu: IvarBool<"_default_menu">,
activate_ignoring_other_apps: bool, activate_ignoring_other_apps: IvarBool<"_activate_ignoring_other_apps">,
} }
mod ivars;
unsafe impl ClassType for ApplicationDelegate { unsafe impl ClassType for ApplicationDelegate {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
const NAME: &'static str = "WinitApplicationDelegate"; const NAME: &'static str = "WinitApplicationDelegate";
} }
unsafe impl ApplicationDelegate { unsafe impl ApplicationDelegate {
#[sel(initWithActivationPolicy:defaultMenu:activateIgnoringOtherApps:)] #[method(initWithActivationPolicy:defaultMenu:activateIgnoringOtherApps:)]
unsafe fn init( unsafe fn init(
&mut self, this: *mut Self,
activation_policy: NSApplicationActivationPolicy, activation_policy: NSApplicationActivationPolicy,
default_menu: bool, default_menu: bool,
activate_ignoring_other_apps: bool, activate_ignoring_other_apps: bool,
) -> Option<NonNull<Self>> { ) -> Option<NonNull<Self>> {
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.map(|this| {
*this.activation_policy = activation_policy; *this.activation_policy = activation_policy;
*this.default_menu = default_menu; *this.default_menu = default_menu;
@ -38,8 +42,8 @@ declare_class!(
}) })
} }
#[sel(applicationDidFinishLaunching:)] #[method(applicationDidFinishLaunching:)]
fn did_finish_launching(&self, _sender: *const Object) { fn did_finish_launching(&self, _sender: Option<&Object>) {
trace_scope!("applicationDidFinishLaunching:"); trace_scope!("applicationDidFinishLaunching:");
AppState::launched( AppState::launched(
*self.activation_policy, *self.activation_policy,
@ -48,8 +52,8 @@ declare_class!(
); );
} }
#[sel(applicationWillTerminate:)] #[method(applicationWillTerminate:)]
fn will_terminate(&self, _sender: *const Object) { fn will_terminate(&self, _sender: Option<&Object>) {
trace_scope!("applicationWillTerminate:"); trace_scope!("applicationWillTerminate:");
// TODO: Notify every window that it will be destroyed, like done in iOS? // TODO: Notify every window that it will be destroyed, like done in iOS?
AppState::exit(); AppState::exit();
@ -62,10 +66,10 @@ impl ApplicationDelegate {
activation_policy: NSApplicationActivationPolicy, activation_policy: NSApplicationActivationPolicy,
default_menu: bool, default_menu: bool,
activate_ignoring_other_apps: bool, activate_ignoring_other_apps: bool,
) -> Id<Self, Shared> { ) -> Id<Self> {
unsafe { unsafe {
msg_send_id![ msg_send_id![
msg_send_id![Self::class(), alloc], Self::alloc(),
initWithActivationPolicy: activation_policy, initWithActivationPolicy: activation_policy,
defaultMenu: default_menu, defaultMenu: default_menu,
activateIgnoringOtherApps: activate_ignoring_other_apps, activateIgnoringOtherApps: activate_ignoring_other_apps,

View file

@ -12,7 +12,7 @@ use std::{
}; };
use core_foundation::runloop::{CFRunLoopGetMain, CFRunLoopWakeUp}; 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 objc2::rc::autoreleasepool;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;

View file

@ -1,6 +1,6 @@
use objc2::foundation::{NSArray, NSObject, NSString}; use icrate::Foundation::{NSArray, NSObject, NSString};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, mutability, ClassType};
extern_class!( extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -8,6 +8,7 @@ extern_class!(
unsafe impl ClassType for NSAppearance { unsafe impl ClassType for NSAppearance {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
@ -15,15 +16,13 @@ type NSAppearanceName = NSString;
extern_methods!( extern_methods!(
unsafe impl NSAppearance { unsafe impl NSAppearance {
pub fn appearanceNamed(name: &NSAppearanceName) -> Id<Self, Shared> { #[method_id(appearanceNamed:)]
unsafe { msg_send_id![Self::class(), appearanceNamed: name] } pub fn appearanceNamed(name: &NSAppearanceName) -> Id<Self>;
}
#[method_id(bestMatchFromAppearancesWithNames:)]
pub fn bestMatchFromAppearancesWithNames( pub fn bestMatchFromAppearancesWithNames(
&self, &self,
appearances: &NSArray<NSAppearanceName>, appearances: &NSArray<NSAppearanceName>,
) -> Id<NSAppearanceName, Shared> { ) -> Id<NSAppearanceName>;
unsafe { msg_send_id![self, bestMatchFromAppearancesWithNames: appearances,] }
}
} }
); );

View file

@ -1,7 +1,7 @@
use objc2::foundation::{MainThreadMarker, NSArray, NSInteger, NSObject, NSUInteger}; use icrate::Foundation::{MainThreadMarker, NSArray, NSInteger, NSObject, NSUInteger};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::runtime::Object; 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 objc2::{Encode, Encoding};
use super::{NSAppearance, NSEvent, NSMenu, NSResponder, NSWindow}; use super::{NSAppearance, NSEvent, NSMenu, NSResponder, NSWindow};
@ -13,10 +13,11 @@ extern_class!(
unsafe impl ClassType for NSApplication { unsafe impl ClassType for NSApplication {
#[inherits(NSObject)] #[inherits(NSObject)]
type Super = NSResponder; type Super = NSResponder;
type Mutability = mutability::InteriorMutable;
} }
); );
pub(crate) fn NSApp() -> Id<NSApplication, Shared> { pub(crate) fn NSApp() -> Id<NSApplication> {
// TODO: Only allow access from main thread // TODO: Only allow access from main thread
NSApplication::shared(unsafe { MainThreadMarker::new_unchecked() }) 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 /// 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 /// 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). /// thread at any time (hence it is only safe to access on the main thread).
pub fn shared(_mtm: MainThreadMarker) -> Id<Self, Shared> { pub fn shared(_mtm: MainThreadMarker) -> Id<Self> {
let app: Option<_> = unsafe { msg_send_id![Self::class(), sharedApplication] }; let app: Option<_> = unsafe { msg_send_id![Self::class(), sharedApplication] };
// SAFETY: `sharedApplication` always initializes the app if it isn't already // SAFETY: `sharedApplication` always initializes the app if it isn't already
unsafe { app.unwrap_unchecked() } unsafe { app.unwrap_unchecked() }
} }
pub fn currentEvent(&self) -> Option<Id<NSEvent, Shared>> { #[method_id(currentEvent)]
unsafe { msg_send_id![self, currentEvent] } pub fn currentEvent(&self) -> Option<Id<NSEvent>>;
}
#[sel(postEvent:atStart:)] #[method(postEvent:atStart:)]
pub fn postEvent_atStart(&self, event: &NSEvent, front_of_queue: bool); pub fn postEvent_atStart(&self, event: &NSEvent, front_of_queue: bool);
#[sel(presentationOptions)] #[method(presentationOptions)]
pub fn presentationOptions(&self) -> NSApplicationPresentationOptions; pub fn presentationOptions(&self) -> NSApplicationPresentationOptions;
pub fn windows(&self) -> Id<NSArray<NSWindow, Shared>, Shared> { #[method_id(windows)]
unsafe { msg_send_id![self, windows] } pub fn windows(&self) -> Id<NSArray<NSWindow>>;
}
pub fn keyWindow(&self) -> Option<Id<NSWindow, Shared>> { #[method_id(keyWindow)]
unsafe { msg_send_id![self, keyWindow] } pub fn keyWindow(&self) -> Option<Id<NSWindow>>;
}
// TODO: NSApplicationDelegate // TODO: NSApplicationDelegate
#[sel(setDelegate:)] #[method(setDelegate:)]
pub fn setDelegate(&self, delegate: &Object); pub fn setDelegate(&self, delegate: &Object);
#[sel(setPresentationOptions:)] #[method(setPresentationOptions:)]
pub fn setPresentationOptions(&self, options: NSApplicationPresentationOptions); pub fn setPresentationOptions(&self, options: NSApplicationPresentationOptions);
#[sel(hide:)] #[method(hide:)]
pub fn hide(&self, sender: Option<&Object>); pub fn hide(&self, sender: Option<&Object>);
#[sel(orderFrontCharacterPalette:)] #[method(orderFrontCharacterPalette:)]
#[allow(dead_code)] #[allow(dead_code)]
pub fn orderFrontCharacterPalette(&self, sender: Option<&Object>); pub fn orderFrontCharacterPalette(&self, sender: Option<&Object>);
#[sel(hideOtherApplications:)] #[method(hideOtherApplications:)]
pub fn hideOtherApplications(&self, sender: Option<&Object>); pub fn hideOtherApplications(&self, sender: Option<&Object>);
#[sel(stop:)] #[method(stop:)]
pub fn stop(&self, sender: Option<&Object>); pub fn stop(&self, sender: Option<&Object>);
#[sel(activateIgnoringOtherApps:)] #[method(activateIgnoringOtherApps:)]
pub fn activateIgnoringOtherApps(&self, ignore: bool); pub fn activateIgnoringOtherApps(&self, ignore: bool);
#[sel(requestUserAttention:)] #[method(requestUserAttention:)]
pub fn requestUserAttention(&self, type_: NSRequestUserAttentionType) -> NSInteger; pub fn requestUserAttention(&self, type_: NSRequestUserAttentionType) -> NSInteger;
#[sel(setActivationPolicy:)] #[method(setActivationPolicy:)]
pub fn setActivationPolicy(&self, policy: NSApplicationActivationPolicy) -> bool; pub fn setActivationPolicy(&self, policy: NSApplicationActivationPolicy) -> bool;
#[sel(setMainMenu:)] #[method(setMainMenu:)]
pub fn setMainMenu(&self, menu: &NSMenu); pub fn setMainMenu(&self, menu: &NSMenu);
pub fn effectiveAppearance(&self) -> Id<NSAppearance, Shared> { #[method_id(effectiveAppearance)]
unsafe { msg_send_id![self, effectiveAppearance] } pub fn effectiveAppearance(&self) -> Id<NSAppearance>;
}
#[sel(setAppearance:)] #[method(setAppearance:)]
pub fn setAppearance(&self, appearance: Option<&NSAppearance>); pub fn setAppearance(&self, appearance: Option<&NSAppearance>);
#[sel(run)] #[method(run)]
pub unsafe fn run(&self); pub unsafe fn run(&self);
} }
); );

View file

@ -1,5 +1,5 @@
use objc2::foundation::NSObject; use icrate::Foundation::NSObject;
use objc2::{extern_class, ClassType}; use objc2::{extern_class, mutability, ClassType};
use super::{NSControl, NSResponder, NSView}; use super::{NSControl, NSResponder, NSView};
@ -10,5 +10,6 @@ extern_class!(
unsafe impl ClassType for NSButton { unsafe impl ClassType for NSButton {
#[inherits(NSView, NSResponder, NSObject)] #[inherits(NSView, NSResponder, NSObject)]
type Super = NSControl; type Super = NSControl;
type Mutability = mutability::InteriorMutable;
} }
); );

View file

@ -1,6 +1,6 @@
use objc2::foundation::NSObject; use icrate::Foundation::NSObject;
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, mutability, ClassType};
extern_class!( extern_class!(
/// An object that stores color data and sometimes opacity (alpha value). /// An object that stores color data and sometimes opacity (alpha value).
@ -11,6 +11,7 @@ extern_class!(
unsafe impl ClassType for NSColor { unsafe impl ClassType for NSColor {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
@ -21,8 +22,7 @@ unsafe impl Sync for NSColor {}
extern_methods!( extern_methods!(
unsafe impl NSColor { unsafe impl NSColor {
pub fn clear() -> Id<Self, Shared> { #[method_id(clearColor)]
unsafe { msg_send_id![Self::class(), clearColor] } pub fn clear() -> Id<Self>;
}
} }
); );

View file

@ -1,5 +1,5 @@
use objc2::foundation::NSObject; use icrate::Foundation::NSObject;
use objc2::{extern_class, extern_methods, ClassType}; use objc2::{extern_class, extern_methods, mutability, ClassType};
use super::{NSResponder, NSView}; use super::{NSResponder, NSView};
@ -10,15 +10,16 @@ extern_class!(
unsafe impl ClassType for NSControl { unsafe impl ClassType for NSControl {
#[inherits(NSResponder, NSObject)] #[inherits(NSResponder, NSObject)]
type Super = NSView; type Super = NSView;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl NSControl { unsafe impl NSControl {
#[sel(setEnabled:)] #[method(setEnabled:)]
pub fn setEnabled(&self, enabled: bool); pub fn setEnabled(&self, enabled: bool);
#[sel(isEnabled)] #[method(isEnabled)]
pub fn isEnabled(&self) -> bool; pub fn isEnabled(&self) -> bool;
} }
); );

View file

@ -1,9 +1,12 @@
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use objc2::foundation::{NSData, NSDictionary, NSNumber, NSObject, NSPoint, NSString}; use icrate::ns_string;
use objc2::rc::{DefaultId, Id, Shared}; use icrate::Foundation::{
NSData, NSDictionary, NSNumber, NSObject, NSObjectProtocol, NSPoint, NSString,
};
use objc2::rc::{DefaultId, Id};
use objc2::runtime::Sel; 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 super::NSImage;
use crate::window::CursorIcon; use crate::window::CursorIcon;
@ -15,6 +18,7 @@ extern_class!(
unsafe impl ClassType for NSCursor { unsafe impl ClassType for NSCursor {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
@ -29,7 +33,7 @@ macro_rules! def_cursor {
pub fn $name:ident(); pub fn $name:ident();
)*} => {$( )*} => {$(
$(#[$($m)*])* $(#[$($m)*])*
pub fn $name() -> Id<Self, Shared> { pub fn $name() -> Id<Self> {
unsafe { msg_send_id![Self::class(), $name] } unsafe { msg_send_id![Self::class(), $name] }
} }
)*}; )*};
@ -41,7 +45,7 @@ macro_rules! def_undocumented_cursor {
pub fn $name:ident(); pub fn $name:ident();
)*} => {$( )*} => {$(
$(#[$($m)*])* $(#[$($m)*])*
pub fn $name() -> Id<Self, Shared> { pub fn $name() -> Id<Self> {
unsafe { Self::from_selector(sel!($name)).unwrap_or_else(|| Default::default()) } 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. // Creating cursors should be thread-safe, though using them for anything probably isn't.
pub fn new(image: &NSImage, hotSpot: NSPoint) -> Id<Self, Shared> { pub fn new(image: &NSImage, hotSpot: NSPoint) -> Id<Self> {
let this = unsafe { msg_send_id![Self::class(), alloc] }; unsafe { msg_send_id![Self::alloc(), initWithImage: image, hotSpot: hotSpot] }
unsafe { msg_send_id![this, initWithImage: image, hotSpot: hotSpot] }
} }
pub fn invisible() -> Id<Self, Shared> { pub fn invisible() -> Id<Self> {
// 16x16 GIF data for invisible cursor // 16x16 GIF data for invisible cursor
// You can reproduce this via ImageMagick. // You can reproduce this via ImageMagick.
// $ convert -size 16x16 xc:none cursor.gif // $ 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, 0xCB, 0xED, 0x0F, 0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B,
]; ];
static CURSOR: Lazy<Id<NSCursor, Shared>> = Lazy::new(|| { static CURSOR: Lazy<Id<NSCursor>> = Lazy::new(|| {
// TODO: Consider using `dataWithBytesNoCopy:` // TODO: Consider using `dataWithBytesNoCopy:`
let data = NSData::with_bytes(CURSOR_BYTES); let data = NSData::with_bytes(CURSOR_BYTES);
let image = NSImage::new_with_data(&data); let image = NSImage::new_with_data(&data);
@ -100,14 +103,13 @@ extern_methods!(
/// Undocumented cursors /// Undocumented cursors
unsafe impl NSCursor { unsafe impl NSCursor {
#[sel(respondsToSelector:)] #[method(respondsToSelector:)]
fn class_responds_to(sel: Sel) -> bool; fn class_responds_to(sel: Sel) -> bool;
unsafe fn from_selector_unchecked(sel: Sel) -> Id<Self, Shared> { #[method_id(performSelector:)]
unsafe { msg_send_id![Self::class(), performSelector: sel] } unsafe fn from_selector_unchecked(sel: Sel) -> Id<Self>;
}
unsafe fn from_selector(sel: Sel) -> Option<Id<Self, Shared>> { unsafe fn from_selector(sel: Sel) -> Option<Id<Self>> {
if Self::class_responds_to(sel) { if Self::class_responds_to(sel) {
Some(unsafe { Self::from_selector_unchecked(sel) }) Some(unsafe { Self::from_selector_unchecked(sel) })
} else { } else {
@ -143,20 +145,20 @@ extern_methods!(
unsafe impl NSCursor { unsafe impl NSCursor {
// Note that loading `busybutclickable` with this code won't animate // Note that loading `busybutclickable` with this code won't animate
// the frames; instead you'll just get them all in a column. // the frames; instead you'll just get them all in a column.
unsafe fn load_webkit_cursor(name: &NSString) -> Id<Self, Shared> { unsafe fn load_webkit_cursor(name: &NSString) -> Id<Self> {
// Snatch a cursor from WebKit; They fit the style of the native // Snatch a cursor from WebKit; They fit the style of the native
// cursors, and will seem completely standard to macOS users. // cursors, and will seem completely standard to macOS users.
// //
// https://stackoverflow.com/a/21786835/5435443 // 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 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); let image = NSImage::new_by_referencing_file(&pdf_path);
// TODO: Handle PLists better // TODO: Handle PLists better
let info_path = cursor_path.join_path(ns_string!("info.plist")); let info_path = cursor_path.stringByAppendingPathComponent(ns_string!("info.plist"));
let info: Id<NSDictionary<NSObject, NSObject>, Shared> = unsafe { let info: Id<NSDictionary<NSObject, NSObject>> = unsafe {
msg_send_id![ msg_send_id![
<NSDictionary<NSObject, NSObject>>::class(), <NSDictionary<NSObject, NSObject>>::class(),
dictionaryWithContentsOfFile: &*info_path, dictionaryWithContentsOfFile: &*info_path,
@ -183,18 +185,18 @@ extern_methods!(
Self::new(&image, hotspot) Self::new(&image, hotspot)
} }
pub fn moveCursor() -> Id<Self, Shared> { pub fn moveCursor() -> Id<Self> {
unsafe { Self::load_webkit_cursor(ns_string!("move")) } unsafe { Self::load_webkit_cursor(ns_string!("move")) }
} }
pub fn cellCursor() -> Id<Self, Shared> { pub fn cellCursor() -> Id<Self> {
unsafe { Self::load_webkit_cursor(ns_string!("cell")) } unsafe { Self::load_webkit_cursor(ns_string!("cell")) }
} }
} }
); );
impl NSCursor { impl NSCursor {
pub fn from_icon(icon: CursorIcon) -> Id<Self, Shared> { pub fn from_icon(icon: CursorIcon) -> Id<Self> {
match icon { match icon {
CursorIcon::Default => Default::default(), CursorIcon::Default => Default::default(),
CursorIcon::Pointer => Self::pointingHandCursor(), CursorIcon::Pointer => Self::pointingHandCursor(),
@ -233,9 +235,7 @@ impl NSCursor {
} }
impl DefaultId for NSCursor { impl DefaultId for NSCursor {
type Ownership = Shared; fn default_id() -> Id<Self> {
fn default_id() -> Id<Self, Shared> {
Self::arrowCursor() Self::arrowCursor()
} }
} }

View file

@ -1,11 +1,11 @@
use std::os::raw::c_ushort; use std::os::raw::c_ushort;
use objc2::encode::{Encode, Encoding}; use icrate::Foundation::{
use objc2::foundation::{
CGFloat, NSCopying, NSInteger, NSObject, NSPoint, NSString, NSTimeInterval, NSUInteger, CGFloat, NSCopying, NSInteger, NSObject, NSPoint, NSString, NSTimeInterval, NSUInteger,
}; };
use objc2::rc::{Id, Shared}; use objc2::encode::{Encode, Encoding};
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, mutability, ClassType};
extern_class!( extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -13,6 +13,7 @@ extern_class!(
unsafe impl ClassType for NSEvent { unsafe impl ClassType for NSEvent {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
@ -24,6 +25,17 @@ extern_class!(
extern_methods!( extern_methods!(
unsafe impl NSEvent { unsafe impl NSEvent {
#[method_id(
otherEventWithType:
location:
modifierFlags:
timestamp:
windowNumber:
context:
subtype:
data1:
data2:
)]
unsafe fn otherEventWithType( unsafe fn otherEventWithType(
type_: NSEventType, type_: NSEventType,
location: NSPoint, location: NSPoint,
@ -34,24 +46,9 @@ extern_methods!(
subtype: NSEventSubtype, subtype: NSEventSubtype,
data1: NSInteger, data1: NSInteger,
data2: NSInteger, data2: NSInteger,
) -> Id<Self, Shared> { ) -> Id<Self>;
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,
]
}
}
pub fn dummy() -> Id<Self, Shared> { pub fn dummy() -> Id<Self> {
unsafe { unsafe {
Self::otherEventWithType( Self::otherEventWithType(
NSEventType::NSApplicationDefined, NSEventType::NSApplicationDefined,
@ -67,6 +64,18 @@ extern_methods!(
} }
} }
#[method_id(
keyEventWithType:
location:
modifierFlags:
timestamp:
windowNumber:
context:
characters:
charactersIgnoringModifiers:
isARepeat:
keyCode:
)]
pub fn keyEventWithType( pub fn keyEventWithType(
type_: NSEventType, type_: NSEventType,
location: NSPoint, location: NSPoint,
@ -78,92 +87,74 @@ extern_methods!(
characters_ignoring_modifiers: &NSString, characters_ignoring_modifiers: &NSString,
is_a_repeat: bool, is_a_repeat: bool,
scancode: c_ushort, scancode: c_ushort,
) -> Id<Self, Shared> { ) -> Id<Self>;
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,
]
}
}
#[sel(locationInWindow)] #[method(locationInWindow)]
pub fn locationInWindow(&self) -> NSPoint; pub fn locationInWindow(&self) -> NSPoint;
// TODO: MainThreadMarker // TODO: MainThreadMarker
#[sel(pressedMouseButtons)] #[method(pressedMouseButtons)]
pub fn pressedMouseButtons() -> NSUInteger; pub fn pressedMouseButtons() -> NSUInteger;
#[sel(modifierFlags)] #[method(modifierFlags)]
pub fn modifierFlags(&self) -> NSEventModifierFlags; pub fn modifierFlags(&self) -> NSEventModifierFlags;
#[sel(type)] #[method(type)]
pub fn type_(&self) -> NSEventType; pub fn type_(&self) -> NSEventType;
#[sel(keyCode)] #[method(keyCode)]
pub fn key_code(&self) -> c_ushort; pub fn key_code(&self) -> c_ushort;
#[sel(magnification)] #[method(magnification)]
pub fn magnification(&self) -> CGFloat; pub fn magnification(&self) -> CGFloat;
#[sel(phase)] #[method(phase)]
pub fn phase(&self) -> NSEventPhase; pub fn phase(&self) -> NSEventPhase;
#[sel(momentumPhase)] #[method(momentumPhase)]
pub fn momentumPhase(&self) -> NSEventPhase; pub fn momentumPhase(&self) -> NSEventPhase;
#[sel(deltaX)] #[method(deltaX)]
pub fn deltaX(&self) -> CGFloat; pub fn deltaX(&self) -> CGFloat;
#[sel(deltaY)] #[method(deltaY)]
pub fn deltaY(&self) -> CGFloat; pub fn deltaY(&self) -> CGFloat;
#[sel(buttonNumber)] #[method(buttonNumber)]
pub fn buttonNumber(&self) -> NSInteger; pub fn buttonNumber(&self) -> NSInteger;
#[sel(scrollingDeltaX)] #[method(scrollingDeltaX)]
pub fn scrollingDeltaX(&self) -> CGFloat; pub fn scrollingDeltaX(&self) -> CGFloat;
#[sel(scrollingDeltaY)] #[method(scrollingDeltaY)]
pub fn scrollingDeltaY(&self) -> CGFloat; pub fn scrollingDeltaY(&self) -> CGFloat;
#[sel(hasPreciseScrollingDeltas)] #[method(hasPreciseScrollingDeltas)]
pub fn hasPreciseScrollingDeltas(&self) -> bool; pub fn hasPreciseScrollingDeltas(&self) -> bool;
#[sel(rotation)] #[method(rotation)]
pub fn rotation(&self) -> f32; pub fn rotation(&self) -> f32;
#[sel(pressure)] #[method(pressure)]
pub fn pressure(&self) -> f32; pub fn pressure(&self) -> f32;
#[sel(stage)] #[method(stage)]
pub fn stage(&self) -> NSInteger; pub fn stage(&self) -> NSInteger;
#[sel(isARepeat)] #[method(isARepeat)]
pub fn is_a_repeat(&self) -> bool; pub fn is_a_repeat(&self) -> bool;
#[sel(windowNumber)] #[method(windowNumber)]
pub fn window_number(&self) -> NSInteger; pub fn window_number(&self) -> NSInteger;
#[sel(timestamp)] #[method(timestamp)]
pub fn timestamp(&self) -> NSTimeInterval; pub fn timestamp(&self) -> NSTimeInterval;
pub fn characters(&self) -> Option<Id<NSString, Shared>> { #[method_id(characters)]
unsafe { msg_send_id![self, characters] } pub fn characters(&self) -> Option<Id<NSString>>;
}
pub fn charactersIgnoringModifiers(&self) -> Option<Id<NSString, Shared>> { #[method_id(charactersIgnoringModifiers)]
unsafe { msg_send_id![self, charactersIgnoringModifiers] } pub fn charactersIgnoringModifiers(&self) -> Option<Id<NSString>>;
}
pub fn lshift_pressed(&self) -> bool { pub fn lshift_pressed(&self) -> bool {
let raw_modifiers = self.modifierFlags().bits() as u32; let raw_modifiers = self.modifierFlags().bits() as u32;
@ -207,10 +198,7 @@ extern_methods!(
} }
); );
unsafe impl NSCopying for NSEvent { unsafe impl NSCopying for NSEvent {}
type Ownership = Shared;
type Output = NSEvent;
}
// The values are from the https://github.com/apple-oss-distributions/IOHIDFamily/blob/19666c840a6d896468416ff0007040a10b7b46b8/IOHIDSystem/IOKit/hidsystem/IOLLEvent.h#L258-L259 // 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; const NX_DEVICELCTLKEYMASK: u32 = 0x00000001;

View file

@ -1,6 +1,6 @@
use objc2::foundation::{NSData, NSObject, NSString}; use icrate::Foundation::{NSData, NSObject, NSString};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
extern_class!( extern_class!(
// TODO: Can this be mutable? // TODO: Can this be mutable?
@ -9,6 +9,7 @@ extern_class!(
unsafe impl ClassType for NSImage { unsafe impl ClassType for NSImage {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
@ -24,14 +25,12 @@ unsafe impl Sync for NSImage {}
extern_methods!( extern_methods!(
unsafe impl NSImage { unsafe impl NSImage {
pub fn new_by_referencing_file(path: &NSString) -> Id<Self, Shared> { pub fn new_by_referencing_file(path: &NSString) -> Id<Self> {
let this = unsafe { msg_send_id![Self::class(), alloc] }; unsafe { msg_send_id![Self::alloc(), initByReferencingFile: path] }
unsafe { msg_send_id![this, initByReferencingFile: path] }
} }
pub fn new_with_data(data: &NSData) -> Id<Self, Shared> { pub fn new_with_data(data: &NSData) -> Id<Self> {
let this = unsafe { msg_send_id![Self::class(), alloc] }; unsafe { msg_send_id![Self::alloc(), initWithData: data] }
unsafe { msg_send_id![this, initWithData: data] }
} }
} }
); );

View file

@ -1,6 +1,6 @@
use objc2::foundation::NSObject; use icrate::Foundation::NSObject;
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, mutability, ClassType};
use super::NSMenuItem; use super::NSMenuItem;
@ -10,16 +10,16 @@ extern_class!(
unsafe impl ClassType for NSMenu { unsafe impl ClassType for NSMenu {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl NSMenu { unsafe impl NSMenu {
pub fn new() -> Id<Self, Shared> { #[method_id(new)]
unsafe { msg_send_id![Self::class(), new] } pub fn new() -> Id<Self>;
}
#[sel(addItem:)] #[method(addItem:)]
pub fn addItem(&self, item: &NSMenuItem); pub fn addItem(&self, item: &NSMenuItem);
} }
); );

View file

@ -1,7 +1,7 @@
use objc2::foundation::{NSObject, NSString}; use icrate::Foundation::{NSObject, NSString};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::runtime::Sel; 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}; use super::{NSEventModifierFlags, NSMenu};
@ -11,23 +11,19 @@ extern_class!(
unsafe impl ClassType for NSMenuItem { unsafe impl ClassType for NSMenuItem {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl NSMenuItem { unsafe impl NSMenuItem {
pub fn new() -> Id<Self, Shared> { #[method_id(new)]
unsafe { msg_send_id![Self::class(), new] } pub fn new() -> Id<Self>;
}
pub fn newWithTitle( pub fn newWithTitle(title: &NSString, action: Sel, key_equivalent: &NSString) -> Id<Self> {
title: &NSString,
action: Sel,
key_equivalent: &NSString,
) -> Id<Self, Shared> {
unsafe { unsafe {
msg_send_id![ msg_send_id![
msg_send_id![Self::class(), alloc], Self::alloc(),
initWithTitle: title, initWithTitle: title,
action: action, action: action,
keyEquivalent: key_equivalent, keyEquivalent: key_equivalent,
@ -35,14 +31,13 @@ extern_methods!(
} }
} }
pub fn separatorItem() -> Id<Self, Shared> { #[method_id(separatorItem)]
unsafe { msg_send_id![Self::class(), separatorItem] } pub fn separatorItem() -> Id<Self>;
}
#[sel(setKeyEquivalentModifierMask:)] #[method(setKeyEquivalentModifierMask:)]
pub fn setKeyEquivalentModifierMask(&self, mask: NSEventModifierFlags); pub fn setKeyEquivalentModifierMask(&self, mask: NSEventModifierFlags);
#[sel(setSubmenu:)] #[method(setSubmenu:)]
pub fn setSubmenu(&self, submenu: &NSMenu); pub fn setSubmenu(&self, submenu: &NSMenu);
} }
); );

View file

@ -25,6 +25,7 @@ mod pasteboard;
mod responder; mod responder;
mod screen; mod screen;
mod tab_group; mod tab_group;
mod text_input_client;
mod text_input_context; mod text_input_context;
mod version; mod version;
mod view; mod view;
@ -51,6 +52,7 @@ pub(crate) use self::responder::NSResponder;
#[allow(unused_imports)] #[allow(unused_imports)]
pub(crate) use self::screen::{NSDeviceDescriptionKey, NSScreen}; pub(crate) use self::screen::{NSDeviceDescriptionKey, NSScreen};
pub(crate) use self::tab_group::NSWindowTabGroup; 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::text_input_context::NSTextInputContext;
pub(crate) use self::version::NSAppKitVersion; pub(crate) use self::version::NSAppKitVersion;
pub(crate) use self::view::{NSTrackingRectTag, NSView}; pub(crate) use self::view::{NSTrackingRectTag, NSView};

View file

@ -1,6 +1,6 @@
use objc2::foundation::{NSObject, NSString}; use icrate::Foundation::{NSObject, NSString};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, mutability, ClassType};
extern_class!( extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -8,14 +8,14 @@ extern_class!(
unsafe impl ClassType for NSPasteboard { unsafe impl ClassType for NSPasteboard {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl NSPasteboard { unsafe impl NSPasteboard {
pub fn propertyListForType(&self, type_: &NSPasteboardType) -> Id<NSObject, Shared> { #[method_id(propertyListForType:)]
unsafe { msg_send_id![self, propertyListForType: type_] } pub fn propertyListForType(&self, type_: &NSPasteboardType) -> Id<NSObject>;
}
} }
); );

View file

@ -1,15 +1,15 @@
use objc2::foundation::{NSArray, NSObject}; use icrate::Foundation::{NSArray, NSObject};
use objc2::rc::Shared; use objc2::{extern_class, extern_methods, mutability, ClassType};
use objc2::{extern_class, extern_methods, ClassType};
use super::NSEvent; use super::NSEvent;
extern_class!( extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
pub(crate) struct NSResponder; pub struct NSResponder;
unsafe impl ClassType for NSResponder { unsafe impl ClassType for NSResponder {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
@ -17,7 +17,7 @@ extern_class!(
extern_methods!( extern_methods!(
unsafe impl NSResponder { unsafe impl NSResponder {
#[sel(interpretKeyEvents:)] #[method(interpretKeyEvents:)]
pub unsafe fn interpretKeyEvents(&self, events: &NSArray<NSEvent, Shared>); pub(crate) unsafe fn interpretKeyEvents(&self, events: &NSArray<NSEvent>);
} }
); );

View file

@ -1,7 +1,8 @@
use objc2::foundation::{CGFloat, NSArray, NSDictionary, NSNumber, NSObject, NSRect, NSString}; use icrate::ns_string;
use objc2::rc::{Id, Shared}; use icrate::Foundation::{CGFloat, NSArray, NSDictionary, NSNumber, NSObject, NSRect, NSString};
use objc2::rc::Id;
use objc2::runtime::Object; 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!( extern_class!(
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
@ -9,6 +10,7 @@ extern_class!(
unsafe impl ClassType for NSScreen { unsafe impl ClassType for NSScreen {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
@ -17,26 +19,21 @@ extern_class!(
extern_methods!( extern_methods!(
unsafe impl NSScreen { unsafe impl NSScreen {
/// The application object must have been created. /// The application object must have been created.
pub fn main() -> Option<Id<Self, Shared>> { #[method_id(mainScreen)]
unsafe { msg_send_id![Self::class(), mainScreen] } pub fn main() -> Option<Id<Self>>;
}
/// The application object must have been created. /// The application object must have been created.
pub fn screens() -> Id<NSArray<Self, Shared>, Shared> { #[method_id(screens)]
unsafe { msg_send_id![Self::class(), screens] } pub fn screens() -> Id<NSArray<Self>>;
}
#[sel(frame)] #[method(frame)]
pub fn frame(&self) -> NSRect; pub fn frame(&self) -> NSRect;
#[sel(visibleFrame)] #[method(visibleFrame)]
pub fn visibleFrame(&self) -> NSRect; pub fn visibleFrame(&self) -> NSRect;
pub fn deviceDescription( #[method_id(deviceDescription)]
&self, pub fn deviceDescription(&self) -> Id<NSDictionary<NSDeviceDescriptionKey, Object>>;
) -> Id<NSDictionary<NSDeviceDescriptionKey, Object>, Shared> {
unsafe { msg_send_id![self, deviceDescription] }
}
pub fn display_id(&self) -> u32 { pub fn display_id(&self) -> u32 {
let key = ns_string!("NSScreenNumber"); let key = ns_string!("NSScreenNumber");
@ -60,7 +57,7 @@ extern_methods!(
}) })
} }
#[sel(backingScaleFactor)] #[method(backingScaleFactor)]
pub fn backingScaleFactor(&self) -> CGFloat; pub fn backingScaleFactor(&self) -> CGFloat;
} }
); );

View file

@ -1,6 +1,6 @@
use objc2::foundation::{NSArray, NSObject}; use icrate::Foundation::{NSArray, NSObject};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, mutability, ClassType};
use super::NSWindow; use super::NSWindow;
@ -10,19 +10,22 @@ extern_class!(
unsafe impl ClassType for NSWindowTabGroup { unsafe impl ClassType for NSWindowTabGroup {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl NSWindowTabGroup { unsafe impl NSWindowTabGroup {
#[sel(selectNextTab)] #[method(selectNextTab)]
pub fn selectNextTab(&self); pub fn selectNextTab(&self);
#[sel(selectPreviousTab)]
#[method(selectPreviousTab)]
pub fn selectPreviousTab(&self); pub fn selectPreviousTab(&self);
pub fn tabbedWindows(&self) -> Id<NSArray<NSWindow, Shared>, Shared> {
unsafe { msg_send_id![self, windows] } #[method_id(windows)]
} pub fn tabbedWindows(&self) -> Id<NSArray<NSWindow>>;
#[sel(setSelectedWindow:)]
#[method(setSelectedWindow:)]
pub fn setSelectedWindow(&self, window: &NSWindow); pub fn setSelectedWindow(&self, window: &NSWindow);
} }
); );

View file

@ -0,0 +1,9 @@
use objc2::{extern_protocol, ProtocolType};
extern_protocol!(
pub(crate) unsafe trait NSTextInputClient {
// TODO: Methods
}
unsafe impl ProtocolType for dyn NSTextInputClient {}
);

View file

@ -1,6 +1,6 @@
use objc2::foundation::{NSObject, NSString}; use icrate::Foundation::{NSObject, NSString};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, mutability, ClassType};
type NSTextInputSourceIdentifier = NSString; type NSTextInputSourceIdentifier = NSString;
@ -11,21 +11,19 @@ extern_class!(
unsafe impl ClassType for NSTextInputContext { unsafe impl ClassType for NSTextInputContext {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
} }
); );
extern_methods!( extern_methods!(
unsafe impl NSTextInputContext { unsafe impl NSTextInputContext {
#[sel(invalidateCharacterCoordinates)] #[method(invalidateCharacterCoordinates)]
pub fn invalidateCharacterCoordinates(&self); pub fn invalidateCharacterCoordinates(&self);
#[sel(discardMarkedText)] #[method(discardMarkedText)]
pub fn discardMarkedText(&self); pub fn discardMarkedText(&self);
pub fn selectedKeyboardInputSource( #[method_id(selectedKeyboardInputSource)]
&self, pub fn selectedKeyboardInputSource(&self) -> Option<Id<NSTextInputSourceIdentifier>>;
) -> Option<Id<NSTextInputSourceIdentifier, Shared>> {
unsafe { msg_send_id![self, selectedKeyboardInputSource] }
}
} }
); );

View file

@ -2,10 +2,10 @@ use std::ffi::c_void;
use std::num::NonZeroIsize; use std::num::NonZeroIsize;
use std::ptr; use std::ptr;
use objc2::foundation::{NSObject, NSPoint, NSRect}; use icrate::Foundation::{NSObject, NSPoint, NSRect};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use objc2::runtime::Object; 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}; use super::{NSCursor, NSResponder, NSTextInputContext, NSWindow};
@ -16,6 +16,7 @@ extern_class!(
unsafe impl ClassType for NSView { unsafe impl ClassType for NSView {
#[inherits(NSObject)] #[inherits(NSObject)]
type Super = NSResponder; type Super = NSResponder;
type Mutability = mutability::InteriorMutable;
} }
); );
@ -31,47 +32,45 @@ extern_class!(
extern_methods!( extern_methods!(
/// Getter methods /// Getter methods
unsafe impl NSView { unsafe impl NSView {
#[sel(frame)] #[method(frame)]
pub fn frame(&self) -> NSRect; pub fn frame(&self) -> NSRect;
#[sel(bounds)] #[method(bounds)]
pub fn bounds(&self) -> NSRect; pub fn bounds(&self) -> NSRect;
#[method_id(inputContext)]
pub fn inputContext( pub fn inputContext(
&self, &self,
// _mtm: MainThreadMarker, // _mtm: MainThreadMarker,
) -> Option<Id<NSTextInputContext, Shared>> { ) -> Option<Id<NSTextInputContext>>;
unsafe { msg_send_id![self, inputContext] }
}
#[sel(visibleRect)] #[method(visibleRect)]
pub fn visibleRect(&self) -> NSRect; pub fn visibleRect(&self) -> NSRect;
#[sel(hasMarkedText)] #[method(hasMarkedText)]
pub fn hasMarkedText(&self) -> bool; pub fn hasMarkedText(&self) -> bool;
#[sel(convertPoint:fromView:)] #[method(convertPoint:fromView:)]
pub fn convertPoint_fromView(&self, point: NSPoint, view: Option<&NSView>) -> NSPoint; pub fn convertPoint_fromView(&self, point: NSPoint, view: Option<&NSView>) -> NSPoint;
pub fn window(&self) -> Option<Id<NSWindow, Shared>> { #[method_id(window)]
unsafe { msg_send_id![self, window] } pub fn window(&self) -> Option<Id<NSWindow>>;
}
} }
unsafe impl NSView { unsafe impl NSView {
#[sel(setWantsBestResolutionOpenGLSurface:)] #[method(setWantsBestResolutionOpenGLSurface:)]
pub fn setWantsBestResolutionOpenGLSurface(&self, value: bool); pub fn setWantsBestResolutionOpenGLSurface(&self, value: bool);
#[sel(setWantsLayer:)] #[method(setWantsLayer:)]
pub fn setWantsLayer(&self, wants_layer: bool); pub fn setWantsLayer(&self, wants_layer: bool);
#[sel(setPostsFrameChangedNotifications:)] #[method(setPostsFrameChangedNotifications:)]
pub fn setPostsFrameChangedNotifications(&self, value: bool); pub fn setPostsFrameChangedNotifications(&self, value: bool);
#[sel(removeTrackingRect:)] #[method(removeTrackingRect:)]
pub fn removeTrackingRect(&self, tag: NSTrackingRectTag); pub fn removeTrackingRect(&self, tag: NSTrackingRectTag);
#[sel(addTrackingRect:owner:userData:assumeInside:)] #[method(addTrackingRect:owner:userData:assumeInside:)]
unsafe fn inner_addTrackingRect( unsafe fn inner_addTrackingRect(
&self, &self,
rect: NSRect, rect: NSRect,
@ -86,11 +85,11 @@ extern_methods!(
.expect("failed creating tracking rect") .expect("failed creating tracking rect")
} }
#[sel(addCursorRect:cursor:)] #[method(addCursorRect:cursor:)]
// NSCursor safe to take by shared reference since it is already immutable // NSCursor safe to take by shared reference since it is already immutable
pub fn addCursorRect(&self, rect: NSRect, cursor: &NSCursor); pub fn addCursorRect(&self, rect: NSRect, cursor: &NSCursor);
#[sel(setHidden:)] #[method(setHidden:)]
pub fn setHidden(&self, hidden: bool); pub fn setHidden(&self, hidden: bool);
} }
); );

View file

@ -1,10 +1,10 @@
use objc2::encode::{Encode, Encoding}; use icrate::Foundation::{
use objc2::foundation::{
CGFloat, NSArray, NSInteger, NSObject, NSPoint, NSRect, NSSize, NSString, NSUInteger, 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::runtime::Object;
use objc2::{extern_class, extern_methods, msg_send_id, ClassType}; use objc2::{extern_class, extern_methods, mutability, ClassType};
use super::{ use super::{
NSButton, NSColor, NSEvent, NSPasteboardType, NSResponder, NSScreen, NSView, NSWindowTabGroup, NSButton, NSColor, NSEvent, NSPasteboardType, NSResponder, NSScreen, NSView, NSWindowTabGroup,
@ -13,11 +13,12 @@ use super::{
extern_class!( extern_class!(
/// Main-Thread-Only! /// Main-Thread-Only!
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
pub(crate) struct NSWindow; pub struct NSWindow;
unsafe impl ClassType for NSWindow { unsafe impl ClassType for NSWindow {
#[inherits(NSObject)] #[inherits(NSObject)]
type Super = NSResponder; type Super = NSResponder;
type Mutability = mutability::InteriorMutable;
} }
); );
@ -32,221 +33,214 @@ extern_class!(
extern_methods!( extern_methods!(
unsafe impl NSWindow { unsafe impl NSWindow {
#[sel(frame)] #[method(frame)]
pub fn frame(&self) -> NSRect; pub(crate) fn frame(&self) -> NSRect;
#[sel(backingScaleFactor)] #[method(backingScaleFactor)]
pub fn backingScaleFactor(&self) -> CGFloat; pub(crate) fn backingScaleFactor(&self) -> CGFloat;
pub fn contentView(&self) -> Id<NSView, Shared> { #[method_id(contentView)]
unsafe { msg_send_id![self, contentView] } pub(crate) fn contentView(&self) -> Id<NSView>;
}
#[sel(setContentView:)] #[method(setContentView:)]
pub fn setContentView(&self, view: &NSView); pub(crate) fn setContentView(&self, view: &NSView);
#[sel(setInitialFirstResponder:)] #[method(setInitialFirstResponder:)]
pub fn setInitialFirstResponder(&self, view: &NSView); pub(crate) fn setInitialFirstResponder(&self, view: &NSView);
#[sel(makeFirstResponder:)] #[method(makeFirstResponder:)]
#[must_use] #[must_use]
pub fn makeFirstResponder(&self, responder: Option<&NSResponder>) -> bool; pub(crate) fn makeFirstResponder(&self, responder: Option<&NSResponder>) -> bool;
#[sel(contentRectForFrameRect:)] #[method(contentRectForFrameRect:)]
pub fn contentRectForFrameRect(&self, windowFrame: NSRect) -> NSRect; pub(crate) fn contentRectForFrameRect(&self, windowFrame: NSRect) -> NSRect;
pub fn screen(&self) -> Option<Id<NSScreen, Shared>> { #[method_id(screen)]
unsafe { msg_send_id![self, screen] } pub(crate) fn screen(&self) -> Option<Id<NSScreen>>;
}
#[sel(setContentSize:)] #[method(setContentSize:)]
pub fn setContentSize(&self, contentSize: NSSize); pub(crate) fn setContentSize(&self, contentSize: NSSize);
#[sel(setFrameTopLeftPoint:)] #[method(setFrameTopLeftPoint:)]
pub fn setFrameTopLeftPoint(&self, point: NSPoint); pub(crate) fn setFrameTopLeftPoint(&self, point: NSPoint);
#[sel(setMinSize:)] #[method(setMinSize:)]
pub fn setMinSize(&self, minSize: NSSize); pub(crate) fn setMinSize(&self, minSize: NSSize);
#[sel(setMaxSize:)] #[method(setMaxSize:)]
pub fn setMaxSize(&self, maxSize: NSSize); pub(crate) fn setMaxSize(&self, maxSize: NSSize);
#[sel(setResizeIncrements:)] #[method(setResizeIncrements:)]
pub fn setResizeIncrements(&self, increments: NSSize); pub(crate) fn setResizeIncrements(&self, increments: NSSize);
#[sel(contentResizeIncrements)] #[method(contentResizeIncrements)]
pub fn contentResizeIncrements(&self) -> NSSize; pub(crate) fn contentResizeIncrements(&self) -> NSSize;
#[sel(setContentResizeIncrements:)] #[method(setContentResizeIncrements:)]
pub fn setContentResizeIncrements(&self, increments: NSSize); pub(crate) fn setContentResizeIncrements(&self, increments: NSSize);
#[sel(setFrame:display:)] #[method(setFrame:display:)]
pub fn setFrame_display(&self, frameRect: NSRect, flag: bool); pub(crate) fn setFrame_display(&self, frameRect: NSRect, flag: bool);
#[sel(setMovable:)] #[method(setMovable:)]
pub fn setMovable(&self, movable: bool); pub(crate) fn setMovable(&self, movable: bool);
#[sel(setSharingType:)] #[method(setSharingType:)]
pub fn setSharingType(&self, sharingType: NSWindowSharingType); pub(crate) fn setSharingType(&self, sharingType: NSWindowSharingType);
#[sel(setTabbingMode:)] #[method(setTabbingMode:)]
pub fn setTabbingMode(&self, tabbingMode: NSWindowTabbingMode); pub(crate) fn setTabbingMode(&self, tabbingMode: NSWindowTabbingMode);
#[sel(setOpaque:)] #[method(setOpaque:)]
pub fn setOpaque(&self, opaque: bool); pub(crate) fn setOpaque(&self, opaque: bool);
#[sel(hasShadow)] #[method(hasShadow)]
pub fn hasShadow(&self) -> bool; pub(crate) fn hasShadow(&self) -> bool;
#[sel(setHasShadow:)] #[method(setHasShadow:)]
pub fn setHasShadow(&self, has_shadow: bool); pub(crate) fn setHasShadow(&self, has_shadow: bool);
#[sel(setIgnoresMouseEvents:)] #[method(setIgnoresMouseEvents:)]
pub fn setIgnoresMouseEvents(&self, ignores: bool); pub(crate) fn setIgnoresMouseEvents(&self, ignores: bool);
#[sel(setBackgroundColor:)] #[method(setBackgroundColor:)]
pub fn setBackgroundColor(&self, color: &NSColor); pub(crate) fn setBackgroundColor(&self, color: &NSColor);
#[sel(styleMask)] #[method(styleMask)]
pub fn styleMask(&self) -> NSWindowStyleMask; pub(crate) fn styleMask(&self) -> NSWindowStyleMask;
#[sel(setStyleMask:)] #[method(setStyleMask:)]
pub fn setStyleMask(&self, mask: NSWindowStyleMask); pub(crate) fn setStyleMask(&self, mask: NSWindowStyleMask);
#[sel(registerForDraggedTypes:)] #[method(registerForDraggedTypes:)]
pub fn registerForDraggedTypes(&self, types: &NSArray<NSPasteboardType>); pub(crate) fn registerForDraggedTypes(&self, types: &NSArray<NSPasteboardType>);
#[sel(makeKeyAndOrderFront:)] #[method(makeKeyAndOrderFront:)]
pub fn makeKeyAndOrderFront(&self, sender: Option<&Object>); pub(crate) fn makeKeyAndOrderFront(&self, sender: Option<&Object>);
#[sel(orderFront:)] #[method(orderFront:)]
pub fn orderFront(&self, sender: Option<&Object>); pub(crate) fn orderFront(&self, sender: Option<&Object>);
#[sel(miniaturize:)] #[method(miniaturize:)]
pub fn miniaturize(&self, sender: Option<&Object>); pub(crate) fn miniaturize(&self, sender: Option<&Object>);
#[sel(sender:)] #[method(sender:)]
pub fn deminiaturize(&self, sender: Option<&Object>); pub(crate) fn deminiaturize(&self, sender: Option<&Object>);
#[sel(toggleFullScreen:)] #[method(toggleFullScreen:)]
pub fn toggleFullScreen(&self, sender: Option<&Object>); pub(crate) fn toggleFullScreen(&self, sender: Option<&Object>);
#[sel(orderOut:)] #[method(orderOut:)]
pub fn orderOut(&self, sender: Option<&Object>); pub(crate) fn orderOut(&self, sender: Option<&Object>);
#[sel(zoom:)] #[method(zoom:)]
pub fn zoom(&self, sender: Option<&Object>); pub(crate) fn zoom(&self, sender: Option<&Object>);
#[sel(selectNextKeyView:)] #[method(selectNextKeyView:)]
pub fn selectNextKeyView(&self, sender: Option<&Object>); pub(crate) fn selectNextKeyView(&self, sender: Option<&Object>);
#[sel(selectPreviousKeyView:)] #[method(selectPreviousKeyView:)]
pub fn selectPreviousKeyView(&self, sender: Option<&Object>); pub(crate) fn selectPreviousKeyView(&self, sender: Option<&Object>);
pub fn firstResponder(&self) -> Option<Id<NSResponder, Shared>> { #[method_id(firstResponder)]
unsafe { msg_send_id![self, firstResponder] } pub(crate) fn firstResponder(&self) -> Option<Id<NSResponder>>;
}
pub fn standardWindowButton(&self, kind: NSWindowButton) -> Option<Id<NSButton, Shared>> { #[method_id(standardWindowButton:)]
unsafe { msg_send_id![self, standardWindowButton: kind] } pub(crate) fn standardWindowButton(&self, kind: NSWindowButton) -> Option<Id<NSButton>>;
}
#[sel(setTitle:)] #[method(setTitle:)]
pub fn setTitle(&self, title: &NSString); pub(crate) fn setTitle(&self, title: &NSString);
pub fn title_(&self) -> Id<NSString, Shared> { #[method_id(title)]
unsafe { msg_send_id![self, title] } pub(crate) fn title_(&self) -> Id<NSString>;
}
#[sel(setReleasedWhenClosed:)] #[method(setReleasedWhenClosed:)]
pub fn setReleasedWhenClosed(&self, val: bool); pub(crate) fn setReleasedWhenClosed(&self, val: bool);
#[sel(setAcceptsMouseMovedEvents:)] #[method(setAcceptsMouseMovedEvents:)]
pub fn setAcceptsMouseMovedEvents(&self, val: bool); pub(crate) fn setAcceptsMouseMovedEvents(&self, val: bool);
#[sel(setTitlebarAppearsTransparent:)] #[method(setTitlebarAppearsTransparent:)]
pub fn setTitlebarAppearsTransparent(&self, val: bool); pub(crate) fn setTitlebarAppearsTransparent(&self, val: bool);
#[sel(setTitleVisibility:)] #[method(setTitleVisibility:)]
pub fn setTitleVisibility(&self, visibility: NSWindowTitleVisibility); pub(crate) fn setTitleVisibility(&self, visibility: NSWindowTitleVisibility);
#[sel(setMovableByWindowBackground:)] #[method(setMovableByWindowBackground:)]
pub fn setMovableByWindowBackground(&self, val: bool); pub(crate) fn setMovableByWindowBackground(&self, val: bool);
#[sel(setLevel:)] #[method(setLevel:)]
pub fn setLevel(&self, level: NSWindowLevel); pub(crate) fn setLevel(&self, level: NSWindowLevel);
#[sel(setAllowsAutomaticWindowTabbing:)] #[method(setAllowsAutomaticWindowTabbing:)]
pub fn setAllowsAutomaticWindowTabbing(val: bool); pub(crate) fn setAllowsAutomaticWindowTabbing(val: bool);
#[sel(setTabbingIdentifier:)] #[method(setTabbingIdentifier:)]
pub fn setTabbingIdentifier(&self, identifier: &NSString); pub(crate) fn setTabbingIdentifier(&self, identifier: &NSString);
#[sel(setDocumentEdited:)] #[method(setDocumentEdited:)]
pub fn setDocumentEdited(&self, val: bool); pub(crate) fn setDocumentEdited(&self, val: bool);
#[sel(occlusionState)] #[method(occlusionState)]
pub fn occlusionState(&self) -> NSWindowOcclusionState; pub(crate) fn occlusionState(&self) -> NSWindowOcclusionState;
#[sel(center)] #[method(center)]
pub fn center(&self); pub(crate) fn center(&self);
#[sel(isResizable)] #[method(isResizable)]
pub fn isResizable(&self) -> bool; pub(crate) fn isResizable(&self) -> bool;
#[sel(isMiniaturizable)] #[method(isMiniaturizable)]
pub fn isMiniaturizable(&self) -> bool; pub(crate) fn isMiniaturizable(&self) -> bool;
#[sel(hasCloseBox)] #[method(hasCloseBox)]
pub fn hasCloseBox(&self) -> bool; pub(crate) fn hasCloseBox(&self) -> bool;
#[sel(isMiniaturized)] #[method(isMiniaturized)]
pub fn isMiniaturized(&self) -> bool; pub(crate) fn isMiniaturized(&self) -> bool;
#[sel(isVisible)] #[method(isVisible)]
pub fn isVisible(&self) -> bool; pub(crate) fn isVisible(&self) -> bool;
#[sel(isKeyWindow)] #[method(isKeyWindow)]
pub fn isKeyWindow(&self) -> bool; pub(crate) fn isKeyWindow(&self) -> bool;
#[sel(isZoomed)] #[method(isZoomed)]
pub fn isZoomed(&self) -> bool; pub(crate) fn isZoomed(&self) -> bool;
#[sel(allowsAutomaticWindowTabbing)] #[method(allowsAutomaticWindowTabbing)]
pub fn allowsAutomaticWindowTabbing() -> bool; pub(crate) fn allowsAutomaticWindowTabbing() -> bool;
#[sel(selectNextTab)] #[method(selectNextTab)]
pub fn selectNextTab(&self); pub(crate) fn selectNextTab(&self);
pub fn tabbingIdentifier(&self) -> Id<NSString, Shared> { #[method_id(tabbingIdentifier)]
unsafe { msg_send_id![self, tabbingIdentifier] } pub(crate) fn tabbingIdentifier(&self) -> Id<NSString>;
}
pub fn tabGroup(&self) -> Id<NSWindowTabGroup, Shared> { #[method_id(tabGroup)]
unsafe { msg_send_id![self, tabGroup] } pub(crate) fn tabGroup(&self) -> Id<NSWindowTabGroup>;
}
#[sel(isDocumentEdited)] #[method(isDocumentEdited)]
pub fn isDocumentEdited(&self) -> bool; pub(crate) fn isDocumentEdited(&self) -> bool;
#[sel(close)] #[method(close)]
pub fn close(&self); pub(crate) fn close(&self);
#[sel(performWindowDragWithEvent:)] #[method(performWindowDragWithEvent:)]
// TODO: Can this actually accept NULL? // TODO: Can this actually accept NULL?
pub fn performWindowDragWithEvent(&self, event: Option<&NSEvent>); pub(crate) fn performWindowDragWithEvent(&self, event: Option<&NSEvent>);
#[sel(invalidateCursorRectsForView:)] #[method(invalidateCursorRectsForView:)]
pub fn invalidateCursorRectsForView(&self, view: &NSView); pub(crate) fn invalidateCursorRectsForView(&self, view: &NSView);
#[sel(setDelegate:)] #[method(setDelegate:)]
pub fn setDelegate(&self, delegate: Option<&NSObject>); pub(crate) fn setDelegate(&self, delegate: Option<&NSObject>);
#[sel(sendEvent:)] #[method(sendEvent:)]
pub unsafe fn sendEvent(&self, event: &NSEvent); pub(crate) unsafe fn sendEvent(&self, event: &NSEvent);
#[sel(addChildWindow:ordered:)] #[method(addChildWindow:ordered:)]
pub unsafe fn addChildWindow(&self, child: &NSWindow, ordered: NSWindowOrderingMode); pub(crate) unsafe fn addChildWindow(&self, child: &NSWindow, ordered: NSWindowOrderingMode);
} }
); );

View file

@ -4,7 +4,7 @@ use core_foundation::{
base::CFRelease, base::CFRelease,
data::{CFDataGetBytePtr, CFDataRef}, data::{CFDataGetBytePtr, CFDataRef},
}; };
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use smol_str::SmolStr; use smol_str::SmolStr;
use super::appkit::{NSEvent, NSEventModifierFlags}; use super::appkit::{NSEvent, NSEventModifierFlags};
@ -31,7 +31,7 @@ pub(crate) enum EventWrapper {
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum EventProxy { pub(crate) enum EventProxy {
DpiChangedProxy { DpiChangedProxy {
window: Id<WinitWindow, Shared>, window: Id<WinitWindow>,
suggested_size: LogicalSize<f64>, suggested_size: LogicalSize<f64>,
scale_factor: f64, scale_factor: f64,
}, },

View file

@ -17,8 +17,8 @@ use core_foundation::runloop::{
kCFRunLoopCommonModes, CFRunLoopAddSource, CFRunLoopGetMain, CFRunLoopSourceContext, kCFRunLoopCommonModes, CFRunLoopAddSource, CFRunLoopGetMain, CFRunLoopSourceContext,
CFRunLoopSourceCreate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp, CFRunLoopSourceCreate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp,
}; };
use objc2::foundation::is_main_thread; use icrate::Foundation::is_main_thread;
use objc2::rc::{autoreleasepool, Id, Shared}; use objc2::rc::{autoreleasepool, Id};
use objc2::{msg_send_id, ClassType}; use objc2::{msg_send_id, ClassType};
use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle}; use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle};
@ -116,7 +116,7 @@ impl<T> EventLoopWindowTarget<T> {
pub struct EventLoop<T: 'static> { pub struct EventLoop<T: 'static> {
/// The delegate is only weakly referenced by NSApplication, so we keep /// The delegate is only weakly referenced by NSApplication, so we keep
/// it around here as well. /// it around here as well.
_delegate: Id<ApplicationDelegate, Shared>, _delegate: Id<ApplicationDelegate>,
window_target: Rc<RootWindowTarget<T>>, window_target: Rc<RootWindowTarget<T>>,
panic_info: Rc<PanicInfo>, panic_info: Rc<PanicInfo>,
@ -157,7 +157,7 @@ impl<T> EventLoop<T> {
// `sharedApplication`) is called anywhere else, or we'll end up // `sharedApplication`) is called anywhere else, or we'll end up
// with the wrong `NSApplication` class and the wrong thread could // with the wrong `NSApplication` class and the wrong thread could
// be marked as main. // be marked as main.
let app: Id<WinitApplication, Shared> = let app: Id<WinitApplication> =
unsafe { msg_send_id![WinitApplication::class(), sharedApplication] }; unsafe { msg_send_id![WinitApplication::class(), sharedApplication] };
use NSApplicationActivationPolicy::*; use NSApplicationActivationPolicy::*;

View file

@ -1,7 +1,8 @@
use objc2::foundation::{NSProcessInfo, NSString}; use icrate::ns_string;
use objc2::rc::{Id, Shared}; use icrate::Foundation::{NSProcessInfo, NSString};
use objc2::rc::Id;
use objc2::runtime::Sel; use objc2::runtime::Sel;
use objc2::{ns_string, sel}; use objc2::sel;
use super::appkit::{NSApp, NSEventModifierFlags, NSMenu, NSMenuItem}; use super::appkit::{NSApp, NSEventModifierFlags, NSMenu, NSMenuItem};
@ -16,17 +17,17 @@ pub fn initialize() {
menubar.addItem(&app_menu_item); menubar.addItem(&app_menu_item);
let app_menu = NSMenu::new(); let app_menu = NSMenu::new();
let process_name = NSProcessInfo::process_info().process_name(); let process_name = NSProcessInfo::processInfo().processName();
// About menu item // 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); let about_item = menu_item(&about_item_title, sel!(orderFrontStandardAboutPanel:), None);
// Seperator menu item // Seperator menu item
let sep_first = NSMenuItem::separatorItem(); let sep_first = NSMenuItem::separatorItem();
// Hide application menu item // 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( let hide_item = menu_item(
&hide_item_title, &hide_item_title,
sel!(hide:), sel!(hide:),
@ -57,7 +58,7 @@ pub fn initialize() {
let sep = NSMenuItem::separatorItem(); let sep = NSMenuItem::separatorItem();
// Quit application menu item // 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( let quit_item = menu_item(
&quit_item_title, &quit_item_title,
sel!(terminate:), sel!(terminate:),
@ -84,7 +85,7 @@ fn menu_item(
title: &NSString, title: &NSString,
selector: Sel, selector: Sel,
key_equivalent: Option<KeyEquivalent<'_>>, key_equivalent: Option<KeyEquivalent<'_>>,
) -> Id<NSMenuItem, Shared> { ) -> Id<NSMenuItem> {
let (key, masks) = match key_equivalent { let (key, masks) = match key_equivalent {
Some(ke) => (ke.key, ke.masks), Some(ke) => (ke.key, ke.masks),
None => (ns_string!(""), None), None => (ns_string!(""), None),

View file

@ -32,7 +32,7 @@ pub(crate) use self::{
use crate::{ use crate::{
error::OsError as RootOsError, event::DeviceId as RootDeviceId, window::WindowAttributes, 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::icon::NoIcon as PlatformIcon;
pub(crate) use crate::platform_impl::Fullscreen; pub(crate) use crate::platform_impl::Fullscreen;
@ -50,9 +50,9 @@ impl DeviceId {
pub(crate) const DEVICE_ID: RootDeviceId = RootDeviceId(DeviceId); pub(crate) const DEVICE_ID: RootDeviceId = RootDeviceId(DeviceId);
pub(crate) struct Window { pub(crate) struct Window {
pub(crate) window: Id<WinitWindow, Shared>, pub(crate) window: Id<WinitWindow>,
// We keep this around so that it doesn't get dropped until the window does. // We keep this around so that it doesn't get dropped until the window does.
_delegate: Id<WinitWindowDelegate, Shared>, _delegate: Id<WinitWindowDelegate>,
} }
impl Drop for Window { impl Drop for Window {

View file

@ -8,7 +8,7 @@ use core_foundation::{
string::CFString, string::CFString,
}; };
use core_graphics::display::{CGDirectDisplayID, CGDisplay, CGDisplayBounds}; use core_graphics::display::{CGDirectDisplayID, CGDisplay, CGDisplayBounds};
use objc2::rc::{Id, Shared}; use objc2::rc::Id;
use super::appkit::NSScreen; use super::appkit::NSScreen;
use super::ffi; use super::ffi;
@ -295,19 +295,14 @@ impl MonitorHandle {
} }
} }
pub(crate) fn ns_screen(&self) -> Option<Id<NSScreen, Shared>> { pub(crate) fn ns_screen(&self) -> Option<Id<NSScreen>> {
let uuid = unsafe { ffi::CGDisplayCreateUUIDFromDisplayID(self.0) }; let uuid = unsafe { ffi::CGDisplayCreateUUIDFromDisplayID(self.0) };
NSScreen::screens() NSScreen::screens().into_iter().find(|screen| {
.into_iter() let other_native_id = screen.display_id();
.find(|screen| { let other_uuid = unsafe {
let other_native_id = screen.display_id(); ffi::CGDisplayCreateUUIDFromDisplayID(other_native_id as CGDirectDisplayID)
let other_uuid = unsafe { };
ffi::CGDisplayCreateUUIDFromDisplayID(other_native_id as CGDirectDisplayID) uuid == other_uuid
}; })
uuid == other_uuid
})
.map(|screen| unsafe {
Id::retain(screen as *const NSScreen as *mut NSScreen).unwrap()
})
} }
} }

View file

@ -1,7 +1,7 @@
use std::ops::Deref; use std::ops::Deref;
use dispatch::Queue; 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 objc2::rc::autoreleasepool;
use crate::{ use crate::{

View file

@ -5,7 +5,7 @@ mod r#async;
pub(crate) use self::r#async::*; pub(crate) use self::r#async::*;
use core_graphics::display::CGDisplay; 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; use crate::dpi::LogicalPosition;

View file

@ -1,23 +1,23 @@
#![allow(clippy::unnecessary_cast)] #![allow(clippy::unnecessary_cast)]
use std::boxed::Box; use std::boxed::Box;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
use std::os::raw::*; use std::ptr::NonNull;
use std::ptr::{self, NonNull};
use std::str;
use objc2::declare::{Ivar, IvarDrop}; use icrate::Foundation::{
use objc2::foundation::{
NSArray, NSAttributedString, NSAttributedStringKey, NSCopying, NSMutableAttributedString, 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::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::{ 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}, event::{code_to_key, code_to_location},
}; };
use crate::{ use crate::{
@ -42,7 +42,7 @@ use crate::{
#[derive(Debug)] #[derive(Debug)]
struct CursorState { struct CursorState {
visible: bool, visible: bool,
cursor: Id<NSCursor, Shared>, cursor: Id<NSCursor>,
} }
impl Default for CursorState { impl Default for CursorState {
@ -119,7 +119,7 @@ fn get_left_modifier_code(key: &Key) -> KeyCode {
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct ViewState { pub struct ViewState {
cursor_state: RefCell<CursorState>, cursor_state: RefCell<CursorState>,
ime_position: Cell<LogicalPosition<f64>>, ime_position: Cell<LogicalPosition<f64>>,
ime_size: Cell<LogicalSize<f64>>, ime_size: Cell<LogicalSize<f64>>,
@ -138,7 +138,7 @@ struct ViewState {
/// to the application, even during IME /// to the application, even during IME
forward_key_to_app: Cell<bool>, forward_key_to_app: Cell<bool>,
marked_text: RefCell<Id<NSMutableAttributedString, Owned>>, marked_text: RefCell<Id<NSMutableAttributedString>>,
accepts_first_mouse: bool, accepts_first_mouse: bool,
} }
@ -147,23 +147,27 @@ declare_class!(
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub(super) struct WinitView { pub(super) struct WinitView {
// Weak reference because the window keeps a strong reference to the view // Weak reference because the window keeps a strong reference to the view
_ns_window: IvarDrop<Box<WeakId<WinitWindow>>>, _ns_window: IvarDrop<Box<WeakId<WinitWindow>>, "__ns_window">,
state: IvarDrop<Box<ViewState>>, state: IvarDrop<Box<ViewState>, "_state">,
} }
mod ivars;
unsafe impl ClassType for WinitView { unsafe impl ClassType for WinitView {
#[inherits(NSResponder, NSObject)] #[inherits(NSResponder, NSObject)]
type Super = NSView; type Super = NSView;
type Mutability = mutability::InteriorMutable;
const NAME: &'static str = "WinitView";
} }
unsafe impl WinitView { unsafe impl WinitView {
#[sel(initWithId:acceptsFirstMouse:)] #[method(initWithId:acceptsFirstMouse:)]
unsafe fn init_with_id( unsafe fn init_with_id(
&mut self, this: *mut Self,
window: &WinitWindow, window: &WinitWindow,
accepts_first_mouse: bool, accepts_first_mouse: bool,
) -> Option<NonNull<Self>> { ) -> Option<NonNull<Self>> {
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.map(|this| {
let state = ViewState { let state = ViewState {
accepts_first_mouse, accepts_first_mouse,
@ -201,7 +205,7 @@ declare_class!(
} }
unsafe impl WinitView { unsafe impl WinitView {
#[sel(viewDidMoveToWindow)] #[method(viewDidMoveToWindow)]
fn view_did_move_to_window(&self) { fn view_did_move_to_window(&self) {
trace_scope!("viewDidMoveToWindow"); trace_scope!("viewDidMoveToWindow");
if let Some(tracking_rect) = self.state.tracking_rect.take() { if let Some(tracking_rect) = self.state.tracking_rect.take() {
@ -213,7 +217,7 @@ declare_class!(
self.state.tracking_rect.set(Some(tracking_rect)); self.state.tracking_rect.set(Some(tracking_rect));
} }
#[sel(frameDidChange:)] #[method(frameDidChange:)]
fn frame_did_change(&self, _event: &NSEvent) { fn frame_did_change(&self, _event: &NSEvent) {
trace_scope!("frameDidChange:"); trace_scope!("frameDidChange:");
if let Some(tracking_rect) = self.state.tracking_rect.take() { if let Some(tracking_rect) = self.state.tracking_rect.take() {
@ -232,7 +236,7 @@ declare_class!(
self.queue_event(WindowEvent::Resized(size)); self.queue_event(WindowEvent::Resized(size));
} }
#[sel(drawRect:)] #[method(drawRect:)]
fn draw_rect(&self, rect: NSRect) { fn draw_rect(&self, rect: NSRect) {
trace_scope!("drawRect:"); trace_scope!("drawRect:");
@ -247,7 +251,7 @@ declare_class!(
} }
} }
#[sel(acceptsFirstResponder)] #[method(acceptsFirstResponder)]
fn accepts_first_responder(&self) -> bool { fn accepts_first_responder(&self) -> bool {
trace_scope!("acceptsFirstResponder"); trace_scope!("acceptsFirstResponder");
true true
@ -256,13 +260,13 @@ declare_class!(
// This is necessary to prevent a beefy terminal error on MacBook Pros: // 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 // 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` // TODO: Add an API extension for using `NSTouchBar`
#[sel(touchBar)] #[method_id(touchBar)]
fn touch_bar(&self) -> bool { fn touch_bar(&self) -> Option<Id<NSObject>> {
trace_scope!("touchBar"); trace_scope!("touchBar");
false None
} }
#[sel(resetCursorRects)] #[method(resetCursorRects)]
fn reset_cursor_rects(&self) { fn reset_cursor_rects(&self) {
trace_scope!("resetCursorRects"); trace_scope!("resetCursorRects");
let bounds = self.bounds(); let bounds = self.bounds();
@ -276,17 +280,17 @@ declare_class!(
} }
} }
unsafe impl Protocol<NSTextInputClient> for WinitView { unsafe impl NSTextInputClient for WinitView {
#[sel(hasMarkedText)] #[method(hasMarkedText)]
fn has_marked_text(&self) -> bool { fn has_marked_text(&self) -> bool {
trace_scope!("hasMarkedText"); 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 { fn marked_range(&self) -> NSRange {
trace_scope!("markedRange"); trace_scope!("markedRange");
let length = self.state.marked_text.borrow().len_utf16(); let length = self.state.marked_text.borrow().length();
if length > 0 { if length > 0 {
NSRange::new(0, length) NSRange::new(0, length)
} else { } else {
@ -294,13 +298,13 @@ declare_class!(
} }
} }
#[sel(selectedRange)] #[method(selectedRange)]
fn selected_range(&self) -> NSRange { fn selected_range(&self) -> NSRange {
trace_scope!("selectedRange"); trace_scope!("selectedRange");
util::EMPTY_RANGE util::EMPTY_RANGE
} }
#[sel(setMarkedText:selectedRange:replacementRange:)] #[method(setMarkedText:selectedRange:replacementRange:)]
fn set_marked_text( fn set_marked_text(
&self, &self,
string: &NSObject, string: &NSObject,
@ -356,7 +360,7 @@ declare_class!(
self.queue_event(WindowEvent::Ime(Ime::Preedit(preedit_string, cursor_range))); self.queue_event(WindowEvent::Ime(Ime::Preedit(preedit_string, cursor_range)));
} }
#[sel(unmarkText)] #[method(unmarkText)]
fn unmark_text(&self) { fn unmark_text(&self) {
trace_scope!("unmarkText"); trace_scope!("unmarkText");
*self.state.marked_text.borrow_mut() = NSMutableAttributedString::new(); *self.state.marked_text.borrow_mut() = NSMutableAttributedString::new();
@ -373,33 +377,33 @@ declare_class!(
} }
} }
#[sel(validAttributesForMarkedText)] #[method_id(validAttributesForMarkedText)]
fn valid_attributes_for_marked_text(&self) -> *const NSArray<NSAttributedStringKey> { fn valid_attributes_for_marked_text(&self) -> Id<NSArray<NSAttributedStringKey>> {
trace_scope!("validAttributesForMarkedText"); trace_scope!("validAttributesForMarkedText");
Id::autorelease_return(NSArray::new()) NSArray::new()
} }
#[sel(attributedSubstringForProposedRange:actualRange:)] #[method_id(attributedSubstringForProposedRange:actualRange:)]
fn attributed_substring_for_proposed_range( fn attributed_substring_for_proposed_range(
&self, &self,
_range: NSRange, _range: NSRange,
_actual_range: *mut c_void, // *mut NSRange _actual_range: *mut NSRange,
) -> *const NSAttributedString { ) -> Option<Id<NSAttributedString>> {
trace_scope!("attributedSubstringForProposedRange:actualRange:"); trace_scope!("attributedSubstringForProposedRange:actualRange:");
ptr::null() None
} }
#[sel(characterIndexForPoint:)] #[method(characterIndexForPoint:)]
fn character_index_for_point(&self, _point: NSPoint) -> NSUInteger { fn character_index_for_point(&self, _point: NSPoint) -> NSUInteger {
trace_scope!("characterIndexForPoint:"); trace_scope!("characterIndexForPoint:");
0 0
} }
#[sel(firstRectForCharacterRange:actualRange:)] #[method(firstRectForCharacterRange:actualRange:)]
fn first_rect_for_character_range( fn first_rect_for_character_range(
&self, &self,
_range: NSRange, _range: NSRange,
_actual_range: *mut c_void, // *mut NSRange _actual_range: *mut NSRange,
) -> NSRect { ) -> NSRect {
trace_scope!("firstRectForCharacterRange:actualRange:"); trace_scope!("firstRectForCharacterRange:actualRange:");
let window = self.window(); let window = self.window();
@ -412,7 +416,7 @@ declare_class!(
NSRect::new(NSPoint::new(x as _, y as _), NSSize::new(width, height)) 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) { fn insert_text(&self, string: &NSObject, _replacement_range: NSRange) {
trace_scope!("insertText:replacementRange:"); 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 // 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. // readable" character happens, i.e. newlines, tabs, and Ctrl+C.
#[sel(doCommandBySelector:)] #[method(doCommandBySelector:)]
fn do_command_by_selector(&self, _command: Sel) { fn do_command_by_selector(&self, _command: Sel) {
trace_scope!("doCommandBySelector:"); trace_scope!("doCommandBySelector:");
// We shouldn't forward any character from just commited text, since we'll end up sending // 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 { unsafe impl WinitView {
#[sel(keyDown:)] #[method(keyDown:)]
fn key_down(&self, event: &NSEvent) { fn key_down(&self, event: &NSEvent) {
trace_scope!("keyDown:"); trace_scope!("keyDown:");
{ {
@ -485,7 +489,7 @@ declare_class!(
// `doCommandBySelector`. (doCommandBySelector means that the keyboard input // `doCommandBySelector`. (doCommandBySelector means that the keyboard input
// is not handled by IME and should be handled by the application) // is not handled by IME and should be handled by the application)
if self.state.ime_allowed.get() { 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) }; unsafe { self.interpretKeyEvents(&events_for_nsview) };
// If the text was commited we must treat the next keyboard event as IME related. // 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) { fn key_up(&self, event: &NSEvent) {
trace_scope!("keyUp:"); trace_scope!("keyUp:");
@ -538,15 +542,15 @@ declare_class!(
} }
} }
#[sel(flagsChanged:)] #[method(flagsChanged:)]
fn flags_changed(&self, ns_event: &NSEvent) { fn flags_changed(&self, event: &NSEvent) {
trace_scope!("flagsChanged:"); trace_scope!("flagsChanged:");
self.update_modifiers(ns_event, true); self.update_modifiers(event, true);
} }
#[sel(insertTab:)] #[method(insertTab:)]
fn insert_tab(&self, _sender: *const Object) { fn insert_tab(&self, _sender: Option<&Object>) {
trace_scope!("insertTab:"); trace_scope!("insertTab:");
let window = self.window(); let window = self.window();
if let Some(first_responder) = window.firstResponder() { if let Some(first_responder) = window.firstResponder() {
@ -556,8 +560,8 @@ declare_class!(
} }
} }
#[sel(insertBackTab:)] #[method(insertBackTab:)]
fn insert_back_tab(&self, _sender: *const Object) { fn insert_back_tab(&self, _sender: Option<&Object>) {
trace_scope!("insertBackTab:"); trace_scope!("insertBackTab:");
let window = self.window(); let window = self.window();
if let Some(first_responder) = window.firstResponder() { if let Some(first_responder) = window.firstResponder() {
@ -569,8 +573,8 @@ declare_class!(
// Allows us to receive Cmd-. (the shortcut for closing a dialog) // Allows us to receive Cmd-. (the shortcut for closing a dialog)
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=300620#c6 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=300620#c6
#[sel(cancelOperation:)] #[method(cancelOperation:)]
fn cancel_operation(&self, _sender: *const Object) { fn cancel_operation(&self, _sender: Option<&Object>) {
trace_scope!("cancelOperation:"); trace_scope!("cancelOperation:");
let event = NSApp() let event = NSApp()
@ -587,42 +591,42 @@ declare_class!(
}); });
} }
#[sel(mouseDown:)] #[method(mouseDown:)]
fn mouse_down(&self, event: &NSEvent) { fn mouse_down(&self, event: &NSEvent) {
trace_scope!("mouseDown:"); trace_scope!("mouseDown:");
self.mouse_motion(event); self.mouse_motion(event);
self.mouse_click(event, ElementState::Pressed); self.mouse_click(event, ElementState::Pressed);
} }
#[sel(mouseUp:)] #[method(mouseUp:)]
fn mouse_up(&self, event: &NSEvent) { fn mouse_up(&self, event: &NSEvent) {
trace_scope!("mouseUp:"); trace_scope!("mouseUp:");
self.mouse_motion(event); self.mouse_motion(event);
self.mouse_click(event, ElementState::Released); self.mouse_click(event, ElementState::Released);
} }
#[sel(rightMouseDown:)] #[method(rightMouseDown:)]
fn right_mouse_down(&self, event: &NSEvent) { fn right_mouse_down(&self, event: &NSEvent) {
trace_scope!("rightMouseDown:"); trace_scope!("rightMouseDown:");
self.mouse_motion(event); self.mouse_motion(event);
self.mouse_click(event, ElementState::Pressed); self.mouse_click(event, ElementState::Pressed);
} }
#[sel(rightMouseUp:)] #[method(rightMouseUp:)]
fn right_mouse_up(&self, event: &NSEvent) { fn right_mouse_up(&self, event: &NSEvent) {
trace_scope!("rightMouseUp:"); trace_scope!("rightMouseUp:");
self.mouse_motion(event); self.mouse_motion(event);
self.mouse_click(event, ElementState::Released); self.mouse_click(event, ElementState::Released);
} }
#[sel(otherMouseDown:)] #[method(otherMouseDown:)]
fn other_mouse_down(&self, event: &NSEvent) { fn other_mouse_down(&self, event: &NSEvent) {
trace_scope!("otherMouseDown:"); trace_scope!("otherMouseDown:");
self.mouse_motion(event); self.mouse_motion(event);
self.mouse_click(event, ElementState::Pressed); self.mouse_click(event, ElementState::Pressed);
} }
#[sel(otherMouseUp:)] #[method(otherMouseUp:)]
fn other_mouse_up(&self, event: &NSEvent) { fn other_mouse_up(&self, event: &NSEvent) {
trace_scope!("otherMouseUp:"); trace_scope!("otherMouseUp:");
self.mouse_motion(event); self.mouse_motion(event);
@ -631,27 +635,27 @@ declare_class!(
// No tracing on these because that would be overly verbose // No tracing on these because that would be overly verbose
#[sel(mouseMoved:)] #[method(mouseMoved:)]
fn mouse_moved(&self, event: &NSEvent) { fn mouse_moved(&self, event: &NSEvent) {
self.mouse_motion(event); self.mouse_motion(event);
} }
#[sel(mouseDragged:)] #[method(mouseDragged:)]
fn mouse_dragged(&self, event: &NSEvent) { fn mouse_dragged(&self, event: &NSEvent) {
self.mouse_motion(event); self.mouse_motion(event);
} }
#[sel(rightMouseDragged:)] #[method(rightMouseDragged:)]
fn right_mouse_dragged(&self, event: &NSEvent) { fn right_mouse_dragged(&self, event: &NSEvent) {
self.mouse_motion(event); self.mouse_motion(event);
} }
#[sel(otherMouseDragged:)] #[method(otherMouseDragged:)]
fn other_mouse_dragged(&self, event: &NSEvent) { fn other_mouse_dragged(&self, event: &NSEvent) {
self.mouse_motion(event); self.mouse_motion(event);
} }
#[sel(mouseEntered:)] #[method(mouseEntered:)]
fn mouse_entered(&self, _event: &NSEvent) { fn mouse_entered(&self, _event: &NSEvent) {
trace_scope!("mouseEntered:"); trace_scope!("mouseEntered:");
self.queue_event(WindowEvent::CursorEntered { self.queue_event(WindowEvent::CursorEntered {
@ -659,7 +663,7 @@ declare_class!(
}); });
} }
#[sel(mouseExited:)] #[method(mouseExited:)]
fn mouse_exited(&self, _event: &NSEvent) { fn mouse_exited(&self, _event: &NSEvent) {
trace_scope!("mouseExited:"); trace_scope!("mouseExited:");
@ -668,7 +672,7 @@ declare_class!(
}); });
} }
#[sel(scrollWheel:)] #[method(scrollWheel:)]
fn scroll_wheel(&self, event: &NSEvent) { fn scroll_wheel(&self, event: &NSEvent) {
trace_scope!("scrollWheel:"); trace_scope!("scrollWheel:");
@ -716,7 +720,7 @@ declare_class!(
}); });
} }
#[sel(magnifyWithEvent:)] #[method(magnifyWithEvent:)]
fn magnify_with_event(&self, event: &NSEvent) { fn magnify_with_event(&self, event: &NSEvent) {
trace_scope!("magnifyWithEvent:"); trace_scope!("magnifyWithEvent:");
@ -735,7 +739,7 @@ declare_class!(
}); });
} }
#[sel(smartMagnifyWithEvent:)] #[method(smartMagnifyWithEvent:)]
fn smart_magnify_with_event(&self, _event: &NSEvent) { fn smart_magnify_with_event(&self, _event: &NSEvent) {
trace_scope!("smartMagnifyWithEvent:"); trace_scope!("smartMagnifyWithEvent:");
@ -744,7 +748,7 @@ declare_class!(
}); });
} }
#[sel(rotateWithEvent:)] #[method(rotateWithEvent:)]
fn rotate_with_event(&self, event: &NSEvent) { fn rotate_with_event(&self, event: &NSEvent) {
trace_scope!("rotateWithEvent:"); trace_scope!("rotateWithEvent:");
@ -763,7 +767,7 @@ declare_class!(
}); });
} }
#[sel(pressureChangeWithEvent:)] #[method(pressureChangeWithEvent:)]
fn pressure_change_with_event(&self, event: &NSEvent) { fn pressure_change_with_event(&self, event: &NSEvent) {
trace_scope!("pressureChangeWithEvent:"); trace_scope!("pressureChangeWithEvent:");
@ -779,13 +783,13 @@ declare_class!(
// Allows us to receive Ctrl-Tab and Ctrl-Esc. // Allows us to receive Ctrl-Tab and Ctrl-Esc.
// Note that this *doesn't* help with any missing Cmd inputs. // 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 // 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 { fn wants_key_down_for_event(&self, _event: &NSEvent) -> bool {
trace_scope!("_wantsKeyDownForEvent:"); trace_scope!("_wantsKeyDownForEvent:");
true true
} }
#[sel(acceptsFirstMouse:)] #[method(acceptsFirstMouse:)]
fn accepts_first_mouse(&self, _event: &NSEvent) -> bool { fn accepts_first_mouse(&self, _event: &NSEvent) -> bool {
trace_scope!("acceptsFirstMouse:"); trace_scope!("acceptsFirstMouse:");
self.state.accepts_first_mouse self.state.accepts_first_mouse
@ -794,17 +798,17 @@ declare_class!(
); );
impl WinitView { impl WinitView {
pub(super) fn new(window: &WinitWindow, accepts_first_mouse: bool) -> Id<Self, Shared> { pub(super) fn new(window: &WinitWindow, accepts_first_mouse: bool) -> Id<Self> {
unsafe { unsafe {
msg_send_id![ msg_send_id![
msg_send_id![Self::class(), alloc], Self::alloc(),
initWithId: window, initWithId: window,
acceptsFirstMouse: accepts_first_mouse, acceptsFirstMouse: accepts_first_mouse,
] ]
} }
} }
fn window(&self) -> Id<WinitWindow, Shared> { fn window(&self) -> Id<WinitWindow> {
// TODO: Simply use `window` property on `NSView`. // TODO: Simply use `window` property on `NSView`.
// That only returns a window _after_ the view has been attached though! // That only returns a window _after_ the view has been attached though!
// (which is incompatible with `frameDidChange:`) // (which is incompatible with `frameDidChange:`)
@ -849,7 +853,7 @@ impl WinitView {
.unwrap_or_else(String::new) .unwrap_or_else(String::new)
} }
pub(super) fn set_cursor_icon(&self, icon: Id<NSCursor, Shared>) { pub(super) fn set_cursor_icon(&self, icon: Id<NSCursor>) {
let mut cursor_state = self.state.cursor_state.borrow_mut(); let mut cursor_state = self.state.cursor_state.borrow_mut();
cursor_state.cursor = icon; 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 // NOTE: to get option as alt working we need to rewrite events
// we're getting from the operating system, which makes it // we're getting from the operating system, which makes it
// impossible to provide such events as extra in `KeyEvent`. // impossible to provide such events as extra in `KeyEvent`.
fn replace_event(event: &NSEvent, option_as_alt: OptionAsAlt) -> Id<NSEvent, Shared> { fn replace_event(event: &NSEvent, option_as_alt: OptionAsAlt) -> Id<NSEvent> {
let ev_mods = event_mods(event).state; let ev_mods = event_mods(event).state;
let ignore_alt_characters = match option_as_alt { let ignore_alt_characters = match option_as_alt {
OptionAsAlt::OnlyLeft if event.lalt_pressed() => true, OptionAsAlt::OnlyLeft if event.lalt_pressed() => true,

View file

@ -35,13 +35,13 @@ use crate::{
}, },
}; };
use core_graphics::display::{CGDisplay, CGPoint}; use core_graphics::display::{CGDisplay, CGPoint};
use objc2::declare::{Ivar, IvarDrop}; use icrate::Foundation::{
use objc2::foundation::{
is_main_thread, CGFloat, NSArray, NSCopying, NSInteger, NSObject, NSPoint, NSRect, NSSize, is_main_thread, CGFloat, NSArray, NSCopying, NSInteger, NSObject, NSPoint, NSRect, NSSize,
NSString, NSString,
}; };
use objc2::rc::{autoreleasepool, Id, Shared}; use objc2::declare::{Ivar, IvarDrop};
use objc2::{declare_class, msg_send, msg_send_id, sel, ClassType}; use objc2::rc::{autoreleasepool, Id};
use objc2::{declare_class, msg_send, msg_send_id, mutability, sel, ClassType};
use super::appkit::{ use super::appkit::{
NSApp, NSAppKitVersion, NSAppearance, NSApplicationPresentationOptions, NSBackingStoreType, NSApp, NSAppKitVersion, NSAppearance, NSApplicationPresentationOptions, NSBackingStoreType,
@ -107,27 +107,31 @@ impl Default for PlatformSpecificWindowBuilderAttributes {
declare_class!( declare_class!(
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct WinitWindow { pub struct WinitWindow {
// TODO: Fix unnecessary boxing here // TODO: Fix unnecessary boxing here
shared_state: IvarDrop<Box<Mutex<SharedState>>>, shared_state: IvarDrop<Box<Mutex<SharedState>>, "_shared_state">,
} }
mod ivars;
unsafe impl ClassType for WinitWindow { unsafe impl ClassType for WinitWindow {
#[inherits(NSResponder, NSObject)] #[inherits(NSResponder, NSObject)]
type Super = NSWindow; type Super = NSWindow;
type Mutability = mutability::InteriorMutable;
const NAME: &'static str = "WinitWindow";
} }
unsafe impl WinitWindow { unsafe impl WinitWindow {
#[sel(initWithContentRect:styleMask:state:)] #[method(initWithContentRect:styleMask:state:)]
unsafe fn init( unsafe fn init(
&mut self, this: *mut Self,
frame: NSRect, frame: NSRect,
mask: NSWindowStyleMask, mask: NSWindowStyleMask,
state: *mut c_void, state: *mut c_void,
) -> Option<NonNull<Self>> { ) -> Option<NonNull<Self>> {
let this: Option<&mut Self> = unsafe { let this: Option<&mut Self> = unsafe {
msg_send![ msg_send![
super(self), super(this),
initWithContentRect: frame, initWithContentRect: frame,
styleMask: mask, styleMask: mask,
backing: NSBackingStoreType::NSBackingStoreBuffered, backing: NSBackingStoreType::NSBackingStoreBuffered,
@ -152,13 +156,13 @@ declare_class!(
} }
unsafe impl WinitWindow { unsafe impl WinitWindow {
#[sel(canBecomeMainWindow)] #[method(canBecomeMainWindow)]
fn can_become_main_window(&self) -> bool { fn can_become_main_window(&self) -> bool {
trace_scope!("canBecomeMainWindow"); trace_scope!("canBecomeMainWindow");
true true
} }
#[sel(canBecomeKeyWindow)] #[method(canBecomeKeyWindow)]
fn can_become_key_window(&self) -> bool { fn can_become_key_window(&self) -> bool {
trace_scope!("canBecomeKeyWindow"); trace_scope!("canBecomeKeyWindow");
true true
@ -249,7 +253,7 @@ impl WinitWindow {
pub(crate) fn new( pub(crate) fn new(
attrs: WindowAttributes, attrs: WindowAttributes,
pl_attrs: PlatformSpecificWindowBuilderAttributes, pl_attrs: PlatformSpecificWindowBuilderAttributes,
) -> Result<(Id<Self, Shared>, Id<WinitWindowDelegate, Shared>), RootOsError> { ) -> Result<(Id<Self>, Id<WinitWindowDelegate>), RootOsError> {
trace_scope!("WinitWindow::new"); trace_scope!("WinitWindow::new");
if !is_main_thread() { if !is_main_thread() {
@ -334,9 +338,9 @@ impl WinitWindow {
// Pass the state through FFI to the method declared on the class // 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 state_ptr: *mut c_void = Box::into_raw(Box::new(Mutex::new(state))).cast();
let this: Option<Id<Self, Shared>> = unsafe { let this: Option<Id<Self>> = unsafe {
msg_send_id![ msg_send_id![
msg_send_id![WinitWindow::class(), alloc], WinitWindow::alloc(),
initWithContentRect: frame, initWithContentRect: frame,
styleMask: masks, styleMask: masks,
state: state_ptr, state: state_ptr,
@ -413,27 +417,26 @@ impl WinitWindow {
match attrs.parent_window { match attrs.parent_window {
Some(RawWindowHandle::AppKit(handle)) => { Some(RawWindowHandle::AppKit(handle)) => {
// SAFETY: Caller ensures the pointer is valid or NULL // SAFETY: Caller ensures the pointer is valid or NULL
let parent: Id<NSWindow, Shared> = let parent: Id<NSWindow> = match unsafe { Id::retain(handle.ns_window.cast()) } {
match unsafe { Id::retain(handle.ns_window.cast()) } { Some(window) => window,
Some(window) => window, None => {
None => { // SAFETY: Caller ensures the pointer is valid or NULL
// SAFETY: Caller ensures the pointer is valid or NULL let parent_view: Id<NSView> =
let parent_view: Id<NSView, Shared> = match unsafe { Id::retain(handle.ns_view.cast()) } {
match unsafe { Id::retain(handle.ns_view.cast()) } { Some(view) => view,
Some(view) => view, None => {
None => { return Err(os_error!(OsError::CreationError(
return Err(os_error!(OsError::CreationError( "raw window handle should be non-empty"
"raw window handle should be non-empty" )))
))) }
} };
}; parent_view.window().ok_or_else(|| {
parent_view.window().ok_or_else(|| { os_error!(OsError::CreationError(
os_error!(OsError::CreationError( "parent view should be installed in a window"
"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` // 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. // where we allow making a window a child window is right here, just after it's been created.
unsafe { parent.addChildWindow(&this, NSWindowOrderingMode::NSWindowAbove) }; unsafe { parent.addChildWindow(&this, NSWindowOrderingMode::NSWindowAbove) };
@ -477,7 +480,7 @@ impl WinitWindow {
this.set_window_level(attrs.window_level); this.set_window_level(attrs.window_level);
// register for drag and drop operations. // register for drag and drop operations.
this.registerForDraggedTypes(&NSArray::from_slice(&[ this.registerForDraggedTypes(&NSArray::from_id_slice(&[
unsafe { NSFilenamesPboardType }.copy() unsafe { NSFilenamesPboardType }.copy()
])); ]));
@ -521,13 +524,7 @@ impl WinitWindow {
Ok((this, delegate)) Ok((this, delegate))
} }
pub(super) fn retain(&self) -> Id<WinitWindow, Shared> { pub(super) fn view(&self) -> Id<WinitView> {
// 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<WinitView, Shared> {
// SAFETY: The view inside WinitWindow is always `WinitView` // SAFETY: The view inside WinitWindow is always `WinitView`
unsafe { Id::cast(self.contentView()) } unsafe { Id::cast(self.contentView()) }
} }
@ -1462,7 +1459,7 @@ pub(super) fn get_ns_theme() -> Theme {
return Theme::Light; return Theme::Light;
} }
let appearance = app.effectiveAppearance(); 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("NSAppearanceNameAqua"),
NSString::from_str("NSAppearanceNameDarkAqua"), NSString::from_str("NSAppearanceNameDarkAqua"),
])); ]));

View file

@ -2,11 +2,11 @@
use std::cell::Cell; use std::cell::Cell;
use std::ptr::{self, NonNull}; use std::ptr::{self, NonNull};
use icrate::Foundation::{NSArray, NSObject, NSSize, NSString};
use objc2::declare::{Ivar, IvarDrop}; use objc2::declare::{Ivar, IvarDrop};
use objc2::foundation::{NSArray, NSObject, NSSize, NSString}; use objc2::rc::{autoreleasepool, Id};
use objc2::rc::{autoreleasepool, Id, Shared};
use objc2::runtime::Object; 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::{ use super::appkit::{
NSApplicationPresentationOptions, NSFilenamesPboardType, NSPasteboard, NSWindowOcclusionState, NSApplicationPresentationOptions, NSFilenamesPboardType, NSPasteboard, NSWindowOcclusionState,
@ -25,7 +25,7 @@ use crate::{
}; };
#[derive(Debug)] #[derive(Debug)]
struct State { pub struct State {
// This is set when WindowBuilder::with_fullscreen was set, // This is set when WindowBuilder::with_fullscreen was set,
// see comments of `window_did_fail_to_enter_fullscreen` // see comments of `window_did_fail_to_enter_fullscreen`
initial_fullscreen: Cell<bool>, initial_fullscreen: Cell<bool>,
@ -40,26 +40,30 @@ struct State {
declare_class!( declare_class!(
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct WinitWindowDelegate { pub(crate) struct WinitWindowDelegate {
window: IvarDrop<Id<WinitWindow, Shared>>, window: IvarDrop<Id<WinitWindow>, "_window">,
// TODO: It may be possible for delegate methods to be called // TODO: It may be possible for delegate methods to be called
// asynchronously, causing data races panics? // asynchronously, causing data races panics?
// TODO: Remove unnecessary boxing here // TODO: Remove unnecessary boxing here
state: IvarDrop<Box<State>>, state: IvarDrop<Box<State>, "_state">,
} }
mod ivars;
unsafe impl ClassType for WinitWindowDelegate { unsafe impl ClassType for WinitWindowDelegate {
type Super = NSObject; type Super = NSObject;
type Mutability = mutability::InteriorMutable;
const NAME: &'static str = "WinitWindowDelegate";
} }
unsafe impl WinitWindowDelegate { unsafe impl WinitWindowDelegate {
#[sel(initWithWindow:initialFullscreen:)] #[method(initWithWindow:initialFullscreen:)]
unsafe fn init_with_winit( unsafe fn init_with_winit(
&mut self, this: *mut Self,
window: &WinitWindow, window: &WinitWindow,
initial_fullscreen: bool, initial_fullscreen: bool,
) -> Option<NonNull<Self>> { ) -> Option<NonNull<Self>> {
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.map(|this| {
let scale_factor = window.scale_factor(); let scale_factor = window.scale_factor();
@ -79,7 +83,7 @@ declare_class!(
this.window.setDelegate(Some(this)); this.window.setDelegate(Some(this));
// Enable theme change event // Enable theme change event
let notification_center: Id<Object, Shared> = let notification_center: Id<Object> =
unsafe { msg_send_id![class!(NSDistributedNotificationCenter), defaultCenter] }; unsafe { msg_send_id![class!(NSDistributedNotificationCenter), defaultCenter] };
let notification_name = let notification_name =
NSString::from_str("AppleInterfaceThemeChangedNotification"); NSString::from_str("AppleInterfaceThemeChangedNotification");
@ -100,14 +104,14 @@ declare_class!(
// NSWindowDelegate + NSDraggingDestination protocols // NSWindowDelegate + NSDraggingDestination protocols
unsafe impl WinitWindowDelegate { unsafe impl WinitWindowDelegate {
#[sel(windowShouldClose:)] #[method(windowShouldClose:)]
fn window_should_close(&self, _: Option<&Object>) -> bool { fn window_should_close(&self, _: Option<&Object>) -> bool {
trace_scope!("windowShouldClose:"); trace_scope!("windowShouldClose:");
self.queue_event(WindowEvent::CloseRequested); self.queue_event(WindowEvent::CloseRequested);
false false
} }
#[sel(windowWillClose:)] #[method(windowWillClose:)]
fn window_will_close(&self, _: Option<&Object>) { fn window_will_close(&self, _: Option<&Object>) {
trace_scope!("windowWillClose:"); trace_scope!("windowWillClose:");
// `setDelegate:` retains the previous value and then autoreleases it // `setDelegate:` retains the previous value and then autoreleases it
@ -119,14 +123,14 @@ declare_class!(
self.queue_event(WindowEvent::Destroyed); self.queue_event(WindowEvent::Destroyed);
} }
#[sel(windowDidResize:)] #[method(windowDidResize:)]
fn window_did_resize(&self, _: Option<&Object>) { fn window_did_resize(&self, _: Option<&Object>) {
trace_scope!("windowDidResize:"); trace_scope!("windowDidResize:");
// NOTE: WindowEvent::Resized is reported in frameDidChange. // NOTE: WindowEvent::Resized is reported in frameDidChange.
self.emit_move_event(); self.emit_move_event();
} }
#[sel(windowWillStartLiveResize:)] #[method(windowWillStartLiveResize:)]
fn window_will_start_live_resize(&self, _: Option<&Object>) { fn window_will_start_live_resize(&self, _: Option<&Object>) {
trace_scope!("windowWillStartLiveResize:"); trace_scope!("windowWillStartLiveResize:");
@ -137,26 +141,26 @@ declare_class!(
self.window.set_resize_increments_inner(increments); self.window.set_resize_increments_inner(increments);
} }
#[sel(windowDidEndLiveResize:)] #[method(windowDidEndLiveResize:)]
fn window_did_end_live_resize(&self, _: Option<&Object>) { fn window_did_end_live_resize(&self, _: Option<&Object>) {
trace_scope!("windowDidEndLiveResize:"); trace_scope!("windowDidEndLiveResize:");
self.window.set_resize_increments_inner(NSSize::new(1., 1.)); self.window.set_resize_increments_inner(NSSize::new(1., 1.));
} }
// This won't be triggered if the move was part of a resize. // This won't be triggered if the move was part of a resize.
#[sel(windowDidMove:)] #[method(windowDidMove:)]
fn window_did_move(&self, _: Option<&Object>) { fn window_did_move(&self, _: Option<&Object>) {
trace_scope!("windowDidMove:"); trace_scope!("windowDidMove:");
self.emit_move_event(); self.emit_move_event();
} }
#[sel(windowDidChangeBackingProperties:)] #[method(windowDidChangeBackingProperties:)]
fn window_did_change_backing_properties(&self, _: Option<&Object>) { fn window_did_change_backing_properties(&self, _: Option<&Object>) {
trace_scope!("windowDidChangeBackingProperties:"); trace_scope!("windowDidChangeBackingProperties:");
self.queue_static_scale_factor_changed_event(); self.queue_static_scale_factor_changed_event();
} }
#[sel(windowDidBecomeKey:)] #[method(windowDidBecomeKey:)]
fn window_did_become_key(&self, _: Option<&Object>) { fn window_did_become_key(&self, _: Option<&Object>) {
trace_scope!("windowDidBecomeKey:"); trace_scope!("windowDidBecomeKey:");
// TODO: center the cursor if the window had mouse grab when it // TODO: center the cursor if the window had mouse grab when it
@ -164,7 +168,7 @@ declare_class!(
self.queue_event(WindowEvent::Focused(true)); self.queue_event(WindowEvent::Focused(true));
} }
#[sel(windowDidResignKey:)] #[method(windowDidResignKey:)]
fn window_did_resign_key(&self, _: Option<&Object>) { fn window_did_resign_key(&self, _: Option<&Object>) {
trace_scope!("windowDidResignKey:"); trace_scope!("windowDidResignKey:");
// It happens rather often, e.g. when the user is Cmd+Tabbing, that the // 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 /// Invoked when the dragged image enters destination bounds or frame
#[sel(draggingEntered:)] #[method(draggingEntered:)]
fn dragging_entered(&self, sender: *mut Object) -> bool { fn dragging_entered(&self, sender: &NSObject) -> bool {
trace_scope!("draggingEntered:"); trace_scope!("draggingEntered:");
use std::path::PathBuf; use std::path::PathBuf;
let pb: Id<NSPasteboard, Shared> = unsafe { msg_send_id![sender, draggingPasteboard] }; let pb: Id<NSPasteboard> = unsafe { msg_send_id![sender, draggingPasteboard] };
let filenames = pb.propertyListForType(unsafe { NSFilenamesPboardType }); let filenames = pb.propertyListForType(unsafe { NSFilenamesPboardType });
let filenames: Id<NSArray<NSString>, Shared> = unsafe { Id::cast(filenames) }; let filenames: Id<NSArray<NSString>> = unsafe { Id::cast(filenames) };
filenames.into_iter().for_each(|file| { filenames.into_iter().for_each(|file| {
let path = PathBuf::from(file.to_string()); let path = PathBuf::from(file.to_string());
@ -199,22 +203,22 @@ declare_class!(
} }
/// Invoked when the image is released /// Invoked when the image is released
#[sel(prepareForDragOperation:)] #[method(prepareForDragOperation:)]
fn prepare_for_drag_operation(&self, _: Option<&Object>) -> bool { fn prepare_for_drag_operation(&self, _sender: &NSObject) -> bool {
trace_scope!("prepareForDragOperation:"); trace_scope!("prepareForDragOperation:");
true true
} }
/// Invoked after the released image has been removed from the screen /// Invoked after the released image has been removed from the screen
#[sel(performDragOperation:)] #[method(performDragOperation:)]
fn perform_drag_operation(&self, sender: *mut Object) -> bool { fn perform_drag_operation(&self, sender: &NSObject) -> bool {
trace_scope!("performDragOperation:"); trace_scope!("performDragOperation:");
use std::path::PathBuf; use std::path::PathBuf;
let pb: Id<NSPasteboard, Shared> = unsafe { msg_send_id![sender, draggingPasteboard] }; let pb: Id<NSPasteboard> = unsafe { msg_send_id![sender, draggingPasteboard] };
let filenames = pb.propertyListForType(unsafe { NSFilenamesPboardType }); let filenames = pb.propertyListForType(unsafe { NSFilenamesPboardType });
let filenames: Id<NSArray<NSString>, Shared> = unsafe { Id::cast(filenames) }; let filenames: Id<NSArray<NSString>> = unsafe { Id::cast(filenames) };
filenames.into_iter().for_each(|file| { filenames.into_iter().for_each(|file| {
let path = PathBuf::from(file.to_string()); let path = PathBuf::from(file.to_string());
@ -225,20 +229,20 @@ declare_class!(
} }
/// Invoked when the dragging operation is complete /// Invoked when the dragging operation is complete
#[sel(concludeDragOperation:)] #[method(concludeDragOperation:)]
fn conclude_drag_operation(&self, _: Option<&Object>) { fn conclude_drag_operation(&self, _sender: Option<&NSObject>) {
trace_scope!("concludeDragOperation:"); trace_scope!("concludeDragOperation:");
} }
/// Invoked when the dragging operation is cancelled /// Invoked when the dragging operation is cancelled
#[sel(draggingExited:)] #[method(draggingExited:)]
fn dragging_exited(&self, _: Option<&Object>) { fn dragging_exited(&self, _sender: Option<&NSObject>) {
trace_scope!("draggingExited:"); trace_scope!("draggingExited:");
self.queue_event(WindowEvent::HoveredFileCancelled); self.queue_event(WindowEvent::HoveredFileCancelled);
} }
/// Invoked when before enter fullscreen /// Invoked when before enter fullscreen
#[sel(windowWillEnterFullScreen:)] #[method(windowWillEnterFullScreen:)]
fn window_will_enter_fullscreen(&self, _: Option<&Object>) { fn window_will_enter_fullscreen(&self, _: Option<&Object>) {
trace_scope!("windowWillEnterFullScreen:"); trace_scope!("windowWillEnterFullScreen:");
@ -267,7 +271,7 @@ declare_class!(
} }
/// Invoked when before exit fullscreen /// Invoked when before exit fullscreen
#[sel(windowWillExitFullScreen:)] #[method(windowWillExitFullScreen:)]
fn window_will_exit_fullscreen(&self, _: Option<&Object>) { fn window_will_exit_fullscreen(&self, _: Option<&Object>) {
trace_scope!("windowWillExitFullScreen:"); trace_scope!("windowWillExitFullScreen:");
@ -275,7 +279,7 @@ declare_class!(
shared_state.in_fullscreen_transition = true; shared_state.in_fullscreen_transition = true;
} }
#[sel(window:willUseFullScreenPresentationOptions:)] #[method(window:willUseFullScreenPresentationOptions:)]
fn window_will_use_fullscreen_presentation_options( fn window_will_use_fullscreen_presentation_options(
&self, &self,
_: Option<&Object>, _: Option<&Object>,
@ -304,7 +308,7 @@ declare_class!(
} }
/// Invoked when entered fullscreen /// Invoked when entered fullscreen
#[sel(windowDidEnterFullScreen:)] #[method(windowDidEnterFullScreen:)]
fn window_did_enter_fullscreen(&self, _: Option<&Object>) { fn window_did_enter_fullscreen(&self, _: Option<&Object>) {
trace_scope!("windowDidEnterFullScreen:"); trace_scope!("windowDidEnterFullScreen:");
self.state.initial_fullscreen.set(false); self.state.initial_fullscreen.set(false);
@ -318,7 +322,7 @@ declare_class!(
} }
/// Invoked when exited fullscreen /// Invoked when exited fullscreen
#[sel(windowDidExitFullScreen:)] #[method(windowDidExitFullScreen:)]
fn window_did_exit_fullscreen(&self, _: Option<&Object>) { fn window_did_exit_fullscreen(&self, _: Option<&Object>) {
trace_scope!("windowDidExitFullScreen:"); trace_scope!("windowDidExitFullScreen:");
@ -348,7 +352,7 @@ declare_class!(
/// due to being in the midst of handling some other animation or user gesture. /// 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 /// 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. /// 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>) { fn window_did_fail_to_enter_fullscreen(&self, _: Option<&Object>) {
trace_scope!("windowDidFailToEnterFullScreen:"); trace_scope!("windowDidFailToEnterFullScreen:");
let mut shared_state = self let mut shared_state = self
@ -372,7 +376,7 @@ declare_class!(
} }
// Invoked when the occlusion state of the window changes // Invoked when the occlusion state of the window changes
#[sel(windowDidChangeOcclusionState:)] #[method(windowDidChangeOcclusionState:)]
fn window_did_change_occlusion_state(&self, _: Option<&Object>) { fn window_did_change_occlusion_state(&self, _: Option<&Object>) {
trace_scope!("windowDidChangeOcclusionState:"); trace_scope!("windowDidChangeOcclusionState:");
self.queue_event(WindowEvent::Occluded( self.queue_event(WindowEvent::Occluded(
@ -384,7 +388,7 @@ declare_class!(
} }
// Observe theme change // Observe theme change
#[sel(effectiveAppearanceDidChange:)] #[method(effectiveAppearanceDidChange:)]
fn effective_appearance_did_change(&self, sender: Option<&Object>) { fn effective_appearance_did_change(&self, sender: Option<&Object>) {
trace_scope!("Triggered `effectiveAppearanceDidChange:`"); trace_scope!("Triggered `effectiveAppearanceDidChange:`");
unsafe { unsafe {
@ -397,7 +401,7 @@ declare_class!(
} }
} }
#[sel(effectiveAppearanceDidChangedOnMainThread:)] #[method(effectiveAppearanceDidChangedOnMainThread:)]
fn effective_appearance_did_changed_on_main_thread(&self, _: Option<&Object>) { fn effective_appearance_did_changed_on_main_thread(&self, _: Option<&Object>) {
let theme = get_ns_theme(); let theme = get_ns_theme();
let mut shared_state = self let mut shared_state = self
@ -411,7 +415,7 @@ declare_class!(
} }
} }
#[sel(windowDidChangeScreen:)] #[method(windowDidChangeScreen:)]
fn window_did_change_screen(&self, _: Option<&Object>) { fn window_did_change_screen(&self, _: Option<&Object>) {
trace_scope!("windowDidChangeScreen:"); trace_scope!("windowDidChangeScreen:");
let is_simple_fullscreen = self let is_simple_fullscreen = self
@ -428,10 +432,10 @@ declare_class!(
); );
impl WinitWindowDelegate { impl WinitWindowDelegate {
pub fn new(window: &WinitWindow, initial_fullscreen: bool) -> Id<Self, Shared> { pub fn new(window: &WinitWindow, initial_fullscreen: bool) -> Id<Self> {
unsafe { unsafe {
msg_send_id![ msg_send_id![
msg_send_id![Self::class(), alloc], Self::alloc(),
initWithWindow: window, initWithWindow: window,
initialFullscreen: initial_fullscreen, initialFullscreen: initial_fullscreen,
] ]