Skip to content

Commit

Permalink
Expose winit always_on_top (bevyengine#6527)
Browse files Browse the repository at this point in the history
# Objective

I needed a window which is always on top, to create a overlay app.

## Solution

expose the `always_on_top` property of winit in bevy's `WindowDescriptor` as a boolean flag

---

## Changelog

### Added
- add `WindowDescriptor.always_on_top` which configures a window to stay on top.
  • Loading branch information
laundmo authored and alradish committed Jan 22, 2023
1 parent e21119d commit a8eba38
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
25 changes: 25 additions & 0 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ pub struct Window {
fit_canvas_to_parent: bool,
command_queue: Vec<WindowCommand>,
alpha_mode: CompositeAlphaMode,
always_on_top: bool,
}
/// A command to be sent to a window.
///
Expand Down Expand Up @@ -369,6 +370,10 @@ pub enum WindowCommand {
SetResizeConstraints {
resize_constraints: WindowResizeConstraints,
},
/// Set whether the window is always on top.
SetAlwaysOnTop {
always_on_top: bool,
},
Close,
}

Expand Down Expand Up @@ -438,6 +443,7 @@ impl Window {
fit_canvas_to_parent: window_descriptor.fit_canvas_to_parent,
command_queue: Vec::new(),
alpha_mode: window_descriptor.alpha_mode,
always_on_top: window_descriptor.always_on_top,
}
}
/// Get the window's [`WindowId`].
Expand Down Expand Up @@ -802,6 +808,18 @@ impl Window {
resolution: UVec2::new(self.physical_width, self.physical_height),
});
}
/// Get whether or not the window is always on top.
#[inline]
pub fn always_on_top(&self) -> bool {
self.always_on_top
}

/// Set whether of not the window is always on top.
pub fn set_always_on_top(&mut self, always_on_top: bool) {
self.always_on_top = always_on_top;
self.command_queue
.push(WindowCommand::SetAlwaysOnTop { always_on_top });
}
/// Close the operating system window corresponding to this [`Window`].
///
/// This will also lead to this [`Window`] being removed from the
Expand Down Expand Up @@ -978,6 +996,12 @@ pub struct WindowDescriptor {
pub fit_canvas_to_parent: bool,
/// Specifies how the alpha channel of the textures should be handled during compositing.
pub alpha_mode: CompositeAlphaMode,
/// Sets the window to always be on top of other windows.
///
/// ## Platform-specific
/// - iOS / Android / Web: Unsupported.
/// - Linux (Wayland): Unsupported.
pub always_on_top: bool,
}

impl Default for WindowDescriptor {
Expand All @@ -1000,6 +1024,7 @@ impl Default for WindowDescriptor {
canvas: None,
fit_canvas_to_parent: false,
alpha_mode: CompositeAlphaMode::Auto,
always_on_top: false,
}
}
}
4 changes: 4 additions & 0 deletions crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ fn change_window(
window.set_max_inner_size(Some(max_inner_size));
}
}
bevy_window::WindowCommand::SetAlwaysOnTop { always_on_top } => {
let window = winit_windows.get_window(id).unwrap();
window.set_always_on_top(always_on_top);
}
bevy_window::WindowCommand::Close => {
// Since we have borrowed `windows` to iterate through them, we can't remove the window from it.
// Add the removal requests to a queue to solve this
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_winit/src/winit_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ impl WinitWindows {
}
.with_resizable(window_descriptor.resizable)
.with_decorations(window_descriptor.decorations)
.with_transparent(window_descriptor.transparent),
.with_transparent(window_descriptor.transparent)
.with_always_on_top(window_descriptor.always_on_top),
};

let constraints = window_descriptor.resize_constraints.check_constraints();
Expand Down
24 changes: 24 additions & 0 deletions examples/window/window_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ fn main() {
width: 500.,
height: 300.,
present_mode: PresentMode::AutoVsync,
always_on_top: true,
..default()
},
..default()
Expand All @@ -25,6 +26,7 @@ fn main() {
.add_system(toggle_cursor)
.add_system(toggle_vsync)
.add_system(cycle_cursor_icon)
.add_system(toggle_always_on_top)
.run();
}

Expand All @@ -43,6 +45,28 @@ fn toggle_vsync(input: Res<Input<KeyCode>>, mut windows: ResMut<Windows>) {
}
}

/// This system toggles whether the window is always on top when pressing the T button
/// You'll notice it won't be covered by other windows.
///
/// This feature only works on some platforms. Please check the
/// [documentation](https://docs.rs/bevy/latest/bevy/prelude/struct.WindowDescriptor.html#structfield.always_on_top)
/// for more details.
fn toggle_always_on_top(input: Res<Input<KeyCode>>, mut windows: ResMut<Windows>) {
if input.just_pressed(KeyCode::T) {
let window = windows.primary_mut();

let on_top: bool = window.always_on_top();

if on_top {
info!("UNLOCKING WINDOW");
} else {
info!("LOCKING WINDOW ON TOP");
}

window.set_always_on_top(!on_top);
}
}

/// This system will then change the title during execution
fn change_title(time: Res<Time>, mut windows: ResMut<Windows>) {
let window = windows.primary_mut();
Expand Down

0 comments on commit a8eba38

Please sign in to comment.