summaryrefslogtreecommitdiffstats
path: root/video/out/mac/common.swift
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/mac/common.swift')
-rw-r--r--video/out/mac/common.swift228
1 files changed, 108 insertions, 120 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
}