summaryrefslogtreecommitdiffstats
path: root/video/out/mac
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/mac')
-rw-r--r--video/out/mac/common.swift228
-rw-r--r--video/out/mac/gl_layer.swift32
-rw-r--r--video/out/mac/metal_layer.swift12
-rw-r--r--video/out/mac/title_bar.swift16
-rw-r--r--video/out/mac/view.swift152
-rw-r--r--video/out/mac/window.swift83
6 files changed, 222 insertions, 301 deletions
diff --git a/video/out/mac/common.swift b/video/out/mac/common.swift
index aac7050..594a4b8 100644
--- a/video/out/mac/common.swift
+++ b/video/out/mac/common.swift
@@ -19,11 +19,13 @@ import Cocoa
import IOKit.pwr_mgt
class Common: NSObject {
- var mpv: MPVHelper?
+ var option: OptionHelper
+ var input: InputHelper?
var log: LogHelper
+ var vo: UnsafeMutablePointer<vo>?
let queue: DispatchQueue = DispatchQueue(label: "io.mpv.queue")
- var window: Window?
+ @objc var window: Window?
var view: View?
var titleBar: TitleBar?
@@ -46,39 +48,26 @@ class Common: NSObject {
didSet { if let window = window { window.title = title } }
}
- init(_ mpLog: OpaquePointer?) {
- log = LogHelper(mpLog)
+ init(_ option: OptionHelper, _ log: LogHelper) {
+ self.option = option
+ self.log = log
}
func initMisc(_ vo: UnsafeMutablePointer<vo>) {
- guard let mpv = mpv else {
- log.sendError("Something went wrong, no MPVHelper was initialized")
- exit(1)
- }
-
startDisplayLink(vo)
initLightSensor()
addDisplayReconfigureObserver()
addAppNotifications()
- mpv.setMacOptionCallback(macOptsWakeupCallback, context: self)
+ option.setMacOptionCallback(macOptsWakeupCallback, context: self)
}
func initApp() {
- guard let mpv = mpv else {
- log.sendError("Something went wrong, no MPVHelper was initialized")
- exit(1)
- }
-
var policy: NSApplication.ActivationPolicy = .regular
- switch mpv.macOpts.macos_app_activation_policy {
- case 0:
- policy = .regular
- case 1:
- policy = .accessory
- case 2:
- policy = .prohibited
- default:
- break
+ switch option.mac.macos_app_activation_policy {
+ case 0: policy = .regular
+ case 1: policy = .accessory
+ case 2: policy = .prohibited
+ default: break
}
NSApp.setActivationPolicy(policy)
@@ -86,63 +75,67 @@ class Common: NSObject {
}
func initWindow(_ vo: UnsafeMutablePointer<vo>, _ previousActiveApp: NSRunningApplication?) {
- let (mpv, targetScreen, wr) = getInitProperties(vo)
+ let (targetScreen, wr) = getInitProperties(vo)
guard let view = self.view else {
- log.sendError("Something went wrong, no View was initialized")
+ log.error("Something went wrong, no View was initialized")
exit(1)
}
window = Window(contentRect: wr, screen: targetScreen, view: view, common: self)
guard let window = self.window else {
- log.sendError("Something went wrong, no Window was initialized")
+ log.error("Something went wrong, no Window was initialized")
exit(1)
}
- window.setOnTop(Bool(mpv.opts.ontop), Int(mpv.opts.ontop_level))
- window.setOnAllWorkspaces(Bool(mpv.opts.all_workspaces))
- window.keepAspect = Bool(mpv.opts.keepaspect_window)
+ window.setOnTop(Bool(option.vo.ontop), Int(option.vo.ontop_level))
+ window.setOnAllWorkspaces(Bool(option.vo.all_workspaces))
+ window.keepAspect = Bool(option.vo.keepaspect_window)
window.title = title
- window.border = Bool(mpv.opts.border)
+ window.border = Bool(option.vo.border)
titleBar = TitleBar(frame: wr, window: window, common: self)
- let minimized = Bool(mpv.opts.window_minimized)
+ let maximized = Bool(option.vo.window_maximized)
+ let minimized = Bool(option.vo.window_minimized)
window.isRestorable = false
window.isReleasedWhenClosed = false
- window.setMaximized(minimized ? false : Bool(mpv.opts.window_maximized))
+ window.setMaximized((minimized || !maximized) ? window.isZoomed : maximized)
window.setMinimized(minimized)
window.makeMain()
window.makeKey()
+ view.layer?.contentsScale = window.backingScaleFactor
+
if !minimized {
window.orderFront(nil)
}
- NSApp.activate(ignoringOtherApps: mpv.opts.focus_on_open)
+ NSApp.activate(ignoringOtherApps: option.vo.focus_on >= 1)
// workaround for macOS 10.15 to refocus the previous App
- if (!mpv.opts.focus_on_open) {
- previousActiveApp?.activate(options: .activateAllWindows)
+ if option.vo.focus_on == 0 {
+ previousActiveApp?.activate()
}
}
func initView(_ vo: UnsafeMutablePointer<vo>, _ layer: CALayer) {
- let (_, _, wr) = getInitProperties(vo)
+ let (_, wr) = getInitProperties(vo)
view = View(frame: wr, common: self)
guard let view = self.view else {
- log.sendError("Something went wrong, no View was initialized")
+ log.error("Something went wrong, no View was initialized")
exit(1)
}
view.layer = layer
view.wantsLayer = true
view.layerContentsPlacement = .scaleProportionallyToFit
+ layer.delegate = view
}
func initWindowState() {
- if mpv?.opts.fullscreen ?? false {
+ if option.vo.fullscreen {
DispatchQueue.main.async {
self.window?.toggleFullScreen(nil)
}
@@ -179,7 +172,7 @@ class Common: NSObject {
guard let screen = getTargetScreen(forFullscreen: false) ?? NSScreen.main,
let link = self.link else
{
- log.sendWarning("Couldn't start DisplayLink, no MPVHelper, Screen or DisplayLink available")
+ log.warning("Couldn't start DisplayLink, no Screen or DisplayLink available")
return
}
@@ -198,7 +191,7 @@ class Common: NSObject {
func updateDisplaylink() {
guard let screen = window?.screen, let link = self.link else {
- log.sendWarning("Couldn't update DisplayLink, no Screen or DisplayLink available")
+ log.warning("Couldn't update DisplayLink, no Screen or DisplayLink available")
return
}
@@ -221,17 +214,17 @@ class Common: NSObject {
}
if fabs(actualFps - nominalFps) > 0.1 {
- log.sendVerbose("Falling back to nominal display refresh rate: \(nominalFps)")
+ log.verbose("Falling back to nominal display refresh rate: \(nominalFps)")
return nominalFps
} else {
return actualFps
}
}
} else {
- log.sendWarning("No DisplayLink available")
+ log.warning("No DisplayLink available")
}
- log.sendWarning("Falling back to standard display refresh rate: 60Hz")
+ log.warning("Falling back to standard display refresh rate: 60Hz")
return 60.0
}
@@ -285,28 +278,28 @@ class Common: NSObject {
}
func lightSensorUpdate() {
- log.sendWarning("lightSensorUpdate not implemented")
+ log.warning("lightSensorUpdate not implemented")
}
func initLightSensor() {
let srv = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleLMUController"))
if srv == IO_OBJECT_NULL {
- log.sendVerbose("Can't find an ambient light sensor")
+ log.verbose("Can't find an ambient light sensor")
return
}
lightSensorIOPort = IONotificationPortCreate(kIOMasterPortDefault)
IONotificationPortSetDispatchQueue(lightSensorIOPort, queue)
var n = io_object_t()
- IOServiceAddInterestNotification(lightSensorIOPort, srv, kIOGeneralInterest, lightSensorCallback, MPVHelper.bridge(obj: self), &n)
+ IOServiceAddInterestNotification(lightSensorIOPort, srv, kIOGeneralInterest, lightSensorCallback, TypeHelper.bridge(obj: self), &n)
let kr = IOServiceOpen(srv, mach_task_self_, 0, &lightSensor)
IOObjectRelease(srv)
if kr != KERN_SUCCESS {
- log.sendVerbose("Can't start ambient light sensor connection")
+ log.verbose("Can't start ambient light sensor connection")
return
}
- lightSensorCallback(MPVHelper.bridge(obj: self), 0, 0, nil)
+ lightSensorCallback(TypeHelper.bridge(obj: self), 0, 0, nil)
}
func uninitLightSensor() {
@@ -322,18 +315,18 @@ class Common: NSObject {
let displayID = com.window?.screen?.displayID ?? display
if displayID == display {
- com.log.sendVerbose("Detected display mode change, updating screen refresh rate")
+ com.log.verbose("Detected display mode change, updating screen refresh rate")
com.flagEvents(VO_EVENT_WIN_STATE)
}
}
}
func addDisplayReconfigureObserver() {
- CGDisplayRegisterReconfigurationCallback(reconfigureCallback, MPVHelper.bridge(obj: self))
+ CGDisplayRegisterReconfigurationCallback(reconfigureCallback, TypeHelper.bridge(obj: self))
}
func removeDisplayReconfigureObserver() {
- CGDisplayRemoveReconfigurationCallback(reconfigureCallback, MPVHelper.bridge(obj: self))
+ CGDisplayRemoveReconfigurationCallback(reconfigureCallback, TypeHelper.bridge(obj: self))
}
func addAppNotifications() {
@@ -365,10 +358,8 @@ class Common: NSObject {
}
func setAppIcon() {
- if let app = NSApp as? Application,
- ProcessInfo.processInfo.environment["MPVBUNDLE"] != "true"
- {
- NSApp.applicationIconImage = app.getMPVIcon()
+ if ProcessInfo.processInfo.environment["MPVBUNDLE"] != "true" {
+ NSApp.applicationIconImage = AppHub.shared.getIcon()
}
}
@@ -381,12 +372,12 @@ class Common: NSObject {
}
func updateICCProfile() {
- log.sendWarning("updateICCProfile not implemented")
+ log.warning("updateICCProfile not implemented")
}
func getScreenBy(id screenID: Int) -> NSScreen? {
if screenID >= NSScreen.screens.count {
- log.sendInfo("Screen ID \(screenID) does not exist, falling back to current device")
+ log.info("Screen ID \(screenID) does not exist, falling back to current device")
return nil
} else if screenID < 0 {
return nil
@@ -404,14 +395,9 @@ class Common: NSObject {
}
func getTargetScreen(forFullscreen fs: Bool) -> NSScreen? {
- guard let mpv = mpv else {
- log.sendWarning("Unexpected nil value in getTargetScreen")
- return nil
- }
-
- let screenID = fs ? mpv.opts.fsscreen_id : mpv.opts.screen_id
+ let screenID = fs ? option.vo.fsscreen_id : option.vo.screen_id
var name: String?
- if let screenName = fs ? mpv.opts.fsscreen_name : mpv.opts.screen_name {
+ if let screenName = fs ? option.vo.fsscreen_name : option.vo.screen_name {
name = String(cString: screenName)
}
return getScreenBy(id: Int(screenID)) ?? getScreenBy(name: name)
@@ -426,7 +412,7 @@ class Common: NSObject {
func getWindowGeometry(forScreen screen: NSScreen,
videoOut vo: UnsafeMutablePointer<vo>) -> NSRect {
let r = screen.convertRectToBacking(screen.frame)
- let targetFrame = (mpv?.macOpts.macos_geometry_calculation ?? Int32(FRAME_VISIBLE)) == FRAME_VISIBLE
+ let targetFrame = option.mac.macos_geometry_calculation == FRAME_VISIBLE
? screen.visibleFrame : screen.frame
let rv = screen.convertRectToBacking(targetFrame)
@@ -453,19 +439,15 @@ class Common: NSObject {
return screen.convertRectFromBacking(NSMakeRect(x, y, width, height))
}
- func getInitProperties(_ vo: UnsafeMutablePointer<vo>) -> (MPVHelper, NSScreen, NSRect) {
- guard let mpv = mpv else {
- log.sendError("Something went wrong, no MPVHelper was initialized")
- exit(1)
- }
+ func getInitProperties(_ vo: UnsafeMutablePointer<vo>) -> (NSScreen, NSRect) {
guard let targetScreen = getTargetScreen(forFullscreen: false) ?? NSScreen.main else {
- log.sendError("Something went wrong, no Screen was found")
+ log.error("Something went wrong, no Screen was found")
exit(1)
}
let wr = getWindowGeometry(forScreen: targetScreen, videoOut: vo)
- return (mpv, targetScreen, wr)
+ return (targetScreen, wr)
}
// call before initApp, because on macOS +10.15 it changes the active App
@@ -478,11 +460,11 @@ class Common: NSObject {
events |= ev
eventsLock.unlock()
- guard let vout = mpv?.vo else {
- log.sendWarning("vo nil in flagEvents")
+ guard let vo = vo else {
+ log.warning("vo nil in flagEvents")
return
}
- vo_wakeup(vout)
+ vo_wakeup(vo)
}
func checkEvents() -> Int {
@@ -510,47 +492,54 @@ class Common: NSObject {
request: UInt32,
data: UnsafeMutableRawPointer?) -> Int32
{
- guard let mpv = mpv else {
- log.sendWarning("Unexpected nil value in Control Callback")
- return VO_FALSE
- }
-
switch mp_voctrl(request) {
case VOCTRL_CHECK_EVENTS:
events.pointee |= Int32(checkEvents())
return VO_TRUE
case VOCTRL_VO_OPTS_CHANGED:
var opt: UnsafeMutableRawPointer?
- while mpv.nextChangedOption(property: &opt) {
+ while option.nextChangedOption(property: &opt) {
switch opt {
- case MPVHelper.getPointer(&mpv.optsPtr.pointee.border):
+ case TypeHelper.toPointer(&option.voPtr.pointee.border):
DispatchQueue.main.async {
- self.window?.border = Bool(mpv.opts.border)
+ self.window?.border = Bool(self.option.vo.border)
}
- case MPVHelper.getPointer(&mpv.optsPtr.pointee.fullscreen):
+ case TypeHelper.toPointer(&option.voPtr.pointee.fullscreen):
DispatchQueue.main.async {
self.window?.toggleFullScreen(nil)
}
- case MPVHelper.getPointer(&mpv.optsPtr.pointee.ontop): fallthrough
- case MPVHelper.getPointer(&mpv.optsPtr.pointee.ontop_level):
+ case TypeHelper.toPointer(&option.voPtr.pointee.ontop): fallthrough
+ case TypeHelper.toPointer(&option.voPtr.pointee.ontop_level):
+ DispatchQueue.main.async {
+ self.window?.setOnTop(Bool(self.option.vo.ontop), Int(self.option.vo.ontop_level))
+ }
+ case TypeHelper.toPointer(&option.voPtr.pointee.all_workspaces):
DispatchQueue.main.async {
- self.window?.setOnTop(Bool(mpv.opts.ontop), Int(mpv.opts.ontop_level))
+ self.window?.setOnAllWorkspaces(Bool(self.option.vo.all_workspaces))
}
- case MPVHelper.getPointer(&mpv.optsPtr.pointee.all_workspaces):
+ case TypeHelper.toPointer(&option.voPtr.pointee.keepaspect_window):
DispatchQueue.main.async {
- self.window?.setOnAllWorkspaces(Bool(mpv.opts.all_workspaces))
+ self.window?.keepAspect = Bool(self.option.vo.keepaspect_window)
}
- case MPVHelper.getPointer(&mpv.optsPtr.pointee.keepaspect_window):
+ case TypeHelper.toPointer(&option.voPtr.pointee.window_minimized):
DispatchQueue.main.async {
- self.window?.keepAspect = Bool(mpv.opts.keepaspect_window)
+ self.window?.setMinimized(Bool(self.option.vo.window_minimized))
}
- case MPVHelper.getPointer(&mpv.optsPtr.pointee.window_minimized):
+ case TypeHelper.toPointer(&option.voPtr.pointee.window_maximized):
DispatchQueue.main.async {
- self.window?.setMinimized(Bool(mpv.opts.window_minimized))
+ self.window?.setMaximized(Bool(self.option.vo.window_maximized))
}
- case MPVHelper.getPointer(&mpv.optsPtr.pointee.window_maximized):
+ case TypeHelper.toPointer(&option.voPtr.pointee.cursor_passthrough):
DispatchQueue.main.async {
- self.window?.setMaximized(Bool(mpv.opts.window_maximized))
+ self.window?.ignoresMouseEvents = self.option.vo.cursor_passthrough
+ }
+ case TypeHelper.toPointer(&option.voPtr.pointee.geometry): fallthrough
+ case TypeHelper.toPointer(&option.voPtr.pointee.autofit): fallthrough
+ case TypeHelper.toPointer(&option.voPtr.pointee.autofit_smaller): fallthrough
+ case TypeHelper.toPointer(&option.voPtr.pointee.autofit_larger):
+ DispatchQueue.main.async {
+ let (_, wr) = self.getInitProperties(vo)
+ self.window?.updateFrame(wr)
}
default:
break
@@ -561,6 +550,13 @@ class Common: NSObject {
let fps = data!.assumingMemoryBound(to: CDouble.self)
fps.pointee = currentFps()
return VO_TRUE
+ case VOCTRL_GET_WINDOW_ID:
+ guard let window = window else {
+ return VO_NOTAVAIL
+ }
+ let wid = data!.assumingMemoryBound(to: Int64.self)
+ wid.pointee = unsafeBitCast(window, to: Int64.self)
+ return VO_TRUE
case VOCTRL_GET_HIDPI_SCALE:
let scaleFactor = data!.assumingMemoryBound(to: CDouble.self)
let screen = getCurrentScreen()
@@ -584,7 +580,7 @@ class Common: NSObject {
case VOCTRL_GET_ICC_PROFILE:
let screen = getCurrentScreen()
guard var iccData = screen?.colorSpace?.iccProfileData else {
- log.sendWarning("No Screen available to retrieve ICC profile")
+ log.warning("No Screen available to retrieve ICC profile")
return VO_TRUE
}
@@ -605,10 +601,8 @@ class Common: NSObject {
case VOCTRL_GET_UNFS_WINDOW_SIZE:
let sizeData = data!.assumingMemoryBound(to: Int32.self)
let size = UnsafeMutableBufferPointer(start: sizeData, count: 2)
- var rect = window?.unfsContentFrame ?? NSRect(x: 0, y: 0, width: 1280, height: 720)
- if let screen = window?.currentScreen, !Bool(mpv.opts.hidpi_window_scale) {
- rect = screen.convertRectToBacking(rect)
- }
+ let rect = (Bool(option.vo.hidpi_window_scale) ? window?.unfsContentFrame
+ : window?.unfsContentFramePixel) ?? NSRect(x: 0, y: 0, width: 1280, height: 720)
size[0] = Int32(rect.size.width)
size[1] = Int32(rect.size.height)
@@ -618,7 +612,7 @@ class Common: NSObject {
let size = UnsafeBufferPointer(start: sizeData, count: 2)
var rect = NSMakeRect(0, 0, CGFloat(size[0]), CGFloat(size[1]))
DispatchQueue.main.async {
- if let screen = self.window?.currentScreen, !Bool(self.mpv?.opts.hidpi_window_scale ?? true) {
+ if let screen = self.window?.currentScreen, !Bool(self.option.vo.hidpi_window_scale) {
rect = screen.convertRectFromBacking(rect)
}
self.window?.updateSize(rect.size)
@@ -630,13 +624,13 @@ class Common: NSObject {
var count: Int32 = 0
let displayName = getCurrentScreen()?.localizedName ?? "Unknown"
- SWIFT_TARRAY_STRING_APPEND(nil, &array, &count, ta_xstrdup(nil, displayName))
- SWIFT_TARRAY_STRING_APPEND(nil, &array, &count, nil)
+ app_bridge_tarray_append(nil, &array, &count, ta_xstrdup(nil, displayName))
+ app_bridge_tarray_append(nil, &array, &count, nil)
dnames.pointee = array
return VO_TRUE
case VOCTRL_GET_DISPLAY_RES:
guard let screen = getCurrentScreen() else {
- log.sendWarning("No Screen available to retrieve frame")
+ log.warning("No Screen available to retrieve frame")
return VO_NOTAVAIL
}
let sizeData = data!.assumingMemoryBound(to: Int32.self)
@@ -650,10 +644,9 @@ class Common: NSObject {
focus.pointee = NSApp.isActive
return VO_TRUE
case VOCTRL_UPDATE_WINDOW_TITLE:
- let titleData = data!.assumingMemoryBound(to: Int8.self)
+ let title = String(cString: data!.assumingMemoryBound(to: CChar.self))
DispatchQueue.main.async {
- let title = NSString(utf8String: titleData) as String?
- self.title = title ?? "Unknown Title"
+ self.title = title
}
return VO_TRUE
default:
@@ -669,20 +662,15 @@ class Common: NSObject {
}
func macOptsUpdate() {
- guard let mpv = mpv else {
- log.sendWarning("Unexpected nil value in mac opts update")
- return
- }
-
var opt: UnsafeMutableRawPointer?
- while mpv.nextChangedMacOption(property: &opt) {
+ while option.nextChangedMacOption(property: &opt) {
switch opt {
- case MPVHelper.getPointer(&mpv.macOptsPtr.pointee.macos_title_bar_appearance):
- titleBar?.set(appearance: Int(mpv.macOpts.macos_title_bar_appearance))
- case MPVHelper.getPointer(&mpv.macOptsPtr.pointee.macos_title_bar_material):
- titleBar?.set(material: Int(mpv.macOpts.macos_title_bar_material))
- case MPVHelper.getPointer(&mpv.macOptsPtr.pointee.macos_title_bar_color):
- titleBar?.set(color: mpv.macOpts.macos_title_bar_color)
+ case TypeHelper.toPointer(&option.macPtr.pointee.macos_title_bar_appearance):
+ titleBar?.set(appearance: Int(option.mac.macos_title_bar_appearance))
+ case TypeHelper.toPointer(&option.macPtr.pointee.macos_title_bar_material):
+ titleBar?.set(material: Int(option.mac.macos_title_bar_material))
+ case TypeHelper.toPointer(&option.macPtr.pointee.macos_title_bar_color):
+ titleBar?.set(color: option.mac.macos_title_bar_color)
default:
break
}
diff --git a/video/out/mac/gl_layer.swift b/video/out/mac/gl_layer.swift
index dd96af7..38320bc 100644
--- a/video/out/mac/gl_layer.swift
+++ b/video/out/mac/gl_layer.swift
@@ -82,8 +82,6 @@ class GLLayer: CAOpenGLLayer {
enum Draw: Int { case normal = 1, atomic, atomicEnd }
var draw: Draw = .normal
- let queue: DispatchQueue = DispatchQueue(label: "io.mpv.queue.draw")
-
var needsICCUpdate: Bool = false {
didSet {
if needsICCUpdate == true {
@@ -199,6 +197,14 @@ class GLLayer: CAOpenGLLayer {
}
}
+ func lockCglContext() {
+ CGLLockContext(cglContext)
+ }
+
+ func unlockCglContext() {
+ CGLUnlockContext(cglContext)
+ }
+
override func copyCGLPixelFormat(forDisplayMask mask: UInt32) -> CGLPixelFormatObj {
return cglPixelFormat
}
@@ -219,17 +225,19 @@ class GLLayer: CAOpenGLLayer {
super.display()
CATransaction.flush()
if isUpdate && needsFlip {
+ lockCglContext()
CGLSetCurrentContext(cglContext)
if libmpv.isRenderUpdateFrame() {
libmpv.drawRender(NSZeroSize, bufferDepth, cglContext, skip: true)
}
+ unlockCglContext()
}
displayLock.unlock()
}
func update(force: Bool = false) {
if force { forceDraw = true }
- queue.async {
+ DispatchQueue.main.async {
if self.forceDraw || !self.inLiveResize {
self.needsFlip = true
self.display()
@@ -241,7 +249,7 @@ class GLLayer: CAOpenGLLayer {
var pix: CGLPixelFormatObj?
var depth: GLint = 8
var err: CGLError = CGLError(rawValue: 0)
- let swRender = ccb.libmpv.macOpts.cocoa_cb_sw_renderer
+ let swRender = ccb.option.mac.cocoa_cb_sw_renderer
if swRender != 1 {
(pix, depth, err) = GLLayer.findPixelFormat(ccb)
@@ -252,7 +260,7 @@ class GLLayer: CAOpenGLLayer {
}
guard let pixelFormat = pix, err == kCGLNoError else {
- ccb.log.sendError("Couldn't create any CGL pixel format")
+ ccb.log.error("Couldn't create any CGL pixel format")
exit(1)
}
@@ -269,12 +277,12 @@ class GLLayer: CAOpenGLLayer {
glBase.insert(CGLPixelFormatAttribute(ver.rawValue), at: 1)
var glFormat = [glBase]
- if ccb.libmpv.macOpts.cocoa_cb_10bit_context {
+ if ccb.option.mac.cocoa_cb_10bit_context {
glFormat += [glFormat10Bit]
}
glFormat += glFormatOptional
- if !ccb.libmpv.macOpts.macos_force_dedicated_gpu {
+ if !ccb.option.mac.macos_force_dedicated_gpu {
glFormat += [glFormatAutoGPU]
}
@@ -289,7 +297,7 @@ class GLLayer: CAOpenGLLayer {
return attributeLookUp[value.rawValue] ?? String(value.rawValue)
})
- ccb.log.sendVerbose("Created CGL pixel format with attributes: " +
+ ccb.log.verbose("Created CGL pixel format with attributes: " +
"\(attArray.joined(separator: ", "))")
return (pix, glFormat.contains(glFormat10Bit) ? 16 : 8, err)
}
@@ -297,11 +305,11 @@ class GLLayer: CAOpenGLLayer {
}
let errS = String(cString: CGLErrorString(err))
- ccb.log.sendWarning("Couldn't create a " +
+ ccb.log.warning("Couldn't create a " +
"\(software ? "software" : "hardware accelerated") " +
"CGL pixel format: \(errS) (\(err.rawValue))")
- if software == false && ccb.libmpv.macOpts.cocoa_cb_sw_renderer == -1 {
- ccb.log.sendWarning("Falling back to software renderer")
+ if software == false && ccb.option.mac.cocoa_cb_sw_renderer == -1 {
+ ccb.log.warning("Falling back to software renderer")
}
return (pix, 8, err)
@@ -313,7 +321,7 @@ class GLLayer: CAOpenGLLayer {
guard let cglContext = context, error == kCGLNoError else {
let errS = String(cString: CGLErrorString(error))
- ccb.log.sendError("Couldn't create a CGLContext: " + errS)
+ ccb.log.error("Couldn't create a CGLContext: " + errS)
exit(1)
}
diff --git a/video/out/mac/metal_layer.swift b/video/out/mac/metal_layer.swift
index 7cea87c..7fc419a 100644
--- a/video/out/mac/metal_layer.swift
+++ b/video/out/mac/metal_layer.swift
@@ -16,10 +16,22 @@
*/
import Cocoa
+import QuartzCore
class MetalLayer: CAMetalLayer {
unowned var common: MacCommon
+ // workaround for a MoltenVK workaround that sets the drawableSize to 1x1 to forcefully complete
+ // the presentation, this causes flicker and the drawableSize possibly staying at 1x1
+ override var drawableSize: CGSize {
+ get { return super.drawableSize }
+ set {
+ if Int(newValue.width) > 1 && Int(newValue.height) > 1 {
+ super.drawableSize = newValue
+ }
+ }
+ }
+
init(common com: MacCommon) {
common = com
super.init()
diff --git a/video/out/mac/title_bar.swift b/video/out/mac/title_bar.swift
index 764c1ff..b274100 100644
--- a/video/out/mac/title_bar.swift
+++ b/video/out/mac/title_bar.swift
@@ -19,7 +19,7 @@ import Cocoa
class TitleBar: NSVisualEffectView {
unowned var common: Common
- var mpv: MPVHelper? { get { return common.mpv } }
+ var option: OptionHelper { get { return common.option } }
var systemBar: NSView? {
get { return common.window?.standardWindowButton(.closeButton)?.superview }
@@ -64,9 +64,9 @@ class TitleBar: NSVisualEffectView {
window.contentView?.addSubview(self, positioned: .above, relativeTo: nil)
window.titlebarAppearsTransparent = true
window.styleMask.insert(.fullSizeContentView)
- set(appearance: Int(mpv?.macOpts.macos_title_bar_appearance ?? 0))
- set(material: Int(mpv?.macOpts.macos_title_bar_material ?? 0))
- set(color: mpv?.macOpts.macos_title_bar_color ?? "#00000000")
+ set(appearance: Int(option.mac.macos_title_bar_appearance))
+ set(material: Int(option.mac.macos_title_bar_material))
+ set(color: option.mac.macos_title_bar_color)
}
required init?(coder: NSCoder) {
@@ -195,10 +195,6 @@ class TitleBar: NSVisualEffectView {
default:
return nil
}
-
-
- let style = UserDefaults.standard.string(forKey: "AppleInterfaceStyle")
- return appearanceFrom(string: style == nil ? "aqua" : "vibrantDark")
}
func materialFrom(string: String) -> NSVisualEffectView.Material {
@@ -221,9 +217,7 @@ class TitleBar: NSVisualEffectView {
case "15", "light": return .light
case "16", "mediumLight": return .mediumLight
case "17", "ultraDark": return .ultraDark
- default: break
+ default: return .titlebar
}
-
- return .titlebar
}
}
diff --git a/video/out/mac/view.swift b/video/out/mac/view.swift
index c4776c3..047a523 100644
--- a/video/out/mac/view.swift
+++ b/video/out/mac/view.swift
@@ -17,9 +17,9 @@
import Cocoa
-class View: NSView {
+class View: NSView, CALayerDelegate {
unowned var common: Common
- var mpv: MPVHelper? { get { return common.mpv } }
+ var input: InputHelper? { get { return common.input } }
var tracker: NSTrackingArea?
var hasMouseDown: Bool = false
@@ -52,7 +52,7 @@ class View: NSView {
addTrackingArea(tracker!)
if containsMouseLocation() {
- cocoa_put_key_with_modifiers(SWIFT_KEY_MOUSE_LEAVE, 0)
+ input?.put(key: SWIFT_KEY_MOUSE_LEAVE)
}
}
@@ -77,30 +77,24 @@ class View: NSView {
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
let pb = sender.draggingPasteboard
guard let types = pb.types else { return false }
+ var files: [String] = []
if types.contains(.fileURL) || types.contains(.URL) {
- if let urls = pb.readObjects(forClasses: [NSURL.self]) as? [URL] {
- let files = urls.map { $0.absoluteString }
- EventsResponder.sharedInstance().handleFilesArray(files)
- return true
- }
+ guard let urls = pb.readObjects(forClasses: [NSURL.self]) as? [URL] else { return false }
+ files = urls.map { $0.absoluteString }
} else if types.contains(.string) {
guard let str = pb.string(forType: .string) else { return false }
- var filesArray: [String] = []
-
- for val in str.components(separatedBy: "\n") {
- let url = val.trimmingCharacters(in: .whitespacesAndNewlines)
+ files = str.components(separatedBy: "\n").compactMap {
+ let url = $0.trimmingCharacters(in: .whitespacesAndNewlines)
let path = (url as NSString).expandingTildeInPath
- if isURL(url) {
- filesArray.append(url)
- } else if path.starts(with: "/") {
- filesArray.append(path)
- }
+ if isURL(url) { return url }
+ if path.starts(with: "/") { return path }
+ return nil
}
- EventsResponder.sharedInstance().handleFilesArray(filesArray)
- return true
}
- return false
+ if files.isEmpty { return false }
+ input?.open(files: files)
+ return true
}
override func acceptsFirstMouse(for event: NSEvent?) -> Bool {
@@ -116,94 +110,66 @@ class View: NSView {
}
override func mouseEntered(with event: NSEvent) {
- if mpv?.mouseEnabled() ?? true {
- cocoa_put_key_with_modifiers(SWIFT_KEY_MOUSE_ENTER, 0)
+ if input?.mouseEnabled() ?? true {
+ input?.put(key: SWIFT_KEY_MOUSE_ENTER)
}
common.updateCursorVisibility()
}
override func mouseExited(with event: NSEvent) {
- if mpv?.mouseEnabled() ?? true {
- cocoa_put_key_with_modifiers(SWIFT_KEY_MOUSE_LEAVE, 0)
+ if input?.mouseEnabled() ?? true {
+ input?.put(key: SWIFT_KEY_MOUSE_LEAVE)
}
common.titleBar?.hide()
common.setCursorVisibility(true)
}
override func mouseMoved(with event: NSEvent) {
- if mpv?.mouseEnabled() ?? true {
- signalMouseMovement(event)
- }
+ signalMouseMovement(event)
common.titleBar?.show()
}
override func mouseDragged(with event: NSEvent) {
- if mpv?.mouseEnabled() ?? true {
- signalMouseMovement(event)
- }
+ signalMouseMovement(event)
}
override func mouseDown(with event: NSEvent) {
- if mpv?.mouseEnabled() ?? true {
- signalMouseDown(event)
- }
+ hasMouseDown = event.clickCount <= 1
+ input?.processMouse(event: event)
}
override func mouseUp(with event: NSEvent) {
- if mpv?.mouseEnabled() ?? true {
- signalMouseUp(event)
- }
+ hasMouseDown = false
common.window?.isMoving = false
+ input?.processMouse(event: event)
}
override func rightMouseDown(with event: NSEvent) {
- if mpv?.mouseEnabled() ?? true {
- signalMouseDown(event)
- }
+ hasMouseDown = event.clickCount <= 1
+ input?.processMouse(event: event)
}
override func rightMouseUp(with event: NSEvent) {
- if mpv?.mouseEnabled() ?? true {
- signalMouseUp(event)
- }
+ hasMouseDown = false
+ input?.processMouse(event: event)
}
override func otherMouseDown(with event: NSEvent) {
- if mpv?.mouseEnabled() ?? true {
- signalMouseDown(event)
- }
+ hasMouseDown = event.clickCount <= 1
+ input?.processMouse(event: event)
}
override func otherMouseUp(with event: NSEvent) {
- if mpv?.mouseEnabled() ?? true {
- signalMouseUp(event)
- }
+ hasMouseDown = false
+ input?.processMouse(event: event)
}
override func magnify(with event: NSEvent) {
- event.phase == .ended ?
- common.windowDidEndLiveResize() : common.windowWillStartLiveResize()
-
+ common.window?.isAnimating = event.phase != .ended
+ event.phase == .ended ? common.windowDidEndLiveResize() : common.windowWillStartLiveResize()
common.window?.addWindowScale(Double(event.magnification))
}
- func signalMouseDown(_ event: NSEvent) {
- signalMouseEvent(event, MP_KEY_STATE_DOWN)
- if event.clickCount > 1 {
- signalMouseEvent(event, MP_KEY_STATE_UP)
- }
- }
-
- func signalMouseUp(_ event: NSEvent) {
- signalMouseEvent(event, MP_KEY_STATE_UP)
- }
-
- func signalMouseEvent(_ event: NSEvent, _ state: UInt32) {
- hasMouseDown = state == MP_KEY_STATE_DOWN
- let mpkey = getMpvButton(event)
- cocoa_put_key_with_modifiers((mpkey | Int32(state)), Int32(event.modifierFlags.rawValue))
- }
-
func signalMouseMovement(_ event: NSEvent) {
var point = convert(event.locationInWindow, from: nil)
point = convertToBacking(point)
@@ -211,46 +177,12 @@ class View: NSView {
common.window?.updateMovableBackground(point)
if !(common.window?.isMoving ?? false) {
- mpv?.setMousePosition(point)
- }
- }
-
- func preciseScroll(_ event: NSEvent) {
- var delta: Double
- var cmd: Int32
-
- if abs(event.deltaY) >= abs(event.deltaX) {
- delta = Double(event.deltaY) * 0.1
- cmd = delta > 0 ? SWIFT_WHEEL_UP : SWIFT_WHEEL_DOWN
- } else {
- delta = Double(event.deltaX) * 0.1
- cmd = delta > 0 ? SWIFT_WHEEL_LEFT : SWIFT_WHEEL_RIGHT
+ input?.setMouse(position: point)
}
-
- mpv?.putAxis(cmd, delta: abs(delta))
}
override func scrollWheel(with event: NSEvent) {
- if !(mpv?.mouseEnabled() ?? true) {
- return
- }
-
- if event.hasPreciseScrollingDeltas {
- preciseScroll(event)
- } else {
- let modifiers = event.modifierFlags
- let deltaX = modifiers.contains(.shift) ? event.scrollingDeltaY : event.scrollingDeltaX
- let deltaY = modifiers.contains(.shift) ? event.scrollingDeltaX : event.scrollingDeltaY
- var mpkey: Int32
-
- if abs(deltaY) >= abs(deltaX) {
- mpkey = deltaY > 0 ? SWIFT_WHEEL_UP : SWIFT_WHEEL_DOWN
- } else {
- mpkey = deltaX > 0 ? SWIFT_WHEEL_LEFT : SWIFT_WHEEL_RIGHT
- }
-
- cocoa_put_key_with_modifiers(mpkey, Int32(modifiers.rawValue))
- }
+ input?.processWheel(event: event)
}
func containsMouseLocation() -> Bool {
@@ -282,16 +214,4 @@ class View: NSView {
guard let window = common.window else { return false }
return !hasMouseDown && containsMouseLocation() && window.isKeyWindow
}
-
- func getMpvButton(_ event: NSEvent) -> Int32 {
- let buttonNumber = event.buttonNumber
- switch (buttonNumber) {
- case 0: return SWIFT_MBTN_LEFT
- case 1: return SWIFT_MBTN_RIGHT
- case 2: return SWIFT_MBTN_MID
- case 3: return SWIFT_MBTN_BACK
- case 4: return SWIFT_MBTN_FORWARD
- default: return SWIFT_MBTN9 + Int32(buttonNumber - 5)
- }
- }
}
diff --git a/video/out/mac/window.swift b/video/out/mac/window.swift
index 7b1a858..c5a711e 100644
--- a/video/out/mac/window.swift
+++ b/video/out/mac/window.swift
@@ -19,14 +19,15 @@ import Cocoa
class Window: NSWindow, NSWindowDelegate {
weak var common: Common! = nil
- var mpv: MPVHelper? { get { return common.mpv } }
+ var option: OptionHelper { get { return common.option } }
+ var input: InputHelper? { get { return common.input } }
var targetScreen: NSScreen?
var previousScreen: NSScreen?
var currentScreen: NSScreen?
var unfScreen: NSScreen?
- var unfsContentFrame: NSRect?
+ var unfsContentFrame: NSRect = NSRect(x: 0, y: 0, width: 160, height: 90)
var isInFullscreen: Bool = false
var isMoving: Bool = false
var previousStyleMask: NSWindow.StyleMask = [.titled, .closable, .miniaturizable, .resizable]
@@ -34,8 +35,8 @@ class Window: NSWindow, NSWindowDelegate {
var isAnimating: Bool = false
let animationLock: NSCondition = NSCondition()
- var unfsContentFramePixel: NSRect { get { return convertToBacking(unfsContentFrame ?? NSRect(x: 0, y: 0, width: 160, height: 90)) } }
- var framePixel: NSRect { get { return convertToBacking(frame) } }
+ var unfsContentFramePixel: NSRect { get { return convertToBacking(unfsContentFrame) } }
+ @objc var framePixel: NSRect { get { return convertToBacking(frame) } }
var keepAspect: Bool = true {
didSet {
@@ -44,7 +45,7 @@ class Window: NSWindow, NSWindowDelegate {
}
if keepAspect {
- contentAspectRatio = unfsContentFrame?.size ?? contentAspectRatio
+ contentAspectRatio = unfsContentFrame.size
} else {
resizeIncrements = NSSize(width: 1.0, height: 1.0)
}
@@ -91,7 +92,9 @@ class Window: NSWindow, NSWindowDelegate {
title = com.title
minSize = NSMakeSize(160, 90)
collectionBehavior = .fullScreenPrimary
+ ignoresMouseEvents = option.vo.cursor_passthrough
delegate = self
+ unfsContentFrame = contentRect
if let cView = contentView {
cView.addSubview(view)
@@ -103,13 +106,11 @@ class Window: NSWindow, NSWindowDelegate {
currentScreen = screen
unfScreen = screen
- if let app = NSApp as? Application {
- app.menuBar.register(#selector(setHalfWindowSize), for: MPM_H_SIZE)
- app.menuBar.register(#selector(setNormalWindowSize), for: MPM_N_SIZE)
- app.menuBar.register(#selector(setDoubleWindowSize), for: MPM_D_SIZE)
- app.menuBar.register(#selector(performMiniaturize(_:)), for: MPM_MINIMIZE)
- app.menuBar.register(#selector(performZoom(_:)), for: MPM_ZOOM)
- }
+ AppHub.shared.menu?.register(#selector(setHalfWindowSize), key: .itemHalfSize)
+ AppHub.shared.menu?.register(#selector(setNormalWindowSize), key: .itemNormalSize)
+ AppHub.shared.menu?.register(#selector(setDoubleWindowSize), key: .itemDoubleSize)
+ AppHub.shared.menu?.register(#selector(performMiniaturize(_:)), key: .itemMinimize)
+ AppHub.shared.menu?.register(#selector(performZoom(_:)), key: .itemZoom)
}
override func toggleFullScreen(_ sender: Any?) {
@@ -141,7 +142,7 @@ class Window: NSWindow, NSWindowDelegate {
setFrame(frame, display: true)
}
- if Bool(mpv?.opts.native_fs ?? true) {
+ if Bool(option.vo.native_fs) {
super.toggleFullScreen(sender)
} else {
if !isInFullscreen {
@@ -192,7 +193,7 @@ class Window: NSWindow, NSWindowDelegate {
func windowDidEnterFullScreen(_ notification: Notification) {
isInFullscreen = true
- mpv?.setOption(fullscreen: isInFullscreen)
+ option.setOption(fullscreen: isInFullscreen)
common.updateCursorVisibility()
endAnimation(frame)
common.titleBar?.show()
@@ -201,7 +202,7 @@ class Window: NSWindow, NSWindowDelegate {
func windowDidExitFullScreen(_ notification: Notification) {
guard let tScreen = targetScreen else { return }
isInFullscreen = false
- mpv?.setOption(fullscreen: isInFullscreen)
+ option.setOption(fullscreen: isInFullscreen)
endAnimation(calculateWindowPosition(for: tScreen, withoutBounds: targetScreen == screen))
common.view?.layerContentsPlacement = .scaleProportionallyToFit
}
@@ -249,7 +250,7 @@ class Window: NSWindow, NSWindowDelegate {
setFrame(targetFrame, display: true)
endAnimation()
isInFullscreen = true
- mpv?.setOption(fullscreen: isInFullscreen)
+ option.setOption(fullscreen: isInFullscreen)
common.windowSetToFullScreen()
}
@@ -268,7 +269,7 @@ class Window: NSWindow, NSWindowDelegate {
setFrame(newFrame, display: true)
endAnimation()
isInFullscreen = false
- mpv?.setOption(fullscreen: isInFullscreen)
+ option.setOption(fullscreen: isInFullscreen)
common.windowSetToWindow()
}
@@ -281,7 +282,7 @@ class Window: NSWindow, NSWindowDelegate {
}
func getFsAnimationDuration(_ def: Double) -> Double {
- let duration = mpv?.macOpts.macos_fs_animation_duration ?? -1
+ let duration = option.mac.macos_fs_animation_duration
if duration < 0 {
return def
} else {
@@ -334,7 +335,7 @@ class Window: NSWindow, NSWindowDelegate {
func updateMovableBackground(_ pos: NSPoint) {
if !isInFullscreen {
- isMovableByWindowBackground = mpv?.canBeDraggedAt(pos) ?? true
+ isMovableByWindowBackground = input?.draggable(at: pos) ?? true
} else {
isMovableByWindowBackground = false
}
@@ -342,35 +343,31 @@ class Window: NSWindow, NSWindowDelegate {
func updateFrame(_ rect: NSRect) {
if rect != frame {
- let cRect = frameRect(forContentRect: rect)
unfsContentFrame = rect
- setFrame(cRect, display: true)
- common.windowDidUpdateFrame()
+ if !isInFullscreen {
+ let cRect = frameRect(forContentRect: rect)
+ setFrame(cRect, display: true)
+ common.windowDidUpdateFrame()
+ }
}
}
func updateSize(_ size: NSSize) {
if let currentSize = contentView?.frame.size, size != currentSize {
let newContentFrame = centeredContentSize(for: frame, size: size)
- if !isInFullscreen {
- updateFrame(newContentFrame)
- } else {
- unfsContentFrame = newContentFrame
- }
+ updateFrame(newContentFrame)
}
}
override func setFrame(_ frameRect: NSRect, display flag: Bool) {
if frameRect.width < minSize.width || frameRect.height < minSize.height {
- common.log.sendVerbose("tried to set too small window size: \(frameRect.size)")
+ common.log.verbose("tried to set too small window size: \(frameRect.size)")
return
}
super.setFrame(frameRect, display: flag)
- if let size = unfsContentFrame?.size, keepAspect {
- contentAspectRatio = size
- }
+ if keepAspect { contentAspectRatio = unfsContentFrame.size }
}
func centeredContentSize(for rect: NSRect, size sz: NSSize) -> NSRect {
@@ -391,10 +388,9 @@ class Window: NSWindow, NSWindowDelegate {
}
func calculateWindowPosition(for tScreen: NSScreen, withoutBounds: Bool) -> NSRect {
- guard let contentFrame = unfsContentFrame, let screen = unfScreen else {
- return frame
- }
- var newFrame = frameRect(forContentRect: contentFrame)
+ guard let screen = unfScreen else { return frame }
+
+ var newFrame = frameRect(forContentRect: unfsContentFrame)
let targetFrame = tScreen.frame
let targetVisibleFrame = tScreen.visibleFrame
let unfsScreenFrame = screen.frame
@@ -504,12 +500,12 @@ class Window: NSWindow, NSWindowDelegate {
@objc func setDoubleWindowSize() { setWindowScale(2.0) }
func setWindowScale(_ scale: Double) {
- mpv?.command("set window-scale \(scale)")
+ input?.command("set window-scale \(scale)")
}
func addWindowScale(_ scale: Double) {
if !isInFullscreen {
- mpv?.command("add window-scale \(scale)")
+ input?.command("add current-window-scale \(scale)")
}
}
@@ -542,7 +538,7 @@ class Window: NSWindow, NSWindowDelegate {
func windowDidEndLiveResize(_ notification: Notification) {
common.windowDidEndLiveResize()
- mpv?.setOption(maximized: isZoomed)
+ option.setOption(maximized: isZoomed)
if let contentViewFrame = contentView?.frame,
!isAnimating && !isInFullscreen
@@ -552,20 +548,23 @@ class Window: NSWindow, NSWindowDelegate {
}
func windowDidResize(_ notification: Notification) {
+ if let contentViewFrame = contentView?.frame, !isAnimating && !isInFullscreen && !inLiveResize {
+ unfsContentFrame = convertToScreen(contentViewFrame)
+ }
common.windowDidResize()
}
func windowShouldClose(_ sender: NSWindow) -> Bool {
- cocoa_put_key(MP_KEY_CLOSE_WIN)
+ input?.put(key: MP_KEY_CLOSE_WIN)
return false
}
func windowDidMiniaturize(_ notification: Notification) {
- mpv?.setOption(minimized: true)
+ option.setOption(minimized: true)
}
func windowDidDeminiaturize(_ notification: Notification) {
- mpv?.setOption(minimized: false)
+ option.setOption(minimized: false)
}
func windowDidResignKey(_ notification: Notification) {
@@ -588,6 +587,6 @@ class Window: NSWindow, NSWindowDelegate {
}
func windowDidMove(_ notification: Notification) {
- mpv?.setOption(maximized: isZoomed)
+ option.setOption(maximized: isZoomed)
}
}