mirror of
https://github.com/rust-windowing/winit.git
synced 2026-08-29 04:40:04 -04:00
Move AppKit (macOS) backend to winit-appkit (#4248)
This commit is contained in:
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@@ -2,9 +2,8 @@
|
|||||||
/winit-android @MarijnS95
|
/winit-android @MarijnS95
|
||||||
|
|
||||||
# Apple (AppKit + UIKit)
|
# Apple (AppKit + UIKit)
|
||||||
|
/winit-appkit @madsmtm
|
||||||
/winit-uikit @madsmtm
|
/winit-uikit @madsmtm
|
||||||
/src/platform/macos.rs @madsmtm
|
|
||||||
/src/platform_impl/apple @madsmtm
|
|
||||||
/winit-common/src/core_foundation @madsmtm
|
/winit-common/src/core_foundation @madsmtm
|
||||||
/winit-common/src/event_handler.rs @madsmtm
|
/winit-common/src/event_handler.rs @madsmtm
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -197,6 +197,10 @@ jobs:
|
|||||||
if: contains(matrix.platform.target, 'linux-gnu')
|
if: contains(matrix.platform.target, 'linux-gnu')
|
||||||
run: cargo $CMD test -p winit-common --features xkb,x11,wayland --no-run
|
run: cargo $CMD test -p winit-common --features xkb,x11,wayland --no-run
|
||||||
|
|
||||||
|
- name: Test winit AppKit
|
||||||
|
if: contains(matrix.platform.target, 'macos')
|
||||||
|
run: cargo $CMD test -p winit-appkit --target=${{ matrix.platform.target }}
|
||||||
|
|
||||||
- name: Test winit Orbital
|
- name: Test winit Orbital
|
||||||
if: contains(matrix.platform.target, 'redox')
|
if: contains(matrix.platform.target, 'redox')
|
||||||
run: cargo test -p winit-orbital
|
run: cargo test -p winit-orbital
|
||||||
|
|||||||
91
Cargo.toml
91
Cargo.toml
@@ -13,6 +13,7 @@ rust-version = "1.80"
|
|||||||
# `winit` has no version here to allow using it in dev deps for docs.
|
# `winit` has no version here to allow using it in dev deps for docs.
|
||||||
winit = { path = "." }
|
winit = { path = "." }
|
||||||
winit-android = { version = "0.0.0", path = "winit-android" }
|
winit-android = { version = "0.0.0", path = "winit-android" }
|
||||||
|
winit-appkit = { version = "0.0.0", path = "winit-appkit" }
|
||||||
winit-common = { version = "0.0.0", path = "winit-common" }
|
winit-common = { version = "0.0.0", path = "winit-common" }
|
||||||
winit-core = { version = "0.0.0", path = "winit-core" }
|
winit-core = { version = "0.0.0", path = "winit-core" }
|
||||||
winit-orbital = { version = "0.0.0", path = "winit-orbital" }
|
winit-orbital = { version = "0.0.0", path = "winit-orbital" }
|
||||||
@@ -200,96 +201,8 @@ softbuffer.workspace = true
|
|||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
winit-android.workspace = true
|
winit-android.workspace = true
|
||||||
|
|
||||||
# AppKit or UIKit
|
|
||||||
[target.'cfg(target_vendor = "apple")'.dependencies]
|
|
||||||
block2.workspace = true
|
|
||||||
dispatch2.workspace = true
|
|
||||||
objc2.workspace = true
|
|
||||||
winit-common = { workspace = true, features = ["core-foundation", "event-handler"] }
|
|
||||||
|
|
||||||
# AppKit
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
objc2-app-kit = { workspace = true, features = [
|
winit-appkit.workspace = true
|
||||||
"std",
|
|
||||||
"objc2-core-foundation",
|
|
||||||
"NSAppearance",
|
|
||||||
"NSApplication",
|
|
||||||
"NSBitmapImageRep",
|
|
||||||
"NSButton",
|
|
||||||
"NSColor",
|
|
||||||
"NSControl",
|
|
||||||
"NSCursor",
|
|
||||||
"NSDragging",
|
|
||||||
"NSEvent",
|
|
||||||
"NSGraphics",
|
|
||||||
"NSGraphicsContext",
|
|
||||||
"NSImage",
|
|
||||||
"NSImageRep",
|
|
||||||
"NSMenu",
|
|
||||||
"NSMenuItem",
|
|
||||||
"NSOpenGLView",
|
|
||||||
"NSPanel",
|
|
||||||
"NSPasteboard",
|
|
||||||
"NSResponder",
|
|
||||||
"NSRunningApplication",
|
|
||||||
"NSScreen",
|
|
||||||
"NSTextInputClient",
|
|
||||||
"NSTextInputContext",
|
|
||||||
"NSToolbar",
|
|
||||||
"NSView",
|
|
||||||
"NSWindow",
|
|
||||||
"NSWindowScripting",
|
|
||||||
"NSWindowTabGroup",
|
|
||||||
] }
|
|
||||||
objc2-core-foundation = { workspace = true, features = [
|
|
||||||
"std",
|
|
||||||
"block2",
|
|
||||||
"CFBase",
|
|
||||||
"CFCGTypes",
|
|
||||||
"CFData",
|
|
||||||
"CFRunLoop",
|
|
||||||
"CFString",
|
|
||||||
"CFUUID",
|
|
||||||
] }
|
|
||||||
objc2-core-graphics = { workspace = true, features = [
|
|
||||||
"std",
|
|
||||||
"libc",
|
|
||||||
"CGDirectDisplay",
|
|
||||||
"CGDisplayConfiguration",
|
|
||||||
"CGDisplayFade",
|
|
||||||
"CGError",
|
|
||||||
"CGRemoteOperation",
|
|
||||||
"CGWindowLevel",
|
|
||||||
] }
|
|
||||||
objc2-core-video = { workspace = true, features = [
|
|
||||||
"std",
|
|
||||||
"objc2-core-graphics",
|
|
||||||
"CVBase",
|
|
||||||
"CVReturn",
|
|
||||||
"CVDisplayLink",
|
|
||||||
] }
|
|
||||||
objc2-foundation = { workspace = true, features = [
|
|
||||||
"std",
|
|
||||||
"block2",
|
|
||||||
"objc2-core-foundation",
|
|
||||||
"NSArray",
|
|
||||||
"NSAttributedString",
|
|
||||||
"NSData",
|
|
||||||
"NSDictionary",
|
|
||||||
"NSDistributedNotificationCenter",
|
|
||||||
"NSEnumerator",
|
|
||||||
"NSGeometry",
|
|
||||||
"NSKeyValueObserving",
|
|
||||||
"NSNotification",
|
|
||||||
"NSObjCRuntime",
|
|
||||||
"NSOperation",
|
|
||||||
"NSPathUtilities",
|
|
||||||
"NSProcessInfo",
|
|
||||||
"NSRunLoop",
|
|
||||||
"NSString",
|
|
||||||
"NSThread",
|
|
||||||
"NSValue",
|
|
||||||
] }
|
|
||||||
|
|
||||||
[target.'cfg(all(target_vendor = "apple", not(target_os = "macos")))'.dependencies]
|
[target.'cfg(all(target_vendor = "apple", not(target_os = "macos")))'.dependencies]
|
||||||
winit-uikit.workspace = true
|
winit-uikit.workspace = true
|
||||||
|
|||||||
@@ -348,6 +348,30 @@ impl winit_android::EventLoopBuilderExtAndroid for EventLoopBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(macos_platform)]
|
||||||
|
impl winit_appkit::EventLoopBuilderExtMacOS for EventLoopBuilder {
|
||||||
|
#[inline]
|
||||||
|
fn with_activation_policy(
|
||||||
|
&mut self,
|
||||||
|
activation_policy: winit_appkit::ActivationPolicy,
|
||||||
|
) -> &mut Self {
|
||||||
|
self.platform_specific.activation_policy = Some(activation_policy);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn with_default_menu(&mut self, enable: bool) -> &mut Self {
|
||||||
|
self.platform_specific.default_menu = enable;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn with_activate_ignoring_other_apps(&mut self, ignore: bool) -> &mut Self {
|
||||||
|
self.platform_specific.activate_ignoring_other_apps = ignore;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(wayland_platform)]
|
#[cfg(wayland_platform)]
|
||||||
impl winit_wayland::EventLoopExtWayland for EventLoop {
|
impl winit_wayland::EventLoopExtWayland for EventLoop {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
#[cfg(android_platform)]
|
#[cfg(android_platform)]
|
||||||
pub use winit_android as android;
|
pub use winit_android as android;
|
||||||
#[cfg(ios_platform)]
|
|
||||||
pub use winit_uikit as ios;
|
|
||||||
#[cfg(macos_platform)]
|
#[cfg(macos_platform)]
|
||||||
pub mod macos;
|
pub use winit_appkit as macos;
|
||||||
#[cfg(orbital_platform)]
|
#[cfg(orbital_platform)]
|
||||||
pub use winit_orbital as orbital;
|
pub use winit_orbital as orbital;
|
||||||
|
#[cfg(ios_platform)]
|
||||||
|
pub use winit_uikit as ios;
|
||||||
#[cfg(any(x11_platform, wayland_platform))]
|
#[cfg(any(x11_platform, wayland_platform))]
|
||||||
pub mod startup_notify;
|
pub mod startup_notify;
|
||||||
#[cfg(wayland_platform)]
|
#[cfg(wayland_platform)]
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
#[macro_use]
|
|
||||||
mod util;
|
|
||||||
|
|
||||||
mod app;
|
|
||||||
mod app_state;
|
|
||||||
mod cursor;
|
|
||||||
mod event;
|
|
||||||
mod event_loop;
|
|
||||||
mod ffi;
|
|
||||||
mod menu;
|
|
||||||
mod monitor;
|
|
||||||
mod notification_center;
|
|
||||||
mod observer;
|
|
||||||
mod view;
|
|
||||||
mod window;
|
|
||||||
mod window_delegate;
|
|
||||||
|
|
||||||
pub(crate) use self::event::{physicalkey_to_scancode, scancode_to_physicalkey};
|
|
||||||
pub(crate) use self::event_loop::{
|
|
||||||
ActiveEventLoop, EventLoop, PlatformSpecificEventLoopAttributes,
|
|
||||||
};
|
|
||||||
pub(crate) use self::monitor::MonitorHandle;
|
|
||||||
pub(crate) use self::window::Window;
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
#[cfg(target_os = "macos")]
|
|
||||||
mod appkit;
|
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
pub use self::appkit::*;
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#[cfg(android_platform)]
|
#[cfg(android_platform)]
|
||||||
pub(crate) use winit_android as platform;
|
pub(crate) use winit_android as platform;
|
||||||
#[cfg(macos_platform)]
|
#[cfg(macos_platform)]
|
||||||
mod apple;
|
pub(crate) use winit_appkit as platform;
|
||||||
#[cfg(any(x11_platform, wayland_platform))]
|
#[cfg(any(x11_platform, wayland_platform))]
|
||||||
mod linux;
|
mod linux;
|
||||||
#[cfg(orbital_platform)]
|
#[cfg(orbital_platform)]
|
||||||
@@ -13,8 +13,6 @@ mod web;
|
|||||||
#[cfg(windows_platform)]
|
#[cfg(windows_platform)]
|
||||||
pub(crate) use winit_win32 as platform;
|
pub(crate) use winit_win32 as platform;
|
||||||
|
|
||||||
#[cfg(macos_platform)]
|
|
||||||
use self::apple as platform;
|
|
||||||
#[cfg(any(x11_platform, wayland_platform))]
|
#[cfg(any(x11_platform, wayland_platform))]
|
||||||
use self::linux as platform;
|
use self::linux as platform;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
|||||||
116
winit-appkit/Cargo.toml
Normal file
116
winit-appkit/Cargo.toml
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
[package]
|
||||||
|
description = "Winit's Appkit / macOS backend"
|
||||||
|
documentation = "https://docs.rs/winit-appkit"
|
||||||
|
edition.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
name = "winit-appkit"
|
||||||
|
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, features = ["std", "objc2"] }
|
||||||
|
objc2.workspace = true
|
||||||
|
objc2-app-kit = { workspace = true, features = [
|
||||||
|
"std",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
"NSAppearance",
|
||||||
|
"NSApplication",
|
||||||
|
"NSBitmapImageRep",
|
||||||
|
"NSButton",
|
||||||
|
"NSColor",
|
||||||
|
"NSControl",
|
||||||
|
"NSCursor",
|
||||||
|
"NSDragging",
|
||||||
|
"NSEvent",
|
||||||
|
"NSGraphics",
|
||||||
|
"NSGraphicsContext",
|
||||||
|
"NSImage",
|
||||||
|
"NSImageRep",
|
||||||
|
"NSMenu",
|
||||||
|
"NSMenuItem",
|
||||||
|
"NSOpenGLView",
|
||||||
|
"NSPanel",
|
||||||
|
"NSPasteboard",
|
||||||
|
"NSResponder",
|
||||||
|
"NSRunningApplication",
|
||||||
|
"NSScreen",
|
||||||
|
"NSTextInputClient",
|
||||||
|
"NSTextInputContext",
|
||||||
|
"NSToolbar",
|
||||||
|
"NSView",
|
||||||
|
"NSWindow",
|
||||||
|
"NSWindowScripting",
|
||||||
|
"NSWindowTabGroup",
|
||||||
|
] }
|
||||||
|
objc2-core-foundation = { workspace = true, features = [
|
||||||
|
"std",
|
||||||
|
"block2",
|
||||||
|
"CFBase",
|
||||||
|
"CFCGTypes",
|
||||||
|
"CFData",
|
||||||
|
"CFRunLoop",
|
||||||
|
"CFString",
|
||||||
|
"CFUUID",
|
||||||
|
] }
|
||||||
|
objc2-core-graphics = { workspace = true, features = [
|
||||||
|
"std",
|
||||||
|
"libc",
|
||||||
|
"CGDirectDisplay",
|
||||||
|
"CGDisplayConfiguration",
|
||||||
|
"CGDisplayFade",
|
||||||
|
"CGError",
|
||||||
|
"CGRemoteOperation",
|
||||||
|
"CGWindowLevel",
|
||||||
|
] }
|
||||||
|
objc2-core-video = { workspace = true, features = [
|
||||||
|
"std",
|
||||||
|
"objc2-core-graphics",
|
||||||
|
"CVBase",
|
||||||
|
"CVReturn",
|
||||||
|
"CVDisplayLink",
|
||||||
|
] }
|
||||||
|
objc2-foundation = { workspace = true, features = [
|
||||||
|
"std",
|
||||||
|
"block2",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
"NSArray",
|
||||||
|
"NSAttributedString",
|
||||||
|
"NSData",
|
||||||
|
"NSDictionary",
|
||||||
|
"NSDistributedNotificationCenter",
|
||||||
|
"NSEnumerator",
|
||||||
|
"NSGeometry",
|
||||||
|
"NSKeyValueObserving",
|
||||||
|
"NSNotification",
|
||||||
|
"NSObjCRuntime",
|
||||||
|
"NSOperation",
|
||||||
|
"NSPathUtilities",
|
||||||
|
"NSProcessInfo",
|
||||||
|
"NSRunLoop",
|
||||||
|
"NSString",
|
||||||
|
"NSThread",
|
||||||
|
"NSValue",
|
||||||
|
] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
winit.workspace = true
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
all-features = true
|
||||||
|
targets = ["aarch64-apple-darwin", "x86_64-apple-darwin"]
|
||||||
1
winit-appkit/README.md
Symbolic link
1
winit-appkit/README.md
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../README.md
|
||||||
@@ -349,7 +349,7 @@ pub(super) fn dummy_event() -> Option<Retained<NSEvent>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option<u32> {
|
pub fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option<u32> {
|
||||||
let code = match physical_key {
|
let code = match physical_key {
|
||||||
PhysicalKey::Code(code) => code,
|
PhysicalKey::Code(code) => code,
|
||||||
PhysicalKey::Unidentified(_) => return None,
|
PhysicalKey::Unidentified(_) => return None,
|
||||||
@@ -481,7 +481,7 @@ pub(crate) fn physicalkey_to_scancode(physical_key: PhysicalKey) -> Option<u32>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn scancode_to_physicalkey(scancode: u32) -> PhysicalKey {
|
pub fn scancode_to_physicalkey(scancode: u32) -> PhysicalKey {
|
||||||
// Follows what Chromium and Firefox do:
|
// Follows what Chromium and Firefox do:
|
||||||
// https://chromium.googlesource.com/chromium/src.git/+/3e1a26c44c024d97dc9a4c09bbc6a2365398ca2c/ui/events/keycodes/dom/dom_code_data.inc
|
// https://chromium.googlesource.com/chromium/src.git/+/3e1a26c44c024d97dc9a4c09bbc6a2365398ca2c/ui/events/keycodes/dom/dom_code_data.inc
|
||||||
// https://searchfox.org/mozilla-central/rev/c597e9c789ad36af84a0370d395be066b7dc94f4/widget/NativeKeyToDOMCodeName.h
|
// https://searchfox.org/mozilla-central/rev/c597e9c789ad36af84a0370d395be066b7dc94f4/widget/NativeKeyToDOMCodeName.h
|
||||||
@@ -29,8 +29,8 @@ use super::event::dummy_event;
|
|||||||
use super::monitor;
|
use super::monitor;
|
||||||
use super::notification_center::create_observer;
|
use super::notification_center::create_observer;
|
||||||
use super::observer::setup_control_flow_observers;
|
use super::observer::setup_control_flow_observers;
|
||||||
use crate::platform::macos::ActivationPolicy;
|
use crate::window::Window;
|
||||||
use crate::platform_impl::Window;
|
use crate::ActivationPolicy;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ActiveEventLoop {
|
pub struct ActiveEventLoop {
|
||||||
@@ -153,10 +153,10 @@ pub struct EventLoop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub(crate) struct PlatformSpecificEventLoopAttributes {
|
pub struct PlatformSpecificEventLoopAttributes {
|
||||||
pub(crate) activation_policy: Option<ActivationPolicy>,
|
pub activation_policy: Option<ActivationPolicy>,
|
||||||
pub(crate) default_menu: bool,
|
pub default_menu: bool,
|
||||||
pub(crate) activate_ignoring_other_apps: bool,
|
pub activate_ignoring_other_apps: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlatformSpecificEventLoopAttributes {
|
impl Default for PlatformSpecificEventLoopAttributes {
|
||||||
@@ -166,9 +166,7 @@ impl Default for PlatformSpecificEventLoopAttributes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoop {
|
impl EventLoop {
|
||||||
pub(crate) fn new(
|
pub fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Result<Self, EventLoopError> {
|
||||||
attributes: &PlatformSpecificEventLoopAttributes,
|
|
||||||
) -> Result<Self, EventLoopError> {
|
|
||||||
let mtm = MainThreadMarker::new()
|
let mtm = MainThreadMarker::new()
|
||||||
.expect("on macOS, `EventLoop` must be created on the main thread!");
|
.expect("on macOS, `EventLoop` must be created on the main thread!");
|
||||||
|
|
||||||
@@ -17,13 +17,12 @@
|
|||||||
//! Instead, Winit guarantees that it will not register an application delegate, so the solution is
|
//! Instead, Winit guarantees that it will not register an application delegate, so the solution is
|
||||||
//! to register your own application delegate, as outlined in the following example (see
|
//! to register your own application delegate, as outlined in the following example (see
|
||||||
//! `objc2-app-kit` for more detailed information).
|
//! `objc2-app-kit` for more detailed information).
|
||||||
#![cfg_attr(target_os = "macos", doc = "```")]
|
//! ```
|
||||||
#![cfg_attr(not(target_os = "macos"), doc = "```ignore")]
|
|
||||||
//! use objc2::rc::Retained;
|
//! use objc2::rc::Retained;
|
||||||
//! use objc2::runtime::ProtocolObject;
|
//! use objc2::runtime::ProtocolObject;
|
||||||
//! use objc2::{define_class, msg_send, DefinedClass, MainThreadMarker, MainThreadOnly};
|
//! use objc2::{define_class, msg_send, DefinedClass, MainThreadMarker, MainThreadOnly};
|
||||||
//! use objc2_app_kit::{NSApplication, NSApplicationDelegate};
|
//! use objc2_app_kit::{NSApplication, NSApplicationDelegate};
|
||||||
//! use objc2_foundation::{NSArray, NSURL, NSObject, NSObjectProtocol};
|
//! use objc2_foundation::{NSArray, NSObject, NSObjectProtocol, NSURL};
|
||||||
//! use winit::event_loop::EventLoop;
|
//! use winit::event_loop::EventLoop;
|
||||||
//!
|
//!
|
||||||
//! define_class!(
|
//! define_class!(
|
||||||
@@ -64,6 +63,24 @@
|
|||||||
//! Ok(())
|
//! Ok(())
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
#![cfg(target_vendor = "apple")] // TODO: Remove once `objc2` allows compiling on all platforms
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod util;
|
||||||
|
|
||||||
|
mod app;
|
||||||
|
mod app_state;
|
||||||
|
mod cursor;
|
||||||
|
mod event;
|
||||||
|
mod event_loop;
|
||||||
|
mod ffi;
|
||||||
|
mod menu;
|
||||||
|
mod monitor;
|
||||||
|
mod notification_center;
|
||||||
|
mod observer;
|
||||||
|
mod view;
|
||||||
|
mod window;
|
||||||
|
mod window_delegate;
|
||||||
|
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
|
|
||||||
@@ -71,12 +88,15 @@ use std::os::raw::c_void;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use winit_core::application::macos::ApplicationHandlerExtMacOS;
|
pub use winit_core::application::macos::ApplicationHandlerExtMacOS;
|
||||||
use winit_core::window::PlatformWindowAttributes;
|
use winit_core::event_loop::ActiveEventLoop;
|
||||||
|
use winit_core::monitor::MonitorHandle;
|
||||||
|
use winit_core::window::{PlatformWindowAttributes, Window};
|
||||||
|
|
||||||
use crate::event_loop::{ActiveEventLoop, EventLoopBuilder};
|
pub use self::event::{physicalkey_to_scancode, scancode_to_physicalkey};
|
||||||
use crate::monitor::MonitorHandle;
|
use self::event_loop::ActiveEventLoop as AppKitActiveEventLoop;
|
||||||
use crate::platform_impl::MonitorHandle as MacOsMonitorHandle;
|
pub use self::event_loop::{EventLoop, PlatformSpecificEventLoopAttributes};
|
||||||
use crate::window::Window;
|
use self::monitor::MonitorHandle as AppKitMonitorHandle;
|
||||||
|
use self::window::Window as AppKitWindow;
|
||||||
|
|
||||||
/// Additional methods on [`Window`] that are specific to MacOS.
|
/// Additional methods on [`Window`] that are specific to MacOS.
|
||||||
pub trait WindowExtMacOS {
|
pub trait WindowExtMacOS {
|
||||||
@@ -172,109 +192,109 @@ pub trait WindowExtMacOS {
|
|||||||
impl WindowExtMacOS for dyn Window + '_ {
|
impl WindowExtMacOS for dyn Window + '_ {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn simple_fullscreen(&self) -> bool {
|
fn simple_fullscreen(&self) -> bool {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.simple_fullscreen())
|
window.maybe_wait_on_main(|w| w.simple_fullscreen())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_simple_fullscreen(&self, fullscreen: bool) -> bool {
|
fn set_simple_fullscreen(&self, fullscreen: bool) -> bool {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(move |w| w.set_simple_fullscreen(fullscreen))
|
window.maybe_wait_on_main(move |w| w.set_simple_fullscreen(fullscreen))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn has_shadow(&self) -> bool {
|
fn has_shadow(&self) -> bool {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.has_shadow())
|
window.maybe_wait_on_main(|w| w.has_shadow())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_has_shadow(&self, has_shadow: bool) {
|
fn set_has_shadow(&self, has_shadow: bool) {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(move |w| w.set_has_shadow(has_shadow));
|
window.maybe_wait_on_main(move |w| w.set_has_shadow(has_shadow));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_tabbing_identifier(&self, identifier: &str) {
|
fn set_tabbing_identifier(&self, identifier: &str) {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.set_tabbing_identifier(identifier))
|
window.maybe_wait_on_main(|w| w.set_tabbing_identifier(identifier))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn tabbing_identifier(&self) -> String {
|
fn tabbing_identifier(&self) -> String {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.tabbing_identifier())
|
window.maybe_wait_on_main(|w| w.tabbing_identifier())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn select_next_tab(&self) {
|
fn select_next_tab(&self) {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.select_next_tab());
|
window.maybe_wait_on_main(|w| w.select_next_tab());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn select_previous_tab(&self) {
|
fn select_previous_tab(&self) {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.select_previous_tab());
|
window.maybe_wait_on_main(|w| w.select_previous_tab());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn select_tab_at_index(&self, index: usize) {
|
fn select_tab_at_index(&self, index: usize) {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(move |w| w.select_tab_at_index(index));
|
window.maybe_wait_on_main(move |w| w.select_tab_at_index(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn num_tabs(&self) -> usize {
|
fn num_tabs(&self) -> usize {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.num_tabs())
|
window.maybe_wait_on_main(|w| w.num_tabs())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_document_edited(&self) -> bool {
|
fn is_document_edited(&self) -> bool {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.is_document_edited())
|
window.maybe_wait_on_main(|w| w.is_document_edited())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_document_edited(&self, edited: bool) {
|
fn set_document_edited(&self, edited: bool) {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(move |w| w.set_document_edited(edited));
|
window.maybe_wait_on_main(move |w| w.set_document_edited(edited));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_option_as_alt(&self, option_as_alt: OptionAsAlt) {
|
fn set_option_as_alt(&self, option_as_alt: OptionAsAlt) {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(move |w| w.set_option_as_alt(option_as_alt));
|
window.maybe_wait_on_main(move |w| w.set_option_as_alt(option_as_alt));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn option_as_alt(&self) -> OptionAsAlt {
|
fn option_as_alt(&self) -> OptionAsAlt {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.option_as_alt())
|
window.maybe_wait_on_main(|w| w.option_as_alt())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_borderless_game(&self, borderless_game: bool) {
|
fn set_borderless_game(&self, borderless_game: bool) {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.set_borderless_game(borderless_game))
|
window.maybe_wait_on_main(|w| w.set_borderless_game(borderless_game))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_borderless_game(&self) -> bool {
|
fn is_borderless_game(&self) -> bool {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.is_borderless_game())
|
window.maybe_wait_on_main(|w| w.is_borderless_game())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_unified_titlebar(&self, unified_titlebar: bool) {
|
fn set_unified_titlebar(&self, unified_titlebar: bool) {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.set_unified_titlebar(unified_titlebar))
|
window.maybe_wait_on_main(|w| w.set_unified_titlebar(unified_titlebar))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn unified_titlebar(&self) -> bool {
|
fn unified_titlebar(&self) -> bool {
|
||||||
let window = self.cast_ref::<crate::platform_impl::Window>().unwrap();
|
let window = self.cast_ref::<AppKitWindow>().unwrap();
|
||||||
window.maybe_wait_on_main(|w| w.unified_titlebar())
|
window.maybe_wait_on_main(|w| w.unified_titlebar())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -513,26 +533,6 @@ pub trait EventLoopBuilderExtMacOS {
|
|||||||
fn with_activate_ignoring_other_apps(&mut self, ignore: bool) -> &mut Self;
|
fn with_activate_ignoring_other_apps(&mut self, ignore: bool) -> &mut Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventLoopBuilderExtMacOS for EventLoopBuilder {
|
|
||||||
#[inline]
|
|
||||||
fn with_activation_policy(&mut self, activation_policy: ActivationPolicy) -> &mut Self {
|
|
||||||
self.platform_specific.activation_policy = Some(activation_policy);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_default_menu(&mut self, enable: bool) -> &mut Self {
|
|
||||||
self.platform_specific.default_menu = enable;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn with_activate_ignoring_other_apps(&mut self, ignore: bool) -> &mut Self {
|
|
||||||
self.platform_specific.activate_ignoring_other_apps = ignore;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Additional methods on [`MonitorHandle`] that are specific to MacOS.
|
/// Additional methods on [`MonitorHandle`] that are specific to MacOS.
|
||||||
pub trait MonitorHandleExtMacOS {
|
pub trait MonitorHandleExtMacOS {
|
||||||
/// Returns a pointer to the NSScreen representing this monitor.
|
/// Returns a pointer to the NSScreen representing this monitor.
|
||||||
@@ -541,7 +541,7 @@ pub trait MonitorHandleExtMacOS {
|
|||||||
|
|
||||||
impl MonitorHandleExtMacOS for MonitorHandle {
|
impl MonitorHandleExtMacOS for MonitorHandle {
|
||||||
fn ns_screen(&self) -> Option<*mut c_void> {
|
fn ns_screen(&self) -> Option<*mut c_void> {
|
||||||
let monitor = self.cast_ref::<MacOsMonitorHandle>().unwrap();
|
let monitor = self.cast_ref::<AppKitMonitorHandle>().unwrap();
|
||||||
// SAFETY: We only use the marker to get a pointer
|
// SAFETY: We only use the marker to get a pointer
|
||||||
let mtm = unsafe { objc2::MainThreadMarker::new_unchecked() };
|
let mtm = unsafe { objc2::MainThreadMarker::new_unchecked() };
|
||||||
monitor.ns_screen(mtm).map(|s| objc2::rc::Retained::as_ptr(&s) as _)
|
monitor.ns_screen(mtm).map(|s| objc2::rc::Retained::as_ptr(&s) as _)
|
||||||
@@ -566,30 +566,26 @@ pub trait ActiveEventLoopExtMacOS {
|
|||||||
|
|
||||||
impl ActiveEventLoopExtMacOS for dyn ActiveEventLoop + '_ {
|
impl ActiveEventLoopExtMacOS for dyn ActiveEventLoop + '_ {
|
||||||
fn hide_application(&self) {
|
fn hide_application(&self) {
|
||||||
let event_loop = self
|
let event_loop =
|
||||||
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
|
self.cast_ref::<AppKitActiveEventLoop>().expect("non macOS event loop on macOS");
|
||||||
.expect("non macOS event loop on macOS");
|
|
||||||
event_loop.hide_application()
|
event_loop.hide_application()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hide_other_applications(&self) {
|
fn hide_other_applications(&self) {
|
||||||
let event_loop = self
|
let event_loop =
|
||||||
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
|
self.cast_ref::<AppKitActiveEventLoop>().expect("non macOS event loop on macOS");
|
||||||
.expect("non macOS event loop on macOS");
|
|
||||||
event_loop.hide_other_applications()
|
event_loop.hide_other_applications()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_allows_automatic_window_tabbing(&self, enabled: bool) {
|
fn set_allows_automatic_window_tabbing(&self, enabled: bool) {
|
||||||
let event_loop = self
|
let event_loop =
|
||||||
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
|
self.cast_ref::<AppKitActiveEventLoop>().expect("non macOS event loop on macOS");
|
||||||
.expect("non macOS event loop on macOS");
|
|
||||||
event_loop.set_allows_automatic_window_tabbing(enabled);
|
event_loop.set_allows_automatic_window_tabbing(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allows_automatic_window_tabbing(&self) -> bool {
|
fn allows_automatic_window_tabbing(&self) -> bool {
|
||||||
let event_loop = self
|
let event_loop =
|
||||||
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
|
self.cast_ref::<AppKitActiveEventLoop>().expect("non macOS event loop on macOS");
|
||||||
.expect("non macOS event loop on macOS");
|
|
||||||
event_loop.allows_automatic_window_tabbing()
|
event_loop.allows_automatic_window_tabbing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,15 @@ use objc2_core_graphics::CGError;
|
|||||||
use tracing::trace;
|
use tracing::trace;
|
||||||
use winit_core::error::OsError;
|
use winit_core::error::OsError;
|
||||||
|
|
||||||
|
macro_rules! os_error {
|
||||||
|
($error:expr) => {{
|
||||||
|
winit_core::error::OsError::new(line!(), file!(), $error)
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! trace_scope {
|
macro_rules! trace_scope {
|
||||||
($s:literal) => {
|
($s:literal) => {
|
||||||
let _crate =
|
let _crate = $crate::util::TraceGuard::new(module_path!(), $s);
|
||||||
$crate::platform_impl::platform::appkit::util::TraceGuard::new(module_path!(), $s);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ use super::event::{
|
|||||||
scancode_to_physicalkey,
|
scancode_to_physicalkey,
|
||||||
};
|
};
|
||||||
use super::window::window_id;
|
use super::window::window_id;
|
||||||
use crate::platform::macos::OptionAsAlt;
|
use crate::OptionAsAlt;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct CursorState {
|
struct CursorState {
|
||||||
@@ -52,13 +52,13 @@ use winit_core::window::{
|
|||||||
|
|
||||||
use super::app_state::AppState;
|
use super::app_state::AppState;
|
||||||
use super::cursor::{cursor_from_icon, CustomCursor};
|
use super::cursor::{cursor_from_icon, CustomCursor};
|
||||||
use super::monitor::{self, flip_window_screen_coordinates, get_display_id};
|
use super::ffi;
|
||||||
|
use super::monitor::{self, flip_window_screen_coordinates, get_display_id, MonitorHandle};
|
||||||
use super::observer::RunLoop;
|
use super::observer::RunLoop;
|
||||||
use super::util::cgerr;
|
use super::util::cgerr;
|
||||||
use super::view::WinitView;
|
use super::view::WinitView;
|
||||||
use super::window::{window_id, WinitPanel, WinitWindow};
|
use super::window::{window_id, WinitPanel, WinitWindow};
|
||||||
use super::{ffi, MonitorHandle};
|
use crate::{OptionAsAlt, WindowAttributesMacOS, WindowExtMacOS};
|
||||||
use crate::platform::macos::{OptionAsAlt, WindowAttributesMacOS, WindowExtMacOS};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct State {
|
pub(crate) struct State {
|
||||||
@@ -70,3 +70,7 @@ objc2-ui-kit = { workspace = true, features = [
|
|||||||
"UIViewController",
|
"UIViewController",
|
||||||
"UIWindow",
|
"UIWindow",
|
||||||
] }
|
] }
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
all-features = true
|
||||||
|
targets = ["aarch64-apple-ios", "aarch64-apple-ios-macabi"]
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
../../src/platform_impl/apple/appkit/notification_center.rs
|
../../winit-appkit/src/notification_center.rs
|
||||||
Reference in New Issue
Block a user