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:
parent
b1b5aefc4b
commit
e2c84725de
109 changed files with 4787 additions and 3679 deletions
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 _,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue