Update objc2 to v0.2.2 (#3702)
- Use new `bitflags!` support. - Use `objc2-ui-kit`. - Change usage of `Id` to `Retained`.
This commit is contained in:
parent
5ea20fc905
commit
d7abe0316e
37 changed files with 332 additions and 1056 deletions
31
Cargo.toml
31
Cargo.toml
|
|
@ -108,13 +108,13 @@ ndk = { version = "0.9.0", default-features = false }
|
||||||
|
|
||||||
[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.5.1"
|
objc2 = "0.5.2"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
core-graphics = "0.23.1"
|
core-graphics = "0.23.1"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies.objc2-foundation]
|
[target.'cfg(target_os = "macos")'.dependencies.objc2-foundation]
|
||||||
version = "0.2.0"
|
version = "0.2.2"
|
||||||
features = [
|
features = [
|
||||||
"dispatch",
|
"dispatch",
|
||||||
"NSArray",
|
"NSArray",
|
||||||
|
|
@ -134,7 +134,7 @@ features = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies.objc2-app-kit]
|
[target.'cfg(target_os = "macos")'.dependencies.objc2-app-kit]
|
||||||
version = "0.2.0"
|
version = "0.2.2"
|
||||||
features = [
|
features = [
|
||||||
"NSAppearance",
|
"NSAppearance",
|
||||||
"NSApplication",
|
"NSApplication",
|
||||||
|
|
@ -164,7 +164,7 @@ features = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[target.'cfg(target_os = "ios")'.dependencies.objc2-foundation]
|
[target.'cfg(target_os = "ios")'.dependencies.objc2-foundation]
|
||||||
version = "0.2.0"
|
version = "0.2.2"
|
||||||
features = [
|
features = [
|
||||||
"dispatch",
|
"dispatch",
|
||||||
"NSArray",
|
"NSArray",
|
||||||
|
|
@ -177,6 +177,29 @@ features = [
|
||||||
"NSSet",
|
"NSSet",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "ios")'.dependencies.objc2-ui-kit]
|
||||||
|
version = "0.2.2"
|
||||||
|
features = [
|
||||||
|
"UIApplication",
|
||||||
|
"UIDevice",
|
||||||
|
"UIEvent",
|
||||||
|
"UIGeometry",
|
||||||
|
"UIGestureRecognizer",
|
||||||
|
"UIOrientation",
|
||||||
|
"UIPanGestureRecognizer",
|
||||||
|
"UIPinchGestureRecognizer",
|
||||||
|
"UIResponder",
|
||||||
|
"UIRotationGestureRecognizer",
|
||||||
|
"UIScreen",
|
||||||
|
"UIScreenMode",
|
||||||
|
"UITapGestureRecognizer",
|
||||||
|
"UITouch",
|
||||||
|
"UITraitCollection",
|
||||||
|
"UIView",
|
||||||
|
"UIViewController",
|
||||||
|
"UIWindow",
|
||||||
|
]
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
unicode-segmentation = "1.7.1"
|
unicode-segmentation = "1.7.1"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -357,7 +357,7 @@ impl MonitorHandleExtIOS for MonitorHandle {
|
||||||
fn ui_screen(&self) -> *mut c_void {
|
fn ui_screen(&self) -> *mut c_void {
|
||||||
// SAFETY: The marker is only used to get the pointer of the screen
|
// SAFETY: The marker is only used to get the pointer of the screen
|
||||||
let mtm = unsafe { objc2_foundation::MainThreadMarker::new_unchecked() };
|
let mtm = unsafe { objc2_foundation::MainThreadMarker::new_unchecked() };
|
||||||
objc2::rc::Id::as_ptr(self.inner.ui_screen(mtm)) as *mut c_void
|
objc2::rc::Retained::as_ptr(self.inner.ui_screen(mtm)) as *mut c_void
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
||||||
|
|
@ -375,7 +375,7 @@ impl MonitorHandleExtMacOS for MonitorHandle {
|
||||||
fn ns_screen(&self) -> Option<*mut c_void> {
|
fn ns_screen(&self) -> Option<*mut c_void> {
|
||||||
// SAFETY: We only use the marker to get a pointer
|
// SAFETY: We only use the marker to get a pointer
|
||||||
let mtm = unsafe { objc2_foundation::MainThreadMarker::new_unchecked() };
|
let mtm = unsafe { objc2_foundation::MainThreadMarker::new_unchecked() };
|
||||||
self.inner.ns_screen(mtm).map(|s| objc2::rc::Id::as_ptr(&s) as _)
|
self.inner.ns_screen(mtm).map(|s| objc2::rc::Retained::as_ptr(&s) as _)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use objc2::{declare_class, mutability, ClassType, DeclaredClass};
|
use objc2::{declare_class, mutability, ClassType, DeclaredClass};
|
||||||
use objc2_foundation::{MainThreadMarker, NSObject, NSObjectProtocol};
|
use objc2_foundation::{MainThreadMarker, NSObject, NSObjectProtocol};
|
||||||
|
use objc2_ui_kit::{UIApplication, UIWindow};
|
||||||
|
|
||||||
use super::app_state::{self, EventWrapper};
|
use super::app_state::{self, EventWrapper};
|
||||||
use super::uikit::{UIApplication, UIWindow};
|
|
||||||
use super::window::WinitUIWindow;
|
use super::window::WinitUIWindow;
|
||||||
use crate::event::{Event, WindowEvent};
|
use crate::event::{Event, WindowEvent};
|
||||||
use crate::window::WindowId as RootWindowId;
|
use crate::window::WindowId as RootWindowId;
|
||||||
|
|
@ -51,6 +51,7 @@ declare_class!(
|
||||||
#[method(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();
|
||||||
|
#[allow(deprecated)]
|
||||||
for window in application.windows().iter() {
|
for window in application.windows().iter() {
|
||||||
if window.is_kind_of::<WinitUIWindow>() {
|
if window.is_kind_of::<WinitUIWindow>() {
|
||||||
// SAFETY: We just checked that the window is a `winit` window
|
// SAFETY: We just checked that the window is a `winit` window
|
||||||
|
|
@ -81,6 +82,7 @@ declare_class!(
|
||||||
impl AppDelegate {
|
impl AppDelegate {
|
||||||
fn send_occluded_event_for_all_windows(&self, application: &UIApplication, occluded: bool) {
|
fn send_occluded_event_for_all_windows(&self, application: &UIApplication, occluded: bool) {
|
||||||
let mut events = Vec::new();
|
let mut events = Vec::new();
|
||||||
|
#[allow(deprecated)]
|
||||||
for window in application.windows().iter() {
|
for window in application.windows().iter() {
|
||||||
if window.is_kind_of::<WinitUIWindow>() {
|
if window.is_kind_of::<WinitUIWindow>() {
|
||||||
// SAFETY: We just checked that the window is a `winit` window
|
// SAFETY: We just checked that the window is a `winit` window
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,15 @@ use core_foundation::runloop::{
|
||||||
kCFRunLoopCommonModes, CFRunLoopAddTimer, CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate,
|
kCFRunLoopCommonModes, CFRunLoopAddTimer, CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate,
|
||||||
CFRunLoopTimerInvalidate, CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate,
|
CFRunLoopTimerInvalidate, CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate,
|
||||||
};
|
};
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Retained;
|
||||||
use objc2::runtime::AnyObject;
|
use objc2::runtime::AnyObject;
|
||||||
use objc2::{msg_send, sel};
|
use objc2::{msg_send, sel};
|
||||||
use objc2_foundation::{
|
use objc2_foundation::{
|
||||||
CGRect, CGSize, MainThreadMarker, NSInteger, NSObjectProtocol, NSOperatingSystemVersion,
|
CGRect, CGSize, MainThreadMarker, NSInteger, NSObjectProtocol, NSOperatingSystemVersion,
|
||||||
NSProcessInfo,
|
NSProcessInfo,
|
||||||
};
|
};
|
||||||
|
use objc2_ui_kit::{UICoordinateSpace, UIView};
|
||||||
|
|
||||||
use super::uikit::UIView;
|
|
||||||
use super::window::WinitUIWindow;
|
use super::window::WinitUIWindow;
|
||||||
use crate::dpi::PhysicalSize;
|
use crate::dpi::PhysicalSize;
|
||||||
use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent};
|
use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent};
|
||||||
|
|
@ -72,7 +72,7 @@ pub(crate) enum EventWrapper {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ScaleFactorChanged {
|
pub struct ScaleFactorChanged {
|
||||||
pub(super) window: Id<WinitUIWindow>,
|
pub(super) window: Retained<WinitUIWindow>,
|
||||||
pub(super) suggested_size: PhysicalSize<u32>,
|
pub(super) suggested_size: PhysicalSize<u32>,
|
||||||
pub(super) scale_factor: f64,
|
pub(super) scale_factor: f64,
|
||||||
}
|
}
|
||||||
|
|
@ -99,25 +99,25 @@ impl Event<HandlePendingUserEvents> {
|
||||||
#[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>>,
|
queued_windows: Vec<Retained<WinitUIWindow>>,
|
||||||
queued_events: Vec<EventWrapper>,
|
queued_events: Vec<EventWrapper>,
|
||||||
queued_gpu_redraws: HashSet<Id<WinitUIWindow>>,
|
queued_gpu_redraws: HashSet<Retained<WinitUIWindow>>,
|
||||||
},
|
},
|
||||||
Launching {
|
Launching {
|
||||||
queued_windows: Vec<Id<WinitUIWindow>>,
|
queued_windows: Vec<Retained<WinitUIWindow>>,
|
||||||
queued_events: Vec<EventWrapper>,
|
queued_events: Vec<EventWrapper>,
|
||||||
queued_handler: EventLoopHandler,
|
queued_handler: EventLoopHandler,
|
||||||
queued_gpu_redraws: HashSet<Id<WinitUIWindow>>,
|
queued_gpu_redraws: HashSet<Retained<WinitUIWindow>>,
|
||||||
},
|
},
|
||||||
ProcessingEvents {
|
ProcessingEvents {
|
||||||
handler: EventLoopHandler,
|
handler: EventLoopHandler,
|
||||||
queued_gpu_redraws: HashSet<Id<WinitUIWindow>>,
|
queued_gpu_redraws: HashSet<Retained<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>>,
|
queued_gpu_redraws: HashSet<Retained<WinitUIWindow>>,
|
||||||
},
|
},
|
||||||
ProcessingRedraws {
|
ProcessingRedraws {
|
||||||
handler: EventLoopHandler,
|
handler: EventLoopHandler,
|
||||||
|
|
@ -228,7 +228,9 @@ impl AppState {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn did_finish_launching_transition(&mut self) -> (Vec<Id<WinitUIWindow>>, Vec<EventWrapper>) {
|
fn did_finish_launching_transition(
|
||||||
|
&mut self,
|
||||||
|
) -> (Vec<Retained<WinitUIWindow>>, Vec<EventWrapper>) {
|
||||||
let (windows, events, handler, queued_gpu_redraws) = match self.take_state() {
|
let (windows, events, handler, queued_gpu_redraws) = match self.take_state() {
|
||||||
AppStateImpl::Launching {
|
AppStateImpl::Launching {
|
||||||
queued_windows,
|
queued_windows,
|
||||||
|
|
@ -344,7 +346,7 @@ impl AppState {
|
||||||
UserCallbackTransitionResult::Success { handler, active_control_flow, processing_redraws }
|
UserCallbackTransitionResult::Success { handler, active_control_flow, processing_redraws }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main_events_cleared_transition(&mut self) -> HashSet<Id<WinitUIWindow>> {
|
fn main_events_cleared_transition(&mut self) -> HashSet<Retained<WinitUIWindow>> {
|
||||||
let (handler, queued_gpu_redraws, active_control_flow) = match self.take_state() {
|
let (handler, queued_gpu_redraws, active_control_flow) = match self.take_state() {
|
||||||
AppStateImpl::ProcessingEvents { handler, queued_gpu_redraws, active_control_flow } => {
|
AppStateImpl::ProcessingEvents { handler, queued_gpu_redraws, active_control_flow } => {
|
||||||
(handler, queued_gpu_redraws, active_control_flow)
|
(handler, queued_gpu_redraws, active_control_flow)
|
||||||
|
|
@ -412,7 +414,7 @@ impl AppState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_key_window(mtm: MainThreadMarker, window: &Id<WinitUIWindow>) {
|
pub(crate) fn set_key_window(mtm: MainThreadMarker, window: &Retained<WinitUIWindow>) {
|
||||||
let mut this = AppState::get_mut(mtm);
|
let mut this = AppState::get_mut(mtm);
|
||||||
match this.state_mut() {
|
match this.state_mut() {
|
||||||
&mut AppStateImpl::NotLaunched { ref mut queued_windows, .. } => {
|
&mut AppStateImpl::NotLaunched { ref mut queued_windows, .. } => {
|
||||||
|
|
@ -432,7 +434,7 @@ pub(crate) fn set_key_window(mtm: MainThreadMarker, window: &Id<WinitUIWindow>)
|
||||||
window.makeKeyAndVisible();
|
window.makeKeyAndVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn queue_gl_or_metal_redraw(mtm: MainThreadMarker, window: Id<WinitUIWindow>) {
|
pub(crate) fn queue_gl_or_metal_redraw(mtm: MainThreadMarker, window: Retained<WinitUIWindow>) {
|
||||||
let mut this = AppState::get_mut(mtm);
|
let mut this = AppState::get_mut(mtm);
|
||||||
match this.state_mut() {
|
match this.state_mut() {
|
||||||
&mut AppStateImpl::NotLaunched { ref mut queued_gpu_redraws, .. }
|
&mut AppStateImpl::NotLaunched { ref mut queued_gpu_redraws, .. }
|
||||||
|
|
@ -722,7 +724,7 @@ fn handle_hidpi_proxy(handler: &mut EventLoopHandler, event: ScaleFactorChanged)
|
||||||
view.setFrame(new_frame);
|
view.setFrame(new_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_view_and_screen_frame(window: &WinitUIWindow) -> (Id<UIView>, CGRect) {
|
fn get_view_and_screen_frame(window: &WinitUIWindow) -> (Retained<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();
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::ffi::c_void;
|
use std::ffi::{c_char, c_int, c_void};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ptr;
|
use std::ptr::{self, NonNull};
|
||||||
use std::sync::mpsc::{self, Receiver, Sender};
|
use std::sync::mpsc::{self, Receiver, Sender};
|
||||||
|
|
||||||
use core_foundation::base::{CFIndex, CFRelease};
|
use core_foundation::base::{CFIndex, CFRelease};
|
||||||
|
|
@ -11,8 +11,10 @@ use core_foundation::runloop::{
|
||||||
CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext, CFRunLoopSourceCreate,
|
CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext, CFRunLoopSourceCreate,
|
||||||
CFRunLoopSourceInvalidate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp,
|
CFRunLoopSourceInvalidate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp,
|
||||||
};
|
};
|
||||||
use objc2::ClassType;
|
use objc2::rc::Retained;
|
||||||
|
use objc2::{msg_send_id, ClassType};
|
||||||
use objc2_foundation::{MainThreadMarker, NSString};
|
use objc2_foundation::{MainThreadMarker, NSString};
|
||||||
|
use objc2_ui_kit::{UIApplication, UIApplicationMain, UIDevice, UIScreen, UIUserInterfaceIdiom};
|
||||||
|
|
||||||
use crate::application::ApplicationHandler;
|
use crate::application::ApplicationHandler;
|
||||||
use crate::error::EventLoopError;
|
use crate::error::EventLoopError;
|
||||||
|
|
@ -26,7 +28,6 @@ use crate::window::{CustomCursor, CustomCursorSource};
|
||||||
|
|
||||||
use super::app_delegate::AppDelegate;
|
use super::app_delegate::AppDelegate;
|
||||||
use super::app_state::AppState;
|
use super::app_state::AppState;
|
||||||
use super::uikit::{UIApplication, UIApplicationMain, UIDevice, UIScreen, UIUserInterfaceIdiom};
|
|
||||||
use super::{app_state, monitor, MonitorHandle};
|
use super::{app_state, monitor, MonitorHandle};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -45,7 +46,8 @@ impl ActiveEventLoop {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||||
Some(MonitorHandle::new(UIScreen::main(self.mtm)))
|
#[allow(deprecated)]
|
||||||
|
Some(MonitorHandle::new(UIScreen::mainScreen(self.mtm)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -172,7 +174,8 @@ impl<T: 'static> EventLoop<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_app<A: ApplicationHandler<T>>(self, app: &mut A) -> ! {
|
pub fn run_app<A: ApplicationHandler<T>>(self, app: &mut A) -> ! {
|
||||||
let application = UIApplication::shared(self.mtm);
|
let application: Option<Retained<UIApplication>> =
|
||||||
|
unsafe { msg_send_id![UIApplication::class(), sharedApplication] };
|
||||||
assert!(
|
assert!(
|
||||||
application.is_none(),
|
application.is_none(),
|
||||||
"\
|
"\
|
||||||
|
|
@ -196,8 +199,19 @@ impl<T: 'static> EventLoop<T> {
|
||||||
// Ensure application delegate is initialized
|
// Ensure application delegate is initialized
|
||||||
let _ = AppDelegate::class();
|
let _ = AppDelegate::class();
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
// These functions are in crt_externs.h.
|
||||||
|
fn _NSGetArgc() -> *mut c_int;
|
||||||
|
fn _NSGetArgv() -> *mut *mut *mut c_char;
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
UIApplicationMain(0, ptr::null(), None, Some(&NSString::from_str(AppDelegate::NAME)))
|
UIApplicationMain(
|
||||||
|
*_NSGetArgc(),
|
||||||
|
NonNull::new(*_NSGetArgv()).unwrap(),
|
||||||
|
None,
|
||||||
|
Some(&NSString::from_str(AppDelegate::NAME)),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
@ -214,7 +228,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
// EventLoopExtIOS
|
// EventLoopExtIOS
|
||||||
impl<T: 'static> EventLoop<T> {
|
impl<T: 'static> EventLoop<T> {
|
||||||
pub fn idiom(&self) -> Idiom {
|
pub fn idiom(&self) -> Idiom {
|
||||||
match UIDevice::current(self.mtm).userInterfaceIdiom() {
|
match UIDevice::currentDevice(self.mtm).userInterfaceIdiom() {
|
||||||
UIUserInterfaceIdiom::Unspecified => Idiom::Unspecified,
|
UIUserInterfaceIdiom::Unspecified => Idiom::Unspecified,
|
||||||
UIUserInterfaceIdiom::Phone => Idiom::Phone,
|
UIUserInterfaceIdiom::Phone => Idiom::Phone,
|
||||||
UIUserInterfaceIdiom::Pad => Idiom::Pad,
|
UIUserInterfaceIdiom::Pad => Idiom::Pad,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ mod app_delegate;
|
||||||
mod app_state;
|
mod app_state;
|
||||||
mod event_loop;
|
mod event_loop;
|
||||||
mod monitor;
|
mod monitor;
|
||||||
mod uikit;
|
|
||||||
mod view;
|
mod view;
|
||||||
mod view_controller;
|
mod view_controller;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,22 @@ use std::collections::{BTreeSet, VecDeque};
|
||||||
use std::{fmt, hash, ptr};
|
use std::{fmt, hash, ptr};
|
||||||
|
|
||||||
use objc2::mutability::IsRetainable;
|
use objc2::mutability::IsRetainable;
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Retained;
|
||||||
use objc2::Message;
|
use objc2::Message;
|
||||||
use objc2_foundation::{run_on_main, MainThreadBound, MainThreadMarker, NSInteger};
|
use objc2_foundation::{run_on_main, MainThreadBound, MainThreadMarker, NSInteger};
|
||||||
|
use objc2_ui_kit::{UIScreen, UIScreenMode};
|
||||||
|
|
||||||
use super::uikit::{UIScreen, UIScreenMode};
|
|
||||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||||
use crate::monitor::VideoModeHandle as RootVideoModeHandle;
|
use crate::monitor::VideoModeHandle as RootVideoModeHandle;
|
||||||
use crate::platform_impl::platform::app_state;
|
use crate::platform_impl::platform::app_state;
|
||||||
|
|
||||||
// Workaround for `MainThreadBound` implementing almost no traits
|
// Workaround for `MainThreadBound` implementing almost no traits
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct MainThreadBoundDelegateImpls<T>(MainThreadBound<Id<T>>);
|
struct MainThreadBoundDelegateImpls<T>(MainThreadBound<Retained<T>>);
|
||||||
|
|
||||||
impl<T: IsRetainable + Message> Clone for MainThreadBoundDelegateImpls<T> {
|
impl<T: IsRetainable + Message> Clone for MainThreadBoundDelegateImpls<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self(run_on_main(|mtm| MainThreadBound::new(Id::clone(self.0.get(mtm)), mtm)))
|
Self(run_on_main(|mtm| MainThreadBound::new(Retained::clone(self.0.get(mtm)), mtm)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ impl<T: IsRetainable + Message> hash::Hash for MainThreadBoundDelegateImpls<T> {
|
||||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||||
// SAFETY: Marker only used to get the pointer
|
// SAFETY: Marker only used to get the pointer
|
||||||
let mtm = unsafe { MainThreadMarker::new_unchecked() };
|
let mtm = unsafe { MainThreadMarker::new_unchecked() };
|
||||||
Id::as_ptr(self.0.get(mtm)).hash(state);
|
Retained::as_ptr(self.0.get(mtm)).hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ impl<T: IsRetainable + Message> PartialEq for MainThreadBoundDelegateImpls<T> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
// SAFETY: Marker only used to get the pointer
|
// SAFETY: Marker only used to get the pointer
|
||||||
let mtm = unsafe { MainThreadMarker::new_unchecked() };
|
let mtm = unsafe { MainThreadMarker::new_unchecked() };
|
||||||
Id::as_ptr(self.0.get(mtm)) == Id::as_ptr(other.0.get(mtm))
|
Retained::as_ptr(self.0.get(mtm)) == Retained::as_ptr(other.0.get(mtm))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,8 +52,8 @@ pub struct VideoModeHandle {
|
||||||
|
|
||||||
impl VideoModeHandle {
|
impl VideoModeHandle {
|
||||||
fn new(
|
fn new(
|
||||||
uiscreen: Id<UIScreen>,
|
uiscreen: Retained<UIScreen>,
|
||||||
screen_mode: Id<UIScreenMode>,
|
screen_mode: Retained<UIScreenMode>,
|
||||||
mtm: MainThreadMarker,
|
mtm: MainThreadMarker,
|
||||||
) -> VideoModeHandle {
|
) -> VideoModeHandle {
|
||||||
let refresh_rate_millihertz = refresh_rate_millihertz(&uiscreen);
|
let refresh_rate_millihertz = refresh_rate_millihertz(&uiscreen);
|
||||||
|
|
@ -83,13 +83,13 @@ impl VideoModeHandle {
|
||||||
self.monitor.clone()
|
self.monitor.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn screen_mode(&self, mtm: MainThreadMarker) -> &Id<UIScreenMode> {
|
pub(super) fn screen_mode(&self, mtm: MainThreadMarker) -> &Retained<UIScreenMode> {
|
||||||
self.screen_mode.0.get(mtm)
|
self.screen_mode.0.get(mtm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MonitorHandle {
|
pub struct MonitorHandle {
|
||||||
ui_screen: MainThreadBound<Id<UIScreen>>,
|
ui_screen: MainThreadBound<Retained<UIScreen>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for MonitorHandle {
|
impl Clone for MonitorHandle {
|
||||||
|
|
@ -140,20 +140,22 @@ impl fmt::Debug for MonitorHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MonitorHandle {
|
impl MonitorHandle {
|
||||||
pub(crate) fn new(ui_screen: Id<UIScreen>) -> Self {
|
pub(crate) fn new(ui_screen: Retained<UIScreen>) -> Self {
|
||||||
// Holding `Id<UIScreen>` implies we're on the main thread.
|
// Holding `Retained<UIScreen>` implies we're on the main thread.
|
||||||
let mtm = MainThreadMarker::new().unwrap();
|
let mtm = MainThreadMarker::new().unwrap();
|
||||||
Self { ui_screen: MainThreadBound::new(ui_screen, mtm) }
|
Self { ui_screen: MainThreadBound::new(ui_screen, mtm) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
run_on_main(|mtm| {
|
run_on_main(|mtm| {
|
||||||
let main = UIScreen::main(mtm);
|
#[allow(deprecated)]
|
||||||
|
let main = UIScreen::mainScreen(mtm);
|
||||||
if *self.ui_screen(mtm) == main {
|
if *self.ui_screen(mtm) == main {
|
||||||
Some("Primary".to_string())
|
Some("Primary".to_string())
|
||||||
} else if *self.ui_screen(mtm) == main.mirroredScreen() {
|
} else if Some(self.ui_screen(mtm)) == main.mirroredScreen().as_ref() {
|
||||||
Some("Mirrored".to_string())
|
Some("Mirrored".to_string())
|
||||||
} else {
|
} else {
|
||||||
|
#[allow(deprecated)]
|
||||||
UIScreen::screens(mtm)
|
UIScreen::screens(mtm)
|
||||||
.iter()
|
.iter()
|
||||||
.position(|rhs| rhs == &**self.ui_screen(mtm))
|
.position(|rhs| rhs == &**self.ui_screen(mtm))
|
||||||
|
|
@ -197,7 +199,7 @@ impl MonitorHandle {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn ui_screen(&self, mtm: MainThreadMarker) -> &Id<UIScreen> {
|
pub(crate) fn ui_screen(&self, mtm: MainThreadMarker) -> &Retained<UIScreen> {
|
||||||
self.ui_screen.get(mtm)
|
self.ui_screen.get(mtm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -237,5 +239,6 @@ fn refresh_rate_millihertz(uiscreen: &UIScreen) -> u32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uiscreens(mtm: MainThreadMarker) -> VecDeque<MonitorHandle> {
|
pub fn uiscreens(mtm: MainThreadMarker) -> VecDeque<MonitorHandle> {
|
||||||
|
#[allow(deprecated)]
|
||||||
UIScreen::screens(mtm).into_iter().map(MonitorHandle::new).collect()
|
UIScreen::screens(mtm).into_iter().map(MonitorHandle::new).collect()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
use objc2::rc::Id;
|
|
||||||
use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
|
|
||||||
use objc2_foundation::{CGRect, MainThreadMarker, NSArray, NSObject};
|
|
||||||
|
|
||||||
use super::{UIResponder, UIWindow};
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIApplication;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIApplication {
|
|
||||||
#[inherits(NSObject)]
|
|
||||||
type Super = UIResponder;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIApplication {
|
|
||||||
pub fn shared(_mtm: MainThreadMarker) -> Option<Id<Self>> {
|
|
||||||
unsafe { msg_send_id![Self::class(), sharedApplication] }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn windows(&self) -> Id<NSArray<UIWindow>> {
|
|
||||||
unsafe { msg_send_id![self, windows] }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[method(statusBarFrame)]
|
|
||||||
pub fn statusBarFrame(&self) -> CGRect;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
use objc2::{extern_class, mutability, ClassType};
|
|
||||||
use objc2_foundation::NSObject;
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UICoordinateSpace;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UICoordinateSpace {
|
|
||||||
type Super = NSObject;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
use objc2::encode::{Encode, Encoding};
|
|
||||||
use objc2::rc::Id;
|
|
||||||
use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
|
|
||||||
use objc2_foundation::{MainThreadMarker, NSInteger, NSObject};
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIDevice;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIDevice {
|
|
||||||
type Super = NSObject;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIDevice {
|
|
||||||
pub fn current(_mtm: MainThreadMarker) -> Id<Self> {
|
|
||||||
unsafe { msg_send_id![Self::class(), currentDevice] }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[method(userInterfaceIdiom)]
|
|
||||||
pub fn userInterfaceIdiom(&self) -> UIUserInterfaceIdiom;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
||||||
pub struct UIUserInterfaceIdiom(NSInteger);
|
|
||||||
|
|
||||||
unsafe impl Encode for UIUserInterfaceIdiom {
|
|
||||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UIUserInterfaceIdiom {
|
|
||||||
pub const Unspecified: UIUserInterfaceIdiom = UIUserInterfaceIdiom(-1);
|
|
||||||
pub const Phone: UIUserInterfaceIdiom = UIUserInterfaceIdiom(0);
|
|
||||||
pub const Pad: UIUserInterfaceIdiom = UIUserInterfaceIdiom(1);
|
|
||||||
pub const TV: UIUserInterfaceIdiom = UIUserInterfaceIdiom(2);
|
|
||||||
pub const CarPlay: UIUserInterfaceIdiom = UIUserInterfaceIdiom(3);
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
use objc2::{extern_class, mutability, ClassType};
|
|
||||||
use objc2_foundation::NSObject;
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIEvent;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIEvent {
|
|
||||||
type Super = NSObject;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
use objc2::encode::{Encode, Encoding};
|
|
||||||
use objc2_foundation::NSUInteger;
|
|
||||||
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
||||||
pub struct UIRectEdge(pub NSUInteger);
|
|
||||||
|
|
||||||
impl UIRectEdge {
|
|
||||||
pub const NONE: Self = Self(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Encode for UIRectEdge {
|
|
||||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
|
||||||
}
|
|
||||||
|
|
@ -1,176 +0,0 @@
|
||||||
use objc2::encode::{Encode, Encoding};
|
|
||||||
use objc2::rc::Id;
|
|
||||||
use objc2::runtime::ProtocolObject;
|
|
||||||
use objc2::{extern_class, extern_methods, extern_protocol, mutability, ClassType, ProtocolType};
|
|
||||||
use objc2_foundation::{CGFloat, CGPoint, NSInteger, NSObject, NSObjectProtocol, NSUInteger};
|
|
||||||
|
|
||||||
use super::UIView;
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
/// [`UIGestureRecognizer`](https://developer.apple.com/documentation/uikit/uigesturerecognizer)
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIGestureRecognizer;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIGestureRecognizer {
|
|
||||||
type Super = NSObject;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIGestureRecognizer {
|
|
||||||
#[method(state)]
|
|
||||||
pub fn state(&self) -> UIGestureRecognizerState;
|
|
||||||
|
|
||||||
/// [`delegate`](https://developer.apple.com/documentation/uikit/uigesturerecognizer/1624207-delegate?language=objc)
|
|
||||||
/// @property(nullable, nonatomic, weak) id<UIGestureRecognizerDelegate> delegate;
|
|
||||||
#[method(setDelegate:)]
|
|
||||||
pub fn setDelegate(&self, delegate: &ProtocolObject<dyn UIGestureRecognizerDelegate>);
|
|
||||||
|
|
||||||
#[method_id(delegate)]
|
|
||||||
pub fn delegate(&self) -> Id<ProtocolObject<dyn UIGestureRecognizerDelegate>>;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
unsafe impl Encode for UIGestureRecognizer {
|
|
||||||
const ENCODING: Encoding = Encoding::Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
// [`UIGestureRecognizerState`](https://developer.apple.com/documentation/uikit/uigesturerecognizer/state)
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
||||||
pub struct UIGestureRecognizerState(NSInteger);
|
|
||||||
|
|
||||||
unsafe impl Encode for UIGestureRecognizerState {
|
|
||||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
impl UIGestureRecognizerState {
|
|
||||||
pub const Possible: Self = Self(0);
|
|
||||||
pub const Began: Self = Self(1);
|
|
||||||
pub const Changed: Self = Self(2);
|
|
||||||
pub const Ended: Self = Self(3);
|
|
||||||
pub const Cancelled: Self = Self(4);
|
|
||||||
pub const Failed: Self = Self(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// [`UIPinchGestureRecognizer`](https://developer.apple.com/documentation/uikit/uipinchgesturerecognizer)
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIPinchGestureRecognizer;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIPinchGestureRecognizer {
|
|
||||||
type Super = UIGestureRecognizer;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIPinchGestureRecognizer {
|
|
||||||
#[method(scale)]
|
|
||||||
pub fn scale(&self) -> CGFloat;
|
|
||||||
|
|
||||||
#[method(velocity)]
|
|
||||||
pub fn velocity(&self) -> CGFloat;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
unsafe impl Encode for UIPinchGestureRecognizer {
|
|
||||||
const ENCODING: Encoding = Encoding::Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
/// [`UIRotationGestureRecognizer`](https://developer.apple.com/documentation/uikit/uirotationgesturerecognizer)
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIRotationGestureRecognizer;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIRotationGestureRecognizer {
|
|
||||||
type Super = UIGestureRecognizer;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIRotationGestureRecognizer {
|
|
||||||
#[method(rotation)]
|
|
||||||
pub fn rotation(&self) -> CGFloat;
|
|
||||||
|
|
||||||
#[method(velocity)]
|
|
||||||
pub fn velocity(&self) -> CGFloat;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
unsafe impl Encode for UIRotationGestureRecognizer {
|
|
||||||
const ENCODING: Encoding = Encoding::Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
/// [`UITapGestureRecognizer`](https://developer.apple.com/documentation/uikit/uitapgesturerecognizer)
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UITapGestureRecognizer;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UITapGestureRecognizer {
|
|
||||||
type Super = UIGestureRecognizer;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UITapGestureRecognizer {
|
|
||||||
#[method(setNumberOfTapsRequired:)]
|
|
||||||
pub fn setNumberOfTapsRequired(&self, number_of_taps_required: NSUInteger);
|
|
||||||
|
|
||||||
#[method(setNumberOfTouchesRequired:)]
|
|
||||||
pub fn setNumberOfTouchesRequired(&self, number_of_touches_required: NSUInteger);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
unsafe impl Encode for UITapGestureRecognizer {
|
|
||||||
const ENCODING: Encoding = Encoding::Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
/// [`UIPanGestureRecognizer`](https://developer.apple.com/documentation/uikit/uipangesturerecognizer)
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIPanGestureRecognizer;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIPanGestureRecognizer {
|
|
||||||
type Super = UIGestureRecognizer;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIPanGestureRecognizer {
|
|
||||||
#[method(translationInView:)]
|
|
||||||
pub fn translationInView(&self, view: &UIView) -> CGPoint;
|
|
||||||
|
|
||||||
#[method(setTranslation:inView:)]
|
|
||||||
pub fn setTranslationInView(&self, translation: CGPoint, view: &UIView);
|
|
||||||
|
|
||||||
#[method(velocityInView:)]
|
|
||||||
pub fn velocityInView(&self, view: &UIView) -> CGPoint;
|
|
||||||
|
|
||||||
#[method(setMinimumNumberOfTouches:)]
|
|
||||||
pub fn setMinimumNumberOfTouches(&self, minimum_number_of_touches: NSUInteger);
|
|
||||||
|
|
||||||
#[method(minimumNumberOfTouches)]
|
|
||||||
pub fn minimumNumberOfTouches(&self) -> NSUInteger;
|
|
||||||
|
|
||||||
#[method(setMaximumNumberOfTouches:)]
|
|
||||||
pub fn setMaximumNumberOfTouches(&self, maximum_number_of_touches: NSUInteger);
|
|
||||||
|
|
||||||
#[method(maximumNumberOfTouches)]
|
|
||||||
pub fn maximumNumberOfTouches(&self) -> NSUInteger;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_protocol!(
|
|
||||||
/// (@protocol UIGestureRecognizerDelegate)[https://developer.apple.com/documentation/uikit/uigesturerecognizerdelegate?language=objc]
|
|
||||||
pub(crate) unsafe trait UIGestureRecognizerDelegate: NSObjectProtocol {}
|
|
||||||
|
|
||||||
unsafe impl ProtocolType for dyn UIGestureRecognizerDelegate {
|
|
||||||
const NAME: &'static str = "UIGestureRecognizerDelegate";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
#![allow(non_snake_case)]
|
|
||||||
#![allow(non_upper_case_globals)]
|
|
||||||
|
|
||||||
use std::os::raw::{c_char, c_int};
|
|
||||||
|
|
||||||
use objc2_foundation::NSString;
|
|
||||||
|
|
||||||
mod application;
|
|
||||||
mod coordinate_space;
|
|
||||||
mod device;
|
|
||||||
mod event;
|
|
||||||
mod geometry;
|
|
||||||
mod gesture_recognizer;
|
|
||||||
mod responder;
|
|
||||||
mod screen;
|
|
||||||
mod screen_mode;
|
|
||||||
mod status_bar_style;
|
|
||||||
mod touch;
|
|
||||||
mod trait_collection;
|
|
||||||
mod view;
|
|
||||||
mod view_controller;
|
|
||||||
mod window;
|
|
||||||
|
|
||||||
pub(crate) use self::application::UIApplication;
|
|
||||||
pub(crate) use self::coordinate_space::UICoordinateSpace;
|
|
||||||
pub(crate) use self::device::{UIDevice, UIUserInterfaceIdiom};
|
|
||||||
pub(crate) use self::event::UIEvent;
|
|
||||||
pub(crate) use self::geometry::UIRectEdge;
|
|
||||||
pub(crate) use self::gesture_recognizer::{
|
|
||||||
UIGestureRecognizer, UIGestureRecognizerDelegate, UIGestureRecognizerState,
|
|
||||||
UIPanGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer,
|
|
||||||
UITapGestureRecognizer,
|
|
||||||
};
|
|
||||||
pub(crate) use self::responder::UIResponder;
|
|
||||||
pub(crate) use self::screen::{UIScreen, UIScreenOverscanCompensation};
|
|
||||||
pub(crate) use self::screen_mode::UIScreenMode;
|
|
||||||
pub(crate) use self::status_bar_style::UIStatusBarStyle;
|
|
||||||
pub(crate) use self::touch::{UITouch, UITouchPhase, UITouchType};
|
|
||||||
pub(crate) use self::trait_collection::{UIForceTouchCapability, UITraitCollection};
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
pub(crate) use self::view::{UIEdgeInsets, UIView};
|
|
||||||
pub(crate) use self::view_controller::{UIInterfaceOrientationMask, UIViewController};
|
|
||||||
pub(crate) use self::window::UIWindow;
|
|
||||||
|
|
||||||
#[link(name = "UIKit", kind = "framework")]
|
|
||||||
extern "C" {
|
|
||||||
pub fn UIApplicationMain(
|
|
||||||
argc: c_int,
|
|
||||||
argv: *const c_char,
|
|
||||||
principalClassName: Option<&NSString>,
|
|
||||||
delegateClassName: Option<&NSString>,
|
|
||||||
) -> c_int;
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
use objc2::{extern_class, mutability, ClassType};
|
|
||||||
use objc2_foundation::NSObject;
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIResponder;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIResponder {
|
|
||||||
type Super = NSObject;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
use objc2::encode::{Encode, Encoding};
|
|
||||||
use objc2::rc::Id;
|
|
||||||
use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
|
|
||||||
use objc2_foundation::{CGFloat, CGRect, MainThreadMarker, NSArray, NSInteger, NSObject};
|
|
||||||
|
|
||||||
use super::{UICoordinateSpace, UIScreenMode};
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIScreen;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIScreen {
|
|
||||||
type Super = NSObject;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIScreen {
|
|
||||||
pub fn main(_mtm: MainThreadMarker) -> Id<Self> {
|
|
||||||
unsafe { msg_send_id![Self::class(), mainScreen] }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn screens(_mtm: MainThreadMarker) -> Id<NSArray<Self>> {
|
|
||||||
unsafe { msg_send_id![Self::class(), screens] }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[method(bounds)]
|
|
||||||
pub fn bounds(&self) -> CGRect;
|
|
||||||
|
|
||||||
#[method(scale)]
|
|
||||||
pub fn scale(&self) -> CGFloat;
|
|
||||||
|
|
||||||
#[method(nativeBounds)]
|
|
||||||
pub fn nativeBounds(&self) -> CGRect;
|
|
||||||
|
|
||||||
#[method(nativeScale)]
|
|
||||||
pub fn nativeScale(&self) -> CGFloat;
|
|
||||||
|
|
||||||
#[method(maximumFramesPerSecond)]
|
|
||||||
pub fn maximumFramesPerSecond(&self) -> NSInteger;
|
|
||||||
|
|
||||||
pub fn mirroredScreen(&self) -> Id<Self> {
|
|
||||||
unsafe { msg_send_id![Self::class(), mirroredScreen] }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn preferredMode(&self) -> Option<Id<UIScreenMode>> {
|
|
||||||
unsafe { msg_send_id![self, preferredMode] }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[method(setCurrentMode:)]
|
|
||||||
pub fn setCurrentMode(&self, mode: Option<&UIScreenMode>);
|
|
||||||
|
|
||||||
pub fn availableModes(&self) -> Id<NSArray<UIScreenMode>> {
|
|
||||||
unsafe { msg_send_id![self, availableModes] }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[method(setOverscanCompensation:)]
|
|
||||||
pub fn setOverscanCompensation(&self, overscanCompensation: UIScreenOverscanCompensation);
|
|
||||||
|
|
||||||
pub fn coordinateSpace(&self) -> Id<UICoordinateSpace> {
|
|
||||||
unsafe { msg_send_id![self, coordinateSpace] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
||||||
pub struct UIScreenOverscanCompensation(NSInteger);
|
|
||||||
|
|
||||||
unsafe impl Encode for UIScreenOverscanCompensation {
|
|
||||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
impl UIScreenOverscanCompensation {
|
|
||||||
pub const Scale: Self = Self(0);
|
|
||||||
pub const InsetBounds: Self = Self(1);
|
|
||||||
pub const None: Self = Self(2);
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
use objc2::{extern_class, extern_methods, mutability, ClassType};
|
|
||||||
use objc2_foundation::{CGSize, NSObject};
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIScreenMode;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIScreenMode {
|
|
||||||
type Super = NSObject;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIScreenMode {
|
|
||||||
#[method(size)]
|
|
||||||
pub fn size(&self) -> CGSize;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
use objc2::encode::{Encode, Encoding};
|
|
||||||
use objc2_foundation::NSInteger;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[repr(isize)]
|
|
||||||
pub enum UIStatusBarStyle {
|
|
||||||
#[default]
|
|
||||||
Default = 0,
|
|
||||||
LightContent = 1,
|
|
||||||
DarkContent = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Encode for UIStatusBarStyle {
|
|
||||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
|
||||||
}
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
use objc2::encode::{Encode, Encoding};
|
|
||||||
use objc2::{extern_class, extern_methods, mutability, ClassType};
|
|
||||||
use objc2_foundation::{CGFloat, CGPoint, NSInteger, NSObject};
|
|
||||||
|
|
||||||
use super::UIView;
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UITouch;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UITouch {
|
|
||||||
type Super = NSObject;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UITouch {
|
|
||||||
#[method(locationInView:)]
|
|
||||||
pub fn locationInView(&self, view: Option<&UIView>) -> CGPoint;
|
|
||||||
|
|
||||||
#[method(type)]
|
|
||||||
pub fn type_(&self) -> UITouchType;
|
|
||||||
|
|
||||||
#[method(force)]
|
|
||||||
pub fn force(&self) -> CGFloat;
|
|
||||||
|
|
||||||
#[method(maximumPossibleForce)]
|
|
||||||
pub fn maximumPossibleForce(&self) -> CGFloat;
|
|
||||||
|
|
||||||
#[method(altitudeAngle)]
|
|
||||||
pub fn altitudeAngle(&self) -> CGFloat;
|
|
||||||
|
|
||||||
#[method(phase)]
|
|
||||||
pub fn phase(&self) -> UITouchPhase;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[repr(isize)]
|
|
||||||
pub enum UITouchType {
|
|
||||||
Direct = 0,
|
|
||||||
Indirect,
|
|
||||||
Pencil,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Encode for UITouchType {
|
|
||||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[repr(isize)]
|
|
||||||
pub enum UITouchPhase {
|
|
||||||
Began = 0,
|
|
||||||
Moved,
|
|
||||||
Stationary,
|
|
||||||
Ended,
|
|
||||||
Cancelled,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Encode for UITouchPhase {
|
|
||||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
use objc2::encode::{Encode, Encoding};
|
|
||||||
use objc2::{extern_class, extern_methods, mutability, ClassType};
|
|
||||||
use objc2_foundation::{NSInteger, NSObject};
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UITraitCollection;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UITraitCollection {
|
|
||||||
type Super = NSObject;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UITraitCollection {
|
|
||||||
#[method(forceTouchCapability)]
|
|
||||||
pub fn forceTouchCapability(&self) -> UIForceTouchCapability;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[repr(isize)]
|
|
||||||
pub enum UIForceTouchCapability {
|
|
||||||
Unknown = 0,
|
|
||||||
Unavailable,
|
|
||||||
Available,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Encode for UIForceTouchCapability {
|
|
||||||
const ENCODING: Encoding = NSInteger::ENCODING;
|
|
||||||
}
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
use objc2::encode::{Encode, Encoding};
|
|
||||||
use objc2::rc::Id;
|
|
||||||
use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
|
|
||||||
use objc2_foundation::{CGFloat, CGRect, NSObject};
|
|
||||||
|
|
||||||
use super::{UICoordinateSpace, UIGestureRecognizer, UIResponder, UIViewController};
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIView;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIView {
|
|
||||||
#[inherits(NSObject)]
|
|
||||||
type Super = UIResponder;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIView {
|
|
||||||
#[method(bounds)]
|
|
||||||
pub fn bounds(&self) -> CGRect;
|
|
||||||
|
|
||||||
#[method(setBounds:)]
|
|
||||||
pub fn setBounds(&self, value: CGRect);
|
|
||||||
|
|
||||||
#[method(frame)]
|
|
||||||
pub fn frame(&self) -> CGRect;
|
|
||||||
|
|
||||||
#[method(setFrame:)]
|
|
||||||
pub fn setFrame(&self, value: CGRect);
|
|
||||||
|
|
||||||
#[method(contentScaleFactor)]
|
|
||||||
pub fn contentScaleFactor(&self) -> CGFloat;
|
|
||||||
|
|
||||||
#[method(setContentScaleFactor:)]
|
|
||||||
pub fn setContentScaleFactor(&self, val: CGFloat);
|
|
||||||
|
|
||||||
#[method(setMultipleTouchEnabled:)]
|
|
||||||
pub fn setMultipleTouchEnabled(&self, val: bool);
|
|
||||||
|
|
||||||
pub fn rootViewController(&self) -> Option<Id<UIViewController>> {
|
|
||||||
unsafe { msg_send_id![self, rootViewController] }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[method(setRootViewController:)]
|
|
||||||
pub fn setRootViewController(&self, rootViewController: Option<&UIViewController>);
|
|
||||||
|
|
||||||
#[method(convertRect:toCoordinateSpace:)]
|
|
||||||
pub fn convertRect_toCoordinateSpace(
|
|
||||||
&self,
|
|
||||||
rect: CGRect,
|
|
||||||
coordinateSpace: &UICoordinateSpace,
|
|
||||||
) -> CGRect;
|
|
||||||
|
|
||||||
#[method(convertRect:fromCoordinateSpace:)]
|
|
||||||
pub fn convertRect_fromCoordinateSpace(
|
|
||||||
&self,
|
|
||||||
rect: CGRect,
|
|
||||||
coordinateSpace: &UICoordinateSpace,
|
|
||||||
) -> CGRect;
|
|
||||||
|
|
||||||
#[method(safeAreaInsets)]
|
|
||||||
pub fn safeAreaInsets(&self) -> UIEdgeInsets;
|
|
||||||
|
|
||||||
#[method(setNeedsDisplay)]
|
|
||||||
pub fn setNeedsDisplay(&self);
|
|
||||||
|
|
||||||
#[method(addGestureRecognizer:)]
|
|
||||||
pub fn addGestureRecognizer(&self, gestureRecognizer: &UIGestureRecognizer);
|
|
||||||
|
|
||||||
#[method(removeGestureRecognizer:)]
|
|
||||||
pub fn removeGestureRecognizer(&self, gestureRecognizer: &UIGestureRecognizer);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct UIEdgeInsets {
|
|
||||||
pub top: CGFloat,
|
|
||||||
pub left: CGFloat,
|
|
||||||
pub bottom: CGFloat,
|
|
||||||
pub right: CGFloat,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Encode for UIEdgeInsets {
|
|
||||||
const ENCODING: Encoding = Encoding::Struct("UIEdgeInsets", &[
|
|
||||||
CGFloat::ENCODING,
|
|
||||||
CGFloat::ENCODING,
|
|
||||||
CGFloat::ENCODING,
|
|
||||||
CGFloat::ENCODING,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
use objc2::encode::{Encode, Encoding};
|
|
||||||
use objc2::rc::Id;
|
|
||||||
use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
|
|
||||||
use objc2_foundation::{NSObject, NSUInteger};
|
|
||||||
|
|
||||||
use super::{UIResponder, UIView};
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIViewController;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIViewController {
|
|
||||||
#[inherits(NSObject)]
|
|
||||||
type Super = UIResponder;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIViewController {
|
|
||||||
#[method(attemptRotationToDeviceOrientation)]
|
|
||||||
pub fn attemptRotationToDeviceOrientation();
|
|
||||||
|
|
||||||
#[method(setNeedsStatusBarAppearanceUpdate)]
|
|
||||||
pub fn setNeedsStatusBarAppearanceUpdate(&self);
|
|
||||||
|
|
||||||
#[method(setNeedsUpdateOfHomeIndicatorAutoHidden)]
|
|
||||||
pub fn setNeedsUpdateOfHomeIndicatorAutoHidden(&self);
|
|
||||||
|
|
||||||
#[method(setNeedsUpdateOfScreenEdgesDeferringSystemGestures)]
|
|
||||||
pub fn setNeedsUpdateOfScreenEdgesDeferringSystemGestures(&self);
|
|
||||||
|
|
||||||
pub fn view(&self) -> Option<Id<UIView>> {
|
|
||||||
unsafe { msg_send_id![self, view] }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[method(setView:)]
|
|
||||||
pub fn setView(&self, view: Option<&UIView>);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
bitflags::bitflags! {
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub struct UIInterfaceOrientationMask: NSUInteger {
|
|
||||||
const Portrait = 1 << 1;
|
|
||||||
const PortraitUpsideDown = 1 << 2;
|
|
||||||
const LandscapeRight = 1 << 3;
|
|
||||||
const LandscapeLeft = 1 << 4;
|
|
||||||
const Landscape = Self::LandscapeLeft.bits() | Self::LandscapeRight.bits();
|
|
||||||
const AllButUpsideDown = Self::Landscape.bits() | Self::Portrait.bits();
|
|
||||||
const All = Self::AllButUpsideDown.bits() | Self::PortraitUpsideDown.bits();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Encode for UIInterfaceOrientationMask {
|
|
||||||
const ENCODING: Encoding = NSUInteger::ENCODING;
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
use objc2::rc::Id;
|
|
||||||
use objc2::{extern_class, extern_methods, msg_send_id, mutability, ClassType};
|
|
||||||
use objc2_foundation::NSObject;
|
|
||||||
|
|
||||||
use super::{UIResponder, UIScreen, UIView};
|
|
||||||
|
|
||||||
extern_class!(
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub(crate) struct UIWindow;
|
|
||||||
|
|
||||||
unsafe impl ClassType for UIWindow {
|
|
||||||
#[inherits(UIResponder, NSObject)]
|
|
||||||
type Super = UIView;
|
|
||||||
type Mutability = mutability::InteriorMutable;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
unsafe impl UIWindow {
|
|
||||||
pub fn screen(&self) -> Id<UIScreen> {
|
|
||||||
unsafe { msg_send_id![self, screen] }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[method(setScreen:)]
|
|
||||||
pub fn setScreen(&self, screen: &UIScreen);
|
|
||||||
|
|
||||||
#[method(setHidden:)]
|
|
||||||
pub fn setHidden(&self, flag: bool);
|
|
||||||
|
|
||||||
#[method(makeKeyAndVisible)]
|
|
||||||
pub fn makeKeyAndVisible(&self);
|
|
||||||
|
|
||||||
#[method(isKeyWindow)]
|
|
||||||
pub fn isKeyWindow(&self) -> bool;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
@ -1,20 +1,18 @@
|
||||||
#![allow(clippy::unnecessary_cast)]
|
#![allow(clippy::unnecessary_cast)]
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Retained;
|
||||||
use objc2::runtime::{AnyClass, NSObjectProtocol, ProtocolObject};
|
use objc2::runtime::{NSObjectProtocol, ProtocolObject};
|
||||||
use objc2::{
|
use objc2::{declare_class, msg_send, msg_send_id, mutability, sel, ClassType, DeclaredClass};
|
||||||
declare_class, extern_methods, msg_send, msg_send_id, mutability, sel, ClassType, DeclaredClass,
|
|
||||||
};
|
|
||||||
use objc2_foundation::{CGFloat, CGPoint, CGRect, MainThreadMarker, NSObject, NSSet};
|
use objc2_foundation::{CGFloat, CGPoint, CGRect, MainThreadMarker, NSObject, NSSet};
|
||||||
|
use objc2_ui_kit::{
|
||||||
|
UICoordinateSpace, UIEvent, UIForceTouchCapability, UIGestureRecognizer,
|
||||||
|
UIGestureRecognizerDelegate, UIGestureRecognizerState, UIPanGestureRecognizer,
|
||||||
|
UIPinchGestureRecognizer, UIResponder, UIRotationGestureRecognizer, UITapGestureRecognizer,
|
||||||
|
UITouch, UITouchPhase, UITouchType, UITraitEnvironment, UIView,
|
||||||
|
};
|
||||||
|
|
||||||
use super::app_state::{self, EventWrapper};
|
use super::app_state::{self, EventWrapper};
|
||||||
use super::uikit::{
|
|
||||||
UIEvent, UIForceTouchCapability, UIGestureRecognizer, UIGestureRecognizerDelegate,
|
|
||||||
UIGestureRecognizerState, UIPanGestureRecognizer, UIPinchGestureRecognizer, UIResponder,
|
|
||||||
UIRotationGestureRecognizer, UITapGestureRecognizer, UITouch, UITouchPhase, UITouchType,
|
|
||||||
UITraitCollection, UIView,
|
|
||||||
};
|
|
||||||
use super::window::WinitUIWindow;
|
use super::window::WinitUIWindow;
|
||||||
use crate::dpi::PhysicalPosition;
|
use crate::dpi::PhysicalPosition;
|
||||||
use crate::event::{Event, Force, Touch, TouchPhase, WindowEvent};
|
use crate::event::{Event, Force, Touch, TouchPhase, WindowEvent};
|
||||||
|
|
@ -22,10 +20,10 @@ use crate::platform_impl::platform::DEVICE_ID;
|
||||||
use crate::window::{WindowAttributes, WindowId as RootWindowId};
|
use crate::window::{WindowAttributes, WindowId as RootWindowId};
|
||||||
|
|
||||||
pub struct WinitViewState {
|
pub struct WinitViewState {
|
||||||
pinch_gesture_recognizer: RefCell<Option<Id<UIPinchGestureRecognizer>>>,
|
pinch_gesture_recognizer: RefCell<Option<Retained<UIPinchGestureRecognizer>>>,
|
||||||
doubletap_gesture_recognizer: RefCell<Option<Id<UITapGestureRecognizer>>>,
|
doubletap_gesture_recognizer: RefCell<Option<Retained<UITapGestureRecognizer>>>,
|
||||||
rotation_gesture_recognizer: RefCell<Option<Id<UIRotationGestureRecognizer>>>,
|
rotation_gesture_recognizer: RefCell<Option<Retained<UIRotationGestureRecognizer>>>,
|
||||||
pan_gesture_recognizer: RefCell<Option<Id<UIPanGestureRecognizer>>>,
|
pan_gesture_recognizer: RefCell<Option<Retained<UIPanGestureRecognizer>>>,
|
||||||
|
|
||||||
// for iOS delta references the start of the Gesture
|
// for iOS delta references the start of the Gesture
|
||||||
rotation_last_delta: Cell<CGFloat>,
|
rotation_last_delta: Cell<CGFloat>,
|
||||||
|
|
@ -39,7 +37,7 @@ declare_class!(
|
||||||
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;
|
type Mutability = mutability::MainThreadOnly;
|
||||||
const NAME: &'static str = "WinitUIView";
|
const NAME: &'static str = "WinitUIView";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,7 +268,7 @@ declare_class!(
|
||||||
fn pan_gesture(&self, recognizer: &UIPanGestureRecognizer) {
|
fn pan_gesture(&self, recognizer: &UIPanGestureRecognizer) {
|
||||||
let window = self.window().unwrap();
|
let window = self.window().unwrap();
|
||||||
|
|
||||||
let translation = recognizer.translationInView(self);
|
let translation = recognizer.translationInView(Some(self));
|
||||||
|
|
||||||
let (phase, dx, dy) = match recognizer.state() {
|
let (phase, dx, dy) = match recognizer.state() {
|
||||||
UIGestureRecognizerState::Began => {
|
UIGestureRecognizerState::Began => {
|
||||||
|
|
@ -328,30 +326,13 @@ declare_class!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
extern_methods!(
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
unsafe impl WinitView {
|
|
||||||
fn window(&self) -> Option<Id<WinitUIWindow>> {
|
|
||||||
unsafe { msg_send_id![self, window] }
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn traitCollection(&self) -> Id<UITraitCollection> {
|
|
||||||
msg_send_id![self, traitCollection]
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Allow the user to customize this
|
|
||||||
#[method(layerClass)]
|
|
||||||
pub(crate) fn layerClass() -> &'static AnyClass;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
impl WinitView {
|
impl WinitView {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
_mtm: MainThreadMarker,
|
mtm: MainThreadMarker,
|
||||||
window_attributes: &WindowAttributes,
|
window_attributes: &WindowAttributes,
|
||||||
frame: CGRect,
|
frame: CGRect,
|
||||||
) -> Id<Self> {
|
) -> Retained<Self> {
|
||||||
let this = Self::alloc().set_ivars(WinitViewState {
|
let this = mtm.alloc().set_ivars(WinitViewState {
|
||||||
pinch_gesture_recognizer: RefCell::new(None),
|
pinch_gesture_recognizer: RefCell::new(None),
|
||||||
doubletap_gesture_recognizer: RefCell::new(None),
|
doubletap_gesture_recognizer: RefCell::new(None),
|
||||||
rotation_gesture_recognizer: RefCell::new(None),
|
rotation_gesture_recognizer: RefCell::new(None),
|
||||||
|
|
@ -361,7 +342,7 @@ impl WinitView {
|
||||||
pinch_last_delta: Cell::new(0.0),
|
pinch_last_delta: Cell::new(0.0),
|
||||||
pan_last_delta: Cell::new(CGPoint { x: 0.0, y: 0.0 }),
|
pan_last_delta: Cell::new(CGPoint { x: 0.0, y: 0.0 }),
|
||||||
});
|
});
|
||||||
let this: Id<Self> = unsafe { msg_send_id![super(this), initWithFrame: frame] };
|
let this: Retained<Self> = unsafe { msg_send_id![super(this), initWithFrame: frame] };
|
||||||
|
|
||||||
this.setMultipleTouchEnabled(true);
|
this.setMultipleTouchEnabled(true);
|
||||||
|
|
||||||
|
|
@ -372,13 +353,23 @@ impl WinitView {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn window(&self) -> Option<Retained<WinitUIWindow>> {
|
||||||
|
// SAFETY: `WinitView`s are always installed in a `WinitUIWindow`
|
||||||
|
(**self).window().map(|window| unsafe { Retained::cast(window) })
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn recognize_pinch_gesture(&self, should_recognize: bool) {
|
pub(crate) fn recognize_pinch_gesture(&self, should_recognize: bool) {
|
||||||
|
let mtm = MainThreadMarker::from(self);
|
||||||
if should_recognize {
|
if should_recognize {
|
||||||
if self.ivars().pinch_gesture_recognizer.borrow().is_none() {
|
if self.ivars().pinch_gesture_recognizer.borrow().is_none() {
|
||||||
let pinch: Id<UIPinchGestureRecognizer> = unsafe {
|
let pinch = unsafe {
|
||||||
msg_send_id![UIPinchGestureRecognizer::alloc(), initWithTarget: self, action: sel!(pinchGesture:)]
|
UIPinchGestureRecognizer::initWithTarget_action(
|
||||||
|
mtm.alloc(),
|
||||||
|
Some(self),
|
||||||
|
Some(sel!(pinchGesture:)),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
pinch.setDelegate(ProtocolObject::from_ref(self));
|
pinch.setDelegate(Some(ProtocolObject::from_ref(self)));
|
||||||
self.addGestureRecognizer(&pinch);
|
self.addGestureRecognizer(&pinch);
|
||||||
self.ivars().pinch_gesture_recognizer.replace(Some(pinch));
|
self.ivars().pinch_gesture_recognizer.replace(Some(pinch));
|
||||||
}
|
}
|
||||||
|
|
@ -393,12 +384,17 @@ impl WinitView {
|
||||||
minimum_number_of_touches: u8,
|
minimum_number_of_touches: u8,
|
||||||
maximum_number_of_touches: u8,
|
maximum_number_of_touches: u8,
|
||||||
) {
|
) {
|
||||||
|
let mtm = MainThreadMarker::from(self);
|
||||||
if should_recognize {
|
if should_recognize {
|
||||||
if self.ivars().pan_gesture_recognizer.borrow().is_none() {
|
if self.ivars().pan_gesture_recognizer.borrow().is_none() {
|
||||||
let pan: Id<UIPanGestureRecognizer> = unsafe {
|
let pan = unsafe {
|
||||||
msg_send_id![UIPanGestureRecognizer::alloc(), initWithTarget: self, action: sel!(panGesture:)]
|
UIPanGestureRecognizer::initWithTarget_action(
|
||||||
|
mtm.alloc(),
|
||||||
|
Some(self),
|
||||||
|
Some(sel!(panGesture:)),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
pan.setDelegate(ProtocolObject::from_ref(self));
|
pan.setDelegate(Some(ProtocolObject::from_ref(self)));
|
||||||
pan.setMinimumNumberOfTouches(minimum_number_of_touches as _);
|
pan.setMinimumNumberOfTouches(minimum_number_of_touches as _);
|
||||||
pan.setMaximumNumberOfTouches(maximum_number_of_touches as _);
|
pan.setMaximumNumberOfTouches(maximum_number_of_touches as _);
|
||||||
self.addGestureRecognizer(&pan);
|
self.addGestureRecognizer(&pan);
|
||||||
|
|
@ -410,12 +406,17 @@ impl WinitView {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn recognize_doubletap_gesture(&self, should_recognize: bool) {
|
pub(crate) fn recognize_doubletap_gesture(&self, should_recognize: bool) {
|
||||||
|
let mtm = MainThreadMarker::from(self);
|
||||||
if should_recognize {
|
if should_recognize {
|
||||||
if self.ivars().doubletap_gesture_recognizer.borrow().is_none() {
|
if self.ivars().doubletap_gesture_recognizer.borrow().is_none() {
|
||||||
let tap: Id<UITapGestureRecognizer> = unsafe {
|
let tap = unsafe {
|
||||||
msg_send_id![UITapGestureRecognizer::alloc(), initWithTarget: self, action: sel!(doubleTapGesture:)]
|
UITapGestureRecognizer::initWithTarget_action(
|
||||||
|
mtm.alloc(),
|
||||||
|
Some(self),
|
||||||
|
Some(sel!(doubleTapGesture:)),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
tap.setDelegate(ProtocolObject::from_ref(self));
|
tap.setDelegate(Some(ProtocolObject::from_ref(self)));
|
||||||
tap.setNumberOfTapsRequired(2);
|
tap.setNumberOfTapsRequired(2);
|
||||||
tap.setNumberOfTouchesRequired(1);
|
tap.setNumberOfTouchesRequired(1);
|
||||||
self.addGestureRecognizer(&tap);
|
self.addGestureRecognizer(&tap);
|
||||||
|
|
@ -427,12 +428,17 @@ impl WinitView {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn recognize_rotation_gesture(&self, should_recognize: bool) {
|
pub(crate) fn recognize_rotation_gesture(&self, should_recognize: bool) {
|
||||||
|
let mtm = MainThreadMarker::from(self);
|
||||||
if should_recognize {
|
if should_recognize {
|
||||||
if self.ivars().rotation_gesture_recognizer.borrow().is_none() {
|
if self.ivars().rotation_gesture_recognizer.borrow().is_none() {
|
||||||
let rotation: Id<UIRotationGestureRecognizer> = unsafe {
|
let rotation = unsafe {
|
||||||
msg_send_id![UIRotationGestureRecognizer::alloc(), initWithTarget: self, action: sel!(rotationGesture:)]
|
UIRotationGestureRecognizer::initWithTarget_action(
|
||||||
|
mtm.alloc(),
|
||||||
|
Some(self),
|
||||||
|
Some(sel!(rotationGesture:)),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
rotation.setDelegate(ProtocolObject::from_ref(self));
|
rotation.setDelegate(Some(ProtocolObject::from_ref(self)));
|
||||||
self.addGestureRecognizer(&rotation);
|
self.addGestureRecognizer(&rotation);
|
||||||
self.ivars().rotation_gesture_recognizer.replace(Some(rotation));
|
self.ivars().rotation_gesture_recognizer.replace(Some(rotation));
|
||||||
}
|
}
|
||||||
|
|
@ -447,9 +453,9 @@ impl WinitView {
|
||||||
let os_supports_force = app_state::os_capabilities().force_touch;
|
let os_supports_force = app_state::os_capabilities().force_touch;
|
||||||
for touch in touches {
|
for touch in touches {
|
||||||
let logical_location = touch.locationInView(None);
|
let logical_location = touch.locationInView(None);
|
||||||
let touch_type = touch.type_();
|
let touch_type = touch.r#type();
|
||||||
let force = if os_supports_force {
|
let force = if os_supports_force {
|
||||||
let trait_collection = unsafe { self.traitCollection() };
|
let trait_collection = self.traitCollection();
|
||||||
let touch_capability = trait_collection.forceTouchCapability();
|
let touch_capability = trait_collection.forceTouchCapability();
|
||||||
// Both the OS _and_ the device need to be checked for force touch support.
|
// Both the OS _and_ the device need to be checked for force touch support.
|
||||||
if touch_capability == UIForceTouchCapability::Available
|
if touch_capability == UIForceTouchCapability::Available
|
||||||
|
|
@ -482,7 +488,7 @@ impl WinitView {
|
||||||
// 2 is UITouchPhase::Stationary and is not expected here
|
// 2 is UITouchPhase::Stationary and is not expected here
|
||||||
UITouchPhase::Ended => TouchPhase::Ended,
|
UITouchPhase::Ended => TouchPhase::Ended,
|
||||||
UITouchPhase::Cancelled => TouchPhase::Cancelled,
|
UITouchPhase::Cancelled => TouchPhase::Cancelled,
|
||||||
_ => panic!("unexpected touch phase: {:?}", phase as i32),
|
_ => panic!("unexpected touch phase: {phase:?}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let physical_location = {
|
let physical_location = {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Retained;
|
||||||
use objc2::{declare_class, msg_send_id, mutability, ClassType, DeclaredClass};
|
use objc2::{declare_class, msg_send_id, mutability, ClassType, DeclaredClass};
|
||||||
use objc2_foundation::{MainThreadMarker, NSObject};
|
use objc2_foundation::{MainThreadMarker, NSObject};
|
||||||
|
use objc2_ui_kit::{
|
||||||
use super::app_state::{self};
|
|
||||||
use super::uikit::{
|
|
||||||
UIDevice, UIInterfaceOrientationMask, UIRectEdge, UIResponder, UIStatusBarStyle,
|
UIDevice, UIInterfaceOrientationMask, UIRectEdge, UIResponder, UIStatusBarStyle,
|
||||||
UIUserInterfaceIdiom, UIView, UIViewController,
|
UIUserInterfaceIdiom, UIView, UIViewController,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::app_state::{self};
|
||||||
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations};
|
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations};
|
||||||
use crate::window::WindowAttributes;
|
use crate::window::WindowAttributes;
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ declare_class!(
|
||||||
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;
|
type Mutability = mutability::MainThreadOnly;
|
||||||
const NAME: &'static str = "WinitUIViewController";
|
const NAME: &'static str = "WinitUIViewController";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ impl WinitViewController {
|
||||||
mtm: MainThreadMarker,
|
mtm: MainThreadMarker,
|
||||||
valid_orientations: ValidOrientations,
|
valid_orientations: ValidOrientations,
|
||||||
) {
|
) {
|
||||||
let mask = match (valid_orientations, UIDevice::current(mtm).userInterfaceIdiom()) {
|
let mask = match (valid_orientations, UIDevice::currentDevice(mtm).userInterfaceIdiom()) {
|
||||||
(ValidOrientations::LandscapeAndPortrait, UIUserInterfaceIdiom::Phone) => {
|
(ValidOrientations::LandscapeAndPortrait, UIUserInterfaceIdiom::Phone) => {
|
||||||
UIInterfaceOrientationMask::AllButUpsideDown
|
UIInterfaceOrientationMask::AllButUpsideDown
|
||||||
},
|
},
|
||||||
|
|
@ -129,23 +129,24 @@ impl WinitViewController {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
self.ivars().supported_orientations.set(mask);
|
self.ivars().supported_orientations.set(mask);
|
||||||
UIViewController::attemptRotationToDeviceOrientation();
|
#[allow(deprecated)]
|
||||||
|
UIViewController::attemptRotationToDeviceOrientation(mtm);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
mtm: MainThreadMarker,
|
mtm: MainThreadMarker,
|
||||||
window_attributes: &WindowAttributes,
|
window_attributes: &WindowAttributes,
|
||||||
view: &UIView,
|
view: &UIView,
|
||||||
) -> Id<Self> {
|
) -> Retained<Self> {
|
||||||
// These are set properly below, we just to set them to something in the meantime.
|
// These are set properly below, we just to set them to something in the meantime.
|
||||||
let this = Self::alloc().set_ivars(ViewControllerState {
|
let this = mtm.alloc().set_ivars(ViewControllerState {
|
||||||
prefers_status_bar_hidden: Cell::new(false),
|
prefers_status_bar_hidden: Cell::new(false),
|
||||||
preferred_status_bar_style: Cell::new(UIStatusBarStyle::Default),
|
preferred_status_bar_style: Cell::new(UIStatusBarStyle::Default),
|
||||||
prefers_home_indicator_auto_hidden: Cell::new(false),
|
prefers_home_indicator_auto_hidden: Cell::new(false),
|
||||||
supported_orientations: Cell::new(UIInterfaceOrientationMask::All),
|
supported_orientations: Cell::new(UIInterfaceOrientationMask::All),
|
||||||
preferred_screen_edges_deferring_system_gestures: Cell::new(UIRectEdge::NONE),
|
preferred_screen_edges_deferring_system_gestures: Cell::new(UIRectEdge::empty()),
|
||||||
});
|
});
|
||||||
let this: Id<Self> = unsafe { msg_send_id![super(this), init] };
|
let this: Retained<Self> = unsafe { msg_send_id![super(this), init] };
|
||||||
|
|
||||||
this.set_prefers_status_bar_hidden(
|
this.set_prefers_status_bar_hidden(
|
||||||
window_attributes.platform_specific.prefers_status_bar_hidden,
|
window_attributes.platform_specific.prefers_status_bar_hidden,
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,19 @@
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Retained;
|
||||||
use objc2::runtime::{AnyObject, NSObject};
|
use objc2::runtime::{AnyObject, NSObject};
|
||||||
use objc2::{class, declare_class, msg_send, msg_send_id, mutability, ClassType, DeclaredClass};
|
use objc2::{class, declare_class, msg_send, msg_send_id, mutability, ClassType, DeclaredClass};
|
||||||
use objc2_foundation::{
|
use objc2_foundation::{
|
||||||
CGFloat, CGPoint, CGRect, CGSize, MainThreadBound, MainThreadMarker, NSObjectProtocol,
|
CGFloat, CGPoint, CGRect, CGSize, MainThreadBound, MainThreadMarker, NSObjectProtocol,
|
||||||
};
|
};
|
||||||
|
use objc2_ui_kit::{
|
||||||
|
UIApplication, UICoordinateSpace, UIResponder, UIScreen, UIScreenOverscanCompensation,
|
||||||
|
UIViewController, UIWindow,
|
||||||
|
};
|
||||||
use tracing::{debug, warn};
|
use tracing::{debug, warn};
|
||||||
|
|
||||||
use super::app_state::EventWrapper;
|
use super::app_state::EventWrapper;
|
||||||
use super::uikit::{
|
|
||||||
UIApplication, UIResponder, UIScreen, UIScreenOverscanCompensation, UIViewController, UIWindow,
|
|
||||||
};
|
|
||||||
use super::view::WinitView;
|
use super::view::WinitView;
|
||||||
use super::view_controller::WinitViewController;
|
use super::view_controller::WinitViewController;
|
||||||
use crate::cursor::Cursor;
|
use crate::cursor::Cursor;
|
||||||
|
|
@ -37,7 +38,7 @@ declare_class!(
|
||||||
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;
|
type Mutability = mutability::MainThreadOnly;
|
||||||
const NAME: &'static str = "WinitUIWindow";
|
const NAME: &'static str = "WinitUIWindow";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,8 +79,8 @@ impl WinitUIWindow {
|
||||||
window_attributes: &WindowAttributes,
|
window_attributes: &WindowAttributes,
|
||||||
frame: CGRect,
|
frame: CGRect,
|
||||||
view_controller: &UIViewController,
|
view_controller: &UIViewController,
|
||||||
) -> Id<Self> {
|
) -> Retained<Self> {
|
||||||
let this: Id<Self> = unsafe { msg_send_id![Self::alloc(), initWithFrame: frame] };
|
let this: Retained<Self> = unsafe { msg_send_id![mtm.alloc(), initWithFrame: frame] };
|
||||||
|
|
||||||
this.setRootViewController(Some(view_controller));
|
this.setRootViewController(Some(view_controller));
|
||||||
|
|
||||||
|
|
@ -106,9 +107,9 @@ impl WinitUIWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Inner {
|
pub struct Inner {
|
||||||
window: Id<WinitUIWindow>,
|
window: Retained<WinitUIWindow>,
|
||||||
view_controller: Id<WinitViewController>,
|
view_controller: Retained<WinitViewController>,
|
||||||
view: Id<WinitView>,
|
view: Retained<WinitView>,
|
||||||
gl_or_metal_backed: bool,
|
gl_or_metal_backed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,7 +397,8 @@ impl Inner {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||||
Some(MonitorHandle::new(UIScreen::main(MainThreadMarker::new().unwrap())))
|
#[allow(deprecated)]
|
||||||
|
Some(MonitorHandle::new(UIScreen::mainScreen(MainThreadMarker::new().unwrap())))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn id(&self) -> WindowId {
|
pub fn id(&self) -> WindowId {
|
||||||
|
|
@ -406,18 +408,18 @@ impl Inner {
|
||||||
#[cfg(feature = "rwh_04")]
|
#[cfg(feature = "rwh_04")]
|
||||||
pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle {
|
pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle {
|
||||||
let mut window_handle = rwh_04::UiKitHandle::empty();
|
let mut window_handle = rwh_04::UiKitHandle::empty();
|
||||||
window_handle.ui_window = Id::as_ptr(&self.window) as _;
|
window_handle.ui_window = Retained::as_ptr(&self.window) as _;
|
||||||
window_handle.ui_view = Id::as_ptr(&self.view) as _;
|
window_handle.ui_view = Retained::as_ptr(&self.view) as _;
|
||||||
window_handle.ui_view_controller = Id::as_ptr(&self.view_controller) as _;
|
window_handle.ui_view_controller = Retained::as_ptr(&self.view_controller) as _;
|
||||||
rwh_04::RawWindowHandle::UiKit(window_handle)
|
rwh_04::RawWindowHandle::UiKit(window_handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rwh_05")]
|
#[cfg(feature = "rwh_05")]
|
||||||
pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle {
|
pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle {
|
||||||
let mut window_handle = rwh_05::UiKitWindowHandle::empty();
|
let mut window_handle = rwh_05::UiKitWindowHandle::empty();
|
||||||
window_handle.ui_window = Id::as_ptr(&self.window) as _;
|
window_handle.ui_window = Retained::as_ptr(&self.window) as _;
|
||||||
window_handle.ui_view = Id::as_ptr(&self.view) as _;
|
window_handle.ui_view = Retained::as_ptr(&self.view) as _;
|
||||||
window_handle.ui_view_controller = Id::as_ptr(&self.view_controller) as _;
|
window_handle.ui_view_controller = Retained::as_ptr(&self.view_controller) as _;
|
||||||
rwh_05::RawWindowHandle::UiKit(window_handle)
|
rwh_05::RawWindowHandle::UiKit(window_handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -429,11 +431,11 @@ impl Inner {
|
||||||
#[cfg(feature = "rwh_06")]
|
#[cfg(feature = "rwh_06")]
|
||||||
pub fn raw_window_handle_rwh_06(&self) -> rwh_06::RawWindowHandle {
|
pub fn raw_window_handle_rwh_06(&self) -> rwh_06::RawWindowHandle {
|
||||||
let mut window_handle = rwh_06::UiKitWindowHandle::new({
|
let mut window_handle = rwh_06::UiKitWindowHandle::new({
|
||||||
let ui_view = Id::as_ptr(&self.view) as _;
|
let ui_view = Retained::as_ptr(&self.view) as _;
|
||||||
std::ptr::NonNull::new(ui_view).expect("Id<T> should never be null")
|
std::ptr::NonNull::new(ui_view).expect("Retained<T> should never be null")
|
||||||
});
|
});
|
||||||
window_handle.ui_view_controller =
|
window_handle.ui_view_controller =
|
||||||
std::ptr::NonNull::new(Id::as_ptr(&self.view_controller) as _);
|
std::ptr::NonNull::new(Retained::as_ptr(&self.view_controller) as _);
|
||||||
rwh_06::RawWindowHandle::UiKit(window_handle)
|
rwh_06::RawWindowHandle::UiKit(window_handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -483,7 +485,8 @@ impl Window {
|
||||||
|
|
||||||
// TODO: transparency, visible
|
// TODO: transparency, visible
|
||||||
|
|
||||||
let main_screen = UIScreen::main(mtm);
|
#[allow(deprecated)]
|
||||||
|
let main_screen = UIScreen::mainScreen(mtm);
|
||||||
let fullscreen = window_attributes.fullscreen.clone().map(Into::into);
|
let fullscreen = window_attributes.fullscreen.clone().map(Into::into);
|
||||||
let screen = match fullscreen {
|
let screen = match fullscreen {
|
||||||
Some(Fullscreen::Exclusive(ref video_mode)) => video_mode.monitor.ui_screen(mtm),
|
Some(Fullscreen::Exclusive(ref video_mode)) => video_mode.monitor.ui_screen(mtm),
|
||||||
|
|
@ -672,10 +675,8 @@ impl Inner {
|
||||||
} else {
|
} else {
|
||||||
let screen_frame = self.rect_to_screen_space(bounds);
|
let screen_frame = self.rect_to_screen_space(bounds);
|
||||||
let status_bar_frame = {
|
let status_bar_frame = {
|
||||||
let app = UIApplication::shared(MainThreadMarker::new().unwrap()).expect(
|
let app = UIApplication::sharedApplication(MainThreadMarker::new().unwrap());
|
||||||
"`Window::get_inner_position` cannot be called before `EventLoop::run_app` on \
|
#[allow(deprecated)]
|
||||||
iOS",
|
|
||||||
);
|
|
||||||
app.statusBarFrame()
|
app.statusBarFrame()
|
||||||
};
|
};
|
||||||
let (y, height) = if screen_frame.origin.y > status_bar_frame.size.height {
|
let (y, height) = if screen_frame.origin.y > status_bar_frame.size.height {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ use objc2_app_kit::{NSApplication, NSEvent, NSEventModifierFlags, NSEventType, N
|
||||||
use objc2_foundation::{MainThreadMarker, NSObject};
|
use objc2_foundation::{MainThreadMarker, NSObject};
|
||||||
|
|
||||||
use super::app_delegate::ApplicationDelegate;
|
use super::app_delegate::ApplicationDelegate;
|
||||||
use super::event::flags_contains;
|
|
||||||
use crate::event::{DeviceEvent, ElementState};
|
use crate::event::{DeviceEvent, ElementState};
|
||||||
|
|
||||||
declare_class!(
|
declare_class!(
|
||||||
|
|
@ -32,7 +31,7 @@ declare_class!(
|
||||||
let event_type = unsafe { event.r#type() };
|
let event_type = unsafe { event.r#type() };
|
||||||
let modifier_flags = unsafe { event.modifierFlags() };
|
let modifier_flags = unsafe { event.modifierFlags() };
|
||||||
if event_type == NSEventType::KeyUp
|
if event_type == NSEventType::KeyUp
|
||||||
&& flags_contains(modifier_flags, NSEventModifierFlags::NSEventModifierFlagCommand)
|
&& modifier_flags.contains(NSEventModifierFlags::NSEventModifierFlagCommand)
|
||||||
{
|
{
|
||||||
if let Some(key_window) = self.keyWindow() {
|
if let Some(key_window) = self.keyWindow() {
|
||||||
key_window.sendEvent(event);
|
key_window.sendEvent(event);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use std::rc::Weak;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Retained;
|
||||||
use objc2::runtime::AnyObject;
|
use objc2::runtime::AnyObject;
|
||||||
use objc2::{declare_class, msg_send_id, mutability, ClassType, DeclaredClass};
|
use objc2::{declare_class, msg_send_id, mutability, ClassType, DeclaredClass};
|
||||||
use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy, NSApplicationDelegate};
|
use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy, NSApplicationDelegate};
|
||||||
|
|
@ -133,7 +133,7 @@ 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> {
|
) -> Retained<Self> {
|
||||||
let this = mtm.alloc().set_ivars(State {
|
let this = mtm.alloc().set_ivars(State {
|
||||||
activation_policy: Policy(activation_policy),
|
activation_policy: Policy(activation_policy),
|
||||||
default_menu,
|
default_menu,
|
||||||
|
|
@ -143,13 +143,13 @@ impl ApplicationDelegate {
|
||||||
unsafe { msg_send_id![super(this), init] }
|
unsafe { msg_send_id![super(this), init] }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(mtm: MainThreadMarker) -> Id<Self> {
|
pub fn get(mtm: MainThreadMarker) -> Retained<Self> {
|
||||||
let app = NSApplication::sharedApplication(mtm);
|
let app = NSApplication::sharedApplication(mtm);
|
||||||
let delegate =
|
let delegate =
|
||||||
unsafe { app.delegate() }.expect("a delegate was not configured on the application");
|
unsafe { app.delegate() }.expect("a delegate was not configured on the application");
|
||||||
if delegate.is_kind_of::<Self>() {
|
if delegate.is_kind_of::<Self>() {
|
||||||
// SAFETY: Just checked that the delegate is an instance of `ApplicationDelegate`
|
// SAFETY: Just checked that the delegate is an instance of `ApplicationDelegate`
|
||||||
unsafe { Id::cast(delegate) }
|
unsafe { Retained::cast(delegate) }
|
||||||
} else {
|
} else {
|
||||||
panic!("tried to get a delegate that was not the one Winit has registered")
|
panic!("tried to get a delegate that was not the one Winit has registered")
|
||||||
}
|
}
|
||||||
|
|
@ -247,7 +247,7 @@ impl ApplicationDelegate {
|
||||||
|
|
||||||
pub fn queue_static_scale_factor_changed_event(
|
pub fn queue_static_scale_factor_changed_event(
|
||||||
&self,
|
&self,
|
||||||
window: Id<WinitWindow>,
|
window: Retained<WinitWindow>,
|
||||||
suggested_size: PhysicalSize<u32>,
|
suggested_size: PhysicalSize<u32>,
|
||||||
scale_factor: f64,
|
scale_factor: f64,
|
||||||
) {
|
) {
|
||||||
|
|
@ -425,7 +425,7 @@ pub(crate) enum QueuedEvent {
|
||||||
WindowEvent(WindowId, WindowEvent),
|
WindowEvent(WindowId, WindowEvent),
|
||||||
DeviceEvent(DeviceEvent),
|
DeviceEvent(DeviceEvent),
|
||||||
ScaleFactorChanged {
|
ScaleFactorChanged {
|
||||||
window: Id<WinitWindow>,
|
window: Retained<WinitWindow>,
|
||||||
suggested_size: PhysicalSize<u32>,
|
suggested_size: PhysicalSize<u32>,
|
||||||
scale_factor: f64,
|
scale_factor: f64,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::ffi::c_uchar;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Retained;
|
||||||
use objc2::runtime::Sel;
|
use objc2::runtime::Sel;
|
||||||
use objc2::{msg_send_id, sel, ClassType};
|
use objc2::{msg_send_id, sel, ClassType};
|
||||||
use objc2_app_kit::{NSBitmapImageRep, NSCursor, NSDeviceRGBColorSpace, NSImage};
|
use objc2_app_kit::{NSBitmapImageRep, NSCursor, NSDeviceRGBColorSpace, NSImage};
|
||||||
|
|
@ -15,7 +15,7 @@ use crate::cursor::{CursorImage, OnlyCursorImageSource};
|
||||||
use crate::window::CursorIcon;
|
use crate::window::CursorIcon;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct CustomCursor(pub(crate) Id<NSCursor>);
|
pub struct CustomCursor(pub(crate) Retained<NSCursor>);
|
||||||
|
|
||||||
// SAFETY: NSCursor is immutable and thread-safe
|
// SAFETY: NSCursor is immutable and thread-safe
|
||||||
// TODO(madsmtm): Put this logic in objc2-app-kit itself
|
// TODO(madsmtm): Put this logic in objc2-app-kit itself
|
||||||
|
|
@ -28,7 +28,7 @@ impl CustomCursor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Id<NSCursor> {
|
pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Retained<NSCursor> {
|
||||||
let width = cursor.width;
|
let width = cursor.width;
|
||||||
let height = cursor.height;
|
let height = cursor.height;
|
||||||
|
|
||||||
|
|
@ -60,14 +60,14 @@ pub(crate) fn cursor_from_image(cursor: &CursorImage) -> Id<NSCursor> {
|
||||||
NSCursor::initWithImage_hotSpot(NSCursor::alloc(), &image, hotspot)
|
NSCursor::initWithImage_hotSpot(NSCursor::alloc(), &image, hotspot)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn default_cursor() -> Id<NSCursor> {
|
pub(crate) fn default_cursor() -> Retained<NSCursor> {
|
||||||
NSCursor::arrowCursor()
|
NSCursor::arrowCursor()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn try_cursor_from_selector(sel: Sel) -> Option<Id<NSCursor>> {
|
unsafe fn try_cursor_from_selector(sel: Sel) -> Option<Retained<NSCursor>> {
|
||||||
let cls = NSCursor::class();
|
let cls = NSCursor::class();
|
||||||
if cls.responds_to(sel) {
|
if cls.responds_to(sel) {
|
||||||
let cursor: Id<NSCursor> = unsafe { msg_send_id![cls, performSelector: sel] };
|
let cursor: Retained<NSCursor> = unsafe { msg_send_id![cls, performSelector: sel] };
|
||||||
Some(cursor)
|
Some(cursor)
|
||||||
} else {
|
} else {
|
||||||
tracing::warn!("cursor `{sel}` appears to be invalid");
|
tracing::warn!("cursor `{sel}` appears to be invalid");
|
||||||
|
|
@ -82,7 +82,7 @@ macro_rules! def_undocumented_cursor {
|
||||||
)*} => {$(
|
)*} => {$(
|
||||||
$(#[$($m)*])*
|
$(#[$($m)*])*
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn $name() -> Id<NSCursor> {
|
fn $name() -> Retained<NSCursor> {
|
||||||
unsafe { try_cursor_from_selector(sel!($name)).unwrap_or_else(|| default_cursor()) }
|
unsafe { try_cursor_from_selector(sel!($name)).unwrap_or_else(|| default_cursor()) }
|
||||||
}
|
}
|
||||||
)*};
|
)*};
|
||||||
|
|
@ -112,7 +112,7 @@ def_undocumented_cursor!(
|
||||||
|
|
||||||
// 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<NSCursor> {
|
unsafe fn load_webkit_cursor(name: &NSString) -> Retained<NSCursor> {
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
|
|
@ -128,7 +128,7 @@ unsafe fn load_webkit_cursor(name: &NSString) -> Id<NSCursor> {
|
||||||
|
|
||||||
// TODO: Handle PLists better
|
// TODO: Handle PLists better
|
||||||
let info_path = cursor_path.stringByAppendingPathComponent(ns_string!("info.plist"));
|
let info_path = cursor_path.stringByAppendingPathComponent(ns_string!("info.plist"));
|
||||||
let info: Id<NSDictionary<NSObject, NSObject>> = unsafe {
|
let info: Retained<NSDictionary<NSObject, NSObject>> = unsafe {
|
||||||
msg_send_id![
|
msg_send_id![
|
||||||
<NSDictionary<NSObject, NSObject>>::class(),
|
<NSDictionary<NSObject, NSObject>>::class(),
|
||||||
dictionaryWithContentsOfFile: &*info_path,
|
dictionaryWithContentsOfFile: &*info_path,
|
||||||
|
|
@ -155,15 +155,15 @@ unsafe fn load_webkit_cursor(name: &NSString) -> Id<NSCursor> {
|
||||||
NSCursor::initWithImage_hotSpot(NSCursor::alloc(), &image, hotspot)
|
NSCursor::initWithImage_hotSpot(NSCursor::alloc(), &image, hotspot)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn webkit_move() -> Id<NSCursor> {
|
fn webkit_move() -> Retained<NSCursor> {
|
||||||
unsafe { load_webkit_cursor(ns_string!("move")) }
|
unsafe { load_webkit_cursor(ns_string!("move")) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn webkit_cell() -> Id<NSCursor> {
|
fn webkit_cell() -> Retained<NSCursor> {
|
||||||
unsafe { load_webkit_cursor(ns_string!("cell")) }
|
unsafe { load_webkit_cursor(ns_string!("cell")) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn invisible_cursor() -> Id<NSCursor> {
|
pub(crate) fn invisible_cursor() -> Retained<NSCursor> {
|
||||||
// 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
|
||||||
|
|
@ -174,7 +174,7 @@ pub(crate) fn invisible_cursor() -> Id<NSCursor> {
|
||||||
0xa3, 0x9c, 0xb4, 0xda, 0x8b, 0xb3, 0x3e, 0x05, 0x00, 0x3b,
|
0xa3, 0x9c, 0xb4, 0xda, 0x8b, 0xb3, 0x3e, 0x05, 0x00, 0x3b,
|
||||||
];
|
];
|
||||||
|
|
||||||
fn new_invisible() -> Id<NSCursor> {
|
fn new_invisible() -> Retained<NSCursor> {
|
||||||
// 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::initWithData(NSImage::alloc(), &data).unwrap();
|
let image = NSImage::initWithData(NSImage::alloc(), &data).unwrap();
|
||||||
|
|
@ -187,7 +187,7 @@ pub(crate) fn invisible_cursor() -> Id<NSCursor> {
|
||||||
CURSOR.get_or_init(|| CustomCursor(new_invisible())).0.clone()
|
CURSOR.get_or_init(|| CustomCursor(new_invisible())).0.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn cursor_from_icon(icon: CursorIcon) -> Id<NSCursor> {
|
pub(crate) fn cursor_from_icon(icon: CursorIcon) -> Retained<NSCursor> {
|
||||||
match icon {
|
match icon {
|
||||||
CursorIcon::Default => default_cursor(),
|
CursorIcon::Default => default_cursor(),
|
||||||
CursorIcon::Pointer => NSCursor::pointingHandCursor(),
|
CursorIcon::Pointer => NSCursor::pointingHandCursor(),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::ffi::c_void;
|
||||||
|
|
||||||
use core_foundation::base::CFRelease;
|
use core_foundation::base::CFRelease;
|
||||||
use core_foundation::data::{CFDataGetBytePtr, CFDataRef};
|
use core_foundation::data::{CFDataGetBytePtr, CFDataRef};
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Retained;
|
||||||
use objc2_app_kit::{NSEvent, NSEventModifierFlags, NSEventSubtype, NSEventType};
|
use objc2_app_kit::{NSEvent, NSEventModifierFlags, NSEventSubtype, NSEventType};
|
||||||
use objc2_foundation::{run_on_main, NSPoint};
|
use objc2_foundation::{run_on_main, NSPoint};
|
||||||
use smol_str::SmolStr;
|
use smol_str::SmolStr;
|
||||||
|
|
@ -133,8 +133,8 @@ pub(crate) fn create_key_event(
|
||||||
let key_without_modifiers = get_modifierless_char(scancode);
|
let key_without_modifiers = get_modifierless_char(scancode);
|
||||||
|
|
||||||
let modifiers = unsafe { ns_event.modifierFlags() };
|
let modifiers = unsafe { ns_event.modifierFlags() };
|
||||||
let has_ctrl = flags_contains(modifiers, NSEventModifierFlags::NSEventModifierFlagControl);
|
let has_ctrl = modifiers.contains(NSEventModifierFlags::NSEventModifierFlagControl);
|
||||||
let has_cmd = flags_contains(modifiers, NSEventModifierFlags::NSEventModifierFlagCommand);
|
let has_cmd = modifiers.contains(NSEventModifierFlags::NSEventModifierFlagCommand);
|
||||||
|
|
||||||
let logical_key = match text_with_all_modifiers.as_ref() {
|
let logical_key = match text_with_all_modifiers.as_ref() {
|
||||||
// Only checking for ctrl and cmd here, not checking for alt because we DO want to
|
// Only checking for ctrl and cmd here, not checking for alt because we DO want to
|
||||||
|
|
@ -305,16 +305,12 @@ const NX_DEVICELALTKEYMASK: NSEventModifierFlags = NSEventModifierFlags(0x000000
|
||||||
const NX_DEVICERALTKEYMASK: NSEventModifierFlags = NSEventModifierFlags(0x00000040);
|
const NX_DEVICERALTKEYMASK: NSEventModifierFlags = NSEventModifierFlags(0x00000040);
|
||||||
const NX_DEVICERCTLKEYMASK: NSEventModifierFlags = NSEventModifierFlags(0x00002000);
|
const NX_DEVICERCTLKEYMASK: NSEventModifierFlags = NSEventModifierFlags(0x00002000);
|
||||||
|
|
||||||
pub(super) fn flags_contains(flags: NSEventModifierFlags, value: NSEventModifierFlags) -> bool {
|
|
||||||
flags.0 & value.0 == value.0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn lalt_pressed(event: &NSEvent) -> bool {
|
pub(super) fn lalt_pressed(event: &NSEvent) -> bool {
|
||||||
flags_contains(unsafe { event.modifierFlags() }, NX_DEVICELALTKEYMASK)
|
unsafe { event.modifierFlags() }.contains(NX_DEVICELALTKEYMASK)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn ralt_pressed(event: &NSEvent) -> bool {
|
pub(super) fn ralt_pressed(event: &NSEvent) -> bool {
|
||||||
flags_contains(unsafe { event.modifierFlags() }, NX_DEVICERALTKEYMASK)
|
unsafe { event.modifierFlags() }.contains(NX_DEVICERALTKEYMASK)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn event_mods(event: &NSEvent) -> Modifiers {
|
pub(super) fn event_mods(event: &NSEvent) -> Modifiers {
|
||||||
|
|
@ -322,38 +318,33 @@ pub(super) fn event_mods(event: &NSEvent) -> Modifiers {
|
||||||
let mut state = ModifiersState::empty();
|
let mut state = ModifiersState::empty();
|
||||||
let mut pressed_mods = ModifiersKeys::empty();
|
let mut pressed_mods = ModifiersKeys::empty();
|
||||||
|
|
||||||
state.set(
|
state
|
||||||
ModifiersState::SHIFT,
|
.set(ModifiersState::SHIFT, flags.contains(NSEventModifierFlags::NSEventModifierFlagShift));
|
||||||
flags_contains(flags, NSEventModifierFlags::NSEventModifierFlagShift),
|
pressed_mods.set(ModifiersKeys::LSHIFT, flags.contains(NX_DEVICELSHIFTKEYMASK));
|
||||||
);
|
pressed_mods.set(ModifiersKeys::RSHIFT, flags.contains(NX_DEVICERSHIFTKEYMASK));
|
||||||
pressed_mods.set(ModifiersKeys::LSHIFT, flags_contains(flags, NX_DEVICELSHIFTKEYMASK));
|
|
||||||
pressed_mods.set(ModifiersKeys::RSHIFT, flags_contains(flags, NX_DEVICERSHIFTKEYMASK));
|
|
||||||
|
|
||||||
state.set(
|
state.set(
|
||||||
ModifiersState::CONTROL,
|
ModifiersState::CONTROL,
|
||||||
flags_contains(flags, NSEventModifierFlags::NSEventModifierFlagControl),
|
flags.contains(NSEventModifierFlags::NSEventModifierFlagControl),
|
||||||
);
|
);
|
||||||
pressed_mods.set(ModifiersKeys::LCONTROL, flags_contains(flags, NX_DEVICELCTLKEYMASK));
|
pressed_mods.set(ModifiersKeys::LCONTROL, flags.contains(NX_DEVICELCTLKEYMASK));
|
||||||
pressed_mods.set(ModifiersKeys::RCONTROL, flags_contains(flags, NX_DEVICERCTLKEYMASK));
|
pressed_mods.set(ModifiersKeys::RCONTROL, flags.contains(NX_DEVICERCTLKEYMASK));
|
||||||
|
|
||||||
state.set(
|
state.set(ModifiersState::ALT, flags.contains(NSEventModifierFlags::NSEventModifierFlagOption));
|
||||||
ModifiersState::ALT,
|
pressed_mods.set(ModifiersKeys::LALT, flags.contains(NX_DEVICELALTKEYMASK));
|
||||||
flags_contains(flags, NSEventModifierFlags::NSEventModifierFlagOption),
|
pressed_mods.set(ModifiersKeys::RALT, flags.contains(NX_DEVICERALTKEYMASK));
|
||||||
);
|
|
||||||
pressed_mods.set(ModifiersKeys::LALT, flags_contains(flags, NX_DEVICELALTKEYMASK));
|
|
||||||
pressed_mods.set(ModifiersKeys::RALT, flags_contains(flags, NX_DEVICERALTKEYMASK));
|
|
||||||
|
|
||||||
state.set(
|
state.set(
|
||||||
ModifiersState::SUPER,
|
ModifiersState::SUPER,
|
||||||
flags_contains(flags, NSEventModifierFlags::NSEventModifierFlagCommand),
|
flags.contains(NSEventModifierFlags::NSEventModifierFlagCommand),
|
||||||
);
|
);
|
||||||
pressed_mods.set(ModifiersKeys::LSUPER, flags_contains(flags, NX_DEVICELCMDKEYMASK));
|
pressed_mods.set(ModifiersKeys::LSUPER, flags.contains(NX_DEVICELCMDKEYMASK));
|
||||||
pressed_mods.set(ModifiersKeys::RSUPER, flags_contains(flags, NX_DEVICERCMDKEYMASK));
|
pressed_mods.set(ModifiersKeys::RSUPER, flags.contains(NX_DEVICERCMDKEYMASK));
|
||||||
|
|
||||||
Modifiers { state, pressed_mods }
|
Modifiers { state, pressed_mods }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn dummy_event() -> Option<Id<NSEvent>> {
|
pub(super) fn dummy_event() -> Option<Retained<NSEvent>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
NSEvent::otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2(
|
NSEvent::otherEventWithType_location_modifierFlags_timestamp_windowNumber_context_subtype_data1_data2(
|
||||||
NSEventType::ApplicationDefined,
|
NSEventType::ApplicationDefined,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ use core_foundation::runloop::{
|
||||||
kCFRunLoopCommonModes, CFRunLoopAddSource, CFRunLoopGetMain, CFRunLoopSourceContext,
|
kCFRunLoopCommonModes, CFRunLoopAddSource, CFRunLoopGetMain, CFRunLoopSourceContext,
|
||||||
CFRunLoopSourceCreate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp,
|
CFRunLoopSourceCreate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp,
|
||||||
};
|
};
|
||||||
use objc2::rc::{autoreleasepool, Id};
|
use objc2::rc::{autoreleasepool, Retained};
|
||||||
use objc2::runtime::ProtocolObject;
|
use objc2::runtime::ProtocolObject;
|
||||||
use objc2::{msg_send_id, ClassType};
|
use objc2::{msg_send_id, ClassType};
|
||||||
use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy, NSWindow};
|
use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy, NSWindow};
|
||||||
|
|
@ -68,12 +68,12 @@ impl PanicInfo {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ActiveEventLoop {
|
pub struct ActiveEventLoop {
|
||||||
delegate: Id<ApplicationDelegate>,
|
delegate: Retained<ApplicationDelegate>,
|
||||||
pub(super) mtm: MainThreadMarker,
|
pub(super) mtm: MainThreadMarker,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActiveEventLoop {
|
impl ActiveEventLoop {
|
||||||
pub(super) fn new_root(delegate: Id<ApplicationDelegate>) -> RootWindowTarget {
|
pub(super) fn new_root(delegate: Retained<ApplicationDelegate>) -> RootWindowTarget {
|
||||||
let mtm = MainThreadMarker::from(&*delegate);
|
let mtm = MainThreadMarker::from(&*delegate);
|
||||||
let p = Self { delegate, mtm };
|
let p = Self { delegate, mtm };
|
||||||
RootWindowTarget { p, _marker: PhantomData }
|
RootWindowTarget { p, _marker: PhantomData }
|
||||||
|
|
@ -186,12 +186,12 @@ pub struct EventLoop<T: 'static> {
|
||||||
///
|
///
|
||||||
/// We intentionally don't store `WinitApplication` since we want to have
|
/// We intentionally don't store `WinitApplication` since we want to have
|
||||||
/// the possibility of swapping that out at some point.
|
/// the possibility of swapping that out at some point.
|
||||||
app: Id<NSApplication>,
|
app: Retained<NSApplication>,
|
||||||
/// The application delegate that we've registered.
|
/// The application delegate that we've registered.
|
||||||
///
|
///
|
||||||
/// The delegate is only weakly referenced by NSApplication, so we must
|
/// The delegate is only weakly referenced by NSApplication, so we must
|
||||||
/// keep it around here as well.
|
/// keep it around here as well.
|
||||||
delegate: Id<ApplicationDelegate>,
|
delegate: Retained<ApplicationDelegate>,
|
||||||
|
|
||||||
// Event sender and receiver, used for EventLoopProxy.
|
// Event sender and receiver, used for EventLoopProxy.
|
||||||
sender: mpsc::Sender<T>,
|
sender: mpsc::Sender<T>,
|
||||||
|
|
@ -225,7 +225,7 @@ impl<T> EventLoop<T> {
|
||||||
let mtm = MainThreadMarker::new()
|
let mtm = MainThreadMarker::new()
|
||||||
.expect("on macOS, `EventLoop` must be created on the main thread!");
|
.expect("on macOS, `EventLoop` must be created on the main thread!");
|
||||||
|
|
||||||
let app: Id<NSApplication> =
|
let app: Retained<NSApplication> =
|
||||||
unsafe { msg_send_id![WinitApplication::class(), sharedApplication] };
|
unsafe { msg_send_id![WinitApplication::class(), sharedApplication] };
|
||||||
|
|
||||||
if !app.is_kind_of::<WinitApplication>() {
|
if !app.is_kind_of::<WinitApplication>() {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Retained;
|
||||||
use objc2::runtime::Sel;
|
use objc2::runtime::Sel;
|
||||||
use objc2::sel;
|
use objc2::sel;
|
||||||
use objc2_app_kit::{NSApplication, NSEventModifierFlags, NSMenu, NSMenuItem};
|
use objc2_app_kit::{NSApplication, NSEventModifierFlags, NSMenu, NSMenuItem};
|
||||||
|
|
@ -48,10 +48,10 @@ pub fn initialize(app: &NSApplication) {
|
||||||
Some(sel!(hideOtherApplications:)),
|
Some(sel!(hideOtherApplications:)),
|
||||||
Some(KeyEquivalent {
|
Some(KeyEquivalent {
|
||||||
key: ns_string!("h"),
|
key: ns_string!("h"),
|
||||||
masks: Some(NSEventModifierFlags(
|
masks: Some(
|
||||||
NSEventModifierFlags::NSEventModifierFlagOption.0
|
NSEventModifierFlags::NSEventModifierFlagOption
|
||||||
| NSEventModifierFlags::NSEventModifierFlagCommand.0,
|
| NSEventModifierFlags::NSEventModifierFlagCommand,
|
||||||
)),
|
),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -91,7 +91,7 @@ fn menu_item(
|
||||||
title: &NSString,
|
title: &NSString,
|
||||||
selector: Option<Sel>,
|
selector: Option<Sel>,
|
||||||
key_equivalent: Option<KeyEquivalent<'_>>,
|
key_equivalent: Option<KeyEquivalent<'_>>,
|
||||||
) -> Id<NSMenuItem> {
|
) -> Retained<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),
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use core_foundation::string::CFString;
|
||||||
use core_graphics::display::{
|
use core_graphics::display::{
|
||||||
CGDirectDisplayID, CGDisplay, CGDisplayBounds, CGDisplayCopyDisplayMode,
|
CGDirectDisplayID, CGDisplay, CGDisplayBounds, CGDisplayCopyDisplayMode,
|
||||||
};
|
};
|
||||||
use objc2::rc::Id;
|
use objc2::rc::Retained;
|
||||||
use objc2::runtime::AnyObject;
|
use objc2::runtime::AnyObject;
|
||||||
use objc2_app_kit::NSScreen;
|
use objc2_app_kit::NSScreen;
|
||||||
use objc2_foundation::{ns_string, run_on_main, MainThreadMarker, NSNumber, NSPoint, NSRect};
|
use objc2_foundation::{ns_string, run_on_main, MainThreadMarker, NSNumber, NSPoint, NSRect};
|
||||||
|
|
@ -295,7 +295,7 @@ impl MonitorHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn ns_screen(&self, mtm: MainThreadMarker) -> Option<Id<NSScreen>> {
|
pub(crate) fn ns_screen(&self, mtm: MainThreadMarker) -> Option<Retained<NSScreen>> {
|
||||||
let uuid = unsafe { ffi::CGDisplayCreateUUIDFromDisplayID(self.0) };
|
let uuid = unsafe { ffi::CGDisplayCreateUUIDFromDisplayID(self.0) };
|
||||||
NSScreen::screens(mtm).into_iter().find(|screen| {
|
NSScreen::screens(mtm).into_iter().find(|screen| {
|
||||||
let other_native_id = get_display_id(screen);
|
let other_native_id = get_display_id(screen);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::cell::{Cell, RefCell};
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use objc2::rc::{Id, WeakId};
|
use objc2::rc::{Retained, WeakId};
|
||||||
use objc2::runtime::{AnyObject, Sel};
|
use objc2::runtime::{AnyObject, Sel};
|
||||||
use objc2::{declare_class, msg_send_id, mutability, sel, ClassType, DeclaredClass};
|
use objc2::{declare_class, msg_send_id, mutability, sel, ClassType, DeclaredClass};
|
||||||
use objc2_app_kit::{
|
use objc2_app_kit::{
|
||||||
|
|
@ -35,7 +35,7 @@ use crate::platform::macos::OptionAsAlt;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct CursorState {
|
struct CursorState {
|
||||||
visible: bool,
|
visible: bool,
|
||||||
cursor: Id<NSCursor>,
|
cursor: Retained<NSCursor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CursorState {
|
impl Default for CursorState {
|
||||||
|
|
@ -111,7 +111,7 @@ fn get_left_modifier_code(key: &Key) -> KeyCode {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ViewState {
|
pub struct ViewState {
|
||||||
/// Strong reference to the global application state.
|
/// Strong reference to the global application state.
|
||||||
app_delegate: Id<ApplicationDelegate>,
|
app_delegate: Retained<ApplicationDelegate>,
|
||||||
|
|
||||||
cursor_state: RefCell<CursorState>,
|
cursor_state: RefCell<CursorState>,
|
||||||
ime_position: Cell<NSPoint>,
|
ime_position: Cell<NSPoint>,
|
||||||
|
|
@ -131,7 +131,7 @@ pub 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>>,
|
marked_text: RefCell<Retained<NSMutableAttributedString>>,
|
||||||
accepts_first_mouse: bool,
|
accepts_first_mouse: bool,
|
||||||
|
|
||||||
// Weak reference because the window keeps a strong reference to the view
|
// Weak reference because the window keeps a strong reference to the view
|
||||||
|
|
@ -221,7 +221,7 @@ declare_class!(
|
||||||
// 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`
|
||||||
#[method_id(touchBar)]
|
#[method_id(touchBar)]
|
||||||
fn touch_bar(&self) -> Option<Id<NSObject>> {
|
fn touch_bar(&self) -> Option<Retained<NSObject>> {
|
||||||
trace_scope!("touchBar");
|
trace_scope!("touchBar");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -340,7 +340,7 @@ declare_class!(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[method_id(validAttributesForMarkedText)]
|
#[method_id(validAttributesForMarkedText)]
|
||||||
fn valid_attributes_for_marked_text(&self) -> Id<NSArray<NSAttributedStringKey>> {
|
fn valid_attributes_for_marked_text(&self) -> Retained<NSArray<NSAttributedStringKey>> {
|
||||||
trace_scope!("validAttributesForMarkedText");
|
trace_scope!("validAttributesForMarkedText");
|
||||||
NSArray::new()
|
NSArray::new()
|
||||||
}
|
}
|
||||||
|
|
@ -350,7 +350,7 @@ declare_class!(
|
||||||
&self,
|
&self,
|
||||||
_range: NSRange,
|
_range: NSRange,
|
||||||
_actual_range: *mut NSRange,
|
_actual_range: *mut NSRange,
|
||||||
) -> Option<Id<NSAttributedString>> {
|
) -> Option<Retained<NSAttributedString>> {
|
||||||
trace_scope!("attributedSubstringForProposedRange:actualRange:");
|
trace_scope!("attributedSubstringForProposedRange:actualRange:");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -776,7 +776,7 @@ impl WinitView {
|
||||||
window: &WinitWindow,
|
window: &WinitWindow,
|
||||||
accepts_first_mouse: bool,
|
accepts_first_mouse: bool,
|
||||||
option_as_alt: OptionAsAlt,
|
option_as_alt: OptionAsAlt,
|
||||||
) -> Id<Self> {
|
) -> Retained<Self> {
|
||||||
let mtm = MainThreadMarker::from(window);
|
let mtm = MainThreadMarker::from(window);
|
||||||
let this = mtm.alloc().set_ivars(ViewState {
|
let this = mtm.alloc().set_ivars(ViewState {
|
||||||
app_delegate: app_delegate.retain(),
|
app_delegate: app_delegate.retain(),
|
||||||
|
|
@ -795,7 +795,7 @@ impl WinitView {
|
||||||
_ns_window: WeakId::new(&window.retain()),
|
_ns_window: WeakId::new(&window.retain()),
|
||||||
option_as_alt: Cell::new(option_as_alt),
|
option_as_alt: Cell::new(option_as_alt),
|
||||||
});
|
});
|
||||||
let this: Id<Self> = unsafe { msg_send_id![super(this), init] };
|
let this: Retained<Self> = unsafe { msg_send_id![super(this), init] };
|
||||||
|
|
||||||
this.setPostsFrameChangedNotifications(true);
|
this.setPostsFrameChangedNotifications(true);
|
||||||
let notification_center = unsafe { NSNotificationCenter::defaultCenter() };
|
let notification_center = unsafe { NSNotificationCenter::defaultCenter() };
|
||||||
|
|
@ -813,7 +813,7 @@ impl WinitView {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window(&self) -> Id<WinitWindow> {
|
fn window(&self) -> Retained<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:`)
|
||||||
|
|
@ -846,11 +846,11 @@ impl WinitView {
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn cursor_icon(&self) -> Id<NSCursor> {
|
pub(super) fn cursor_icon(&self) -> Retained<NSCursor> {
|
||||||
self.ivars().cursor_state.borrow().cursor.clone()
|
self.ivars().cursor_state.borrow().cursor.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn set_cursor_icon(&self, icon: Id<NSCursor>) {
|
pub(super) fn set_cursor_icon(&self, icon: Retained<NSCursor>) {
|
||||||
let mut cursor_state = self.ivars().cursor_state.borrow_mut();
|
let mut cursor_state = self.ivars().cursor_state.borrow_mut();
|
||||||
cursor_state.cursor = icon;
|
cursor_state.cursor = icon;
|
||||||
}
|
}
|
||||||
|
|
@ -1083,7 +1083,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> {
|
fn replace_event(event: &NSEvent, option_as_alt: OptionAsAlt) -> Retained<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 lalt_pressed(event) => true,
|
OptionAsAlt::OnlyLeft if lalt_pressed(event) => true,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#![allow(clippy::unnecessary_cast)]
|
#![allow(clippy::unnecessary_cast)]
|
||||||
|
|
||||||
use objc2::rc::{autoreleasepool, Id};
|
use objc2::rc::{autoreleasepool, Retained};
|
||||||
use objc2::{declare_class, mutability, ClassType, DeclaredClass};
|
use objc2::{declare_class, mutability, ClassType, DeclaredClass};
|
||||||
use objc2_app_kit::{NSResponder, NSWindow};
|
use objc2_app_kit::{NSResponder, NSWindow};
|
||||||
use objc2_foundation::{MainThreadBound, MainThreadMarker, NSObject};
|
use objc2_foundation::{MainThreadBound, MainThreadMarker, NSObject};
|
||||||
|
|
@ -11,9 +11,9 @@ use crate::error::OsError as RootOsError;
|
||||||
use crate::window::WindowAttributes;
|
use crate::window::WindowAttributes;
|
||||||
|
|
||||||
pub(crate) struct Window {
|
pub(crate) struct Window {
|
||||||
window: MainThreadBound<Id<WinitWindow>>,
|
window: MainThreadBound<Retained<WinitWindow>>,
|
||||||
/// The window only keeps a weak reference to this, so we must keep it around here.
|
/// The window only keeps a weak reference to this, so we must keep it around here.
|
||||||
delegate: MainThreadBound<Id<WindowDelegate>>,
|
delegate: MainThreadBound<Retained<WindowDelegate>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Window {
|
impl Drop for Window {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use std::collections::VecDeque;
|
||||||
|
|
||||||
use core_graphics::display::{CGDisplay, CGPoint};
|
use core_graphics::display::{CGDisplay, CGPoint};
|
||||||
use monitor::VideoModeHandle;
|
use monitor::VideoModeHandle;
|
||||||
use objc2::rc::{autoreleasepool, Id};
|
use objc2::rc::{autoreleasepool, Retained};
|
||||||
use objc2::runtime::{AnyObject, ProtocolObject};
|
use objc2::runtime::{AnyObject, ProtocolObject};
|
||||||
use objc2::{declare_class, msg_send_id, mutability, sel, ClassType, DeclaredClass};
|
use objc2::{declare_class, msg_send_id, mutability, sel, ClassType, DeclaredClass};
|
||||||
use objc2_app_kit::{
|
use objc2_app_kit::{
|
||||||
|
|
@ -73,9 +73,9 @@ impl Default for PlatformSpecificWindowAttributes {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct State {
|
pub(crate) struct State {
|
||||||
/// Strong reference to the global application state.
|
/// Strong reference to the global application state.
|
||||||
app_delegate: Id<ApplicationDelegate>,
|
app_delegate: Retained<ApplicationDelegate>,
|
||||||
|
|
||||||
window: Id<WinitWindow>,
|
window: Retained<WinitWindow>,
|
||||||
|
|
||||||
current_theme: Cell<Option<Theme>>,
|
current_theme: Cell<Option<Theme>>,
|
||||||
|
|
||||||
|
|
@ -231,7 +231,7 @@ declare_class!(
|
||||||
None => {
|
None => {
|
||||||
let current_monitor = self.current_monitor_inner();
|
let current_monitor = self.current_monitor_inner();
|
||||||
*fullscreen = Some(Fullscreen::Borderless(current_monitor));
|
*fullscreen = Some(Fullscreen::Borderless(current_monitor));
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
self.ivars().in_fullscreen_transition.set(true);
|
self.ivars().in_fullscreen_transition.set(true);
|
||||||
}
|
}
|
||||||
|
|
@ -262,11 +262,9 @@ declare_class!(
|
||||||
let mut options = proposed_options;
|
let mut options = proposed_options;
|
||||||
let fullscreen = self.ivars().fullscreen.borrow();
|
let fullscreen = self.ivars().fullscreen.borrow();
|
||||||
if let Some(Fullscreen::Exclusive(_)) = &*fullscreen {
|
if let Some(Fullscreen::Exclusive(_)) = &*fullscreen {
|
||||||
options = NSApplicationPresentationOptions(
|
options = NSApplicationPresentationOptions::NSApplicationPresentationFullScreen
|
||||||
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen.0
|
| NSApplicationPresentationOptions::NSApplicationPresentationHideDock
|
||||||
| NSApplicationPresentationOptions::NSApplicationPresentationHideDock.0
|
| NSApplicationPresentationOptions::NSApplicationPresentationHideMenuBar;
|
||||||
| NSApplicationPresentationOptions::NSApplicationPresentationHideMenuBar.0,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
options
|
options
|
||||||
|
|
@ -333,8 +331,7 @@ declare_class!(
|
||||||
#[method(windowDidChangeOcclusionState:)]
|
#[method(windowDidChangeOcclusionState:)]
|
||||||
fn window_did_change_occlusion_state(&self, _: Option<&AnyObject>) {
|
fn window_did_change_occlusion_state(&self, _: Option<&AnyObject>) {
|
||||||
trace_scope!("windowDidChangeOcclusionState:");
|
trace_scope!("windowDidChangeOcclusionState:");
|
||||||
let visible = self.window().occlusionState().0 & NSWindowOcclusionState::Visible.0
|
let visible = self.window().occlusionState().contains(NSWindowOcclusionState::Visible);
|
||||||
== NSWindowOcclusionState::Visible.0;
|
|
||||||
self.queue_event(WindowEvent::Occluded(!visible));
|
self.queue_event(WindowEvent::Occluded(!visible));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,11 +355,9 @@ declare_class!(
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
let pb: Id<NSPasteboard> = unsafe { msg_send_id![sender, draggingPasteboard] };
|
let pb: Retained<NSPasteboard> = unsafe { msg_send_id![sender, draggingPasteboard] };
|
||||||
let filenames = pb
|
let filenames = pb.propertyListForType(unsafe { NSFilenamesPboardType }).unwrap();
|
||||||
.propertyListForType(unsafe { NSFilenamesPboardType })
|
let filenames: Retained<NSArray<NSString>> = unsafe { Retained::cast(filenames) };
|
||||||
.unwrap();
|
|
||||||
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());
|
||||||
|
|
@ -386,11 +381,9 @@ declare_class!(
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
let pb: Id<NSPasteboard> = unsafe { msg_send_id![sender, draggingPasteboard] };
|
let pb: Retained<NSPasteboard> = unsafe { msg_send_id![sender, draggingPasteboard] };
|
||||||
let filenames = pb
|
let filenames = pb.propertyListForType(unsafe { NSFilenamesPboardType }).unwrap();
|
||||||
.propertyListForType(unsafe { NSFilenamesPboardType })
|
let filenames: Retained<NSArray<NSString>> = unsafe { Retained::cast(filenames) };
|
||||||
.unwrap();
|
|
||||||
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());
|
||||||
|
|
@ -444,7 +437,7 @@ fn new_window(
|
||||||
app_delegate: &ApplicationDelegate,
|
app_delegate: &ApplicationDelegate,
|
||||||
attrs: &WindowAttributes,
|
attrs: &WindowAttributes,
|
||||||
mtm: MainThreadMarker,
|
mtm: MainThreadMarker,
|
||||||
) -> Option<Id<WinitWindow>> {
|
) -> Option<Retained<WinitWindow>> {
|
||||||
autoreleasepool(|_| {
|
autoreleasepool(|_| {
|
||||||
let screen = match attrs.fullscreen.clone().map(Into::into) {
|
let screen = match attrs.fullscreen.clone().map(Into::into) {
|
||||||
Some(Fullscreen::Borderless(Some(monitor)))
|
Some(Fullscreen::Borderless(Some(monitor)))
|
||||||
|
|
@ -489,38 +482,38 @@ fn new_window(
|
||||||
// if decorations is set to false, ignore pl_attrs
|
// if decorations is set to false, ignore pl_attrs
|
||||||
//
|
//
|
||||||
// if the titlebar is hidden, ignore other pl_attrs
|
// if the titlebar is hidden, ignore other pl_attrs
|
||||||
NSWindowStyleMask::Borderless.0
|
NSWindowStyleMask::Borderless
|
||||||
| NSWindowStyleMask::Resizable.0
|
| NSWindowStyleMask::Resizable
|
||||||
| NSWindowStyleMask::Miniaturizable.0
|
| NSWindowStyleMask::Miniaturizable
|
||||||
} else {
|
} else {
|
||||||
// default case, resizable window with titlebar and titlebar buttons
|
// default case, resizable window with titlebar and titlebar buttons
|
||||||
NSWindowStyleMask::Closable.0
|
NSWindowStyleMask::Closable
|
||||||
| NSWindowStyleMask::Miniaturizable.0
|
| NSWindowStyleMask::Miniaturizable
|
||||||
| NSWindowStyleMask::Resizable.0
|
| NSWindowStyleMask::Resizable
|
||||||
| NSWindowStyleMask::Titled.0
|
| NSWindowStyleMask::Titled
|
||||||
};
|
};
|
||||||
|
|
||||||
if !attrs.resizable {
|
if !attrs.resizable {
|
||||||
masks &= !NSWindowStyleMask::Resizable.0;
|
masks &= !NSWindowStyleMask::Resizable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !attrs.enabled_buttons.contains(WindowButtons::MINIMIZE) {
|
if !attrs.enabled_buttons.contains(WindowButtons::MINIMIZE) {
|
||||||
masks &= !NSWindowStyleMask::Miniaturizable.0;
|
masks &= !NSWindowStyleMask::Miniaturizable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !attrs.enabled_buttons.contains(WindowButtons::CLOSE) {
|
if !attrs.enabled_buttons.contains(WindowButtons::CLOSE) {
|
||||||
masks &= !NSWindowStyleMask::Closable.0;
|
masks &= !NSWindowStyleMask::Closable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if attrs.platform_specific.fullsize_content_view {
|
if attrs.platform_specific.fullsize_content_view {
|
||||||
masks |= NSWindowStyleMask::FullSizeContentView.0;
|
masks |= NSWindowStyleMask::FullSizeContentView;
|
||||||
}
|
}
|
||||||
|
|
||||||
let window: Option<Id<WinitWindow>> = unsafe {
|
let window: Option<Retained<WinitWindow>> = unsafe {
|
||||||
msg_send_id![
|
msg_send_id![
|
||||||
super(mtm.alloc().set_ivars(())),
|
super(mtm.alloc().set_ivars(())),
|
||||||
initWithContentRect: frame,
|
initWithContentRect: frame,
|
||||||
styleMask: NSWindowStyleMask(masks),
|
styleMask: masks,
|
||||||
backing: NSBackingStoreType::NSBackingStoreBuffered,
|
backing: NSBackingStoreType::NSBackingStoreBuffered,
|
||||||
defer: false,
|
defer: false,
|
||||||
]
|
]
|
||||||
|
|
@ -625,7 +618,7 @@ impl WindowDelegate {
|
||||||
app_delegate: &ApplicationDelegate,
|
app_delegate: &ApplicationDelegate,
|
||||||
attrs: WindowAttributes,
|
attrs: WindowAttributes,
|
||||||
mtm: MainThreadMarker,
|
mtm: MainThreadMarker,
|
||||||
) -> Result<Id<Self>, RootOsError> {
|
) -> Result<Retained<Self>, RootOsError> {
|
||||||
let window = new_window(app_delegate, &attrs, mtm)
|
let window = new_window(app_delegate, &attrs, mtm)
|
||||||
.ok_or_else(|| os_error!(OsError::CreationError("couldn't create `NSWindow`")))?;
|
.ok_or_else(|| os_error!(OsError::CreationError("couldn't create `NSWindow`")))?;
|
||||||
|
|
||||||
|
|
@ -634,8 +627,8 @@ impl WindowDelegate {
|
||||||
Some(rwh_06::RawWindowHandle::AppKit(handle)) => {
|
Some(rwh_06::RawWindowHandle::AppKit(handle)) => {
|
||||||
// SAFETY: Caller ensures the pointer is valid or NULL
|
// SAFETY: Caller ensures the pointer is valid or NULL
|
||||||
// Unwrap is fine, since the pointer comes from `NonNull`.
|
// Unwrap is fine, since the pointer comes from `NonNull`.
|
||||||
let parent_view: Id<NSView> =
|
let parent_view: Retained<NSView> =
|
||||||
unsafe { Id::retain(handle.ns_view.as_ptr().cast()) }.unwrap();
|
unsafe { Retained::retain(handle.ns_view.as_ptr().cast()) }.unwrap();
|
||||||
let parent = parent_view.window().ok_or_else(|| {
|
let parent = parent_view.window().ok_or_else(|| {
|
||||||
os_error!(OsError::CreationError("parent view should be installed in a window"))
|
os_error!(OsError::CreationError("parent view should be installed in a window"))
|
||||||
})?;
|
})?;
|
||||||
|
|
@ -685,7 +678,7 @@ impl WindowDelegate {
|
||||||
is_simple_fullscreen: Cell::new(false),
|
is_simple_fullscreen: Cell::new(false),
|
||||||
saved_style: Cell::new(None),
|
saved_style: Cell::new(None),
|
||||||
});
|
});
|
||||||
let delegate: Id<WindowDelegate> = unsafe { msg_send_id![super(delegate), init] };
|
let delegate: Retained<WindowDelegate> = unsafe { msg_send_id![super(delegate), init] };
|
||||||
|
|
||||||
if scale_factor != 1.0 {
|
if scale_factor != 1.0 {
|
||||||
delegate.queue_static_scale_factor_changed_event();
|
delegate.queue_static_scale_factor_changed_event();
|
||||||
|
|
@ -745,9 +738,9 @@ impl WindowDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub(super) fn view(&self) -> Id<WinitView> {
|
pub(super) fn view(&self) -> Retained<WinitView> {
|
||||||
// SAFETY: The view inside WinitWindow is always `WinitView`
|
// SAFETY: The view inside WinitWindow is always `WinitView`
|
||||||
unsafe { Id::cast(self.window().contentView().unwrap()) }
|
unsafe { Retained::cast(self.window().contentView().unwrap()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
|
@ -960,13 +953,13 @@ impl WindowDelegate {
|
||||||
self.ivars().resizable.set(resizable);
|
self.ivars().resizable.set(resizable);
|
||||||
let fullscreen = self.ivars().fullscreen.borrow().is_some();
|
let fullscreen = self.ivars().fullscreen.borrow().is_some();
|
||||||
if !fullscreen {
|
if !fullscreen {
|
||||||
let mut mask = self.window().styleMask().0;
|
let mut mask = self.window().styleMask();
|
||||||
if resizable {
|
if resizable {
|
||||||
mask |= NSWindowStyleMask::Resizable.0;
|
mask |= NSWindowStyleMask::Resizable;
|
||||||
} else {
|
} else {
|
||||||
mask &= !NSWindowStyleMask::Resizable.0;
|
mask &= !NSWindowStyleMask::Resizable;
|
||||||
}
|
}
|
||||||
self.set_style_mask(NSWindowStyleMask(mask));
|
self.set_style_mask(mask);
|
||||||
}
|
}
|
||||||
// Otherwise, we don't change the mask until we exit fullscreen.
|
// Otherwise, we don't change the mask until we exit fullscreen.
|
||||||
}
|
}
|
||||||
|
|
@ -978,23 +971,23 @@ impl WindowDelegate {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_enabled_buttons(&self, buttons: WindowButtons) {
|
pub fn set_enabled_buttons(&self, buttons: WindowButtons) {
|
||||||
let mut mask = self.window().styleMask().0;
|
let mut mask = self.window().styleMask();
|
||||||
|
|
||||||
if buttons.contains(WindowButtons::CLOSE) {
|
if buttons.contains(WindowButtons::CLOSE) {
|
||||||
mask |= NSWindowStyleMask::Closable.0;
|
mask |= NSWindowStyleMask::Closable;
|
||||||
} else {
|
} else {
|
||||||
mask &= !NSWindowStyleMask::Closable.0;
|
mask &= !NSWindowStyleMask::Closable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if buttons.contains(WindowButtons::MINIMIZE) {
|
if buttons.contains(WindowButtons::MINIMIZE) {
|
||||||
mask |= NSWindowStyleMask::Miniaturizable.0;
|
mask |= NSWindowStyleMask::Miniaturizable;
|
||||||
} else {
|
} else {
|
||||||
mask &= !NSWindowStyleMask::Miniaturizable.0;
|
mask &= !NSWindowStyleMask::Miniaturizable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This must happen before the button's "enabled" status has been set,
|
// This must happen before the button's "enabled" status has been set,
|
||||||
// hence we do it synchronously.
|
// hence we do it synchronously.
|
||||||
self.set_style_mask(NSWindowStyleMask(mask));
|
self.set_style_mask(mask);
|
||||||
|
|
||||||
// We edit the button directly instead of using `NSResizableWindowMask`,
|
// We edit the button directly instead of using `NSResizableWindowMask`,
|
||||||
// since that mask also affect the resizability of the window (which is
|
// since that mask also affect the resizability of the window (which is
|
||||||
|
|
@ -1115,9 +1108,8 @@ impl WindowDelegate {
|
||||||
// we make it resizable temporarily.
|
// we make it resizable temporarily.
|
||||||
let curr_mask = self.window().styleMask();
|
let curr_mask = self.window().styleMask();
|
||||||
|
|
||||||
let required =
|
let required = NSWindowStyleMask::Titled | NSWindowStyleMask::Resizable;
|
||||||
NSWindowStyleMask(NSWindowStyleMask::Titled.0 | NSWindowStyleMask::Resizable.0);
|
let needs_temp_mask = !curr_mask.contains(required);
|
||||||
let needs_temp_mask = !mask_contains(curr_mask, required);
|
|
||||||
if needs_temp_mask {
|
if needs_temp_mask {
|
||||||
self.set_style_mask(required);
|
self.set_style_mask(required);
|
||||||
}
|
}
|
||||||
|
|
@ -1134,12 +1126,12 @@ impl WindowDelegate {
|
||||||
|
|
||||||
fn saved_style(&self) -> NSWindowStyleMask {
|
fn saved_style(&self) -> NSWindowStyleMask {
|
||||||
let base_mask =
|
let base_mask =
|
||||||
self.ivars().saved_style.take().unwrap_or_else(|| self.window().styleMask()).0;
|
self.ivars().saved_style.take().unwrap_or_else(|| self.window().styleMask());
|
||||||
NSWindowStyleMask(if self.ivars().resizable.get() {
|
if self.ivars().resizable.get() {
|
||||||
base_mask | NSWindowStyleMask::Resizable.0
|
base_mask | NSWindowStyleMask::Resizable
|
||||||
} else {
|
} else {
|
||||||
base_mask & !NSWindowStyleMask::Resizable.0
|
base_mask & !NSWindowStyleMask::Resizable
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is called when the window is exiting fullscreen, whether by the
|
/// This is called when the window is exiting fullscreen, whether by the
|
||||||
|
|
@ -1194,7 +1186,7 @@ impl WindowDelegate {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if mask_contains(self.window().styleMask(), NSWindowStyleMask::Resizable) {
|
if self.window().styleMask().contains(NSWindowStyleMask::Resizable) {
|
||||||
// Just use the native zoom if resizable
|
// Just use the native zoom if resizable
|
||||||
self.window().zoom(None);
|
self.window().zoom(None);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1346,9 +1338,8 @@ impl WindowDelegate {
|
||||||
// set a normal style temporarily. The previous state will be
|
// set a normal style temporarily. The previous state will be
|
||||||
// restored in `WindowDelegate::window_did_exit_fullscreen`.
|
// restored in `WindowDelegate::window_did_exit_fullscreen`.
|
||||||
let curr_mask = self.window().styleMask();
|
let curr_mask = self.window().styleMask();
|
||||||
let required =
|
let required = NSWindowStyleMask::Titled | NSWindowStyleMask::Resizable;
|
||||||
NSWindowStyleMask(NSWindowStyleMask::Titled.0 | NSWindowStyleMask::Resizable.0);
|
if !curr_mask.contains(required) {
|
||||||
if !mask_contains(curr_mask, required) {
|
|
||||||
self.set_style_mask(required);
|
self.set_style_mask(required);
|
||||||
self.ivars().saved_style.set(Some(curr_mask));
|
self.ivars().saved_style.set(Some(curr_mask));
|
||||||
}
|
}
|
||||||
|
|
@ -1379,11 +1370,10 @@ impl WindowDelegate {
|
||||||
// delegate in `window:willUseFullScreenPresentationOptions:`.
|
// delegate in `window:willUseFullScreenPresentationOptions:`.
|
||||||
self.ivars().save_presentation_opts.set(Some(app.presentationOptions()));
|
self.ivars().save_presentation_opts.set(Some(app.presentationOptions()));
|
||||||
|
|
||||||
let presentation_options = NSApplicationPresentationOptions(
|
let presentation_options =
|
||||||
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen.0
|
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen
|
||||||
| NSApplicationPresentationOptions::NSApplicationPresentationHideDock.0
|
| NSApplicationPresentationOptions::NSApplicationPresentationHideDock
|
||||||
| NSApplicationPresentationOptions::NSApplicationPresentationHideMenuBar.0,
|
| NSApplicationPresentationOptions::NSApplicationPresentationHideMenuBar;
|
||||||
);
|
|
||||||
app.setPresentationOptions(presentation_options);
|
app.setPresentationOptions(presentation_options);
|
||||||
|
|
||||||
let window_level = unsafe { ffi::CGShieldingWindowLevel() } as NSWindowLevel + 1;
|
let window_level = unsafe { ffi::CGShieldingWindowLevel() } as NSWindowLevel + 1;
|
||||||
|
|
@ -1391,9 +1381,9 @@ impl WindowDelegate {
|
||||||
},
|
},
|
||||||
(Some(Fullscreen::Exclusive(ref video_mode)), Some(Fullscreen::Borderless(_))) => {
|
(Some(Fullscreen::Exclusive(ref video_mode)), Some(Fullscreen::Borderless(_))) => {
|
||||||
let presentation_options = self.ivars().save_presentation_opts.get().unwrap_or(
|
let presentation_options = self.ivars().save_presentation_opts.get().unwrap_or(
|
||||||
NSApplicationPresentationOptions(NSApplicationPresentationOptions::NSApplicationPresentationFullScreen.0
|
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen
|
||||||
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideDock.0
|
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideDock
|
||||||
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideMenuBar.0),
|
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideMenuBar
|
||||||
);
|
);
|
||||||
app.setPresentationOptions(presentation_options);
|
app.setPresentationOptions(presentation_options);
|
||||||
|
|
||||||
|
|
@ -1432,19 +1422,19 @@ impl WindowDelegate {
|
||||||
|
|
||||||
let new_mask = {
|
let new_mask = {
|
||||||
let mut new_mask = if decorations {
|
let mut new_mask = if decorations {
|
||||||
NSWindowStyleMask::Closable.0
|
NSWindowStyleMask::Closable
|
||||||
| NSWindowStyleMask::Miniaturizable.0
|
| NSWindowStyleMask::Miniaturizable
|
||||||
| NSWindowStyleMask::Resizable.0
|
| NSWindowStyleMask::Resizable
|
||||||
| NSWindowStyleMask::Titled.0
|
| NSWindowStyleMask::Titled
|
||||||
} else {
|
} else {
|
||||||
NSWindowStyleMask::Borderless.0 | NSWindowStyleMask::Resizable.0
|
NSWindowStyleMask::Borderless | NSWindowStyleMask::Resizable
|
||||||
};
|
};
|
||||||
if !resizable {
|
if !resizable {
|
||||||
new_mask &= !NSWindowStyleMask::Resizable.0;
|
new_mask &= !NSWindowStyleMask::Resizable;
|
||||||
}
|
}
|
||||||
new_mask
|
new_mask
|
||||||
};
|
};
|
||||||
self.set_style_mask(NSWindowStyleMask(new_mask));
|
self.set_style_mask(new_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -1547,7 +1537,7 @@ impl WindowDelegate {
|
||||||
pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle {
|
pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle {
|
||||||
let mut window_handle = rwh_04::AppKitHandle::empty();
|
let mut window_handle = rwh_04::AppKitHandle::empty();
|
||||||
window_handle.ns_window = self.window() as *const WinitWindow as *mut _;
|
window_handle.ns_window = self.window() as *const WinitWindow as *mut _;
|
||||||
window_handle.ns_view = Id::as_ptr(&self.contentView().unwrap()) as *mut _;
|
window_handle.ns_view = Retained::as_ptr(&self.contentView().unwrap()) as *mut _;
|
||||||
rwh_04::RawWindowHandle::AppKit(window_handle)
|
rwh_04::RawWindowHandle::AppKit(window_handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1556,7 +1546,7 @@ impl WindowDelegate {
|
||||||
pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle {
|
pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle {
|
||||||
let mut window_handle = rwh_05::AppKitWindowHandle::empty();
|
let mut window_handle = rwh_05::AppKitWindowHandle::empty();
|
||||||
window_handle.ns_window = self.window() as *const WinitWindow as *mut _;
|
window_handle.ns_window = self.window() as *const WinitWindow as *mut _;
|
||||||
window_handle.ns_view = Id::as_ptr(&self.view()) as *mut _;
|
window_handle.ns_view = Retained::as_ptr(&self.view()) as *mut _;
|
||||||
rwh_05::RawWindowHandle::AppKit(window_handle)
|
rwh_05::RawWindowHandle::AppKit(window_handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1570,8 +1560,8 @@ impl WindowDelegate {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn raw_window_handle_rwh_06(&self) -> rwh_06::RawWindowHandle {
|
pub fn raw_window_handle_rwh_06(&self) -> rwh_06::RawWindowHandle {
|
||||||
let window_handle = rwh_06::AppKitWindowHandle::new({
|
let window_handle = rwh_06::AppKitWindowHandle::new({
|
||||||
let ptr = Id::as_ptr(&self.view()) as *mut _;
|
let ptr = Retained::as_ptr(&self.view()) as *mut _;
|
||||||
std::ptr::NonNull::new(ptr).expect("Id<T> should never be null")
|
std::ptr::NonNull::new(ptr).expect("Retained<T> should never be null")
|
||||||
});
|
});
|
||||||
rwh_06::RawWindowHandle::AppKit(window_handle)
|
rwh_06::RawWindowHandle::AppKit(window_handle)
|
||||||
}
|
}
|
||||||
|
|
@ -1579,9 +1569,9 @@ impl WindowDelegate {
|
||||||
fn toggle_style_mask(&self, mask: NSWindowStyleMask, on: bool) {
|
fn toggle_style_mask(&self, mask: NSWindowStyleMask, on: bool) {
|
||||||
let current_style_mask = self.window().styleMask();
|
let current_style_mask = self.window().styleMask();
|
||||||
if on {
|
if on {
|
||||||
self.set_style_mask(NSWindowStyleMask(current_style_mask.0 | mask.0));
|
self.set_style_mask(current_style_mask | mask);
|
||||||
} else {
|
} else {
|
||||||
self.set_style_mask(NSWindowStyleMask(current_style_mask.0 & (!mask.0)));
|
self.set_style_mask(current_style_mask & !mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1654,10 +1644,9 @@ impl WindowExtMacOS for WindowDelegate {
|
||||||
self.ivars().is_simple_fullscreen.set(true);
|
self.ivars().is_simple_fullscreen.set(true);
|
||||||
|
|
||||||
// Simulate pre-Lion fullscreen by hiding the dock and menu bar
|
// Simulate pre-Lion fullscreen by hiding the dock and menu bar
|
||||||
let presentation_options = NSApplicationPresentationOptions(
|
let presentation_options =
|
||||||
NSApplicationPresentationOptions::NSApplicationPresentationAutoHideDock.0
|
NSApplicationPresentationOptions::NSApplicationPresentationAutoHideDock
|
||||||
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideMenuBar.0,
|
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideMenuBar;
|
||||||
);
|
|
||||||
app.setPresentationOptions(presentation_options);
|
app.setPresentationOptions(presentation_options);
|
||||||
|
|
||||||
// Hide the titlebar
|
// Hide the titlebar
|
||||||
|
|
@ -1755,10 +1744,6 @@ impl WindowExtMacOS for WindowDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mask_contains(mask: NSWindowStyleMask, value: NSWindowStyleMask) -> bool {
|
|
||||||
mask.0 & value.0 == value.0
|
|
||||||
}
|
|
||||||
|
|
||||||
const DEFAULT_STANDARD_FRAME: NSRect =
|
const DEFAULT_STANDARD_FRAME: NSRect =
|
||||||
NSRect::new(NSPoint::new(50.0, 50.0), NSSize::new(800.0, 600.0));
|
NSRect::new(NSPoint::new(50.0, 50.0), NSSize::new(800.0, 600.0));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue