1#[cfg(target_os = "ios")]
2pub use ios::get_safe_area_insets;
3
4#[cfg(target_os = "ios")]
5mod ios {
6 use egui::{SafeAreaInsets, epaint::MarginF32};
7 use objc2::{ClassType, rc::Retained};
8 use objc2_foundation::{MainThreadMarker, NSObjectProtocol};
9 use objc2_ui_kit::{UIApplication, UISceneActivationState, UIWindowScene};
10
11 pub fn get_safe_area_insets() -> SafeAreaInsets {
21 let Some(main_thread_marker) = MainThreadMarker::new() else {
22 log::error!("Getting safe area insets needs to be performed on the main thread");
23 return SafeAreaInsets::default();
24 };
25
26 let app = UIApplication::sharedApplication(main_thread_marker);
27
28 #[allow(unsafe_code)]
29 unsafe {
30 for scene in app.connectedScenes() {
32 if scene.isKindOfClass(UIWindowScene::class())
33 && matches!(
34 scene.activationState(),
35 UISceneActivationState::ForegroundActive
36 | UISceneActivationState::ForegroundInactive
37 )
38 {
39 let window_scene = Retained::cast::<UIWindowScene>(scene.clone());
41 if let Some(window) = window_scene.keyWindow() {
42 let insets = window.safeAreaInsets();
43 return SafeAreaInsets(MarginF32 {
44 top: insets.top as f32,
45 left: insets.left as f32,
46 right: insets.right as f32,
47 bottom: insets.bottom as f32,
48 });
49 }
50 }
51 }
52 }
53
54 SafeAreaInsets::default()
55 }
56}