diff --git a/winit-appkit/src/window_delegate.rs b/winit-appkit/src/window_delegate.rs index fe4da61ef..7a30b7f74 100644 --- a/winit-appkit/src/window_delegate.rs +++ b/winit-appkit/src/window_delegate.rs @@ -330,6 +330,20 @@ define_class!( trace_scope!("windowDidChangeOcclusionState:"); let visible = self.window().occlusionState().contains(NSWindowOcclusionState::Visible); self.queue_event(WindowEvent::Occluded(!visible)); + + // We do this here rather than in `window:willUseFullScreenPresentationOptions` + // because doing it there leaves the menu bar interactable despite being hidden. + // Moving it here produces the most consistent results. + if self.is_borderless_game() + && matches!(*self.ivars().fullscreen.borrow(), Some(Fullscreen::Borderless(_))) + { + let mtm = MainThreadMarker::from(self); + let app = NSApplication::sharedApplication(mtm); + app.setPresentationOptions( + NSApplicationPresentationOptions::HideDock + | NSApplicationPresentationOptions::HideMenuBar, + ); + } } #[unsafe(method(windowDidChangeScreen:))] @@ -1534,7 +1548,7 @@ impl WindowDelegate { } match (old_fullscreen, fullscreen) { - (None, Some(fullscreen)) => { + (None, Some(_)) => { // `toggleFullScreen` doesn't work if the `StyleMask` is none, so we // set a normal style temporarily. The previous state will be // restored in `WindowDelegate::window_did_exit_fullscreen`. @@ -1545,16 +1559,6 @@ impl WindowDelegate { self.ivars().saved_style.set(Some(curr_mask)); } - // In borderless games, we want to disable the dock and menu bar - // by setting the presentation options. We do this here rather than in - // `window:willUseFullScreenPresentationOptions` because for some reason - // the menu bar remains interactable despite being hidden. - if self.is_borderless_game() && matches!(fullscreen, Fullscreen::Borderless(_)) { - let presentation_options = NSApplicationPresentationOptions::HideDock - | NSApplicationPresentationOptions::HideMenuBar; - app.setPresentationOptions(presentation_options); - } - toggle_fullscreen(self.window()); }, (Some(Fullscreen::Borderless(_)), None) => { diff --git a/winit/examples/application.rs b/winit/examples/application.rs index dc432bb0e..bc8d7dee6 100644 --- a/winit/examples/application.rs +++ b/winit/examples/application.rs @@ -251,6 +251,12 @@ impl Application { Action::ToggleSimpleFullscreen => { window.window.set_simple_fullscreen(!window.window.simple_fullscreen()); }, + #[cfg(macos_platform)] + Action::ToggleBorderlessGame => { + let current = window.window.is_borderless_game(); + window.window.set_borderless_game(!current); + info!("Borderless game: {}", !current); + }, Action::ToggleMaximize => window.toggle_maximize(), Action::Minimize => window.minimize(), Action::NextCursor => window.next_cursor(), @@ -1027,6 +1033,8 @@ enum Action { ToggleFullscreen, #[cfg(macos_platform)] ToggleSimpleFullscreen, + #[cfg(macos_platform)] + ToggleBorderlessGame, ToggleMaximize, Minimize, NextCursor, @@ -1064,6 +1072,8 @@ impl Action { Action::ToggleFullscreen => "Toggle fullscreen", #[cfg(macos_platform)] Action::ToggleSimpleFullscreen => "Toggle simple fullscreen", + #[cfg(macos_platform)] + Action::ToggleBorderlessGame => "Toggle borderless game mode", Action::ToggleMaximize => "Maximize", Action::Minimize => "Minimize", Action::ToggleResizeIncrements => "Use resize increments when resizing window", @@ -1315,6 +1325,8 @@ const KEY_BINDINGS: &[Binding<&'static str>] = &[ Binding::new("T", ModifiersState::META, Action::CreateNewTab), #[cfg(macos_platform)] Binding::new("O", ModifiersState::CONTROL, Action::CycleOptionAsAlt), + #[cfg(macos_platform)] + Binding::new("B", ModifiersState::CONTROL, Action::ToggleBorderlessGame), Binding::new("S", ModifiersState::ALT, Action::EmitSurfaceSize), Binding::new("S", ModifiersState::CONTROL, Action::Message), ]; diff --git a/winit/src/changelog/unreleased.md b/winit/src/changelog/unreleased.md index 14d27a6b3..c90eb1122 100644 --- a/winit/src/changelog/unreleased.md +++ b/winit/src/changelog/unreleased.md @@ -54,3 +54,4 @@ changelog entry. - On X11, fix `set_hittest` not working on some window managers. - On Redox, handle `EINTR` when reading from `event_socket` instead of panicking. - On Wayland, switch from using the `ahash` hashing algorithm to `foldhash`. +- On macOS, fix borderless game presentation options not sticking after switching spaces.