1#![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)] #![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#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub struct InternalToken;
113
114#[cfg(feature = "std")]
115thread_local!(
116 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 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
176pub 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() {}