diff --git a/src/platform/ios.rs b/src/platform/ios.rs index c4923bdf07..89a9d65561 100644 --- a/src/platform/ios.rs +++ b/src/platform/ios.rs @@ -1,45 +1,79 @@ //! # iOS / UIKit //! -//! Winit has an OS requirement of iOS 8 or higher, and is regularly tested on -//! iOS 9.3. +//! Winit has [the same iOS version requirements as `rustc`][rustc-ios-version], although it's +//! frequently only tested on newer iOS versions. //! -//! ## Building app +//! [rustc-ios-version]: https://doc.rust-lang.org/rustc/platform-support/apple-ios.html#os-version //! -//! To build ios app you will need rustc built for this targets: +//! ## Running on Mac Catalyst //! -//! - armv7-apple-ios -//! - armv7s-apple-ios -//! - i386-apple-ios -//! - aarch64-apple-ios -//! - x86_64-apple-ios +//! Mac Catalyst allows running applications using UIKit on macOS, which can be very useful for +//! testing. See [`rustc`'s documentation on Mac Catalyst][rustc-mac-catalyst] for details on how to +//! use these targets. To use these with Winit, you'll need to bundle your application before +//! running it, otherwise UIKit will exit with an error. //! -//! Then +//! To run e.g. the `window` example in the Winit repository, you can use [`cargo-bundle`] as +//! follows: //! +//! ```console +//! $ cargo +nightly bundle --format=ios --target=aarch64-apple-ios-macabi --example=window +//! $ ./target/aarch64-apple-ios-macabi/debug/examples/bundle/ios/winit.app/window //! ``` -//! 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() -//! } +//! [rustc-mac-catalyst]: https://doc.rust-lang.org/rustc/platform-support/apple-ios-macabi.html +//! [`cargo-bundle`]: https://github.com/burtonageo/cargo-bundle //! -//! fn start_inner() { -//! ... -//! } -//! ``` +//! ## Introduction to building an app +//! +//! Building and running your application in the iOS simulator, or on a real device, is a bit more +//! complicated than Mac Catalyst - fundamentally, you must use Xcode, since the binary needs to be +//! bundled, signed, notarized and uploaded to the device (there is [an open source work-in-progress +//! on re-implementing parts of this][apple-platform-rs], but the user-story around it is not yet +//! clear). +//! +//! This means that you're left with effectively two options: Use a tool that manages the Xcode +//! configuration for you, or use Xcode directly. [`cargo-dinghy`] and [`cargo-mobile2`] are notable +//! projects in the ecosystem that attempt the former, and [`cargo-xcode`] is an excellent project +//! that attempts the latter. We will also attempt to describe here how you would go about using +//! Xcode directly: //! -//! Compile project and then drag resulting .a into Xcode project. Add winit.h to xcode. +//! First off, you'll need the correct Rust targets, see [`rustc`'s documentation on iOS][rustc-ios] +//! for details. Nowadays, the correct targets are usually `aarch64-apple-ios-sim` for the +//! simulator, and `aarch64-apple-ios` for the actual device. //! -//! ```ignore -//! void start_winit_app(); +//! Next, create a new Xcode project using the "App" template. The exact configuration does not +//! really matter, as we're going to delete most of it, since it's tailored for Objective-C and/or +//! Swift, and Rust/Winit is neither. Specifically, we need to delete: +//! - Everything relating to storyboards (unless you want to use e.g. a launch screen). This +//! includes the relevant keys in `Info.plist`. +//! - All the generated C header, Objective-C and/or Swift files. +//! +//! Now that we have a fairly clean slate that we can build upon, you can add a "run script" build +//! phase to your Xcode target, which will get invoked instead of the "compile sources" and "link +//! binary" steps. The basic script should look something like: +//! +//! ```sh +//! # Build desired targets based on `ARCHS` environment variable +//! cargo build --target=aarch64-apple-ios --target=armv7s-apple-ios +//! # Merge these with `lipo`, and place the result in "$TARGET_BUILD_DIR/$EXECUTABLE_PATH", which +//! # is understood by Xcode +//! lipo "$TARGET_BUILD_DIR/$EXECUTABLE_PATH" target/aarch64-apple-ios/debug/my_app target/armv7s-apple-ios/debug/my_app //! ``` //! -//! Use start_winit_app inside your xcode's main function. +//! Note that this is very much the overall idea; the script needs to be much more involved to +//! properly deal with different target architectures, invoking `lipo` when needed, incremental +//! rebuild change detection, and so on. `cargo-xcode` has a script [here][cargo-xcode-script] that +//! handles most of this complexity, you might be able to build upon that. +//! +//! Apologies that we're not able to provide you with more than this; work is in-progress on +//! improving the situation, but it's slow-going. //! +//! [apple-platform-rs]: https://github.com/indygreg/apple-platform-rs +//! [`cargo-dinghy`]: https://github.com/sonos/dinghy +//! [`cargo-mobile2`]: https://github.com/tauri-apps/cargo-mobile2 +//! [`cargo-xcode`]: https://crates.io/crates/cargo-xcode +//! [rustc-ios]: https://doc.rust-lang.org/rustc/platform-support/apple-ios.html +//! [cargo-xcode-script]: https://gitlab.com/kornelski/cargo-xcode/-/blob/main/src/xcodebuild.sh //! //! ## App lifecycle and events //! diff --git a/src/platform/macos.rs b/src/platform/macos.rs index 9aeb0940ba..44bc8b8b33 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -1,7 +1,9 @@ //! # macOS / AppKit //! -//! Winit has an OS requirement of macOS 10.11 or higher (same as Rust -//! itself), and is regularly tested on macOS 10.14. +//! Winit has [the same macOS version requirements as `rustc`][rustc-macos-version], and is tested +//! once in a while on as low as macOS 10.14. +//! +//! [rustc-macos-version]: https://doc.rust-lang.org/rustc/platform-support/apple-darwin.html#os-version //! //! ## Custom `NSApplicationDelegate` //! diff --git a/src/window.rs b/src/window.rs index 7dd7807107..35894692ac 100644 --- a/src/window.rs +++ b/src/window.rs @@ -590,7 +590,6 @@ impl Window { /// /// - **Windows** This API uses `RedrawWindow` to request a `WM_PAINT` message and /// `RedrawRequested` is emitted in sync with any `WM_PAINT` messages. - /// - **iOS:** Can only be called on the main thread. /// - **Wayland:** The events are aligned with the frame callbacks when /// [`Window::pre_present_notify`] is used. /// - **Web:** [`WindowEvent::RedrawRequested`] will be aligned with the @@ -671,8 +670,8 @@ impl Window { /// /// ## Platform-specific /// - /// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the - /// window's [safe area] in the screen space coordinate system. + /// - **iOS:** Returns the top left coordinates of the window's [safe area] in the screen space + /// coordinate system. /// - **Web:** Returns the top-left coordinates relative to the viewport. _Note: this returns /// the same value as [`Window::outer_position`]._ /// - **Android / Wayland:** Always returns [`NotSupportedError`]. @@ -697,8 +696,8 @@ impl Window { /// /// ## Platform-specific /// - /// - **iOS:** Can only be called on the main thread. Returns the top left coordinates of the - /// window in the screen space coordinate system. + /// - **iOS:** Returns the top left coordinates of the window in the screen space coordinate + /// system. /// - **Web:** Returns the top-left coordinates relative to the viewport. /// - **Android / Wayland:** Always returns [`NotSupportedError`]. #[inline] @@ -727,8 +726,8 @@ impl Window { /// /// ## Platform-specific /// - /// - **iOS:** Can only be called on the main thread. Sets the top left coordinates of the - /// window in the screen space coordinate system. + /// - **iOS:** Sets the top left coordinates of the window in the screen space coordinate + /// system. /// - **Web:** Sets the top-left coordinates relative to the viewport. Doesn't account for CSS /// [`transform`]. /// - **Android / Wayland:** Unsupported. @@ -752,8 +751,8 @@ impl Window { /// /// ## Platform-specific /// - /// - **iOS:** Can only be called on the main thread. Returns the `PhysicalSize` of the window's - /// [safe area] in screen space coordinates. + /// - **iOS:** Returns the `PhysicalSize` of the window's [safe area] in screen space + /// coordinates. /// - **Web:** Returns the size of the canvas element. Doesn't account for CSS [`transform`]. /// /// [safe area]: https://developer.apple.com/documentation/uikit/uiview/2891103-safeareainsets?language=objc @@ -818,8 +817,7 @@ impl Window { /// /// ## Platform-specific /// - /// - **iOS:** Can only be called on the main thread. Returns the [`PhysicalSize`] of the window - /// in screen space coordinates. + /// - **iOS:** Returns the [`PhysicalSize`] of the window in screen space coordinates. /// - **Web:** Returns the size of the canvas element. _Note: this returns the same value as /// [`Window::inner_size`]._ #[inline] @@ -973,7 +971,6 @@ impl Window { /// ## Platform-specific /// /// - **Android / Wayland / Web:** Unsupported. - /// - **iOS:** Can only be called on the main thread. #[inline] pub fn set_visible(&self, visible: bool) { let _span = tracing::debug_span!("winit::Window::set_visible", visible).entered(); @@ -1121,7 +1118,6 @@ impl Window { /// separate spaces are not preferred. /// /// The dock and the menu bar are disabled in exclusive fullscreen mode. - /// - **iOS:** Can only be called on the main thread. /// - **Wayland:** Does not support exclusive fullscreen mode and will no-op a request. /// - **Windows:** Screen saver is disabled in fullscreen mode. /// - **Android / Orbital:** Unsupported. @@ -1148,7 +1144,6 @@ impl Window { /// /// ## Platform-specific /// - /// - **iOS:** Can only be called on the main thread. /// - **Android / Orbital:** Will always return `None`. /// - **Wayland:** Can return `Borderless(None)` when there are no monitors. /// - **Web:** Can only return `None` or `Borderless`.