Expose deferred screen edges setting for ios devices (#18729)

# 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 <alice.i.cecile@gmail.com>
Co-authored-by: Greeble <166992735+greeble-dev@users.noreply.github.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
This commit is contained in:
Peter S. 2025-04-30 23:24:53 +02:00 committed by GitHub
parent 21b62d640b
commit cd67bac544
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 73 additions and 1 deletions

View File

@ -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::*;

View File

@ -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,
}
}

View File

@ -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();
}

View File

@ -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

View File

@ -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()