Skip to main content

i_slint_core/
lib.rs

1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4// cSpell: ignore sharedvector textlayout
5
6#![doc = include_str!("README.md")]
7#![doc(html_logo_url = "https://slint.dev/logo/slint-logo-square-light.svg")]
8#![cfg_attr(docsrs, feature(doc_cfg))]
9#![deny(unsafe_code)]
10#![allow(clippy::missing_safety_doc)] // FFI surface has many exported unsafe entry points
11#![cfg_attr(slint_nightly_test, feature(non_exhaustive_omitted_patterns_lint))]
12#![cfg_attr(slint_nightly_test, warn(non_exhaustive_omitted_patterns))]
13#![no_std]
14#![debugger_visualizer(gdb_script_file = "gdb_pretty_printers.py")]
15
16extern crate alloc;
17#[cfg(feature = "std")]
18extern crate std;
19
20#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
21pub mod unsafe_single_threaded;
22#[cfg(all(not(feature = "std"), not(feature = "unsafe-single-threaded")))]
23compile_error!(
24    "At least one of the following feature need to be enabled: `std` or `unsafe-single-threaded`"
25);
26pub use crate::items::OperatingSystemType;
27#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
28pub use crate::unsafe_single_threaded::thread_local;
29#[cfg(feature = "std")]
30pub use std::thread_local;
31
32pub mod accessibility;
33pub mod animations;
34pub mod api;
35pub mod callbacks;
36pub mod component_factory;
37pub mod context;
38pub mod cursor;
39pub mod data_transfer;
40pub mod date_time;
41pub mod debug_log;
42pub mod future;
43pub mod graphics;
44pub mod input;
45pub mod item_focus;
46pub mod item_rendering;
47pub mod item_tree;
48pub mod items;
49pub mod layout;
50pub mod lengths;
51pub mod menus;
52pub mod model;
53pub mod partial_renderer;
54pub mod platform;
55pub mod properties;
56pub mod renderer;
57#[cfg(feature = "rtti")]
58pub mod rtti;
59pub mod sharedvector;
60pub mod slice;
61pub mod string;
62pub mod styled_text;
63pub mod textlayout;
64pub mod timers;
65pub mod translations;
66pub mod window;
67
68#[doc(inline)]
69pub use string::SharedString;
70
71#[doc(inline)]
72pub use sharedvector::SharedVector;
73
74#[doc(inline)]
75pub use graphics::{ImageInner, StaticTextures};
76
77#[doc(inline)]
78pub use properties::Property;
79
80#[doc(inline)]
81pub use callbacks::Callback;
82
83#[doc(inline)]
84pub use graphics::Color;
85
86#[doc(inline)]
87pub use graphics::Brush;
88
89#[doc(inline)]
90pub use graphics::RgbaColor;
91
92#[cfg(feature = "std")]
93#[doc(inline)]
94pub use graphics::PathData;
95
96#[doc(inline)]
97pub use graphics::BorderRadius;
98
99#[doc(inline)]
100pub use data_transfer::DataTransfer;
101
102pub use context::{SlintContext, SlintContextWeak, with_global_context};
103
104#[cfg(not(slint_int_coord))]
105pub type Coord = f32;
106#[cfg(slint_int_coord)]
107pub type Coord = i32;
108
109/// This type is not exported from the public API crate, so function having this
110/// parameter cannot be called from the public API without naming it
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub struct InternalToken;
113
114#[cfg(feature = "std")]
115thread_local!(
116    /// Permit testing code to force an OS type
117    pub static OPERATING_SYSTEM_OVERRIDE: core::cell::Cell<Option<OperatingSystemType>> =
118        Default::default();
119);
120
121#[cfg(not(target_family = "wasm"))]
122pub fn detect_operating_system() -> OperatingSystemType {
123    #[cfg(feature = "std")]
124    if let Some(os_override) = OPERATING_SYSTEM_OVERRIDE.with(|os_override| os_override.get()) {
125        return os_override;
126    }
127
128    if cfg!(target_os = "android") {
129        OperatingSystemType::Android
130    } else if cfg!(target_os = "ios") {
131        OperatingSystemType::Ios
132    } else if cfg!(target_os = "macos") {
133        OperatingSystemType::Macos
134    } else if cfg!(target_os = "windows") {
135        OperatingSystemType::Windows
136    } else if cfg!(target_os = "linux") {
137        OperatingSystemType::Linux
138    } else {
139        OperatingSystemType::Other
140    }
141}
142
143#[cfg(target_family = "wasm")]
144pub fn detect_operating_system() -> OperatingSystemType {
145    if let Some(os_override) = OPERATING_SYSTEM_OVERRIDE.with(|os_override| os_override.get()) {
146        return os_override;
147    }
148
149    // Querying the navigator involves a round-trip to JavaScript and some string processing, so
150    // cache the result: it cannot change for the lifetime of the page.
151    static DETECTED: std::sync::LazyLock<OperatingSystemType> = std::sync::LazyLock::new(|| {
152        let mut user_agent =
153            web_sys::window().and_then(|w| w.navigator().user_agent().ok()).unwrap_or_default();
154        user_agent.make_ascii_lowercase();
155        let mut platform =
156            web_sys::window().and_then(|w| w.navigator().platform().ok()).unwrap_or_default();
157        platform.make_ascii_lowercase();
158
159        if user_agent.contains("ipad") || user_agent.contains("iphone") {
160            OperatingSystemType::Ios
161        } else if user_agent.contains("android") {
162            OperatingSystemType::Android
163        } else if platform.starts_with("mac") {
164            OperatingSystemType::Macos
165        } else if platform.starts_with("win") {
166            OperatingSystemType::Windows
167        } else if platform.starts_with("linux") {
168            OperatingSystemType::Linux
169        } else {
170            OperatingSystemType::Other
171        }
172    });
173    *DETECTED
174}
175
176/// Returns true if the current platform is an Apple platform (macOS, iOS, iPadOS)
177pub fn is_apple_platform() -> bool {
178    matches!(detect_operating_system(), OperatingSystemType::Macos | OperatingSystemType::Ios)
179}
180
181pub fn open_url(url: &str, window: &crate::api::Window) -> Result<(), crate::api::PlatformError> {
182    crate::window::WindowInner::from_pub(window).context().platform().open_url(url)
183}
184
185#[cfg(target_os = "macos")]
186pub fn macos_bring_all_windows_to_front() {
187    use objc2::MainThreadMarker;
188    use objc2_app_kit::NSApplication;
189    let Some(mtm) = MainThreadMarker::new() else { return };
190    NSApplication::sharedApplication(mtm).arrangeInFront(None);
191}
192
193#[cfg(not(target_os = "macos"))]
194pub fn macos_bring_all_windows_to_front() {}