diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index b5a047566d..787f479355 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -76,8 +76,8 @@ pub struct ComputedCameraValues { old_viewport_size: Option, } -/// The defining component for camera entities, storing information about how and what to render -/// through this camera. +/// The defining [`Component`] for camera entities, +/// storing information about how and what to render through this camera. /// /// The [`Camera`] component is added to an entity to define the properties of the viewpoint from /// which rendering occurs. It defines the position of the view to render, the projection method diff --git a/crates/bevy_window/src/cursor.rs b/crates/bevy_window/src/cursor.rs index 2bc4f34f70..9622f2afd1 100644 --- a/crates/bevy_window/src/cursor.rs +++ b/crates/bevy_window/src/cursor.rs @@ -3,9 +3,9 @@ use bevy_reflect::{prelude::ReflectDefault, FromReflect, Reflect, ReflectFromRef #[cfg(feature = "serialize")] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; -/// The icon to display for a window's cursor. +/// The icon to display for a [`Window`](crate::window::Window)'s [`Cursor`](crate::window::Cursor). /// -/// Examples of all of these cursors can be found [here](https://www.w3schools.com/cssref/playit.asp?filename=playcss_cursor). +/// Examples of all of these cursors can be found [here](https://www.w3schools.com/cssref/playit.php?filename=playcss_cursor&preval=crosshair). /// This `enum` is simply a copy of a similar `enum` found in [`winit`](https://docs.rs/winit/latest/winit/window/enum.CursorIcon.html). /// `winit`, in turn, mostly copied cursor types available in the browser. #[derive(Default, Debug, Hash, PartialEq, Eq, Clone, Copy, Reflect, FromReflect)] diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index 40f661b38c..dc2978242a 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -12,16 +12,19 @@ use bevy_utils::tracing::warn; use crate::CursorIcon; -/// Marker component for the window considered the primary window. +/// Marker [`Component`] for the window considered the primary window. /// /// Currently this is assumed to only exist on 1 entity at a time. +/// +/// [`WindowPlugin`](crate::WindowPlugin) will spawn a window entity +/// with this component if `primary_window` is `Some`. #[derive( Default, Debug, Component, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Reflect, FromReflect, )] #[reflect(Component, FromReflect)] pub struct PrimaryWindow; -/// Reference to a window, whether it be a direct link to a specific entity or +/// Reference to a [`Window`], whether it be a direct link to a specific entity or /// a more vague defaulting choice. #[repr(C)] #[derive(Default, Copy, Clone, Debug, Reflect, FromReflect)] @@ -86,7 +89,15 @@ impl NormalizedWindowRef { } } -/// Define how a window will be created and how it will behave. +/// The defining [`Component`] for window entities, +/// storing information about how it should appear and behave. +/// +/// Each window corresponds to an entity, and is uniquely identified by the value of their [`Entity`]. +/// When the [`Window`] component is added to an entity, a new window will be opened. +/// When it is removed or the entity is despawned, the window will close. +/// +/// This component is synchronized with `winit` through `bevy_winit`: +/// it will reflect the current state of the window and can be modified to change this state. #[derive(Component, Debug, Clone, Reflect, FromReflect)] #[cfg_attr( feature = "serialize", @@ -99,7 +110,7 @@ pub struct Window { pub cursor: Cursor, /// What presentation mode to give the window. pub present_mode: PresentMode, - /// Which fullscreen or windowing mode should be used? + /// Which fullscreen or windowing mode should be used. pub mode: WindowMode, /// Where the window should be placed. pub position: WindowPosition, @@ -109,7 +120,8 @@ pub struct Window { pub title: String, /// How the alpha channel of textures should be handled while compositing. pub composite_alpha_mode: CompositeAlphaMode, - /// Which size limits to give the window. + /// The limits of the window's logical size + /// (found in its [`resolution`](WindowResolution)) when resizing. pub resize_constraints: WindowResizeConstraints, /// Should the window be resizable? /// @@ -135,9 +147,9 @@ pub struct Window { /// macOS X transparent works with winit out of the box, so this issue might be related to: . /// You should also set the window `composite_alpha_mode` to `CompositeAlphaMode::PostMultiplied`. pub transparent: bool, - /// Should the window start focused? + /// Get/set whether the window is focused. pub focused: bool, - /// Should the window always be on top of other windows? + /// Where should the window appear relative to other overlapping window. /// /// ## Platform-specific /// @@ -239,36 +251,50 @@ impl Window { } /// The window's client area width in logical pixels. + /// + /// See [`WindowResolution`] for an explanation about logical/physical sizes. #[inline] pub fn width(&self) -> f32 { self.resolution.width() } /// The window's client area height in logical pixels. + /// + /// See [`WindowResolution`] for an explanation about logical/physical sizes. #[inline] pub fn height(&self) -> f32 { self.resolution.height() } /// The window's client area width in physical pixels. + /// + /// See [`WindowResolution`] for an explanation about logical/physical sizes. #[inline] pub fn physical_width(&self) -> u32 { self.resolution.physical_width() } /// The window's client area height in physical pixels. + /// + /// See [`WindowResolution`] for an explanation about logical/physical sizes. #[inline] pub fn physical_height(&self) -> u32 { self.resolution.physical_height() } /// The window's scale factor. + /// + /// Ratio of physical size to logical size, see [`WindowResolution`]. #[inline] pub fn scale_factor(&self) -> f64 { self.resolution.scale_factor() } - /// The cursor position in this window + /// The cursor position in this window in logical pixels. + /// + /// Returns `None` if the cursor is outside the window area. + /// + /// See [`WindowResolution`] for an explanation about logical/physical sizes. #[inline] pub fn cursor_position(&self) -> Option { self.internal @@ -276,7 +302,11 @@ impl Window { .map(|position| (position / self.scale_factor()).as_vec2()) } - /// The physical cursor position in this window + /// The cursor position in this window in physical pixels. + /// + /// Returns `None` if the cursor is outside the window area. + /// + /// See [`WindowResolution`] for an explanation about logical/physical sizes. #[inline] pub fn physical_cursor_position(&self) -> Option { self.internal @@ -284,22 +314,27 @@ impl Window { .map(|position| position.as_vec2()) } - /// Set the cursor position in this window + /// Set the cursor position in this window in logical pixels. + /// + /// See [`WindowResolution`] for an explanation about logical/physical sizes. pub fn set_cursor_position(&mut self, position: Option) { self.internal.physical_cursor_position = position.map(|p| p.as_dvec2() * self.scale_factor()); } - /// Set the physical cursor position in this window + /// Set the cursor position in this window in physical pixels. + /// + /// See [`WindowResolution`] for an explanation about logical/physical sizes. pub fn set_physical_cursor_position(&mut self, position: Option) { self.internal.physical_cursor_position = position; } } -/// The size limits on a window. +/// The size limits on a [`Window`]. /// -/// These values are measured in logical pixels, so the user's +/// These values are measured in logical pixels (see [`WindowResolution`]), so the user's /// scale factor does affect the size limits on the window. +/// /// Please note that if the window is resizable, then when the window is /// maximized it may have a size outside of these limits. The functionality /// required to disable maximizing is not yet exposed by winit. @@ -369,7 +404,7 @@ impl WindowResizeConstraints { } } -/// Stores data about the window's cursor. +/// Cursor data for a [`Window`]. #[derive(Debug, Copy, Clone, Reflect, FromReflect)] #[cfg_attr( feature = "serialize", @@ -378,7 +413,7 @@ impl WindowResizeConstraints { )] #[reflect(Debug, Default, FromReflect)] pub struct Cursor { - /// Get the current [`CursorIcon`] while inside the window. + /// What the cursor should look like while inside the window. pub icon: CursorIcon, /// Whether the cursor is visible or not. @@ -391,7 +426,7 @@ pub struct Cursor { /// - **`iOS`** and **`Android`** do not have cursors pub visible: bool, - /// Whether or not the cursor is locked. + /// Whether or not the cursor is locked by or confined within the window. /// /// ## Platform-specific /// @@ -421,7 +456,7 @@ impl Default for Cursor { } } -/// Defines where window should be placed at on creation. +/// Defines where a [`Window`] should be placed on the screen. #[derive(Default, Debug, Clone, Copy, PartialEq, Reflect, FromReflect)] #[cfg_attr( feature = "serialize", @@ -430,14 +465,19 @@ impl Default for Cursor { )] #[reflect(Debug, PartialEq, FromReflect)] pub enum WindowPosition { - /// Position will be set by the window manager + /// Position will be set by the window manager. + /// Bevy will delegate this decision to the window manager and no guarantees can be made about where the window will be placed. + /// + /// Used at creation but will be changed to [`At`](WindowPosition::At). #[default] Automatic, - /// Window will be centered on the selected monitor + /// Window will be centered on the selected monitor. /// /// Note that this does not account for window decorations. + /// + /// Used at creation or for update but will be changed to [`At`](WindowPosition::At) Centered(MonitorSelection), - /// The window's top-left corner will be placed at the specified position (in physical pixels) + /// The window's top-left corner should be placed at the specified position (in physical pixels). /// /// (0,0) represents top-left corner of screen space. At(IVec2), @@ -460,19 +500,52 @@ impl WindowPosition { } } -/// ## Window Sizes +/// Controls the size of a [`Window`] /// -/// There are three sizes associated with a window. The physical size which is -/// the height and width in physical pixels on the monitor. The logical size -/// which is the physical size scaled by an operating system provided factor to -/// account for monitors with differing pixel densities or user preference. And -/// the requested size, measured in logical pixels, which is the value submitted +/// ## Physical, logical and requested sizes +/// +/// There are three sizes associated with a window: +/// - the physical size, +/// which represents the actual height and width in physical pixels +/// the window occupies on the monitor, +/// - the logical size, +/// which represents the size that should be used to scale elements +/// inside the window, measured in logical pixels, +/// - the requested size, +/// measured in logical pixels, which is the value submitted /// to the API when creating the window, or requesting that it be resized. /// -/// The actual size, in logical pixels, of the window may not match the -/// requested size due to operating system limits on the window size, or the -/// quantization of the logical size when converting the physical size to the -/// logical size through the scaling factor. +/// ## Scale factor +/// +/// The reason logical size and physical size are separated and can be different +/// is to account for the cases where: +/// - several monitors have different pixel densities, +/// - the user has set up a pixel density preference in its operating system, +/// - the Bevy `App` has specified a specific scale factor between both. +/// +/// The factor between physical size and logical size can be retrieved with +/// [`WindowResolution::scale_factor`]. +/// +/// For the first two cases, a scale factor is set automatically by the operating +/// system through the window backend. You can get it with +/// [`WindowResolution::base_scale_factor`]. +/// +/// For the third case, you can override this automatic scale factor with +/// [`WindowResolution::set_scale_factor_override`]. +/// +/// ## Requested and obtained sizes +/// +/// The logical size should be equal to the requested size after creating/resizing, +/// when possible. +/// The reason the requested size and logical size might be different +/// is because the corresponding physical size might exceed limits (either the +/// size limits of the monitor, or limits defined in [`WindowResizeConstraints`]). +/// +/// Note: The requested size is not kept in memory, for example requesting a size +/// too big for the screen, making the logical size different from the requested size, +/// and then setting a scale factor that makes the previous requested size within +/// the limits of the screen will not get back that previous requested size. + #[derive(Debug, Clone, PartialEq, Reflect, FromReflect)] #[cfg_attr( feature = "serialize", @@ -481,9 +554,17 @@ impl WindowPosition { )] #[reflect(Debug, PartialEq, Default, FromReflect)] pub struct WindowResolution { + /// Width of the window in physical pixels. physical_width: u32, + /// Height of the window in physical pixels. physical_height: u32, + /// Code-provided ratio of physical size to logical size. + /// + /// Should be used instead `scale_factor` when set. scale_factor_override: Option, + /// OS-provided ratio of physical size to logical size. + /// + /// Set automatically depending on the pixel density of the screen. scale_factor: f64, } @@ -520,7 +601,7 @@ impl WindowResolution { (self.physical_width() as f64 / self.scale_factor()) as f32 } - /// The window's client area width in logical pixels. + /// The window's client area height in logical pixels. #[inline] pub fn height(&self) -> f32 { (self.physical_height() as f64 / self.scale_factor()) as f32 @@ -538,7 +619,7 @@ impl WindowResolution { self.physical_height } - /// The ratio of physical pixels to logical pixels + /// The ratio of physical pixels to logical pixels. /// /// `physical_pixels = logical_pixels * scale_factor` pub fn scale_factor(&self) -> f64 { @@ -590,6 +671,9 @@ impl WindowResolution { } /// Set the window's scale factor, this will be used over what the backend decides. + /// + /// This can change the logical and physical sizes if the resulting physical + /// size is not within the limits. #[inline] pub fn set_scale_factor_override(&mut self, scale_factor_override: Option) { let (width, height) = (self.width(), self.height()); @@ -628,7 +712,7 @@ impl From for WindowResolution { } } -/// Defines if and how the cursor is grabbed. +/// Defines if and how the [`Cursor`] is grabbed by a [`Window`]. /// /// ## Platform-specific /// @@ -654,7 +738,7 @@ pub enum CursorGrabMode { Locked, } -/// Stores internal state that isn't directly accessible. +/// Stores internal [`Window`] state that isn't directly accessible. #[derive(Default, Debug, Copy, Clone, PartialEq, Reflect, FromReflect)] #[cfg_attr( feature = "serialize", @@ -683,7 +767,9 @@ impl InternalWindowState { } } -/// Defines which monitor to use. +/// References a screen monitor. +/// +/// Used when centering a [`Window`] on a monitor. #[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect, FromReflect)] #[cfg_attr( feature = "serialize", @@ -692,17 +778,18 @@ impl InternalWindowState { )] #[reflect(Debug, PartialEq, FromReflect)] pub enum MonitorSelection { - /// Uses current monitor of the window. + /// Uses the current monitor of the window. /// - /// Will fall back to the system default if the window has not yet been created. + /// If [`WindowPosition::Centered(MonitorSelection::Current)`](WindowPosition::Centered) is used when creating a window, + /// the window doesn't have a monitor yet, this will fall back to [`WindowPosition::Automatic`]. Current, - /// Uses primary monitor of the system. + /// Uses the primary monitor of the system. Primary, - /// Uses monitor with the specified index. + /// Uses the monitor with the specified index. Index(usize), } -/// Presentation mode for a window. +/// Presentation mode for a [`Window`]. /// /// The presentation mode specifies when a frame is presented to the window. The [`Fifo`] /// option corresponds to a traditional `VSync`, where the framerate is capped by the @@ -760,7 +847,7 @@ pub enum PresentMode { Fifo = 4, // NOTE: The explicit ordinal values mirror wgpu. } -/// Specifies how the alpha channel of the textures should be handled during compositing. +/// Specifies how the alpha channel of the textures should be handled during compositing, for a [`Window`]. #[repr(C)] #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Reflect, FromReflect)] #[cfg_attr( @@ -796,7 +883,7 @@ pub enum CompositeAlphaMode { Inherit = 4, } -/// Defines the way a window is displayed +/// Defines the way a [`Window`] is displayed. #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Reflect, FromReflect)] #[cfg_attr( feature = "serialize", @@ -805,22 +892,41 @@ pub enum CompositeAlphaMode { )] #[reflect(Debug, PartialEq, FromReflect)] pub enum WindowMode { - /// Creates a window that uses the given size. + /// The window should take a portion of the screen, using the window resolution size. #[default] Windowed, - /// Creates a borderless window that uses the full size of the screen. + /// The window should appear fullscreen by being borderless and using the full + /// size of the screen. + /// + /// When setting this, the window's physical size will be modified to match the size + /// of the current monitor resolution, and the logical size will follow based + /// on the scale factor, see [`WindowResolution`]. BorderlessFullscreen, - /// Creates a fullscreen window that will render at desktop resolution. The app will use the closest supported size - /// from the given size and scale it to fit the screen. + /// The window should be in "true"/"legacy" Fullscreen mode. + /// + /// When setting this, the operating system will be requested to use the + /// **closest** resolution available for the current monitor to match as + /// closely as possible the window's physical size. + /// After that, the window's physical size will be modified to match + /// that monitor resolution, and the logical size will follow based on the + /// scale factor, see [`WindowResolution`]. SizedFullscreen, - /// Creates a fullscreen window that uses the maximum supported size. + /// The window should be in "true"/"legacy" Fullscreen mode. + /// + /// When setting this, the operating system will be requested to use the + /// **biggest** resolution available for the current monitor. + /// After that, the window's physical size will be modified to match + /// that monitor resolution, and the logical size will follow based on the + /// scale factor, see [`WindowResolution`]. Fullscreen, } -/// A window level groups windows with respect to their z-position. +/// Specifies where a [`Window`] should appear relative to other overlapping windows (on top or under) . +/// +/// Levels are groups of windows with respect to their z-position. /// /// The relative ordering between windows in different window levels is fixed. -/// The z-order of a window within the same window level may change dynamically on user interaction. +/// The z-order of windows within the same window level may change dynamically on user interaction. /// /// ## Platform-specific /// @@ -833,18 +939,18 @@ pub enum WindowMode { )] #[reflect(Debug, PartialEq, FromReflect)] pub enum WindowLevel { - /// The window will always be below normal windows. + /// The window will always be below [`WindowLevel::Normal`] and [`WindowLevel::AlwaysOnTop`] windows. /// /// This is useful for a widget-based app. AlwaysOnBottom, - /// The default. + /// The default group. #[default] Normal, - /// The window will always be on top of normal windows. + /// The window will always be on top of [`WindowLevel::Normal`] and [`WindowLevel::AlwaysOnBottom`] windows. AlwaysOnTop, } -/// The window theme variant to use. +/// The [`Window`] theme variant to use. #[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect, FromReflect)] #[cfg_attr( feature = "serialize",