summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkemi <der.richter@gmx.de>2018-02-16 13:07:15 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-02-28 00:48:44 -0800
commit938ad6ebc037ebb32b41619a31b15f8ade712867 (patch)
treefc8c27e6c73f79a75de42032dabdd3650ef54601
parenta4c436bac26cc9a6f257764bbb268adde8ef8496 (diff)
downloadmpv-938ad6ebc037ebb32b41619a31b15f8ade712867.tar.bz2
mpv-938ad6ebc037ebb32b41619a31b15f8ade712867.tar.xz
cocoa-cb: change border and borderless window styling
the title bar is now within the window bounds instead of outside. same as QuickTime Player. it supports several standard styles, two dark and two light ones. additionally we have properly rounded corners now and the borderless window also has the proper window shadow. Also make the earliest supported macOS version 10.10. Fixes #4789, #3944
-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')