diff options
Diffstat (limited to 'video/out/mac')
-rw-r--r-- | video/out/mac/common.swift | 353 | ||||
-rw-r--r-- | video/out/mac/gl_layer.swift | 64 | ||||
-rw-r--r-- | video/out/mac/metal_layer.swift | 55 | ||||
-rw-r--r-- | video/out/mac/title_bar.swift | 125 | ||||
-rw-r--r-- | video/out/mac/view.swift | 168 | ||||
-rw-r--r-- | video/out/mac/window.swift | 183 |
6 files changed, 458 insertions, 490 deletions
diff --git a/video/out/mac/common.swift b/video/out/mac/common.swift index 6c3d0fcfb3..50a508e872 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,62 +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.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) } @@ -151,7 +145,7 @@ class Common: NSObject { } func uninitCommon() { - setCursorVisiblility(true) + setCursorVisibility(true) stopDisplaylink() uninitLightSensor() removeDisplayReconfigureObserver() @@ -163,23 +157,11 @@ class Common: NSObject { view?.removeFromSuperview() } - let linkCallback: CVDisplayLinkOutputCallback = { - (displayLink: CVDisplayLink, - inNow: UnsafePointer<CVTimeStamp>, - inOutputTime: UnsafePointer<CVTimeStamp>, - flagsIn: CVOptionFlags, - flagsOut: UnsafeMutablePointer<CVOptionFlags>, - displayLinkContext: UnsafeMutableRawPointer?) -> CVReturn in - let com = unsafeBitCast(displayLinkContext, to: Common.self) - return com.displayLinkCallback(displayLink, inNow, inOutputTime, flagsIn, flagsOut) - } - func displayLinkCallback(_ displayLink: CVDisplayLink, - _ inNow: UnsafePointer<CVTimeStamp>, - _ inOutputTime: UnsafePointer<CVTimeStamp>, - _ flagsIn: CVOptionFlags, - _ flagsOut: UnsafeMutablePointer<CVOptionFlags>) -> CVReturn - { + _ inNow: UnsafePointer<CVTimeStamp>, + _ inOutputTime: UnsafePointer<CVTimeStamp>, + _ flagsIn: CVOptionFlags, + _ flagsOut: UnsafeMutablePointer<CVOptionFlags>) -> CVReturn { return kCVReturnSuccess } @@ -187,19 +169,14 @@ class Common: NSObject { CVDisplayLinkCreateWithActiveCGDisplays(&link) 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") + let link = self.link else { + log.warning("Couldn't start DisplayLink, no Screen or DisplayLink available") return } CVDisplayLinkSetCurrentCGDisplay(link, screen.displayID) - if #available(macOS 10.12, *) { - CVDisplayLinkSetOutputHandler(link) { link, now, out, inFlags, outFlags -> CVReturn in - return self.displayLinkCallback(link, now, out, inFlags, outFlags) - } - } else { - CVDisplayLinkSetOutputCallback(link, linkCallback, MPVHelper.bridge(obj: self)) + CVDisplayLinkSetOutputHandler(link) { link, now, out, inFlags, outFlags -> CVReturn in + return self.displayLinkCallback(link, now, out, inFlags, outFlags) } CVDisplayLinkStart(link) } @@ -212,7 +189,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 } @@ -235,17 +212,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 } @@ -282,7 +259,7 @@ class Common: NSObject { return lux > 0 ? lux : 0 } - var lightSensorCallback: IOServiceInterestCallback = { (ctx, service, messageType, messageArgument) -> Void in + var lightSensorCallback: IOServiceInterestCallback = { (ctx, _ service, _ messageType, _ messageArgument) in let com = unsafeBitCast(ctx, to: Common.self) var outputs: UInt32 = 2 @@ -299,28 +276,29 @@ 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() { @@ -336,18 +314,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() { @@ -379,28 +357,26 @@ 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() } } func updateCursorVisibility() { - setCursorVisiblility(cursorVisibilityWanted) + setCursorVisibility(cursorVisibilityWanted) } - func setCursorVisiblility(_ visible: Bool) { + func setCursorVisibility(_ visible: Bool) { NSCursor.setHiddenUntilMouseMoves(!visible && (view?.canHideCursor() ?? false)) } 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 @@ -409,23 +385,17 @@ class Common: NSObject { } func getScreenBy(name screenName: String?) -> NSScreen? { - for screen in NSScreen.screens { - if screen.displayName == screenName { - return screen - } + for screen in NSScreen.screens + where [screen.localizedName, screen.name, screen.uniqueName, screen.serialNumber].contains(screenName) { + return screen } return nil } 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) @@ -437,46 +407,45 @@ class Common: NSObject { NSScreen.main } - func getWindowGeometry(forScreen targetScreen: NSScreen, + func getWindowGeometry(forScreen screen: NSScreen, videoOut vo: UnsafeMutablePointer<vo>) -> NSRect { - let r = targetScreen.convertRectToBacking(targetScreen.frame) - let targetFrame = - (mpv?.macOpts.macos_geometry_calculation ?? Int32(FRAME_VISIBLE)) == FRAME_VISIBLE ? - targetScreen.visibleFrame : targetScreen.frame - let rv = targetScreen.convertRectToBacking(targetFrame) - + let r = screen.convertRectToBacking(screen.frame) + let targetFrame = option.mac.macos_geometry_calculation == FRAME_VISIBLE + ? screen.visibleFrame : screen.frame + let rv = screen.convertRectToBacking(targetFrame) + + // convert origin to be relative to target screen + var originY = rv.origin.y - r.origin.y + let originX = rv.origin.x - r.origin.x // flip the y origin, mp_rect expects the origin at the top-left // macOS' windowing system operates from the bottom-left - var originY = r.size.height - rv.origin.y - rv.size.height - var screenRC: mp_rect = mp_rect(x0: Int32(rv.origin.x), + originY = -(originY + rv.size.height) + var screenRC: mp_rect = mp_rect(x0: Int32(originX), y0: Int32(originY), - x1: Int32(rv.origin.x + rv.size.width), + x1: Int32(originX + rv.size.width), y1: Int32(originY + rv.size.height)) + var geo: vo_win_geometry = vo_win_geometry() - vo_calc_window_geometry2(vo, &screenRC, Double(targetScreen.backingScaleFactor), &geo) + vo_calc_window_geometry2(vo, &screenRC, Double(screen.backingScaleFactor), &geo) vo_apply_window_geometry(vo, &geo) - // flip the y origin again let height = CGFloat(geo.win.y1 - geo.win.y0) - originY = r.size.height - CGFloat(geo.win.y0) - height - let wr = NSMakeRect(CGFloat(geo.win.x0), originY, - CGFloat(geo.win.x1 - geo.win.x0), height) - return targetScreen.convertRectFromBacking(wr) + let width = CGFloat(geo.win.x1 - geo.win.x0) + // flip the y origin again + let y = CGFloat(-geo.win.y1) + let x = CGFloat(geo.win.x0) + return screen.convertRectFromBacking(NSRect(x: x, y: y, width: width, height: 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 @@ -489,11 +458,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 { @@ -517,47 +486,57 @@ class Common: NSObject { func windowDidChangeOcclusionState() {} @objc func control(_ vo: UnsafeMutablePointer<vo>, - events: UnsafeMutablePointer<Int32>, - request: UInt32, - data: UnsafeMutableRawPointer) -> Int32 - { - guard let mpv = mpv else { - log.sendWarning("Unexpected nil value in Control Callback") - return VO_FALSE - } - + events: UnsafeMutablePointer<Int32>, + request: UInt32, + data: UnsafeMutableRawPointer?) -> Int32 { 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), + 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?.setOnAllWorkspaces(Bool(self.option.vo.all_workspaces)) + } + case TypeHelper.toPointer(&option.voPtr.pointee.keepaspect_window): + DispatchQueue.main.async { + self.window?.keepAspect = Bool(self.option.vo.keepaspect_window) + } + case TypeHelper.toPointer(&option.voPtr.pointee.window_minimized): DispatchQueue.main.async { - self.window?.setOnTop(Bool(mpv.opts.ontop), Int(mpv.opts.ontop_level)) + self.window?.setMinimized(Bool(self.option.vo.window_minimized)) } - case MPVHelper.getPointer(&mpv.optsPtr.pointee.keepaspect_window): + case TypeHelper.toPointer(&option.voPtr.pointee.window_maximized): DispatchQueue.main.async { - self.window?.keepAspect = Bool(mpv.opts.keepaspect_window) + self.window?.setMaximized(Bool(self.option.vo.window_maximized)) } - case MPVHelper.getPointer(&mpv.optsPtr.pointee.window_minimized): + case TypeHelper.toPointer(&option.voPtr.pointee.cursor_passthrough): DispatchQueue.main.async { - self.window?.setMinimized(Bool(mpv.opts.window_minimized)) + self.window?.ignoresMouseEvents = self.option.vo.cursor_passthrough } - case MPVHelper.getPointer(&mpv.optsPtr.pointee.window_maximized): + case TypeHelper.toPointer(&option.voPtr.pointee.geometry), + TypeHelper.toPointer(&option.voPtr.pointee.autofit), + TypeHelper.toPointer(&option.voPtr.pointee.autofit_smaller), + TypeHelper.toPointer(&option.voPtr.pointee.autofit_larger): DispatchQueue.main.async { - self.window?.setMaximized(Bool(mpv.opts.window_maximized)) + let (_, wr) = self.getInitProperties(vo) + self.window?.updateFrame(wr) } default: break @@ -565,11 +544,18 @@ class Common: NSObject { } return VO_TRUE case VOCTRL_GET_DISPLAY_FPS: - let fps = data.assumingMemoryBound(to: CDouble.self) + 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 scaleFactor = data!.assumingMemoryBound(to: CDouble.self) let screen = getCurrentScreen() let factor = window?.backingScaleFactor ?? screen?.backingScaleFactor ?? 1.0 @@ -582,20 +568,20 @@ class Common: NSObject { disableDisplaySleep() return VO_TRUE case VOCTRL_SET_CURSOR_VISIBILITY: - let cursorVisibility = data.assumingMemoryBound(to: CBool.self) + let cursorVisibility = data!.assumingMemoryBound(to: CBool.self) cursorVisibilityWanted = cursorVisibility.pointee DispatchQueue.main.async { - self.setCursorVisiblility(self.cursorVisibilityWanted) + self.setCursorVisibility(self.cursorVisibilityWanted) } return VO_TRUE 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 } - let icc = data.assumingMemoryBound(to: bstr.self) + let icc = data!.assumingMemoryBound(to: bstr.self) iccData.withUnsafeMutableBytes { (ptr: UnsafeMutableRawBufferPointer) in guard let baseAddress = ptr.baseAddress, ptr.count > 0 else { return } let u8Ptr = baseAddress.assumingMemoryBound(to: UInt8.self) @@ -604,52 +590,60 @@ class Common: NSObject { return VO_TRUE case VOCTRL_GET_AMBIENT_LUX: if lightSensor != 0 { - let lux = data.assumingMemoryBound(to: Int32.self) + let lux = data!.assumingMemoryBound(to: Int32.self) lux.pointee = Int32(lmuToLux(lastLmu)) - return VO_TRUE; + return VO_TRUE } return VO_NOTIMPL case VOCTRL_GET_UNFS_WINDOW_SIZE: - let sizeData = data.assumingMemoryBound(to: Int32.self) + 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) return VO_TRUE case VOCTRL_SET_UNFS_WINDOW_SIZE: - let sizeData = data.assumingMemoryBound(to: Int32.self) + let sizeData = data!.assumingMemoryBound(to: Int32.self) let size = UnsafeBufferPointer(start: sizeData, count: 2) - var rect = NSMakeRect(0, 0, CGFloat(size[0]), CGFloat(size[1])) + var rect = NSRect(x: 0, y: 0, width: CGFloat(size[0]), height: CGFloat(size[1])) DispatchQueue.main.async { - if let screen = self.window?.currentScreen, !Bool(self.mpv?.opts.hidpi_window_scale ?? 1) { + if let screen = self.window?.currentScreen, !Bool(self.option.vo.hidpi_window_scale) { rect = screen.convertRectFromBacking(rect) } self.window?.updateSize(rect.size) } return VO_TRUE case VOCTRL_GET_DISPLAY_NAMES: - let dnames = data.assumingMemoryBound(to: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?.self) - var array: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>? = nil + let dnames = data!.assumingMemoryBound(to: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?.self) + var array: UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>? var count: Int32 = 0 - let displayName = getCurrentScreen()?.displayName ?? "Unknown" + let displayName = getCurrentScreen()?.uniqueName ?? "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.warning("No Screen available to retrieve frame") + return VO_NOTAVAIL + } + let sizeData = data!.assumingMemoryBound(to: Int32.self) + let size = UnsafeMutableBufferPointer(start: sizeData, count: 2) + let frame = screen.convertRectToBacking(screen.frame) + size[0] = Int32(frame.size.width) + size[1] = Int32(frame.size.height) + return VO_TRUE case VOCTRL_GET_FOCUSED: - let focus = data.assumingMemoryBound(to: CBool.self) + let focus = data!.assumingMemoryBound(to: CBool.self) 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: @@ -657,7 +651,7 @@ class Common: NSObject { } } - let macOptsWakeupCallback: swift_wakeup_cb_fn = { ( ctx ) in + let macOptsWakeupCallback: OptionHelper.WakeupCallback = { ( ctx ) in let com = unsafeBitCast(ctx, to: Common.self) DispatchQueue.main.async { com.macOptsUpdate() @@ -665,20 +659,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 6c48004f4f..eba6f1a2d4 100644 --- a/video/out/mac/gl_layer.swift +++ b/video/out/mac/gl_layer.swift @@ -52,24 +52,24 @@ let glFormatAutoGPU: [CGLPixelFormatAttribute] = [ kCGLPFASupportsAutomaticGraphicsSwitching ] -let attributeLookUp: [UInt32:String] = [ - kCGLOGLPVersion_3_2_Core.rawValue: "kCGLOGLPVersion_3_2_Core", - kCGLOGLPVersion_Legacy.rawValue: "kCGLOGLPVersion_Legacy", - kCGLPFAOpenGLProfile.rawValue: "kCGLPFAOpenGLProfile", - UInt32(kCGLRendererGenericFloatID): "kCGLRendererGenericFloatID", - kCGLPFARendererID.rawValue: "kCGLPFARendererID", - kCGLPFAAccelerated.rawValue: "kCGLPFAAccelerated", - kCGLPFADoubleBuffer.rawValue: "kCGLPFADoubleBuffer", - kCGLPFABackingStore.rawValue: "kCGLPFABackingStore", - kCGLPFAColorSize.rawValue: "kCGLPFAColorSize", - kCGLPFAColorFloat.rawValue: "kCGLPFAColorFloat", +let attributeLookUp: [UInt32: String] = [ + kCGLOGLPVersion_3_2_Core.rawValue: "kCGLOGLPVersion_3_2_Core", + kCGLOGLPVersion_Legacy.rawValue: "kCGLOGLPVersion_Legacy", + kCGLPFAOpenGLProfile.rawValue: "kCGLPFAOpenGLProfile", + UInt32(kCGLRendererGenericFloatID): "kCGLRendererGenericFloatID", + kCGLPFARendererID.rawValue: "kCGLPFARendererID", + kCGLPFAAccelerated.rawValue: "kCGLPFAAccelerated", + kCGLPFADoubleBuffer.rawValue: "kCGLPFADoubleBuffer", + kCGLPFABackingStore.rawValue: "kCGLPFABackingStore", + kCGLPFAColorSize.rawValue: "kCGLPFAColorSize", + kCGLPFAColorFloat.rawValue: "kCGLPFAColorFloat", kCGLPFAAllowOfflineRenderers.rawValue: "kCGLPFAAllowOfflineRenderers", - kCGLPFASupportsAutomaticGraphicsSwitching.rawValue: "kCGLPFASupportsAutomaticGraphicsSwitching", + kCGLPFASupportsAutomaticGraphicsSwitching.rawValue: "kCGLPFASupportsAutomaticGraphicsSwitching" ] class GLLayer: CAOpenGLLayer { unowned var cocoaCB: CocoaCB - var libmpv: LibmpvHelper { get { return cocoaCB.libmpv } } + var libmpv: LibmpvHelper { return cocoaCB.libmpv } let displayLock = NSLock() let cglContext: CGLContextObj @@ -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 { @@ -109,7 +107,7 @@ class GLLayer: CAOpenGLLayer { autoresizingMask = [.layerWidthSizable, .layerHeightSizable] backgroundColor = NSColor.black.cgColor - if #available(macOS 10.12, *), bufferDepth > 8 { + if bufferDepth > 8 { contentsFormat = .RGBA16Float } @@ -178,7 +176,7 @@ class GLLayer: CAOpenGLLayer { glGetIntegerv(GLenum(GL_VIEWPORT), &dims) surfaceSize = NSSize(width: CGFloat(dims[2]), height: CGFloat(dims[3])) - if NSEqualSizes(surfaceSize, NSZeroSize) { + if surfaceSize == NSSize.zero { surfaceSize = bounds.size surfaceSize.width *= contentsScale surfaceSize.height *= contentsScale @@ -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) + libmpv.drawRender(NSSize.zero, 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 == 1) { + if ccb.option.mac.cocoa_cb_10bit_context { glFormat += [glFormat10Bit] } glFormat += glFormatOptional - if (ccb.libmpv.macOpts.macos_force_dedicated_gpu == 0) { + if !ccb.option.mac.macos_force_dedicated_gpu { glFormat += [glFormatAutoGPU] } @@ -289,7 +297,7 @@ class GLLayer: CAOpenGLLayer { return attributeLookUp[value.rawValue] ?? String(value.rawValue) }) |