summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst12
-rw-r--r--options/options.c5
-rw-r--r--options/options.h1
-rw-r--r--osdep/macOS_mpv_helper.swift1
-rw-r--r--osdep/macosx_application.m16
-rw-r--r--video/out/cocoa-cb/events_view.swift11
-rw-r--r--video/out/cocoa-cb/window.swift118
-rw-r--r--video/out/cocoa_cb_common.swift8
-rw-r--r--waftools/detections/compiler_swift.py6
9 files changed, 158 insertions, 20 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 1a5af8121a..2a2ca665c3 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -4852,6 +4852,18 @@ The following video options are currently all specific to ``--vo=gpu`` and
OS X only.
+``--macos-title-bar-style=<dark|ultradark|light|mediumlight|auto>``
+ Sets the styling of the title bar (default: dark).
+ OS X and cocoa-cb only
+
+ :dark: Dark title bar with vibrancy, a subtle blurring effect that
+ dynamically blends the background (Video) into the title bar.
+ :ultradark: Darker title bar with vibrancy (like QuickTime Player).
+ :light: Bright title bar with vibrancy.
+ :mediumlight: Less bright title bar with vibrancy.
+ :auto: Detects the system settings and sets the title bar styling
+ appropriately, either ultradark or mediumlight.
+
``--android-surface-size=<WxH>``
Set dimensions of the rendering surface used by the Android gpu context.
Needs to be set by the embedding application if the dimensions change during
diff --git a/options/options.c b/options/options.c
index 2f4116299d..878f7be12f 100644
--- a/options/options.c
+++ b/options/options.c
@@ -87,6 +87,7 @@ extern const struct m_sub_options d3d11_conf;
extern const struct m_sub_options d3d11va_conf;
extern const struct m_sub_options angle_conf;
extern const struct m_sub_options cocoa_conf;
+extern const struct m_sub_options macos_conf;
extern const struct m_sub_options android_conf;
static const struct m_sub_options screenshot_conf = {
@@ -735,6 +736,10 @@ const m_option_t mp_opts[] = {
OPT_SUBSTRUCT("", cocoa_opts, cocoa_conf, 0),
#endif
+#if HAVE_MACOS_COCOA_CB
+ OPT_SUBSTRUCT("", macos_opts, macos_conf, 0),
+#endif
+
#if HAVE_ANDROID
OPT_SUBSTRUCT("", android_opts, android_conf, 0),
#endif
diff --git a/options/options.h b/options/options.h
index db5b92b86a..e76aa03db4 100644
--- a/options/options.h
+++ b/options/options.h
@@ -341,6 +341,7 @@ typedef struct MPOpts {
struct d3d11_opts *d3d11_opts;
struct d3d11va_opts *d3d11va_opts;
struct cocoa_opts *cocoa_opts;
+ struct macos_opts *macos_opts;
struct android_opts *android_opts;
struct dvd_opts *dvd_opts;
diff --git a/osdep/macOS_mpv_helper.swift b/osdep/macOS_mpv_helper.swift
index 15081d0133..c8b9771ba6 100644
--- a/osdep/macOS_mpv_helper.swift
+++ b/osdep/macOS_mpv_helper.swift
@@ -39,6 +39,7 @@ class MPVHelper: NSObject {
mpv_observe_property(mpvHandle, 0, "ontop", MPV_FORMAT_FLAG)
mpv_observe_property(mpvHandle, 0, "border", MPV_FORMAT_FLAG)
mpv_observe_property(mpvHandle, 0, "keepaspect-window", MPV_FORMAT_FLAG)
+ mpv_observe_property(mpvHandle, 0, "macos-title-bar-style", MPV_FORMAT_STRING)
}
func setGLCB() {
diff --git a/osdep/macosx_application.m b/osdep/macosx_application.m
index a65910ec9e..fe117f7a1c 100644
--- a/osdep/macosx_application.m
+++ b/osdep/macosx_application.m
@@ -23,6 +23,7 @@
#include "common/msg.h"
#include "input/input.h"
#include "player/client.h"
+#include "options/m_config.h"
#import "osdep/macosx_application_objc.h"
#include "osdep/macosx_compat.h"
@@ -39,6 +40,21 @@
#define MPV_PROTOCOL @"mpv://"
+struct macos_opts {
+ int macos_title_bar_style;
+};
+
+#define OPT_BASE_STRUCT struct macos_opts
+const struct m_sub_options macos_conf = {
+ .opts = (const struct m_option[]) {
+ OPT_CHOICE("macos-title-bar-style", macos_title_bar_style, 0,
+ ({"dark", 0}, {"ultradark", 1}, {"light", 2},
+ {"mediumlight", 3}, {"auto", 4})),
+ {0}
+ },
+ .size = sizeof(struct macos_opts),
+};
+
// Whether the NSApplication singleton was created. If this is false, we are
// running in libmpv mode, and cocoa_main() was never called.
static bool application_instantiated;
diff --git a/video/out/cocoa-cb/events_view.swift b/video/out/cocoa-cb/events_view.swift
index 4cb154c64a..e2da8345f1 100644
--- a/video/out/cocoa-cb/events_view.swift
+++ b/video/out/cocoa-cb/events_view.swift
@@ -110,12 +110,14 @@ class EventsView: NSView {
if mpv.getBoolProperty("input-cursor") {
cocoa_put_key_with_modifiers(SWIFT_KEY_MOUSE_LEAVE, 0)
}
+ cocoaCB.window.hideTitleBar()
}
override func mouseMoved(with event: NSEvent) {
if mpv != nil && mpv.getBoolProperty("input-cursor") {
signalMouseMovement(event)
}
+ cocoaCB.window.showTitleBar()
}
override func mouseDragged(with event: NSEvent) {
@@ -233,8 +235,7 @@ class EventsView: NSView {
let menuBarHeight = NSApp.mainMenu!.menuBarHeight
if cocoaCB.window.isInFullscreen && (menuBarHeight > 0) {
- let titleBar = NSWindow.frameRect(forContentRect: CGRect.zero, styleMask: .titled)
- topMargin = titleBar.size.height + 1 + menuBarHeight
+ topMargin = cocoaCB.window.titleBarHeight + 1 + menuBarHeight
}
var vF = window!.screen!.frame
@@ -244,7 +245,11 @@ class EventsView: NSView {
let vFV = convert(vFW, from: nil)
let pt = convert(window!.mouseLocationOutsideOfEventStream, from: nil)
- let clippedBounds = bounds.intersection(vFV)
+ var clippedBounds = bounds.intersection(vFV)
+ if !cocoaCB.window.isInFullscreen {
+ clippedBounds.origin.y += cocoaCB.window.titleBarHeight
+ clippedBounds.size.height -= cocoaCB.window.titleBarHeight
+ }
return clippedBounds.contains(pt)
}
diff --git a/video/out/cocoa-cb/window.swift b/video/out/cocoa-cb/window.swift
index 869bfb8be6..bd94330dcb 100644
--- a/video/out/cocoa-cb/window.swift
+++ b/video/out/cocoa-cb/window.swift
@@ -49,6 +49,21 @@ class Window: NSWindow, NSWindowDelegate {
}
}
+ var border: Bool = true {
+ didSet { if !border { hideTitleBar() } }
+ }
+
+ var titleBarEffect: NSVisualEffectView?
+ var titleBar: NSView {
+ get { return (standardWindowButton(.closeButton)?.superview)! }
+ }
+ var titleBarHeight: CGFloat {
+ get { return NSWindow.frameRect(forContentRect: CGRect.zero, styleMask: .titled).size.height }
+ }
+ var titleButtons: [NSButton] {
+ get { return ([.closeButton, .miniaturizeButton, .zoomButton] as [NSWindow.ButtonType]).flatMap { standardWindowButton($0) } }
+ }
+
override var canBecomeKey: Bool { return true }
override var canBecomeMain: Bool { return true }
@@ -95,6 +110,94 @@ class Window: NSWindow, NSWindowDelegate {
}
}
+ func initTitleBar() {
+ var f = contentView!.bounds
+ f.origin.y = f.size.height - titleBarHeight
+ f.size.height = titleBarHeight
+
+ styleMask.insert(.fullSizeContentView)
+ titleBar.alphaValue = 0
+ titlebarAppearsTransparent = true
+ titleBarEffect = NSVisualEffectView(frame: f)
+ titleBarEffect!.alphaValue = 0
+ titleBarEffect!.blendingMode = .withinWindow
+ titleBarEffect!.autoresizingMask = [.viewWidthSizable, .viewMinYMargin]
+
+ setTitleBarStyle(mpv.getStringProperty("macos-title-bar-style") ?? "dark")
+ contentView!.addSubview(titleBarEffect!, positioned: .above, relativeTo: nil)
+
+ border = mpv.getBoolProperty("border")
+ }
+
+ func setTitleBarStyle(_ style: String) {
+ var effect = style
+ if effect == "auto" {
+ let systemStyle = UserDefaults.standard.string(forKey: "AppleInterfaceStyle")
+ effect = systemStyle == nil ? "mediumlight" : "ultradark"
+ }
+
+ switch effect {
+ case "mediumlight":
+ appearance = NSAppearance(named: NSAppearanceNameVibrantLight)
+ titleBarEffect!.material = .titlebar
+ titleBarEffect!.state = .followsWindowActiveState
+ case "light":
+ appearance = NSAppearance(named: NSAppearanceNameVibrantLight)
+ titleBarEffect!.material = .light
+ titleBarEffect!.state = .active
+ case "ultradark":
+ appearance = NSAppearance(named: NSAppearanceNameVibrantDark)
+ titleBarEffect!.material = .titlebar
+ titleBarEffect!.state = .followsWindowActiveState
+ case "dark": fallthrough
+ default:
+ appearance = NSAppearance(named: NSAppearanceNameVibrantDark)
+ titleBarEffect!.material = .dark
+ titleBarEffect!.state = .active
+ }
+ }
+
+ func showTitleBar() {
+ if !border && !isInFullscreen { return }
+ let loc = cocoaCB.view.convert(mouseLocationOutsideOfEventStream, from: nil)
+
+ titleButtons.forEach { $0.isHidden = false }
+ NSAnimationContext.runAnimationGroup({ (context) -> Void in
+ context.duration = 0.20
+ titleBar.animator().alphaValue = 1
+ if !isInFullscreen && !isAnimating {
+ titleBarEffect!.animator().alphaValue = 1
+ }
+ }, completionHandler: nil )
+
+ if loc.y > titleBarHeight {
+ hideTitleBarDelayed()
+ } else {
+ NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(hideTitleBar), object: nil)
+ }
+ }
+
+ func hideTitleBar() {
+ if isInFullscreen && !isAnimating {
+ titleBarEffect!.alphaValue = 0
+ return
+ }
+ NSAnimationContext.runAnimationGroup({ (context) -> Void in
+ context.duration = 0.20
+ titleBar.animator().alphaValue = 0
+ titleBarEffect!.animator().alphaValue = 0
+ }, completionHandler: {
+ self.titleButtons.forEach { $0.isHidden = true }
+ })
+ }
+
+ func hideTitleBarDelayed() {
+ NSObject.cancelPreviousPerformRequests(withTarget: self,
+ selector: #selector(hideTitleBar),
+ object: nil)
+ perform(#selector(hideTitleBar), with: nil, afterDelay: 0.5)
+ }
+
override func toggleFullScreen(_ sender: Any?) {
if isAnimating {
return
@@ -146,6 +249,7 @@ class Window: NSWindow, NSWindowDelegate {
let cRect = contentRect(forFrameRect: frame)
var intermediateFrame = aspectFit(rect: cRect, in: targetScreen!.frame)
intermediateFrame = frameRect(forContentRect: intermediateFrame)
+ hideTitleBar()
NSAnimationContext.runAnimationGroup({ (context) -> Void in
context.duration = duration - 0.05
@@ -156,6 +260,7 @@ class Window: NSWindow, NSWindowDelegate {
func window(_ window: NSWindow, startCustomAnimationToExitFullScreenWithDuration duration: TimeInterval) {
let newFrame = calculateWindowPosition(for: targetScreen!, withoutBounds: targetScreen == screen)
let intermediateFrame = aspectFit(rect: newFrame, in: screen!.frame)
+ hideTitleBar()
setFrame(intermediateFrame, display: true)
NSAnimationContext.runAnimationGroup({ (context) -> Void in
@@ -169,6 +274,7 @@ class Window: NSWindow, NSWindowDelegate {
cocoaCB.flagEvents(VO_EVENT_FULLSCREEN_STATE)
cocoaCB.updateCusorVisibility()
endAnimation(frame)
+ showTitleBar()
}
func windowDidExitFullScreen(_ notification: Notification) {
@@ -222,18 +328,6 @@ class Window: NSWindow, NSWindowDelegate {
cocoaCB.layer.neededFlips += 1
}
- func setBorder(_ state: Bool) {
- if styleMask.contains(.titled) != state {
- if state {
- styleMask.remove(.borderless)
- styleMask.insert(.titled)
- } else {
- styleMask.remove(.titled)
- styleMask.insert(.borderless)
- }
- }
- }
-
func setOnTop(_ state: Bool) {
if state {
let ontopLevel = mpv.getStringProperty("ontop-level") ?? "window"
diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift
index cd43195a3e..c18bb29971 100644
--- a/video/out/cocoa_cb_common.swift
+++ b/video/out/cocoa_cb_common.swift
@@ -99,12 +99,12 @@ class CocoaCB: NSObject {
screen: targetScreen, cocoaCB: self)
win.title = window.title
win.setOnTop(mpv.getBoolProperty("ontop"))
- win.setBorder(mpv.getBoolProperty("border"))
win.keepAspect = mpv.getBoolProperty("keepaspect-window")
window.close()
window = win
window.contentView!.addSubview(view)
view.frame = window.contentView!.frame
+ window.initTitleBar()
setAppIcon()
window.isRestorable = false
@@ -486,7 +486,7 @@ class CocoaCB: NSObject {
switch String(cString: property.name) {
case "border":
if let data = MPVHelper.mpvFlagToBool(property.data) {
- window.setBorder(data)
+ window.border = data
}
case "ontop":
if let data = MPVHelper.mpvFlagToBool(property.data) {
@@ -496,6 +496,10 @@ class CocoaCB: NSObject {
if let data = MPVHelper.mpvFlagToBool(property.data) {
window.keepAspect = data
}
+ case "macos-title-bar-style":
+ if let data = MPVHelper.mpvStringArrayToString(property.data) {
+ window.setTitleBarStyle(data)
+ }
default:
break
}
diff --git a/waftools/detections/compiler_swift.py b/waftools/detections/compiler_swift.py
index 81c71415f7..2e24362ecf 100644
--- a/waftools/detections/compiler_swift.py
+++ b/waftools/detections/compiler_swift.py
@@ -8,8 +8,9 @@ def __run(cmd):
return ""
def __add_swift_flags(ctx):
- ctx.env.SWIFT_FLAGS = ('-frontend -c -sdk %s -enable-objc-interop -emit-objc-header'
- ' -emit-module -parse-as-library') % (ctx.env.MACOS_SDK)
+ ctx.env.SWIFT_FLAGS = ('-frontend -c -sdk %s -enable-objc-interop'
+ ' -emit-objc-header -parse-as-library'
+ ' -target x86_64-apple-macosx10.10') % (ctx.env.MACOS_SDK)
swift_version = __run([ctx.env.SWIFT, '-version']).split(' ')[3].split('.')[:2]
major, minor = [int(n) for n in swift_version]
@@ -31,7 +32,6 @@ def __find_swift_library(ctx):
'Toolchains/XcodeDefault.xctoolchain/usr/lib/swift_static/macosx',
'usr/lib/swift_static/macosx'
]
- dev_path = __run('xcode-select -p')[1:]
dev_path = __run(['xcode-select', '-p'])[1:]
ctx.start_msg('Checking for Swift Library')