summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorder richter <der.richter@gmx.de>2024-03-23 20:09:15 +0100
committerder richter <der.richter@gmx.de>2024-03-24 23:03:48 +0100
commit7e07e1a087e4107914294c5e9717f798e446c5d9 (patch)
treed0342930685761b1f3bb1c471c9b0c8e21fd8a95
parentdeb9d30e905b7b4645f18a26e6274a2859221631 (diff)
downloadmpv-7e07e1a087e4107914294c5e9717f798e446c5d9.tar.bz2
mpv-7e07e1a087e4107914294c5e9717f798e446c5d9.tar.xz
mac/apphub: migrate remaining events functionality to new AppHub
add new app_bridge objc file for bridging between mpv core and app functionality. replace old EventsResponder singleton with AppHub. another step to clean up all App functionality and have one central place for it.
-rw-r--r--input/input.c2
-rw-r--r--meson.build5
-rw-r--r--osdep/mac/app_bridge.h (renamed from osdep/mac/events.h)4
-rw-r--r--osdep/mac/app_bridge.m (renamed from osdep/mac/events_objc.h)37
-rw-r--r--osdep/mac/app_hub.swift109
-rw-r--r--osdep/mac/application.m18
-rw-r--r--osdep/mac/events.m185
-rw-r--r--osdep/mac/menu_bar.swift10
-rw-r--r--osdep/mac/meson.build8
-rw-r--r--osdep/mac/remote_command_center.swift4
-rw-r--r--osdep/mac/swift_bridge.h1
-rw-r--r--osdep/mac/touch_bar.swift4
-rw-r--r--player/main.c2
-rw-r--r--video/out/vo_libmpv.c2
14 files changed, 167 insertions, 224 deletions
diff --git a/input/input.c b/input/input.c
index 9d14ce3b84..9fd2a16f0c 100644
--- a/input/input.c
+++ b/input/input.c
@@ -50,7 +50,7 @@
#include "common/common.h"
#if HAVE_COCOA
-#include "osdep/mac/events.h"
+#include "osdep/mac/app_bridge.h"
#endif
#define input_lock(ictx) mp_mutex_lock(&ictx->mutex)
diff --git a/meson.build b/meson.build
index 08cae3966d..c471d5d7b5 100644
--- a/meson.build
+++ b/meson.build
@@ -400,7 +400,7 @@ if features['cocoa']
'osdep/path-mac.m',
'osdep/utils-mac.c',
'osdep/mac/application.m',
- 'osdep/mac/events.m')
+ 'osdep/mac/app_bridge.m')
main_fn_source = files('osdep/main-fn-mac.c')
endif
@@ -1517,9 +1517,10 @@ features += {'swift': swift.allowed()}
swift_sources = []
if features['cocoa'] and features['swift']
- swift_sources += files('osdep/mac/libmpv_helper.swift',
+ swift_sources += files('osdep/mac/app_hub.swift',
'osdep/mac/event_helper.swift',
'osdep/mac/input_helper.swift',
+ 'osdep/mac/libmpv_helper.swift',
'osdep/mac/log_helper.swift',
'osdep/mac/menu_bar.swift',
'osdep/mac/option_helper.swift',
diff --git a/osdep/mac/events.h b/osdep/mac/app_bridge.h
index 5c3ac38b6b..53388d8ba8 100644
--- a/osdep/mac/events.h
+++ b/osdep/mac/app_bridge.h
@@ -20,12 +20,10 @@
#ifndef MAC_EVENTS
#define MAC_EVENTS
-struct input_ctx;
-struct mpv_handle;
+#include "input/input.h"
void cocoa_init_media_keys(void);
void cocoa_uninit_media_keys(void);
-
void cocoa_set_input_context(struct input_ctx *input_context);
void cocoa_set_mpv_handle(struct mpv_handle *ctx);
void cocoa_init_cocoa_cb(void);
diff --git a/osdep/mac/events_objc.h b/osdep/mac/app_bridge.m
index ece2254702..976cfed3d1 100644
--- a/osdep/mac/events_objc.h
+++ b/osdep/mac/app_bridge.m
@@ -17,19 +17,34 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
-#import <Cocoa/Cocoa.h>
-#include "osdep/mac/events.h"
+#include "config.h"
-@class RemoteCommandCenter;
-@class InputHelper;
-struct input_ctx;
+#include "osdep/mac/app_bridge.h"
+#if HAVE_SWIFT
+#include "osdep/mac/swift.h"
+#endif
-@interface EventsResponder : NSObject
+void cocoa_init_media_keys(void)
+{
+ [[AppHub shared] startRemote];
+}
-+ (EventsResponder *)sharedInstance;
-- (void)setIsApplication:(BOOL)isApplication;
+void cocoa_uninit_media_keys(void)
+{
+ [[AppHub shared] stopRemote];
+}
-@property(nonatomic, retain) RemoteCommandCenter *remoteCommandCenter;
-@property(nonatomic, retain) InputHelper *inputHelper;
+void cocoa_set_input_context(struct input_ctx *input_context)
+{
+ [[AppHub shared] initInput:input_context];
+}
-@end
+void cocoa_set_mpv_handle(struct mpv_handle *ctx)
+{
+ [[AppHub shared] initMpv:ctx];
+}
+
+void cocoa_init_cocoa_cb(void)
+{
+ [[AppHub shared] initCocoaCb];
+}
diff --git a/osdep/mac/app_hub.swift b/osdep/mac/app_hub.swift
new file mode 100644
index 0000000000..cdfd03f153
--- /dev/null
+++ b/osdep/mac/app_hub.swift
@@ -0,0 +1,109 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+class AppHub: NSObject {
+ @objc static let shared = AppHub()
+
+ var mpv: OpaquePointer?
+ @objc var input: InputHelper
+#if HAVE_MACOS_MEDIA_PLAYER
+ var remote: RemoteCommandCenter?
+#endif
+
+ var isApplication: Bool { get { NSApp is Application } }
+
+ private override init() {
+ input = InputHelper()
+ }
+
+ @objc func initMpv(_ mpv: OpaquePointer) {
+ if isApplication {
+ self.mpv = mpv
+ mpv_observe_property(mpv, 0, "duration", MPV_FORMAT_DOUBLE)
+ mpv_observe_property(mpv, 0, "time-pos", MPV_FORMAT_DOUBLE)
+ mpv_observe_property(mpv, 0, "speed", MPV_FORMAT_DOUBLE)
+ mpv_observe_property(mpv, 0, "pause", MPV_FORMAT_FLAG)
+ mpv_observe_property(mpv, 0, "media-title", MPV_FORMAT_STRING)
+ mpv_observe_property(mpv, 0, "chapter-metadata/title", MPV_FORMAT_STRING)
+ mpv_observe_property(mpv, 0, "metadata/by-key/album", MPV_FORMAT_STRING)
+ mpv_observe_property(mpv, 0, "metadata/by-key/artist", MPV_FORMAT_STRING)
+ mpv_set_wakeup_callback(mpv, wakeup, TypeHelper.bridge(obj: self))
+ return
+ }
+
+ mpv_destroy(mpv)
+ }
+
+ @objc func initInput(_ input: OpaquePointer?) {
+ self.input.signal(input: input)
+ }
+
+ @objc func initCocoaCb() {
+ guard let app = NSApp as? Application else { return }
+ DispatchQueue.main.sync { app.initCocoaCb(mpv) }
+ }
+
+ @objc func startRemote() {
+#if HAVE_MACOS_MEDIA_PLAYER
+ if remote == nil { remote = RemoteCommandCenter() }
+ remote?.start()
+#endif
+ }
+
+ @objc func stopRemote() {
+#if HAVE_MACOS_MEDIA_PLAYER
+ remote?.stop()
+#endif
+ }
+
+ let wakeup: EventHelper.wakeup_cb = { ( ctx ) in
+ let event = unsafeBitCast(ctx, to: AppHub.self)
+ DispatchQueue.main.async { event.eventLoop() }
+ }
+
+ func eventLoop() {
+ while let mpv = mpv, let event = mpv_wait_event(mpv, 0) {
+ if event.pointee.event_id == MPV_EVENT_NONE { break }
+ handle(event: event)
+ }
+ }
+
+ func handle(event: UnsafeMutablePointer<mpv_event>) {
+ if let app = NSApp as? Application {
+ app.processEvent(event)
+ }
+
+#if HAVE_MACOS_MEDIA_PLAYER
+ if let remote = remote {
+ remote.processEvent(event)
+ }
+#endif
+
+ switch event.pointee.event_id {
+ case MPV_EVENT_SHUTDOWN:
+#if HAVE_MACOS_COCOA_CB
+ if let app = NSApp as? Application, app.cocoaCB?.isShuttingDown ?? false {
+ mpv = nil;
+ return
+ }
+#endif
+ mpv_destroy(mpv)
+ mpv = nil
+ default: break
+ }
+ }
+}
diff --git a/osdep/mac/application.m b/osdep/mac/application.m
index 32066d8ae0..b56882b6b8 100644
--- a/osdep/mac/application.m
+++ b/osdep/mac/application.m
@@ -26,7 +26,6 @@
#include "options/options.h"
#import "osdep/mac/application_objc.h"
-#import "osdep/mac/events_objc.h"
#include "osdep/threads.h"
#include "osdep/main-fn.h"
@@ -87,7 +86,7 @@ static mp_thread playback_thread_id;
@interface Application ()
{
- EventsResponder *_eventsResponder;
+ AppHub *_appHub;
}
@end
@@ -112,15 +111,15 @@ static void terminate_cocoa_application(void)
- (void)sendEvent:(NSEvent *)event
{
- if ([self modalWindow] || ![_eventsResponder.inputHelper processKeyWithEvent:event])
+ if ([self modalWindow] || ![_appHub.input processKeyWithEvent:event])
[super sendEvent:event];
- [_eventsResponder.inputHelper wakeup];
+ [_appHub.input wakeup];
}
- (id)init
{
if (self = [super init]) {
- _eventsResponder = [EventsResponder sharedInstance];
+ _appHub = [AppHub shared];
NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager];
[em setEventHandler:self
@@ -203,7 +202,7 @@ static const char mac_icon[] =
- (void)handleQuitEvent:(NSAppleEventDescriptor *)event
withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
- if (![_eventsResponder.inputHelper command:@"quit"])
+ if (![_appHub.input command:@"quit"])
terminate_cocoa_application();
}
@@ -219,7 +218,7 @@ static const char mac_icon[] =
range:NSMakeRange(0, [MPV_PROTOCOL length])];
url = [url stringByRemovingPercentEncoding];
- [_eventsResponder.inputHelper openWithFiles:@[url]];
+ [_appHub.input openWithFiles:@[url]];
}
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
@@ -231,7 +230,7 @@ static const char mac_icon[] =
SEL cmpsel = @selector(localizedStandardCompare:);
NSArray *files = [filenames sortedArrayUsingSelector:cmpsel];
- [_eventsResponder.inputHelper openWithFiles:files];
+ [_appHub.input openWithFiles:files];
}
@end
@@ -315,7 +314,6 @@ int cocoa_main(int argc, char *argv[])
{
@autoreleasepool {
application_instantiated = true;
- [[EventsResponder sharedInstance] setIsApplication:YES];
struct playback_thread_ctx ctx = {0};
ctx.argc = &argc;
@@ -332,7 +330,7 @@ int cocoa_main(int argc, char *argv[])
}
mp_thread_create(&playback_thread_id, playback_thread, &ctx);
- [[EventsResponder sharedInstance].inputHelper wait];
+ [[AppHub shared].input wait];
cocoa_run_runloop();
// This should never be reached: cocoa_run_runloop blocks until the
diff --git a/osdep/mac/events.m b/osdep/mac/events.m
deleted file mode 100644
index 127a674339..0000000000
--- a/osdep/mac/events.m
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Cocoa Application Event Handling
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#import <Cocoa/Cocoa.h>
-
-#include "mpv_talloc.h"
-#include "input/event.h"
-#include "input/input.h"
-#include "player/client.h"
-
-#import "osdep/mac/events_objc.h"
-#import "osdep/mac/application_objc.h"
-
-#include "config.h"
-
-#if HAVE_SWIFT
-#include "osdep/mac/swift.h"
-#endif
-
-@interface EventsResponder ()
-{
- struct mpv_handle *_ctx;
- BOOL _is_application;
-}
-
-- (BOOL)setMpvHandle:(struct mpv_handle *)ctx;
-- (void)initCocoaCb;
-- (void)readEvents;
-- (void)startMediaKeys;
-- (void)stopMediaKeys;
-@end
-
-void cocoa_init_media_keys(void)
-{
- [[EventsResponder sharedInstance] startMediaKeys];
-}
-
-void cocoa_uninit_media_keys(void)
-{
- [[EventsResponder sharedInstance] stopMediaKeys];
-}
-
-void cocoa_set_input_context(struct input_ctx *input_context)
-{
- [[EventsResponder sharedInstance].inputHelper signalWithInput:input_context];
-}
-
-static void wakeup(void *context)
-{
- [[EventsResponder sharedInstance] readEvents];
-}
-
-void cocoa_set_mpv_handle(struct mpv_handle *ctx)
-{
- if ([[EventsResponder sharedInstance] setMpvHandle:ctx]) {
- mpv_observe_property(ctx, 0, "duration", MPV_FORMAT_DOUBLE);
- mpv_observe_property(ctx, 0, "time-pos", MPV_FORMAT_DOUBLE);
- mpv_observe_property(ctx, 0, "speed", MPV_FORMAT_DOUBLE);
- mpv_observe_property(ctx, 0, "pause", MPV_FORMAT_FLAG);
- mpv_observe_property(ctx, 0, "media-title", MPV_FORMAT_STRING);
- mpv_observe_property(ctx, 0, "chapter-metadata/title", MPV_FORMAT_STRING);
- mpv_observe_property(ctx, 0, "metadata/by-key/album", MPV_FORMAT_STRING);
- mpv_observe_property(ctx, 0, "metadata/by-key/artist", MPV_FORMAT_STRING);
- mpv_set_wakeup_callback(ctx, wakeup, NULL);
- }
-}
-
-void cocoa_init_cocoa_cb(void)
-{
- [[EventsResponder sharedInstance] initCocoaCb];
-}
-
-@implementation EventsResponder
-
-@synthesize remoteCommandCenter = _remoteCommandCenter;
-@synthesize inputHelper = _inputHelper;
-
-+ (EventsResponder *)sharedInstance
-{
- static EventsResponder *responder = nil;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- responder = [EventsResponder new];
- responder.inputHelper = [[InputHelper alloc] init: nil :nil];
- });
- return responder;
-}
-
-- (void)setIsApplication:(BOOL)isApplication
-{
- _is_application = isApplication;
-}
-
-- (BOOL)setMpvHandle:(struct mpv_handle *)ctx
-{
- if (_is_application) {
- _ctx = ctx;
- return YES;
- }
-
- mpv_destroy(ctx);
- return NO;
-}
-
-- (void)initCocoaCb
-{
- if (_is_application) {
- dispatch_sync(dispatch_get_main_queue(), ^{
- [NSApp initCocoaCb:_ctx];
- });
- }
-}
-
-- (void)readEvents
-{
- dispatch_async(dispatch_get_main_queue(), ^{
- while (_ctx) {
- mpv_event *event = mpv_wait_event(_ctx, 0);
- if (event->event_id == MPV_EVENT_NONE)
- break;
- [self processEvent:event];
- }
- });
-}
-
--(void)processEvent:(struct mpv_event *)event
-{
- if(_is_application) {
- [NSApp processEvent:event];
- }
-
- if (_remoteCommandCenter) {
- [_remoteCommandCenter processEvent:event];
- }
-
- switch (event->event_id) {
- case MPV_EVENT_SHUTDOWN: {
-#if HAVE_MACOS_COCOA_CB
- if ([(Application *)NSApp cocoaCB].isShuttingDown) {
- _ctx = nil;
- return;
- }
-#endif
- mpv_destroy(_ctx);
- _ctx = nil;
- break;
- }
- default:
- break;
- }
-}
-
-- (void)startMediaKeys
-{
-#if HAVE_MACOS_MEDIA_PLAYER
- if (_remoteCommandCenter == nil) {
- _remoteCommandCenter = [[RemoteCommandCenter alloc] init];
- }
-#endif
-
- [_remoteCommandCenter start];
-}
-
-- (void)stopMediaKeys
-{
- [_remoteCommandCenter stop];
-}
-
-@end
diff --git a/osdep/mac/menu_bar.swift b/osdep/mac/menu_bar.swift
index 631007a074..f81e97daaf 100644
--- a/osdep/mac/menu_bar.swift
+++ b/osdep/mac/menu_bar.swift
@@ -318,7 +318,7 @@ class MenuBar: NSObject {
@objc func quit(_ menuItem: MenuItem) {
guard let menuConfig = menuItem.config else { return }
- EventsResponder.sharedInstance().inputHelper.command(menuConfig.command)
+ AppHub.shared.input.command(menuConfig.command)
}
@objc func openFiles() {
@@ -327,7 +327,7 @@ class MenuBar: NSObject {
panel.canChooseDirectories = true
if panel.runModal() == .OK {
- EventsResponder.sharedInstance().inputHelper.open(files: panel.urls.map { $0.path })
+ AppHub.shared.input.open(files: panel.urls.map { $0.path })
}
}
@@ -335,7 +335,7 @@ class MenuBar: NSObject {
let panel = NSOpenPanel()
if panel.runModal() == .OK, let url = panel.urls.first {
- EventsResponder.sharedInstance().inputHelper.command("loadlist \"\(url.path)\"")
+ AppHub.shared.input.command("loadlist \"\(url.path)\"")
}
}
@@ -355,13 +355,13 @@ class MenuBar: NSObject {
}
if alert.runModal() == .alertFirstButtonReturn && input.stringValue.count > 0 {
- EventsResponder.sharedInstance().inputHelper.open(files: [input.stringValue])
+ AppHub.shared.input.open(files: [input.stringValue])
}
}
@objc func command(_ menuItem: MenuItem) {
guard let menuConfig = menuItem.config else { return }
- EventsResponder.sharedInstance().inputHelper.command(menuConfig.command)
+ AppHub.shared.input.command(menuConfig.command)
}
@objc func url(_ menuItem: MenuItem) {
diff --git a/osdep/mac/meson.build b/osdep/mac/meson.build
index faebf7e1d6..de32eb2a3c 100644
--- a/osdep/mac/meson.build
+++ b/osdep/mac/meson.build
@@ -19,10 +19,18 @@ if get_option('optimization') != '0'
swift_flags += '-O'
endif
+if macos_cocoa_cb.allowed()
+ swift_flags += ['-D', 'HAVE_MACOS_COCOA_CB']
+endif
+
if macos_touchbar.allowed()
swift_flags += ['-D', 'HAVE_MACOS_TOUCHBAR']
endif
+if macos_media_player.allowed()
+ swift_flags += ['-D', 'HAVE_MACOS_MEDIA_PLAYER']
+endif
+
extra_flags = get_option('swift-flags').split()
swift_flags += extra_flags
diff --git a/osdep/mac/remote_command_center.swift b/osdep/mac/remote_command_center.swift
index bec63a1984..547a14c232 100644
--- a/osdep/mac/remote_command_center.swift
+++ b/osdep/mac/remote_command_center.swift
@@ -155,7 +155,7 @@ class RemoteCommandCenter: NSObject {
self.configs[event.command]?.state = state
}
- EventsResponder.sharedInstance().inputHelper.put(key: config.key | Int32(state))
+ AppHub.shared.input.put(key: config.key | Int32(state))
return .success
}
@@ -166,7 +166,7 @@ class RemoteCommandCenter: NSObject {
}
let cmd = String(format: "seek %.02f absolute", posEvent.positionTime)
- return EventsResponder.sharedInstance().inputHelper.command(cmd) ? .success : .commandFailed
+ return AppHub.shared.input.command(cmd) ? .success : .commandFailed
}
@objc func processEvent(_ event: UnsafeMutablePointer<mpv_event>) {
diff --git a/osdep/mac/swift_bridge.h b/osdep/mac/swift_bridge.h
index b47fbbaf05..f4d1c545d7 100644
--- a/osdep/mac/swift_bridge.h
+++ b/osdep/mac/swift_bridge.h
@@ -32,7 +32,6 @@
#include "video/out/win_state.h"
#include "osdep/mac/application_objc.h"
-#include "osdep/mac/events_objc.h"
// complex macros won't get imported to Swift so we have to reassign them
diff --git a/osdep/mac/touch_bar.swift b/osdep/mac/touch_bar.swift
index 002c3dacb1..c21776c9e2 100644
--- a/osdep/mac/touch_bar.swift
+++ b/osdep/mac/touch_bar.swift
@@ -225,12 +225,12 @@ class TouchBar: NSTouchBar, NSTouchBarDelegate {
@objc func buttonAction(_ button: NSButton) {
guard let identifier = getIdentifierFrom(view: button), let command = configs[identifier]?.command else { return }
- EventsResponder.sharedInstance().inputHelper.command(command)
+ AppHub.shared.input.command(command)
}
@objc func seekbarChanged(_ slider: NSSlider) {
guard let identifier = getIdentifierFrom(view: slider), let command = configs[identifier]?.command else { return }
- EventsResponder.sharedInstance().inputHelper.command(String(format: command, slider.doubleValue))
+ AppHub.shared.input.command(String(format: command, slider.doubleValue))
}
func format(time: Int) -> String {
diff --git a/player/main.c b/player/main.c
index 09cce990bb..48d29b520e 100644
--- a/player/main.c
+++ b/player/main.c
@@ -71,7 +71,7 @@ static const char def_config[] =
;
#if HAVE_COCOA
-#include "osdep/mac/events.h"
+#include "osdep/mac/app_bridge.h"
#endif
#ifndef FULLCONFIG
diff --git a/video/out/vo_libmpv.c b/video/out/vo_libmpv.c
index fafe85acda..7974eed3f7 100644
--- a/video/out/vo_libmpv.c
+++ b/video/out/vo_libmpv.c
@@ -28,7 +28,7 @@
#include "libmpv.h"
#if HAVE_MACOS_COCOA_CB
-#include "osdep/mac/events.h"
+#include "osdep/mac/app_bridge.h"
#endif
/*