diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index aee97375..2b6b702c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea2065b5..4b0bb580 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/Cargo.toml b/Cargo.toml index f0f485f7..c7a4ec83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 diff --git a/src/event_loop.rs b/src/event_loop.rs index dbd167cb..fc3e15ad 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -383,6 +383,41 @@ impl winit_wayland::EventLoopBuilderExtWayland for EventLoopBuilder { } } +#[cfg(web_platform)] +impl winit_web::EventLoopExtWeb for EventLoop { + fn spawn_app(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 { + 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] diff --git a/src/platform/mod.rs b/src/platform/mod.rs index d0f96d84..14e215a0 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -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)] diff --git a/src/platform_impl/mod.rs b/src/platform_impl/mod.rs index 77439441..e20f7674 100644 --- a/src/platform_impl/mod.rs +++ b/src/platform_impl/mod.rs @@ -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), diff --git a/src/platform_impl/web/mod.rs b/src/platform_impl/web/mod.rs deleted file mode 100644 index 7c98b106..00000000 --- a/src/platform_impl/web/mod.rs +++ /dev/null @@ -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 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; diff --git a/winit-web/Cargo.toml b/winit-web/Cargo.toml new file mode 100644 index 00000000..bde7e1c9 --- /dev/null +++ b/winit-web/Cargo.toml @@ -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"] diff --git a/winit-web/README.md b/winit-web/README.md new file mode 120000 index 00000000..32d46ee8 --- /dev/null +++ b/winit-web/README.md @@ -0,0 +1 @@ +../README.md \ No newline at end of file diff --git a/src/platform_impl/web/async/abortable.rs b/winit-web/src/async/abortable.rs similarity index 100% rename from src/platform_impl/web/async/abortable.rs rename to winit-web/src/async/abortable.rs diff --git a/src/platform_impl/web/async/atomic_waker.rs b/winit-web/src/async/atomic_waker.rs similarity index 100% rename from src/platform_impl/web/async/atomic_waker.rs rename to winit-web/src/async/atomic_waker.rs diff --git a/src/platform_impl/web/async/channel.rs b/winit-web/src/async/channel.rs similarity index 100% rename from src/platform_impl/web/async/channel.rs rename to winit-web/src/async/channel.rs diff --git a/src/platform_impl/web/async/concurrent_queue.rs b/winit-web/src/async/concurrent_queue.rs similarity index 100% rename from src/platform_impl/web/async/concurrent_queue.rs rename to winit-web/src/async/concurrent_queue.rs diff --git a/src/platform_impl/web/async/dispatcher.rs b/winit-web/src/async/dispatcher.rs similarity index 100% rename from src/platform_impl/web/async/dispatcher.rs rename to winit-web/src/async/dispatcher.rs diff --git a/src/platform_impl/web/async/mod.rs b/winit-web/src/async/mod.rs similarity index 100% rename from src/platform_impl/web/async/mod.rs rename to winit-web/src/async/mod.rs diff --git a/src/platform_impl/web/async/notifier.rs b/winit-web/src/async/notifier.rs similarity index 100% rename from src/platform_impl/web/async/notifier.rs rename to winit-web/src/async/notifier.rs diff --git a/src/platform_impl/web/async/wrapper.rs b/winit-web/src/async/wrapper.rs similarity index 100% rename from src/platform_impl/web/async/wrapper.rs rename to winit-web/src/async/wrapper.rs diff --git a/src/platform_impl/web/cursor.rs b/winit-web/src/cursor.rs similarity index 99% rename from src/platform_impl/web/cursor.rs rename to winit-web/src/cursor.rs index 8d182d85..d5035481 100644 --- a/src/platform_impl/web/cursor.rs +++ b/winit-web/src/cursor.rs @@ -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 { diff --git a/src/platform_impl/web/error.rs b/winit-web/src/error.rs similarity index 100% rename from src/platform_impl/web/error.rs rename to winit-web/src/error.rs diff --git a/src/platform_impl/web/event.rs b/winit-web/src/event.rs similarity index 100% rename from src/platform_impl/web/event.rs rename to winit-web/src/event.rs diff --git a/src/platform_impl/web/event_loop/mod.rs b/winit-web/src/event_loop/mod.rs similarity index 83% rename from src/platform_impl/web/event_loop/mod.rs rename to winit-web/src/event_loop/mod.rs index db6d87e9..35f64412 100644 --- a/src/platform_impl/web/event_loop/mod.rs +++ b/winit-web/src/event_loop/mod.rs @@ -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 { + pub fn new(_: &PlatformSpecificEventLoopAttributes) -> Result { 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(), + ) } } diff --git a/src/platform_impl/web/event_loop/proxy.rs b/winit-web/src/event_loop/proxy.rs similarity index 95% rename from src/platform_impl/web/event_loop/proxy.rs rename to winit-web/src/event_loop/proxy.rs index 4f987ef0..b5092c7a 100644 --- a/src/platform_impl/web/event_loop/proxy.rs +++ b/winit-web/src/event_loop/proxy.rs @@ -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, ()>); diff --git a/src/platform_impl/web/event_loop/runner.rs b/winit-web/src/event_loop/runner.rs similarity index 98% rename from src/platform_impl/web/event_loop/runner.rs rename to winit-web/src/event_loop/runner.rs index f6a6e426..4aeaf383 100644 --- a/src/platform_impl/web/event_loop/runner.rs +++ b/winit-web/src/event_loop/runner.rs @@ -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); diff --git a/src/platform_impl/web/event_loop/state.rs b/winit-web/src/event_loop/state.rs similarity index 100% rename from src/platform_impl/web/event_loop/state.rs rename to winit-web/src/event_loop/state.rs diff --git a/src/platform_impl/web/event_loop/window_target.rs b/winit-web/src/event_loop/window_target.rs similarity index 98% rename from src/platform_impl/web/event_loop/window_target.rs rename to winit-web/src/event_loop/window_target.rs index 619c2644..84c080e8 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/winit-web/src/event_loop/window_target.rs @@ -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>); diff --git a/src/platform_impl/web/keyboard.rs b/winit-web/src/keyboard.rs similarity index 100% rename from src/platform_impl/web/keyboard.rs rename to winit-web/src/keyboard.rs diff --git a/src/platform/web.rs b/winit-web/src/lib.rs similarity index 85% rename from src/platform/web.rs rename to winit-web/src/lib.rs index 51971bcd..bff8ebfb 100644 --- a/src/platform/web.rs +++ b/winit-web/src/lib.rs @@ -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> { - self.cast_ref::().expect("non Web window on Web").canvas() + self.cast_ref::().expect("non Web window on Web").canvas() } fn prevent_default(&self) -> bool { - self.cast_ref::() - .expect("non Web window on Web") - .prevent_default() + self.cast_ref::().expect("non Web window on Web").prevent_default() } fn set_prevent_default(&self, prevent_default: bool) { - self.cast_ref::() + self.cast_ref::() .expect("non Web window on Web") .set_prevent_default(prevent_default) } fn is_cursor_lock_raw(&self) -> bool { - self.cast_ref::() - .expect("non Web window on Web") - .is_cursor_lock_raw() + self.cast_ref::().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) -> 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(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 { - 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::() - .expect("non Web event loop on Web"); + let event_loop = self.cast_ref::().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::() - .expect("non Web event loop on Web"); + let event_loop = self.cast_ref::().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::() - .expect("non Web event loop on Web"); + let event_loop = self.cast_ref::().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::() - .expect("non Web event loop on Web"); + let event_loop = self.cast_ref::().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::() - .expect("non Web event loop on Web"); + let event_loop = self.cast_ref::().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::() - .expect("non Web event loop on Web"); + let event_loop = self.cast_ref::().expect("non Web event loop on Web"); event_loop.is_cursor_lock_raw() } #[inline] fn has_multiple_screens(&self) -> Result { - let event_loop = self - .cast_ref::() - .expect("non Web event loop on Web"); + let event_loop = self.cast_ref::().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::() - .expect("non Web event loop on Web"); + let event_loop = self.cast_ref::().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::() - .expect("non Web event loop on Web"); + let event_loop = self.cast_ref::().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); diff --git a/src/platform_impl/web/lock.rs b/winit-web/src/lock.rs similarity index 100% rename from src/platform_impl/web/lock.rs rename to winit-web/src/lock.rs diff --git a/src/platform_impl/web/main_thread.rs b/winit-web/src/main_thread.rs similarity index 100% rename from src/platform_impl/web/main_thread.rs rename to winit-web/src/main_thread.rs diff --git a/src/platform_impl/web/monitor.rs b/winit-web/src/monitor.rs similarity index 99% rename from src/platform_impl/web/monitor.rs rename to winit-web/src/monitor.rs index 56f4e7f2..102ba488 100644 --- a/src/platform_impl/web/monitor.rs +++ b/winit-web/src/monitor.rs @@ -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, }; diff --git a/src/platform_impl/web/script/.swcrc b/winit-web/src/script/.swcrc similarity index 100% rename from src/platform_impl/web/script/.swcrc rename to winit-web/src/script/.swcrc diff --git a/src/platform_impl/web/script/eslint.config.mjs b/winit-web/src/script/eslint.config.mjs similarity index 100% rename from src/platform_impl/web/script/eslint.config.mjs rename to winit-web/src/script/eslint.config.mjs diff --git a/src/platform_impl/web/script/package.json b/winit-web/src/script/package.json similarity index 100% rename from src/platform_impl/web/script/package.json rename to winit-web/src/script/package.json diff --git a/src/platform_impl/web/script/scheduler.d.ts b/winit-web/src/script/scheduler.d.ts similarity index 100% rename from src/platform_impl/web/script/scheduler.d.ts rename to winit-web/src/script/scheduler.d.ts diff --git a/src/platform_impl/web/script/tsconfig.json b/winit-web/src/script/tsconfig.json similarity index 100% rename from src/platform_impl/web/script/tsconfig.json rename to winit-web/src/script/tsconfig.json diff --git a/src/platform_impl/web/script/worker.min.js b/winit-web/src/script/worker.min.js similarity index 100% rename from src/platform_impl/web/script/worker.min.js rename to winit-web/src/script/worker.min.js diff --git a/src/platform_impl/web/script/worker.ts b/winit-web/src/script/worker.ts similarity index 100% rename from src/platform_impl/web/script/worker.ts rename to winit-web/src/script/worker.ts diff --git a/src/platform_impl/web/web_sys/animation_frame.rs b/winit-web/src/web_sys/animation_frame.rs similarity index 100% rename from src/platform_impl/web/web_sys/animation_frame.rs rename to winit-web/src/web_sys/animation_frame.rs diff --git a/src/platform_impl/web/web_sys/canvas.rs b/winit-web/src/web_sys/canvas.rs similarity index 99% rename from src/platform_impl/web/web_sys/canvas.rs rename to winit-web/src/web_sys/canvas.rs index b2933d6b..3a9f8ae5 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/winit-web/src/web_sys/canvas.rs @@ -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 { diff --git a/src/platform_impl/web/web_sys/event.rs b/winit-web/src/web_sys/event.rs similarity index 99% rename from src/platform_impl/web/web_sys/event.rs rename to winit-web/src/web_sys/event.rs index 448c259d..849dff92 100644 --- a/src/platform_impl/web/web_sys/event.rs +++ b/winit-web/src/web_sys/event.rs @@ -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 diff --git a/src/platform_impl/web/web_sys/event_handle.rs b/winit-web/src/web_sys/event_handle.rs similarity index 100% rename from src/platform_impl/web/web_sys/event_handle.rs rename to winit-web/src/web_sys/event_handle.rs diff --git a/src/platform_impl/web/web_sys/fullscreen.rs b/winit-web/src/web_sys/fullscreen.rs similarity index 97% rename from src/platform_impl/web/web_sys/fullscreen.rs rename to winit-web/src/web_sys/fullscreen.rs index ba735fd9..9f3baf93 100644 --- a/src/platform_impl/web/web_sys/fullscreen.rs +++ b/winit-web/src/web_sys/fullscreen.rs @@ -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, diff --git a/src/platform_impl/web/web_sys/intersection_handle.rs b/winit-web/src/web_sys/intersection_handle.rs similarity index 100% rename from src/platform_impl/web/web_sys/intersection_handle.rs rename to winit-web/src/web_sys/intersection_handle.rs diff --git a/src/platform_impl/web/web_sys/media_query_handle.rs b/winit-web/src/web_sys/media_query_handle.rs similarity index 100% rename from src/platform_impl/web/web_sys/media_query_handle.rs rename to winit-web/src/web_sys/media_query_handle.rs diff --git a/src/platform_impl/web/web_sys/mod.rs b/winit-web/src/web_sys/mod.rs similarity index 100% rename from src/platform_impl/web/web_sys/mod.rs rename to winit-web/src/web_sys/mod.rs diff --git a/src/platform_impl/web/web_sys/pointer.rs b/winit-web/src/web_sys/pointer.rs similarity index 98% rename from src/platform_impl/web/web_sys/pointer.rs rename to winit-web/src/web_sys/pointer.rs index 6d5fa9f8..0187947e 100644 --- a/src/platform_impl/web/web_sys/pointer.rs +++ b/winit-web/src/web_sys/pointer.rs @@ -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 { diff --git a/src/platform_impl/web/web_sys/resize_scaling.rs b/winit-web/src/web_sys/resize_scaling.rs similarity index 100% rename from src/platform_impl/web/web_sys/resize_scaling.rs rename to winit-web/src/web_sys/resize_scaling.rs diff --git a/src/platform_impl/web/web_sys/safe_area.rs b/winit-web/src/web_sys/safe_area.rs similarity index 100% rename from src/platform_impl/web/web_sys/safe_area.rs rename to winit-web/src/web_sys/safe_area.rs diff --git a/src/platform_impl/web/web_sys/schedule.rs b/winit-web/src/web_sys/schedule.rs similarity index 99% rename from src/platform_impl/web/web_sys/schedule.rs rename to winit-web/src/web_sys/schedule.rs index f51a311c..4cacf2bc 100644 --- a/src/platform_impl/web/web_sys/schedule.rs +++ b/winit-web/src/web_sys/schedule.rs @@ -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 { diff --git a/src/platform_impl/web/window.rs b/winit-web/src/window.rs similarity index 98% rename from src/platform_impl/web/window.rs rename to winit-web/src/window.rs index 7d339310..b6e21215 100644 --- a/src/platform_impl/web/window.rs +++ b/winit-web/src/window.rs @@ -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,