macOS: add option to explicitly hide menu/dock in Borderless (#3882)
This commit is contained in:
parent
9419e4e1a7
commit
d37c591378
3 changed files with 52 additions and 1 deletions
|
|
@ -63,6 +63,8 @@ changelog entry.
|
|||
and `Serialize` on many types.
|
||||
- Add `MonitorHandle::current_video_mode()`.
|
||||
- Add basic iOS IME support. The soft keyboard can now be shown using `Window::set_ime_allowed`.
|
||||
- On macOS, add `WindowExtMacOS::set_borderless_game` and `WindowAttributesExtMacOS::with_borderless_game`
|
||||
to fully disable the menu bar and dock in Borderless Fullscreen as commonly done in games.
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
|||
|
|
@ -150,6 +150,12 @@ pub trait WindowExtMacOS {
|
|||
|
||||
/// Getter for the [`WindowExtMacOS::set_option_as_alt`].
|
||||
fn option_as_alt(&self) -> OptionAsAlt;
|
||||
|
||||
/// Disable the Menu Bar and Dock in Borderless Fullscreen mode. Useful for games.
|
||||
fn set_borderless_game(&self, borderless_game: bool);
|
||||
|
||||
/// Getter for the [`WindowExtMacOS::set_borderless_game`].
|
||||
fn is_borderless_game(&self) -> bool;
|
||||
}
|
||||
|
||||
impl WindowExtMacOS for dyn Window + '_ {
|
||||
|
|
@ -236,6 +242,18 @@ impl WindowExtMacOS for dyn Window + '_ {
|
|||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.option_as_alt())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_borderless_game(&self, borderless_game: bool) {
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.set_borderless_game(borderless_game))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_borderless_game(&self) -> bool {
|
||||
let window = self.as_any().downcast_ref::<crate::platform_impl::Window>().unwrap();
|
||||
window.maybe_wait_on_main(|w| w.is_borderless_game())
|
||||
}
|
||||
}
|
||||
|
||||
/// Corresponds to `NSApplicationActivationPolicy`.
|
||||
|
|
@ -287,6 +305,8 @@ pub trait WindowAttributesExtMacOS {
|
|||
///
|
||||
/// See [`WindowExtMacOS::set_option_as_alt`] for details on what this means if set.
|
||||
fn with_option_as_alt(self, option_as_alt: OptionAsAlt) -> Self;
|
||||
/// See [`WindowExtMacOS::set_borderless_game`] for details on what this means if set.
|
||||
fn with_borderless_game(self, borderless_game: bool) -> Self;
|
||||
}
|
||||
|
||||
impl WindowAttributesExtMacOS for WindowAttributes {
|
||||
|
|
@ -355,6 +375,12 @@ impl WindowAttributesExtMacOS for WindowAttributes {
|
|||
self.platform_specific.option_as_alt = option_as_alt;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_borderless_game(mut self, borderless_game: bool) -> Self {
|
||||
self.platform_specific.borderless_game = borderless_game;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub trait EventLoopBuilderExtMacOS {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ pub struct PlatformSpecificWindowAttributes {
|
|||
pub accepts_first_mouse: bool,
|
||||
pub tabbing_identifier: Option<String>,
|
||||
pub option_as_alt: OptionAsAlt,
|
||||
pub borderless_game: bool,
|
||||
}
|
||||
|
||||
impl Default for PlatformSpecificWindowAttributes {
|
||||
|
|
@ -73,6 +74,7 @@ impl Default for PlatformSpecificWindowAttributes {
|
|||
accepts_first_mouse: true,
|
||||
tabbing_identifier: None,
|
||||
option_as_alt: Default::default(),
|
||||
borderless_game: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -121,6 +123,7 @@ pub(crate) struct State {
|
|||
standard_frame: Cell<Option<NSRect>>,
|
||||
is_simple_fullscreen: Cell<bool>,
|
||||
saved_style: Cell<Option<NSWindowStyleMask>>,
|
||||
is_borderless_game: Cell<bool>,
|
||||
}
|
||||
|
||||
declare_class!(
|
||||
|
|
@ -731,6 +734,7 @@ impl WindowDelegate {
|
|||
standard_frame: Cell::new(None),
|
||||
is_simple_fullscreen: Cell::new(false),
|
||||
saved_style: Cell::new(None),
|
||||
is_borderless_game: Cell::new(attrs.platform_specific.borderless_game),
|
||||
});
|
||||
let delegate: Retained<WindowDelegate> = unsafe { msg_send_id![super(delegate), init] };
|
||||
|
||||
|
|
@ -1417,7 +1421,7 @@ impl WindowDelegate {
|
|||
}
|
||||
|
||||
match (old_fullscreen, fullscreen) {
|
||||
(None, Some(_)) => {
|
||||
(None, Some(fullscreen)) => {
|
||||
// `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`.
|
||||
|
|
@ -1427,6 +1431,17 @@ impl WindowDelegate {
|
|||
self.set_style_mask(required);
|
||||
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::NSApplicationPresentationHideDock
|
||||
| NSApplicationPresentationOptions::NSApplicationPresentationHideMenuBar;
|
||||
app.setPresentationOptions(presentation_options);
|
||||
}
|
||||
|
||||
toggle_fullscreen(self.window());
|
||||
},
|
||||
(Some(Fullscreen::Borderless(_)), None) => {
|
||||
|
|
@ -1813,6 +1828,14 @@ impl WindowExtMacOS for WindowDelegate {
|
|||
fn option_as_alt(&self) -> OptionAsAlt {
|
||||
self.view().option_as_alt()
|
||||
}
|
||||
|
||||
fn set_borderless_game(&self, borderless_game: bool) {
|
||||
self.ivars().is_borderless_game.set(borderless_game);
|
||||
}
|
||||
|
||||
fn is_borderless_game(&self) -> bool {
|
||||
self.ivars().is_borderless_game.get()
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_STANDARD_FRAME: NSRect =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue