mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-02-02 14:56:34 +11:00
On Web, cache commonly used values (#2947)
This commit is contained in:
parent
c4d70d75c1
commit
af26f01b95
7 changed files with 131 additions and 126 deletions
|
@ -4,4 +4,6 @@ disallowed-methods = [
|
|||
{ path = "web_sys::HtmlCanvasElement::height", reason = "Winit shouldn't touch the internal canvas size" },
|
||||
{ path = "web_sys::HtmlCanvasElement::set_width", reason = "Winit shouldn't touch the internal canvas size" },
|
||||
{ path = "web_sys::HtmlCanvasElement::set_height", reason = "Winit shouldn't touch the internal canvas size" },
|
||||
{ path = "web_sys::Window::document", reason = "cache this to reduce calls to JS" },
|
||||
{ path = "web_sys::Window::get_computed_style", reason = "cache this to reduce calls to JS" },
|
||||
]
|
||||
|
|
|
@ -19,7 +19,7 @@ use std::{
|
|||
rc::{Rc, Weak},
|
||||
};
|
||||
use wasm_bindgen::prelude::Closure;
|
||||
use web_sys::{KeyboardEvent, PageTransitionEvent, PointerEvent, WheelEvent};
|
||||
use web_sys::{Document, KeyboardEvent, PageTransitionEvent, PointerEvent, WheelEvent};
|
||||
use web_time::{Duration, Instant};
|
||||
|
||||
pub struct Shared<T: 'static>(Rc<Execution<T>>);
|
||||
|
@ -41,6 +41,7 @@ pub struct Execution<T: 'static> {
|
|||
events: RefCell<VecDeque<EventWrapper<T>>>,
|
||||
id: RefCell<u32>,
|
||||
window: web_sys::Window,
|
||||
document: Document,
|
||||
all_canvases: RefCell<Vec<(WindowId, Weak<RefCell<backend::Canvas>>)>>,
|
||||
redraw_pending: RefCell<HashSet<WindowId>>,
|
||||
destroy_pending: RefCell<VecDeque<WindowId>>,
|
||||
|
@ -141,13 +142,18 @@ impl<T: 'static> Runner<T> {
|
|||
|
||||
impl<T: 'static> Shared<T> {
|
||||
pub fn new() -> Self {
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
let window = web_sys::window().expect("only callable from inside the `Window`");
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
let document = window.document().expect("Failed to obtain document");
|
||||
|
||||
Shared(Rc::new(Execution {
|
||||
runner: RefCell::new(RunnerEnum::Pending),
|
||||
suspended: Cell::new(false),
|
||||
event_loop_recreation: Cell::new(false),
|
||||
events: RefCell::new(VecDeque::new()),
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
window: web_sys::window().expect("only callable from inside the `Window`"),
|
||||
window,
|
||||
document,
|
||||
id: RefCell::new(0),
|
||||
all_canvases: RefCell::new(Vec::new()),
|
||||
redraw_pending: RefCell::new(HashSet::new()),
|
||||
|
@ -168,6 +174,10 @@ impl<T: 'static> Shared<T> {
|
|||
&self.0.window
|
||||
}
|
||||
|
||||
pub fn document(&self) -> &Document {
|
||||
&self.0.document
|
||||
}
|
||||
|
||||
pub fn add_canvas(&self, id: WindowId, canvas: &Rc<RefCell<backend::Canvas>>) {
|
||||
self.0
|
||||
.all_canvases
|
||||
|
@ -394,13 +404,13 @@ impl<T: 'static> Shared<T> {
|
|||
let runner = self.clone();
|
||||
*self.0.on_visibility_change.borrow_mut() = Some(EventListenerHandle::new(
|
||||
// Safari <14 doesn't support the `visibilitychange` event on `Window`.
|
||||
&self.window().document().expect("Failed to obtain document"),
|
||||
self.document(),
|
||||
"visibilitychange",
|
||||
Closure::new(move |_| {
|
||||
if !runner.0.suspended.get() {
|
||||
for (id, canvas) in &*runner.0.all_canvases.borrow() {
|
||||
if let Some(canvas) = canvas.upgrade() {
|
||||
let is_visible = backend::is_visible(runner.window());
|
||||
let is_visible = backend::is_visible(runner.document());
|
||||
// only fire if:
|
||||
// - not visible and intersects
|
||||
// - not visible and we don't know if it intersects yet
|
||||
|
|
|
@ -725,7 +725,7 @@ impl<T> EventLoopWindowTarget<T> {
|
|||
let runner = self.runner.clone();
|
||||
canvas.on_intersection(move |is_intersecting| {
|
||||
// only fire if visible while skipping the first event if it's intersecting
|
||||
if backend::is_visible(runner.window())
|
||||
if backend::is_visible(runner.document())
|
||||
&& !(is_intersecting && canvas_clone.borrow().is_intersecting.is_none())
|
||||
{
|
||||
runner.send_event(Event::WindowEvent {
|
||||
|
|
|
@ -21,7 +21,9 @@ use smol_str::SmolStr;
|
|||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
use wasm_bindgen::{closure::Closure, JsCast, JsValue};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, WheelEvent};
|
||||
use web_sys::{
|
||||
CssStyleDeclaration, Document, Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, WheelEvent,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct Canvas {
|
||||
|
@ -44,8 +46,10 @@ pub struct Canvas {
|
|||
|
||||
pub struct Common {
|
||||
pub window: web_sys::Window,
|
||||
pub document: Document,
|
||||
/// Note: resizing the HTMLCanvasElement should go through `backend::set_canvas_size` to ensure the DPI factor is maintained.
|
||||
pub raw: HtmlCanvasElement,
|
||||
style: CssStyleDeclaration,
|
||||
old_size: Rc<Cell<PhysicalSize<u32>>>,
|
||||
current_size: Rc<Cell<PhysicalSize<u32>>>,
|
||||
wants_fullscreen: Rc<RefCell<bool>>,
|
||||
|
@ -55,21 +59,16 @@ impl Canvas {
|
|||
pub fn create(
|
||||
id: WindowId,
|
||||
window: web_sys::Window,
|
||||
document: Document,
|
||||
attr: &WindowAttributes,
|
||||
platform_attr: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<Self, RootOE> {
|
||||
let canvas = match platform_attr.canvas {
|
||||
Some(canvas) => canvas,
|
||||
None => {
|
||||
let document = window
|
||||
.document()
|
||||
.ok_or_else(|| os_error!(OsError("Failed to obtain document".to_owned())))?;
|
||||
|
||||
document
|
||||
.create_element("canvas")
|
||||
.map_err(|_| os_error!(OsError("Failed to create canvas element".to_owned())))?
|
||||
.unchecked_into()
|
||||
}
|
||||
None => document
|
||||
.create_element("canvas")
|
||||
.map_err(|_| os_error!(OsError("Failed to create canvas element".to_owned())))?
|
||||
.unchecked_into(),
|
||||
};
|
||||
|
||||
// A tabindex is needed in order to capture local keyboard events.
|
||||
|
@ -83,15 +82,24 @@ impl Canvas {
|
|||
.map_err(|_| os_error!(OsError("Failed to set a tabindex".to_owned())))?;
|
||||
}
|
||||
|
||||
#[allow(clippy::disallowed_methods)]
|
||||
let style = window
|
||||
.get_computed_style(&canvas)
|
||||
.expect("Failed to obtain computed style")
|
||||
// this can't fail: we aren't using a pseudo-element
|
||||
.expect("Invalid pseudo-element");
|
||||
|
||||
if let Some(size) = attr.inner_size {
|
||||
let size = size.to_logical(super::scale_factor(&window));
|
||||
super::set_canvas_size(&window, &canvas, size);
|
||||
super::set_canvas_size(&document, &canvas, &style, size);
|
||||
}
|
||||
|
||||
Ok(Canvas {
|
||||
common: Common {
|
||||
window,
|
||||
document,
|
||||
raw: canvas,
|
||||
style,
|
||||
old_size: Rc::default(),
|
||||
current_size: Rc::default(),
|
||||
wants_fullscreen: Rc::new(RefCell::new(false)),
|
||||
|
@ -117,12 +125,7 @@ impl Canvas {
|
|||
if lock {
|
||||
self.raw().request_pointer_lock();
|
||||
} else {
|
||||
let document = self
|
||||
.common
|
||||
.window
|
||||
.document()
|
||||
.ok_or_else(|| os_error!(OsError("Failed to obtain document".to_owned())))?;
|
||||
document.exit_pointer_lock();
|
||||
self.common.document.exit_pointer_lock();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -141,50 +144,58 @@ impl Canvas {
|
|||
y: bounds.y(),
|
||||
};
|
||||
|
||||
let document = self.window().document().expect("Failed to obtain document");
|
||||
|
||||
if document.contains(Some(self.raw())) {
|
||||
let style = self
|
||||
.window()
|
||||
.get_computed_style(self.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 += super::style_size_property(&style, "border-left-width")
|
||||
+ super::style_size_property(&style, "padding-left");
|
||||
position.y += super::style_size_property(&style, "border-top-width")
|
||||
+ super::style_size_property(&style, "padding-top");
|
||||
}
|
||||
if self.document().contains(Some(self.raw()))
|
||||
&& self.style().get_property_value("display").unwrap() != "none"
|
||||
{
|
||||
position.x += super::style_size_property(self.style(), "border-left-width")
|
||||
+ super::style_size_property(self.style(), "padding-left");
|
||||
position.y += super::style_size_property(self.style(), "border-top-width")
|
||||
+ super::style_size_property(self.style(), "padding-top");
|
||||
}
|
||||
|
||||
position
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn old_size(&self) -> PhysicalSize<u32> {
|
||||
self.common.old_size.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
self.common.current_size.get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_old_size(&self, size: PhysicalSize<u32>) {
|
||||
self.common.old_size.set(size)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_current_size(&self, size: PhysicalSize<u32>) {
|
||||
self.common.current_size.set(size)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn window(&self) -> &web_sys::Window {
|
||||
&self.common.window
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn document(&self) -> &Document {
|
||||
&self.common.document
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn raw(&self) -> &HtmlCanvasElement {
|
||||
&self.common.raw
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn style(&self) -> &CssStyleDeclaration {
|
||||
&self.common.style
|
||||
}
|
||||
|
||||
pub fn on_touch_start(&mut self, prevent_default: bool) {
|
||||
self.on_touch_start = Some(self.common.add_event("touchstart", move |event: Event| {
|
||||
if prevent_default {
|
||||
|
@ -382,7 +393,9 @@ impl Canvas {
|
|||
{
|
||||
self.on_resize_scale = Some(ResizeScaleHandle::new(
|
||||
self.window().clone(),
|
||||
self.document().clone(),
|
||||
self.raw().clone(),
|
||||
self.style().clone(),
|
||||
scale_handler,
|
||||
size_handler,
|
||||
));
|
||||
|
@ -425,7 +438,7 @@ impl Canvas {
|
|||
// Then we resize the canvas to the new size, a new
|
||||
// `Resized` event will be sent by the `ResizeObserver`:
|
||||
let new_size = new_size.to_logical(scale);
|
||||
super::set_canvas_size(self.window(), self.raw(), new_size);
|
||||
super::set_canvas_size(self.document(), self.raw(), self.style(), new_size);
|
||||
|
||||
// Set the size might not trigger the event because the calculation is inaccurate.
|
||||
self.on_resize_scale
|
||||
|
@ -527,6 +540,6 @@ impl Common {
|
|||
}
|
||||
|
||||
pub fn is_fullscreen(&self) -> bool {
|
||||
super::is_fullscreen(&self.window, &self.raw)
|
||||
super::is_fullscreen(&self.document, &self.raw)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,14 @@ use crate::platform::web::WindowExtWebSys;
|
|||
use crate::window::Window;
|
||||
use wasm_bindgen::closure::Closure;
|
||||
use web_sys::{
|
||||
CssStyleDeclaration, Element, HtmlCanvasElement, PageTransitionEvent, VisibilityState,
|
||||
CssStyleDeclaration, Document, Element, HtmlCanvasElement, PageTransitionEvent, VisibilityState,
|
||||
};
|
||||
|
||||
pub fn throw(msg: &str) {
|
||||
wasm_bindgen::throw_str(msg);
|
||||
}
|
||||
|
||||
pub fn exit_fullscreen(window: &web_sys::Window) {
|
||||
let document = window.document().expect("Failed to obtain document");
|
||||
|
||||
pub fn exit_fullscreen(document: &Document) {
|
||||
document.exit_fullscreen();
|
||||
}
|
||||
|
||||
|
@ -69,35 +67,28 @@ pub fn scale_factor(window: &web_sys::Window) -> f64 {
|
|||
}
|
||||
|
||||
pub fn set_canvas_size(
|
||||
window: &web_sys::Window,
|
||||
document: &Document,
|
||||
raw: &HtmlCanvasElement,
|
||||
style: &CssStyleDeclaration,
|
||||
mut new_size: LogicalSize<f64>,
|
||||
) {
|
||||
let document = window.document().expect("Failed to obtain document");
|
||||
|
||||
if !document.contains(Some(raw)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let style = window
|
||||
.get_computed_style(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" {
|
||||
return;
|
||||
}
|
||||
|
||||
if style.get_property_value("box-sizing").unwrap() == "border-box" {
|
||||
new_size.width += style_size_property(&style, "border-left-width")
|
||||
+ style_size_property(&style, "border-right-width")
|
||||
+ style_size_property(&style, "padding-left")
|
||||
+ style_size_property(&style, "padding-right");
|
||||
new_size.height += style_size_property(&style, "border-top-width")
|
||||
+ style_size_property(&style, "border-bottom-width")
|
||||
+ style_size_property(&style, "padding-top")
|
||||
+ style_size_property(&style, "padding-bottom");
|
||||
new_size.width += style_size_property(style, "border-left-width")
|
||||
+ style_size_property(style, "border-right-width")
|
||||
+ style_size_property(style, "padding-left")
|
||||
+ style_size_property(style, "padding-right");
|
||||
new_size.height += style_size_property(style, "border-top-width")
|
||||
+ style_size_property(style, "border-bottom-width")
|
||||
+ style_size_property(style, "padding-top")
|
||||
+ style_size_property(style, "padding-bottom");
|
||||
}
|
||||
|
||||
set_canvas_style_property(raw, "width", &format!("{}px", new_size.width));
|
||||
|
@ -123,9 +114,7 @@ pub fn set_canvas_style_property(raw: &HtmlCanvasElement, property: &str, value:
|
|||
.unwrap_or_else(|err| panic!("error: {err:?}\nFailed to set {property}"))
|
||||
}
|
||||
|
||||
pub fn is_fullscreen(window: &web_sys::Window, canvas: &HtmlCanvasElement) -> bool {
|
||||
let document = window.document().expect("Failed to obtain document");
|
||||
|
||||
pub fn is_fullscreen(document: &Document, canvas: &HtmlCanvasElement) -> bool {
|
||||
match document.fullscreen_element() {
|
||||
Some(elem) => {
|
||||
let canvas: &Element = canvas;
|
||||
|
@ -143,8 +132,7 @@ pub fn is_dark_mode(window: &web_sys::Window) -> Option<bool> {
|
|||
.map(|media| media.matches())
|
||||
}
|
||||
|
||||
pub fn is_visible(window: &web_sys::Window) -> bool {
|
||||
let document = window.document().expect("Failed to obtain document");
|
||||
pub fn is_visible(document: &Document) -> bool {
|
||||
document.visibility_state() == VisibilityState::Visible
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@ use once_cell::unsync::Lazy;
|
|||
use wasm_bindgen::prelude::{wasm_bindgen, Closure};
|
||||
use wasm_bindgen::{JsCast, JsValue};
|
||||
use web_sys::{
|
||||
HtmlCanvasElement, MediaQueryList, ResizeObserver, ResizeObserverBoxOptions,
|
||||
ResizeObserverEntry, ResizeObserverOptions, ResizeObserverSize, Window,
|
||||
CssStyleDeclaration, Document, HtmlCanvasElement, MediaQueryList, ResizeObserver,
|
||||
ResizeObserverBoxOptions, ResizeObserverEntry, ResizeObserverOptions, ResizeObserverSize,
|
||||
Window,
|
||||
};
|
||||
|
||||
use crate::dpi::{LogicalSize, PhysicalSize};
|
||||
|
@ -20,7 +21,9 @@ pub struct ResizeScaleHandle(Rc<RefCell<ResizeScaleInternal>>);
|
|||
impl ResizeScaleHandle {
|
||||
pub(crate) fn new<S, R>(
|
||||
window: Window,
|
||||
document: Document,
|
||||
canvas: HtmlCanvasElement,
|
||||
style: CssStyleDeclaration,
|
||||
scale_handler: S,
|
||||
resize_handler: R,
|
||||
) -> Self
|
||||
|
@ -30,7 +33,9 @@ impl ResizeScaleHandle {
|
|||
{
|
||||
Self(ResizeScaleInternal::new(
|
||||
window,
|
||||
document,
|
||||
canvas,
|
||||
style,
|
||||
scale_handler,
|
||||
resize_handler,
|
||||
))
|
||||
|
@ -45,7 +50,9 @@ impl ResizeScaleHandle {
|
|||
/// changes of the `devicePixelRatio`.
|
||||
struct ResizeScaleInternal {
|
||||
window: Window,
|
||||
document: Document,
|
||||
canvas: HtmlCanvasElement,
|
||||
style: CssStyleDeclaration,
|
||||
mql: MediaQueryListHandle,
|
||||
observer: ResizeObserver,
|
||||
_observer_closure: Closure<dyn FnMut(Array, ResizeObserver)>,
|
||||
|
@ -57,7 +64,9 @@ struct ResizeScaleInternal {
|
|||
impl ResizeScaleInternal {
|
||||
fn new<S, R>(
|
||||
window: Window,
|
||||
document: Document,
|
||||
canvas: HtmlCanvasElement,
|
||||
style: CssStyleDeclaration,
|
||||
scale_handler: S,
|
||||
resize_handler: R,
|
||||
) -> Rc<RefCell<Self>>
|
||||
|
@ -80,7 +89,7 @@ impl ResizeScaleInternal {
|
|||
if let Some(rc_self) = weak_self.upgrade() {
|
||||
let mut this = rc_self.borrow_mut();
|
||||
|
||||
let size = Self::process_entry(&this.window, &this.canvas, entries);
|
||||
let size = this.process_entry(entries);
|
||||
|
||||
if this.notify_scale.replace(false) {
|
||||
let scale = backend::scale_factor(&this.window);
|
||||
|
@ -94,7 +103,9 @@ impl ResizeScaleInternal {
|
|||
|
||||
RefCell::new(Self {
|
||||
window,
|
||||
document,
|
||||
canvas,
|
||||
style,
|
||||
mql,
|
||||
observer,
|
||||
_observer_closure: observer_closure,
|
||||
|
@ -142,17 +153,8 @@ impl ResizeScaleInternal {
|
|||
}
|
||||
|
||||
fn notify(&mut self) {
|
||||
let style = self
|
||||
.window
|
||||
.get_computed_style(&self.canvas)
|
||||
.expect("Failed to obtain computed style")
|
||||
// this can't fail: we aren't using a pseudo-element
|
||||
.expect("Invalid pseudo-element");
|
||||
|
||||
let document = self.window.document().expect("Failed to obtain document");
|
||||
|
||||
if !document.contains(Some(&self.canvas))
|
||||
|| style.get_property_value("display").unwrap() == "none"
|
||||
if !self.document.contains(Some(&self.canvas))
|
||||
|| self.style.get_property_value("display").unwrap() == "none"
|
||||
{
|
||||
let size = PhysicalSize::new(0, 0);
|
||||
|
||||
|
@ -175,19 +177,19 @@ impl ResizeScaleInternal {
|
|||
}
|
||||
|
||||
let mut size = LogicalSize::new(
|
||||
backend::style_size_property(&style, "width"),
|
||||
backend::style_size_property(&style, "height"),
|
||||
backend::style_size_property(&self.style, "width"),
|
||||
backend::style_size_property(&self.style, "height"),
|
||||
);
|
||||
|
||||
if style.get_property_value("box-sizing").unwrap() == "border-box" {
|
||||
size.width -= backend::style_size_property(&style, "border-left-width")
|
||||
+ backend::style_size_property(&style, "border-right-width")
|
||||
+ backend::style_size_property(&style, "padding-left")
|
||||
+ backend::style_size_property(&style, "padding-right");
|
||||
size.height -= backend::style_size_property(&style, "border-top-width")
|
||||
+ backend::style_size_property(&style, "border-bottom-width")
|
||||
+ backend::style_size_property(&style, "padding-top")
|
||||
+ backend::style_size_property(&style, "padding-bottom");
|
||||
if self.style.get_property_value("box-sizing").unwrap() == "border-box" {
|
||||
size.width -= backend::style_size_property(&self.style, "border-left-width")
|
||||
+ backend::style_size_property(&self.style, "border-right-width")
|
||||
+ backend::style_size_property(&self.style, "padding-left")
|
||||
+ backend::style_size_property(&self.style, "padding-right");
|
||||
size.height -= backend::style_size_property(&self.style, "border-top-width")
|
||||
+ backend::style_size_property(&self.style, "border-bottom-width")
|
||||
+ backend::style_size_property(&self.style, "padding-top")
|
||||
+ backend::style_size_property(&self.style, "padding-bottom");
|
||||
}
|
||||
|
||||
let size = size.to_physical(backend::scale_factor(&self.window));
|
||||
|
@ -229,11 +231,7 @@ impl ResizeScaleInternal {
|
|||
this.notify();
|
||||
}
|
||||
|
||||
fn process_entry(
|
||||
window: &Window,
|
||||
canvas: &HtmlCanvasElement,
|
||||
entries: Array,
|
||||
) -> PhysicalSize<u32> {
|
||||
fn process_entry(&self, entries: Array) -> PhysicalSize<u32> {
|
||||
let entry: ResizeObserverEntry = entries.get(0).unchecked_into();
|
||||
|
||||
// Safari doesn't support `devicePixelContentBoxSize`
|
||||
|
@ -241,7 +239,7 @@ impl ResizeScaleInternal {
|
|||
let rect = entry.content_rect();
|
||||
|
||||
return LogicalSize::new(rect.width(), rect.height())
|
||||
.to_physical(backend::scale_factor(window));
|
||||
.to_physical(backend::scale_factor(&self.window));
|
||||
}
|
||||
|
||||
let entry: ResizeObserverSize = entry
|
||||
|
@ -249,13 +247,8 @@ impl ResizeScaleInternal {
|
|||
.get(0)
|
||||
.unchecked_into();
|
||||
|
||||
let style = window
|
||||
.get_computed_style(canvas)
|
||||
.expect("Failed to get computed style of canvas")
|
||||
// this can only be empty if we provided an invalid `pseudoElt`
|
||||
.expect("`getComputedStyle` can not be empty");
|
||||
|
||||
let writing_mode = style
|
||||
let writing_mode = self
|
||||
.style
|
||||
.get_property_value("writing-mode")
|
||||
.expect("`writing-mode` is a valid CSS property");
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::window::{
|
|||
};
|
||||
|
||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, WebDisplayHandle, WebWindowHandle};
|
||||
use web_sys::HtmlCanvasElement;
|
||||
use web_sys::{CssStyleDeclaration, Document, HtmlCanvasElement};
|
||||
|
||||
use super::r#async::Dispatcher;
|
||||
use super::{backend, monitor::MonitorHandle, EventLoopWindowTarget, Fullscreen};
|
||||
|
@ -27,6 +27,8 @@ pub struct Window {
|
|||
|
||||
pub struct Inner {
|
||||
pub window: web_sys::Window,
|
||||
document: Document,
|
||||
style: CssStyleDeclaration,
|
||||
canvas: Rc<RefCell<backend::Canvas>>,
|
||||
previous_pointer: RefCell<&'static str>,
|
||||
register_redraw_request: Box<dyn Fn()>,
|
||||
|
@ -46,7 +48,10 @@ impl Window {
|
|||
let prevent_default = platform_attr.prevent_default;
|
||||
|
||||
let window = target.runner.window();
|
||||
let canvas = backend::Canvas::create(id, window.clone(), &attr, platform_attr)?;
|
||||
let document = target.runner.document();
|
||||
let canvas =
|
||||
backend::Canvas::create(id, window.clone(), document.clone(), &attr, platform_attr)?;
|
||||
let style = canvas.style().clone();
|
||||
let canvas = Rc::new(RefCell::new(canvas));
|
||||
|
||||
let register_redraw_request = Box::new(move || runner.request_redraw(RootWI(id)));
|
||||
|
@ -62,6 +67,8 @@ impl Window {
|
|||
has_focus,
|
||||
inner: Dispatcher::new(Inner {
|
||||
window: window.clone(),
|
||||
document: document.clone(),
|
||||
style,
|
||||
canvas,
|
||||
previous_pointer: RefCell::new("auto"),
|
||||
register_redraw_request,
|
||||
|
@ -130,24 +137,16 @@ impl Window {
|
|||
let mut position = position.to_logical::<f64>(inner.scale_factor());
|
||||
|
||||
let canvas = inner.canvas.borrow();
|
||||
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");
|
||||
}
|
||||
if inner.document.contains(Some(canvas.raw()))
|
||||
&& inner.style.get_property_value("display").unwrap() != "none"
|
||||
{
|
||||
position.x -= backend::style_size_property(&inner.style, "margin-left")
|
||||
+ backend::style_size_property(&inner.style, "border-left-width")
|
||||
+ backend::style_size_property(&inner.style, "padding-left");
|
||||
position.y -= backend::style_size_property(&inner.style, "margin-top")
|
||||
+ backend::style_size_property(&inner.style, "border-top-width")
|
||||
+ backend::style_size_property(&inner.style, "padding-top");
|
||||
}
|
||||
|
||||
canvas.set_attribute("position", "fixed");
|
||||
|
@ -172,7 +171,7 @@ impl Window {
|
|||
self.inner.dispatch(move |inner| {
|
||||
let size = size.to_logical(inner.scale_factor());
|
||||
let canvas = inner.canvas.borrow();
|
||||
backend::set_canvas_size(canvas.window(), canvas.raw(), size);
|
||||
backend::set_canvas_size(canvas.document(), canvas.raw(), canvas.style(), size);
|
||||
});
|
||||
|
||||
None
|
||||
|
@ -324,7 +323,7 @@ impl Window {
|
|||
if fullscreen.is_some() {
|
||||
inner.canvas.borrow().request_fullscreen();
|
||||
} else if inner.canvas.borrow().is_fullscreen() {
|
||||
backend::exit_fullscreen(&inner.window);
|
||||
backend::exit_fullscreen(&inner.document);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue