From cd67bac544a874f668c706b837c8b3093dfb9545 Mon Sep 17 00:00:00 2001 From: "Peter S." Date: Wed, 30 Apr 2025 23:24:53 +0200 Subject: [PATCH] Expose deferred screen edges setting for ios devices (#18729) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Objective - This just exposes the preferred [screen edges deferring system gestures](https://developer.apple.com/documentation/uikit/uiviewcontroller/preferredscreenedgesdeferringsystemgestures) setting from [winit](https://docs.rs/winit/latest/winit/platform/ios/trait.WindowExtIOS.html#tymethod.set_preferred_screen_edges_deferring_system_gestures), making it accessible in bevy apps. This setting is useful for ios apps that make use of the screen edges, letting the app have control of the first edge gesture before relegating to the os. ## Testing - Tested on simulator and on an iPhone Xs --- --------- Co-authored-by: Alice Cecile Co-authored-by: Greeble <166992735+greeble-dev@users.noreply.github.com> Co-authored-by: François Mockers --- crates/bevy_window/src/window.rs | 37 ++++++++++++++++++++++++++ crates/bevy_winit/src/converters.rs | 16 +++++++++++ crates/bevy_winit/src/system.rs | 10 +++++++ crates/bevy_winit/src/winit_windows.rs | 7 +++++ examples/mobile/src/lib.rs | 4 ++- 5 files changed, 73 insertions(+), 1 deletion(-) diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index e09e254d40..31ff212ebe 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -443,6 +443,17 @@ pub struct Window { /// /// [`WindowAttributesExtIOS::with_prefers_status_bar_hidden`]: https://docs.rs/winit/latest/x86_64-apple-darwin/winit/platform/ios/trait.WindowAttributesExtIOS.html#tymethod.with_prefers_status_bar_hidden pub prefers_status_bar_hidden: bool, + /// Sets screen edges for which you want your gestures to take precedence + /// over the system gestures. + /// + /// Corresponds to [`WindowAttributesExtIOS::with_preferred_screen_edges_deferring_system_gestures`]. + /// + /// # Platform-specific + /// + /// - Only used on iOS. + /// + /// [`WindowAttributesExtIOS::with_preferred_screen_edges_deferring_system_gestures`]: https://docs.rs/winit/latest/x86_64-apple-darwin/winit/platform/ios/trait.WindowAttributesExtIOS.html#tymethod.with_preferred_screen_edges_deferring_system_gestures + pub preferred_screen_edges_deferring_system_gestures: ScreenEdge, } impl Default for Window { @@ -487,6 +498,7 @@ impl Default for Window { titlebar_show_buttons: true, prefers_home_indicator_hidden: false, prefers_status_bar_hidden: false, + preferred_screen_edges_deferring_system_gestures: Default::default(), } } } @@ -1444,6 +1456,31 @@ impl Default for EnabledButtons { #[derive(Component, Default)] pub struct ClosingWindow; +/// The edges of a screen. Corresponds to [`winit::platform::ios::ScreenEdge`]. +/// +/// # Platform-specific +/// +/// - Only used on iOS. +/// +/// [`winit::platform::ios::ScreenEdge`]: https://docs.rs/winit/latest/x86_64-apple-darwin/winit/platform/ios/struct.ScreenEdge.html +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Reflect)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] +pub enum ScreenEdge { + #[default] + /// No edge. + None, + /// The top edge of the screen. + Top, + /// The left edge of the screen. + Left, + /// The bottom edge of the screen. + Bottom, + /// The right edge of the screen. + Right, + /// All edges of the screen. + All, +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/bevy_winit/src/converters.rs b/crates/bevy_winit/src/converters.rs index ba41c62534..3de27162a4 100644 --- a/crates/bevy_winit/src/converters.rs +++ b/crates/bevy_winit/src/converters.rs @@ -10,6 +10,9 @@ use bevy_window::SystemCursorIcon; use bevy_window::{EnabledButtons, WindowLevel, WindowTheme}; use winit::keyboard::{Key, NamedKey, NativeKey}; +#[cfg(target_os = "ios")] +use bevy_window::ScreenEdge; + pub fn convert_keyboard_input( keyboard_input: &winit::event::KeyEvent, window: Entity, @@ -718,3 +721,16 @@ pub fn convert_resize_direction(resize_direction: CompassOctant) -> winit::windo CompassOctant::SouthEast => winit::window::ResizeDirection::SouthEast, } } + +#[cfg(target_os = "ios")] +/// Converts a [`bevy_window::ScreenEdge`] to a [`winit::platform::ios::ScreenEdge`]. +pub(crate) fn convert_screen_edge(edge: ScreenEdge) -> winit::platform::ios::ScreenEdge { + match edge { + ScreenEdge::None => winit::platform::ios::ScreenEdge::NONE, + ScreenEdge::Top => winit::platform::ios::ScreenEdge::TOP, + ScreenEdge::Bottom => winit::platform::ios::ScreenEdge::BOTTOM, + ScreenEdge::Left => winit::platform::ios::ScreenEdge::LEFT, + ScreenEdge::Right => winit::platform::ios::ScreenEdge::RIGHT, + ScreenEdge::All => winit::platform::ios::ScreenEdge::ALL, + } +} diff --git a/crates/bevy_winit/src/system.rs b/crates/bevy_winit/src/system.rs index f4ed1a59a3..32925db26b 100644 --- a/crates/bevy_winit/src/system.rs +++ b/crates/bevy_winit/src/system.rs @@ -568,6 +568,16 @@ pub(crate) fn changed_windows( if window.prefers_status_bar_hidden != cache.window.prefers_status_bar_hidden { winit_window.set_prefers_status_bar_hidden(window.prefers_status_bar_hidden); } + if window.preferred_screen_edges_deferring_system_gestures + != cache + .window + .preferred_screen_edges_deferring_system_gestures + { + use crate::converters::convert_screen_edge; + let preferred_edge = + convert_screen_edge(window.preferred_screen_edges_deferring_system_gestures); + winit_window.set_preferred_screen_edges_deferring_system_gestures(preferred_edge); + } } cache.window = window.clone(); } diff --git a/crates/bevy_winit/src/winit_windows.rs b/crates/bevy_winit/src/winit_windows.rs index 119da10fe1..b1d4b3d7b6 100644 --- a/crates/bevy_winit/src/winit_windows.rs +++ b/crates/bevy_winit/src/winit_windows.rs @@ -145,7 +145,14 @@ impl WinitWindows { #[cfg(target_os = "ios")] { + use crate::converters::convert_screen_edge; use winit::platform::ios::WindowAttributesExtIOS; + + let preferred_edge = + convert_screen_edge(window.preferred_screen_edges_deferring_system_gestures); + + winit_window_attributes = winit_window_attributes + .with_preferred_screen_edges_deferring_system_gestures(preferred_edge); winit_window_attributes = winit_window_attributes .with_prefers_home_indicator_hidden(window.prefers_home_indicator_hidden); winit_window_attributes = winit_window_attributes diff --git a/examples/mobile/src/lib.rs b/examples/mobile/src/lib.rs index c5df6ee3c7..ba93268e86 100644 --- a/examples/mobile/src/lib.rs +++ b/examples/mobile/src/lib.rs @@ -5,7 +5,7 @@ use bevy::{ input::{gestures::RotationGesture, touch::TouchPhase}, log::{Level, LogPlugin}, prelude::*, - window::{AppLifecycle, WindowMode}, + window::{AppLifecycle, ScreenEdge, WindowMode}, winit::WinitSettings, }; @@ -34,6 +34,8 @@ pub fn main() { prefers_home_indicator_hidden: true, // Only has an effect on iOS prefers_status_bar_hidden: true, + // Only has an effect on iOS + preferred_screen_edges_deferring_system_gestures: ScreenEdge::Bottom, ..default() }), ..default()