Reduce usage of direct msg_send!

This commit is contained in:
Mads Marquart 2024-05-06 17:09:38 +02:00 committed by GitHub
parent cb39ab29f4
commit d5d202d60e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 61 additions and 86 deletions

View file

@ -121,11 +121,14 @@ features = [
"NSAttributedString", "NSAttributedString",
"NSData", "NSData",
"NSDictionary", "NSDictionary",
"NSDistributedNotificationCenter",
"NSEnumerator", "NSEnumerator",
"NSNotification",
"NSObjCRuntime", "NSObjCRuntime",
"NSString",
"NSPathUtilities", "NSPathUtilities",
"NSProcessInfo", "NSProcessInfo",
"NSRunLoop",
"NSString",
"NSThread", "NSThread",
"NSValue", "NSValue",
] ]

View file

@ -17,7 +17,8 @@ use objc2::rc::Id;
use objc2::runtime::AnyObject; use objc2::runtime::AnyObject;
use objc2::{msg_send, sel}; use objc2::{msg_send, sel};
use objc2_foundation::{ use objc2_foundation::{
CGRect, CGSize, MainThreadMarker, NSInteger, NSOperatingSystemVersion, NSProcessInfo, CGRect, CGSize, MainThreadMarker, NSInteger, NSObjectProtocol, NSOperatingSystemVersion,
NSProcessInfo,
}; };
use super::uikit::UIView; use super::uikit::UIView;
@ -857,23 +858,17 @@ fn meets_requirements(
} }
fn get_version() -> NSOperatingSystemVersion { fn get_version() -> NSOperatingSystemVersion {
unsafe { let process_info = NSProcessInfo::processInfo();
let process_info = NSProcessInfo::processInfo(); let atleast_ios_8 = process_info.respondsToSelector(sel!(operatingSystemVersion));
let atleast_ios_8: bool = msg_send![ // Winit requires atleast iOS 8 because no one has put the time into supporting earlier os
&process_info, // versions. Older iOS versions are increasingly difficult to test. For example, Xcode 11 does
respondsToSelector: sel!(operatingSystemVersion) // not support debugging on devices with an iOS version of less than 8. Another example, in
]; // order to use an iOS simulator older than iOS 8, you must download an older version of Xcode
// winit requires atleast iOS 8 because no one has put the time into supporting earlier os // (<9), and at least Xcode 7 has been tested to not even run on macOS 10.15 - Xcode 8 might?
// versions. Older iOS versions are increasingly difficult to test. For example, //
// Xcode 11 does not support debugging on devices with an iOS version of less than // The minimum required iOS version is likely to grow in the future.
// 8. Another example, in order to use an iOS simulator older than iOS 8, you must assert!(atleast_ios_8, "`winit` requires iOS version 8 or greater");
// download an older version of Xcode (<9), and at least Xcode 7 has been tested to process_info.operatingSystemVersion()
// not even run on macOS 10.15 - Xcode 8 might?
//
// The minimum required iOS version is likely to grow in the future.
assert!(atleast_ios_8, "`winit` requires iOS version 8 or greater");
process_info.operatingSystemVersion()
}
} }
pub fn os_capabilities() -> OSCapabilities { pub fn os_capabilities() -> OSCapabilities {

View file

@ -5,7 +5,9 @@ use std::collections::VecDeque;
use objc2::rc::Id; use objc2::rc::Id;
use objc2::runtime::{AnyObject, NSObject}; use objc2::runtime::{AnyObject, NSObject};
use objc2::{class, declare_class, msg_send, msg_send_id, mutability, ClassType, DeclaredClass}; use objc2::{class, declare_class, msg_send, msg_send_id, mutability, ClassType, DeclaredClass};
use objc2_foundation::{CGFloat, CGPoint, CGRect, CGSize, MainThreadBound, MainThreadMarker}; use objc2_foundation::{
CGFloat, CGPoint, CGRect, CGSize, MainThreadBound, MainThreadMarker, NSObjectProtocol,
};
use tracing::{debug, warn}; use tracing::{debug, warn};
use super::app_state::EventWrapper; use super::app_state::EventWrapper;
@ -505,12 +507,8 @@ impl Window {
let view = WinitView::new(mtm, &window_attributes, frame); let view = WinitView::new(mtm, &window_attributes, frame);
let gl_or_metal_backed = unsafe { let gl_or_metal_backed =
let layer_class = WinitView::layerClass(); view.isKindOfClass(class!(CAMetalLayer)) || view.isKindOfClass(class!(CAEAGLLayer));
let is_metal = msg_send![layer_class, isSubclassOfClass: class!(CAMetalLayer)];
let is_gl = msg_send![layer_class, isSubclassOfClass: class!(CAEAGLLayer)];
is_metal || is_gl
};
let view_controller = WinitViewController::new(mtm, &window_attributes, &view); let view_controller = WinitViewController::new(mtm, &window_attributes, &view);
let window = WinitUIWindow::new(mtm, &window_attributes, frame, &view_controller); let window = WinitUIWindow::new(mtm, &window_attributes, frame, &view_controller);

View file

@ -5,17 +5,15 @@ use std::ptr;
use objc2::rc::{Id, WeakId}; use objc2::rc::{Id, WeakId};
use objc2::runtime::{AnyObject, Sel}; use objc2::runtime::{AnyObject, Sel};
use objc2::{ use objc2::{declare_class, msg_send_id, mutability, sel, ClassType, DeclaredClass};
class, declare_class, msg_send, msg_send_id, mutability, sel, ClassType, DeclaredClass,
};
use objc2_app_kit::{ use objc2_app_kit::{
NSApplication, NSCursor, NSEvent, NSEventPhase, NSResponder, NSTextInputClient, NSApplication, NSCursor, NSEvent, NSEventPhase, NSResponder, NSTextInputClient,
NSTrackingRectTag, NSView, NSTrackingRectTag, NSView, NSViewFrameDidChangeNotification,
}; };
use objc2_foundation::{ use objc2_foundation::{
MainThreadMarker, NSArray, NSAttributedString, NSAttributedStringKey, NSCopying, MainThreadMarker, NSArray, NSAttributedString, NSAttributedStringKey, NSCopying,
NSMutableAttributedString, NSNotFound, NSObject, NSObjectProtocol, NSPoint, NSRange, NSRect, NSMutableAttributedString, NSNotFound, NSNotificationCenter, NSObject, NSObjectProtocol,
NSSize, NSString, NSUInteger, NSPoint, NSRange, NSRect, NSSize, NSString, NSUInteger,
}; };
use super::app_delegate::ApplicationDelegate; use super::app_delegate::ApplicationDelegate;
@ -202,7 +200,7 @@ declare_class!(
} }
#[method(drawRect:)] #[method(drawRect:)]
fn draw_rect(&self, rect: NSRect) { fn draw_rect(&self, _rect: NSRect) {
trace_scope!("drawRect:"); trace_scope!("drawRect:");
// It's a workaround for https://github.com/rust-windowing/winit/issues/2640, don't replace with `self.window_id()`. // It's a workaround for https://github.com/rust-windowing/winit/issues/2640, don't replace with `self.window_id()`.
@ -210,10 +208,7 @@ declare_class!(
self.ivars().app_delegate.handle_redraw(window.id()); self.ivars().app_delegate.handle_redraw(window.id());
} }
#[allow(clippy::let_unit_value)] // This is a direct subclass of NSView, no need to call superclass' drawRect:
unsafe {
let _: () = msg_send![super(self), drawRect: rect];
}
} }
#[method(acceptsFirstResponder)] #[method(acceptsFirstResponder)]
@ -803,20 +798,14 @@ impl WinitView {
let this: Id<Self> = unsafe { msg_send_id![super(this), init] }; let this: Id<Self> = unsafe { msg_send_id![super(this), init] };
this.setPostsFrameChangedNotifications(true); this.setPostsFrameChangedNotifications(true);
let notification_center: &AnyObject = let notification_center = unsafe { NSNotificationCenter::defaultCenter() };
unsafe { msg_send![class!(NSNotificationCenter), defaultCenter] };
// About frame change
let frame_did_change_notification_name =
NSString::from_str("NSViewFrameDidChangeNotification");
#[allow(clippy::let_unit_value)]
unsafe { unsafe {
let _: () = msg_send![ notification_center.addObserver_selector_name_object(
notification_center, &this,
addObserver: &*this, sel!(frameDidChange:),
selector: sel!(frameDidChange:), Some(NSViewFrameDidChangeNotification),
name: &*frame_did_change_notification_name, Some(&this),
object: &*this, )
];
} }
*this.ivars().input_source.borrow_mut() = this.current_input_source(); *this.ivars().input_source.borrow_mut() = this.current_input_source();

View file

@ -1,15 +1,12 @@
#![allow(clippy::unnecessary_cast)] #![allow(clippy::unnecessary_cast)]
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::ptr;
use core_graphics::display::{CGDisplay, CGPoint}; use core_graphics::display::{CGDisplay, CGPoint};
use monitor::VideoModeHandle; use monitor::VideoModeHandle;
use objc2::rc::{autoreleasepool, Id}; use objc2::rc::{autoreleasepool, Id};
use objc2::runtime::{AnyObject, ProtocolObject}; use objc2::runtime::{AnyObject, ProtocolObject};
use objc2::{ use objc2::{declare_class, msg_send_id, mutability, sel, ClassType, DeclaredClass};
class, declare_class, msg_send, msg_send_id, mutability, sel, ClassType, DeclaredClass,
};
use objc2_app_kit::{ use objc2_app_kit::{
NSAppKitVersionNumber, NSAppKitVersionNumber10_12, NSAppearance, NSApplication, NSAppKitVersionNumber, NSAppKitVersionNumber10_12, NSAppearance, NSApplication,
NSApplicationPresentationOptions, NSBackingStoreType, NSDraggingDestination, NSApplicationPresentationOptions, NSBackingStoreType, NSDraggingDestination,
@ -19,8 +16,9 @@ use objc2_app_kit::{
NSWindowTabbingMode, NSWindowTitleVisibility, NSWindowTabbingMode, NSWindowTitleVisibility,
}; };
use objc2_foundation::{ use objc2_foundation::{
CGFloat, MainThreadMarker, NSArray, NSCopying, NSObject, NSObjectProtocol, NSPoint, NSRect, ns_string, CGFloat, MainThreadMarker, NSArray, NSCopying, NSDistributedNotificationCenter,
NSSize, NSString, NSObject, NSObjectNSDelayedPerforming, NSObjectNSThreadPerformAdditions, NSObjectProtocol,
NSPoint, NSRect, NSSize, NSString,
}; };
use super::app_delegate::ApplicationDelegate; use super::app_delegate::ApplicationDelegate;
@ -319,14 +317,12 @@ declare_class!(
self.ivars().in_fullscreen_transition.set(false); self.ivars().in_fullscreen_transition.set(false);
self.ivars().target_fullscreen.replace(None); self.ivars().target_fullscreen.replace(None);
if self.ivars().initial_fullscreen.get() { if self.ivars().initial_fullscreen.get() {
#[allow(clippy::let_unit_value)]
unsafe { unsafe {
let _: () = msg_send![ self.window().performSelector_withObject_afterDelay(
self.window(), sel!(toggleFullScreen:),
performSelector: sel!(toggleFullScreen:), None,
withObject: ptr::null::<AnyObject>(), 0.5,
afterDelay: 0.5, )
];
}; };
} else { } else {
self.restore_state_from_fullscreen(); self.restore_state_from_fullscreen();
@ -421,16 +417,15 @@ declare_class!(
unsafe impl WindowDelegate { unsafe impl WindowDelegate {
// Observe theme change // Observe theme change
#[method(effectiveAppearanceDidChange:)] #[method(effectiveAppearanceDidChange:)]
fn effective_appearance_did_change(this: *mut Self, sender: Option<&AnyObject>) { fn effective_appearance_did_change(&self, sender: Option<&AnyObject>) {
trace_scope!("effectiveAppearanceDidChange:"); trace_scope!("effectiveAppearanceDidChange:");
unsafe { unsafe {
msg_send![ self.performSelectorOnMainThread_withObject_waitUntilDone(
this, sel!(effectiveAppearanceDidChangedOnMainThread:),
performSelectorOnMainThread: sel!(effectiveAppearanceDidChangedOnMainThread:), sender,
withObject: sender, false,
waitUntilDone: false, )
] };
}
} }
#[method(effectiveAppearanceDidChangedOnMainThread:)] #[method(effectiveAppearanceDidChangedOnMainThread:)]
@ -698,17 +693,14 @@ impl WindowDelegate {
window.setDelegate(Some(ProtocolObject::from_ref(&*delegate))); window.setDelegate(Some(ProtocolObject::from_ref(&*delegate)));
// Enable theme change event // Enable theme change event
let notification_center: Id<AnyObject> = let notification_center = unsafe { NSDistributedNotificationCenter::defaultCenter() };
unsafe { msg_send_id![class!(NSDistributedNotificationCenter), defaultCenter] }; unsafe {
let notification_name = NSString::from_str("AppleInterfaceThemeChangedNotification"); notification_center.addObserver_selector_name_object(
let _: () = unsafe { &delegate,
msg_send![ sel!(effectiveAppearanceDidChange:),
&notification_center, Some(ns_string!("AppleInterfaceThemeChangedNotification")),
addObserver: &*delegate, None,
selector: sel!(effectiveAppearanceDidChange:), )
name: &*notification_name,
object: ptr::null::<AnyObject>(),
]
}; };
if attrs.blur { if attrs.blur {
@ -1772,8 +1764,7 @@ const DEFAULT_STANDARD_FRAME: NSRect =
pub(super) fn get_ns_theme(mtm: MainThreadMarker) -> Theme { pub(super) fn get_ns_theme(mtm: MainThreadMarker) -> Theme {
let app = NSApplication::sharedApplication(mtm); let app = NSApplication::sharedApplication(mtm);
let has_theme: bool = unsafe { msg_send![&app, respondsToSelector: sel!(effectiveAppearance)] }; if !app.respondsToSelector(sel!(effectiveAppearance)) {
if !has_theme {
return Theme::Light; return Theme::Light;
} }
let appearance = app.effectiveAppearance(); let appearance = app.effectiveAppearance();
@ -1791,8 +1782,7 @@ pub(super) fn get_ns_theme(mtm: MainThreadMarker) -> Theme {
fn set_ns_theme(theme: Option<Theme>, mtm: MainThreadMarker) { fn set_ns_theme(theme: Option<Theme>, mtm: MainThreadMarker) {
let app = NSApplication::sharedApplication(mtm); let app = NSApplication::sharedApplication(mtm);
let has_theme: bool = unsafe { msg_send![&app, respondsToSelector: sel!(effectiveAppearance)] }; if app.respondsToSelector(sel!(effectiveAppearance)) {
if has_theme {
let appearance = theme.map(|t| { let appearance = theme.map(|t| {
let name = match t { let name = match t {
Theme::Dark => NSString::from_str("NSAppearanceNameDarkAqua"), Theme::Dark => NSString::from_str("NSAppearanceNameDarkAqua"),