Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Winit 0.29 follow up #11052

Closed
10 of 23 tasks
Vrixyz opened this issue Dec 21, 2023 · 20 comments
Closed
10 of 23 tasks

Winit 0.29 follow up #11052

Vrixyz opened this issue Dec 21, 2023 · 20 comments
Labels
A-Input Player input via keyboard, mouse, gamepad, and more A-Windowing Platform-agnostic interface layer to run your app in C-Feature A new feature, making something new possible C-Tracking-Issue An issue that collects information about a broad development initiative D-Domain-Expert Requires deep knowledge in a given domain D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes

Comments

@Vrixyz
Copy link
Member

Vrixyz commented Dec 21, 2023

A few shortcuts were taken in #10702 in order to merge it in a reasonable amount of time.

This issue serves to :

  • coordinate addressing those follow-ups
  • offer a place to discuss the winit update
  • mentoring opportunities

Feel free to create or ask a dedicated issue for any listed task, if you feel like it's worth it.

Known regressions (important follow ups?)

Follow up

I'd like to avoid bloating this PR, here are a few follow up tasks worthy of a separate PR, or new issue to track them once this PR is closed, as they would either complicate reviews, or at risk of being controversial:

@Vrixyz Vrixyz added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled A-Input Player input via keyboard, mouse, gamepad, and more A-Windowing Platform-agnostic interface layer to run your app in C-Tracking-Issue An issue that collects information about a broad development initiative labels Dec 21, 2023
@nicopap nicopap removed the S-Needs-Triage This issue needs to be labelled label Dec 21, 2023
github-merge-queue bot pushed a commit that referenced this issue Dec 21, 2023
Improves #11052

# Changelog
- Remove `Window::fit_canvas_to_parent`, as its resizing on wasm now
respects its CSS configuration.

## Migration Guide
- Remove uses of `Window::fit_canvas_to_parent` in favor of CSS
properties, for example:
  ```css
  canvas {
    width: 100%;
    height: 100%;
  }
  ```
@alice-i-cecile alice-i-cecile added this to the 0.13 milestone Dec 21, 2023
@alice-i-cecile alice-i-cecile added the D-Trivial Nice and easy! A great choice to get started with Bevy label Dec 21, 2023
@daxpedda
Copy link
Contributor

daxpedda commented Dec 22, 2023

This has been addressed in Winit v0.29.4.

  • investigate this unwrap (winit_window.canvas().unwrap();)

See #10702 (comment).

EDIT: This part of the code will go away in #11065.


One thing I believe was overlooked is the missing documentation on setting a CSS size on the canvas. This will become a major footgun for any deployments targeting any platform with a scale factor that's not 1.0.

FWIW: Window::fit_canvas_to_parent was still useful to apply the CSS width: 100%; height: 100%, something similar should be introduced again (without all the resizing stuff, it should literally only apply these CSS values).

github-merge-queue bot pushed a commit that referenced this issue Dec 24, 2023
# Objective

Replace the canvas appending code with a simpler version provided by
Winit v0.29.

Related: #11052.

## Solution

Use
[`WindowBuilder::with_append()`](https://docs.rs/winit/0.29.5/wasm32-unknown-unknown/winit/platform/web/trait.WindowBuilderExtWebSys.html#tymethod.with_append).
@rniii
Copy link

rniii commented Dec 26, 2023

Could that property be bought back for setting the CSS? Right now, the canvas seems to still get an inline style with width/height (and max-/min-) set, so you also need to use !important on your stylesheet.

Another thing that seems to have went unnoticed is that canvas elements default to display: inline, which causes them to not exactly fit in the parent element and overflow, so this option could also add display: block (or it could be always there).

Either way, I do agree it should be at least documented if not added.

@daxpedda
Copy link
Contributor

daxpedda commented Dec 30, 2023

I didn't review #10702, but looking at it now there is at least one big problem: AboutToWait is used to update and draw. This can't work unfortunately, because AboutToWait has no relationship with time or drawing or anything really, it's wholly dependent on user input and other various events, it could fire once per second or a million times.

EDIT: I looked into it a bit further, and as far as I can see Bevy has some system in place to update based on RedrawRequested, but still do the redrawing in AboutToWait. This could be fine, but unfortunately I couldn't find any reference to WindowEvent::RedrawRequested, so I assume that this was missed during the update.

The only meaning ascribed to it should be that there are currently no further events. It is recommended to draw either based on your own timings (maybe in combination with ControlFlow::WaitUntil), or simply use Window::request_redraw(), which has to be called every frame to queue the next one, and then draw on RedrawRequested.

If Bevy wants to also update exactly as fast as it draws, then it can do the update in RedrawRequested as well.

My assumption is that this is the culprit behind #11122 and rust-windowing/winit#1418 (which is linked by a bunch of Bevy issues).

Please feel free to tag me at any Winit related issues/PRs, I'm happy to chime in or review them.

@miketwenty1
Copy link

miketwenty1 commented Jan 5, 2024

@daxpedda @rniii Not having fit_canvas_to_parent available has made things very difficult/weird for me. I'm creating my js/wasm files with wasm-bindgen and it's a bit of black box. I don't have access to directly manipulate the canvas element, so I made a sort of hacky js work around. However, even after resizing my canvas to full width/height it's creating issues for mobile I think alluded to by:

This will become a major footgun for any deployments targeting any platform with a scale factor that's not 1.0.

Not sure if this is alluding to scale factor / aspect ratio for mobile resolution vs viewport?

Are there any issues with reverting back this change until something better is possible? Fwiw fit_canvas_to_parent was working very well for me on mobile and desktop.

@daxpedda
Copy link
Contributor

daxpedda commented Jan 5, 2024

web-sys = { version = "0.3", features = [
	"CssStyleDeclaration",
	"Document",
	"HtmlCanvasElement",
	"Window",
] }
fn fit_canvas_to_parent(windows: Query<&Window, With<PrimaryWindow>>) {
    let window = windows.single();
    let canvas: HtmlCanvasElement = web_sys::window()
        .unwrap()
        .document()
        .unwrap()
        .query_selector(window.canvas().unwrap())
        .unwrap()
        .unwrap();
    let style = canvas.style();
    style.set_property("width", "100%").unwrap();
    style.set_property("height", "100%").unwrap();
}

This should do the trick, please let me know if this doesn't work out for you.

@miketwenty1
Copy link

miketwenty1 commented Jan 5, 2024

@daxpedda
I'm getting this error with copy-pasta

275 |       let canvas: HtmlCanvasElement = web_sys::window()
    |  _________________-----------------___^
    | |                 |
    | |                 expected due to this
276 | |         .unwrap()
277 | |         .document()
278 | |         .unwrap()
279 | |         .query_selector(window.canvas().unwrap())
280 | |         .unwrap()
281 | |         .unwrap();
    | |_________________^ expected `HtmlCanvasElement`, found `Element`

Changing HtmlCanvasElement to Element causes this error:
no method named canvasfound for reference&bevy::prelude::Window in the current scope field, not a method

This is my web-sys dep:

[dependencies.web-sys]
version = "0.3"
features = [
    "CssStyleDeclaration",
    "Document",
    "HtmlCanvasElement",
    "Clipboard",
    "Window",
    "Navigator",
    "Permissions",
]

@daxpedda
Copy link
Contributor

daxpedda commented Jan 5, 2024

So I actually tried out my suggestion and fixed it up in #11052 (comment).
Unfortunately I can see now that Bevy doesn't actually populate Window::canvas, so this should probably be removed now as well.

So this is what I tried and I can confirm it works:

use web_sys::HtmlCanvasElement;
use wasm_bindgen::JsCast;

fn fit_canvas_to_parent() {
    let canvas: HtmlCanvasElement = web_sys::window()
        .unwrap()
        .document()
        .unwrap()
        .query_selector("canvas")
        .unwrap()
        .unwrap()
        .unchecked_into();
    let style = canvas.style();
    style.set_property("width", "100%").unwrap();
    style.set_property("height", "100%").unwrap();
}

also add the following to your App:

        .add_systems(Startup, fit_canvas_to_parent)

@miketwenty1
Copy link

miketwenty1 commented Jan 6, 2024

@daxpedda Things seem to be much better doing this. On mobile though the cursor/touch position and where the mouse/touch is.. is off while running off main.. and gets worse the further from top left of the screen i go. Any ideas here? Possibly unrelated but thought i should check.

view port in my metadata is:
<meta name="viewport" content="width=device-width, initial-scale=1.0">

I'm guessing this is a viewport issue scale issue not resizing for mobile now for some reason. I'm assuming the fit_canvas_to_parent was doing something here to address this? only me speculating.

@daxpedda
Copy link
Contributor

daxpedda commented Jan 6, 2024

What browser and OS are you using?
Could you also tell me the output of window.devicePixelRatio by entering that in the JS console?

This might be a Winit bug, but we supposedly fixed that a long while ago.

I'm assuming the fit_canvas_to_parent was doing something here to address this?

I don't think so, but maybe Bevy was adjusting these positions somewhere to fix the old bug in Winit?

@miketwenty1
Copy link

tested on a bunch devicePixelRatio on old build with bevy 12.1 and new build with main.
On old build pretty much any devicePixelRatio will be good.

On new build given the following config I've setup with you, only window.devicePixelRatio resulting in 2 will work.

@miketwenty1
Copy link

I think this is for sure a bug. @daxpedda so I opened an issue. Still not 100% sure if it's related to this or something else.
#11231

@alice-i-cecile
Copy link
Member

Another near duplicate: #11320.

@daxpedda
Copy link
Contributor

Following up on #11227 (comment):

// TODO(clean): winit docs recommends calling pre_present_notify before this.
// though `present()` doesn't present the frame, it schedules it to be presented
// by wgpu.
// https://docs.rs/winit/0.29.9/wasm32-unknown-unknown/winit/window/struct.Window.html#method.pre_present_notify

gfx-rs/wgpu#5093 seems to now clarify whats going on here, so Window::pre_present_notify() should be called here.

github-merge-queue bot pushed a commit that referenced this issue Jan 22, 2024
Add logical key data to KeyboardInput

Addresses an item of #11052

---------

Co-authored-by: Mateusz Wachowiak <[email protected]>
@alice-i-cecile alice-i-cecile removed this from the 0.13 milestone Feb 12, 2024
Subserial pushed a commit to Subserial/bevy_winit_hook that referenced this issue Feb 20, 2024
Add logical key data to KeyboardInput

Addresses an item of bevyengine/bevy#11052

---------

Co-authored-by: Mateusz Wachowiak <[email protected]>
@tripokey
Copy link
Contributor

PSA: Removing the instant dependency seems to trigger the following error (in the browsers web console) if you happen to have instant somewhere else in your dependency tree:

Uncaught TypeError: Failed to resolve module specifier "env". Relative references must start with either "/", "./", or "../".

This happens because bevy previously enabled the wasm-bindgen feature for the instant crate which hides the error.

A workaround for this issue is to add the instant crate to your application with the wasm-bindgen feature enabled.

@tripokey
Copy link
Contributor

tripokey commented Feb 21, 2024

So I actually tried out my suggestion and fixed it up in #11052 (comment). Unfortunately I can see now that Bevy doesn't actually populate Window::canvas, so this should probably be removed now as well.

So this is what I tried and I can confirm it works:

use web_sys::HtmlCanvasElement;
use wasm_bindgen::JsCast;

fn fit_canvas_to_parent() {
    let canvas: HtmlCanvasElement = web_sys::window()
        .unwrap()
        .document()
        .unwrap()
        .query_selector("canvas")
        .unwrap()
        .unwrap()
        .unchecked_into();
    let style = canvas.style();
    style.set_property("width", "100%").unwrap();
    style.set_property("height", "100%").unwrap();
}

also add the following to your App:

        .add_systems(Startup, fit_canvas_to_parent)

@daxpedda thanks for this, it saved me since the information is not present in the migration guide: https://bevyengine.org/learn/migration-guides/0-12-to-0-13/#remove-canvasparentresizeplugin

@Vrixyz
Copy link
Member Author

Vrixyz commented Feb 22, 2024

@tripokey thanks for commenting your experience, sorry about the migration, I think #11278 would have helped, can you weigh in ?

@tripokey
Copy link
Contributor

@Vrixyz I merged your MR on top of the 0.13 release and replace the manual fit_canvas_to_parent system with the fit_canvas_to_parent Window settings. And it seems to work.

@simbleau
Copy link
Contributor

simbleau commented Feb 29, 2024

PSA: Removing the instant dependency seems to trigger the following error (in the browsers web console) if you happen to have instant somewhere else in your dependency tree:

Uncaught TypeError: Failed to resolve module specifier "env". Relative references must start with either "/", "./", or "../".

This happens because bevy previously enabled the wasm-bindgen feature for the instant crate which hides the error.

A workaround for this issue is to add the instant crate to your application with the wasm-bindgen feature enabled.

I'm really interested to know how you discovered this. I found your comment and thank gosh I did! Is this being tracked anywhere?

@tripokey
Copy link
Contributor

PSA: Removing the instant dependency seems to trigger the following error (in the browsers web console) if you happen to have instant somewhere else in your dependency tree:

Uncaught TypeError: Failed to resolve module specifier "env". Relative references must start with either "/", "./", or "../".

This happens because bevy previously enabled the wasm-bindgen feature for the instant crate which hides the error.
A workaround for this issue is to add the instant crate to your application with the wasm-bindgen feature enabled.

I'm really interested to know how you discovered this. I found your comment and thank gosh I did! Is this being tracked anywhere?

I just got lucky googling the error and found:
rustwasm/wasm-bindgen#3500 (reply in thread)

Then double checked my Cargo.lock file and Bevy's dependencies 😅

@BD103 BD103 added D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes D-Domain-Expert Requires deep knowledge in a given domain and removed D-Trivial Nice and easy! A great choice to get started with Bevy labels Jul 18, 2024
@alice-i-cecile
Copy link
Member

Marking as closed, but we should open individual issues for any remaining problems here.

@alice-i-cecile alice-i-cecile closed this as not planned Won't fix, can't repro, duplicate, stale Nov 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Input Player input via keyboard, mouse, gamepad, and more A-Windowing Platform-agnostic interface layer to run your app in C-Feature A new feature, making something new possible C-Tracking-Issue An issue that collects information about a broad development initiative D-Domain-Expert Requires deep knowledge in a given domain D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes
Projects
None yet
Development

No branches or pull requests

9 participants