From b7c5b26d35f9ba4e8776c63be69fd4aefd1afb3c Mon Sep 17 00:00:00 2001 From: der richter Date: Fri, 29 Mar 2024 15:48:36 +0100 Subject: [PATCH] mac/app: rewrite Application class in swift --- meson.build | 3 +- osdep/mac/application.m | 95 ------------------------------- osdep/mac/application.swift | 106 +++++++++++++++++++++++++++++++++++ osdep/mac/application_objc.h | 4 -- 4 files changed, 108 insertions(+), 100 deletions(-) create mode 100644 osdep/mac/application.swift diff --git a/meson.build b/meson.build index 0715254c65..a5aedb3800 100644 --- a/meson.build +++ b/meson.build @@ -1532,7 +1532,8 @@ features += {'swift': swift.allowed()} swift_sources = [] if features['cocoa'] and features['swift'] - swift_sources += files('osdep/mac/app_hub.swift', + swift_sources += files('osdep/mac/application.swift', + 'osdep/mac/app_hub.swift', 'osdep/mac/event_helper.swift', 'osdep/mac/input_helper.swift', 'osdep/mac/libmpv_helper.swift', diff --git a/osdep/mac/application.m b/osdep/mac/application.m index 753b9bcfa4..fb2889e92a 100644 --- a/osdep/mac/application.m +++ b/osdep/mac/application.m @@ -33,17 +33,8 @@ #include "osdep/mac/swift.h" #endif -#define MPV_PROTOCOL @"mpv://" - static mp_thread playback_thread_id; -@interface Application () -{ - AppHub *_appHub; -} - -@end - static Application *mpv_shared_app(void) { return (Application *)[Application sharedApplication]; @@ -57,92 +48,6 @@ static void terminate_cocoa_application(void) }); } -@implementation Application -@synthesize openCount = _open_count; - -- (void)sendEvent:(NSEvent *)event -{ - if ([self modalWindow] || ![_appHub.input processKeyWithEvent:event]) - [super sendEvent:event]; - [_appHub.input wakeup]; -} - -- (id)init -{ - if (self = [super init]) { - _appHub = [AppHub shared]; - - NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager]; - [em setEventHandler:self - andSelector:@selector(getUrl:withReplyEvent:) - forEventClass:kInternetEventClass - andEventID:kAEGetURL]; - } - - return self; -} - -- (void)dealloc -{ - NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager]; - [em removeEventHandlerForEventClass:kInternetEventClass - andEventID:kAEGetURL]; - [em removeEventHandlerForEventClass:kCoreEventClass - andEventID:kAEQuitApplication]; - [super dealloc]; -} - -#if HAVE_MACOS_TOUCHBAR -- (NSTouchBar *)makeTouchBar -{ - return [[AppHub shared] touchBar]; -} -#endif - -- (void)applicationWillFinishLaunching:(NSNotification *)notification -{ - NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager]; - [em setEventHandler:self - andSelector:@selector(handleQuitEvent:withReplyEvent:) - forEventClass:kCoreEventClass - andEventID:kAEQuitApplication]; -} - -- (void)handleQuitEvent:(NSAppleEventDescriptor *)event - withReplyEvent:(NSAppleEventDescriptor *)replyEvent -{ - if (![_appHub.input command:@"quit"]) - terminate_cocoa_application(); -} - -- (void)getUrl:(NSAppleEventDescriptor *)event - withReplyEvent:(NSAppleEventDescriptor *)replyEvent -{ - NSString *url = - [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; - - url = [url stringByReplacingOccurrencesOfString:MPV_PROTOCOL - withString:@"" - options:NSAnchoredSearch - range:NSMakeRange(0, [MPV_PROTOCOL length])]; - - url = [url stringByRemovingPercentEncoding]; - [_appHub.input openWithFiles:@[url]]; -} - -- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames -{ - if (mpv_shared_app().openCount > 0) { - mpv_shared_app().openCount--; - return; - } - - SEL cmpsel = @selector(localizedStandardCompare:); - NSArray *files = [filenames sortedArrayUsingSelector:cmpsel]; - [_appHub.input openWithFiles:files]; -} -@end - struct playback_thread_ctx { int *argc; char ***argv; diff --git a/osdep/mac/application.swift b/osdep/mac/application.swift new file mode 100644 index 0000000000..6b317be67c --- /dev/null +++ b/osdep/mac/application.swift @@ -0,0 +1,106 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see . + */ + +import Cocoa + +class Application: NSApplication, NSApplicationDelegate { + let appHub: AppHub + let MPV_PROTOCOL: String = "mpv://" + @objc var openCount: Int = 0 + + override init() { + appHub = AppHub.shared + super.init() + + let eventManager = NSAppleEventManager.shared() + eventManager.setEventHandler( + self, + andSelector: #selector(self.getUrl(event:replyEvent:)), + forEventClass: AEEventClass(kInternetEventClass), + andEventID: AEEventID(kAEGetURL) + ) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + deinit { + let eventManager = NSAppleEventManager.shared() + eventManager.removeEventHandler(forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL)) + eventManager.removeEventHandler(forEventClass: AEEventClass(kCoreEventClass), andEventID: kAEQuitApplication) + } + + func terminateApplication() { + DispatchQueue.main.async { + NSApp.hide(NSApp) + NSApp.terminate(NSApp) + } + } + + override func sendEvent(_ event: NSEvent) { + if modalWindow != nil || !appHub.input.processKey(event: event) { + super.sendEvent(event) + } + appHub.input.wakeup() + } + +#if HAVE_MACOS_TOUCHBAR + override func makeTouchBar() -> NSTouchBar? { + return appHub.touchBar + } +#endif + + func applicationWillFinishLaunching(_ notification: Notification) { + let eventManager = NSAppleEventManager.shared() + eventManager.setEventHandler( + self, + andSelector: #selector(handleQuit(event:replyEvent:)), + forEventClass: AEEventClass(kCoreEventClass), + andEventID: kAEQuitApplication + ) + } + + @objc func handleQuit(event: NSAppleEventDescriptor?, replyEvent: NSAppleEventDescriptor?) { + if !appHub.input.command("quit") { + terminateApplication() + } + } + + @objc func getUrl(event: NSAppleEventDescriptor?, replyEvent: NSAppleEventDescriptor?) { + guard var url: String = event?.paramDescriptor(forKeyword: keyDirectObject)?.stringValue else { return } + + if url.hasPrefix(MPV_PROTOCOL) { + url.removeFirst(MPV_PROTOCOL.count) + } + + url = url.removingPercentEncoding ?? url + appHub.input.open(files: [url]) + } + + func application(_ sender: NSApplication, openFiles: [String]) { + if openCount > 0 { + openCount -= openFiles.count + return + } + + let files = openFiles.sorted { (strL: String, strR: String) -> Bool in + return strL.localizedStandardCompare(strR) == .orderedAscending + } + appHub.input.open(files: files) + } +} diff --git a/osdep/mac/application_objc.h b/osdep/mac/application_objc.h index b27d7d234f..255ede8bc2 100644 --- a/osdep/mac/application_objc.h +++ b/osdep/mac/application_objc.h @@ -17,7 +17,3 @@ #import #include "osdep/mac/application.h" - -@interface Application : NSApplication -@property(nonatomic, assign) size_t openCount; -@end