Move UIKit backend to winit-uikit
This commit is contained in:
parent
0adc0898f0
commit
927af44aa4
18 changed files with 128 additions and 110 deletions
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
|
|
@ -2,7 +2,7 @@
|
|||
/winit-android @MarijnS95
|
||||
|
||||
# Apple (AppKit + UIKit)
|
||||
/src/platform/ios.rs @madsmtm
|
||||
/winit-uikit @madsmtm
|
||||
/src/platform/macos.rs @madsmtm
|
||||
/src/platform_impl/apple @madsmtm
|
||||
/winit-common/src/core_foundation @madsmtm
|
||||
|
|
|
|||
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
|
|
@ -201,6 +201,11 @@ jobs:
|
|||
if: contains(matrix.platform.target, 'redox')
|
||||
run: cargo test -p winit-orbital
|
||||
|
||||
- name: Test winit UIKit
|
||||
if: contains(matrix.platform.target, 'ios')
|
||||
# TODO: Run on Simulator
|
||||
run: cargo $CMD test -p winit-uikit --target=${{ matrix.platform.target }} --no-run
|
||||
|
||||
- name: Test winit Win32
|
||||
if: contains(matrix.platform.target, 'windows')
|
||||
run: cargo $CMD test -p winit-win32 --target=${{ matrix.platform.target }}
|
||||
|
|
|
|||
48
Cargo.toml
48
Cargo.toml
|
|
@ -16,6 +16,7 @@ winit-android = { version = "0.0.0", path = "winit-android" }
|
|||
winit-common = { version = "0.0.0", path = "winit-common" }
|
||||
winit-core = { version = "0.0.0", path = "winit-core" }
|
||||
winit-orbital = { version = "0.0.0", path = "winit-orbital" }
|
||||
winit-uikit = { version = "0.0.0", path = "winit-uikit" }
|
||||
winit-win32 = { version = "0.0.0", path = "winit-win32" }
|
||||
|
||||
# Core dependencies.
|
||||
|
|
@ -164,6 +165,7 @@ serde = [
|
|||
"dpi/serde",
|
||||
"bitflags/serde",
|
||||
"winit-core/serde",
|
||||
"winit-uikit/serde",
|
||||
]
|
||||
wayland = [
|
||||
"wayland-client",
|
||||
|
|
@ -296,52 +298,8 @@ objc2-foundation = { workspace = true, features = [
|
|||
"NSValue",
|
||||
] }
|
||||
|
||||
# UIKit
|
||||
[target.'cfg(all(target_vendor = "apple", not(target_os = "macos")))'.dependencies]
|
||||
objc2-core-foundation = { workspace = true, features = [
|
||||
"std",
|
||||
"CFCGTypes",
|
||||
"CFBase",
|
||||
"CFRunLoop",
|
||||
"CFString",
|
||||
] }
|
||||
objc2-foundation = { workspace = true, features = [
|
||||
"std",
|
||||
"block2",
|
||||
"objc2-core-foundation",
|
||||
"NSArray",
|
||||
"NSEnumerator",
|
||||
"NSGeometry",
|
||||
"NSObjCRuntime",
|
||||
"NSOperation",
|
||||
"NSString",
|
||||
"NSThread",
|
||||
"NSSet",
|
||||
] }
|
||||
objc2-ui-kit = { workspace = true, features = [
|
||||
"std",
|
||||
"objc2-core-foundation",
|
||||
"UIApplication",
|
||||
"UIDevice",
|
||||
"UIEvent",
|
||||
"UIGeometry",
|
||||
"UIGestureRecognizer",
|
||||
"UITextInput",
|
||||
"UITextInputTraits",
|
||||
"UIOrientation",
|
||||
"UIPanGestureRecognizer",
|
||||
"UIPinchGestureRecognizer",
|
||||
"UIResponder",
|
||||
"UIRotationGestureRecognizer",
|
||||
"UIScreen",
|
||||
"UIScreenMode",
|
||||
"UITapGestureRecognizer",
|
||||
"UITouch",
|
||||
"UITraitCollection",
|
||||
"UIView",
|
||||
"UIViewController",
|
||||
"UIWindow",
|
||||
] }
|
||||
winit-uikit.workspace = true
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
winit-win32.workspace = true
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#[cfg(android_platform)]
|
||||
pub use winit_android as android;
|
||||
#[cfg(ios_platform)]
|
||||
pub mod ios;
|
||||
pub use winit_uikit as ios;
|
||||
#[cfg(macos_platform)]
|
||||
pub mod macos;
|
||||
#[cfg(orbital_platform)]
|
||||
|
|
|
|||
|
|
@ -1,11 +1,6 @@
|
|||
#[cfg(target_os = "macos")]
|
||||
mod appkit;
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
mod uikit;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
#[cfg(target_os = "macos")]
|
||||
pub use self::appkit::*;
|
||||
#[allow(unused_imports)]
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
pub use self::uikit::*;
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
#![allow(clippy::let_unit_value)]
|
||||
|
||||
mod app_state;
|
||||
mod event_loop;
|
||||
mod monitor;
|
||||
mod notification_center;
|
||||
mod view;
|
||||
mod view_controller;
|
||||
mod window;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub(crate) use self::event_loop::{
|
||||
ActiveEventLoop, EventLoop, PlatformSpecificEventLoopAttributes,
|
||||
};
|
||||
pub(crate) use self::monitor::MonitorHandle;
|
||||
pub(crate) use self::window::Window;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum OsError {}
|
||||
|
||||
impl fmt::Display for OsError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "os error")
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
../appkit/notification_center.rs
|
||||
|
|
@ -1,17 +1,19 @@
|
|||
#[cfg(android_platform)]
|
||||
pub(crate) use winit_android as platform;
|
||||
#[cfg(target_vendor = "apple")]
|
||||
#[cfg(macos_platform)]
|
||||
mod apple;
|
||||
#[cfg(any(x11_platform, wayland_platform))]
|
||||
mod linux;
|
||||
#[cfg(orbital_platform)]
|
||||
pub(crate) use winit_orbital as platform;
|
||||
#[cfg(ios_platform)]
|
||||
pub(crate) use winit_uikit as platform;
|
||||
#[cfg(web_platform)]
|
||||
mod web;
|
||||
#[cfg(windows_platform)]
|
||||
pub(crate) use winit_win32 as platform;
|
||||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
#[cfg(macos_platform)]
|
||||
use self::apple as platform;
|
||||
#[cfg(any(x11_platform, wayland_platform))]
|
||||
use self::linux as platform;
|
||||
|
|
|
|||
72
winit-uikit/Cargo.toml
Normal file
72
winit-uikit/Cargo.toml
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
[package]
|
||||
description = "Winit's UIKit (iOS/tvOS/visionOS) backend"
|
||||
documentation = "https://docs.rs/winit-uikit"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
name = "winit-uikit"
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
version = "0.0.0"
|
||||
|
||||
[features]
|
||||
serde = ["dep:serde", "bitflags/serde", "smol_str/serde", "dpi/serde"]
|
||||
|
||||
[dependencies]
|
||||
bitflags.workspace = true
|
||||
dpi.workspace = true
|
||||
rwh_06.workspace = true
|
||||
serde = { workspace = true, optional = true }
|
||||
smol_str.workspace = true
|
||||
tracing.workspace = true
|
||||
winit-common = { workspace = true, features = ["core-foundation", "event-handler"] }
|
||||
winit-core.workspace = true
|
||||
|
||||
# Platform-specific
|
||||
[target.'cfg(target_vendor = "apple")'.dependencies]
|
||||
block2.workspace = true
|
||||
dispatch2.workspace = true
|
||||
objc2.workspace = true
|
||||
objc2-core-foundation = { workspace = true, features = [
|
||||
"std",
|
||||
"CFCGTypes",
|
||||
"CFBase",
|
||||
"CFRunLoop",
|
||||
"CFString",
|
||||
] }
|
||||
objc2-foundation = { workspace = true, features = [
|
||||
"std",
|
||||
"block2",
|
||||
"objc2-core-foundation",
|
||||
"NSArray",
|
||||
"NSEnumerator",
|
||||
"NSGeometry",
|
||||
"NSObjCRuntime",
|
||||
"NSOperation",
|
||||
"NSString",
|
||||
"NSThread",
|
||||
"NSSet",
|
||||
] }
|
||||
objc2-ui-kit = { workspace = true, features = [
|
||||
"std",
|
||||
"objc2-core-foundation",
|
||||
"UIApplication",
|
||||
"UIDevice",
|
||||
"UIEvent",
|
||||
"UIGeometry",
|
||||
"UIGestureRecognizer",
|
||||
"UITextInput",
|
||||
"UITextInputTraits",
|
||||
"UIOrientation",
|
||||
"UIPanGestureRecognizer",
|
||||
"UIPinchGestureRecognizer",
|
||||
"UIResponder",
|
||||
"UIRotationGestureRecognizer",
|
||||
"UIScreen",
|
||||
"UIScreenMode",
|
||||
"UITapGestureRecognizer",
|
||||
"UITouch",
|
||||
"UITraitCollection",
|
||||
"UIView",
|
||||
"UIViewController",
|
||||
"UIWindow",
|
||||
] }
|
||||
1
winit-uikit/README.md
Symbolic link
1
winit-uikit/README.md
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../README.md
|
||||
|
|
@ -23,8 +23,8 @@ use winit_core::event::{StartCause, SurfaceSizeWriter, WindowEvent};
|
|||
use winit_core::event_loop::ControlFlow;
|
||||
use winit_core::window::WindowId;
|
||||
|
||||
use super::window::WinitUIWindow;
|
||||
use super::ActiveEventLoop;
|
||||
use crate::event_loop::ActiveEventLoop;
|
||||
use crate::window::WinitUIWindow;
|
||||
|
||||
macro_rules! bug {
|
||||
($($msg:tt)*) => {
|
||||
|
|
@ -28,11 +28,12 @@ use winit_core::window::{Theme, Window as CoreWindow};
|
|||
|
||||
use super::app_state::{send_occluded_event_for_all_windows, AppState};
|
||||
use super::notification_center::create_observer;
|
||||
use super::{app_state, monitor, MonitorHandle};
|
||||
use crate::platform_impl::Window;
|
||||
use crate::monitor::MonitorHandle;
|
||||
use crate::window::Window;
|
||||
use crate::{app_state, monitor};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ActiveEventLoop {
|
||||
pub struct ActiveEventLoop {
|
||||
pub(super) mtm: MainThreadMarker,
|
||||
}
|
||||
|
||||
|
|
@ -138,12 +139,10 @@ pub struct EventLoop {
|
|||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct PlatformSpecificEventLoopAttributes {}
|
||||
pub struct PlatformSpecificEventLoopAttributes {}
|
||||
|
||||
impl EventLoop {
|
||||
pub(crate) fn new(
|
||||
_: &PlatformSpecificEventLoopAttributes,
|
||||
) -> Result<EventLoop, EventLoopError> {
|
||||
pub fn new(_: &PlatformSpecificEventLoopAttributes) -> Result<EventLoop, EventLoopError> {
|
||||
let mtm = MainThreadMarker::new()
|
||||
.expect("On iOS, `EventLoop` must be created on the main thread");
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
//! # iOS / UIKit
|
||||
//! # Winit's UIKit (iOS/tvOS/visionOS) backend
|
||||
//!
|
||||
//! Winit has [the same iOS version requirements as `rustc`][rustc-ios-version], although it's
|
||||
//! frequently only tested on newer iOS versions.
|
||||
|
|
@ -98,16 +98,26 @@
|
|||
//! register an application delegate, so you can set up a custom one in a nib file instead.
|
||||
//!
|
||||
//! [app-delegate]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate?language=objc
|
||||
#![cfg(target_vendor = "apple")] // TODO: Remove once `objc2` allows compiling on all platforms
|
||||
|
||||
mod app_state;
|
||||
mod event_loop;
|
||||
mod monitor;
|
||||
mod notification_center;
|
||||
mod view;
|
||||
mod view_controller;
|
||||
mod window;
|
||||
|
||||
use std::os::raw::c_void;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use winit_core::window::PlatformWindowAttributes;
|
||||
use winit_core::monitor::{MonitorHandle, VideoMode};
|
||||
use winit_core::window::{PlatformWindowAttributes, Window};
|
||||
|
||||
use crate::monitor::{MonitorHandle, VideoMode};
|
||||
use crate::platform_impl::MonitorHandle as IosMonitorHandle;
|
||||
use crate::window::Window;
|
||||
pub use self::event_loop::{EventLoop, PlatformSpecificEventLoopAttributes};
|
||||
use self::monitor::MonitorHandle as UIKitMonitorHandle;
|
||||
use self::window::Window as UIKitWindow;
|
||||
|
||||
/// Additional methods on [`Window`] that are specific to iOS.
|
||||
pub trait WindowExtIOS {
|
||||
|
|
@ -212,25 +222,25 @@ pub trait WindowExtIOS {
|
|||
impl WindowExtIOS for dyn Window + '_ {
|
||||
#[inline]
|
||||
fn set_scale_factor(&self, scale_factor: f64) {
|
||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
let window = self.cast_ref::<UIKitWindow>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_scale_factor(scale_factor));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_valid_orientations(&self, valid_orientations: ValidOrientations) {
|
||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
let window = self.cast_ref::<UIKitWindow>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_valid_orientations(valid_orientations));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_prefers_home_indicator_hidden(&self, hidden: bool) {
|
||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
let window = self.cast_ref::<UIKitWindow>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_prefers_home_indicator_hidden(hidden));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_preferred_screen_edges_deferring_system_gestures(&self, edges: ScreenEdge) {
|
||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
let window = self.cast_ref::<UIKitWindow>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| {
|
||||
w.set_preferred_screen_edges_deferring_system_gestures(edges)
|
||||
});
|
||||
|
|
@ -238,19 +248,19 @@ impl WindowExtIOS for dyn Window + '_ {
|
|||
|
||||
#[inline]
|
||||
fn set_prefers_status_bar_hidden(&self, hidden: bool) {
|
||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
let window = self.cast_ref::<UIKitWindow>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_prefers_status_bar_hidden(hidden));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_preferred_status_bar_style(&self, status_bar_style: StatusBarStyle) {
|
||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
let window = self.cast_ref::<UIKitWindow>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.set_preferred_status_bar_style(status_bar_style))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn recognize_pinch_gesture(&self, should_recognize: bool) {
|
||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
let window = self.cast_ref::<UIKitWindow>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.recognize_pinch_gesture(should_recognize));
|
||||
}
|
||||
|
||||
|
|
@ -261,7 +271,7 @@ impl WindowExtIOS for dyn Window + '_ {
|
|||
minimum_number_of_touches: u8,
|
||||
maximum_number_of_touches: u8,
|
||||
) {
|
||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
let window = self.cast_ref::<UIKitWindow>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| {
|
||||
w.recognize_pan_gesture(
|
||||
should_recognize,
|
||||
|
|
@ -273,13 +283,13 @@ impl WindowExtIOS for dyn Window + '_ {
|
|||
|
||||
#[inline]
|
||||
fn recognize_doubletap_gesture(&self, should_recognize: bool) {
|
||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
let window = self.cast_ref::<UIKitWindow>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.recognize_doubletap_gesture(should_recognize));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn recognize_rotation_gesture(&self, should_recognize: bool) {
|
||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
let window = self.cast_ref::<UIKitWindow>().unwrap();
|
||||
window.maybe_wait_on_main(move |w| w.recognize_rotation_gesture(should_recognize));
|
||||
}
|
||||
}
|
||||
|
|
@ -395,13 +405,13 @@ impl MonitorHandleExtIOS for MonitorHandle {
|
|||
fn ui_screen(&self) -> *mut c_void {
|
||||
// SAFETY: The marker is only used to get the pointer of the screen
|
||||
let mtm = unsafe { objc2::MainThreadMarker::new_unchecked() };
|
||||
let monitor = self.cast_ref::<IosMonitorHandle>().unwrap();
|
||||
let monitor = self.cast_ref::<UIKitMonitorHandle>().unwrap();
|
||||
objc2::rc::Retained::as_ptr(monitor.ui_screen(mtm)) as *mut c_void
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn preferred_video_mode(&self) -> VideoMode {
|
||||
let monitor = self.cast_ref::<IosMonitorHandle>().unwrap();
|
||||
let monitor = self.cast_ref::<UIKitMonitorHandle>().unwrap();
|
||||
monitor.preferred_video_mode()
|
||||
}
|
||||
}
|
||||
1
winit-uikit/src/notification_center.rs
Symbolic link
1
winit-uikit/src/notification_center.rs
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../src/platform_impl/apple/appkit/notification_center.rs
|
||||
|
|
@ -8,7 +8,7 @@ use objc2_ui_kit::{
|
|||
UIUserInterfaceIdiom, UIView, UIViewController,
|
||||
};
|
||||
|
||||
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations, WindowAttributesIos};
|
||||
use crate::{ScreenEdge, StatusBarStyle, ValidOrientations, WindowAttributesIos};
|
||||
|
||||
pub struct ViewControllerState {
|
||||
prefers_status_bar_hidden: Cell<bool>,
|
||||
|
|
@ -30,8 +30,10 @@ use winit_core::window::{
|
|||
use super::app_state::EventWrapper;
|
||||
use super::view::WinitView;
|
||||
use super::view_controller::WinitViewController;
|
||||
use super::{app_state, monitor, ActiveEventLoop, MonitorHandle};
|
||||
use crate::platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations, WindowAttributesIos};
|
||||
use super::{app_state, monitor};
|
||||
use crate::event_loop::ActiveEventLoop;
|
||||
use crate::monitor::MonitorHandle;
|
||||
use crate::{ScreenEdge, StatusBarStyle, ValidOrientations, WindowAttributesIos};
|
||||
|
||||
define_class!(
|
||||
#[unsafe(super(UIWindow, UIResponder, NSObject))]
|
||||
Loading…
Add table
Add a link
Reference in a new issue