Format everything and add rustfmt to travis (#951)

* Format everything and add rustfmt to travis

* Remove extern crate winit from examples and add force_multiline_blocks

* Format the code properly

* Fix inconsistent period in PULL_REQUEST_TEMPLATE.md

* Only run rustfmt on nightly

* Travis fixings
This commit is contained in:
Osspial 2019-06-21 11:33:15 -04:00 committed by GitHub
parent b1b5aefc4b
commit e2c84725de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
109 changed files with 4787 additions and 3679 deletions

View file

@ -1,26 +1,23 @@
use std::{mem, ptr};
use std::cell::{RefCell, RefMut};
use std::mem::ManuallyDrop;
use std::os::raw::c_void;
use std::time::Instant;
use std::{
cell::{RefCell, RefMut},
mem::{self, ManuallyDrop},
os::raw::c_void,
ptr,
time::Instant,
};
use crate::event::{Event, StartCause};
use crate::event_loop::ControlFlow;
use crate::{
event::{Event, StartCause},
event_loop::ControlFlow,
};
use crate::platform_impl::platform::event_loop::{EventHandler, Never};
use crate::platform_impl::platform::ffi::{
id,
CFAbsoluteTimeGetCurrent,
CFRelease,
CFRunLoopAddTimer,
CFRunLoopGetMain,
CFRunLoopRef,
CFRunLoopTimerCreate,
CFRunLoopTimerInvalidate,
CFRunLoopTimerRef,
CFRunLoopTimerSetNextFireDate,
kCFRunLoopCommonModes,
NSUInteger,
use crate::platform_impl::platform::{
event_loop::{EventHandler, Never},
ffi::{
id, kCFRunLoopCommonModes, CFAbsoluteTimeGetCurrent, CFRelease, CFRunLoopAddTimer,
CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate, CFRunLoopTimerInvalidate,
CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate, NSUInteger,
},
};
macro_rules! bug {
@ -62,13 +59,19 @@ enum AppStateImpl {
impl Drop for AppStateImpl {
fn drop(&mut self) {
match self {
&mut AppStateImpl::NotLaunched { ref mut queued_windows, .. } |
&mut AppStateImpl::Launching { ref mut queued_windows, .. } => unsafe {
&mut AppStateImpl::NotLaunched {
ref mut queued_windows,
..
}
| &mut AppStateImpl::Launching {
ref mut queued_windows,
..
} => unsafe {
for &mut window in queued_windows {
let () = msg_send![window, release];
}
}
_ => {}
},
_ => {},
}
}
}
@ -88,7 +91,9 @@ impl AppState {
static mut APP_STATE: RefCell<Option<AppState>> = RefCell::new(None);
if cfg!(debug_assertions) {
assert_main_thread!("bug in winit: `AppState::get_mut()` can only be called on the main thread");
assert_main_thread!(
"bug in winit: `AppState::get_mut()` can only be called on the main thread"
);
}
let mut guard = APP_STATE.borrow_mut();
@ -108,26 +113,31 @@ impl AppState {
}
init_guard(&mut guard)
}
RefMut::map(guard, |state| {
state.as_mut().unwrap()
})
RefMut::map(guard, |state| state.as_mut().unwrap())
}
// requires main thread and window is a UIWindow
// retains window
pub unsafe fn set_key_window(window: id) {
let mut this = AppState::get_mut();
match &mut this.app_state {
&mut AppStateImpl::NotLaunched { ref mut queued_windows, .. } => {
&mut AppStateImpl::NotLaunched {
ref mut queued_windows,
..
} => {
queued_windows.push(window);
msg_send![window, retain];
return;
}
},
&mut AppStateImpl::ProcessingEvents { .. } => {},
&mut AppStateImpl::InUserCallback { .. } => {},
&mut AppStateImpl::Terminated => panic!("Attempt to create a `Window` \
after the app has terminated"),
app_state => unreachable!("unexpected state: {:#?}", app_state), // all other cases should be impossible
&mut AppStateImpl::Terminated => {
panic!(
"Attempt to create a `Window` \
after the app has terminated"
)
},
app_state => unreachable!("unexpected state: {:#?}", app_state), /* all other cases should be impossible */
}
drop(this);
msg_send![window, makeKeyAndVisible]
@ -144,15 +154,22 @@ impl AppState {
let windows = ptr::read(queued_windows);
let events = ptr::read(queued_events);
(windows, events)
}
_ => panic!("winit iOS expected the app to be in a `NotLaunched` \
state, but was not - please file an issue"),
},
_ => {
panic!(
"winit iOS expected the app to be in a `NotLaunched` \
state, but was not - please file an issue"
)
},
};
ptr::write(&mut this.app_state, AppStateImpl::Launching {
queued_windows,
queued_events,
queued_event_handler,
});
ptr::write(
&mut this.app_state,
AppStateImpl::Launching {
queued_windows,
queued_events,
queued_event_handler,
},
);
}
// requires main thread
@ -163,10 +180,12 @@ impl AppState {
ref mut queued_windows,
..
} => mem::replace(queued_windows, Vec::new()),
_ => panic!(
"winit iOS expected the app to be in a `Launching` \
state, but was not - please file an issue"
),
_ => {
panic!(
"winit iOS expected the app to be in a `Launching` \
state, but was not - please file an issue"
)
},
};
// have to drop RefMut because the window setup code below can trigger new events
drop(this);
@ -188,11 +207,11 @@ impl AppState {
let screen: id = msg_send![window, screen];
let () = msg_send![screen, retain];
let () = msg_send![window, setScreen:0 as id];
let () = msg_send![window, setScreen:screen];
let () = msg_send![window, setScreen: screen];
let () = msg_send![screen, release];
let controller: id = msg_send![window, rootViewController];
let () = msg_send![window, setRootViewController:ptr::null::<()>()];
let () = msg_send![window, setRootViewController:controller];
let () = msg_send![window, setRootViewController: controller];
let () = msg_send![window, makeKeyAndVisible];
}
let () = msg_send![window, release];
@ -209,16 +228,23 @@ impl AppState {
let events = ptr::read(queued_events);
let event_handler = ptr::read(queued_event_handler);
(windows, events, event_handler)
}
_ => panic!("winit iOS expected the app to be in a `Launching` \
state, but was not - please file an issue"),
},
_ => {
panic!(
"winit iOS expected the app to be in a `Launching` \
state, but was not - please file an issue"
)
},
};
ptr::write(&mut this.app_state, AppStateImpl::ProcessingEvents {
event_handler,
active_control_flow: ControlFlow::Poll,
});
ptr::write(
&mut this.app_state,
AppStateImpl::ProcessingEvents {
event_handler,
active_control_flow: ControlFlow::Poll,
},
);
drop(this);
let events = std::iter::once(Event::NewEvents(StartCause::Init)).chain(events);
AppState::handle_nonuser_events(events);
@ -238,69 +264,79 @@ impl AppState {
// AppState::did_finish_launching handles the special transition `Init`
pub unsafe fn handle_wakeup_transition() {
let mut this = AppState::get_mut();
let event = match this.control_flow {
ControlFlow::Poll => {
let event_handler = match &mut this.app_state {
&mut AppStateImpl::NotLaunched { .. } |
&mut AppStateImpl::Launching { .. } => return,
&mut AppStateImpl::PollFinished {
ref mut waiting_event_handler,
} => ptr::read(waiting_event_handler),
_ => bug!("`EventHandler` unexpectedly started polling"),
};
ptr::write(&mut this.app_state, AppStateImpl::ProcessingEvents {
event_handler,
active_control_flow: ControlFlow::Poll,
});
Event::NewEvents(StartCause::Poll)
}
ControlFlow::Wait => {
let (event_handler, start) = match &mut this.app_state {
&mut AppStateImpl::NotLaunched { .. } |
&mut AppStateImpl::Launching { .. } => return,
&mut AppStateImpl::Waiting {
ref mut waiting_event_handler,
ref mut start,
} => (ptr::read(waiting_event_handler), *start),
_ => bug!("`EventHandler` unexpectedly woke up"),
};
ptr::write(&mut this.app_state, AppStateImpl::ProcessingEvents {
event_handler,
active_control_flow: ControlFlow::Wait,
});
Event::NewEvents(StartCause::WaitCancelled {
start,
requested_resume: None,
})
}
ControlFlow::WaitUntil(requested_resume) => {
let (event_handler, start) = match &mut this.app_state {
&mut AppStateImpl::NotLaunched { .. } |
&mut AppStateImpl::Launching { .. } => return,
&mut AppStateImpl::Waiting {
ref mut waiting_event_handler,
ref mut start,
} => (ptr::read(waiting_event_handler), *start),
_ => bug!("`EventHandler` unexpectedly woke up"),
};
ptr::write(&mut this.app_state, AppStateImpl::ProcessingEvents {
event_handler,
active_control_flow: ControlFlow::WaitUntil(requested_resume),
});
if Instant::now() >= requested_resume {
Event::NewEvents(StartCause::ResumeTimeReached {
start,
requested_resume,
})
} else {
let event =
match this.control_flow {
ControlFlow::Poll => {
let event_handler = match &mut this.app_state {
&mut AppStateImpl::NotLaunched { .. }
| &mut AppStateImpl::Launching { .. } => return,
&mut AppStateImpl::PollFinished {
ref mut waiting_event_handler,
} => ptr::read(waiting_event_handler),
_ => bug!("`EventHandler` unexpectedly started polling"),
};
ptr::write(
&mut this.app_state,
AppStateImpl::ProcessingEvents {
event_handler,
active_control_flow: ControlFlow::Poll,
},
);
Event::NewEvents(StartCause::Poll)
},
ControlFlow::Wait => {
let (event_handler, start) = match &mut this.app_state {
&mut AppStateImpl::NotLaunched { .. }
| &mut AppStateImpl::Launching { .. } => return,
&mut AppStateImpl::Waiting {
ref mut waiting_event_handler,
ref mut start,
} => (ptr::read(waiting_event_handler), *start),
_ => bug!("`EventHandler` unexpectedly woke up"),
};
ptr::write(
&mut this.app_state,
AppStateImpl::ProcessingEvents {
event_handler,
active_control_flow: ControlFlow::Wait,
},
);
Event::NewEvents(StartCause::WaitCancelled {
start,
requested_resume: Some(requested_resume),
requested_resume: None,
})
}
}
ControlFlow::Exit => bug!("unexpected controlflow `Exit`"),
};
},
ControlFlow::WaitUntil(requested_resume) => {
let (event_handler, start) = match &mut this.app_state {
&mut AppStateImpl::NotLaunched { .. }
| &mut AppStateImpl::Launching { .. } => return,
&mut AppStateImpl::Waiting {
ref mut waiting_event_handler,
ref mut start,
} => (ptr::read(waiting_event_handler), *start),
_ => bug!("`EventHandler` unexpectedly woke up"),
};
ptr::write(
&mut this.app_state,
AppStateImpl::ProcessingEvents {
event_handler,
active_control_flow: ControlFlow::WaitUntil(requested_resume),
},
);
if Instant::now() >= requested_resume {
Event::NewEvents(StartCause::ResumeTimeReached {
start,
requested_resume,
})
} else {
Event::NewEvents(StartCause::WaitCancelled {
start,
requested_resume: Some(requested_resume),
})
}
},
ControlFlow::Exit => bug!("unexpected controlflow `Exit`"),
};
drop(this);
AppState::handle_nonuser_event(event)
}
@ -328,8 +364,8 @@ impl AppState {
..
} => {
queued_events.extend(events);
return
}
return;
},
&mut AppStateImpl::ProcessingEvents {
ref mut event_handler,
ref mut active_control_flow,
@ -338,9 +374,12 @@ impl AppState {
| &mut AppStateImpl::Waiting { .. }
| &mut AppStateImpl::Terminated => bug!("unexpected attempted to process an event"),
};
ptr::write(&mut this.app_state, AppStateImpl::InUserCallback {
queued_events: Vec::new(),
});
ptr::write(
&mut this.app_state,
AppStateImpl::InUserCallback {
queued_events: Vec::new(),
},
);
drop(this);
for event in events {
@ -360,7 +399,7 @@ impl AppState {
active_control_flow,
};
this.control_flow = control_flow;
break
break;
}
drop(this);
for event in queued_events {
@ -384,9 +423,12 @@ impl AppState {
| &mut AppStateImpl::Waiting { .. }
| &mut AppStateImpl::Terminated => bug!("unexpected attempted to process an event"),
};
ptr::write(&mut this.app_state, AppStateImpl::InUserCallback {
queued_events: Vec::new(),
});
ptr::write(
&mut this.app_state,
AppStateImpl::InUserCallback {
queued_events: Vec::new(),
},
);
drop(this);
event_handler.handle_user_events(&mut control_flow);
@ -404,7 +446,7 @@ impl AppState {
active_control_flow,
};
this.control_flow = control_flow;
break
break;
}
drop(this);
for event in queued_events {
@ -419,7 +461,7 @@ impl AppState {
let mut this = AppState::get_mut();
match &mut this.app_state {
&mut AppStateImpl::NotLaunched { .. } | &mut AppStateImpl::Launching { .. } => return,
&mut AppStateImpl::ProcessingEvents { .. } => {}
&mut AppStateImpl::ProcessingEvents { .. } => {},
_ => unreachable!(),
};
drop(this);
@ -432,7 +474,12 @@ impl AppState {
&mut AppStateImpl::ProcessingEvents {
ref mut event_handler,
ref mut active_control_flow,
} => (ManuallyDrop::new(ptr::read(event_handler)), *active_control_flow),
} => {
(
ManuallyDrop::new(ptr::read(event_handler)),
*active_control_flow,
)
},
_ => unreachable!(),
};
@ -457,7 +504,8 @@ impl AppState {
)
},
(ControlFlow::WaitUntil(old_instant), ControlFlow::WaitUntil(new_instant))
if old_instant == new_instant => {
if old_instant == new_instant =>
{
let start = Instant::now();
ptr::write(
&mut this.app_state,
@ -503,7 +551,7 @@ impl AppState {
// it is not possible to quit an iOS app gracefully and programatically
warn!("`ControlFlow::Exit` ignored on iOS");
this.control_flow = old
}
},
}
}
@ -511,7 +559,11 @@ impl AppState {
let mut this = unsafe { AppState::get_mut() };
let mut old = mem::replace(&mut this.app_state, AppStateImpl::Terminated);
let mut control_flow = this.control_flow;
if let AppStateImpl::ProcessingEvents { ref mut event_handler, .. } = old {
if let AppStateImpl::ProcessingEvents {
ref mut event_handler,
..
} = old
{
drop(this);
event_handler.handle_nonuser_event(Event::LoopDestroyed, &mut control_flow)
} else {
@ -535,7 +587,7 @@ impl Drop for EventLoopWaker {
impl EventLoopWaker {
fn new(rl: CFRunLoopRef) -> EventLoopWaker {
extern fn wakeup_main_loop(_timer: CFRunLoopTimerRef, _info: *mut c_void) {}
extern "C" fn wakeup_main_loop(_timer: CFRunLoopTimerRef, _info: *mut c_void) {}
unsafe {
// create a timer with a 1microsec interval (1ns does not work) to mimic polling.
// it is initially setup with a first fire time really far into the
@ -577,4 +629,4 @@ impl EventLoopWaker {
}
}
}
}
}

View file

@ -1,50 +1,33 @@
use std::{mem, ptr};
use std::collections::VecDeque;
use std::ffi::c_void;
use std::fmt::{self, Debug, Formatter};
use std::marker::PhantomData;
use std::sync::mpsc::{self, Sender, Receiver};
use crate::event::Event;
use crate::event_loop::{
ControlFlow,
EventLoopWindowTarget as RootEventLoopWindowTarget,
EventLoopClosed,
use std::{
collections::VecDeque,
ffi::c_void,
fmt::{self, Debug, Formatter},
marker::PhantomData,
mem, ptr,
sync::mpsc::{self, Receiver, Sender},
};
use crate::platform::ios::Idiom;
use crate::platform_impl::platform::app_state::AppState;
use crate::platform_impl::platform::ffi::{
id,
nil,
CFIndex,
CFRelease,
CFRunLoopActivity,
CFRunLoopAddObserver,
CFRunLoopAddSource,
CFRunLoopGetMain,
CFRunLoopObserverCreate,
CFRunLoopObserverRef,
CFRunLoopSourceContext,
CFRunLoopSourceCreate,
CFRunLoopSourceInvalidate,
CFRunLoopSourceRef,
CFRunLoopSourceSignal,
CFRunLoopWakeUp,
kCFRunLoopCommonModes,
kCFRunLoopDefaultMode,
kCFRunLoopEntry,
kCFRunLoopBeforeWaiting,
kCFRunLoopAfterWaiting,
kCFRunLoopExit,
NSOperatingSystemVersion,
NSString,
UIApplicationMain,
UIUserInterfaceIdiom,
use crate::{
event::Event,
event_loop::{
ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootEventLoopWindowTarget,
},
platform::ios::Idiom,
};
use crate::platform_impl::platform::{
app_state::AppState,
ffi::{
id, kCFRunLoopAfterWaiting, kCFRunLoopBeforeWaiting, kCFRunLoopCommonModes,
kCFRunLoopDefaultMode, kCFRunLoopEntry, kCFRunLoopExit, nil, CFIndex, CFRelease,
CFRunLoopActivity, CFRunLoopAddObserver, CFRunLoopAddSource, CFRunLoopGetMain,
CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext,
CFRunLoopSourceCreate, CFRunLoopSourceInvalidate, CFRunLoopSourceRef,
CFRunLoopSourceSignal, CFRunLoopWakeUp, NSOperatingSystemVersion, NSString,
UIApplicationMain, UIUserInterfaceIdiom,
},
monitor, view, MonitorHandle,
};
use crate::platform_impl::platform::monitor;
use crate::platform_impl::platform::MonitorHandle;
use crate::platform_impl::platform::view;
pub struct EventLoopWindowTarget<T: 'static> {
receiver: Receiver<T>,
@ -67,8 +50,11 @@ impl<T: 'static> EventLoop<T> {
static mut SINGLETON_INIT: bool = false;
unsafe {
assert_main_thread!("`EventLoop` can only be created on the main thread on iOS");
assert!(!SINGLETON_INIT, "Only one `EventLoop` is supported on iOS. \
`EventLoopProxy` might be helpful");
assert!(
!SINGLETON_INIT,
"Only one `EventLoop` is supported on iOS. \
`EventLoopProxy` might be helpful"
);
SINGLETON_INIT = true;
view::create_delegate_class();
}
@ -92,25 +78,34 @@ impl<T: 'static> EventLoop<T> {
capabilities,
},
_marker: PhantomData,
}
},
}
}
pub fn run<F>(self, event_handler: F) -> !
where
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow)
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
{
unsafe {
let application: *mut c_void = msg_send![class!(UIApplication), sharedApplication];
assert_eq!(application, ptr::null_mut(), "\
`EventLoop` cannot be `run` after a call to `UIApplicationMain` on iOS\n\
Note: `EventLoop::run` calls `UIApplicationMain` on iOS");
assert_eq!(
application,
ptr::null_mut(),
"\
`EventLoop` cannot be `run` after a call to `UIApplicationMain` on iOS\n\
Note: `EventLoop::run` calls `UIApplicationMain` on iOS"
);
AppState::will_launch(Box::new(EventLoopHandler {
f: event_handler,
event_loop: self.window_target,
}));
UIApplicationMain(0, ptr::null(), nil, NSString::alloc(nil).init_str("AppDelegate"));
UIApplicationMain(
0,
ptr::null(),
nil,
NSString::alloc(nil).init_str("AppDelegate"),
);
unreachable!()
}
}
@ -121,16 +116,12 @@ impl<T: 'static> EventLoop<T> {
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
// guaranteed to be on main thread
unsafe {
monitor::uiscreens()
}
unsafe { monitor::uiscreens() }
}
pub fn primary_monitor(&self) -> MonitorHandle {
// guaranteed to be on main thread
unsafe {
monitor::main_uiscreen()
}
unsafe { monitor::main_uiscreen() }
}
pub fn window_target(&self) -> &RootEventLoopWindowTarget<T> {
@ -142,9 +133,7 @@ impl<T: 'static> EventLoop<T> {
impl<T: 'static> EventLoop<T> {
pub fn idiom(&self) -> Idiom {
// guaranteed to be on main thread
unsafe {
self::get_idiom()
}
unsafe { self::get_idiom() }
}
}
@ -183,18 +172,12 @@ impl<T> EventLoopProxy<T> {
// we want all the members of context to be zero/null, except one
let mut context: CFRunLoopSourceContext = mem::zeroed();
context.perform = event_loop_proxy_handler;
let source = CFRunLoopSourceCreate(
ptr::null_mut(),
CFIndex::max_value() - 1,
&mut context,
);
let source =
CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::max_value() - 1, &mut context);
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
CFRunLoopWakeUp(rl);
EventLoopProxy {
sender,
source,
}
EventLoopProxy { sender, source }
}
}
@ -213,7 +196,7 @@ impl<T> EventLoopProxy<T> {
fn setup_control_flow_observers() {
unsafe {
// begin is queued with the highest priority to ensure it is processed before other observers
extern fn control_flow_begin_handler(
extern "C" fn control_flow_begin_handler(
_: CFRunLoopObserverRef,
activity: CFRunLoopActivity,
_: *mut c_void,
@ -230,7 +213,7 @@ fn setup_control_flow_observers() {
// end is queued with the lowest priority to ensure it is processed after other observers
// without that, LoopDestroyed will get sent after EventsCleared
extern fn control_flow_end_handler(
extern "C" fn control_flow_end_handler(
_: CFRunLoopObserverRef,
activity: CFRunLoopActivity,
_: *mut c_void,
@ -282,7 +265,8 @@ struct EventLoopHandler<F, T: 'static> {
impl<F, T: 'static> Debug for EventLoopHandler<F, T> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.debug_struct("EventLoopHandler")
formatter
.debug_struct("EventLoopHandler")
.field("event_loop", &self.event_loop)
.finish()
}
@ -303,11 +287,7 @@ where
fn handle_user_events(&mut self, control_flow: &mut ControlFlow) {
for event in self.event_loop.p.receiver.try_iter() {
(self.f)(
Event::UserEvent(event),
&self.event_loop,
control_flow,
);
(self.f)(Event::UserEvent(event), &self.event_loop, control_flow);
}
}
}
@ -325,7 +305,10 @@ pub struct Capabilities {
impl From<NSOperatingSystemVersion> for Capabilities {
fn from(os_version: NSOperatingSystemVersion) -> Capabilities {
assert!(os_version.major >= 8, "`winit` current requires iOS version 8 or greater");
assert!(
os_version.major >= 8,
"`winit` current requires iOS version 8 or greater"
);
let supports_safe_area = os_version.major >= 11;

View file

@ -1,11 +1,8 @@
#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
use std::ffi::CString;
use std::ops::BitOr;
use std::os::raw::*;
use std::{ffi::CString, ops::BitOr, os::raw::*};
use objc::{Encode, Encoding};
use objc::runtime::Object;
use objc::{runtime::Object, Encode, Encoding};
use crate::platform::ios::{Idiom, ValidOrientations};
@ -87,7 +84,9 @@ pub struct UIEdgeInsets {
pub struct UIUserInterfaceIdiom(NSInteger);
unsafe impl Encode for UIUserInterfaceIdiom {
fn encode() -> Encoding { NSInteger::encode() }
fn encode() -> Encoding {
NSInteger::encode()
}
}
impl UIUserInterfaceIdiom {
@ -128,7 +127,9 @@ impl Into<Idiom> for UIUserInterfaceIdiom {
pub struct UIInterfaceOrientationMask(NSUInteger);
unsafe impl Encode for UIInterfaceOrientationMask {
fn encode() -> Encoding { NSUInteger::encode() }
fn encode() -> Encoding {
NSUInteger::encode()
}
}
impl UIInterfaceOrientationMask {
@ -136,9 +137,12 @@ impl UIInterfaceOrientationMask {
pub const PortraitUpsideDown: UIInterfaceOrientationMask = UIInterfaceOrientationMask(1 << 2);
pub const LandscapeLeft: UIInterfaceOrientationMask = UIInterfaceOrientationMask(1 << 4);
pub const LandscapeRight: UIInterfaceOrientationMask = UIInterfaceOrientationMask(1 << 3);
pub const Landscape: UIInterfaceOrientationMask = UIInterfaceOrientationMask(Self::LandscapeLeft.0 | Self::LandscapeRight.0);
pub const AllButUpsideDown: UIInterfaceOrientationMask = UIInterfaceOrientationMask(Self::Landscape.0 | Self::Portrait.0);
pub const All: UIInterfaceOrientationMask = UIInterfaceOrientationMask(Self::AllButUpsideDown.0 | Self::PortraitUpsideDown.0);
pub const Landscape: UIInterfaceOrientationMask =
UIInterfaceOrientationMask(Self::LandscapeLeft.0 | Self::LandscapeRight.0);
pub const AllButUpsideDown: UIInterfaceOrientationMask =
UIInterfaceOrientationMask(Self::Landscape.0 | Self::Portrait.0);
pub const All: UIInterfaceOrientationMask =
UIInterfaceOrientationMask(Self::AllButUpsideDown.0 | Self::PortraitUpsideDown.0);
}
impl BitOr for UIInterfaceOrientationMask {
@ -155,18 +159,23 @@ impl UIInterfaceOrientationMask {
idiom: Idiom,
) -> UIInterfaceOrientationMask {
match (valid_orientations, idiom) {
(ValidOrientations::LandscapeAndPortrait, Idiom::Phone) => UIInterfaceOrientationMask::AllButUpsideDown,
(ValidOrientations::LandscapeAndPortrait, Idiom::Phone) => {
UIInterfaceOrientationMask::AllButUpsideDown
},
(ValidOrientations::LandscapeAndPortrait, _) => UIInterfaceOrientationMask::All,
(ValidOrientations::Landscape, _) => UIInterfaceOrientationMask::Landscape,
(ValidOrientations::Portrait, Idiom::Phone) => UIInterfaceOrientationMask::Portrait,
(ValidOrientations::Portrait, _) => UIInterfaceOrientationMask::Portrait | UIInterfaceOrientationMask::PortraitUpsideDown,
(ValidOrientations::Portrait, _) => {
UIInterfaceOrientationMask::Portrait
| UIInterfaceOrientationMask::PortraitUpsideDown
},
}
}
}
#[link(name = "UIKit", kind = "framework")]
#[link(name = "CoreFoundation", kind = "framework")]
extern {
extern "C" {
pub static kCFRunLoopDefaultMode: CFRunLoopMode;
pub static kCFRunLoopCommonModes: CFRunLoopMode;
@ -203,15 +212,8 @@ extern {
callout: CFRunLoopTimerCallBack,
context: *mut CFRunLoopTimerContext,
) -> CFRunLoopTimerRef;
pub fn CFRunLoopAddTimer(
rl: CFRunLoopRef,
timer: CFRunLoopTimerRef,
mode: CFRunLoopMode,
);
pub fn CFRunLoopTimerSetNextFireDate(
timer: CFRunLoopTimerRef,
fireDate: CFAbsoluteTime,
);
pub fn CFRunLoopAddTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFRunLoopMode);
pub fn CFRunLoopTimerSetNextFireDate(timer: CFRunLoopTimerRef, fireDate: CFAbsoluteTime);
pub fn CFRunLoopTimerInvalidate(time: CFRunLoopTimerRef);
pub fn CFRunLoopSourceCreate(
@ -219,11 +221,7 @@ extern {
order: CFIndex,
context: *mut CFRunLoopSourceContext,
) -> CFRunLoopSourceRef;
pub fn CFRunLoopAddSource(
rl: CFRunLoopRef,
source: CFRunLoopSourceRef,
mode: CFRunLoopMode,
);
pub fn CFRunLoopAddSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFRunLoopMode);
pub fn CFRunLoopSourceInvalidate(source: CFRunLoopSourceRef);
pub fn CFRunLoopSourceSignal(source: CFRunLoopSourceRef);
@ -259,15 +257,9 @@ pub const kCFRunLoopBeforeWaiting: CFRunLoopActivity = 1 << 5;
pub const kCFRunLoopAfterWaiting: CFRunLoopActivity = 1 << 6;
pub const kCFRunLoopExit: CFRunLoopActivity = 1 << 7;
pub type CFRunLoopObserverCallBack = extern "C" fn(
observer: CFRunLoopObserverRef,
activity: CFRunLoopActivity,
info: *mut c_void,
);
pub type CFRunLoopTimerCallBack = extern "C" fn(
timer: CFRunLoopTimerRef,
info: *mut c_void,
);
pub type CFRunLoopObserverCallBack =
extern "C" fn(observer: CFRunLoopObserverRef, activity: CFRunLoopActivity, info: *mut c_void);
pub type CFRunLoopTimerCallBack = extern "C" fn(timer: CFRunLoopTimerRef, info: *mut c_void);
pub enum CFRunLoopObserverContext {}
pub enum CFRunLoopTimerContext {}
@ -299,11 +291,11 @@ pub trait NSString: Sized {
impl NSString for id {
unsafe fn initWithUTF8String_(self, c_string: *const c_char) -> id {
msg_send![self, initWithUTF8String:c_string as id]
msg_send![self, initWithUTF8String: c_string as id]
}
unsafe fn stringByAppendingString_(self, other: id) -> id {
msg_send![self, stringByAppendingString:other]
msg_send![self, stringByAppendingString: other]
}
unsafe fn init_str(self, string: &str) -> id {

View file

@ -26,7 +26,6 @@
//! fn start_inner() {
//! ...
//! }
//!
//! ```
//!
//! Compile project and then drag resulting .a into Xcode project. Add winit.h to xcode.
@ -78,12 +77,10 @@ mod window;
use std::fmt;
pub use self::event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget};
pub use self::monitor::MonitorHandle;
pub use self::window::{
PlatformSpecificWindowBuilderAttributes,
Window,
WindowId,
pub use self::{
event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget},
monitor::MonitorHandle,
window::{PlatformSpecificWindowBuilderAttributes, Window, WindowId},
};
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -108,7 +105,7 @@ pub enum OsError {}
impl fmt::Display for OsError {
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
_ => unreachable!()
_ => unreachable!(),
}
}
}

View file

@ -4,10 +4,14 @@ use std::{
ops::{Deref, DerefMut},
};
use crate::dpi::{PhysicalPosition, PhysicalSize};
use crate::monitor::VideoMode;
use crate::{
dpi::{PhysicalPosition, PhysicalSize},
monitor::VideoMode,
};
use crate::platform_impl::platform::ffi::{id, nil, CGFloat, CGRect, CGSize, NSInteger, NSUInteger};
use crate::platform_impl::platform::ffi::{
id, nil, CGFloat, CGRect, CGSize, NSInteger, NSUInteger,
};
pub struct Inner {
uiscreen: id,
@ -30,7 +34,9 @@ impl Deref for MonitorHandle {
fn deref(&self) -> &Inner {
unsafe {
assert_main_thread!("`MonitorHandle` methods can only be run on the main thread on iOS");
assert_main_thread!(
"`MonitorHandle` methods can only be run on the main thread on iOS"
);
}
&self.inner
}
@ -39,7 +45,9 @@ impl Deref for MonitorHandle {
impl DerefMut for MonitorHandle {
fn deref_mut(&mut self) -> &mut Inner {
unsafe {
assert_main_thread!("`MonitorHandle` methods can only be run on the main thread on iOS");
assert_main_thread!(
"`MonitorHandle` methods can only be run on the main thread on iOS"
);
}
&mut self.inner
}
@ -89,7 +97,9 @@ impl MonitorHandle {
assert_main_thread!("`MonitorHandle` can only be cloned on the main thread on iOS");
let () = msg_send![uiscreen, retain];
}
MonitorHandle { inner: Inner { uiscreen } }
MonitorHandle {
inner: Inner { uiscreen },
}
}
}
@ -180,7 +190,7 @@ pub unsafe fn uiscreens() -> VecDeque<MonitorHandle> {
loop {
let screen: id = msg_send![screens_enum, nextObject];
if screen == nil {
break result
break result;
}
result.push_back(MonitorHandle::retained_new(screen));
}

View file

@ -1,31 +1,23 @@
use std::collections::HashMap;
use objc::declare::ClassDecl;
use objc::runtime::{BOOL, Class, NO, Object, Sel, YES};
use crate::event::{
DeviceId as RootDeviceId,
Event,
Touch,
TouchPhase,
WindowEvent
use objc::{
declare::ClassDecl,
runtime::{Class, Object, Sel, BOOL, NO, YES},
};
use crate::platform::ios::MonitorHandleExtIOS;
use crate::window::{WindowAttributes, WindowId as RootWindowId};
use crate::platform_impl::platform::app_state::AppState;
use crate::platform_impl::platform::DeviceId;
use crate::platform_impl::platform::event_loop;
use crate::platform_impl::platform::ffi::{
id,
nil,
CGFloat,
CGPoint,
CGRect,
UIInterfaceOrientationMask,
UITouchPhase,
use crate::{
event::{DeviceId as RootDeviceId, Event, Touch, TouchPhase, WindowEvent},
platform::ios::MonitorHandleExtIOS,
window::{WindowAttributes, WindowId as RootWindowId},
};
use crate::platform_impl::platform::{
app_state::AppState,
event_loop,
ffi::{id, nil, CGFloat, CGPoint, CGRect, UIInterfaceOrientationMask, UITouchPhase},
window::PlatformSpecificWindowBuilderAttributes,
DeviceId,
};
use crate::platform_impl::platform::window::{PlatformSpecificWindowBuilderAttributes};
// requires main thread
unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
@ -40,10 +32,13 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
classes.entry(root_view_class).or_insert_with(move || {
let uiview_class = class!(UIView);
let is_uiview: BOOL = msg_send![root_view_class, isSubclassOfClass:uiview_class];
assert_eq!(is_uiview, YES, "`root_view_class` must inherit from `UIView`");
let is_uiview: BOOL = msg_send![root_view_class, isSubclassOfClass: uiview_class];
assert_eq!(
is_uiview, YES,
"`root_view_class` must inherit from `UIView`"
);
extern fn draw_rect(object: &Object, _: Sel, rect: CGRect) {
extern "C" fn draw_rect(object: &Object, _: Sel, rect: CGRect) {
unsafe {
let window: id = msg_send![object, window];
AppState::handle_nonuser_event(Event::WindowEvent {
@ -55,13 +50,14 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
}
}
extern fn layout_subviews(object: &Object, _: Sel) {
extern "C" fn layout_subviews(object: &Object, _: Sel) {
unsafe {
let window: id = msg_send![object, window];
let bounds: CGRect = msg_send![window, bounds];
let screen: id = msg_send![window, screen];
let screen_space: id = msg_send![screen, coordinateSpace];
let screen_frame: CGRect = msg_send![object, convertRect:bounds toCoordinateSpace:screen_space];
let screen_frame: CGRect =
msg_send![object, convertRect:bounds toCoordinateSpace:screen_space];
let size = crate::dpi::LogicalSize {
width: screen_frame.size.width,
height: screen_frame.size.height,
@ -78,10 +74,14 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
let mut decl = ClassDecl::new(&format!("WinitUIView{}", ID), root_view_class)
.expect("Failed to declare class `WinitUIView`");
ID += 1;
decl.add_method(sel!(drawRect:),
draw_rect as extern fn(&Object, Sel, CGRect));
decl.add_method(sel!(layoutSubviews),
layout_subviews as extern fn(&Object, Sel));
decl.add_method(
sel!(drawRect:),
draw_rect as extern "C" fn(&Object, Sel, CGRect),
);
decl.add_method(
sel!(layoutSubviews),
layout_subviews as extern "C" fn(&Object, Sel),
);
decl.register()
})
}
@ -92,33 +92,39 @@ unsafe fn get_view_controller_class() -> &'static Class {
if CLASS.is_none() {
let uiviewcontroller_class = class!(UIViewController);
extern fn set_prefers_status_bar_hidden(object: &mut Object, _: Sel, hidden: BOOL) {
extern "C" fn set_prefers_status_bar_hidden(object: &mut Object, _: Sel, hidden: BOOL) {
unsafe {
object.set_ivar::<BOOL>("_prefers_status_bar_hidden", hidden);
let () = msg_send![object, setNeedsStatusBarAppearanceUpdate];
}
}
extern fn prefers_status_bar_hidden(object: &Object, _: Sel) -> BOOL {
unsafe {
*object.get_ivar::<BOOL>("_prefers_status_bar_hidden")
}
extern "C" fn prefers_status_bar_hidden(object: &Object, _: Sel) -> BOOL {
unsafe { *object.get_ivar::<BOOL>("_prefers_status_bar_hidden") }
}
extern fn set_supported_orientations(object: &mut Object, _: Sel, orientations: UIInterfaceOrientationMask) {
extern "C" fn set_supported_orientations(
object: &mut Object,
_: Sel,
orientations: UIInterfaceOrientationMask,
) {
unsafe {
object.set_ivar::<UIInterfaceOrientationMask>("_supported_orientations", orientations);
object.set_ivar::<UIInterfaceOrientationMask>(
"_supported_orientations",
orientations,
);
let () = msg_send![class!(UIViewController), attemptRotationToDeviceOrientation];
}
}
extern fn supported_orientations(object: &Object, _: Sel) -> UIInterfaceOrientationMask {
unsafe {
*object.get_ivar::<UIInterfaceOrientationMask>("_supported_orientations")
}
extern "C" fn supported_orientations(
object: &Object,
_: Sel,
) -> UIInterfaceOrientationMask {
unsafe { *object.get_ivar::<UIInterfaceOrientationMask>("_supported_orientations") }
}
extern fn should_autorotate(_: &Object, _: Sel) -> BOOL {
extern "C" fn should_autorotate(_: &Object, _: Sel) -> BOOL {
YES
}
@ -126,16 +132,27 @@ unsafe fn get_view_controller_class() -> &'static Class {
.expect("Failed to declare class `WinitUIViewController`");
decl.add_ivar::<BOOL>("_prefers_status_bar_hidden");
decl.add_ivar::<UIInterfaceOrientationMask>("_supported_orientations");
decl.add_method(sel!(setPrefersStatusBarHidden:),
set_prefers_status_bar_hidden as extern fn(&mut Object, Sel, BOOL));
decl.add_method(sel!(prefersStatusBarHidden),
prefers_status_bar_hidden as extern fn(&Object, Sel) -> BOOL);
decl.add_method(sel!(setSupportedInterfaceOrientations:),
set_supported_orientations as extern fn(&mut Object, Sel, UIInterfaceOrientationMask));
decl.add_method(sel!(supportedInterfaceOrientations),
supported_orientations as extern fn(&Object, Sel) -> UIInterfaceOrientationMask);
decl.add_method(sel!(shouldAutorotate),
should_autorotate as extern fn(&Object, Sel) -> BOOL);
decl.add_method(
sel!(setPrefersStatusBarHidden:),
set_prefers_status_bar_hidden as extern "C" fn(&mut Object, Sel, BOOL),
);
decl.add_method(
sel!(prefersStatusBarHidden),
prefers_status_bar_hidden as extern "C" fn(&Object, Sel) -> BOOL,
);
decl.add_method(
sel!(setSupportedInterfaceOrientations:),
set_supported_orientations
as extern "C" fn(&mut Object, Sel, UIInterfaceOrientationMask),
);
decl.add_method(
sel!(supportedInterfaceOrientations),
supported_orientations as extern "C" fn(&Object, Sel) -> UIInterfaceOrientationMask,
);
decl.add_method(
sel!(shouldAutorotate),
should_autorotate as extern "C" fn(&Object, Sel) -> BOOL,
);
CLASS = Some(decl.register());
}
CLASS.unwrap()
@ -147,7 +164,7 @@ unsafe fn get_window_class() -> &'static Class {
if CLASS.is_none() {
let uiwindow_class = class!(UIWindow);
extern fn become_key_window(object: &Object, _: Sel) {
extern "C" fn become_key_window(object: &Object, _: Sel) {
unsafe {
AppState::handle_nonuser_event(Event::WindowEvent {
window_id: RootWindowId(object.into()),
@ -157,7 +174,7 @@ unsafe fn get_window_class() -> &'static Class {
}
}
extern fn resign_key_window(object: &Object, _: Sel) {
extern "C" fn resign_key_window(object: &Object, _: Sel) {
unsafe {
AppState::handle_nonuser_event(Event::WindowEvent {
window_id: RootWindowId(object.into()),
@ -167,7 +184,7 @@ unsafe fn get_window_class() -> &'static Class {
}
}
extern fn handle_touches(object: &Object, _: Sel, touches: id, _:id) {
extern "C" fn handle_touches(object: &Object, _: Sel, touches: id, _: id) {
unsafe {
let uiscreen = msg_send![object, screen];
let touches_enum: id = msg_send![touches, objectEnumerator];
@ -175,9 +192,9 @@ unsafe fn get_window_class() -> &'static Class {
loop {
let touch: id = msg_send![touches_enum, nextObject];
if touch == nil {
break
break;
}
let location: CGPoint = msg_send![touch, locationInView:nil];
let location: CGPoint = msg_send![touch, locationInView: nil];
let touch_id = touch as u64;
let phase: UITouchPhase = msg_send![touch, phase];
let phase = match phase {
@ -203,16 +220,20 @@ unsafe fn get_window_class() -> &'static Class {
}
}
extern fn set_content_scale_factor(object: &mut Object, _: Sel, hidpi_factor: CGFloat) {
extern "C" fn set_content_scale_factor(object: &mut Object, _: Sel, hidpi_factor: CGFloat) {
unsafe {
let () = msg_send![super(object, class!(UIWindow)), setContentScaleFactor:hidpi_factor];
let () = msg_send![
super(object, class!(UIWindow)),
setContentScaleFactor: hidpi_factor
];
let view_controller: id = msg_send![object, rootViewController];
let view: id = msg_send![view_controller, view];
let () = msg_send![view, setContentScaleFactor:hidpi_factor];
let () = msg_send![view, setContentScaleFactor: hidpi_factor];
let bounds: CGRect = msg_send![object, bounds];
let screen: id = msg_send![object, screen];
let screen_space: id = msg_send![screen, coordinateSpace];
let screen_frame: CGRect = msg_send![object, convertRect:bounds toCoordinateSpace:screen_space];
let screen_frame: CGRect =
msg_send![object, convertRect:bounds toCoordinateSpace:screen_space];
let size = crate::dpi::LogicalSize {
width: screen_frame.size.width,
height: screen_frame.size.height,
@ -221,32 +242,47 @@ unsafe fn get_window_class() -> &'static Class {
std::iter::once(Event::WindowEvent {
window_id: RootWindowId(object.into()),
event: WindowEvent::HiDpiFactorChanged(hidpi_factor as _),
}).chain(std::iter::once(Event::WindowEvent {
})
.chain(std::iter::once(Event::WindowEvent {
window_id: RootWindowId(object.into()),
event: WindowEvent::Resized(size),
}))
})),
);
}
}
let mut decl = ClassDecl::new("WinitUIWindow", uiwindow_class)
.expect("Failed to declare class `WinitUIWindow`");
decl.add_method(sel!(becomeKeyWindow),
become_key_window as extern fn(&Object, Sel));
decl.add_method(sel!(resignKeyWindow),
resign_key_window as extern fn(&Object, Sel));
decl.add_method(
sel!(becomeKeyWindow),
become_key_window as extern "C" fn(&Object, Sel),
);
decl.add_method(
sel!(resignKeyWindow),
resign_key_window as extern "C" fn(&Object, Sel),
);
decl.add_method(sel!(touchesBegan:withEvent:),
handle_touches as extern fn(this: &Object, _: Sel, _: id, _:id));
decl.add_method(sel!(touchesMoved:withEvent:),
handle_touches as extern fn(this: &Object, _: Sel, _: id, _:id));
decl.add_method(sel!(touchesEnded:withEvent:),
handle_touches as extern fn(this: &Object, _: Sel, _: id, _:id));
decl.add_method(sel!(touchesCancelled:withEvent:),
handle_touches as extern fn(this: &Object, _: Sel, _: id, _:id));
decl.add_method(
sel!(touchesBegan:withEvent:),
handle_touches as extern "C" fn(this: &Object, _: Sel, _: id, _: id),
);
decl.add_method(
sel!(touchesMoved:withEvent:),
handle_touches as extern "C" fn(this: &Object, _: Sel, _: id, _: id),
);
decl.add_method(
sel!(touchesEnded:withEvent:),
handle_touches as extern "C" fn(this: &Object, _: Sel, _: id, _: id),
);
decl.add_method(
sel!(touchesCancelled:withEvent:),
handle_touches as extern "C" fn(this: &Object, _: Sel, _: id, _: id),
);
decl.add_method(sel!(setContentScaleFactor:),
set_content_scale_factor as extern fn(&mut Object, Sel, CGFloat));
decl.add_method(
sel!(setContentScaleFactor:),
set_content_scale_factor as extern "C" fn(&mut Object, Sel, CGFloat),
);
CLASS = Some(decl.register());
}
@ -263,9 +299,9 @@ pub unsafe fn create_view(
let view: id = msg_send![class, alloc];
assert!(!view.is_null(), "Failed to create `UIView` instance");
let view: id = msg_send![view, initWithFrame:frame];
let view: id = msg_send![view, initWithFrame: frame];
assert!(!view.is_null(), "Failed to initialize `UIView` instance");
let () = msg_send![view, setMultipleTouchEnabled:YES];
let () = msg_send![view, setMultipleTouchEnabled: YES];
view
}
@ -279,9 +315,15 @@ pub unsafe fn create_view_controller(
let class = get_view_controller_class();
let view_controller: id = msg_send![class, alloc];
assert!(!view_controller.is_null(), "Failed to create `UIViewController` instance");
assert!(
!view_controller.is_null(),
"Failed to create `UIViewController` instance"
);
let view_controller: id = msg_send![view_controller, init];
assert!(!view_controller.is_null(), "Failed to initialize `UIViewController` instance");
assert!(
!view_controller.is_null(),
"Failed to initialize `UIViewController` instance"
);
let status_bar_hidden = if window_attributes.decorations {
NO
} else {
@ -292,9 +334,15 @@ pub unsafe fn create_view_controller(
platform_attributes.valid_orientations,
idiom,
);
let () = msg_send![view_controller, setPrefersStatusBarHidden:status_bar_hidden];
let () = msg_send![view_controller, setSupportedInterfaceOrientations:supported_orientations];
let () = msg_send![view_controller, setView:view];
let () = msg_send![
view_controller,
setPrefersStatusBarHidden: status_bar_hidden
];
let () = msg_send![
view_controller,
setSupportedInterfaceOrientations: supported_orientations
];
let () = msg_send![view_controller, setView: view];
view_controller
}
@ -309,11 +357,14 @@ pub unsafe fn create_window(
let window: id = msg_send![class, alloc];
assert!(!window.is_null(), "Failed to create `UIWindow` instance");
let window: id = msg_send![window, initWithFrame:frame];
assert!(!window.is_null(), "Failed to initialize `UIWindow` instance");
let () = msg_send![window, setRootViewController:view_controller];
let window: id = msg_send![window, initWithFrame: frame];
assert!(
!window.is_null(),
"Failed to initialize `UIWindow` instance"
);
let () = msg_send![window, setRootViewController: view_controller];
if let Some(hidpi_factor) = platform_attributes.hidpi_factor {
let () = msg_send![window, setContentScaleFactor:hidpi_factor as CGFloat];
let () = msg_send![window, setContentScaleFactor: hidpi_factor as CGFloat];
}
if let &Some(ref monitor) = &window_attributes.fullscreen {
let () = msg_send![window, setScreen:monitor.ui_screen()];
@ -323,29 +374,25 @@ pub unsafe fn create_window(
}
pub fn create_delegate_class() {
extern fn did_finish_launching(_: &mut Object, _: Sel, _: id, _: id) -> BOOL {
extern "C" fn did_finish_launching(_: &mut Object, _: Sel, _: id, _: id) -> BOOL {
unsafe {
AppState::did_finish_launching();
}
YES
}
extern fn did_become_active(_: &Object, _: Sel, _: id) {
unsafe {
AppState::handle_nonuser_event(Event::Suspended(false))
}
extern "C" fn did_become_active(_: &Object, _: Sel, _: id) {
unsafe { AppState::handle_nonuser_event(Event::Suspended(false)) }
}
extern fn will_resign_active(_: &Object, _: Sel, _: id) {
unsafe {
AppState::handle_nonuser_event(Event::Suspended(true))
}
extern "C" fn will_resign_active(_: &Object, _: Sel, _: id) {
unsafe { AppState::handle_nonuser_event(Event::Suspended(true)) }
}
extern fn will_enter_foreground(_: &Object, _: Sel, _: id) {}
extern fn did_enter_background(_: &Object, _: Sel, _: id) {}
extern "C" fn will_enter_foreground(_: &Object, _: Sel, _: id) {}
extern "C" fn did_enter_background(_: &Object, _: Sel, _: id) {}
extern fn will_terminate(_: &Object, _: Sel, _: id) {
extern "C" fn will_terminate(_: &Object, _: Sel, _: id) {
unsafe {
let app: id = msg_send![class!(UIApplication), sharedApplication];
let windows: id = msg_send![app, windows];
@ -354,9 +401,9 @@ pub fn create_delegate_class() {
loop {
let window: id = msg_send![windows_enum, nextObject];
if window == nil {
break
break;
}
let is_winit_window: BOOL = msg_send![window, isKindOfClass:class!(WinitUIWindow)];
let is_winit_window: BOOL = msg_send![window, isKindOfClass: class!(WinitUIWindow)];
if is_winit_window == YES {
events.push(Event::WindowEvent {
window_id: RootWindowId(window.into()),
@ -370,23 +417,36 @@ pub fn create_delegate_class() {
}
let ui_responder = class!(UIResponder);
let mut decl = ClassDecl::new("AppDelegate", ui_responder).expect("Failed to declare class `AppDelegate`");
let mut decl =
ClassDecl::new("AppDelegate", ui_responder).expect("Failed to declare class `AppDelegate`");
unsafe {
decl.add_method(sel!(application:didFinishLaunchingWithOptions:),
did_finish_launching as extern fn(&mut Object, Sel, id, id) -> BOOL);
decl.add_method(
sel!(application:didFinishLaunchingWithOptions:),
did_finish_launching as extern "C" fn(&mut Object, Sel, id, id) -> BOOL,
);
decl.add_method(sel!(applicationDidBecomeActive:),
did_become_active as extern fn(&Object, Sel, id));
decl.add_method(sel!(applicationWillResignActive:),
will_resign_active as extern fn(&Object, Sel, id));
decl.add_method(sel!(applicationWillEnterForeground:),
will_enter_foreground as extern fn(&Object, Sel, id));
decl.add_method(sel!(applicationDidEnterBackground:),
did_enter_background as extern fn(&Object, Sel, id));
decl.add_method(
sel!(applicationDidBecomeActive:),
did_become_active as extern "C" fn(&Object, Sel, id),
);
decl.add_method(
sel!(applicationWillResignActive:),
will_resign_active as extern "C" fn(&Object, Sel, id),
);
decl.add_method(
sel!(applicationWillEnterForeground:),
will_enter_foreground as extern "C" fn(&Object, Sel, id),
);
decl.add_method(
sel!(applicationDidEnterBackground:),
did_enter_background as extern "C" fn(&Object, Sel, id),
);
decl.add_method(sel!(applicationWillTerminate:),
will_terminate as extern fn(&Object, Sel, id));
decl.add_method(
sel!(applicationWillTerminate:),
will_terminate as extern "C" fn(&Object, Sel, id),
);
decl.register();
}

View file

@ -3,35 +3,21 @@ use std::{
ops::{Deref, DerefMut},
};
use objc::runtime::{Class, NO, Object, YES};
use objc::runtime::{Class, Object, NO, YES};
use crate::dpi::{self, LogicalPosition, LogicalSize};
use crate::error::{ExternalError, NotSupportedError, OsError as RootOsError};
use crate::icon::Icon;
use crate::monitor::MonitorHandle as RootMonitorHandle;
use crate::platform::ios::{MonitorHandleExtIOS, ValidOrientations};
use crate::window::{
CursorIcon,
WindowAttributes,
};
use crate::platform_impl::{
platform::{
use crate::{
dpi::{self, LogicalPosition, LogicalSize},
error::{ExternalError, NotSupportedError, OsError as RootOsError},
icon::Icon,
monitor::MonitorHandle as RootMonitorHandle,
platform::ios::{MonitorHandleExtIOS, ValidOrientations},
platform_impl::platform::{
app_state::AppState,
event_loop,
ffi::{
id,
CGFloat,
CGPoint,
CGRect,
CGSize,
UIEdgeInsets,
UIInterfaceOrientationMask,
},
monitor,
view,
EventLoopWindowTarget,
MonitorHandle
ffi::{id, CGFloat, CGPoint, CGRect, CGSize, UIEdgeInsets, UIInterfaceOrientationMask},
monitor, view, EventLoopWindowTarget, MonitorHandle,
},
window::{CursorIcon, WindowAttributes},
};
pub struct Inner {
@ -59,10 +45,10 @@ impl Inner {
pub fn set_visible(&self, visible: bool) {
match visible {
true => unsafe {
let () = msg_send![self.window, setHidden:NO];
let () = msg_send![self.window, setHidden: NO];
},
false => unsafe {
let () = msg_send![self.window, setHidden:YES];
let () = msg_send![self.window, setHidden: YES];
},
}
}
@ -104,7 +90,7 @@ impl Inner {
size: screen_frame.size,
};
let bounds = self.from_screen_space(new_screen_frame);
let () = msg_send![self.window, setBounds:bounds];
let () = msg_send![self.window, setBounds: bounds];
}
}
@ -181,10 +167,10 @@ impl Inner {
// this is pretty slow on iOS, so avoid doing it if we can
if uiscreen != current {
let () = msg_send![self.window, setScreen:uiscreen];
let () = msg_send![self.window, setScreen: uiscreen];
}
let () = msg_send![self.window, setFrame:bounds];
}
let () = msg_send![self.window, setFrame: bounds];
},
None => warn!("`Window::set_fullscreen(None)` ignored on iOS"),
}
}
@ -213,7 +199,10 @@ impl Inner {
pub fn set_decorations(&self, decorations: bool) {
unsafe {
let status_bar_hidden = if decorations { NO } else { YES };
let () = msg_send![self.view_controller, setPrefersStatusBarHidden:status_bar_hidden];
let () = msg_send![
self.view_controller,
setPrefersStatusBarHidden: status_bar_hidden
];
}
}
@ -232,20 +221,18 @@ impl Inner {
pub fn current_monitor(&self) -> RootMonitorHandle {
unsafe {
let uiscreen: id = msg_send![self.window, screen];
RootMonitorHandle { inner: MonitorHandle::retained_new(uiscreen) }
RootMonitorHandle {
inner: MonitorHandle::retained_new(uiscreen),
}
}
}
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
unsafe {
monitor::uiscreens()
}
unsafe { monitor::uiscreens() }
}
pub fn primary_monitor(&self) -> MonitorHandle {
unsafe {
monitor::main_uiscreen()
}
unsafe { monitor::main_uiscreen() }
}
pub fn id(&self) -> WindowId {
@ -306,23 +293,35 @@ impl Window {
// TODO: transparency, visible
unsafe {
let screen = window_attributes.fullscreen
let screen = window_attributes
.fullscreen
.as_ref()
.map(|screen| screen.ui_screen() as _)
.unwrap_or_else(|| monitor::main_uiscreen().ui_screen());
let screen_bounds: CGRect = msg_send![screen, bounds];
let frame = match window_attributes.inner_size {
Some(dim) => CGRect {
origin: screen_bounds.origin,
size: CGSize { width: dim.width, height: dim.height },
Some(dim) => {
CGRect {
origin: screen_bounds.origin,
size: CGSize {
width: dim.width,
height: dim.height,
},
}
},
None => screen_bounds,
};
let view = view::create_view(&window_attributes, &platform_attributes, frame.clone());
let view_controller = view::create_view_controller(&window_attributes, &platform_attributes, view);
let window = view::create_window(&window_attributes, &platform_attributes, frame, view_controller);
let view_controller =
view::create_view_controller(&window_attributes, &platform_attributes, view);
let window = view::create_window(
&window_attributes,
&platform_attributes,
frame,
view_controller,
);
let supports_safe_area = event_loop.capabilities().supports_safe_area;
@ -342,23 +341,38 @@ impl Window {
// WindowExtIOS
impl Inner {
pub fn ui_window(&self) -> id { self.window }
pub fn ui_view_controller(&self) -> id { self.view_controller }
pub fn ui_view(&self) -> id { self.view }
pub fn ui_window(&self) -> id {
self.window
}
pub fn ui_view_controller(&self) -> id {
self.view_controller
}
pub fn ui_view(&self) -> id {
self.view
}
pub fn set_hidpi_factor(&self, hidpi_factor: f64) {
unsafe {
assert!(dpi::validate_hidpi_factor(hidpi_factor), "`WindowExtIOS::set_hidpi_factor` received an invalid hidpi factor");
assert!(
dpi::validate_hidpi_factor(hidpi_factor),
"`WindowExtIOS::set_hidpi_factor` received an invalid hidpi factor"
);
let hidpi_factor = hidpi_factor as CGFloat;
let () = msg_send![self.view, setContentScaleFactor:hidpi_factor];
let () = msg_send![self.view, setContentScaleFactor: hidpi_factor];
}
}
pub fn set_valid_orientations(&self, valid_orientations: ValidOrientations) {
unsafe {
let idiom = event_loop::get_idiom();
let supported_orientations = UIInterfaceOrientationMask::from_valid_orientations_idiom(valid_orientations, idiom);
msg_send![self.view_controller, setSupportedInterfaceOrientations:supported_orientations];
let supported_orientations = UIInterfaceOrientationMask::from_valid_orientations_idiom(
valid_orientations,
idiom,
);
msg_send![
self.view_controller,
setSupportedInterfaceOrientations: supported_orientations
];
}
}
}
@ -411,14 +425,18 @@ impl Inner {
let screen_frame = self.to_screen_space(bounds);
let status_bar_frame: CGRect = {
let app: id = msg_send![class!(UIApplication), sharedApplication];
assert!(!app.is_null(), "`Window::get_inner_position` cannot be called before `EventLoop::run` on iOS");
assert!(
!app.is_null(),
"`Window::get_inner_position` cannot be called before `EventLoop::run` on iOS"
);
msg_send![app, statusBarFrame]
};
let (y, height) = if screen_frame.origin.y > status_bar_frame.size.height {
(screen_frame.origin.y, screen_frame.size.height)
} else {
let y = status_bar_frame.size.height;
let height = screen_frame.size.height - (status_bar_frame.size.height - screen_frame.origin.y);
let height = screen_frame.size.height
- (status_bar_frame.size.height - screen_frame.origin.y);
(y, height)
};
CGRect {
@ -429,7 +447,7 @@ impl Inner {
size: CGSize {
width: screen_frame.size.width,
height,
}
},
}
}
}
@ -453,13 +471,17 @@ unsafe impl Sync for WindowId {}
impl From<&Object> for WindowId {
fn from(window: &Object) -> WindowId {
WindowId { window: window as *const _ as _ }
WindowId {
window: window as *const _ as _,
}
}
}
impl From<&mut Object> for WindowId {
fn from(window: &mut Object) -> WindowId {
WindowId { window: window as _ }
WindowId {
window: window as _,
}
}
}