[macOS] Replace custom main loop with [NSApp run]
and CFRunLoop
observer.
This commit is contained in:
parent
0595bb8a42
commit
a317ce75a6
@ -441,6 +441,7 @@ public:
|
|||||||
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;
|
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;
|
||||||
virtual void show_emoji_and_symbol_picker() const override;
|
virtual void show_emoji_and_symbol_picker() const override;
|
||||||
|
|
||||||
|
void _process_events(bool p_pump);
|
||||||
virtual void process_events() override;
|
virtual void process_events() override;
|
||||||
virtual void force_process_and_drop_events() override;
|
virtual void force_process_and_drop_events() override;
|
||||||
|
|
||||||
|
@ -1901,6 +1901,11 @@ DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode,
|
|||||||
void DisplayServerMacOS::show_window(WindowID p_id) {
|
void DisplayServerMacOS::show_window(WindowID p_id) {
|
||||||
WindowData &wd = windows[p_id];
|
WindowData &wd = windows[p_id];
|
||||||
|
|
||||||
|
if (p_id == MAIN_WINDOW_ID) {
|
||||||
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
|
static_cast<OS_MacOS *>(OS::get_singleton())->activate();
|
||||||
|
}
|
||||||
|
|
||||||
popup_open(p_id);
|
popup_open(p_id);
|
||||||
if ([wd.window_object isMiniaturized]) {
|
if ([wd.window_object isMiniaturized]) {
|
||||||
return;
|
return;
|
||||||
@ -3204,8 +3209,13 @@ void DisplayServerMacOS::show_emoji_and_symbol_picker() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerMacOS::process_events() {
|
void DisplayServerMacOS::process_events() {
|
||||||
|
_process_events(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerMacOS::_process_events(bool p_pump) {
|
||||||
ERR_FAIL_COND(!Thread::is_main_thread());
|
ERR_FAIL_COND(!Thread::is_main_thread());
|
||||||
|
|
||||||
|
if (p_pump) {
|
||||||
while (true) {
|
while (true) {
|
||||||
NSEvent *event = [NSApp
|
NSEvent *event = [NSApp
|
||||||
nextEventMatchingMask:NSEventMaskAny
|
nextEventMatchingMask:NSEventMaskAny
|
||||||
@ -3219,6 +3229,7 @@ void DisplayServerMacOS::process_events() {
|
|||||||
|
|
||||||
[NSApp sendEvent:event];
|
[NSApp sendEvent:event];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process "menu_callback"s.
|
// Process "menu_callback"s.
|
||||||
while (List<MenuCall>::Element *call_p = deferred_menu_calls.front()) {
|
while (List<MenuCall>::Element *call_p = deferred_menu_calls.front()) {
|
||||||
|
@ -36,8 +36,8 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
@interface GodotApplicationDelegate : NSObject <NSUserInterfaceItemSearching, NSApplicationDelegate>
|
@interface GodotApplicationDelegate : NSObject <NSUserInterfaceItemSearching, NSApplicationDelegate>
|
||||||
|
- (void)activate;
|
||||||
- (void)forceUnbundledWindowActivationHackStep1;
|
- (void)forceUnbundledWindowActivationHackStep1;
|
||||||
- (void)forceUnbundledWindowActivationHackStep2;
|
- (void)forceUnbundledWindowActivationHackStep2;
|
||||||
- (void)forceUnbundledWindowActivationHackStep3;
|
- (void)forceUnbundledWindowActivationHackStep3;
|
||||||
- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
|
|
||||||
@end
|
@end
|
||||||
|
@ -124,7 +124,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)notice {
|
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
|
||||||
|
static_cast<OS_MacOS *>(OS::get_singleton())->start_main();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)activate {
|
||||||
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
|
|
||||||
NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
||||||
const char *bundled_id = getenv("__CFBundleIdentifier");
|
const char *bundled_id = getenv("__CFBundleIdentifier");
|
||||||
NSString *nsbundleid_env = [NSString stringWithUTF8String:(bundled_id != nullptr) ? bundled_id : ""];
|
NSString *nsbundleid_env = [NSString stringWithUTF8String:(bundled_id != nullptr) ? bundled_id : ""];
|
||||||
@ -139,11 +145,6 @@
|
|||||||
|
|
||||||
- (id)init {
|
- (id)init {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
NSAppleEventManager *aem = [NSAppleEventManager sharedAppleEventManager];
|
|
||||||
[aem setEventHandler:self andSelector:@selector(handleAppleEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
|
|
||||||
[aem setEventHandler:self andSelector:@selector(handleAppleEvent:withReplyEvent:) forEventClass:kCoreEventClass andEventID:kAEOpenDocuments];
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,36 +153,45 @@
|
|||||||
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:@"AppleColorPreferencesChangedNotification" object:nil];
|
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:@"AppleColorPreferencesChangedNotification" object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleAppleEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
|
- (void)application:(NSApplication *)application openURLs:(NSArray<NSURL *> *)urls {
|
||||||
OS_MacOS *os = (OS_MacOS *)OS::get_singleton();
|
OS_MacOS *os = (OS_MacOS *)OS::get_singleton();
|
||||||
if (!event || !os) {
|
if (!os) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> args;
|
List<String> args;
|
||||||
if (([event eventClass] == kInternetEventClass) && ([event eventID] == kAEGetURL)) {
|
for (NSURL *url in urls) {
|
||||||
// Opening URL scheme.
|
if ([url isFileURL]) {
|
||||||
NSString *url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
|
|
||||||
args.push_back(vformat("--uri=\"%s\"", String::utf8([url UTF8String])));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (([event eventClass] == kCoreEventClass) && ([event eventID] == kAEOpenDocuments)) {
|
|
||||||
// Opening file association.
|
|
||||||
NSAppleEventDescriptor *files = [event paramDescriptorForKeyword:keyDirectObject];
|
|
||||||
if (files) {
|
|
||||||
NSInteger count = [files numberOfItems];
|
|
||||||
for (NSInteger i = 1; i <= count; i++) {
|
|
||||||
NSURL *url = [NSURL URLWithString:[[files descriptorAtIndex:i] stringValue]];
|
|
||||||
args.push_back(String::utf8([url.path UTF8String]));
|
args.push_back(String::utf8([url.path UTF8String]));
|
||||||
|
} else {
|
||||||
|
args.push_back(vformat("--uri=\"%s\"", String::utf8([url.absoluteString UTF8String])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!args.is_empty()) {
|
if (!args.is_empty()) {
|
||||||
if (os->get_main_loop()) {
|
if (os->get_main_loop()) {
|
||||||
// Application is already running, open a new instance with the URL/files as command line arguments.
|
// Application is already running, open a new instance with the URL/files as command line arguments.
|
||||||
os->create_instance(args);
|
os->create_instance(args);
|
||||||
} else {
|
} else if (os->get_cmd_argc() == 0) {
|
||||||
|
// Application is just started, add to the list of command line arguments and continue.
|
||||||
|
os->set_cmdline_platform_args(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)application:(NSApplication *)sender openFiles:(NSArray<NSString *> *)filenames {
|
||||||
|
OS_MacOS *os = (OS_MacOS *)OS::get_singleton();
|
||||||
|
if (!os) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> args;
|
||||||
|
for (NSString *filename in filenames) {
|
||||||
|
NSURL *url = [NSURL URLWithString:filename];
|
||||||
|
args.push_back(String::utf8([url.path UTF8String]));
|
||||||
|
}
|
||||||
|
if (!args.is_empty()) {
|
||||||
|
if (os->get_main_loop()) {
|
||||||
|
// Application is already running, open a new instance with the URL/files as command line arguments.
|
||||||
|
os->create_instance(args);
|
||||||
|
} else if (os->get_cmd_argc() == 0) {
|
||||||
// Application is just started, add to the list of command line arguments and continue.
|
// Application is just started, add to the list of command line arguments and continue.
|
||||||
os->set_cmdline_platform_args(args);
|
os->set_cmdline_platform_args(args);
|
||||||
}
|
}
|
||||||
@ -220,11 +230,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)applicationWillTerminate:(NSNotification *)notification {
|
||||||
|
OS_MacOS *os = (OS_MacOS *)OS::get_singleton();
|
||||||
|
if (os) {
|
||||||
|
os->cleanup();
|
||||||
|
exit(os->get_exit_code());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
||||||
if (ds) {
|
if (ds) {
|
||||||
ds->send_window_event(ds->get_window(DisplayServerMacOS::MAIN_WINDOW_ID), DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
|
ds->send_window_event(ds->get_window(DisplayServerMacOS::MAIN_WINDOW_ID), DisplayServerMacOS::WINDOW_EVENT_CLOSE_REQUEST);
|
||||||
}
|
}
|
||||||
|
OS_MacOS *os = (OS_MacOS *)OS::get_singleton();
|
||||||
|
if (!os || os->os_should_terminate()) {
|
||||||
|
return NSTerminateNow;
|
||||||
|
}
|
||||||
return NSTerminateCancel;
|
return NSTerminateCancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,36 +59,12 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OS_MacOS os;
|
OS_MacOS os(argv[0], argc - first_arg, &argv[first_arg]);
|
||||||
Error err;
|
|
||||||
|
|
||||||
// We must override main when testing is enabled.
|
// We must override main when testing is enabled.
|
||||||
TEST_MAIN_OVERRIDE
|
TEST_MAIN_OVERRIDE
|
||||||
|
|
||||||
@autoreleasepool {
|
os.run(); // Note: This function will never return.
|
||||||
err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != OK) {
|
|
||||||
if (err == ERR_HELP) { // Returned by --help and --version, so success.
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
@autoreleasepool {
|
|
||||||
ret = Main::start();
|
|
||||||
}
|
|
||||||
if (ret == EXIT_SUCCESS) {
|
|
||||||
os.run();
|
|
||||||
} else {
|
|
||||||
os.set_exit_code(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@autoreleasepool {
|
|
||||||
Main::cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.get_exit_code();
|
return os.get_exit_code();
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,13 @@
|
|||||||
#include "servers/audio_server.h"
|
#include "servers/audio_server.h"
|
||||||
|
|
||||||
class OS_MacOS : public OS_Unix {
|
class OS_MacOS : public OS_Unix {
|
||||||
|
const char *execpath = nullptr;
|
||||||
|
int argc = 0;
|
||||||
|
char **argv = nullptr;
|
||||||
|
|
||||||
|
id delegate = nullptr;
|
||||||
|
bool should_terminate = false;
|
||||||
|
|
||||||
JoypadApple *joypad_apple = nullptr;
|
JoypadApple *joypad_apple = nullptr;
|
||||||
|
|
||||||
#ifdef COREAUDIO_ENABLED
|
#ifdef COREAUDIO_ENABLED
|
||||||
@ -51,7 +58,7 @@ class OS_MacOS : public OS_Unix {
|
|||||||
|
|
||||||
CrashHandler crash_handler;
|
CrashHandler crash_handler;
|
||||||
|
|
||||||
CFRunLoopObserverRef pre_wait_observer;
|
CFRunLoopObserverRef pre_wait_observer = nil;
|
||||||
|
|
||||||
MainLoop *main_loop = nullptr;
|
MainLoop *main_loop = nullptr;
|
||||||
|
|
||||||
@ -64,6 +71,8 @@ class OS_MacOS : public OS_Unix {
|
|||||||
static _FORCE_INLINE_ String get_framework_executable(const String &p_path);
|
static _FORCE_INLINE_ String get_framework_executable(const String &p_path);
|
||||||
static void pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context);
|
static void pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context);
|
||||||
|
|
||||||
|
void terminate();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void initialize_core() override;
|
virtual void initialize_core() override;
|
||||||
virtual void initialize() override;
|
virtual void initialize() override;
|
||||||
@ -131,8 +140,13 @@ public:
|
|||||||
virtual String get_system_ca_certificates() override;
|
virtual String get_system_ca_certificates() override;
|
||||||
virtual OS::PreferredTextureFormat get_preferred_texture_format() const override;
|
virtual OS::PreferredTextureFormat get_preferred_texture_format() const override;
|
||||||
|
|
||||||
void run();
|
void run(); // Runs macOS native event loop.
|
||||||
|
void start_main(); // Initializes and runs Godot main loop.
|
||||||
|
void activate();
|
||||||
|
void cleanup();
|
||||||
|
bool os_should_terminate() const { return should_terminate; }
|
||||||
|
int get_cmd_argc() const { return argc; }
|
||||||
|
|
||||||
OS_MacOS();
|
OS_MacOS(const char *p_execpath, int p_argc, char **p_argv);
|
||||||
~OS_MacOS();
|
~OS_MacOS();
|
||||||
};
|
};
|
||||||
|
@ -47,14 +47,20 @@
|
|||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
void OS_MacOS::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) {
|
void OS_MacOS::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) {
|
||||||
// Prevent main loop from sleeping and redraw window during modal popup display.
|
OS_MacOS *os = static_cast<OS_MacOS *>(OS::get_singleton());
|
||||||
// Do not redraw when rendering is done from the separate thread, it will conflict with the OpenGL context updates.
|
|
||||||
|
|
||||||
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
|
@autoreleasepool {
|
||||||
if (get_singleton()->get_main_loop() && ds && !get_singleton()->is_separate_thread_rendering_enabled() && !ds->get_is_resizing()) {
|
@try {
|
||||||
Main::force_redraw();
|
if (DisplayServer::get_singleton()) {
|
||||||
if (!Main::is_iterating()) { // Avoid cyclic loop.
|
static_cast<DisplayServerMacOS *>(DisplayServer::get_singleton())->_process_events(false); // Get rid of pending events.
|
||||||
Main::iteration();
|
}
|
||||||
|
os->joypad_apple->process_joypads();
|
||||||
|
|
||||||
|
if (Main::iteration()) {
|
||||||
|
os->terminate();
|
||||||
|
}
|
||||||
|
} @catch (NSException *exception) {
|
||||||
|
ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,36 +829,69 @@ OS::PreferredTextureFormat OS_MacOS::get_preferred_texture_format() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OS_MacOS::run() {
|
void OS_MacOS::run() {
|
||||||
if (!main_loop) {
|
[NSApp run];
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
void OS_MacOS::start_main() {
|
||||||
|
Error err;
|
||||||
|
@autoreleasepool {
|
||||||
|
err = Main::setup(execpath, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (err == OK) {
|
||||||
|
int ret;
|
||||||
|
@autoreleasepool {
|
||||||
|
ret = Main::start();
|
||||||
|
}
|
||||||
|
if (ret == EXIT_SUCCESS) {
|
||||||
|
if (main_loop) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
main_loop->initialize();
|
main_loop->initialize();
|
||||||
}
|
}
|
||||||
|
pre_wait_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, &pre_wait_observer_cb, nullptr);
|
||||||
bool quit = false;
|
CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
||||||
while (!quit) {
|
return;
|
||||||
@autoreleasepool {
|
|
||||||
@try {
|
|
||||||
if (DisplayServer::get_singleton()) {
|
|
||||||
DisplayServer::get_singleton()->process_events(); // Get rid of pending events.
|
|
||||||
}
|
|
||||||
joypad_apple->process_joypads();
|
|
||||||
|
|
||||||
if (Main::iteration()) {
|
|
||||||
quit = true;
|
|
||||||
}
|
|
||||||
} @catch (NSException *exception) {
|
|
||||||
ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String));
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
set_exit_code(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
} else if (err == ERR_HELP) { // Returned by --help and --version, so success.
|
||||||
|
set_exit_code(EXIT_SUCCESS);
|
||||||
|
} else {
|
||||||
|
set_exit_code(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
main_loop->finalize();
|
terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
OS_MacOS::OS_MacOS() {
|
void OS_MacOS::activate() {
|
||||||
|
[delegate activate];
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_MacOS::terminate() {
|
||||||
|
if (pre_wait_observer) {
|
||||||
|
CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
||||||
|
CFRelease(pre_wait_observer);
|
||||||
|
pre_wait_observer = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
should_terminate = true;
|
||||||
|
[NSApp terminate:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_MacOS::cleanup() {
|
||||||
|
if (main_loop) {
|
||||||
|
main_loop->finalize();
|
||||||
|
@autoreleasepool {
|
||||||
|
Main::cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_MacOS::OS_MacOS(const char *p_execpath, int p_argc, char **p_argv) {
|
||||||
|
execpath = p_execpath;
|
||||||
|
argc = p_argc;
|
||||||
|
argv = p_argv;
|
||||||
if (is_sandboxed()) {
|
if (is_sandboxed()) {
|
||||||
// Load security-scoped bookmarks, request access, remove stale or invalid bookmarks.
|
// Load security-scoped bookmarks, request access, remove stale or invalid bookmarks.
|
||||||
NSArray *bookmarks = [[NSUserDefaults standardUserDefaults] arrayForKey:@"sec_bookmarks"];
|
NSArray *bookmarks = [[NSUserDefaults standardUserDefaults] arrayForKey:@"sec_bookmarks"];
|
||||||
@ -886,7 +925,7 @@ OS_MacOS::OS_MacOS() {
|
|||||||
[GodotApplication sharedApplication];
|
[GodotApplication sharedApplication];
|
||||||
|
|
||||||
// In case we are unbundled, make us a proper UI application.
|
// In case we are unbundled, make us a proper UI application.
|
||||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
|
||||||
|
|
||||||
// Menu bar setup must go between sharedApplication above and
|
// Menu bar setup must go between sharedApplication above and
|
||||||
// finishLaunching below, in order to properly emulate the behavior
|
// finishLaunching below, in order to properly emulate the behavior
|
||||||
@ -894,35 +933,13 @@ OS_MacOS::OS_MacOS() {
|
|||||||
|
|
||||||
NSMenu *main_menu = [[NSMenu alloc] initWithTitle:@""];
|
NSMenu *main_menu = [[NSMenu alloc] initWithTitle:@""];
|
||||||
[NSApp setMainMenu:main_menu];
|
[NSApp setMainMenu:main_menu];
|
||||||
[NSApp finishLaunching];
|
|
||||||
|
|
||||||
id delegate = [[GodotApplicationDelegate alloc] init];
|
delegate = [[GodotApplicationDelegate alloc] init];
|
||||||
ERR_FAIL_NULL(delegate);
|
ERR_FAIL_NULL(delegate);
|
||||||
[NSApp setDelegate:delegate];
|
[NSApp setDelegate:delegate];
|
||||||
[NSApp registerUserInterfaceItemSearchHandler:delegate];
|
[NSApp registerUserInterfaceItemSearchHandler:delegate];
|
||||||
|
|
||||||
pre_wait_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, &pre_wait_observer_cb, nullptr);
|
|
||||||
CFRunLoopAddObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
|
||||||
|
|
||||||
// Process application:openFile: event.
|
|
||||||
while (true) {
|
|
||||||
NSEvent *event = [NSApp
|
|
||||||
nextEventMatchingMask:NSEventMaskAny
|
|
||||||
untilDate:[NSDate distantPast]
|
|
||||||
inMode:NSDefaultRunLoopMode
|
|
||||||
dequeue:YES];
|
|
||||||
|
|
||||||
if (event == nil) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NSApp sendEvent:event];
|
|
||||||
}
|
|
||||||
|
|
||||||
[NSApp activateIgnoringOtherApps:YES];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OS_MacOS::~OS_MacOS() {
|
OS_MacOS::~OS_MacOS() {
|
||||||
CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), pre_wait_observer, kCFRunLoopCommonModes);
|
// NOP
|
||||||
CFRelease(pre_wait_observer);
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user