Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to toggle window control buttons #9083

Merged
merged 3 commits into from
Jul 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion crates/bevy_window/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>();
Expand Down
54 changes: 51 additions & 3 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
mockersf marked this conversation as resolved.
Show resolved Hide resolved
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.
aleksa2808 marked this conversation as resolved.
Show resolved Hide resolved
pub decorations: bool,
mockersf marked this conversation as resolved.
Show resolved Hide resolved
/// Should the window be transparent?
///
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -963,3 +972,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 {
mockersf marked this conversation as resolved.
Show resolved Hide resolved
/// 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,
}
}
}
16 changes: 15 additions & 1 deletion crates/bevy_winit/src/converters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
}
9 changes: 8 additions & 1 deletion crates/bevy_winit/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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 {
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 @@ -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.
Expand Down Expand Up @@ -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);

Expand Down
30 changes: 30 additions & 0 deletions examples/window/window_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -34,6 +38,7 @@ fn main() {
toggle_theme,
toggle_cursor,
toggle_vsync,
toggle_window_controls,
cycle_cursor_icon,
switch_level,
),
Expand Down Expand Up @@ -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();
Expand Down