diff options
author | Akemi <der.richter@gmx.de> | 2018-02-16 13:07:15 +0100 |
---|---|---|
committer | Kevin Mitchell <kevmitch@gmail.com> | 2018-02-28 00:48:44 -0800 |
commit | 938ad6ebc037ebb32b41619a31b15f8ade712867 (patch) | |
tree | fc8c27e6c73f79a75de42032dabdd3650ef54601 /video | |
parent | a4c436bac26cc9a6f257764bbb268adde8ef8496 (diff) | |
download | mpv-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
Diffstat (limited to 'video')
-rw-r--r-- | video/out/cocoa-cb/events_view.swift | 11 | ||||
-rw-r--r-- | video/out/cocoa-cb/window.swift | 118 | ||||
-rw-r--r-- | video/out/cocoa_cb_common.swift | 8 |
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 } |