use dpi::{LogicalPosition, LogicalSize};
#[cfg(target_os = "macos")]
use macos::{
MacOSDisplayId as PlatformDisplayId, MacOSDisplayObserver as PlatformDisplayObserver,
MacOSError as PlatformError, get_macos_displays as get_platform_displays,
};
#[cfg(target_os = "windows")]
use windows::{
WindowsDisplayId as PlatformDisplayId, WindowsDisplayObserver as PlatformDisplayObserver,
WindowsError as PlatformError, get_windows_displays as get_platform_displays,
};
#[cfg(target_os = "macos")]
pub mod macos;
#[cfg(target_os = "windows")]
pub mod windows;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Initialization failed.")]
InitializationError(PlatformError),
#[error("A platform-specific error has occurred.")]
PlatformError(PlatformError),
}
impl From<PlatformError> for Error {
fn from(value: PlatformError) -> Self {
Self::PlatformError(value)
}
}
pub fn get_displays() -> Result<Vec<Display>, Error> {
Ok(get_platform_displays()?)
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct DisplayId(PlatformDisplayId);
impl From<PlatformDisplayId> for DisplayId {
fn from(value: PlatformDisplayId) -> Self {
Self(value)
}
}
impl DisplayId {
#[cfg(target_os = "windows")]
pub fn windows_id(&self) -> &PlatformDisplayId {
&self.0
}
#[cfg(target_os = "macos")]
pub fn macos_id(&self) -> &PlatformDisplayId {
&self.0
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Display {
pub id: DisplayId,
pub origin: LogicalPosition<i32>,
pub size: LogicalSize<u32>,
pub scale_factor: f64,
pub is_primary: bool,
pub is_mirrored: bool,
}
#[derive(Debug, Clone)]
pub enum Event {
Added(Display),
Removed(DisplayId),
SizeChanged {
display: Display,
before: LogicalSize<u32>,
after: LogicalSize<u32>,
},
OriginChanged {
display: Display,
before: LogicalPosition<i32>,
after: LogicalPosition<i32>,
},
Mirrored(Display),
UnMirrored(Display),
}
pub type DisplayEventCallback = Box<dyn FnMut(Event) + Send + 'static>;
pub struct DisplayObserver {
inner: PlatformDisplayObserver,
}
impl From<PlatformDisplayObserver> for DisplayObserver {
fn from(inner: PlatformDisplayObserver) -> Self {
Self { inner }
}
}
impl From<DisplayObserver> for PlatformDisplayObserver {
fn from(value: DisplayObserver) -> Self {
value.inner
}
}
impl DisplayObserver {
pub fn new() -> Result<Self, Error> {
Ok(Self {
inner: PlatformDisplayObserver::new()?,
})
}
pub fn set_callback<F>(&self, callback: F)
where
F: FnMut(Event) + Send + 'static,
{
self.inner.set_callback(Box::new(callback));
}
pub fn remove_callback(&self) {
self.inner.remove_callback();
}
pub fn run(&self) -> Result<(), Error> {
#[cfg(target_os = "windows")]
{
self.inner.run()?;
Ok(())
}
#[cfg(target_os = "macos")]
{
self.inner.run();
Ok(())
}
}
}