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

stdweb support for eventloop 2.0 #797

Closed
wants to merge 31 commits into from

Conversation

ryanisaacg
Copy link
Contributor

@ryanisaacg ryanisaacg commented Feb 20, 2019

Unresolved design questions:

  • Should multiple canvases be supported? I'm leaning no
  • Should fullscreen be supported? If it should be, should it be the size of the window or some attempt to make the canvas actually fullscreen?
  • Is the window icon synonymous with the favicon? I'm leaning yes
  • Should file dropping be supported? It's a JS File object which isn't as useful as it is on desktop
  • Should show / hide be supported?
  • How should refresh rate (opaque to a web page) be handled by VideoMode?

Implementation:

  • Creating a canvas / setting window title
  • DOM -> winit event binding support
  • Event cause
  • ControlFlow handling
    • Poll
    • Wait
    • WaitUntil
    • Exit
  • Pointer events
  • Keyboard events
  • Requesting redraws
  • Canvas positioning within the window
  • KeyboardEvent::which PR to stdweb
  • Pointer capture API (stdweb PR)
  • DPI handling (the browser handles it)
  • Handle on close events (stdweb PR)
  • Mouse wheel events
  • Fullscreen (stdweb PR)
  • Monitor APIs
  • Add logging

Testing / docs:

  • Tested on all platforms changed
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created an example program if it would help users understand this functionality
  • Add stdweb to CI

Everything typechecks, but nothing is implemented
@icefoxen icefoxen mentioned this pull request Feb 26, 2019
@Osspial Osspial added DS - web C - in progress Implementation is proceeding smoothly S - platform parity Unintended platform differences labels Mar 6, 2019
@Osspial Osspial added this to the EventLoop 2.0 milestone Mar 6, 2019
@ryanisaacg
Copy link
Contributor Author

Ok, so I've made a bunch of progress on this (most of it was just churning through various bad designs that didn't work at all) and it's in a state where you can make a window, run an event loop, and receive events! 🎉

I made a roadmap in the PR text to give an indication of where I'm at on the implantation, and the unresolved questions I have about the design. If any maintainers (or users for that matter) have opinions, please let me know!

@solson
Copy link

solson commented Mar 13, 2019

Apologies if this question is naive, but would it make sense for winit to support wasm-bindgen's web-sys directly, rather than stdweb? According to this thread, stdweb plans to become a wrapper around web-sys that's a bit higher level (but also more expensive), while web-sys provides the bare minimum only-pay-for-what-you-use interface for Web APIs.

Either way, it would be fine to support both, or stdweb now and web-sys later, so I don't mean to imply the PR should be blocked over this.

@ryanisaacg
Copy link
Contributor Author

Essentially: stdweb is what I'm more familiar with and what my downstream project uses. I would be open to supporting both (for example the rand crate allows either via feature flags) if someone else contributes the web-sys backend.

@Osspial
Copy link
Contributor

Osspial commented Mar 13, 2019

General thoughts on the API questions you have:

Should multiple canvases be supported? I'm leaning no

I'd agree with that for now. We can revisit this once we figure out #696, but for now only having a single canvas is simplest.

Should fullscreen be supported? If it should be, should it be the size of the window or some attempt to make the canvas actually fullscreen?

Yes, and I'd say to actually make the canvas fullscreen. This is a feature that's commonly supported across browsers (video fullscreening, for instance), it's useful to have, and it's consistent with the other backends.

Is the window icon synonymous with the favicon? I'm leaning yes

Eeeeh, I'm less sure about this. If we do end up supporting multiple canvases at some point there's no clean solution for what to do when multiple icons get set on different Window objects. This feels like it should be handled by the parent webpage.

Should file dropping be supported? It's a JS File object which isn't as useful as it is on desktop
Should show / hide be supported?

I'd say no for now. Using the same File API across both desktop platforms and web platforms implies that the data they provide can be used the same way, which doesn't seem to be the case (I'd be surprised if std::fs::File::open works on the web, but I may be wrong there). We can come back to this later though, and see about maybe exposing a different API to make clear that it has different semantics.

@ryanisaacg
Copy link
Contributor Author

Just a heads up: my progress on this is going to slow down for a while, as I'll probably not have as much time to work on it for the next few weeks.

@blm768
Copy link
Contributor

blm768 commented Jun 8, 2019

After a little testing, it's looking like the basic canvas creation and event handling seem to be working (at least with a slightly generous definition of "working") with the web-sys version. At this point, my thought is that I should focus on exploring the integration of the three existing efforts so we can avoid having too much duplication of effort. It's probably too early in the design and implementation process to just merge everything into one massive PR, but some early consideration for integration will probably pay off in the long run.

While I'm thinking about it, I've got a couple of thoughts I've been considering:

  • I noticed that both this PR and WIP - wasm_bindgen backend for eventloop-2.0 #845 use an exception to bail out of the main event loop. If it's not too late in the design process for eventloop-2.0, it seems like providing a "sanctioned" way to bail out of the event loop early would be useful, especially if winit ever picks up another callback-driven backend. I'm not familiar enough with winit yet to propose any particular design, but it seems like it's worth some consideration.
  • When handling the closures in wasm-bindgen, it's necessary to keep the Closure objects alive on the Rust side at least as long as they might be used on the JavaScript side; after the Rust object is dropped, trying to call the JavaScript closure produces an exception. The Closures can just be leaked, but it seems better to clean them up properly. This requires a small design change, which may have some bearing on the integration efforts. It might be worth including something similar to this change in the stdweb backend since it allows for de-registration of the event handlers when the event loop and/or window go out of scope on the Rust side.

@goddessfreya
Copy link
Contributor

@ryanisaacg Are you intending to maintain the stdweb backend after this PR lands?

@ryanisaacg
Copy link
Contributor Author

@zegentzy Yes, but without a guarantee that I'll have a lot of time for it. I'll do my best to keep it updated, though; at the very least I'll be using it downstream.

@goddessfreya
Copy link
Contributor

Okay. Should prolly add a new column and row to the table in https://github.com/rust-windowing/winit/blob/master/CONTRIBUTING.md then.

Also to the tables in https://github.com/rust-windowing/winit/blob/master/FEATURES.md when you are done.

@Osspial can probably add you to rust-windowing

@Osspial Osspial changed the base branch from eventloop-2.0 to master June 13, 2019 05:31

event_loop.run(|event, _, control_flow| {
println!("{:?}", event);
console!(log, format!("{:?}", event));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to revert the changes in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, before merge I'll be doing some cleanup (this is still actively in development and I use this example to test.)

Copy link
Contributor

@hecrj hecrj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Let me know if I can help!

src/platform_impl/stdweb/event_loop.rs Outdated Show resolved Hide resolved
@hecrj
Copy link
Contributor

hecrj commented Jun 25, 2019

I am currently working on unifying both the stdweb and web_sys efforts. I am just restructuring the work by @ryanisaacg and @blm768 while removing duplication. Take a look here: https://github.com/hecrj/winit/tree/web/src/platform_impl/web

In summary, I have created a new web platform that contains two backends: stdweb and web_sys. Most of the code in the web platform is backend agnostic. Each backend simply provides Canvas and Timeout types which is where the actual wiring happens. These types are also useful to avoid leaking closures.

The web_sys backend is already usable. I have been able to use it successfully with wgpu and WebGL. Here is an example that renders a triangle and outputs the window events on console: http://hello-triangle.surge.sh/

The stdweb backend should be quite straightforward to implement. I will work on that later today.

Additionally, I have made some other changes:

  • Added support for the ReceivedCharacter event.
  • Made the keyboard and focused events local to the canvas by adding a tabindex attribute. Now you need to click on the canvas to interact with it. This should allow us to easily implement support for multiple windows in the same document, and it also removes awkward global listeners.
  • Because of the previous change and given that a document has only one title, set_title now only changes the alt attribute of the canvas.

Let me know what you think!

@blm768
Copy link
Contributor

blm768 commented Jun 26, 2019

@hecrj: I haven't looked through your changes thoroughly, but I'm thrilled to learn that it's working (particularly with wgpu, which should be really useful in making my own toy project more portable).

Have you happened to look at the changes in #845? If I recall correctly, they had already started on multi-canvas support, and the WebsysWindowBuilderExt trait might be a useful starting pattern. For the single-canvas cases, it may also be possible to extend that trait to provide some mechanism to use the document title as the window title, ensure that the canvas has focus so it receives events immediately, etc.

That raises a question about winit in general, actually: does it generally report any input events for windows that don't have focus (i.e. "mouse over" events that happen "in passing")? If so, we'll probably want to retain some kind of support for those events.

@felixrabe
Copy link
Contributor

felixrabe commented Jun 26, 2019

(Just noticed that this is a Draft PR that I didn't know about previously. Quick intro with very helpful screenshot here: https://github.blog/2019-02-14-introducing-draft-pull-requests/)

@hecrj
Copy link
Contributor

hecrj commented Jun 26, 2019

@blm768

For the single-canvas cases, it may also be possible to extend that trait to provide some mechanism to use the document title as the window title, ensure that the canvas has focus so it receives events immediately, etc.

I see that #845 uses platform-specific builder attributes to take control of an already existing canvas in the document. Maybe we could take this approach and simply make the Window take control of the whole document when the attribute is not provided.

That raises a question about winit in general, actually: does it generally report any input events for windows that don't have focus (i.e. "mouse over" events that happen "in passing")? If so, we'll probably want to retain some kind of support for those events.

Not sure what the desired behavior is in this case, but the current one reports mouse events just fine even when the canvas loses focus. Right now, the only events that are focus-dependent are keyboard events.

@hecrj hecrj mentioned this pull request Jul 2, 2019
26 tasks
@goddessfreya
Copy link
Contributor

@ryanisaacg As we discussed on Discord, I've made a new web branch with @hecrj's fork. It should be noted that it was four commits behind your branch, so you might want to push those changes to it, if they are still applicable.

Anyways, closing. Thanks!

@goddessfreya
Copy link
Contributor

@ryanisaacg Can you open a tracking issue with the things at the top? Thanks.

@ryanisaacg
Copy link
Contributor Author

@zegentzy sure, opened #1072

@ryanisaacg ryanisaacg deleted the stdweb-eventloop-2 branch September 24, 2019 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C - in progress Implementation is proceeding smoothly DS - web S - platform parity Unintended platform differences
Development

Successfully merging this pull request may close these issues.

7 participants