#[cfg(not(feature = "mini"))]
use crate::compat::OnceLock;
#[cfg(all(target_os = "android", not(feature = "mini"), not(feature = "embedded")))]
use crate::platform::android::AndroidPlatform;
#[cfg(all(
any(target_os = "ohos", feature = "harmony"),
not(target_os = "android"),
not(feature = "mini"),
not(feature = "embedded")
))]
use crate::platform::harmony::HarmonyPlatform;
#[cfg(all(not(feature = "mini"), target_os = "ios", not(feature = "embedded")))]
use crate::platform::ios::IosMobilePlatform;
#[cfg(all(
target_os = "linux",
not(feature = "mini"),
not(feature = "embedded"),
not(feature = "harmony")
))]
use crate::platform::linux::LinuxPlatform;
#[cfg(all(
not(feature = "mini"),
target_os = "macos",
not(feature = "embedded"),
any(feature = "macos", feature = "macos-legacy"),
// Must mirror the `create_native_platform` gate below exactly: this import has
// no other user, so if the two ever diverge the build warns about an unused
// import (or fails outright).
not(feature = "harmony")
))]
use crate::platform::macos::macos_bridge::SelectedMacOSPlatform;
#[cfg(all(not(feature = "embedded"), feature = "mobile-api"))]
use crate::platform::mobile;
#[cfg(not(feature = "mini"))]
pub use crate::platform::types::*;
#[cfg(all(
target_os = "linux",
not(feature = "embedded"),
feature = "wayland-native",
not(feature = "harmony")
))]
use crate::platform::wayland::WaylandPlatform;
#[cfg(all(
not(feature = "mini"),
target_os = "windows",
not(feature = "embedded"),
// Must mirror its only user, `create_native_platform`, exactly.
not(feature = "harmony")
))]
use crate::platform::windows::WindowsPlatform;
#[cfg(all(
target_os = "linux",
not(feature = "embedded"),
feature = "wayland-native",
not(feature = "harmony")
))]
fn is_wayland_session() -> bool {
std::env::var("WAYLAND_DISPLAY").is_ok()
|| std::env::var("XDG_SESSION_TYPE")
.map(|t| t.eq_ignore_ascii_case("wayland"))
.unwrap_or(false)
}
#[cfg(all(not(feature = "mini"), feature = "embedded"))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(crate::platform::stub::StubPlatform::new(
"embedded-runtime-stub",
crate::core::PlatformFamily::Embedded,
))
}
#[cfg(all(
not(feature = "mini"),
target_os = "windows",
not(feature = "embedded"),
// Mirrors the macOS/Linux/iOS arms: the `harmony` preview backend must win on
// any host, otherwise `--features full` defines this function twice.
not(feature = "harmony")
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(WindowsPlatform::new())
}
#[cfg(all(
not(feature = "mini"),
target_os = "macos",
not(feature = "embedded"),
any(feature = "macos", feature = "macos-legacy"),
not(feature = "harmony")
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(SelectedMacOSPlatform::new())
}
#[cfg(all(
not(feature = "mini"),
target_os = "macos",
not(feature = "embedded"),
not(any(feature = "macos", feature = "macos-legacy")),
not(feature = "harmony")
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(crate::platform::stub::StubPlatform::new(
"macos-fallback-stub",
crate::core::PlatformFamily::Desktop,
))
}
#[cfg(all(
not(feature = "mini"),
target_os = "linux",
not(feature = "embedded"),
feature = "wayland-native",
not(feature = "harmony")
))]
fn create_native_platform() -> Box<dyn Platform> {
if is_wayland_session() {
Box::new(WaylandPlatform::new())
} else {
Box::new(LinuxPlatform::new())
}
}
#[cfg(all(
not(feature = "mini"),
target_os = "linux",
not(feature = "embedded"),
not(feature = "wayland-native"),
not(feature = "harmony")
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(LinuxPlatform::new())
}
#[cfg(all(
not(feature = "mini"),
target_os = "android",
not(feature = "embedded"),
// Mirrors the HarmonyOS arm's own `not(target_os = "android")` exclusion, and
// keeps the two mutually exclusive when the feature is set on an Android host.
not(feature = "harmony")
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(AndroidPlatform::new())
}
#[cfg(all(
any(target_os = "ohos", feature = "harmony"),
not(target_os = "android"),
not(feature = "mini"),
not(feature = "embedded")
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(HarmonyPlatform::new())
}
#[cfg(all(
not(feature = "mini"),
target_os = "ios",
not(feature = "embedded"),
not(feature = "harmony")
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(IosMobilePlatform::new())
}
#[cfg(all(
not(feature = "mini"),
not(feature = "embedded"),
feature = "wasm",
target_arch = "wasm32"
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(crate::platform::wasm::WasmPlatform::default())
}
#[cfg(all(
not(feature = "mini"),
not(feature = "embedded"),
not(all(feature = "wasm", target_arch = "wasm32")),
not(target_os = "android"),
not(any(target_os = "ohos", feature = "harmony")),
not(any(target_os = "windows", target_os = "macos", target_os = "linux", target_os = "ios"))
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(crate::platform::stub::StubPlatform::new(
"unknown-runtime-stub",
crate::core::PlatformFamily::Desktop,
))
}
#[cfg(not(feature = "mini"))]
static PLATFORM: OnceLock<Box<dyn Platform>> = OnceLock::new();
#[cfg(not(feature = "mini"))]
pub fn get_platform() -> &'static dyn Platform {
PLATFORM.get_or_init(create_native_platform).as_ref()
}
#[cfg(not(feature = "mini"))]
pub fn init() {
get_platform().init();
}
#[cfg(not(feature = "mini"))]
pub fn run() {
get_platform().run();
}
#[cfg(not(feature = "mini"))]
pub fn quit() {
get_platform().quit();
}
#[cfg(not(feature = "mini"))]
pub fn capabilities() -> PlatformCapabilities {
get_platform().capabilities()
}
#[cfg(not(feature = "mini"))]
pub fn backend_name() -> &'static str {
get_platform().backend_name()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RuntimeGuiMode {
NativeInteractive,
PreviewOrStub,
}
#[cfg(not(feature = "mini"))]
pub fn runtime_gui_mode_for(platform: &dyn Platform) -> RuntimeGuiMode {
match platform.backend_name() {
"cocoa" | "WindowsPlatform" => RuntimeGuiMode::NativeInteractive,
"wayland" => {
#[cfg(all(target_os = "linux", feature = "wayland-native"))]
{
RuntimeGuiMode::NativeInteractive
}
#[cfg(not(all(target_os = "linux", feature = "wayland-native")))]
{
RuntimeGuiMode::PreviewOrStub
}
}
"gtk" => {
#[cfg(all(target_os = "linux", feature = "gtk-native"))]
{
RuntimeGuiMode::NativeInteractive
}
#[cfg(not(all(target_os = "linux", feature = "gtk-native")))]
{
RuntimeGuiMode::PreviewOrStub
}
}
"harmony-desktop"
| "harmony-state-backend"
| "macos-objc2-preview"
| "macos-fallback-stub"
| "android-state-backend"
| "ios-mobile-stub" => RuntimeGuiMode::PreviewOrStub,
_ => RuntimeGuiMode::PreviewOrStub,
}
}
#[cfg(not(feature = "mini"))]
pub fn runtime_gui_mode() -> RuntimeGuiMode {
runtime_gui_mode_for(get_platform())
}
#[cfg(not(feature = "mini"))]
pub fn dpi_scale_factor() -> f32 {
get_platform().dpi_scale_factor()
}
#[cfg(feature = "mobile-api")]
pub fn mobile_backend_name() -> &'static str {
#[cfg(not(feature = "embedded"))]
{
if let Some(ext) = get_platform().mobile_extension() {
return match ext.mobile_backend() {
crate::platform::types::MobileBackend::Android => "android-mobile",
crate::platform::types::MobileBackend::Ios => "ios-mobile",
crate::platform::types::MobileBackend::HarmonyMobile => "harmony-mobile",
};
}
mobile::get_mobile_platform().backend_name()
}
#[cfg(feature = "embedded")]
{
"embedded"
}
}
#[cfg(feature = "mobile-api")]
pub fn mobile_attach_to_native_view(native_handle: usize) -> bool {
#[cfg(not(feature = "embedded"))]
{
if let Some(ext) = get_platform().mobile_extension() {
return ext.attach_to_native_view(native_handle);
}
mobile::get_mobile_platform().attach_to_native_view(native_handle)
}
#[cfg(feature = "embedded")]
{
let _ = native_handle;
false
}
}