mac: use config cache und wakeup for mac option runtime changes

remove the libmpv observer for the macOS specific options and use a
config cache + change callback for runtime changes. this is also a
preparation for new backends and generalises even more, since libmpv
functions can't and shouldn't be used in usual vo backends. for feature
parity the config cache is used.
This commit is contained in:
der richter 2020-07-31 10:37:02 +02:00
parent 9035a51b13
commit 5fb0f36937
5 changed files with 72 additions and 60 deletions

View File

@ -182,14 +182,6 @@ class LibmpvHelper {
for ptr in cargs { free(UnsafeMutablePointer(mutating: ptr)) }
}
func observeString(_ property: String) {
mpv_observe_property(mpvHandle, 0, property, MPV_FORMAT_STRING)
}
func observeFlag(_ property: String) {
mpv_observe_property(mpvHandle, 0, property, MPV_FORMAT_FLAG)
}
// Unsafe function when called while using the render API
func command(_ cmd: String) {
if mpvHandle == nil { return }

View File

@ -17,11 +17,15 @@
import Cocoa
typealias swift_wakeup_cb_fn = (@convention(c) (UnsafeMutableRawPointer?) -> Void)?
class MPVHelper {
var log: LogHelper
var vo: UnsafeMutablePointer<vo>
var optsCachePtr: UnsafeMutablePointer<m_config_cache>
var optsPtr: UnsafeMutablePointer<mp_vo_opts>
var macOptsCachePtr: UnsafeMutablePointer<m_config_cache>
var macOptsPtr: UnsafeMutablePointer<macos_opts>
// these computed properties return a local copy of the struct accessed:
// - don't use if you rely on the pointers
@ -29,9 +33,10 @@ class MPVHelper {
var vout: vo { get { return vo.pointee } }
var optsCache: m_config_cache { get { return optsCachePtr.pointee } }
var opts: mp_vo_opts { get { return optsPtr.pointee } }
var macOptsCache: m_config_cache { get { return macOptsCachePtr.pointee } }
var macOpts: macos_opts { get { return macOptsPtr.pointee } }
var input: OpaquePointer { get { return vout.input_ctx } }
var macOpts: macos_opts = macos_opts()
init(_ vo: UnsafeMutablePointer<vo>, _ log: LogHelper) {
self.vo = vo
@ -47,14 +52,15 @@ class MPVHelper {
optsCachePtr = cache
optsPtr = UnsafeMutablePointer<mp_vo_opts>(OpaquePointer(cache.pointee.opts))
guard let ptr = mp_get_config_group(vo,
vo.pointee.global,
app.getMacOSConf()) else
guard let macCache = m_config_cache_alloc(vo,
vo.pointee.global,
app.getMacOSConf()) else
{
// will never be hit, mp_get_config_group asserts for invalid groups
return
exit(1)
}
macOpts = UnsafeMutablePointer<macos_opts>(OpaquePointer(ptr)).pointee
macOptsCachePtr = macCache
macOptsPtr = UnsafeMutablePointer<macos_opts>(OpaquePointer(macCache.pointee.opts))
}
func canBeDraggedAt(_ pos: NSPoint) -> Bool {
@ -74,25 +80,33 @@ class MPVHelper {
mp_input_put_wheel(input, mpkey, delta)
}
func nextChangedConfig(property: inout UnsafeMutableRawPointer?) -> Bool {
func nextChangedOption(property: inout UnsafeMutableRawPointer?) -> Bool {
return m_config_cache_get_next_changed(optsCachePtr, &property)
}
func setConfigProperty(fullscreen: Bool) {
func setOption(fullscreen: Bool) {
optsPtr.pointee.fullscreen = fullscreen
m_config_cache_write_opt(optsCachePtr, UnsafeMutableRawPointer(&optsPtr.pointee.fullscreen))
}
func setConfigProperty(minimized: Bool) {
func setOption(minimized: Bool) {
optsPtr.pointee.window_minimized = Int32(minimized)
m_config_cache_write_opt(optsCachePtr, UnsafeMutableRawPointer(&optsPtr.pointee.window_minimized))
}
func setConfigProperty(maximized: Bool) {
func setOption(maximized: Bool) {
optsPtr.pointee.window_maximized = Int32(maximized)
m_config_cache_write_opt(optsCachePtr, UnsafeMutableRawPointer(&optsPtr.pointee.window_maximized))
}
func setMacOptionCallback(_ callback: swift_wakeup_cb_fn, context object: AnyObject) {
m_config_cache_set_wakeup_cb(macOptsCachePtr, callback, MPVHelper.bridge(obj: object))
}
func nextChangedMacOption(property: inout UnsafeMutableRawPointer?) -> Bool {
return m_config_cache_get_next_changed(macOptsCachePtr, &property)
}
func command(_ cmd: String) {
let cCmd = UnsafePointer<Int8>(strdup(cmd))
let mpvCmd = mp_input_parse_cmd(input, bstr0(cCmd), "")

View File

@ -36,11 +36,6 @@ class CocoaCB: Common {
libmpv = LibmpvHelper(mpvHandle, newlog)
super.init(newlog)
layer = GLLayer(cocoaCB: self)
libmpv.observeString("macos-title-bar-style")
libmpv.observeString("macos-title-bar-appearance")
libmpv.observeString("macos-title-bar-material")
libmpv.observeString("macos-title-bar-color")
}
func preinit(_ vo: UnsafeMutablePointer<vo>) {
@ -238,34 +233,6 @@ class CocoaCB: Common {
switch event.pointee.event_id {
case MPV_EVENT_SHUTDOWN:
shutdown()
case MPV_EVENT_PROPERTY_CHANGE:
if backendState == .initialized {
handlePropertyChange(event)
}
default:
break
}
}
func handlePropertyChange(_ event: UnsafePointer<mpv_event>) {
let pData = OpaquePointer(event.pointee.data)
guard let property = UnsafePointer<mpv_event_property>(pData)?.pointee else {
return
}
switch String(cString: property.name) {
case "macos-title-bar-appearance":
if let data = LibmpvHelper.mpvStringArrayToString(property.data) {
titleBar?.set(appearance: data)
}
case "macos-title-bar-material":
if let data = LibmpvHelper.mpvStringArrayToString(property.data) {
titleBar?.set(material: data)
}
case "macos-title-bar-color":
if let data = LibmpvHelper.mpvStringArrayToString(property.data) {
titleBar?.set(color: data)
}
default:
break
}

View File

@ -49,9 +49,15 @@ class Common: NSObject {
}
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()
mpv.setMacOptionCallback(macOptsWakeupCallback, context: self)
}
func initApp() {
@ -438,7 +444,7 @@ class Common: NSObject {
return VO_TRUE
case VOCTRL_VO_OPTS_CHANGED:
var o: UnsafeMutableRawPointer?
while mpv.nextChangedConfig(property: &o) {
while mpv.nextChangedOption(property: &o) {
guard let opt = o else {
log.sendError("No changed options was retrieved")
return VO_TRUE
@ -546,4 +552,37 @@ class Common: NSObject {
return VO_NOTIMPL
}
}
let macOptsWakeupCallback: swift_wakeup_cb_fn = { ( ctx ) in
let com = unsafeBitCast(ctx, to: Common.self)
DispatchQueue.main.async {
com.macOptsUpdate()
}
}
func macOptsUpdate() {
guard let mpv = mpv else {
log.sendWarning("Unexpected nil value in mac opts update")
return
}
var o: UnsafeMutableRawPointer?
while mpv.nextChangedMacOption(property: &o) {
guard let opt = o else {
log.sendWarning("Could not retrieve changed mac option")
return
}
switch opt {
case UnsafeMutableRawPointer(&mpv.macOptsPtr.pointee.macos_title_bar_appearance):
titleBar?.set(appearance: Int(mpv.macOpts.macos_title_bar_appearance))
case UnsafeMutableRawPointer(&mpv.macOptsPtr.pointee.macos_title_bar_material):
titleBar?.set(material: Int(mpv.macOpts.macos_title_bar_material))
case UnsafeMutableRawPointer(&mpv.macOptsPtr.pointee.macos_title_bar_color):
titleBar?.set(color: mpv.macOpts.macos_title_bar_color)
default:
break
}
}
}
}

View File

@ -183,7 +183,7 @@ class Window: NSWindow, NSWindowDelegate {
func windowDidEnterFullScreen(_ notification: Notification) {
isInFullscreen = true
mpv?.setConfigProperty(fullscreen: isInFullscreen)
mpv?.setOption(fullscreen: isInFullscreen)
common.updateCursorVisibility()
endAnimation(frame)
common.titleBar?.show()
@ -192,7 +192,7 @@ class Window: NSWindow, NSWindowDelegate {
func windowDidExitFullScreen(_ notification: Notification) {
guard let tScreen = targetScreen else { return }
isInFullscreen = false
mpv?.setConfigProperty(fullscreen: isInFullscreen)
mpv?.setOption(fullscreen: isInFullscreen)
endAnimation(calculateWindowPosition(for: tScreen, withoutBounds: targetScreen == screen))
common.view?.layerContentsPlacement = .scaleProportionallyToFit
}
@ -230,7 +230,7 @@ class Window: NSWindow, NSWindowDelegate {
setFrame(targetFrame, display: true)
endAnimation()
isInFullscreen = true
mpv?.setConfigProperty(fullscreen: isInFullscreen)
mpv?.setOption(fullscreen: isInFullscreen)
common.windowSetToFullScreen()
}
@ -242,7 +242,7 @@ class Window: NSWindow, NSWindowDelegate {
styleMask.remove(.fullScreen)
endAnimation()
isInFullscreen = false
mpv?.setConfigProperty(fullscreen: isInFullscreen)
mpv?.setOption(fullscreen: isInFullscreen)
common.windowSetToWindow()
}
@ -496,7 +496,7 @@ class Window: NSWindow, NSWindowDelegate {
func windowDidEndLiveResize(_ notification: Notification) {
common.windowDidEndLiveResize()
mpv?.setConfigProperty(maximized: isZoomed)
mpv?.setOption(maximized: isZoomed)
if let contentViewFrame = contentView?.frame,
!isAnimating && !isInFullscreen
@ -515,11 +515,11 @@ class Window: NSWindow, NSWindowDelegate {
}
func windowDidMiniaturize(_ notification: Notification) {
mpv?.setConfigProperty(minimized: true)
mpv?.setOption(minimized: true)
}
func windowDidDeminiaturize(_ notification: Notification) {
mpv?.setConfigProperty(minimized: false)
mpv?.setOption(minimized: false)
}
func windowDidResignKey(_ notification: Notification) {
@ -542,6 +542,6 @@ class Window: NSWindow, NSWindowDelegate {
}
func windowDidMove(_ notification: Notification) {
mpv?.setConfigProperty(maximized: isZoomed)
mpv?.setOption(maximized: isZoomed)
}
}