diff options
Diffstat (limited to 'video/out')
-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 } |