From d3a121be9478cb7048a0e0d6fcb01c9f2e2791ee Mon Sep 17 00:00:00 2001 From: Toniman Date: Sat, 23 Jan 2021 19:05:53 +0100 Subject: [PATCH 1/4] Added `set_minimized` and `set_position` to `Window` --- crates/bevy_window/src/event.rs | 8 +++++ crates/bevy_window/src/lib.rs | 3 +- crates/bevy_window/src/window.rs | 61 ++++++++++++++++++++++++++++++++ crates/bevy_winit/src/lib.rs | 20 ++++++++++- 4 files changed, 90 insertions(+), 2 deletions(-) diff --git a/crates/bevy_window/src/event.rs b/crates/bevy_window/src/event.rs index 8c97ace0b934b..cf150c52fccd6 100644 --- a/crates/bevy_window/src/event.rs +++ b/crates/bevy_window/src/event.rs @@ -89,3 +89,11 @@ pub enum FileDragAndDrop { HoveredFileCancelled { id: WindowId }, } + +/// An event that is sent when a window is repositioned in physical pixels. +#[derive(Debug, Clone)] +pub struct WindowMoved { + pub id: WindowId, + pub x: i32, + pub y: i32, +} diff --git a/crates/bevy_window/src/lib.rs b/crates/bevy_window/src/lib.rs index 55c46bef8fd6f..d01b5f751e640 100644 --- a/crates/bevy_window/src/lib.rs +++ b/crates/bevy_window/src/lib.rs @@ -12,7 +12,7 @@ pub use windows::*; pub mod prelude { pub use crate::{ CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter, Window, - WindowDescriptor, Windows, + WindowDescriptor, WindowMoved, Windows, }; } @@ -47,6 +47,7 @@ impl Plugin for WindowPlugin { .add_event::() .add_event::() .add_event::() + .add_event::() .init_resource::(); if self.add_primary_window { diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index 0bcb3c6f73068..bff08cff7963a 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -54,6 +54,8 @@ pub struct Window { requested_height: f32, physical_width: u32, physical_height: u32, + x: i32, + y: i32, scale_factor_override: Option, backend_scale_factor: f64, title: String, @@ -106,6 +108,13 @@ pub enum WindowCommand { SetMaximized { maximized: bool, }, + SetMinimized { + minimized: bool, + }, + SetPosition { + x: i32, + y: i32, + }, } /// Defines the way a window is displayed @@ -132,6 +141,8 @@ impl Window { id, requested_width: window_descriptor.width, requested_height: window_descriptor.height, + x: window_descriptor.x, + y: window_descriptor.y, physical_width, physical_height, scale_factor_override: window_descriptor.scale_factor_override, @@ -199,12 +210,51 @@ impl Window { self.physical_height } + /// The window's client position on the x axis in physical pixels. + #[inline] + pub fn x(&self) -> i32 { + self.x + } + + /// The window's client position on the y axis in physical pixels. + #[inline] + pub fn y(&self) -> i32 { + self.y + } + #[inline] pub fn set_maximized(&mut self, maximized: bool) { self.command_queue .push(WindowCommand::SetMaximized { maximized }); } + /// Sets the window to minimized or back. + /// + /// # Platform-specific + /// - iOS / Android / Web: Unsupported. + /// - Wayland: Un-minimize is unsupported. + #[inline] + pub fn set_minimized(&mut self, minimized: bool) { + self.command_queue + .push(WindowCommand::SetMinimized { minimized }); + } + + /// Modifies the position of the window in physical pixels. + /// + /// Note that the top-left hand corner of the desktop is not necessarily the same as the screen. If the user uses a desktop with multiple monitors, + /// the top-left hand corner of the desktop is the top-left hand corner of the monitor at the top-left of the desktop. This automatically un-maximizes + /// the window if it's maximized. + /// + /// # Platform-specific + /// + /// - iOS: Can only be called on the main thread. Sets the top left coordinates of the window in the screen space coordinate system. + /// - Web: Sets the top-left coordinates relative to the viewport. + /// - Android / Wayland: Unsupported. + #[inline] + pub fn set_position(&mut self, x: i32, y: i32) { + self.command_queue.push(WindowCommand::SetPosition { x, y }) + } + /// Request the OS to resize the window such the the client area matches the /// specified width and height. #[allow(clippy::float_cmp)] @@ -250,6 +300,13 @@ impl Window { self.physical_height = physical_height; } + #[allow(missing_docs)] + #[inline] + pub fn update_actual_position_from_backend(&mut self, x: i32, y: i32) { + self.x = x; + self.y = y; + } + /// The ratio of physical pixels to logical pixels /// /// `physical_pixels = logical_pixels * scale_factor` @@ -373,6 +430,8 @@ impl Window { #[derive(Debug, Clone)] pub struct WindowDescriptor { + pub x: i32, + pub y: i32, pub width: f32, pub height: f32, pub scale_factor_override: Option, @@ -391,6 +450,8 @@ impl Default for WindowDescriptor { fn default() -> Self { WindowDescriptor { title: "bevy".to_string(), + x: 0, + y: 0, width: 1280., height: 720., scale_factor_override: None, diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index f41b1186b6a91..9b3519b6c1d07 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -17,9 +17,10 @@ use bevy_utils::tracing::{error, trace, warn}; use bevy_window::{ CreateWindow, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter, WindowBackendScaleFactorChanged, WindowCloseRequested, WindowCreated, WindowFocused, - WindowResized, WindowScaleFactorChanged, Windows, + WindowMoved, WindowResized, WindowScaleFactorChanged, Windows, }; use winit::{ + dpi::PhysicalPosition, event::{self, DeviceEvent, Event, WindowEvent}, event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget}, }; @@ -127,6 +128,14 @@ fn change_window(_: &mut World, resources: &mut Resources) { let window = winit_windows.get_window(id).unwrap(); window.set_maximized(maximized) } + bevy_window::WindowCommand::SetMinimized { minimized } => { + let window = winit_windows.get_window(id).unwrap(); + window.set_minimized(minimized) + } + bevy_window::WindowCommand::SetPosition { x, y } => { + let window = winit_windows.get_window(id).unwrap(); + window.set_outer_position(PhysicalPosition { x, y }); + } } } } @@ -423,6 +432,15 @@ pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) { app.resources.get_mut::>().unwrap(); events.send(FileDragAndDrop::HoveredFileCancelled { id: window_id }); } + WindowEvent::Moved(position) => { + window.update_actual_position_from_backend(position.x, position.y); + let mut events = app.resources.get_mut::>().unwrap(); + events.send(WindowMoved { + id: window_id, + x: position.x, + y: position.y, + }); + } _ => {} } } From ae3642d06d8397bfcfffc5f3e139edc1ea5ef8b4 Mon Sep 17 00:00:00 2001 From: Toniman20 Date: Sun, 24 Jan 2021 14:38:48 +0100 Subject: [PATCH 2/4] Replaced `i32` with `IVec2` Removed `WindowDescriptor` addition, because winit does not allow setting the position on window creation. Also changed position in `Window` to an `Option` for the same reason. --- crates/bevy_window/src/event.rs | 5 ++--- crates/bevy_window/src/window.rs | 37 +++++++++++--------------------- crates/bevy_winit/src/lib.rs | 15 +++++++------ 3 files changed, 23 insertions(+), 34 deletions(-) diff --git a/crates/bevy_window/src/event.rs b/crates/bevy_window/src/event.rs index cf150c52fccd6..2498d66d73a5f 100644 --- a/crates/bevy_window/src/event.rs +++ b/crates/bevy_window/src/event.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use super::{WindowDescriptor, WindowId}; -use bevy_math::Vec2; +use bevy_math::{IVec2, Vec2}; /// A window event that is sent whenever a window has been resized. #[derive(Debug, Clone)] @@ -94,6 +94,5 @@ pub enum FileDragAndDrop { #[derive(Debug, Clone)] pub struct WindowMoved { pub id: WindowId, - pub x: i32, - pub y: i32, + pub position: IVec2, } diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index bff08cff7963a..7a9b079e63ecd 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -1,4 +1,4 @@ -use bevy_math::Vec2; +use bevy_math::{ivec2, IVec2, Vec2}; use bevy_utils::Uuid; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] @@ -54,8 +54,7 @@ pub struct Window { requested_height: f32, physical_width: u32, physical_height: u32, - x: i32, - y: i32, + position: Option, scale_factor_override: Option, backend_scale_factor: f64, title: String, @@ -112,8 +111,7 @@ pub enum WindowCommand { minimized: bool, }, SetPosition { - x: i32, - y: i32, + position: IVec2, }, } @@ -141,8 +139,7 @@ impl Window { id, requested_width: window_descriptor.width, requested_height: window_descriptor.height, - x: window_descriptor.x, - y: window_descriptor.y, + position: None, physical_width, physical_height, scale_factor_override: window_descriptor.scale_factor_override, @@ -210,16 +207,10 @@ impl Window { self.physical_height } - /// The window's client position on the x axis in physical pixels. + /// The window's client position in physical pixels. #[inline] - pub fn x(&self) -> i32 { - self.x - } - - /// The window's client position on the y axis in physical pixels. - #[inline] - pub fn y(&self) -> i32 { - self.y + pub fn position(&self) -> Option { + self.position } #[inline] @@ -251,8 +242,9 @@ impl Window { /// - Web: Sets the top-left coordinates relative to the viewport. /// - Android / Wayland: Unsupported. #[inline] - pub fn set_position(&mut self, x: i32, y: i32) { - self.command_queue.push(WindowCommand::SetPosition { x, y }) + pub fn set_position(&mut self, position: IVec2) { + self.command_queue + .push(WindowCommand::SetPosition { position }) } /// Request the OS to resize the window such the the client area matches the @@ -302,9 +294,8 @@ impl Window { #[allow(missing_docs)] #[inline] - pub fn update_actual_position_from_backend(&mut self, x: i32, y: i32) { - self.x = x; - self.y = y; + pub fn update_actual_position_from_backend(&mut self, position: IVec2) { + self.position = Some(position); } /// The ratio of physical pixels to logical pixels @@ -430,8 +421,6 @@ impl Window { #[derive(Debug, Clone)] pub struct WindowDescriptor { - pub x: i32, - pub y: i32, pub width: f32, pub height: f32, pub scale_factor_override: Option, @@ -450,8 +439,6 @@ impl Default for WindowDescriptor { fn default() -> Self { WindowDescriptor { title: "bevy".to_string(), - x: 0, - y: 0, width: 1280., height: 720., scale_factor_override: None, diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 9b3519b6c1d07..0f5d082a3739a 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -12,7 +12,7 @@ pub use winit_windows::*; use bevy_app::{prelude::*, AppExit, ManualEventReader}; use bevy_ecs::{IntoSystem, Resources, World}; -use bevy_math::Vec2; +use bevy_math::{ivec2, Vec2}; use bevy_utils::tracing::{error, trace, warn}; use bevy_window::{ CreateWindow, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter, @@ -132,9 +132,12 @@ fn change_window(_: &mut World, resources: &mut Resources) { let window = winit_windows.get_window(id).unwrap(); window.set_minimized(minimized) } - bevy_window::WindowCommand::SetPosition { x, y } => { + bevy_window::WindowCommand::SetPosition { position } => { let window = winit_windows.get_window(id).unwrap(); - window.set_outer_position(PhysicalPosition { x, y }); + window.set_outer_position(PhysicalPosition { + x: position[0], + y: position[1], + }); } } } @@ -433,12 +436,12 @@ pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) { events.send(FileDragAndDrop::HoveredFileCancelled { id: window_id }); } WindowEvent::Moved(position) => { - window.update_actual_position_from_backend(position.x, position.y); + let position = ivec2(position.x, position.y); + window.update_actual_position_from_backend(position); let mut events = app.resources.get_mut::>().unwrap(); events.send(WindowMoved { id: window_id, - x: position.x, - y: position.y, + position, }); } _ => {} From e98acc414b2661619784c6357e3e1fd3a1810f12 Mon Sep 17 00:00:00 2001 From: Toniman20 Date: Sun, 24 Jan 2021 14:44:33 +0100 Subject: [PATCH 3/4] fixed clippy --- crates/bevy_window/src/window.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index 7a9b079e63ecd..486d7cf82dd3a 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -1,4 +1,4 @@ -use bevy_math::{ivec2, IVec2, Vec2}; +use bevy_math::{IVec2, Vec2}; use bevy_utils::Uuid; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] From 8a6fa380eaced4c46e4d7979adfdbe6fb85a9618 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Sun, 24 Jan 2021 17:19:09 -0800 Subject: [PATCH 4/4] set position on window construction --- crates/bevy_window/src/window.rs | 3 ++- crates/bevy_winit/src/winit_windows.rs | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index 486d7cf82dd3a..fc9d800cdaeff 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -134,12 +134,13 @@ impl Window { physical_width: u32, physical_height: u32, scale_factor: f64, + position: Option, ) -> Self { Window { id, requested_width: window_descriptor.width, requested_height: window_descriptor.height, - position: None, + position, physical_width, physical_height, scale_factor_override: window_descriptor.scale_factor_override, diff --git a/crates/bevy_winit/src/winit_windows.rs b/crates/bevy_winit/src/winit_windows.rs index d32b4d2e41233..736b98e762305 100644 --- a/crates/bevy_winit/src/winit_windows.rs +++ b/crates/bevy_winit/src/winit_windows.rs @@ -1,3 +1,4 @@ +use bevy_math::IVec2; use bevy_utils::HashMap; use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode}; @@ -110,16 +111,20 @@ impl WinitWindows { } } + let position = winit_window + .outer_position() + .ok() + .map(|position| IVec2::new(position.x, position.y)); let inner_size = winit_window.inner_size(); let scale_factor = winit_window.scale_factor(); self.windows.insert(winit_window.id(), winit_window); - Window::new( window_id, &window_descriptor, inner_size.width, inner_size.height, scale_factor, + position, ) }