use crate::application::CALL_MAIN;
use crate::coordinates::{Position, Size};
use crate::surface::Surface;
use crate::sys;
use std::fmt::Display;
use std::sync::Arc;
#[derive(Debug)]
#[must_use = "Dropping a window will close it!"]
pub struct Window {
owner: Arc<WindowOwner>,
created_surface: bool,
}
#[derive(Debug)]
pub(crate) struct WindowOwner {
pub(crate) sys: crate::sys::Window,
#[cfg(feature = "exfiltrate")]
pub(crate) registry_id: Option<u64>,
}
#[cfg(feature = "exfiltrate")]
impl Drop for WindowOwner {
fn drop(&mut self) {
if let Some(id) = self.registry_id {
crate::registry::closed(id);
}
}
}
#[derive(thiserror::Error, Debug)]
pub struct FullscreenError(#[from] sys::FullscreenError);
impl Display for FullscreenError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl Window {
pub async fn fullscreen(title: String) -> Result<Self, FullscreenError> {
assert!(
crate::application::is_main_thread_running(),
"{}",
CALL_MAIN
);
#[cfg(feature = "exfiltrate")]
let registry_id =
crate::registry::opened(crate::registry::Origin::Fullscreen, title.clone(), None);
let sys = crate::sys::Window::fullscreen(title).await?;
Ok(Window {
owner: Arc::new(WindowOwner {
sys,
#[cfg(feature = "exfiltrate")]
registry_id,
}),
created_surface: false,
})
}
pub async fn new(position: Position, size: Size, title: String) -> Self {
assert!(
crate::application::is_main_thread_running(),
"Call app_window::application::main"
);
#[cfg(feature = "exfiltrate")]
let registry_id = crate::registry::opened(
crate::registry::Origin::Requested,
title.clone(),
Some((position, size)),
);
let sys = crate::sys::Window::new(position, size, title).await;
Window {
owner: Arc::new(WindowOwner {
sys,
#[cfg(feature = "exfiltrate")]
registry_id,
}),
created_surface: false,
}
}
pub async fn surface(&mut self) -> Surface {
assert!(!self.created_surface, "Surface already created");
self.created_surface = true;
#[cfg(feature = "exfiltrate")]
if let Some(id) = self.owner.registry_id {
crate::registry::surface_attached(id);
}
let sys_surface = self.owner.sys.surface().await;
Surface::new(sys_surface, self.owner.clone())
}
pub async fn default() -> Self {
assert!(
crate::application::is_main_thread_running(),
"{}",
CALL_MAIN
);
#[cfg(feature = "exfiltrate")]
let registry_id = crate::registry::opened(
crate::registry::Origin::PlatformDefault,
String::new(),
None,
);
let sys = crate::sys::Window::default().await;
Window {
owner: Arc::new(WindowOwner {
sys,
#[cfg(feature = "exfiltrate")]
registry_id,
}),
created_surface: false,
}
}
}
#[cfg(test)]
mod test {
use crate::window::Window;
#[cfg_attr(target_arch = "wasm32", wasm_lite::wasm_lite_test)]
#[test]
fn test_send() {
fn assert_send<T: Send>() {}
assert_send::<Window>();
fn assert_sync<T: Sync>() {}
assert_sync::<Window>();
}
}