-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Labels
B - bugDang, that shouldn't have happenedDang, that shouldn't have happenedDS - webAffects the Web backend (WebAssembly/WASM)Affects the Web backend (WebAssembly/WASM)
Description
Description
on wasm, window.surface_size() returns 0x0 immediately after create_window(), even when the canvas has explicit dimensions and with_surface_size() is used. the size only updates after the first resize event.
in winit-web/src/web_sys/canvas.rs, Canvas::create() calls set_canvas_size() to update the dom but never updates the current_size cache that surface_size() returns.
i think the fix would be to update the cache after setting the canvas size:
if let Some(size) = attr.surface_size {
let logical_size = size.to_logical(super::scale_factor(&common.window));
super::set_canvas_size(&common.document, &common.raw, &common.style, logical_size);
// can we update common.current_size and common.old_size here?
}minimally reproducible example
// src/main.rs
use wasm_bindgen::prelude::*;
use winit::{
application::ApplicationHandler,
dpi::{PhysicalSize, Size},
event::WindowEvent,
event_loop::{ActiveEventLoop, EventLoop},
platform::web::{WindowAttributesWeb},
window::{Window, WindowId}
};
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
#[derive(Default)]
struct App(Option<Box<dyn Window>>);
impl ApplicationHandler for App {
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
let mut attribs = winit::window::WindowAttributes::default()
.with_surface_size(Size::Physical(PhysicalSize::new(1280, 720)));
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
let canvas = document
.get_element_by_id("canvas")
.expect("no #canvas found")
.dyn_into::<web_sys::HtmlCanvasElement>()
.unwrap();
log(&format!("canvas size according to html/web_sys: {}x{}", canvas.width(), canvas.height()));
attribs = attribs.with_platform_attributes(Box::new(
WindowAttributesWeb::default().with_canvas(Some(canvas.into())),
));
let window = event_loop.create_window(attribs).unwrap();
let surface_size = window.surface_size();
log(&format!("window.surface_size() returns: {}x{}", surface_size.width, surface_size.height));
self.0 = Some(window);
}
fn window_event(&mut self, _: &dyn ActiveEventLoop, _: WindowId, event: WindowEvent) {
if let WindowEvent::SurfaceResized(new_size) = event {
let window = self.0.as_ref().unwrap();
let size = window.surface_size();
log(&format!("SurfaceResized -> surface_size() now returns: {}x{}", size.width, size.height));
}
}
}
fn main() {
use winit::platform::web::EventLoopExtWeb;
let event_loop = EventLoop::new().unwrap();
let app = App::default();
event_loop.spawn_app(app);
}# Cargo.toml
[package]
name = "winit-surface-size-bug"
version = "0.1.0"
edition = "2021"
[dependencies]
winit = { git = "https://github.com/rust-windowing/winit" }
[target.'cfg(target_arch = "wasm32")'.dependencies]
web-sys = { version = "0.3", features = ["Window", "Document", "HtmlCanvasElement", "console"] }
wasm-bindgen = "0.2"<!doctype html>
<html lang="en">
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<script type="module">
import init from './winit-surface-size-bug.js';
init()
</script>
</body>
</html>#!/bin/bash
set -e
cargo build --target wasm32-unknown-unknown --release
mkdir -p pkg
wasm-bindgen --out-dir pkg --target web target/wasm32-unknown-unknown/release/winit-surface-size-bug.wasm
cp index.html pkg/
cd pkg && python3 -m http.server 8080Tested browsers
Chrome, Safari (newer than listed)
Tested devices
iPhone 12 Pro Max Safari, iPad Pro Safari
Winit version
latest development version at the time of this pull request a9c189a4
Metadata
Metadata
Assignees
Labels
B - bugDang, that shouldn't have happenedDang, that shouldn't have happenedDS - webAffects the Web backend (WebAssembly/WASM)Affects the Web backend (WebAssembly/WASM)