2023-06-04 14:29:59 +02:00
|
|
|
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
|
2019-06-25 03:15:34 +02:00
|
|
|
use crate::error::{ExternalError, NotSupportedError, OsError as RootOE};
|
|
|
|
|
use crate::icon::Icon;
|
2020-11-27 03:03:08 +01:00
|
|
|
use crate::window::{
|
2023-01-29 16:46:46 +01:00
|
|
|
CursorGrabMode, CursorIcon, ImePurpose, ResizeDirection, Theme, UserAttentionType,
|
|
|
|
|
WindowAttributes, WindowButtons, WindowId as RootWI, WindowLevel,
|
2020-11-27 03:03:08 +01:00
|
|
|
};
|
2019-09-24 19:39:13 -04:00
|
|
|
|
2022-07-21 22:22:36 +03:00
|
|
|
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, WebDisplayHandle, WebWindowHandle};
|
2023-06-05 02:44:54 +02:00
|
|
|
use web_sys::HtmlCanvasElement;
|
2019-06-25 03:15:34 +02:00
|
|
|
|
2023-06-05 02:44:54 +02:00
|
|
|
use super::r#async::Dispatcher;
|
2022-09-21 10:04:28 +02:00
|
|
|
use super::{backend, monitor::MonitorHandle, EventLoopWindowTarget, Fullscreen};
|
2019-06-25 03:15:34 +02:00
|
|
|
|
2023-06-05 02:44:54 +02:00
|
|
|
use std::cell::RefCell;
|
2019-06-25 03:15:34 +02:00
|
|
|
use std::collections::vec_deque::IntoIter as VecDequeIter;
|
|
|
|
|
use std::collections::VecDeque;
|
2020-09-21 06:42:07 +08:00
|
|
|
use std::rc::Rc;
|
2023-06-05 02:44:54 +02:00
|
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
|
|
|
use std::sync::Arc;
|
2019-06-25 03:15:34 +02:00
|
|
|
|
|
|
|
|
pub struct Window {
|
2023-06-05 02:44:54 +02:00
|
|
|
id: WindowId,
|
|
|
|
|
has_focus: Arc<AtomicBool>,
|
|
|
|
|
pub inner: Dispatcher<Inner>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct Inner {
|
|
|
|
|
pub window: web_sys::Window,
|
2020-09-21 06:42:07 +08:00
|
|
|
canvas: Rc<RefCell<backend::Canvas>>,
|
2019-06-25 03:15:34 +02:00
|
|
|
previous_pointer: RefCell<&'static str>,
|
2019-09-23 09:14:26 -04:00
|
|
|
register_redraw_request: Box<dyn Fn()>,
|
2020-09-21 06:42:07 +08:00
|
|
|
destroy_fn: Option<Box<dyn FnOnce()>>,
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Window {
|
2022-06-10 19:05:28 +02:00
|
|
|
pub(crate) fn new<T>(
|
2019-06-25 03:15:34 +02:00
|
|
|
target: &EventLoopWindowTarget<T>,
|
|
|
|
|
attr: WindowAttributes,
|
2022-03-18 14:09:39 +01:00
|
|
|
platform_attr: PlatformSpecificWindowBuilderAttributes,
|
2019-06-25 03:15:34 +02:00
|
|
|
) -> Result<Self, RootOE> {
|
2019-06-25 18:39:41 +02:00
|
|
|
let runner = target.runner.clone();
|
2019-06-25 03:15:34 +02:00
|
|
|
|
2019-09-19 18:40:18 -04:00
|
|
|
let id = target.generate_id();
|
|
|
|
|
|
2022-07-14 13:22:31 -02:30
|
|
|
let prevent_default = platform_attr.prevent_default;
|
|
|
|
|
|
2023-06-05 02:44:54 +02:00
|
|
|
let window = target.runner.window();
|
2023-06-14 09:43:53 +02:00
|
|
|
let canvas = backend::Canvas::create(id, window.clone(), &attr, platform_attr)?;
|
2022-06-10 13:43:33 +03:00
|
|
|
let canvas = Rc::new(RefCell::new(canvas));
|
2019-09-23 09:14:26 -04:00
|
|
|
|
|
|
|
|
let register_redraw_request = Box::new(move || runner.request_redraw(RootWI(id)));
|
2019-06-25 03:15:34 +02:00
|
|
|
|
2023-06-14 10:26:26 +02:00
|
|
|
target.register(&canvas, id, prevent_default);
|
2019-06-25 03:15:34 +02:00
|
|
|
|
2020-09-21 06:42:07 +08:00
|
|
|
let runner = target.runner.clone();
|
|
|
|
|
let destroy_fn = Box::new(move || runner.notify_destroy_window(RootWI(id)));
|
|
|
|
|
|
2023-06-14 10:26:26 +02:00
|
|
|
let has_focus = canvas.borrow().has_focus.clone();
|
2023-06-05 02:44:54 +02:00
|
|
|
let window = Window {
|
|
|
|
|
id,
|
|
|
|
|
has_focus,
|
|
|
|
|
inner: Dispatcher::new(Inner {
|
|
|
|
|
window: window.clone(),
|
|
|
|
|
canvas,
|
|
|
|
|
previous_pointer: RefCell::new("auto"),
|
|
|
|
|
register_redraw_request,
|
|
|
|
|
destroy_fn: Some(destroy_fn),
|
|
|
|
|
})
|
|
|
|
|
.unwrap(),
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-25 03:15:34 +02:00
|
|
|
window.set_title(&attr.title);
|
|
|
|
|
window.set_maximized(attr.maximized);
|
|
|
|
|
window.set_visible(attr.visible);
|
|
|
|
|
window.set_window_icon(attr.window_icon);
|
|
|
|
|
|
|
|
|
|
Ok(window)
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-05 02:44:54 +02:00
|
|
|
pub fn canvas(&self) -> Option<HtmlCanvasElement> {
|
|
|
|
|
self.inner.with(|inner| inner.canvas.borrow().raw().clone())
|
2019-06-25 18:07:47 +02:00
|
|
|
}
|
|
|
|
|
|
2019-06-25 03:15:34 +02:00
|
|
|
pub fn set_title(&self, title: &str) {
|
2023-06-05 02:44:54 +02:00
|
|
|
if self
|
|
|
|
|
.inner
|
|
|
|
|
.with(|inner| inner.canvas.borrow().set_attribute("alt", title))
|
|
|
|
|
.is_none()
|
|
|
|
|
{
|
|
|
|
|
let title = title.to_owned();
|
|
|
|
|
self.inner
|
|
|
|
|
.dispatch(move |inner| inner.canvas.borrow().set_attribute("alt", &title));
|
|
|
|
|
}
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
2023-01-15 23:39:36 +03:00
|
|
|
pub fn set_transparent(&self, _transparent: bool) {}
|
|
|
|
|
|
2019-06-25 03:15:34 +02:00
|
|
|
pub fn set_visible(&self, _visible: bool) {
|
|
|
|
|
// Intentionally a no-op
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-17 20:44:14 +02:00
|
|
|
#[inline]
|
|
|
|
|
pub fn is_visible(&self) -> Option<bool> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-25 03:15:34 +02:00
|
|
|
pub fn request_redraw(&self) {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner
|
|
|
|
|
.dispatch(|inner| (inner.register_redraw_request)());
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-31 14:39:33 -08:00
|
|
|
pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.queue(|inner| {
|
|
|
|
|
Ok(inner
|
|
|
|
|
.canvas
|
|
|
|
|
.borrow()
|
|
|
|
|
.position()
|
|
|
|
|
.to_physical(inner.scale_factor()))
|
|
|
|
|
})
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-31 14:39:33 -08:00
|
|
|
pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
|
|
|
|
|
// Note: the canvas element has no window decorations, so this is equal to `outer_position`.
|
|
|
|
|
self.outer_position()
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-31 14:39:33 -08:00
|
|
|
pub fn set_outer_position(&self, position: Position) {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.dispatch(move |inner| {
|
2023-07-10 23:55:43 +02:00
|
|
|
let mut position = position.to_logical::<f64>(inner.scale_factor());
|
2019-06-25 03:15:34 +02:00
|
|
|
|
2023-06-05 02:44:54 +02:00
|
|
|
let canvas = inner.canvas.borrow();
|
2023-07-10 23:55:43 +02:00
|
|
|
let document = inner.window.document().expect("Failed to obtain document");
|
|
|
|
|
|
|
|
|
|
if document.contains(Some(canvas.raw())) {
|
|
|
|
|
let style = inner
|
|
|
|
|
.window
|
|
|
|
|
.get_computed_style(canvas.raw())
|
|
|
|
|
.expect("Failed to obtain computed style")
|
|
|
|
|
// this can't fail: we aren't using a pseudo-element
|
|
|
|
|
.expect("Invalid pseudo-element");
|
|
|
|
|
|
|
|
|
|
if style.get_property_value("display").unwrap() != "none" {
|
|
|
|
|
position.x -= backend::style_size_property(&style, "margin-left")
|
|
|
|
|
+ backend::style_size_property(&style, "border-left-width")
|
|
|
|
|
+ backend::style_size_property(&style, "padding-left");
|
|
|
|
|
position.y -= backend::style_size_property(&style, "margin-top")
|
|
|
|
|
+ backend::style_size_property(&style, "border-top-width")
|
|
|
|
|
+ backend::style_size_property(&style, "padding-top");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-05 02:44:54 +02:00
|
|
|
canvas.set_attribute("position", "fixed");
|
|
|
|
|
canvas.set_attribute("left", &position.x.to_string());
|
|
|
|
|
canvas.set_attribute("top", &position.y.to_string());
|
|
|
|
|
});
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2019-12-31 14:39:33 -08:00
|
|
|
pub fn inner_size(&self) -> PhysicalSize<u32> {
|
2023-06-14 09:43:53 +02:00
|
|
|
self.inner.queue(|inner| inner.canvas.borrow().inner_size())
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2019-12-31 14:39:33 -08:00
|
|
|
pub fn outer_size(&self) -> PhysicalSize<u32> {
|
|
|
|
|
// Note: the canvas element has no window decorations, so this is equal to `inner_size`.
|
|
|
|
|
self.inner_size()
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2023-07-10 04:02:26 +00:00
|
|
|
pub fn request_inner_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.dispatch(move |inner| {
|
2023-06-14 09:43:53 +02:00
|
|
|
let size = size.to_logical(inner.scale_factor());
|
|
|
|
|
let canvas = inner.canvas.borrow();
|
|
|
|
|
backend::set_canvas_size(canvas.window(), canvas.raw(), size);
|
2023-06-05 02:44:54 +02:00
|
|
|
});
|
2023-07-10 04:02:26 +00:00
|
|
|
|
|
|
|
|
None
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2019-12-31 14:39:33 -08:00
|
|
|
pub fn set_min_inner_size(&self, _dimensions: Option<Size>) {
|
2019-06-25 03:15:34 +02:00
|
|
|
// Intentionally a no-op: users can't resize canvas elements
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2019-12-31 14:39:33 -08:00
|
|
|
pub fn set_max_inner_size(&self, _dimensions: Option<Size>) {
|
2019-06-25 03:15:34 +02:00
|
|
|
// Intentionally a no-op: users can't resize canvas elements
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-03 21:50:22 +03:00
|
|
|
#[inline]
|
|
|
|
|
pub fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn set_resize_increments(&self, _increments: Option<Size>) {
|
|
|
|
|
// Intentionally a no-op: users can't resize canvas elements
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-25 03:15:34 +02:00
|
|
|
#[inline]
|
|
|
|
|
pub fn set_resizable(&self, _resizable: bool) {
|
|
|
|
|
// Intentionally a no-op: users can't resize canvas elements
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-17 17:03:17 +02:00
|
|
|
pub fn is_resizable(&self) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-29 12:03:51 +02:00
|
|
|
#[inline]
|
|
|
|
|
pub fn set_enabled_buttons(&self, _buttons: WindowButtons) {}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn enabled_buttons(&self) -> WindowButtons {
|
|
|
|
|
WindowButtons::all()
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-25 03:15:34 +02:00
|
|
|
#[inline]
|
2020-01-03 14:52:27 -05:00
|
|
|
pub fn scale_factor(&self) -> f64 {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.queue(|inner| inner.scale_factor())
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.dispatch(move |inner| {
|
|
|
|
|
*inner.previous_pointer.borrow_mut() = cursor.name();
|
|
|
|
|
backend::set_canvas_style_property(
|
|
|
|
|
inner.canvas.borrow().raw(),
|
|
|
|
|
"cursor",
|
|
|
|
|
cursor.name(),
|
|
|
|
|
);
|
|
|
|
|
});
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2019-12-31 14:39:33 -08:00
|
|
|
pub fn set_cursor_position(&self, _position: Position) -> Result<(), ExternalError> {
|
2020-07-26 21:13:17 +00:00
|
|
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2022-06-13 09:43:14 +03:00
|
|
|
pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.queue(move |inner| {
|
|
|
|
|
let lock = match mode {
|
|
|
|
|
CursorGrabMode::None => false,
|
|
|
|
|
CursorGrabMode::Locked => true,
|
|
|
|
|
CursorGrabMode::Confined => {
|
|
|
|
|
return Err(ExternalError::NotSupported(NotSupportedError::new()))
|
|
|
|
|
}
|
|
|
|
|
};
|
2022-06-13 09:43:14 +03:00
|
|
|
|
2023-06-05 02:44:54 +02:00
|
|
|
inner
|
|
|
|
|
.canvas
|
|
|
|
|
.borrow()
|
|
|
|
|
.set_cursor_lock(lock)
|
|
|
|
|
.map_err(ExternalError::Os)
|
|
|
|
|
})
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn set_cursor_visible(&self, visible: bool) {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.dispatch(move |inner| {
|
|
|
|
|
if !visible {
|
|
|
|
|
inner.canvas.borrow().set_attribute("cursor", "none");
|
|
|
|
|
} else {
|
|
|
|
|
inner
|
|
|
|
|
.canvas
|
|
|
|
|
.borrow()
|
|
|
|
|
.set_attribute("cursor", &inner.previous_pointer.borrow());
|
|
|
|
|
}
|
|
|
|
|
});
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
2021-03-07 10:43:23 +01:00
|
|
|
#[inline]
|
|
|
|
|
pub fn drag_window(&self) -> Result<(), ExternalError> {
|
|
|
|
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-11 18:07:09 +01:00
|
|
|
#[inline]
|
|
|
|
|
pub fn drag_resize_window(&self, _direction: ResizeDirection) -> Result<(), ExternalError> {
|
|
|
|
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-12 19:10:46 +02:00
|
|
|
#[inline]
|
|
|
|
|
pub fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), ExternalError> {
|
|
|
|
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-22 01:04:11 -05:00
|
|
|
#[inline]
|
|
|
|
|
pub fn set_minimized(&self, _minimized: bool) {
|
|
|
|
|
// Intentionally a no-op, as canvases cannot be 'minimized'
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-19 23:39:04 +02:00
|
|
|
#[inline]
|
|
|
|
|
pub fn is_minimized(&self) -> Option<bool> {
|
|
|
|
|
// Canvas cannot be 'minimized'
|
|
|
|
|
Some(false)
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-25 03:15:34 +02:00
|
|
|
#[inline]
|
|
|
|
|
pub fn set_maximized(&self, _maximized: bool) {
|
2019-09-24 19:33:32 -04:00
|
|
|
// Intentionally a no-op, as canvases cannot be 'maximized'
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
2021-01-27 20:01:17 +02:00
|
|
|
#[inline]
|
|
|
|
|
pub fn is_maximized(&self) -> bool {
|
|
|
|
|
// Canvas cannot be 'maximized'
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-25 03:15:34 +02:00
|
|
|
#[inline]
|
2022-09-21 10:04:28 +02:00
|
|
|
pub(crate) fn fullscreen(&self) -> Option<Fullscreen> {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.queue(|inner| {
|
|
|
|
|
if inner.canvas.borrow().is_fullscreen() {
|
|
|
|
|
Some(Fullscreen::Borderless(Some(MonitorHandle)))
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
})
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2022-09-21 10:04:28 +02:00
|
|
|
pub(crate) fn set_fullscreen(&self, fullscreen: Option<Fullscreen>) {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.dispatch(move |inner| {
|
|
|
|
|
if fullscreen.is_some() {
|
|
|
|
|
inner.canvas.borrow().request_fullscreen();
|
|
|
|
|
} else if inner.canvas.borrow().is_fullscreen() {
|
|
|
|
|
backend::exit_fullscreen(&inner.window);
|
|
|
|
|
}
|
|
|
|
|
});
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn set_decorations(&self, _decorations: bool) {
|
|
|
|
|
// Intentionally a no-op, no canvas decorations
|
|
|
|
|
}
|
2022-02-17 15:31:13 +02:00
|
|
|
|
|
|
|
|
pub fn is_decorated(&self) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
2019-06-25 03:15:34 +02:00
|
|
|
|
|
|
|
|
#[inline]
|
2022-11-26 03:50:58 +02:00
|
|
|
pub fn set_window_level(&self, _level: WindowLevel) {
|
2019-06-25 03:15:34 +02:00
|
|
|
// Intentionally a no-op, no window ordering
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn set_window_icon(&self, _window_icon: Option<Icon>) {
|
|
|
|
|
// Currently an intentional no-op
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2023-06-22 19:12:14 +00:00
|
|
|
pub fn set_ime_cursor_area(&self, _position: Position, _size: Size) {
|
2019-09-24 19:33:32 -04:00
|
|
|
// Currently a no-op as it does not seem there is good support for this on web
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-07 05:29:25 +03:00
|
|
|
#[inline]
|
|
|
|
|
pub fn set_ime_allowed(&self, _allowed: bool) {
|
|
|
|
|
// Currently not implemented
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-29 16:46:46 +01:00
|
|
|
#[inline]
|
|
|
|
|
pub fn set_ime_purpose(&self, _purpose: ImePurpose) {
|
|
|
|
|
// Currently not implemented
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-19 18:39:53 +02:00
|
|
|
#[inline]
|
|
|
|
|
pub fn focus_window(&self) {
|
|
|
|
|
// Currently a no-op as it does not seem there is good support for this on web
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-27 03:03:08 +01:00
|
|
|
#[inline]
|
|
|
|
|
pub fn request_user_attention(&self, _request_type: Option<UserAttentionType>) {
|
|
|
|
|
// Currently an intentional no-op
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-07 20:09:24 +03:00
|
|
|
#[inline]
|
2022-09-21 10:04:28 +02:00
|
|
|
pub fn current_monitor(&self) -> Option<MonitorHandle> {
|
2023-06-05 02:44:54 +02:00
|
|
|
Some(MonitorHandle)
|
2020-09-07 20:09:24 +03:00
|
|
|
}
|
|
|
|
|
|
2019-06-25 03:15:34 +02:00
|
|
|
#[inline]
|
2022-03-18 14:09:39 +01:00
|
|
|
pub fn available_monitors(&self) -> VecDequeIter<MonitorHandle> {
|
2019-06-25 03:15:34 +02:00
|
|
|
VecDeque::new().into_iter()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2022-09-21 10:04:28 +02:00
|
|
|
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
|
|
|
|
Some(MonitorHandle)
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2022-03-18 14:09:39 +01:00
|
|
|
pub fn id(&self) -> WindowId {
|
2022-06-10 13:43:33 +03:00
|
|
|
self.id
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
2019-09-24 19:39:13 -04:00
|
|
|
|
|
|
|
|
#[inline]
|
2021-11-30 17:50:23 +01:00
|
|
|
pub fn raw_window_handle(&self) -> RawWindowHandle {
|
2022-07-21 22:22:36 +03:00
|
|
|
let mut window_handle = WebWindowHandle::empty();
|
|
|
|
|
window_handle.id = self.id.0;
|
|
|
|
|
RawWindowHandle::Web(window_handle)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn raw_display_handle(&self) -> RawDisplayHandle {
|
|
|
|
|
RawDisplayHandle::Web(WebDisplayHandle::empty())
|
2019-09-24 19:39:13 -04:00
|
|
|
}
|
2022-10-19 03:34:36 +09:00
|
|
|
|
2022-11-29 11:05:51 +02:00
|
|
|
#[inline]
|
|
|
|
|
pub fn set_theme(&self, _theme: Option<Theme>) {}
|
|
|
|
|
|
2022-10-19 03:34:36 +09:00
|
|
|
#[inline]
|
|
|
|
|
pub fn theme(&self) -> Option<Theme> {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.queue(|inner| {
|
|
|
|
|
backend::is_dark_mode(&inner.window).map(|is_dark_mode| {
|
|
|
|
|
if is_dark_mode {
|
2023-02-20 08:51:21 +01:00
|
|
|
Theme::Dark
|
|
|
|
|
} else {
|
|
|
|
|
Theme::Light
|
|
|
|
|
}
|
|
|
|
|
})
|
2023-06-05 02:44:54 +02:00
|
|
|
})
|
2022-10-19 03:34:36 +09:00
|
|
|
}
|
2022-11-03 10:11:37 -07:00
|
|
|
|
|
|
|
|
#[inline]
|
2023-01-17 03:30:14 +02:00
|
|
|
pub fn has_focus(&self) -> bool {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.has_focus.load(Ordering::Relaxed)
|
2023-01-17 03:30:14 +02:00
|
|
|
}
|
|
|
|
|
|
2022-11-03 10:11:37 -07:00
|
|
|
pub fn title(&self) -> String {
|
|
|
|
|
String::new()
|
|
|
|
|
}
|
2023-05-28 20:02:59 +02:00
|
|
|
|
|
|
|
|
pub fn reset_dead_keys(&self) {
|
|
|
|
|
// Not supported
|
|
|
|
|
}
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
|
2020-09-21 06:42:07 +08:00
|
|
|
impl Drop for Window {
|
|
|
|
|
fn drop(&mut self) {
|
2023-06-05 02:44:54 +02:00
|
|
|
self.inner.dispatch_mut(|inner| {
|
|
|
|
|
if let Some(destroy_fn) = inner.destroy_fn.take() {
|
|
|
|
|
destroy_fn();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Inner {
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn scale_factor(&self) -> f64 {
|
|
|
|
|
super::backend::scale_factor(&self.window)
|
|
|
|
|
}
|
2020-09-21 06:42:07 +08:00
|
|
|
}
|
|
|
|
|
|
2019-06-25 03:15:34 +02:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
2022-03-18 14:09:39 +01:00
|
|
|
pub struct WindowId(pub(crate) u32);
|
2019-06-25 03:15:34 +02:00
|
|
|
|
2022-03-18 14:09:39 +01:00
|
|
|
impl WindowId {
|
|
|
|
|
pub const unsafe fn dummy() -> Self {
|
|
|
|
|
Self(0)
|
2019-06-25 03:15:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-02 14:27:19 +03:00
|
|
|
impl From<WindowId> for u64 {
|
|
|
|
|
fn from(window_id: WindowId) -> Self {
|
|
|
|
|
window_id.0 as u64
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<u64> for WindowId {
|
|
|
|
|
fn from(raw_id: u64) -> Self {
|
|
|
|
|
Self(raw_id as u32)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-14 13:22:31 -02:30
|
|
|
#[derive(Clone)]
|
2022-03-18 14:09:39 +01:00
|
|
|
pub struct PlatformSpecificWindowBuilderAttributes {
|
2020-01-15 21:20:14 -05:00
|
|
|
pub(crate) canvas: Option<backend::RawCanvasType>,
|
2022-07-14 13:22:31 -02:30
|
|
|
pub(crate) prevent_default: bool,
|
|
|
|
|
pub(crate) focusable: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for PlatformSpecificWindowBuilderAttributes {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
canvas: None,
|
|
|
|
|
prevent_default: true,
|
|
|
|
|
focusable: true,
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-01-15 21:20:14 -05:00
|
|
|
}
|