summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
/*