use bevy::prelude::*;
use bevy::window::WindowMode;
use super::constants::SCALE_FACTOR_EPSILON;
use super::types::FullscreenRestoreState;
use super::types::MonitorScaleStrategy;
use super::types::WindowRestoreState;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Resource)]
pub enum Platform {
MacOs,
Windows,
X11,
Wayland,
}
impl Platform {
#[must_use]
#[allow(
clippy::missing_const_for_fn,
reason = "Linux platform detection reads WAYLAND_DISPLAY at runtime"
)]
pub fn detect() -> Self {
#[cfg(target_os = "macos")]
{
Self::MacOs
}
#[cfg(target_os = "windows")]
{
Self::Windows
}
#[cfg(target_os = "linux")]
{
if std::env::var("WAYLAND_DISPLAY")
.map(|v| !v.is_empty())
.unwrap_or(false)
{
Self::Wayland
} else {
Self::X11
}
}
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
{
compile_error!("Unsupported platform")
}
}
#[must_use]
pub const fn is_x11(self) -> bool { matches!(self, Self::X11) }
#[must_use]
pub const fn is_wayland(self) -> bool { matches!(self, Self::Wayland) }
#[must_use]
pub const fn position_available(self) -> bool { !matches!(self, Self::Wayland) }
#[must_use]
pub fn modes_match(self, target: WindowMode, actual: WindowMode) -> bool {
target == actual
|| (matches!(self, Self::Wayland)
&& matches!(target, WindowMode::Fullscreen(..))
&& matches!(actual, WindowMode::BorderlessFullscreen(..)))
}
#[must_use]
pub const fn should_hide_on_startup(self) -> bool {
#[cfg(feature = "workaround-winit-4445")]
{
!matches!(self, Self::X11)
}
#[cfg(not(feature = "workaround-winit-4445"))]
{
true
}
}
#[must_use]
pub const fn needs_frame_compensation(self) -> bool {
#[cfg(feature = "workaround-winit-4445")]
{
matches!(self, Self::X11)
}
#[cfg(not(feature = "workaround-winit-4445"))]
{
false
}
}
#[must_use]
pub const fn position_reliable_for_settle(self) -> bool { !self.needs_frame_compensation() }
#[must_use]
pub const fn should_clamp_position(self) -> bool { matches!(self, Self::MacOs) }
#[must_use]
pub const fn exclusive_fullscreen_fallback(self) -> bool { matches!(self, Self::Wayland) }
#[must_use]
pub(crate) const fn fullscreen_restore_state(self) -> FullscreenRestoreState {
#[cfg(feature = "workaround-winit-3124")]
if matches!(self, Self::Windows) {
return FullscreenRestoreState::WaitForSurface;
}
match self {
Self::X11 => FullscreenRestoreState::MoveToMonitor,
_ => FullscreenRestoreState::ApplyMode,
}
}
#[must_use]
pub(crate) fn scale_strategy(
self,
starting_scale: f64,
target_scale: f64,
) -> MonitorScaleStrategy {
if !cfg!(feature = "workaround-winit-4440") {
return MonitorScaleStrategy::ApplyUnchanged;
}
if matches!(self, Self::Wayland) {
return MonitorScaleStrategy::ApplyUnchanged;
}
if (starting_scale - target_scale).abs() < SCALE_FACTOR_EPSILON {
MonitorScaleStrategy::ApplyUnchanged
} else if matches!(self, Self::Windows) {
MonitorScaleStrategy::CompensateSizeOnly(WindowRestoreState::NeedInitialMove)
} else if starting_scale < target_scale {
MonitorScaleStrategy::LowerToHigher
} else {
MonitorScaleStrategy::HigherToLower(WindowRestoreState::NeedInitialMove)
}
}
#[must_use]
pub const fn needs_managed_scale_fixup(self) -> bool { matches!(self, Self::Windows) }
}