Move Web backend to winit-web

This commit is contained in:
Mads Marquart 2025-05-16 01:23:35 +02:00 committed by Kirill Chibisov
parent 2d4b9938f0
commit e542a78deb
50 changed files with 259 additions and 273 deletions

3
.github/CODEOWNERS vendored
View file

@ -17,8 +17,7 @@
/winit-x11 @kchibisov @notgull
# Web
/src/platform/web.rs @daxpedda
/src/platform_impl/web @daxpedda
/winit-web @daxpedda
# Windows (Win32)
/winit-win32 @notgull

View file

@ -199,7 +199,7 @@ jobs:
- name: Test winit AppKit
if: contains(matrix.platform.target, 'macos')
run: cargo $CMD test -p winit-appkit --target=${{ matrix.platform.target }}
run: cargo $CMD test -p winit-appkit $OPTIONS
- name: Test winit Orbital
if: contains(matrix.platform.target, 'redox')
@ -208,11 +208,15 @@ jobs:
- name: Test winit UIKit
if: contains(matrix.platform.target, 'ios')
# TODO: Run on Simulator
run: cargo $CMD test -p winit-uikit --target=${{ matrix.platform.target }} --no-run
run: cargo $CMD test -p winit-uikit $OPTIONS --no-run
- name: Test winit Web
if: contains(matrix.platform.target, 'wasm')
run: cargo $CMD test -p winit-web $OPTIONS --no-run
- name: Test winit Win32
if: contains(matrix.platform.target, 'windows')
run: cargo $CMD test -p winit-win32 --target=${{ matrix.platform.target }}
run: cargo $CMD test -p winit-win32 $OPTIONS
- name: Test winit X11
if: contains(matrix.platform.target, 'linux-gnu')
@ -317,7 +321,7 @@ jobs:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./src/platform_impl/web/script
working-directory: ./winit-web/src/script
steps:
- uses: taiki-e/checkout-action@v1
@ -332,7 +336,7 @@ jobs:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./src/platform_impl/web/script
working-directory: ./winit-web/src/script
steps:
- uses: taiki-e/checkout-action@v1

View file

@ -19,6 +19,7 @@ winit-core = { version = "0.0.0", path = "winit-core" }
winit-orbital = { version = "0.0.0", path = "winit-orbital" }
winit-uikit = { version = "0.0.0", path = "winit-uikit" }
winit-wayland = { version = "0.0.0", path = "winit-wayland", default-features = false }
winit-web = { version = "0.0.0", path = "winit-web" }
winit-win32 = { version = "0.0.0", path = "winit-win32" }
winit-x11 = { version = "0.0.0", path = "winit-x11" }
@ -108,17 +109,7 @@ categories = ["gui"]
description = "Cross-platform window creation library."
documentation = "https://docs.rs/winit"
edition.workspace = true
include = [
"/build.rs",
"/docs",
"/examples",
"/FEATURES.md",
"/LICENSE",
"/src",
"!/src/platform_impl/web/script",
"/src/platform_impl/web/script/**/*.min.js",
"/tests",
]
include = ["/build.rs", "/docs", "/examples", "/FEATURES.md", "/LICENSE", "/src", "/tests"]
keywords = ["windowing"]
license.workspace = true
name = "winit"
@ -221,74 +212,15 @@ winit-x11 = { workspace = true, optional = true }
[target.'cfg(target_os = "redox")'.dependencies]
winit-orbital.workspace = true
# Web
[target.'cfg(target_family = "wasm")'.dependencies]
js-sys.workspace = true
pin-project.workspace = true
wasm-bindgen.workspace = true
wasm-bindgen-futures.workspace = true
web-time.workspace = true
web_sys = { workspace = true, features = [
"AbortController",
"AbortSignal",
"Blob",
"BlobPropertyBag",
"console",
"CssStyleDeclaration",
"Document",
"DomException",
"DomRect",
"DomRectReadOnly",
"Element",
"Event",
"EventTarget",
"FocusEvent",
"HtmlCanvasElement",
"HtmlElement",
"HtmlHtmlElement",
"HtmlImageElement",
"ImageBitmap",
"ImageBitmapOptions",
"ImageBitmapRenderingContext",
"ImageData",
"IntersectionObserver",
"IntersectionObserverEntry",
"KeyboardEvent",
"MediaQueryList",
"MessageChannel",
"MessagePort",
"Navigator",
"Node",
"OrientationLockType",
"OrientationType",
"PageTransitionEvent",
"Permissions",
"PermissionState",
"PermissionStatus",
"PointerEvent",
"PremultiplyAlpha",
"ResizeObserver",
"ResizeObserverBoxOptions",
"ResizeObserverEntry",
"ResizeObserverOptions",
"ResizeObserverSize",
"Screen",
"ScreenOrientation",
"Url",
"VisibilityState",
"WheelEvent",
"Window",
"Worker",
] }
[target.'cfg(all(target_family = "wasm", target_feature = "atomics"))'.dependencies]
atomic-waker.workspace = true
concurrent-queue.workspace = true
winit-web.workspace = true
[target.'cfg(target_family = "wasm")'.dev-dependencies]
console_error_panic_hook.workspace = true
tracing-web.workspace = true
wasm-bindgen-futures.workspace = true
wasm-bindgen-test.workspace = true
web-time.workspace = true
[[example]]
doc-scrape-examples = true

View file

@ -383,6 +383,41 @@ impl winit_wayland::EventLoopBuilderExtWayland for EventLoopBuilder {
}
}
#[cfg(web_platform)]
impl winit_web::EventLoopExtWeb for EventLoop {
fn spawn_app<A: ApplicationHandler + 'static>(self, app: A) {
self.event_loop.spawn_app(app);
}
fn set_poll_strategy(&self, strategy: winit_web::PollStrategy) {
self.event_loop.set_poll_strategy(strategy);
}
fn poll_strategy(&self) -> winit_web::PollStrategy {
self.event_loop.poll_strategy()
}
fn set_wait_until_strategy(&self, strategy: winit_web::WaitUntilStrategy) {
self.event_loop.set_wait_until_strategy(strategy);
}
fn wait_until_strategy(&self) -> winit_web::WaitUntilStrategy {
self.event_loop.wait_until_strategy()
}
fn has_multiple_screens(&self) -> Result<bool, winit_core::error::NotSupportedError> {
self.event_loop.has_multiple_screens()
}
fn request_detailed_monitor_permission(&self) -> winit_web::MonitorPermissionFuture {
self.event_loop.request_detailed_monitor_permission()
}
fn has_detailed_monitor_permission(&self) -> winit_web::HasMonitorPermissionFuture {
self.event_loop.has_detailed_monitor_permission()
}
}
#[cfg(windows_platform)]
impl winit_win32::EventLoopBuilderExtWindows for EventLoopBuilder {
#[inline]

View file

@ -15,7 +15,7 @@ pub mod startup_notify;
#[cfg(wayland_platform)]
pub use winit_wayland as wayland;
#[cfg(web_platform)]
pub mod web;
pub use winit_web as web;
#[cfg(windows_platform)]
pub use winit_win32 as windows;
#[cfg(x11_platform)]

View file

@ -9,7 +9,7 @@ pub(crate) use winit_orbital as platform;
#[cfg(ios_platform)]
pub(crate) use winit_uikit as platform;
#[cfg(web_platform)]
mod web;
pub(crate) use winit_web as platform;
#[cfg(windows_platform)]
pub(crate) use winit_win32 as platform;
@ -17,8 +17,6 @@ pub(crate) use winit_win32 as platform;
use self::linux as platform;
#[allow(unused_imports)]
pub use self::platform::*;
#[cfg(web_platform)]
use self::web as platform;
#[cfg(all(
not(ios_platform),

View file

@ -1,44 +0,0 @@
// Brief introduction to the internals of the Web backend:
// The Web backend used to support both wasm-bindgen and stdweb as methods of binding to the
// environment. Because they are both supporting the same underlying APIs, the actual Web bindings
// are cordoned off into backend abstractions, which present the thinnest unifying layer possible.
//
// When adding support for new events or interactions with the browser, first consult trusted
// documentation (such as MDN) to ensure it is well-standardised and supported across many browsers.
// Once you have decided on the relevant Web APIs, add support to both backends.
//
// The backend is used by the rest of the module to implement Winit's business logic, which forms
// the rest of the code. 'device', 'error', 'monitor', and 'window' define Web-specific structures
// for winit's cross-platform structures. They are all relatively simple translations.
//
// The event_loop module handles listening for and processing events. 'Proxy' implements
// EventLoopProxy and 'WindowTarget' implements ActiveEventLoop. WindowTarget also handles
// registering the event handlers. The 'Execution' struct in the 'runner' module handles taking
// incoming events (from the registered handlers) and ensuring they are passed to the user in a
// compliant way.
// TODO: FP, remove when <https://github.com/rust-lang/rust-clippy/issues/12377> is fixed.
#![allow(clippy::empty_docs)]
mod r#async;
mod cursor;
mod error;
mod event;
pub(crate) mod event_loop;
mod keyboard;
mod lock;
pub(crate) mod main_thread;
mod monitor;
pub(crate) mod web_sys;
pub(crate) mod window;
pub(crate) use cursor::CustomCursorFuture;
pub(crate) use self::event_loop::{
ActiveEventLoop, EventLoop, PlatformSpecificEventLoopAttributes,
};
pub(crate) use self::monitor::{
HasMonitorPermissionFuture, MonitorHandle, MonitorPermissionFuture, OrientationLockFuture,
};
use self::web_sys as backend;
pub use self::window::Window;

95
winit-web/Cargo.toml Normal file
View file

@ -0,0 +1,95 @@
[package]
description = "Winit's Web (WebAssembly) backend"
documentation = "https://docs.rs/winit-web"
edition.workspace = true
include = [
"/src",
"!/src/platform_impl/web/script",
"/src/platform_impl/web/script/**/*.min.js",
"README.md",
]
license.workspace = true
name = "winit-web"
repository.workspace = true
rust-version.workspace = true
version = "0.0.0"
[features]
serde = ["dep:serde", "bitflags/serde", "smol_str/serde", "dpi/serde"]
[dependencies]
bitflags.workspace = true
cursor-icon.workspace = true
dpi.workspace = true
rwh_06.workspace = true
serde = { workspace = true, optional = true }
smol_str.workspace = true
tracing.workspace = true
winit-core.workspace = true
# Platform-specific
js-sys.workspace = true
pin-project.workspace = true
wasm-bindgen.workspace = true
wasm-bindgen-futures.workspace = true
web-time.workspace = true
web_sys = { workspace = true, features = [
"AbortController",
"AbortSignal",
"Blob",
"BlobPropertyBag",
"console",
"CssStyleDeclaration",
"Document",
"DomException",
"DomRect",
"DomRectReadOnly",
"Element",
"Event",
"EventTarget",
"FocusEvent",
"HtmlCanvasElement",
"HtmlElement",
"HtmlHtmlElement",
"HtmlImageElement",
"ImageBitmap",
"ImageBitmapOptions",
"ImageBitmapRenderingContext",
"ImageData",
"IntersectionObserver",
"IntersectionObserverEntry",
"KeyboardEvent",
"MediaQueryList",
"MessageChannel",
"MessagePort",
"Navigator",
"Node",
"OrientationLockType",
"OrientationType",
"PageTransitionEvent",
"Permissions",
"PermissionState",
"PermissionStatus",
"PointerEvent",
"PremultiplyAlpha",
"ResizeObserver",
"ResizeObserverBoxOptions",
"ResizeObserverEntry",
"ResizeObserverOptions",
"ResizeObserverSize",
"Screen",
"ScreenOrientation",
"Url",
"VisibilityState",
"WheelEvent",
"Window",
"Worker",
] }
[target.'cfg(target_feature = "atomics")'.dependencies]
atomic-waker.workspace = true
concurrent-queue.workspace = true
[package.metadata.docs.rs]
all-features = true
targets = ["wasm32-unknown-unknown"]

1
winit-web/README.md Symbolic link
View file

@ -0,0 +1 @@
../README.md

View file

@ -21,11 +21,11 @@ use web_sys::{
};
use winit_core::cursor::{Cursor, CursorImage, CustomCursorProvider, CustomCursorSource};
use super::backend::Style;
use super::main_thread::{MainThreadMarker, MainThreadSafe};
use super::r#async::{AbortHandle, Abortable, DropAbortHandle, Notified, Notifier};
use super::ActiveEventLoop;
use crate::platform::web::CustomCursorError;
use crate::backend::Style;
use crate::event_loop::ActiveEventLoop;
use crate::main_thread::{MainThreadMarker, MainThreadSafe};
use crate::r#async::{AbortHandle, Abortable, DropAbortHandle, Notified, Notifier};
use crate::CustomCursorError;
#[derive(Clone, Debug)]
pub struct CustomCursor {

View file

@ -4,8 +4,9 @@ use winit_core::application::ApplicationHandler;
use winit_core::error::{EventLoopError, NotSupportedError};
use winit_core::event_loop::ActiveEventLoop as RootActiveEventLoop;
use super::{backend, HasMonitorPermissionFuture, MonitorPermissionFuture};
use crate::platform::web::{PollStrategy, WaitUntilStrategy};
use crate::{
backend, HasMonitorPermissionFuture, MonitorPermissionFuture, PollStrategy, WaitUntilStrategy,
};
mod proxy;
pub(crate) mod runner;
@ -20,12 +21,12 @@ pub struct EventLoop {
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) struct PlatformSpecificEventLoopAttributes {}
pub struct PlatformSpecificEventLoopAttributes {}
static EVENT_LOOP_CREATED: AtomicBool = AtomicBool::new(false);
impl EventLoop {
pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Result<Self, EventLoopError> {
pub fn new(_: &PlatformSpecificEventLoopAttributes) -> Result<Self, EventLoopError> {
if EVENT_LOOP_CREATED.swap(true, Ordering::Relaxed) {
// For better cross-platformness.
return Err(EventLoopError::RecreationAttempt);
@ -90,11 +91,13 @@ impl EventLoop {
self.elw.has_multiple_screens()
}
pub(crate) fn request_detailed_monitor_permission(&self) -> MonitorPermissionFuture {
self.elw.request_detailed_monitor_permission()
pub fn request_detailed_monitor_permission(&self) -> MonitorPermissionFuture {
MonitorPermissionFuture(self.elw.request_detailed_monitor_permission())
}
pub fn has_detailed_monitor_permission(&self) -> HasMonitorPermissionFuture {
self.elw.runner.monitor().has_detailed_monitor_permission_async()
HasMonitorPermissionFuture(
self.elw.runner.monitor().has_detailed_monitor_permission_async(),
)
}
}

View file

@ -6,8 +6,8 @@ use std::task::Poll;
use winit_core::event_loop::EventLoopProxyProvider;
use super::super::main_thread::MainThreadMarker;
use crate::platform_impl::web::event_loop::runner::WeakShared;
use crate::platform_impl::web::r#async::{AtomicWaker, Wrapper};
use crate::event_loop::runner::WeakShared;
use crate::r#async::{AtomicWaker, Wrapper};
#[derive(Debug)]
pub struct EventLoopProxy(Wrapper<WeakShared, Arc<State>, ()>);

View file

@ -17,17 +17,16 @@ use winit_core::event::{
use winit_core::event_loop::{ControlFlow, DeviceEvents};
use winit_core::window::WindowId;
use super::super::event;
use super::super::main_thread::MainThreadMarker;
use super::super::monitor::MonitorHandler;
use super::proxy::EventLoopProxy;
use super::state::State;
use super::{backend, ActiveEventLoop, EventLoop};
use crate::platform::web::{PollStrategy, WaitUntilStrategy};
use crate::platform_impl::platform::backend::{EventListenerHandle, SafeAreaHandle};
use crate::platform_impl::platform::r#async::DispatchRunner;
use crate::platform_impl::platform::window::Inner;
use crate::platform_impl::web::web_sys::event::mouse_button_to_id;
use crate::backend::{EventListenerHandle, SafeAreaHandle};
use crate::event_loop::ActiveEventLoop;
use crate::main_thread::MainThreadMarker;
use crate::monitor::MonitorHandler;
use crate::r#async::DispatchRunner;
use crate::web_sys::event::mouse_button_to_id;
use crate::window::Inner;
use crate::{backend, event, EventLoop, PollStrategy, WaitUntilStrategy};
#[derive(Debug)]
pub struct Shared(Rc<Execution>);

View file

@ -21,10 +21,10 @@ use super::super::lock;
use super::super::monitor::MonitorPermissionFuture;
use super::runner::Event;
use super::{backend, runner};
use crate::platform::web::{CustomCursorFuture, PollStrategy, WaitUntilStrategy};
use crate::platform_impl::platform::cursor::CustomCursor;
use crate::platform_impl::web::event_loop::proxy::EventLoopProxy;
use crate::platform_impl::Window;
use crate::cursor::CustomCursor;
use crate::event_loop::proxy::EventLoopProxy;
use crate::window::Window;
use crate::{CustomCursorFuture, PollStrategy, WaitUntilStrategy};
#[derive(Default, Debug)]
struct ModifiersShared(Rc<Cell<ModifiersState>>);

View file

@ -16,7 +16,7 @@
//! [with_canvas]: WindowAttributesWeb::with_canvas
//! [get]: WindowExtWeb::canvas
//! [insert]: WindowAttributesWeb::with_append
#![cfg_attr(not(web_platform), doc = "[wasm_bindgen]: https://docs.rs/wasm-bindgen")]
//! [wasm_bindgen]: https://docs.rs/wasm-bindgen
//! [Rust and WebAssembly book]: https://rustwasm.github.io/book
//!
//! ## CSS properties
@ -41,6 +41,43 @@
//! [`WindowEvent::PointerLeft`]: crate::event::WindowEvent::PointerLeft
//! [`Window::set_outer_position()`]: crate::window::Window::set_outer_position
// Brief introduction to the internals of the Web backend:
// The Web backend used to support both wasm-bindgen and stdweb as methods of binding to the
// environment. Because they are both supporting the same underlying APIs, the actual Web bindings
// are cordoned off into backend abstractions, which present the thinnest unifying layer possible.
//
// When adding support for new events or interactions with the browser, first consult trusted
// documentation (such as MDN) to ensure it is well-standardised and supported across many browsers.
// Once you have decided on the relevant Web APIs, add support to both backends.
//
// The backend is used by the rest of the module to implement Winit's business logic, which forms
// the rest of the code. 'device', 'error', 'monitor', and 'window' define Web-specific structures
// for winit's cross-platform structures. They are all relatively simple translations.
//
// The event_loop module handles listening for and processing events. 'Proxy' implements
// EventLoopProxy and 'WindowTarget' implements ActiveEventLoop. WindowTarget also handles
// registering the event handlers. The 'Execution' struct in the 'runner' module handles taking
// incoming events (from the registered handlers) and ensuring they are passed to the user in a
// compliant way.
macro_rules! os_error {
($error:expr) => {{
winit_core::error::OsError::new(line!(), file!(), $error)
}};
}
mod r#async;
mod cursor;
mod error;
mod event;
pub(crate) mod event_loop;
mod keyboard;
mod lock;
pub(crate) mod main_thread;
mod monitor;
pub(crate) mod web_sys;
pub(crate) mod window;
use std::cell::Ref;
use std::error::Error;
use std::fmt::{self, Display, Formatter};
@ -49,31 +86,27 @@ use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};
use ::web_sys::HtmlCanvasElement;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(web_platform)]
use web_sys::HtmlCanvasElement;
use winit_core::window::PlatformWindowAttributes;
use winit_core::application::ApplicationHandler;
use winit_core::cursor::{CustomCursor, CustomCursorSource};
use winit_core::error::NotSupportedError;
use winit_core::event_loop::ActiveEventLoop;
use winit_core::monitor::MonitorHandleProvider;
use winit_core::window::{PlatformWindowAttributes, Window};
use crate::application::ApplicationHandler;
use crate::cursor::{CustomCursor, CustomCursorSource};
use crate::error::NotSupportedError;
use crate::event_loop::{ActiveEventLoop, EventLoop};
use crate::monitor::MonitorHandleProvider;
use crate::platform_impl::main_thread::{MainThreadMarker, MainThreadSafe};
use crate::platform_impl::{web_sys as backend, MonitorHandle as WebMonitorHandle};
#[cfg(web_platform)]
use crate::platform_impl::{
CustomCursorFuture as PlatformCustomCursorFuture,
pub use self::event_loop::{EventLoop, PlatformSpecificEventLoopAttributes};
use self::web_sys as backend;
use self::window::Window as WebWindow;
use crate::cursor::CustomCursorFuture as PlatformCustomCursorFuture;
use crate::event_loop::ActiveEventLoop as WebActiveEventLoop;
use crate::main_thread::{MainThreadMarker, MainThreadSafe};
use crate::monitor::{
HasMonitorPermissionFuture as PlatformHasMonitorPermissionFuture,
MonitorPermissionFuture as PlatformMonitorPermissionFuture,
MonitorHandle as WebMonitorHandle, MonitorPermissionFuture as PlatformMonitorPermissionFuture,
OrientationLockFuture as PlatformOrientationLockFuture,
};
use crate::window::Window;
#[cfg(not(web_platform))]
#[doc(hidden)]
pub struct HtmlCanvasElement;
pub trait WindowExtWeb {
/// Only returns the canvas if called from inside the window context (the
@ -107,25 +140,21 @@ pub trait WindowExtWeb {
impl WindowExtWeb for dyn Window + '_ {
#[inline]
fn canvas(&self) -> Option<Ref<'_, HtmlCanvasElement>> {
self.cast_ref::<crate::platform_impl::Window>().expect("non Web window on Web").canvas()
self.cast_ref::<WebWindow>().expect("non Web window on Web").canvas()
}
fn prevent_default(&self) -> bool {
self.cast_ref::<crate::platform_impl::Window>()
.expect("non Web window on Web")
.prevent_default()
self.cast_ref::<WebWindow>().expect("non Web window on Web").prevent_default()
}
fn set_prevent_default(&self, prevent_default: bool) {
self.cast_ref::<crate::platform_impl::Window>()
self.cast_ref::<WebWindow>()
.expect("non Web window on Web")
.set_prevent_default(prevent_default)
}
fn is_cursor_lock_raw(&self) -> bool {
self.cast_ref::<crate::platform_impl::Window>()
.expect("non Web window on Web")
.is_cursor_lock_raw()
self.cast_ref::<WebWindow>().expect("non Web window on Web").is_cursor_lock_raw()
}
}
@ -144,7 +173,6 @@ impl WindowAttributesWeb {
/// In any case, the canvas won't be automatically inserted into the Web page.
///
/// [`None`] by default.
#[cfg_attr(not(web_platform), doc = "", doc = "[`HtmlCanvasElement`]: #only-available-on-wasm")]
pub fn with_canvas(mut self, canvas: Option<HtmlCanvasElement>) -> Self {
match canvas {
Some(canvas) => {
@ -216,9 +244,9 @@ pub trait EventLoopExtWeb {
/// Initializes the winit event loop.
///
/// Unlike
#[cfg_attr(all(web_platform, target_feature = "exception-handling"), doc = "`run_app()`")]
#[cfg_attr(target_feature = "exception-handling", doc = "`run_app()`")]
#[cfg_attr(
not(all(web_platform, target_feature = "exception-handling")),
not(target_feature = "exception-handling"),
doc = "[`run_app()`]"
)]
/// [^1], this returns immediately, and doesn't throw an exception in order to
@ -231,7 +259,7 @@ pub trait EventLoopExtWeb {
#[rustfmt::skip]
///
#[cfg_attr(
not(all(web_platform, target_feature = "exception-handling")),
not(target_feature = "exception-handling"),
doc = "[`run_app()`]: EventLoop::run_app()"
)]
/// [^1]: `run_app()` is _not_ available on Wasm when the target supports `exception-handling`.
@ -294,40 +322,6 @@ pub trait EventLoopExtWeb {
fn has_detailed_monitor_permission(&self) -> HasMonitorPermissionFuture;
}
impl EventLoopExtWeb for EventLoop {
fn spawn_app<A: ApplicationHandler + 'static>(self, app: A) {
self.event_loop.spawn_app(app);
}
fn set_poll_strategy(&self, strategy: PollStrategy) {
self.event_loop.set_poll_strategy(strategy);
}
fn poll_strategy(&self) -> PollStrategy {
self.event_loop.poll_strategy()
}
fn set_wait_until_strategy(&self, strategy: WaitUntilStrategy) {
self.event_loop.set_wait_until_strategy(strategy);
}
fn wait_until_strategy(&self) -> WaitUntilStrategy {
self.event_loop.wait_until_strategy()
}
fn has_multiple_screens(&self) -> Result<bool, NotSupportedError> {
self.event_loop.has_multiple_screens()
}
fn request_detailed_monitor_permission(&self) -> MonitorPermissionFuture {
MonitorPermissionFuture(self.event_loop.request_detailed_monitor_permission())
}
fn has_detailed_monitor_permission(&self) -> HasMonitorPermissionFuture {
HasMonitorPermissionFuture(self.event_loop.has_detailed_monitor_permission())
}
}
pub trait ActiveEventLoopExtWeb {
/// Sets the strategy for [`ControlFlow::Poll`].
///
@ -396,73 +390,55 @@ pub trait ActiveEventLoopExtWeb {
impl ActiveEventLoopExtWeb for dyn ActiveEventLoop + '_ {
#[inline]
fn create_custom_cursor_async(&self, source: CustomCursorSource) -> CustomCursorFuture {
let event_loop = self
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
.expect("non Web event loop on Web");
let event_loop = self.cast_ref::<WebActiveEventLoop>().expect("non Web event loop on Web");
event_loop.create_custom_cursor_async(source)
}
#[inline]
fn set_poll_strategy(&self, strategy: PollStrategy) {
let event_loop = self
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
.expect("non Web event loop on Web");
let event_loop = self.cast_ref::<WebActiveEventLoop>().expect("non Web event loop on Web");
event_loop.set_poll_strategy(strategy);
}
#[inline]
fn poll_strategy(&self) -> PollStrategy {
let event_loop = self
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
.expect("non Web event loop on Web");
let event_loop = self.cast_ref::<WebActiveEventLoop>().expect("non Web event loop on Web");
event_loop.poll_strategy()
}
#[inline]
fn set_wait_until_strategy(&self, strategy: WaitUntilStrategy) {
let event_loop = self
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
.expect("non Web event loop on Web");
let event_loop = self.cast_ref::<WebActiveEventLoop>().expect("non Web event loop on Web");
event_loop.set_wait_until_strategy(strategy);
}
#[inline]
fn wait_until_strategy(&self) -> WaitUntilStrategy {
let event_loop = self
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
.expect("non Web event loop on Web");
let event_loop = self.cast_ref::<WebActiveEventLoop>().expect("non Web event loop on Web");
event_loop.wait_until_strategy()
}
#[inline]
fn is_cursor_lock_raw(&self) -> bool {
let event_loop = self
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
.expect("non Web event loop on Web");
let event_loop = self.cast_ref::<WebActiveEventLoop>().expect("non Web event loop on Web");
event_loop.is_cursor_lock_raw()
}
#[inline]
fn has_multiple_screens(&self) -> Result<bool, NotSupportedError> {
let event_loop = self
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
.expect("non Web event loop on Web");
let event_loop = self.cast_ref::<WebActiveEventLoop>().expect("non Web event loop on Web");
event_loop.has_multiple_screens()
}
#[inline]
fn request_detailed_monitor_permission(&self) -> MonitorPermissionFuture {
let event_loop = self
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
.expect("non Web event loop on Web");
let event_loop = self.cast_ref::<WebActiveEventLoop>().expect("non Web event loop on Web");
MonitorPermissionFuture(event_loop.request_detailed_monitor_permission())
}
#[inline]
fn has_detailed_monitor_permission(&self) -> bool {
let event_loop = self
.cast_ref::<crate::platform_impl::ActiveEventLoop>()
.expect("non Web event loop on Web");
let event_loop = self.cast_ref::<WebActiveEventLoop>().expect("non Web event loop on Web");
event_loop.has_detailed_monitor_permission()
}
}
@ -518,9 +494,6 @@ pub enum WaitUntilStrategy {
Worker,
}
#[cfg(not(web_platform))]
struct PlatformCustomCursorFuture;
#[derive(Debug)]
pub struct CustomCursorFuture(pub(crate) PlatformCustomCursorFuture);
@ -550,9 +523,6 @@ impl Display for CustomCursorError {
impl Error for CustomCursorError {}
#[cfg(not(web_platform))]
struct PlatformMonitorPermissionFuture;
/// Can be dropped without aborting the request for detailed monitor permissions.
#[derive(Debug)]
pub struct MonitorPermissionFuture(pub(crate) PlatformMonitorPermissionFuture);
@ -595,9 +565,6 @@ impl Display for MonitorPermissionError {
impl Error for MonitorPermissionError {}
#[cfg(not(web_platform))]
struct PlatformHasMonitorPermissionFuture;
#[derive(Debug)]
pub struct HasMonitorPermissionFuture(PlatformHasMonitorPermissionFuture);
@ -713,9 +680,6 @@ pub enum OrientationLock {
},
}
#[cfg(not(web_platform))]
struct PlatformOrientationLockFuture;
/// Can be dropped without aborting the request to lock the screen.
#[derive(Debug)]
pub struct OrientationLockFuture(PlatformOrientationLockFuture);

View file

@ -28,7 +28,7 @@ use super::event_loop::runner::WeakShared;
use super::main_thread::MainThreadMarker;
use super::r#async::{Dispatcher, Notified, Notifier};
use super::web_sys::{Engine, EventListenerHandle};
use crate::platform::web::{
use crate::{
MonitorPermissionError, Orientation, OrientationData, OrientationLock, OrientationLockError,
};

View file

@ -29,7 +29,7 @@ use super::intersection_handle::IntersectionObserverHandle;
use super::media_query_handle::MediaQueryListHandle;
use super::pointer::PointerHandler;
use super::{event, fullscreen, ResizeScaleHandle};
use crate::platform::web::WindowAttributesWeb;
use crate::WindowAttributesWeb;
#[allow(dead_code)]
pub struct Canvas {

View file

@ -9,7 +9,7 @@ use winit_core::event::{FingerId, MouseButton, MouseScrollDelta, PointerKind};
use winit_core::keyboard::{Key, KeyLocation, ModifiersState, NamedKey, PhysicalKey};
use super::Engine;
use crate::platform_impl::web::keyboard::FromAttributeValue;
use crate::keyboard::FromAttributeValue;
bitflags::bitflags! {
// https://www.w3.org/TR/pointerevents3/#the-buttons-property

View file

@ -8,9 +8,8 @@ use wasm_bindgen::{JsCast, JsValue};
use web_sys::{console, Document, Element, HtmlCanvasElement, Window};
use winit_core::monitor::Fullscreen;
use super::super::main_thread::MainThreadMarker;
use super::super::monitor::{self, ScreenDetailed};
use crate::platform_impl::MonitorHandle;
use crate::main_thread::MainThreadMarker;
use crate::monitor::{self, MonitorHandle, ScreenDetailed};
pub(crate) fn request_fullscreen(
main_thread: MainThreadMarker,

View file

@ -9,8 +9,8 @@ use winit_core::keyboard::ModifiersState;
use super::canvas::Common;
use super::event;
use super::event_handle::EventListenerHandle;
use crate::platform_impl::web::event::mkdid;
use crate::platform_impl::web::web_sys::event::mouse_button_to_id;
use crate::event::mkdid;
use crate::web_sys::event::mouse_button_to_id;
#[allow(dead_code)]
pub(super) struct PointerHandler {

View file

@ -9,7 +9,7 @@ use web_sys::{
AbortController, AbortSignal, Blob, BlobPropertyBag, MessageChannel, MessagePort, Url, Worker,
};
use crate::platform::web::{PollStrategy, WaitUntilStrategy};
use crate::{PollStrategy, WaitUntilStrategy};
#[derive(Debug)]
pub struct Schedule {

View file

@ -16,10 +16,11 @@ use winit_core::window::{
WindowAttributes, WindowButtons, WindowId, WindowLevel,
};
use super::main_thread::MainThreadMarker;
use super::monitor::MonitorHandler;
use super::r#async::Dispatcher;
use super::{backend, lock, ActiveEventLoop};
use crate::event_loop::ActiveEventLoop;
use crate::main_thread::MainThreadMarker;
use crate::monitor::MonitorHandler;
use crate::r#async::Dispatcher;
use crate::{backend, lock};
pub struct Window {
inner: Dispatcher<Inner>,