On Windows and macOS, add API to enable/disable window controls (#2537)
* On Windows and macOS, add API to enable/disable window controls * fix build * missing import * use `WindowButtons` flags * rename to `[set_]enabled_buttons` * add example, fix windows impl for minimize * macOS: Fix button enabling close/minimize while disabling maximized * Update src/platform_impl/windows/window.rs Co-authored-by: Kirill Chibisov <contact@kchibisov.com> * compose the flags on a sep line, use `bool::then` Co-authored-by: Mads Marquart <mads@marquart.dk> Co-authored-by: Kirill Chibisov <contact@kchibisov.com>
This commit is contained in:
parent
28e34c2e1b
commit
94688a62f0
14 changed files with 343 additions and 36 deletions
|
|
@ -1,5 +1,5 @@
|
|||
use objc2::foundation::NSObject;
|
||||
use objc2::{extern_class, ClassType};
|
||||
use objc2::{extern_class, extern_methods, ClassType};
|
||||
|
||||
use super::{NSResponder, NSView};
|
||||
|
||||
|
|
@ -12,3 +12,13 @@ extern_class!(
|
|||
type Super = NSView;
|
||||
}
|
||||
);
|
||||
|
||||
extern_methods!(
|
||||
unsafe impl NSControl {
|
||||
#[sel(setEnabled:)]
|
||||
pub fn setEnabled(&self, enabled: bool);
|
||||
|
||||
#[sel(isEnabled)]
|
||||
pub fn isEnabled(&self) -> bool;
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -180,6 +180,12 @@ extern_methods!(
|
|||
#[sel(isResizable)]
|
||||
pub fn isResizable(&self) -> bool;
|
||||
|
||||
#[sel(isMiniaturizable)]
|
||||
pub fn isMiniaturizable(&self) -> bool;
|
||||
|
||||
#[sel(hasCloseBox)]
|
||||
pub fn hasCloseBox(&self) -> bool;
|
||||
|
||||
#[sel(isMiniaturized)]
|
||||
pub fn isMiniaturized(&self) -> bool;
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ use crate::{
|
|||
Fullscreen, OsError,
|
||||
},
|
||||
window::{
|
||||
CursorGrabMode, CursorIcon, Theme, UserAttentionType, WindowAttributes,
|
||||
CursorGrabMode, CursorIcon, Theme, UserAttentionType, WindowAttributes, WindowButtons,
|
||||
WindowId as RootWindowId, WindowLevel,
|
||||
},
|
||||
};
|
||||
|
|
@ -269,6 +269,14 @@ impl WinitWindow {
|
|||
masks &= !NSWindowStyleMask::NSResizableWindowMask;
|
||||
}
|
||||
|
||||
if !attrs.enabled_buttons.contains(WindowButtons::MINIMIZE) {
|
||||
masks &= !NSWindowStyleMask::NSMiniaturizableWindowMask;
|
||||
}
|
||||
|
||||
if !attrs.enabled_buttons.contains(WindowButtons::CLOSE) {
|
||||
masks &= !NSWindowStyleMask::NSClosableWindowMask;
|
||||
}
|
||||
|
||||
if pl_attrs.fullsize_content_view {
|
||||
masks |= NSWindowStyleMask::NSFullSizeContentViewWindowMask;
|
||||
}
|
||||
|
|
@ -333,6 +341,12 @@ impl WinitWindow {
|
|||
this.setMovableByWindowBackground(true);
|
||||
}
|
||||
|
||||
if !attrs.enabled_buttons.contains(WindowButtons::MAXIMIZE) {
|
||||
if let Some(button) = this.standardWindowButton(NSWindowButton::Zoom) {
|
||||
button.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(increments) = attrs.resize_increments {
|
||||
let increments = increments.to_logical(this.scale_factor());
|
||||
let (w, h) = (increments.width, increments.height);
|
||||
|
|
@ -624,6 +638,53 @@ impl WinitWindow {
|
|||
self.isResizable()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_enabled_buttons(&self, buttons: WindowButtons) {
|
||||
let mut mask = self.styleMask();
|
||||
|
||||
if buttons.contains(WindowButtons::CLOSE) {
|
||||
mask |= NSWindowStyleMask::NSClosableWindowMask;
|
||||
} else {
|
||||
mask &= !NSWindowStyleMask::NSClosableWindowMask;
|
||||
}
|
||||
|
||||
if buttons.contains(WindowButtons::MINIMIZE) {
|
||||
mask |= NSWindowStyleMask::NSMiniaturizableWindowMask;
|
||||
} else {
|
||||
mask &= !NSWindowStyleMask::NSMiniaturizableWindowMask;
|
||||
}
|
||||
|
||||
// This must happen before the button's "enabled" status has been set,
|
||||
// hence we do it synchronously.
|
||||
self.set_style_mask_sync(mask);
|
||||
|
||||
// We edit the button directly instead of using `NSResizableWindowMask`,
|
||||
// since that mask also affect the resizability of the window (which is
|
||||
// controllable by other means in `winit`).
|
||||
if let Some(button) = self.standardWindowButton(NSWindowButton::Zoom) {
|
||||
button.setEnabled(buttons.contains(WindowButtons::MAXIMIZE));
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn enabled_buttons(&self) -> WindowButtons {
|
||||
let mut buttons = WindowButtons::empty();
|
||||
if self.isMiniaturizable() {
|
||||
buttons |= WindowButtons::MINIMIZE;
|
||||
}
|
||||
if self
|
||||
.standardWindowButton(NSWindowButton::Zoom)
|
||||
.map(|b| b.isEnabled())
|
||||
.unwrap_or(true)
|
||||
{
|
||||
buttons |= WindowButtons::MAXIMIZE;
|
||||
}
|
||||
if self.hasCloseBox() {
|
||||
buttons |= WindowButtons::CLOSE;
|
||||
}
|
||||
buttons
|
||||
}
|
||||
|
||||
pub fn set_cursor_icon(&self, icon: CursorIcon) {
|
||||
let view = self.view();
|
||||
let mut cursor_state = view.state.cursor_state.lock().unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue