Ensure that winit initializes NSApplication (#3069)

This commit is contained in:
Mads Marquart 2023-08-30 15:19:30 +02:00 committed by GitHub
parent 5f1a4b65ad
commit 477619c0a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -19,6 +19,7 @@ use core_foundation::runloop::{
}; };
use icrate::Foundation::MainThreadMarker; use icrate::Foundation::MainThreadMarker;
use objc2::rc::{autoreleasepool, Id}; use objc2::rc::{autoreleasepool, Id};
use objc2::runtime::NSObjectProtocol;
use objc2::{msg_send_id, ClassType}; use objc2::{msg_send_id, ClassType};
use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle}; use raw_window_handle::{AppKitDisplayHandle, RawDisplayHandle};
@ -109,7 +110,10 @@ impl<T> EventLoopWindowTarget<T> {
pub struct EventLoop<T: 'static> { pub struct EventLoop<T: 'static> {
/// Store a reference to the application for convenience. /// Store a reference to the application for convenience.
app: Id<WinitApplication>, ///
/// We intentially don't store `WinitApplication` since we want to have
/// the possiblity of swapping that out at some point.
app: Id<NSApplication>,
/// The delegate is only weakly referenced by NSApplication, so we keep /// The delegate is only weakly referenced by NSApplication, so we keep
/// it around here as well. /// it around here as well.
_delegate: Id<ApplicationDelegate>, _delegate: Id<ApplicationDelegate>,
@ -152,15 +156,15 @@ impl<T> EventLoop<T> {
attributes: &PlatformSpecificEventLoopAttributes, attributes: &PlatformSpecificEventLoopAttributes,
) -> Result<Self, EventLoopError> { ) -> Result<Self, EventLoopError> {
let mtm = MainThreadMarker::new() let mtm = MainThreadMarker::new()
.expect("On macOS, `EventLoop` must be created on the main thread!"); .expect("on macOS, `EventLoop` must be created on the main thread!");
// This must be done before `NSApp()` (equivalent to sending let app: Id<NSApplication> =
// `sharedApplication`) is called anywhere else, or we'll end up
// with the wrong `NSApplication` class and the wrong thread could
// be marked as main.
let app: Id<WinitApplication> =
unsafe { msg_send_id![WinitApplication::class(), sharedApplication] }; unsafe { msg_send_id![WinitApplication::class(), sharedApplication] };
if !app.is_kind_of::<WinitApplication>() {
panic!("`winit` requires control over the principal class. You must create the event loop before other parts of your application initialize NSApplication");
}
use NSApplicationActivationPolicy::*; use NSApplicationActivationPolicy::*;
let activation_policy = match attributes.activation_policy { let activation_policy = match attributes.activation_policy {
ActivationPolicy::Regular => NSApplicationActivationPolicyRegular, ActivationPolicy::Regular => NSApplicationActivationPolicyRegular,