Skip to content

Commit e332032

Browse files
committed
cocoa-cb: re-enable wid (NSView) embedding on macOS for libmpv use
In version 0.37, support for the old cocoa backend has been dropped, which unfortunately also removed the ability of embedding mpv in native applications by specifying a wid - which is still working for all other platforms. This PR aims to remedy that situation by leveraging the existing cocoa-cb implementation which already had just about everything that it takes and it has been merely about gluing loose ends together and omitting those parts that are specific to standalone application use, like NSApplication and NSWindow.
1 parent 72efbfd commit e332032

File tree

9 files changed

+257
-38
lines changed

9 files changed

+257
-38
lines changed

DOCS/man/options.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3763,6 +3763,21 @@ Window
37633763
specially, and mpv will draw on top of the desktop wallpaper and below
37643764
desktop icons.
37653765

3766+
On macOS/Cocoa, the ID is interpreted as ``NSView*``. Pass it as value cast
3767+
to ``intptr_t``. mpv will create its own sub-view.
3768+
The following constraints apply:
3769+
- This is only supported with libmpv. Specifying a wid with mpv cli will
3770+
and with an error
3771+
- The supplied NSView pointer must be from the same process into which
3772+
libmpv is loaded. Since macOS does not support cross-process window
3773+
access, attempts trying to do so will always crash
3774+
- The process needs to have an NSApplication with event loop running
3775+
on the main thread
3776+
- The wid must be set after mpv_create() and before mpv_initialize()
3777+
and cannot be changed afterwards
3778+
- The only supported vo is libmpv, which will be automatically set when
3779+
a wid is provided
3780+
37663781
On Android, the ID is interpreted as ``android.view.Surface``. Pass it as a
37673782
value cast to ``intptr_t``. Use with ``--vo=mediacodec_embed`` and
37683783
``--hwdec=mediacodec`` for direct rendering using MediaCodec, or with

osdep/mac/app_bridge.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ void cocoa_uninit_media_keys(void);
107107
void cocoa_set_input_context(struct input_ctx *input_context);
108108
void cocoa_set_mpv_handle(struct mpv_handle *ctx);
109109
void cocoa_init_cocoa_cb(void);
110+
void cocoa_init_embedded_view(int64_t wid);
110111
// multithreaded wrapper for mpv_main
111112
int cocoa_main(int argc, char *argv[]);
112113

osdep/mac/app_bridge.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ void cocoa_init_cocoa_cb(void)
161161
[[AppHub shared] initCocoaCb];
162162
}
163163

164+
void cocoa_init_embedded_view(int64_t wid)
165+
{
166+
[[AppHub shared] initCocoaCbWithView:(__bridge NSView *)(void *)wid];
167+
}
168+
164169
int cocoa_main(int argc, char *argv[])
165170
{
166171
return [(Application *)[Application sharedApplication] main:argc :argv];

osdep/mac/app_hub.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,13 @@ class AppHub: NSObject {
5151
}
5252

5353
@objc func initMpv(_ mpv: OpaquePointer) {
54+
55+
log.log = mp_log_new(nil, mp_client_get_log(mpv), "app")
56+
log.verbose("AppHub: initMpv enter")
57+
5458
event = EventHelper(self, mpv)
5559
if let mpv = event?.mpv {
5660
self.mpv = mpv
57-
log.log = mp_log_new(nil, mp_client_get_log(mpv), "app")
5861
option = OptionHelper(UnsafeMutablePointer(mpv), mp_client_get_global(mpv))
5962
input.option = option
6063
DispatchQueue.main.sync { menu = MenuBar(self) }
@@ -76,6 +79,7 @@ class AppHub: NSObject {
7679
}
7780

7881
@objc func initInput(_ input: OpaquePointer?) {
82+
if !isApplication { return }
7983
log.verbose("Initialising Input")
8084
self.input.signal(input: input)
8185
}
@@ -90,6 +94,15 @@ class AppHub: NSObject {
9094
#endif
9195
}
9296

97+
@objc func initCocoaCbWithView(_ view: NSView) {
98+
#if HAVE_MACOS_COCOA_CB
99+
log.verbose("Initialising CocoaCB (embedded view)")
100+
DispatchQueue.main.sync {
101+
self.cocoaCb = CocoaCB(mpv_create_client(mpv, "cocoacb"), view)
102+
}
103+
#endif
104+
}
105+
93106
@objc func startRemote() {
94107
#if HAVE_MACOS_MEDIA_PLAYER
95108
log.verbose("Starting RemoteCommandCenter")

osdep/mac/event_helper.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,6 @@ class EventHelper {
7171
var events: [String: [Int: EventSubscriber]] = [:]
7272

7373
init?(_ appHub: AppHub, _ mpv: OpaquePointer) {
74-
if !appHub.isApplication {
75-
mpv_destroy(mpv)
76-
return nil
77-
}
78-
7974
self.appHub = appHub
8075
self.mpv = mpv
8176
mpv_set_wakeup_callback(mpv, wakeup, TypeHelper.bridge(obj: self))

player/main.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "common/codecs.h"
4343
#include "common/encode.h"
4444
#include "options/m_config.h"
45+
#include "options/m_config_frontend.h"
4546
#include "options/m_option.h"
4647
#include "options/m_property.h"
4748
#include "common/common.h"
@@ -366,6 +367,25 @@ int mp_initialize(struct MPContext *mpctx, char **options)
366367
return r == M_OPT_EXIT ? 1 : -1;
367368
}
368369

370+
#if HAVE_COCOA
371+
372+
if (mpctx->is_cli && opts->vo->WinID > 0)
373+
{
374+
MP_FATAL(mpctx, "On macOS, window embedding via 'wid' parameter is not supported from the CLI.\n");
375+
return -1;
376+
}
377+
378+
if (!mpctx->is_cli && opts->vo->WinID > 0)
379+
{
380+
MP_INFO(mpctx, "A 'wid' for window embedding is specified. Setting vo=libmpv, which is the only supported way on macOS.\n");
381+
382+
int r = m_config_set_option_cli(mpctx->mconfig, bstr0("vo"), bstr0("libmpv"), 0);
383+
if (r < 0) {
384+
MP_WARN(mpctx, "Failed to force vo=libmpv for wid embedding (err=%d)\n", r);
385+
}
386+
}
387+
#endif
388+
369389
if (opts->operation_mode == 1) {
370390
m_config_set_profile(mpctx->mconfig, "builtin-pseudo-gui",
371391
M_SETOPT_NO_OVERWRITE);
@@ -410,8 +430,10 @@ int mp_initialize(struct MPContext *mpctx, char **options)
410430
MP_STATS(mpctx, "start init");
411431

412432
#if HAVE_COCOA
413-
mpv_handle *ctx = mp_new_client(mpctx->clients, "mac");
414-
cocoa_set_mpv_handle(ctx);
433+
if (mpctx->is_cli || opts->vo->WinID > 0) {
434+
mpv_handle *ctx = mp_new_client(mpctx->clients, "mac");
435+
cocoa_set_mpv_handle(ctx);
436+
}
415437
#endif
416438

417439
#if HAVE_WIN32_SMTC

0 commit comments

Comments
 (0)