mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 13:51:30 +11:00
Use correct canvas size for scale factor change
This commit is contained in:
parent
8f7f3efc0d
commit
c88a4ab221
|
@ -71,6 +71,8 @@ And please only add new entries to the top of this list, right below the `# Unre
|
|||
- On Web, `EventLoopProxy` now implements `Send`.
|
||||
- On Web, `Window` now implements `Send` and `Sync`.
|
||||
- **Breaking:** `WindowExtWebSys::canvas()` now returns an `Option`.
|
||||
- On Web, use the correct canvas size when calculating the new size during scale factor change,
|
||||
instead of using the output bitmap size.
|
||||
|
||||
# 0.28.6
|
||||
|
||||
|
|
|
@ -59,7 +59,10 @@ mod wasm {
|
|||
let body = document.body().unwrap();
|
||||
|
||||
// Set a background color for the canvas to make it easier to tell where the canvas is for debugging purposes.
|
||||
canvas.style().set_css_text("background-color: crimson;");
|
||||
canvas
|
||||
.style()
|
||||
.set_property("background-color", "crimson")
|
||||
.unwrap();
|
||||
body.append_child(&canvas).unwrap();
|
||||
|
||||
let log_header = document.create_element("h2").unwrap();
|
||||
|
|
|
@ -327,16 +327,14 @@ impl<T: 'static> Shared<T> {
|
|||
|
||||
// Now handle the `ScaleFactorChanged` events.
|
||||
for &(id, ref canvas) in &*self.0.all_canvases.borrow() {
|
||||
let canvas = match canvas.upgrade() {
|
||||
Some(rc) => rc.borrow().raw().clone(),
|
||||
let rc = match canvas.upgrade() {
|
||||
Some(rc) => rc,
|
||||
// This shouldn't happen, but just in case...
|
||||
None => continue,
|
||||
};
|
||||
let canvas = rc.borrow();
|
||||
// First, we send the `ScaleFactorChanged` event:
|
||||
let current_size = crate::dpi::PhysicalSize {
|
||||
width: canvas.width(),
|
||||
height: canvas.height(),
|
||||
};
|
||||
let current_size = canvas.size().get();
|
||||
let logical_size = current_size.to_logical::<f64>(old_scale);
|
||||
let mut new_size = logical_size.to_physical(new_scale);
|
||||
self.handle_single_event_sync(
|
||||
|
@ -351,7 +349,7 @@ impl<T: 'static> Shared<T> {
|
|||
);
|
||||
|
||||
// Then we resize the canvas to the new size and send a `Resized` event:
|
||||
backend::set_canvas_size(self.window(), &canvas, crate::dpi::Size::Physical(new_size));
|
||||
backend::set_canvas_size(&canvas, crate::dpi::Size::Physical(new_size));
|
||||
self.handle_single_event_sync(
|
||||
Event::WindowEvent {
|
||||
window_id: id,
|
||||
|
|
|
@ -16,7 +16,7 @@ use super::{
|
|||
runner,
|
||||
window::WindowId,
|
||||
};
|
||||
use crate::dpi::{PhysicalSize, Size};
|
||||
use crate::dpi::Size;
|
||||
use crate::event::{
|
||||
DeviceEvent, DeviceId as RootDeviceId, ElementState, Event, KeyEvent, Touch, TouchPhase,
|
||||
WindowEvent,
|
||||
|
@ -89,6 +89,7 @@ impl<T> EventLoopWindowTarget<T> {
|
|||
has_focus: Arc<AtomicBool>,
|
||||
) {
|
||||
self.runner.add_canvas(RootWindowId(id), canvas);
|
||||
let canvas_clone = canvas.clone();
|
||||
let mut canvas = canvas.borrow_mut();
|
||||
canvas.set_attribute("data-raw-handle", &id.0.to_string());
|
||||
|
||||
|
@ -502,32 +503,27 @@ impl<T> EventLoopWindowTarget<T> {
|
|||
prevent_default,
|
||||
);
|
||||
|
||||
let runner = self.runner.clone();
|
||||
let raw = canvas.raw().clone();
|
||||
|
||||
// The size to restore to after exiting fullscreen.
|
||||
let mut intended_size = PhysicalSize {
|
||||
width: raw.width(),
|
||||
height: raw.height(),
|
||||
};
|
||||
let mut intended_size = canvas.size().get();
|
||||
|
||||
canvas.on_fullscreen_change({
|
||||
let window = self.runner.window().clone();
|
||||
let runner = self.runner.clone();
|
||||
|
||||
move || {
|
||||
let canvas = canvas_clone.borrow();
|
||||
|
||||
// If the canvas is marked as fullscreen, it is moving *into* fullscreen
|
||||
// If it is not, it is moving *out of* fullscreen
|
||||
let new_size = if backend::is_fullscreen(&window, &raw) {
|
||||
intended_size = PhysicalSize {
|
||||
width: raw.width(),
|
||||
height: raw.height(),
|
||||
};
|
||||
let new_size = if backend::is_fullscreen(&window, canvas.raw()) {
|
||||
intended_size = canvas.size().get();
|
||||
|
||||
backend::window_size(&window).to_physical(backend::scale_factor(&window))
|
||||
} else {
|
||||
intended_size
|
||||
};
|
||||
|
||||
backend::set_canvas_size(&window, &raw, Size::Physical(new_size));
|
||||
backend::set_canvas_size(&canvas, Size::Physical(new_size));
|
||||
runner.send_event(Event::WindowEvent {
|
||||
window_id: RootWindowId(id),
|
||||
event: WindowEvent::Resized(new_size),
|
||||
|
|
|
@ -2,13 +2,14 @@ use super::event_handle::EventListenerHandle;
|
|||
use super::media_query_handle::MediaQueryListHandle;
|
||||
use super::pointer::PointerHandler;
|
||||
use super::{event, ButtonsState};
|
||||
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
||||
use crate::dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize};
|
||||
use crate::error::OsError as RootOE;
|
||||
use crate::event::{Force, MouseButton, MouseScrollDelta};
|
||||
use crate::keyboard::{Key, KeyCode, KeyLocation, ModifiersState};
|
||||
use crate::platform_impl::{OsError, PlatformSpecificWindowBuilderAttributes};
|
||||
use crate::window::WindowAttributes;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
|
||||
use js_sys::Promise;
|
||||
|
@ -39,15 +40,17 @@ pub struct Common {
|
|||
pub window: web_sys::Window,
|
||||
/// Note: resizing the HTMLCanvasElement should go through `backend::set_canvas_size` to ensure the DPI factor is maintained.
|
||||
pub raw: HtmlCanvasElement,
|
||||
size: Rc<Cell<PhysicalSize<u32>>>,
|
||||
wants_fullscreen: Rc<RefCell<bool>>,
|
||||
}
|
||||
|
||||
impl Canvas {
|
||||
pub fn create(
|
||||
window: web_sys::Window,
|
||||
attr: PlatformSpecificWindowBuilderAttributes,
|
||||
attr: &WindowAttributes,
|
||||
platform_attr: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<Self, RootOE> {
|
||||
let canvas = match attr.canvas {
|
||||
let canvas = match platform_attr.canvas {
|
||||
Some(canvas) => canvas,
|
||||
None => {
|
||||
let document = window
|
||||
|
@ -66,16 +69,28 @@ impl Canvas {
|
|||
// sequential keyboard navigation, but its order is defined by the
|
||||
// document's source order.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
|
||||
if attr.focusable {
|
||||
if platform_attr.focusable {
|
||||
canvas
|
||||
.set_attribute("tabindex", "0")
|
||||
.map_err(|_| os_error!(OsError("Failed to set a tabindex".to_owned())))?;
|
||||
}
|
||||
|
||||
Ok(Canvas {
|
||||
let size = attr
|
||||
.inner_size
|
||||
.unwrap_or(
|
||||
LogicalSize {
|
||||
width: 1024.0,
|
||||
height: 768.0,
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
.to_physical(super::scale_factor(&window));
|
||||
|
||||
let canvas = Canvas {
|
||||
common: Common {
|
||||
window,
|
||||
raw: canvas,
|
||||
size: Rc::new(Cell::new(size)),
|
||||
wants_fullscreen: Rc::new(RefCell::new(false)),
|
||||
},
|
||||
on_touch_start: None,
|
||||
|
@ -88,7 +103,11 @@ impl Canvas {
|
|||
on_fullscreen_change: None,
|
||||
on_dark_mode: None,
|
||||
pointer_handler: PointerHandler::new(),
|
||||
})
|
||||
};
|
||||
|
||||
super::set_canvas_size(&canvas, size.into());
|
||||
|
||||
Ok(canvas)
|
||||
}
|
||||
|
||||
pub fn set_cursor_lock(&self, lock: bool) -> Result<(), RootOE> {
|
||||
|
@ -121,11 +140,12 @@ impl Canvas {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> PhysicalSize<u32> {
|
||||
PhysicalSize {
|
||||
width: self.common.raw.width(),
|
||||
height: self.common.raw.height(),
|
||||
}
|
||||
pub fn window(&self) -> &web_sys::Window {
|
||||
&self.common.window
|
||||
}
|
||||
|
||||
pub fn size(&self) -> &Rc<Cell<PhysicalSize<u32>>> {
|
||||
&self.common.size
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> &HtmlCanvasElement {
|
||||
|
|
|
@ -76,12 +76,19 @@ pub fn scale_factor(window: &web_sys::Window) -> f64 {
|
|||
window.device_pixel_ratio()
|
||||
}
|
||||
|
||||
pub fn set_canvas_size(window: &web_sys::Window, raw: &HtmlCanvasElement, size: Size) {
|
||||
let scale_factor = scale_factor(window);
|
||||
let logical_size = size.to_logical::<f64>(scale_factor);
|
||||
pub fn set_canvas_size(canvas: &Canvas, new_size: Size) {
|
||||
let scale_factor = scale_factor(canvas.window());
|
||||
|
||||
set_canvas_style_property(raw, "width", &format!("{}px", logical_size.width));
|
||||
set_canvas_style_property(raw, "height", &format!("{}px", logical_size.height));
|
||||
let physical_size = new_size.to_physical(scale_factor);
|
||||
canvas.size().set(physical_size);
|
||||
|
||||
let logical_size = new_size.to_logical::<f64>(scale_factor);
|
||||
set_canvas_style_property(canvas.raw(), "width", &format!("{}px", logical_size.width));
|
||||
set_canvas_style_property(
|
||||
canvas.raw(),
|
||||
"height",
|
||||
&format!("{}px", logical_size.height),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn set_canvas_style_property(raw: &HtmlCanvasElement, property: &str, value: &str) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Position, Size};
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};
|
||||
use crate::error::{ExternalError, NotSupportedError, OsError as RootOE};
|
||||
use crate::event;
|
||||
use crate::icon::Icon;
|
||||
|
@ -48,7 +48,7 @@ impl Window {
|
|||
let prevent_default = platform_attr.prevent_default;
|
||||
|
||||
let window = target.runner.window();
|
||||
let canvas = backend::Canvas::create(window.clone(), platform_attr)?;
|
||||
let canvas = backend::Canvas::create(window.clone(), &attr, platform_attr)?;
|
||||
let canvas = Rc::new(RefCell::new(canvas));
|
||||
|
||||
let register_redraw_request = Box::new(move || runner.request_redraw(RootWI(id)));
|
||||
|
@ -67,15 +67,6 @@ impl Window {
|
|||
let runner = target.runner.clone();
|
||||
let destroy_fn = Box::new(move || runner.notify_destroy_window(RootWI(id)));
|
||||
|
||||
backend::set_canvas_size(
|
||||
window,
|
||||
canvas.borrow().raw(),
|
||||
attr.inner_size.unwrap_or(Size::Logical(LogicalSize {
|
||||
width: 1024.0,
|
||||
height: 768.0,
|
||||
})),
|
||||
);
|
||||
|
||||
let window = Window {
|
||||
id,
|
||||
has_focus,
|
||||
|
@ -171,7 +162,7 @@ impl Window {
|
|||
pub fn set_inner_size(&self, size: Size) {
|
||||
self.inner.dispatch(move |inner| {
|
||||
let old_size = inner.inner_size();
|
||||
backend::set_canvas_size(&inner.window, inner.canvas.borrow().raw(), size);
|
||||
backend::set_canvas_size(&inner.canvas.borrow(), size);
|
||||
let new_size = inner.inner_size();
|
||||
if old_size != new_size {
|
||||
(inner.resize_notify_fn)(new_size);
|
||||
|
@ -454,7 +445,7 @@ impl Inner {
|
|||
|
||||
#[inline]
|
||||
pub fn inner_size(&self) -> PhysicalSize<u32> {
|
||||
self.canvas.borrow().size()
|
||||
self.canvas.borrow().size().get()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue