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