Expose winit always_on_top (#6527)
# 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.
This commit is contained in:
parent
b765682c6e
commit
635320f172
@ -294,6 +294,7 @@ pub struct Window {
|
|||||||
fit_canvas_to_parent: bool,
|
fit_canvas_to_parent: bool,
|
||||||
command_queue: Vec<WindowCommand>,
|
command_queue: Vec<WindowCommand>,
|
||||||
alpha_mode: CompositeAlphaMode,
|
alpha_mode: CompositeAlphaMode,
|
||||||
|
always_on_top: bool,
|
||||||
}
|
}
|
||||||
/// A command to be sent to a window.
|
/// A command to be sent to a window.
|
||||||
///
|
///
|
||||||
@ -369,6 +370,10 @@ pub enum WindowCommand {
|
|||||||
SetResizeConstraints {
|
SetResizeConstraints {
|
||||||
resize_constraints: WindowResizeConstraints,
|
resize_constraints: WindowResizeConstraints,
|
||||||
},
|
},
|
||||||
|
/// Set whether the window is always on top.
|
||||||
|
SetAlwaysOnTop {
|
||||||
|
always_on_top: bool,
|
||||||
|
},
|
||||||
Close,
|
Close,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,6 +443,7 @@ impl Window {
|
|||||||
fit_canvas_to_parent: window_descriptor.fit_canvas_to_parent,
|
fit_canvas_to_parent: window_descriptor.fit_canvas_to_parent,
|
||||||
command_queue: Vec::new(),
|
command_queue: Vec::new(),
|
||||||
alpha_mode: window_descriptor.alpha_mode,
|
alpha_mode: window_descriptor.alpha_mode,
|
||||||
|
always_on_top: window_descriptor.always_on_top,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get the window's [`WindowId`].
|
/// Get the window's [`WindowId`].
|
||||||
@ -796,6 +802,18 @@ impl Window {
|
|||||||
resolution: UVec2::new(self.physical_width, self.physical_height),
|
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`].
|
/// Close the operating system window corresponding to this [`Window`].
|
||||||
///
|
///
|
||||||
/// This will also lead to this [`Window`] being removed from the
|
/// This will also lead to this [`Window`] being removed from the
|
||||||
@ -972,6 +990,12 @@ pub struct WindowDescriptor {
|
|||||||
pub fit_canvas_to_parent: bool,
|
pub fit_canvas_to_parent: bool,
|
||||||
/// 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.
|
||||||
pub alpha_mode: CompositeAlphaMode,
|
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 {
|
impl Default for WindowDescriptor {
|
||||||
@ -994,6 +1018,7 @@ impl Default for WindowDescriptor {
|
|||||||
canvas: None,
|
canvas: None,
|
||||||
fit_canvas_to_parent: false,
|
fit_canvas_to_parent: false,
|
||||||
alpha_mode: CompositeAlphaMode::Auto,
|
alpha_mode: CompositeAlphaMode::Auto,
|
||||||
|
always_on_top: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,10 @@ fn change_window(
|
|||||||
window.set_max_inner_size(Some(max_inner_size));
|
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 => {
|
bevy_window::WindowCommand::Close => {
|
||||||
// Since we have borrowed `windows` to iterate through them, we can't remove the window from it.
|
// 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
|
// Add the removal requests to a queue to solve this
|
||||||
|
@ -72,7 +72,8 @@ impl WinitWindows {
|
|||||||
}
|
}
|
||||||
.with_resizable(window_descriptor.resizable)
|
.with_resizable(window_descriptor.resizable)
|
||||||
.with_decorations(window_descriptor.decorations)
|
.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();
|
let constraints = window_descriptor.resize_constraints.check_constraints();
|
||||||
|
@ -15,6 +15,7 @@ fn main() {
|
|||||||
width: 500.,
|
width: 500.,
|
||||||
height: 300.,
|
height: 300.,
|
||||||
present_mode: PresentMode::AutoVsync,
|
present_mode: PresentMode::AutoVsync,
|
||||||
|
always_on_top: true,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
..default()
|
..default()
|
||||||
@ -25,6 +26,7 @@ fn main() {
|
|||||||
.add_system(toggle_cursor)
|
.add_system(toggle_cursor)
|
||||||
.add_system(toggle_vsync)
|
.add_system(toggle_vsync)
|
||||||
.add_system(cycle_cursor_icon)
|
.add_system(cycle_cursor_icon)
|
||||||
|
.add_system(toggle_always_on_top)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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
|
/// This system will then change the title during execution
|
||||||
fn change_title(time: Res<Time>, mut windows: ResMut<Windows>) {
|
fn change_title(time: Res<Time>, mut windows: ResMut<Windows>) {
|
||||||
let window = windows.primary_mut();
|
let window = windows.primary_mut();
|
||||||
|
Loading…
Reference in New Issue
Block a user