use crate::compat::OnceLock;
#[cfg(not(feature = "mini"))]
#[allow(unused_imports)]
use crate::core::PlatformFamily;
#[cfg(target_os = "ios")]
use crate::platform::ios::IosMobilePlatform;
#[cfg(all(target_os = "linux", not(feature = "embedded")))]
use crate::platform::linux::LinuxPlatform;
#[cfg(all(
target_os = "macos",
not(feature = "embedded"),
any(feature = "macos", feature = "macos-legacy")
))]
use crate::platform::macos::macos_bridge::SelectedMacOSPlatform;
#[cfg(all(not(feature = "embedded"), feature = "mobile-api"))]
use crate::platform::mobile;
pub use crate::platform::types::*;
#[cfg(all(target_os = "linux", not(feature = "embedded"), feature = "wayland-native"))]
use crate::platform::wayland::WaylandPlatform;
#[cfg(all(target_os = "windows", not(feature = "embedded")))]
use crate::platform::windows::WindowsPlatform;
#[cfg(not(feature = "mini"))]
#[allow(unused_imports)]
use crate::platform::StubPlatform;
#[cfg(all(target_os = "linux", not(feature = "embedded"), feature = "wayland-native"))]
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(StubPlatform::new("embedded-runtime-stub", PlatformFamily::Embedded))
}
#[cfg(all(not(feature = "mini"), target_os = "windows", not(feature = "embedded")))]
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")
))]
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"))
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(StubPlatform::new("macos-fallback-stub", PlatformFamily::Desktop))
}
#[cfg(all(
not(feature = "mini"),
target_os = "linux",
not(feature = "embedded"),
feature = "wayland-native"
))]
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")
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(LinuxPlatform::new())
}
#[cfg(all(not(feature = "mini"), target_os = "ios", not(feature = "embedded")))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(IosMobilePlatform::new())
}
#[cfg(all(
not(feature = "mini"),
not(feature = "embedded"),
not(any(target_os = "windows", target_os = "macos", target_os = "linux", target_os = "ios"))
))]
fn create_native_platform() -> Box<dyn Platform> {
Box::new(StubPlatform::new("unknown-runtime-stub", 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()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RuntimeGuiMode {
NativeInteractive,
PreviewOrStub,
}
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"))]
{
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"))]
{
mobile::get_mobile_platform().attach_to_native_view(native_handle)
}
#[cfg(feature = "embedded")]
{
let _ = native_handle;
false
}
}