Add option to toggle window control buttons (#9083)
# Objective Implements #9082 but with an option to toggle minimize and close buttons too. ## Solution - Added an `enabled_buttons` member to the `Window` struct through which users can enable or disable specific window control buttons. --- ## Changelog - Added an `enabled_buttons` member to the `Window` struct through which users can enable or disable specific window control buttons. - Added a new system to the `window_settings` example which demonstrates the toggling functionality. --- ## Migration guide - Added an `enabled_buttons` member to the `Window` struct through which users can enable or disable specific window control buttons.
This commit is contained in:
parent
453bd058fe
commit
5e8ee108cb
@ -141,7 +141,8 @@ impl Plugin for WindowPlugin {
|
||||
.register_type::<InternalWindowState>()
|
||||
.register_type::<MonitorSelection>()
|
||||
.register_type::<WindowResizeConstraints>()
|
||||
.register_type::<WindowTheme>();
|
||||
.register_type::<WindowTheme>()
|
||||
.register_type::<EnabledButtons>();
|
||||
|
||||
// Register `PathBuf` as it's used by `FileDragAndDrop`
|
||||
app.register_type::<PathBuf>();
|
||||
|
@ -126,13 +126,21 @@ pub struct Window {
|
||||
/// Note: This does not stop the program from fullscreening/setting
|
||||
/// the size programmatically.
|
||||
pub resizable: bool,
|
||||
/// Specifies which window control buttons should be enabled.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// **`iOS`**, **`Android`**, and the **`Web`** do not have window control buttons.
|
||||
///
|
||||
/// On some **`Linux`** environments these values have no effect.
|
||||
pub enabled_buttons: EnabledButtons,
|
||||
/// Should the window have decorations enabled?
|
||||
///
|
||||
/// (Decorations are the minimize, maximize, and close buttons on desktop apps)
|
||||
///
|
||||
// ## Platform-specific
|
||||
//
|
||||
// **`iOS`**, **`Android`**, and the **`Web`** do not have decorations.
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// **`iOS`**, **`Android`**, and the **`Web`** do not have decorations.
|
||||
pub decorations: bool,
|
||||
/// Should the window be transparent?
|
||||
///
|
||||
@ -221,6 +229,7 @@ impl Default for Window {
|
||||
ime_enabled: Default::default(),
|
||||
ime_position: Default::default(),
|
||||
resizable: true,
|
||||
enabled_buttons: Default::default(),
|
||||
decorations: true,
|
||||
transparent: false,
|
||||
focused: true,
|
||||
@ -1001,3 +1010,42 @@ pub enum WindowTheme {
|
||||
/// Use the dark variant.
|
||||
Dark,
|
||||
}
|
||||
|
||||
/// Specifies which [`Window`] control buttons should be enabled.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// **`iOS`**, **`Android`**, and the **`Web`** do not have window control buttons.
|
||||
///
|
||||
/// On some **`Linux`** environments these values have no effect.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Reflect)]
|
||||
#[cfg_attr(
|
||||
feature = "serialize",
|
||||
derive(serde::Serialize, serde::Deserialize),
|
||||
reflect(Serialize, Deserialize)
|
||||
)]
|
||||
#[reflect(Debug, PartialEq, Default)]
|
||||
pub struct EnabledButtons {
|
||||
/// Enables the functionality of the minimize button.
|
||||
pub minimize: bool,
|
||||
/// Enables the functionality of the maximize button.
|
||||
///
|
||||
/// macOS note: When [`Window`] `resizable` member is set to `false`
|
||||
/// the maximize button will be disabled regardless of this value.
|
||||
/// Additionaly, when `resizable` is set to `true` the window will
|
||||
/// be maximized when its bar is double-clicked regardless of whether
|
||||
/// the maximize button is enabled or not.
|
||||
pub maximize: bool,
|
||||
/// Enables the functionality of the close button.
|
||||
pub close: bool,
|
||||
}
|
||||
|
||||
impl Default for EnabledButtons {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
minimize: true,
|
||||
maximize: true,
|
||||
close: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use bevy_input::{
|
||||
ButtonState,
|
||||
};
|
||||
use bevy_math::Vec2;
|
||||
use bevy_window::{CursorIcon, WindowLevel, WindowTheme};
|
||||
use bevy_window::{CursorIcon, EnabledButtons, WindowLevel, WindowTheme};
|
||||
|
||||
pub fn convert_keyboard_input(
|
||||
keyboard_input: &winit::event::KeyboardInput,
|
||||
@ -293,3 +293,17 @@ pub fn convert_window_theme(theme: WindowTheme) -> winit::window::Theme {
|
||||
WindowTheme::Dark => winit::window::Theme::Dark,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn convert_enabled_buttons(enabled_buttons: EnabledButtons) -> winit::window::WindowButtons {
|
||||
let mut window_buttons = winit::window::WindowButtons::empty();
|
||||
if enabled_buttons.minimize {
|
||||
window_buttons.insert(winit::window::WindowButtons::MINIMIZE);
|
||||
}
|
||||
if enabled_buttons.maximize {
|
||||
window_buttons.insert(winit::window::WindowButtons::MAXIMIZE);
|
||||
}
|
||||
if enabled_buttons.close {
|
||||
window_buttons.insert(winit::window::WindowButtons::CLOSE);
|
||||
}
|
||||
window_buttons
|
||||
}
|
||||
|
@ -23,7 +23,10 @@ use winit::{
|
||||
use crate::web_resize::{CanvasParentResizeEventChannel, WINIT_CANVAS_SELECTOR};
|
||||
use crate::{
|
||||
accessibility::{AccessKitAdapters, WinitActionHandlers},
|
||||
converters::{self, convert_window_level, convert_window_theme, convert_winit_theme},
|
||||
converters::{
|
||||
self, convert_enabled_buttons, convert_window_level, convert_window_theme,
|
||||
convert_winit_theme,
|
||||
},
|
||||
get_best_videomode, get_fitting_videomode, WinitWindows,
|
||||
};
|
||||
|
||||
@ -222,6 +225,10 @@ pub(crate) fn changed_window(
|
||||
winit_window.set_resizable(window.resizable);
|
||||
}
|
||||
|
||||
if window.enabled_buttons != cache.window.enabled_buttons {
|
||||
winit_window.set_enabled_buttons(convert_enabled_buttons(window.enabled_buttons));
|
||||
}
|
||||
|
||||
if window.resize_constraints != cache.window.resize_constraints {
|
||||
let constraints = window.resize_constraints.check_constraints();
|
||||
let min_inner_size = LogicalSize {
|
||||
|
@ -18,7 +18,7 @@ use winit::{
|
||||
|
||||
use crate::{
|
||||
accessibility::{AccessKitAdapters, WinitActionHandler, WinitActionHandlers},
|
||||
converters::{convert_window_level, convert_window_theme},
|
||||
converters::{convert_enabled_buttons, convert_window_level, convert_window_theme},
|
||||
};
|
||||
|
||||
/// A resource which maps window entities to [`winit`] library windows.
|
||||
@ -94,6 +94,7 @@ impl WinitWindows {
|
||||
.with_window_level(convert_window_level(window.window_level))
|
||||
.with_theme(window.window_theme.map(convert_window_theme))
|
||||
.with_resizable(window.resizable)
|
||||
.with_enabled_buttons(convert_enabled_buttons(window.enabled_buttons))
|
||||
.with_decorations(window.decorations)
|
||||
.with_transparent(window.transparent);
|
||||
|
||||
|
@ -20,6 +20,10 @@ fn main() {
|
||||
// Tells wasm not to override default event handling, like F5, Ctrl+R etc.
|
||||
prevent_default_event_handling: false,
|
||||
window_theme: Some(WindowTheme::Dark),
|
||||
enabled_buttons: bevy::window::EnabledButtons {
|
||||
maximize: false,
|
||||
..Default::default()
|
||||
},
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
@ -34,6 +38,7 @@ fn main() {
|
||||
toggle_theme,
|
||||
toggle_cursor,
|
||||
toggle_vsync,
|
||||
toggle_window_controls,
|
||||
cycle_cursor_icon,
|
||||
switch_level,
|
||||
),
|
||||
@ -76,6 +81,31 @@ fn switch_level(input: Res<Input<KeyCode>>, mut windows: Query<&mut Window>) {
|
||||
}
|
||||
}
|
||||
|
||||
/// This system toggles the window controls when pressing buttons 1, 2 and 3
|
||||
///
|
||||
/// This feature only works on some platforms. Please check the
|
||||
/// [documentation](https://docs.rs/bevy/latest/bevy/prelude/struct.Window.html#structfield.enabled_buttons)
|
||||
/// for more details.
|
||||
fn toggle_window_controls(input: Res<Input<KeyCode>>, mut windows: Query<&mut Window>) {
|
||||
let toggle_minimize = input.just_pressed(KeyCode::Key1);
|
||||
let toggle_maximize = input.just_pressed(KeyCode::Key2);
|
||||
let toggle_close = input.just_pressed(KeyCode::Key3);
|
||||
|
||||
if toggle_minimize || toggle_maximize || toggle_close {
|
||||
let mut window = windows.single_mut();
|
||||
|
||||
if toggle_minimize {
|
||||
window.enabled_buttons.minimize = !window.enabled_buttons.minimize;
|
||||
}
|
||||
if toggle_maximize {
|
||||
window.enabled_buttons.maximize = !window.enabled_buttons.maximize;
|
||||
}
|
||||
if toggle_close {
|
||||
window.enabled_buttons.close = !window.enabled_buttons.close;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This system will then change the title during execution
|
||||
fn change_title(mut windows: Query<&mut Window>, time: Res<Time>) {
|
||||
let mut window = windows.single_mut();
|
||||
|
Loading…
Reference in New Issue
Block a user