App Bundles operate in their own shell environment that is different from the one in the terminal. the default PATH variable for all Bundles is /usr/bin:/bin:/usr/sbin:/sbin. because of that mpv can not find binaries installed by package manager that might be used in scripts for example. add an option to prepend paths to the Bundle PATH. we prepend to make the order fully configurable, opposed to appending where the default Bundle binaries would always take precedence.
Unified · Split
| @@ -6601,6 +6601,21 @@ them. · 6600 unmodified lines | |||
| 6601 | precedence over any other shortcuts, they are not propagated to the mpv core and they can't be | 6601 | precedence over any other shortcuts, they are not propagated to the mpv core and they can't be |
| 6602 | used in config files like ``input.conf`` or script bindings. | 6602 | used in config files like ``input.conf`` or script bindings. |
| 6603 | 6603 | ||
| 6604 | ``--macos-bundle-path=path1,path2,...`` | ||
| 6605 | App Bundles operate in their own shell environment that is different from the one in the | ||
| 6606 | terminal. The default PATH variable for all Bundles is ``/usr/bin:/bin:/usr/sbin:/sbin``. | ||
| 6607 | Because of that mpv can not find binaries installed by package manager that might be used in | ||
| 6608 | scripts for example. This option prepends all given paths to the default Bundle PATH. | ||
| 6609 | |||
| 6610 | Default value in following order: | ||
| 6611 | |||
| 6612 | :/usr/local/bin: homebrew (Intel) install path | ||
| 6613 | :/usr/local/sbin: homebrew (Intel) install path | ||
| 6614 | :/opt/local/bin: MacPorts install path | ||
| 6615 | :/opt/local/sbin: MacPorts install path | ||
| 6616 | :/opt/homebrew/bin: homebrew (ARM) install path | ||
| 6617 | :/opt/homebrew/sbin: homebrew (ARM) install path | ||
| 6618 | |||
| 6604 | ``--android-surface-size=<WxH>`` | 6619 | ``--android-surface-size=<WxH>`` |
| 6605 | Set dimensions of the rendering surface used by the Android gpu context. | 6620 | Set dimensions of the rendering surface used by the Android gpu context. |
| 6606 | Needs to be set by the embedding application if the dimensions change during | 6621 | Needs to be set by the embedding application if the dimensions change during |
| @@ -63,6 +63,7 @@ struct macos_opts { · 62 unmodified lines | |||
| 63 | int macos_geometry_calculation; | 63 | int macos_geometry_calculation; |
| 64 | int macos_render_timer; | 64 | int macos_render_timer; |
| 65 | bool macos_menu_shortcuts; | 65 | bool macos_menu_shortcuts; |
| 66 | char **macos_bundle_path; | ||
| 66 | int cocoa_cb_sw_renderer; | 67 | int cocoa_cb_sw_renderer; |
| 67 | bool cocoa_cb_10bit_context; | 68 | bool cocoa_cb_10bit_context; |
| 68 | int cocoa_cb_output_csp; | 69 | int cocoa_cb_output_csp; |
| @@ -53,6 +53,7 @@ const struct m_sub_options macos_conf = { · 52 unmodified lines | |||
| 53 | {"callback", RENDER_TIMER_CALLBACK}, {"precise", RENDER_TIMER_PRECISE}, | 53 | {"callback", RENDER_TIMER_CALLBACK}, {"precise", RENDER_TIMER_PRECISE}, |
| 54 | {"system", RENDER_TIMER_SYSTEM}, {"feedback", RENDER_TIMER_PRESENTATION_FEEDBACK})}, | 54 | {"system", RENDER_TIMER_SYSTEM}, {"feedback", RENDER_TIMER_PRESENTATION_FEEDBACK})}, |
| 55 | {"macos-menu-shortcuts", OPT_BOOL(macos_menu_shortcuts)}, | 55 | {"macos-menu-shortcuts", OPT_BOOL(macos_menu_shortcuts)}, |
| 56 | {"macos-bundle-path", OPT_STRINGLIST(macos_bundle_path)}, | ||
| 56 | {"cocoa-cb-sw-renderer", OPT_CHOICE(cocoa_cb_sw_renderer, | 57 | {"cocoa-cb-sw-renderer", OPT_CHOICE(cocoa_cb_sw_renderer, |
| 57 | {"auto", -1}, {"no", 0}, {"yes", 1})}, | 58 | {"auto", -1}, {"no", 0}, {"yes", 1})}, |
| 58 | {"cocoa-cb-10bit-context", OPT_BOOL(cocoa_cb_10bit_context)}, | 59 | {"cocoa-cb-10bit-context", OPT_BOOL(cocoa_cb_10bit_context)}, |
| @@ -80,6 +81,10 @@ const struct m_sub_options macos_conf = { · 21 unmodified lines | |||
| 80 | .macos_fs_animation_duration = -1, | 81 | .macos_fs_animation_duration = -1, |
| 81 | .macos_render_timer = RENDER_TIMER_CALLBACK, | 82 | .macos_render_timer = RENDER_TIMER_CALLBACK, |
| 82 | .macos_menu_shortcuts = true, | 83 | .macos_menu_shortcuts = true, |
| 84 | .macos_bundle_path = (char *[]){ | ||
| 85 | "/usr/local/bin", "/usr/local/sbin", "/opt/local/bin", "/opt/local/sbin", | ||
| 86 | "/opt/homebrew/bin", "/opt/homebrew/sbin", NULL | ||
| 87 | }, | ||
| 83 | .cocoa_cb_sw_renderer = -1, | 88 | .cocoa_cb_sw_renderer = -1, |
| 84 | .cocoa_cb_10bit_context = true, | 89 | .cocoa_cb_10bit_context = true, |
| 85 | .cocoa_cb_output_csp = MAC_CSP_AUTO, | 90 | .cocoa_cb_output_csp = MAC_CSP_AUTO, |
| @@ -38,6 +38,7 @@ class AppHub: NSObject { · 37 unmodified lines | |||
| 38 | 38 | ||
| 39 | let MPV_PROTOCOL: String = "mpv://" | 39 | let MPV_PROTOCOL: String = "mpv://" |
| 40 | var isApplication: Bool { return NSApp is Application } | 40 | var isApplication: Bool { return NSApp is Application } |
| 41 | var isBundle: Bool { return ProcessInfo.processInfo.environment["MPVBUNDLE"] == "true" } | ||
| 41 | var openEvents: Int = 0 | 42 | var openEvents: Int = 0 |
| 42 | 43 | ||
| 43 | private override init() { | 44 | private override init() { |
| @@ -59,6 +60,12 @@ class AppHub: NSObject { · 15 unmodified lines | |||
| 59 | input.option = option | 60 | input.option = option |
| 60 | DispatchQueue.main.sync { menu = MenuBar(self) } | 61 | DispatchQueue.main.sync { menu = MenuBar(self) } |
| 61 | } | 62 | } |
| 63 | if let bundlePath = option?.mac.macos_bundle_path, isBundle { | ||
| 64 | let path = TypeHelper.toStringArray(bundlePath).joined(separator: ":") + ":" + | ||
| 65 | (ProcessInfo.processInfo.environment["PATH"] ?? "") | ||
| 66 | log.verbose("Setting Bundle PATH to: \(path)") | ||
| 67 | _ = path.withCString { setenv("PATH", $0, 1) } | ||
| 68 | } | ||
| 62 | 69 | ||
| 63 | #if HAVE_MACOS_MEDIA_PLAYER | 70 | #if HAVE_MACOS_MEDIA_PLAYER |
| 64 | remote?.registerEvents() | 71 | remote?.registerEvents() |
| @@ -20,7 +20,6 @@ import Cocoa · 19 unmodified lines | |||
| 20 | class Application: NSApplication, NSApplicationDelegate { | 20 | class Application: NSApplication, NSApplicationDelegate { |
| 21 | var appHub: AppHub { return AppHub.shared } | 21 | var appHub: AppHub { return AppHub.shared } |
| 22 | var eventManager: NSAppleEventManager { return NSAppleEventManager.shared() } | 22 | var eventManager: NSAppleEventManager { return NSAppleEventManager.shared() } |
| 23 | var isBundle: Bool { return ProcessInfo.processInfo.environment["MPVBUNDLE"] == "true" } | ||
| 24 | var playbackThreadId: mp_thread! | 23 | var playbackThreadId: mp_thread! |
| 25 | var argc: Int32? | 24 | var argc: Int32? |
| 26 | var argv: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>? | 25 | var argv: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>? |
| @@ -78,20 +77,13 @@ class Application: NSApplication, NSApplicationDelegate { · 51 unmodified lines | |||
| 78 | } | 77 | } |
| 79 | 78 | ||
| 80 | func setupBundle() { | 79 | func setupBundle() { |
| 81 | if !isBundle { return } | 80 | if !appHub.isBundle { return } |
| 82 | 81 | ||
| 83 | // started from finder the first argument after the binary may start with -psn_ | 82 | // started from finder the first argument after the binary may start with -psn_ |
| 84 | if CommandLine.argc > 1 && CommandLine.arguments[1].hasPrefix("-psn_") { | 83 | if CommandLine.argc > 1 && CommandLine.arguments[1].hasPrefix("-psn_") { |
| 85 | argc? = 1 | 84 | argc? = 1 |
| 86 | argv?[1] = nil | 85 | argv?[1] = nil |
| 87 | } | 86 | } |
| 88 | |||
| 89 | let path = (ProcessInfo.processInfo.environment["PATH"] ?? "") + | ||
| 90 | ":/usr/local/bin:/usr/local/sbin" + // homebrew Intel | ||
| 91 | ":/opt/local/bin:/opt/local/sbin" + // MacPorts | ||
| 92 | ":/opt/homebrew/bin:/opt/homebrew/sbin" // homebrew ARM | ||
| 93 | appHub.log.verbose("Setting Bundle $PATH to: \(path)") | ||
| 94 | _ = path.withCString { setenv("PATH", $0, 1) } | ||
| 95 | } | 87 | } |
| 96 | 88 | ||
| 97 | let playbackThread: @convention(c) (UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? = { (ptr: UnsafeMutableRawPointer) in | 89 | let playbackThread: @convention(c) (UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? = { (ptr: UnsafeMutableRawPointer) in |
| @@ -108,7 +100,7 @@ class Application: NSApplication, NSApplicationDelegate { · 10 unmodified lines | |||
| 108 | 100 | ||
| 109 | NSApp = self | 101 | NSApp = self |
| 110 | NSApp.delegate = self | 102 | NSApp.delegate = self |
| 111 | NSApp.setActivationPolicy(isBundle ? .regular : .accessory) | 103 | NSApp.setActivationPolicy(appHub.isBundle ? .regular : .accessory) |
| 112 | setupBundle() | 104 | setupBundle() |
| 113 | pthread_create(&playbackThreadId, nil, playbackThread, TypeHelper.bridge(obj: self)) | 105 | pthread_create(&playbackThreadId, nil, playbackThread, TypeHelper.bridge(obj: self)) |
| 114 | appHub.input.wait() | 106 | appHub.input.wait() |
| @@ -50,6 +50,17 @@ class TypeHelper { · 49 unmodified lines | |||
| 50 | } | 50 | } |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | // char ** OPT_STRINGLIST | ||
| 54 | class func toStringArray(_ obj: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>?) -> [String] { | ||
| 55 | guard var cStringArray = obj else { return [] } | ||
| 56 | var stringArray: [String] = [] | ||
| 57 | while let cString = cStringArray.pointee { | ||
| 58 | stringArray.append(String(cString: cString)) | ||
| 59 | cStringArray += 1 | ||
| 60 | } | ||
| 61 | return stringArray | ||
| 62 | } | ||
| 63 | |||
| 53 | // *(char **) MPV_FORMAT_STRING | 64 | // *(char **) MPV_FORMAT_STRING |
| 54 | class func toString(_ obj: UnsafeMutableRawPointer?) -> String? { | 65 | class func toString(_ obj: UnsafeMutableRawPointer?) -> String? { |
| 55 | guard let str = obj else { return nil } | 66 | guard let str = obj else { return nil } |