Update objc2 crates (#3634)
Changes relevant to Winit: - `icrate` has been deprecated in favour of separate crates per framework, in our case `objc2-foundation` and `objc2-app-kit` (and in the future `objc2-ui-kit` on iOS). - Moved `MainThreadMarker::run_on_main` to free-standing function `run_on_main`. - Changed how features work, this should result in less code that we need to compile. - Enums are now real structs instead of type-aliases and free constants.
This commit is contained in:
parent
575d978202
commit
259e868c05
38 changed files with 289 additions and 270 deletions
|
|
@ -4,29 +4,24 @@ use std::collections::VecDeque;
|
|||
use std::ptr;
|
||||
|
||||
use core_graphics::display::{CGDisplay, CGPoint};
|
||||
use icrate::AppKit::{
|
||||
NSAppKitVersionNumber, NSAppKitVersionNumber10_12, NSAppearance, NSApplication,
|
||||
NSApplicationPresentationAutoHideDock, NSApplicationPresentationAutoHideMenuBar,
|
||||
NSApplicationPresentationFullScreen, NSApplicationPresentationHideDock,
|
||||
NSApplicationPresentationHideMenuBar, NSApplicationPresentationOptions, NSBackingStoreBuffered,
|
||||
NSColor, NSCriticalRequest, NSDraggingDestination, NSFilenamesPboardType,
|
||||
NSInformationalRequest, NSPasteboard, NSScreen, NSView, NSWindowAbove, NSWindowCloseButton,
|
||||
NSWindowDelegate, NSWindowFullScreenButton, NSWindowLevel, NSWindowMiniaturizeButton,
|
||||
NSWindowOcclusionStateVisible, NSWindowSharingNone, NSWindowSharingReadOnly, NSWindowStyleMask,
|
||||
NSWindowStyleMaskBorderless, NSWindowStyleMaskClosable, NSWindowStyleMaskFullSizeContentView,
|
||||
NSWindowStyleMaskMiniaturizable, NSWindowStyleMaskResizable, NSWindowStyleMaskTitled,
|
||||
NSWindowTabbingModePreferred, NSWindowTitleHidden, NSWindowZoomButton,
|
||||
};
|
||||
use icrate::Foundation::{
|
||||
CGFloat, MainThreadMarker, NSArray, NSCopying, NSObject, NSObjectProtocol, NSPoint, NSRect,
|
||||
NSSize, NSString,
|
||||
};
|
||||
use monitor::VideoModeHandle;
|
||||
use objc2::rc::{autoreleasepool, Id};
|
||||
use objc2::runtime::{AnyObject, ProtocolObject};
|
||||
use objc2::{
|
||||
class, declare_class, msg_send, msg_send_id, mutability, sel, ClassType, DeclaredClass,
|
||||
};
|
||||
use objc2_app_kit::{
|
||||
NSAppKitVersionNumber, NSAppKitVersionNumber10_12, NSAppearance, NSApplication,
|
||||
NSApplicationPresentationOptions, NSBackingStoreType, NSColor, NSDraggingDestination,
|
||||
NSFilenamesPboardType, NSPasteboard, NSRequestUserAttentionType, NSScreen, NSView,
|
||||
NSWindowButton, NSWindowDelegate, NSWindowFullScreenButton, NSWindowLevel,
|
||||
NSWindowOcclusionState, NSWindowOrderingMode, NSWindowSharingType, NSWindowStyleMask,
|
||||
NSWindowTabbingMode, NSWindowTitleVisibility,
|
||||
};
|
||||
use objc2_foundation::{
|
||||
CGFloat, MainThreadMarker, NSArray, NSCopying, NSObject, NSObjectProtocol, NSPoint, NSRect,
|
||||
NSSize, NSString,
|
||||
};
|
||||
|
||||
use super::app_delegate::ApplicationDelegate;
|
||||
use super::cursor::cursor_from_icon;
|
||||
|
|
@ -266,9 +261,11 @@ declare_class!(
|
|||
let mut options = proposed_options;
|
||||
let fullscreen = self.ivars().fullscreen.borrow();
|
||||
if let Some(Fullscreen::Exclusive(_)) = &*fullscreen {
|
||||
options = NSApplicationPresentationFullScreen
|
||||
| NSApplicationPresentationHideDock
|
||||
| NSApplicationPresentationHideMenuBar;
|
||||
options = NSApplicationPresentationOptions(
|
||||
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen.0
|
||||
| NSApplicationPresentationOptions::NSApplicationPresentationHideDock.0
|
||||
| NSApplicationPresentationOptions::NSApplicationPresentationHideMenuBar.0,
|
||||
);
|
||||
}
|
||||
|
||||
options
|
||||
|
|
@ -337,8 +334,8 @@ declare_class!(
|
|||
#[method(windowDidChangeOcclusionState:)]
|
||||
fn window_did_change_occlusion_state(&self, _: Option<&AnyObject>) {
|
||||
trace_scope!("windowDidChangeOcclusionState:");
|
||||
let visible = self.window().occlusionState() & NSWindowOcclusionStateVisible
|
||||
== NSWindowOcclusionStateVisible;
|
||||
let visible = self.window().occlusionState().0 & NSWindowOcclusionState::Visible.0
|
||||
== NSWindowOcclusionState::Visible.0;
|
||||
self.queue_event(WindowEvent::Occluded(!visible));
|
||||
}
|
||||
|
||||
|
|
@ -490,39 +487,39 @@ fn new_window(attrs: &WindowAttributes, mtm: MainThreadMarker) -> Option<Id<Wini
|
|||
// if decorations is set to false, ignore pl_attrs
|
||||
//
|
||||
// if the titlebar is hidden, ignore other pl_attrs
|
||||
NSWindowStyleMaskBorderless
|
||||
| NSWindowStyleMaskResizable
|
||||
| NSWindowStyleMaskMiniaturizable
|
||||
NSWindowStyleMask::Borderless.0
|
||||
| NSWindowStyleMask::Resizable.0
|
||||
| NSWindowStyleMask::Miniaturizable.0
|
||||
} else {
|
||||
// default case, resizable window with titlebar and titlebar buttons
|
||||
NSWindowStyleMaskClosable
|
||||
| NSWindowStyleMaskMiniaturizable
|
||||
| NSWindowStyleMaskResizable
|
||||
| NSWindowStyleMaskTitled
|
||||
NSWindowStyleMask::Closable.0
|
||||
| NSWindowStyleMask::Miniaturizable.0
|
||||
| NSWindowStyleMask::Resizable.0
|
||||
| NSWindowStyleMask::Titled.0
|
||||
};
|
||||
|
||||
if !attrs.resizable {
|
||||
masks &= !NSWindowStyleMaskResizable;
|
||||
masks &= !NSWindowStyleMask::Resizable.0;
|
||||
}
|
||||
|
||||
if !attrs.enabled_buttons.contains(WindowButtons::MINIMIZE) {
|
||||
masks &= !NSWindowStyleMaskMiniaturizable;
|
||||
masks &= !NSWindowStyleMask::Miniaturizable.0;
|
||||
}
|
||||
|
||||
if !attrs.enabled_buttons.contains(WindowButtons::CLOSE) {
|
||||
masks &= !NSWindowStyleMaskClosable;
|
||||
masks &= !NSWindowStyleMask::Closable.0;
|
||||
}
|
||||
|
||||
if attrs.platform_specific.fullsize_content_view {
|
||||
masks |= NSWindowStyleMaskFullSizeContentView;
|
||||
masks |= NSWindowStyleMask::FullSizeContentView.0;
|
||||
}
|
||||
|
||||
let window: Option<Id<WinitWindow>> = unsafe {
|
||||
msg_send_id![
|
||||
super(mtm.alloc().set_ivars(())),
|
||||
initWithContentRect: frame,
|
||||
styleMask: masks,
|
||||
backing: NSBackingStoreBuffered,
|
||||
styleMask: NSWindowStyleMask(masks),
|
||||
backing: NSBackingStoreType::NSBackingStoreBuffered,
|
||||
defer: false,
|
||||
]
|
||||
};
|
||||
|
|
@ -538,26 +535,26 @@ fn new_window(attrs: &WindowAttributes, mtm: MainThreadMarker) -> Option<Id<Wini
|
|||
|
||||
if let Some(identifier) = &attrs.platform_specific.tabbing_identifier {
|
||||
window.setTabbingIdentifier(&NSString::from_str(identifier));
|
||||
window.setTabbingMode(NSWindowTabbingModePreferred);
|
||||
window.setTabbingMode(NSWindowTabbingMode::Preferred);
|
||||
}
|
||||
|
||||
if attrs.content_protected {
|
||||
window.setSharingType(NSWindowSharingNone);
|
||||
window.setSharingType(NSWindowSharingType::NSWindowSharingNone);
|
||||
}
|
||||
|
||||
if attrs.platform_specific.titlebar_transparent {
|
||||
window.setTitlebarAppearsTransparent(true);
|
||||
}
|
||||
if attrs.platform_specific.title_hidden {
|
||||
window.setTitleVisibility(NSWindowTitleHidden);
|
||||
window.setTitleVisibility(NSWindowTitleVisibility::NSWindowTitleHidden);
|
||||
}
|
||||
if attrs.platform_specific.titlebar_buttons_hidden {
|
||||
for titlebar_button in &[
|
||||
#[allow(deprecated)]
|
||||
NSWindowFullScreenButton,
|
||||
NSWindowMiniaturizeButton,
|
||||
NSWindowCloseButton,
|
||||
NSWindowZoomButton,
|
||||
NSWindowButton::NSWindowMiniaturizeButton,
|
||||
NSWindowButton::NSWindowCloseButton,
|
||||
NSWindowButton::NSWindowZoomButton,
|
||||
] {
|
||||
if let Some(button) = window.standardWindowButton(*titlebar_button) {
|
||||
button.setHidden(true);
|
||||
|
|
@ -569,7 +566,7 @@ fn new_window(attrs: &WindowAttributes, mtm: MainThreadMarker) -> Option<Id<Wini
|
|||
}
|
||||
|
||||
if !attrs.enabled_buttons.contains(WindowButtons::MAXIMIZE) {
|
||||
if let Some(button) = window.standardWindowButton(NSWindowZoomButton) {
|
||||
if let Some(button) = window.standardWindowButton(NSWindowButton::NSWindowZoomButton) {
|
||||
button.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -641,7 +638,9 @@ impl WindowDelegate {
|
|||
|
||||
// SAFETY: We know that there are no parent -> child -> parent cycles since the only place in `winit`
|
||||
// where we allow making a window a child window is right here, just after it's been created.
|
||||
unsafe { parent.addChildWindow_ordered(&window, NSWindowAbove) };
|
||||
unsafe {
|
||||
parent.addChildWindow_ordered(&window, NSWindowOrderingMode::NSWindowAbove)
|
||||
};
|
||||
}
|
||||
Some(raw) => panic!("invalid raw window handle {raw:?} on macOS"),
|
||||
None => (),
|
||||
|
|
@ -975,13 +974,13 @@ impl WindowDelegate {
|
|||
self.ivars().resizable.set(resizable);
|
||||
let fullscreen = self.ivars().fullscreen.borrow().is_some();
|
||||
if !fullscreen {
|
||||
let mut mask = self.window().styleMask();
|
||||
let mut mask = self.window().styleMask().0;
|
||||
if resizable {
|
||||
mask |= NSWindowStyleMaskResizable;
|
||||
mask |= NSWindowStyleMask::Resizable.0;
|
||||
} else {
|
||||
mask &= !NSWindowStyleMaskResizable;
|
||||
mask &= !NSWindowStyleMask::Resizable.0;
|
||||
}
|
||||
self.set_style_mask(mask);
|
||||
self.set_style_mask(NSWindowStyleMask(mask));
|
||||
}
|
||||
// Otherwise, we don't change the mask until we exit fullscreen.
|
||||
}
|
||||
|
|
@ -993,28 +992,31 @@ impl WindowDelegate {
|
|||
|
||||
#[inline]
|
||||
pub fn set_enabled_buttons(&self, buttons: WindowButtons) {
|
||||
let mut mask = self.window().styleMask();
|
||||
let mut mask = self.window().styleMask().0;
|
||||
|
||||
if buttons.contains(WindowButtons::CLOSE) {
|
||||
mask |= NSWindowStyleMaskClosable;
|
||||
mask |= NSWindowStyleMask::Closable.0;
|
||||
} else {
|
||||
mask &= !NSWindowStyleMaskClosable;
|
||||
mask &= !NSWindowStyleMask::Closable.0;
|
||||
}
|
||||
|
||||
if buttons.contains(WindowButtons::MINIMIZE) {
|
||||
mask |= NSWindowStyleMaskMiniaturizable;
|
||||
mask |= NSWindowStyleMask::Miniaturizable.0;
|
||||
} else {
|
||||
mask &= !NSWindowStyleMaskMiniaturizable;
|
||||
mask &= !NSWindowStyleMask::Miniaturizable.0;
|
||||
}
|
||||
|
||||
// This must happen before the button's "enabled" status has been set,
|
||||
// hence we do it synchronously.
|
||||
self.set_style_mask(mask);
|
||||
self.set_style_mask(NSWindowStyleMask(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.window().standardWindowButton(NSWindowZoomButton) {
|
||||
if let Some(button) = self
|
||||
.window()
|
||||
.standardWindowButton(NSWindowButton::NSWindowZoomButton)
|
||||
{
|
||||
button.setEnabled(buttons.contains(WindowButtons::MAXIMIZE));
|
||||
}
|
||||
}
|
||||
|
|
@ -1027,7 +1029,7 @@ impl WindowDelegate {
|
|||
}
|
||||
if self
|
||||
.window()
|
||||
.standardWindowButton(NSWindowZoomButton)
|
||||
.standardWindowButton(NSWindowButton::NSWindowZoomButton)
|
||||
.map(|b| b.isEnabled())
|
||||
.unwrap_or(true)
|
||||
{
|
||||
|
|
@ -1131,7 +1133,8 @@ impl WindowDelegate {
|
|||
// we make it resizable temporarily.
|
||||
let curr_mask = self.window().styleMask();
|
||||
|
||||
let required = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable;
|
||||
let required =
|
||||
NSWindowStyleMask(NSWindowStyleMask::Titled.0 | NSWindowStyleMask::Resizable.0);
|
||||
let needs_temp_mask = !mask_contains(curr_mask, required);
|
||||
if needs_temp_mask {
|
||||
self.set_style_mask(required);
|
||||
|
|
@ -1152,12 +1155,13 @@ impl WindowDelegate {
|
|||
.ivars()
|
||||
.saved_style
|
||||
.take()
|
||||
.unwrap_or_else(|| self.window().styleMask());
|
||||
if self.ivars().resizable.get() {
|
||||
base_mask | NSWindowStyleMaskResizable
|
||||
.unwrap_or_else(|| self.window().styleMask())
|
||||
.0;
|
||||
NSWindowStyleMask(if self.ivars().resizable.get() {
|
||||
base_mask | NSWindowStyleMask::Resizable.0
|
||||
} else {
|
||||
base_mask & !NSWindowStyleMaskResizable
|
||||
}
|
||||
base_mask & !NSWindowStyleMask::Resizable.0
|
||||
})
|
||||
}
|
||||
|
||||
/// This is called when the window is exiting fullscreen, whether by the
|
||||
|
|
@ -1212,7 +1216,7 @@ impl WindowDelegate {
|
|||
return;
|
||||
}
|
||||
|
||||
if mask_contains(self.window().styleMask(), NSWindowStyleMaskResizable) {
|
||||
if mask_contains(self.window().styleMask(), NSWindowStyleMask::Resizable) {
|
||||
// Just use the native zoom if resizable
|
||||
self.window().zoom(None);
|
||||
} else {
|
||||
|
|
@ -1369,7 +1373,8 @@ impl WindowDelegate {
|
|||
// set a normal style temporarily. The previous state will be
|
||||
// restored in `WindowDelegate::window_did_exit_fullscreen`.
|
||||
let curr_mask = self.window().styleMask();
|
||||
let required = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable;
|
||||
let required =
|
||||
NSWindowStyleMask(NSWindowStyleMask::Titled.0 | NSWindowStyleMask::Resizable.0);
|
||||
if !mask_contains(curr_mask, required) {
|
||||
self.set_style_mask(required);
|
||||
self.ivars().saved_style.set(Some(curr_mask));
|
||||
|
|
@ -1403,9 +1408,11 @@ impl WindowDelegate {
|
|||
.save_presentation_opts
|
||||
.set(Some(app.presentationOptions()));
|
||||
|
||||
let presentation_options = NSApplicationPresentationFullScreen
|
||||
| NSApplicationPresentationHideDock
|
||||
| NSApplicationPresentationHideMenuBar;
|
||||
let presentation_options = NSApplicationPresentationOptions(
|
||||
NSApplicationPresentationOptions::NSApplicationPresentationFullScreen.0
|
||||
| NSApplicationPresentationOptions::NSApplicationPresentationHideDock.0
|
||||
| NSApplicationPresentationOptions::NSApplicationPresentationHideMenuBar.0,
|
||||
);
|
||||
app.setPresentationOptions(presentation_options);
|
||||
|
||||
let window_level = unsafe { ffi::CGShieldingWindowLevel() } as NSWindowLevel + 1;
|
||||
|
|
@ -1413,9 +1420,9 @@ impl WindowDelegate {
|
|||
}
|
||||
(Some(Fullscreen::Exclusive(ref video_mode)), Some(Fullscreen::Borderless(_))) => {
|
||||
let presentation_options = self.ivars().save_presentation_opts.get().unwrap_or(
|
||||
NSApplicationPresentationFullScreen
|
||||
| NSApplicationPresentationAutoHideDock
|
||||
| NSApplicationPresentationAutoHideMenuBar,
|
||||
NSApplicationPresentationOptions(NSApplicationPresentationOptions::NSApplicationPresentationFullScreen.0
|
||||
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideDock.0
|
||||
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideMenuBar.0),
|
||||
);
|
||||
app.setPresentationOptions(presentation_options);
|
||||
|
||||
|
|
@ -1455,19 +1462,19 @@ impl WindowDelegate {
|
|||
|
||||
let new_mask = {
|
||||
let mut new_mask = if decorations {
|
||||
NSWindowStyleMaskClosable
|
||||
| NSWindowStyleMaskMiniaturizable
|
||||
| NSWindowStyleMaskResizable
|
||||
| NSWindowStyleMaskTitled
|
||||
NSWindowStyleMask::Closable.0
|
||||
| NSWindowStyleMask::Miniaturizable.0
|
||||
| NSWindowStyleMask::Resizable.0
|
||||
| NSWindowStyleMask::Titled.0
|
||||
} else {
|
||||
NSWindowStyleMaskBorderless | NSWindowStyleMaskResizable
|
||||
NSWindowStyleMask::Borderless.0 | NSWindowStyleMask::Resizable.0
|
||||
};
|
||||
if !resizable {
|
||||
new_mask &= !NSWindowStyleMaskResizable;
|
||||
new_mask &= !NSWindowStyleMask::Resizable.0;
|
||||
}
|
||||
new_mask
|
||||
};
|
||||
self.set_style_mask(new_mask);
|
||||
self.set_style_mask(NSWindowStyleMask(new_mask));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -1534,8 +1541,8 @@ impl WindowDelegate {
|
|||
pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
|
||||
let mtm = MainThreadMarker::from(self);
|
||||
let ns_request_type = request_type.map(|ty| match ty {
|
||||
UserAttentionType::Critical => NSCriticalRequest,
|
||||
UserAttentionType::Informational => NSInformationalRequest,
|
||||
UserAttentionType::Critical => NSRequestUserAttentionType::NSCriticalRequest,
|
||||
UserAttentionType::Informational => NSRequestUserAttentionType::NSInformationalRequest,
|
||||
});
|
||||
if let Some(ty) = ns_request_type {
|
||||
NSApplication::sharedApplication(mtm).requestUserAttention(ty);
|
||||
|
|
@ -1602,9 +1609,9 @@ impl WindowDelegate {
|
|||
fn toggle_style_mask(&self, mask: NSWindowStyleMask, on: bool) {
|
||||
let current_style_mask = self.window().styleMask();
|
||||
if on {
|
||||
self.set_style_mask(current_style_mask | mask);
|
||||
self.set_style_mask(NSWindowStyleMask(current_style_mask.0 | mask.0));
|
||||
} else {
|
||||
self.set_style_mask(current_style_mask & (!mask));
|
||||
self.set_style_mask(NSWindowStyleMask(current_style_mask.0 & (!mask.0)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1629,9 +1636,9 @@ impl WindowDelegate {
|
|||
#[inline]
|
||||
pub fn set_content_protected(&self, protected: bool) {
|
||||
self.window().setSharingType(if protected {
|
||||
NSWindowSharingNone
|
||||
NSWindowSharingType::NSWindowSharingNone
|
||||
} else {
|
||||
NSWindowSharingReadOnly
|
||||
NSWindowSharingType::NSWindowSharingReadOnly
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -1683,12 +1690,14 @@ impl WindowExtMacOS for WindowDelegate {
|
|||
self.ivars().is_simple_fullscreen.set(true);
|
||||
|
||||
// Simulate pre-Lion fullscreen by hiding the dock and menu bar
|
||||
let presentation_options =
|
||||
NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar;
|
||||
let presentation_options = NSApplicationPresentationOptions(
|
||||
NSApplicationPresentationOptions::NSApplicationPresentationAutoHideDock.0
|
||||
| NSApplicationPresentationOptions::NSApplicationPresentationAutoHideMenuBar.0,
|
||||
);
|
||||
app.setPresentationOptions(presentation_options);
|
||||
|
||||
// Hide the titlebar
|
||||
self.toggle_style_mask(NSWindowStyleMaskTitled, false);
|
||||
self.toggle_style_mask(NSWindowStyleMask::Titled, false);
|
||||
|
||||
// Set the window frame to the screen frame size
|
||||
let screen = self
|
||||
|
|
@ -1698,8 +1707,8 @@ impl WindowExtMacOS for WindowDelegate {
|
|||
self.window().setFrame_display(screen.frame(), true);
|
||||
|
||||
// Fullscreen windows can't be resized, minimized, or moved
|
||||
self.toggle_style_mask(NSWindowStyleMaskMiniaturizable, false);
|
||||
self.toggle_style_mask(NSWindowStyleMaskResizable, false);
|
||||
self.toggle_style_mask(NSWindowStyleMask::Miniaturizable, false);
|
||||
self.toggle_style_mask(NSWindowStyleMask::Resizable, false);
|
||||
self.window().setMovable(false);
|
||||
|
||||
true
|
||||
|
|
@ -1793,7 +1802,7 @@ impl WindowExtMacOS for WindowDelegate {
|
|||
}
|
||||
|
||||
fn mask_contains(mask: NSWindowStyleMask, value: NSWindowStyleMask) -> bool {
|
||||
mask & value == value
|
||||
mask.0 & value.0 == value.0
|
||||
}
|
||||
|
||||
const DEFAULT_STANDARD_FRAME: NSRect =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue