summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
Diffstat (limited to 'video/out')
-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
3 files changed, 120 insertions, 17 deletions
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
}