Creating window when event loop is not running generally doesn't work, since a bunch of events and sync OS requests can't be processed. This is also an issue on e.g. Android, since window can't be created outside event loop easily. Thus deprecate the window creation when event loop is not running, as well as other resource creation to running event loop. Given that all the examples use the bad pattern of creating the window when event loop is not running and also most example existence is questionable, since they show single thing and the majority of their code is window/event loop initialization, they wore merged into a single example 'window.rs' example that showcases very simple application using winit. Fixes #3399.
111 lines
3 KiB
Rust
111 lines
3 KiB
Rust
//! iOS support
|
|
//!
|
|
//! # Building app
|
|
//! To build ios app you will need rustc built for this targets:
|
|
//!
|
|
//! - armv7-apple-ios
|
|
//! - armv7s-apple-ios
|
|
//! - i386-apple-ios
|
|
//! - aarch64-apple-ios
|
|
//! - x86_64-apple-ios
|
|
//!
|
|
//! Then
|
|
//!
|
|
//! ```
|
|
//! cargo build --target=...
|
|
//! ```
|
|
//! The simplest way to integrate your app into xcode environment is to build it
|
|
//! as a static library. Wrap your main function and export it.
|
|
//!
|
|
//! ```rust, ignore
|
|
//! #[no_mangle]
|
|
//! pub extern fn start_winit_app() {
|
|
//! start_inner()
|
|
//! }
|
|
//!
|
|
//! fn start_inner() {
|
|
//! ...
|
|
//! }
|
|
//! ```
|
|
//!
|
|
//! Compile project and then drag resulting .a into Xcode project. Add winit.h to xcode.
|
|
//!
|
|
//! ```ignore
|
|
//! void start_winit_app();
|
|
//! ```
|
|
//!
|
|
//! Use start_winit_app inside your xcode's main function.
|
|
//!
|
|
//!
|
|
//! # App lifecycle and events
|
|
//!
|
|
//! iOS environment is very different from other platforms and you must be very
|
|
//! careful with it's events. Familiarize yourself with
|
|
//! [app lifecycle](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/).
|
|
//!
|
|
//!
|
|
//! This is how those event are represented in winit:
|
|
//!
|
|
//! - applicationDidBecomeActive is Resumed
|
|
//! - applicationWillResignActive is Suspended
|
|
//! - applicationWillTerminate is LoopExiting
|
|
//!
|
|
//! Keep in mind that after LoopExiting event is received every attempt to draw with
|
|
//! opengl will result in segfault.
|
|
//!
|
|
//! Also note that app may not receive the LoopExiting event if suspended; it might be SIGKILL'ed.
|
|
|
|
#![cfg(ios_platform)]
|
|
#![allow(clippy::let_unit_value)]
|
|
|
|
mod app_state;
|
|
mod event_loop;
|
|
mod ffi;
|
|
mod monitor;
|
|
mod uikit;
|
|
mod view;
|
|
mod window;
|
|
|
|
use std::fmt;
|
|
|
|
use crate::event::DeviceId as RootDeviceId;
|
|
|
|
pub(crate) use self::{
|
|
event_loop::{
|
|
ActiveEventLoop, EventLoop, EventLoopProxy, OwnedDisplayHandle,
|
|
PlatformSpecificEventLoopAttributes,
|
|
},
|
|
monitor::{MonitorHandle, VideoModeHandle},
|
|
window::{PlatformSpecificWindowAttributes, Window, WindowId},
|
|
};
|
|
pub(crate) use crate::cursor::NoCustomCursor as PlatformCustomCursor;
|
|
pub(crate) use crate::cursor::NoCustomCursor as PlatformCustomCursorBuilder;
|
|
pub(crate) use crate::icon::NoIcon as PlatformIcon;
|
|
pub(crate) use crate::platform_impl::Fullscreen;
|
|
|
|
/// There is no way to detect which device that performed a certain event in
|
|
/// UIKit (i.e. you can't differentiate between different external keyboards,
|
|
/// or whether it was the main touchscreen, assistive technologies, or some
|
|
/// other pointer device that caused a touch event).
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
pub struct DeviceId;
|
|
|
|
impl DeviceId {
|
|
pub const unsafe fn dummy() -> Self {
|
|
DeviceId
|
|
}
|
|
}
|
|
|
|
pub(crate) const DEVICE_ID: RootDeviceId = RootDeviceId(DeviceId);
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
|
pub struct KeyEventExtra {}
|
|
|
|
#[derive(Debug)]
|
|
pub enum OsError {}
|
|
|
|
impl fmt::Display for OsError {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "os error")
|
|
}
|
|
}
|