diff --git a/CHANGELOG.md b/CHANGELOG.md index 5be8107c..b0d0aa4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # Unreleased +- Add web support via the 'stdweb' or 'web-sys' features - On macOS, implement `run_return`. - On iOS, fix inverted parameter in `set_prefers_home_indicator_hidden`. diff --git a/src/dpi.rs b/src/dpi.rs index 9c89c12c..99848ae9 100644 --- a/src/dpi.rs +++ b/src/dpi.rs @@ -55,6 +55,7 @@ //! - **Wayland:** On Wayland, DPI factors are set per-screen by the server, and are always integers (most often 1 or 2). //! - **iOS:** DPI factors are both constant and device-specific on iOS. //! - **Android:** This feature isn't yet implemented on Android, so the DPI factor will always be returned as 1.0. +//! - **Web:** DPI factors are handled by the browser and will always be 1.0 for your application. //! //! The window's logical size is conserved across DPI changes, resulting in the physical size changing instead. This //! may be surprising on X11, but is quite standard elsewhere. Physical size changes always produce a diff --git a/src/monitor.rs b/src/monitor.rs index 8e085a58..6db5f12b 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -145,12 +145,20 @@ impl MonitorHandle { /// Returns a human-readable name of the monitor. /// /// Returns `None` if the monitor doesn't exist anymore. + /// + /// ## Platform-specific + /// + /// - **Web:** Always returns None #[inline] pub fn name(&self) -> Option { self.inner.name() } /// Returns the monitor's resolution. + /// + /// ## Platform-specific + /// + /// - **Web:** Always returns (0,0) #[inline] pub fn size(&self) -> PhysicalSize { self.inner.size() @@ -158,6 +166,10 @@ impl MonitorHandle { /// Returns the top-left corner position of the monitor relative to the larger full /// screen area. + /// + /// ## Platform-specific + /// + /// - **Web:** Always returns (0,0) #[inline] pub fn position(&self) -> PhysicalPosition { self.inner.position() @@ -171,12 +183,17 @@ impl MonitorHandle { /// /// - **X11:** Can be overridden using the `WINIT_HIDPI_FACTOR` environment variable. /// - **Android:** Always returns 1.0. + /// - **Web:** Always returns 1.0 #[inline] pub fn hidpi_factor(&self) -> f64 { self.inner.hidpi_factor() } /// Returns all fullscreen video modes supported by this monitor. + /// + /// ## Platform-specific + /// + /// - **Web:** Always returns an empty iterator #[inline] pub fn video_modes(&self) -> impl Iterator { self.inner.video_modes() diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 01125fbb..27ecde18 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -7,6 +7,7 @@ //! - `macos` //! - `unix` //! - `windows` +//! - `web` //! //! And the following platform-specific module: //! diff --git a/src/platform/web.rs b/src/platform/web.rs index 6a1a98cd..5fca0c42 100644 --- a/src/platform/web.rs +++ b/src/platform/web.rs @@ -1,5 +1,10 @@ #![cfg(target_arch = "wasm32")] +//! The web target does not automatically insert the canvas element object into the web page, to +//! allow end users to determine how the page should be laid out. Use the `WindowExtStdweb` or +//! `WindowExtWebSys` traits (depending on your web backend) to retrieve the canvas from the +//! Window. + #[cfg(feature = "stdweb")] use stdweb::web::html_element::CanvasElement; diff --git a/src/platform_impl/web/event_loop/proxy.rs b/src/platform_impl/web/event_loop/proxy.rs index ad9a35f7..e98585a3 100644 --- a/src/platform_impl/web/event_loop/proxy.rs +++ b/src/platform_impl/web/event_loop/proxy.rs @@ -2,7 +2,7 @@ use super::runner; use crate::event::Event; use crate::event_loop::EventLoopClosed; -pub struct Proxy{ +pub struct Proxy { runner: runner::Shared, } @@ -20,7 +20,7 @@ impl Proxy { impl Clone for Proxy { fn clone(&self) -> Self { Proxy { - runner: self.runner.clone() + runner: self.runner.clone(), } } } diff --git a/src/platform_impl/web/mod.rs b/src/platform_impl/web/mod.rs index a272835d..44d4fc19 100644 --- a/src/platform_impl/web/mod.rs +++ b/src/platform_impl/web/mod.rs @@ -21,9 +21,7 @@ pub use self::error::OsError; pub use self::event_loop::{ EventLoop, Proxy as EventLoopProxy, WindowTarget as EventLoopWindowTarget, }; -pub use self::monitor::{ - Handle as MonitorHandle, Mode as VideoMode -}; +pub use self::monitor::{Handle as MonitorHandle, Mode as VideoMode}; pub use self::window::{ Id as WindowId, PlatformSpecificBuilderAttributes as PlatformSpecificWindowBuilderAttributes, Window, diff --git a/src/platform_impl/web/monitor.rs b/src/platform_impl/web/monitor.rs index 196c23c8..0bec465a 100644 --- a/src/platform_impl/web/monitor.rs +++ b/src/platform_impl/web/monitor.rs @@ -10,19 +10,21 @@ impl Handle { } pub fn position(&self) -> PhysicalPosition { - unimplemented!(); + PhysicalPosition { x: 0.0, y: 0.0 } } pub fn name(&self) -> Option { - unimplemented!(); + None } pub fn size(&self) -> PhysicalSize { - unimplemented!(); + PhysicalSize { + width: 0.0, + height: 0.0, + } } pub fn video_modes(&self) -> impl Iterator { - // TODO: is this possible ? std::iter::empty() } } @@ -45,9 +47,6 @@ impl Mode { } pub fn monitor(&self) -> MonitorHandle { - MonitorHandle { - inner: Handle - } + MonitorHandle { inner: Handle } } } - diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index 0ac1cdc2..43c0511d 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -4,7 +4,7 @@ use crate::icon::Icon; use crate::monitor::MonitorHandle as RootMH; use crate::window::{CursorIcon, Fullscreen, WindowAttributes, WindowId as RootWI}; -use raw_window_handle::{RawWindowHandle, web::WebHandle}; +use raw_window_handle::web::WebHandle; use super::{backend, monitor, EventLoopWindowTarget}; @@ -179,13 +179,13 @@ impl Window { #[inline] pub fn set_cursor_position(&self, _position: LogicalPosition) -> Result<(), ExternalError> { - // TODO: pointer capture + // Intentionally a no-op, as the web does not support setting cursor positions Ok(()) } #[inline] pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> { - // TODO: pointer capture + // Intentionally a no-op, as the web does not (properly) support grabbing the cursor Ok(()) } @@ -201,7 +201,7 @@ impl Window { #[inline] pub fn set_maximized(&self, _maximized: bool) { - // TODO: should there be a maximization / fullscreen API? + // Intentionally a no-op, as canvases cannot be 'maximized' } #[inline] @@ -232,7 +232,7 @@ impl Window { #[inline] pub fn set_ime_position(&self, _position: LogicalPosition) { - // TODO: what is this? + // Currently a no-op as it does not seem there is good support for this on web } #[inline] diff --git a/src/window.rs b/src/window.rs index 1eaeec47..6be850cc 100644 --- a/src/window.rs +++ b/src/window.rs @@ -303,6 +303,10 @@ impl WindowBuilder { /// Builds the window. /// /// Possible causes of error include denied permission, incompatible system, and lack of memory. + /// + /// Platform-specific behavior: + /// - **Web**: The window is created but not inserted into the web page automatically. Please + /// see the web platform module for more information. #[inline] pub fn build( self, @@ -321,6 +325,10 @@ impl Window { /// /// Error should be very rare and only occur in case of permission denied, incompatible system, /// out of memory, etc. + /// + /// Platform-specific behavior: + /// - **Web**: The window is created but not inserted into the web page automatically. Please + /// see the web platform module for more information. #[inline] pub fn new(event_loop: &EventLoopWindowTarget) -> Result { let builder = WindowBuilder::new(); @@ -476,6 +484,7 @@ impl Window { /// ## Platform-specific /// /// - **iOS:** Has no effect. + /// - **Web:** Has no effect. #[inline] pub fn set_min_inner_size(&self, dimensions: Option) { self.window.set_min_inner_size(dimensions) @@ -486,6 +495,7 @@ impl Window { /// ## Platform-specific /// /// - **iOS:** Has no effect. + /// - **Web:** Has no effect. #[inline] pub fn set_max_inner_size(&self, dimensions: Option) { self.window.set_max_inner_size(dimensions) @@ -511,6 +521,7 @@ impl Window { /// /// - **Android:** Has no effect. /// - **iOS:** Can only be called on the main thread. + /// - **Web:** Has no effect. #[inline] pub fn set_visible(&self, visible: bool) { self.window.set_visible(visible) @@ -530,6 +541,7 @@ impl Window { /// ## Platform-specific /// /// - **iOS:** Has no effect. + /// - **Web:** Has no effect. #[inline] pub fn set_resizable(&self, resizable: bool) { self.window.set_resizable(resizable) @@ -540,6 +552,7 @@ impl Window { /// ## Platform-specific /// /// - **iOS:** Has no effect. + /// - **Web:** Has no effect. #[inline] pub fn set_maximized(&self, maximized: bool) { self.window.set_maximized(maximized) @@ -585,8 +598,11 @@ impl Window { /// Turn window decorations on or off. /// /// ## Platform-specific + /// - **iOS:** Can only be called on the main thread. Controls whether the status bar is hidden + /// via [`setPrefersStatusBarHidden`]. + /// - **Web:** Has no effect. /// - /// - **iOS:** Has no effect. + /// [`setPrefersStatusBarHidden`]: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc #[inline] pub fn set_decorations(&self, decorations: bool) { self.window.set_decorations(decorations) @@ -597,6 +613,7 @@ impl Window { /// ## Platform-specific /// /// - **iOS:** Has no effect. + /// - **Web:** Has no effect. #[inline] pub fn set_always_on_top(&self, always_on_top: bool) { self.window.set_always_on_top(always_on_top) @@ -620,6 +637,7 @@ impl Window { /// ## Platform-specific /// /// **iOS:** Has no effect. + /// - **Web:** Has no effect. #[inline] pub fn set_ime_position(&self, position: LogicalPosition) { self.window.set_ime_position(position) @@ -644,6 +662,7 @@ impl Window { /// ## Platform-specific /// /// - **iOS:** Always returns an `Err`. + /// - **Web:** Has no effect. #[inline] pub fn set_cursor_position(&self, position: LogicalPosition) -> Result<(), ExternalError> { self.window.set_cursor_position(position) @@ -657,6 +676,7 @@ impl Window { /// awkward. /// - **Android:** Has no effect. /// - **iOS:** Always returns an Err. + /// - **Web:** Has no effect. #[inline] pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> { self.window.set_cursor_grab(grab)