Skip to content

Commit 32acbfb

Browse files
authored
Added set_minimized and set_position to Window (#1292)
Added `set_minimized` and `set_position` to `Window`
1 parent 7e368e0 commit 32acbfb

File tree

5 files changed

+89
-6
lines changed

5 files changed

+89
-6
lines changed

crates/bevy_window/src/event.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::path::PathBuf;
22

33
use super::{WindowDescriptor, WindowId};
4-
use bevy_math::Vec2;
4+
use bevy_math::{IVec2, Vec2};
55

66
/// A window event that is sent whenever a window has been resized.
77
#[derive(Debug, Clone)]
@@ -89,3 +89,10 @@ pub enum FileDragAndDrop {
8989

9090
HoveredFileCancelled { id: WindowId },
9191
}
92+
93+
/// An event that is sent when a window is repositioned in physical pixels.
94+
#[derive(Debug, Clone)]
95+
pub struct WindowMoved {
96+
pub id: WindowId,
97+
pub position: IVec2,
98+
}

crates/bevy_window/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub use windows::*;
1212
pub mod prelude {
1313
pub use crate::{
1414
CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter, Window,
15-
WindowDescriptor, Windows,
15+
WindowDescriptor, WindowMoved, Windows,
1616
};
1717
}
1818

@@ -47,6 +47,7 @@ impl Plugin for WindowPlugin {
4747
.add_event::<WindowScaleFactorChanged>()
4848
.add_event::<WindowBackendScaleFactorChanged>()
4949
.add_event::<FileDragAndDrop>()
50+
.add_event::<WindowMoved>()
5051
.init_resource::<Windows>();
5152

5253
if self.add_primary_window {

crates/bevy_window/src/window.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use bevy_math::Vec2;
1+
use bevy_math::{IVec2, Vec2};
22
use bevy_utils::Uuid;
33

44
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
@@ -54,6 +54,7 @@ pub struct Window {
5454
requested_height: f32,
5555
physical_width: u32,
5656
physical_height: u32,
57+
position: Option<IVec2>,
5758
scale_factor_override: Option<f64>,
5859
backend_scale_factor: f64,
5960
title: String,
@@ -106,6 +107,12 @@ pub enum WindowCommand {
106107
SetMaximized {
107108
maximized: bool,
108109
},
110+
SetMinimized {
111+
minimized: bool,
112+
},
113+
SetPosition {
114+
position: IVec2,
115+
},
109116
}
110117

111118
/// Defines the way a window is displayed
@@ -127,11 +134,13 @@ impl Window {
127134
physical_width: u32,
128135
physical_height: u32,
129136
scale_factor: f64,
137+
position: Option<IVec2>,
130138
) -> Self {
131139
Window {
132140
id,
133141
requested_width: window_descriptor.width,
134142
requested_height: window_descriptor.height,
143+
position,
135144
physical_width,
136145
physical_height,
137146
scale_factor_override: window_descriptor.scale_factor_override,
@@ -199,12 +208,46 @@ impl Window {
199208
self.physical_height
200209
}
201210

211+
/// The window's client position in physical pixels.
212+
#[inline]
213+
pub fn position(&self) -> Option<IVec2> {
214+
self.position
215+
}
216+
202217
#[inline]
203218
pub fn set_maximized(&mut self, maximized: bool) {
204219
self.command_queue
205220
.push(WindowCommand::SetMaximized { maximized });
206221
}
207222

223+
/// Sets the window to minimized or back.
224+
///
225+
/// # Platform-specific
226+
/// - iOS / Android / Web: Unsupported.
227+
/// - Wayland: Un-minimize is unsupported.
228+
#[inline]
229+
pub fn set_minimized(&mut self, minimized: bool) {
230+
self.command_queue
231+
.push(WindowCommand::SetMinimized { minimized });
232+
}
233+
234+
/// Modifies the position of the window in physical pixels.
235+
///
236+
/// 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,
237+
/// 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
238+
/// the window if it's maximized.
239+
///
240+
/// # Platform-specific
241+
///
242+
/// - iOS: Can only be called on the main thread. Sets the top left coordinates of the window in the screen space coordinate system.
243+
/// - Web: Sets the top-left coordinates relative to the viewport.
244+
/// - Android / Wayland: Unsupported.
245+
#[inline]
246+
pub fn set_position(&mut self, position: IVec2) {
247+
self.command_queue
248+
.push(WindowCommand::SetPosition { position })
249+
}
250+
208251
/// Request the OS to resize the window such the the client area matches the
209252
/// specified width and height.
210253
#[allow(clippy::float_cmp)]
@@ -250,6 +293,12 @@ impl Window {
250293
self.physical_height = physical_height;
251294
}
252295

296+
#[allow(missing_docs)]
297+
#[inline]
298+
pub fn update_actual_position_from_backend(&mut self, position: IVec2) {
299+
self.position = Some(position);
300+
}
301+
253302
/// The ratio of physical pixels to logical pixels
254303
///
255304
/// `physical_pixels = logical_pixels * scale_factor`

crates/bevy_winit/src/lib.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ pub use winit_windows::*;
1212

1313
use bevy_app::{prelude::*, AppExit, ManualEventReader};
1414
use bevy_ecs::{IntoSystem, Resources, World};
15-
use bevy_math::Vec2;
15+
use bevy_math::{ivec2, Vec2};
1616
use bevy_utils::tracing::{error, trace, warn};
1717
use bevy_window::{
1818
CreateWindow, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter,
1919
WindowBackendScaleFactorChanged, WindowCloseRequested, WindowCreated, WindowFocused,
20-
WindowResized, WindowScaleFactorChanged, Windows,
20+
WindowMoved, WindowResized, WindowScaleFactorChanged, Windows,
2121
};
2222
use winit::{
23+
dpi::PhysicalPosition,
2324
event::{self, DeviceEvent, Event, WindowEvent},
2425
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
2526
};
@@ -127,6 +128,17 @@ fn change_window(_: &mut World, resources: &mut Resources) {
127128
let window = winit_windows.get_window(id).unwrap();
128129
window.set_maximized(maximized)
129130
}
131+
bevy_window::WindowCommand::SetMinimized { minimized } => {
132+
let window = winit_windows.get_window(id).unwrap();
133+
window.set_minimized(minimized)
134+
}
135+
bevy_window::WindowCommand::SetPosition { position } => {
136+
let window = winit_windows.get_window(id).unwrap();
137+
window.set_outer_position(PhysicalPosition {
138+
x: position[0],
139+
y: position[1],
140+
});
141+
}
130142
}
131143
}
132144
}
@@ -423,6 +435,15 @@ pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) {
423435
app.resources.get_mut::<Events<FileDragAndDrop>>().unwrap();
424436
events.send(FileDragAndDrop::HoveredFileCancelled { id: window_id });
425437
}
438+
WindowEvent::Moved(position) => {
439+
let position = ivec2(position.x, position.y);
440+
window.update_actual_position_from_backend(position);
441+
let mut events = app.resources.get_mut::<Events<WindowMoved>>().unwrap();
442+
events.send(WindowMoved {
443+
id: window_id,
444+
position,
445+
});
446+
}
426447
_ => {}
427448
}
428449
}

crates/bevy_winit/src/winit_windows.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use bevy_math::IVec2;
12
use bevy_utils::HashMap;
23
use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode};
34

@@ -110,16 +111,20 @@ impl WinitWindows {
110111
}
111112
}
112113

114+
let position = winit_window
115+
.outer_position()
116+
.ok()
117+
.map(|position| IVec2::new(position.x, position.y));
113118
let inner_size = winit_window.inner_size();
114119
let scale_factor = winit_window.scale_factor();
115120
self.windows.insert(winit_window.id(), winit_window);
116-
117121
Window::new(
118122
window_id,
119123
&window_descriptor,
120124
inner_size.width,
121125
inner_size.height,
122126
scale_factor,
127+
position,
123128
)
124129
}
125130

0 commit comments

Comments
 (0)