Skip to content

Commit

Permalink
cocoa-cb: migrate to swift 5 with swift 4 fallback
Browse files Browse the repository at this point in the history
this migrates our current swift code to version 5 and 4. building is
support from 10.12.6 and xcode 9.1 onwards.

dynamic linking is the new default, since Apple removed static libs
from their new toolchains and it's the recommended way.

additionally the found macOS SDK version is printed since it's an
important information for finding possible errors now.

Fixes mpv-player#6470
  • Loading branch information
Akemi authored and jeeb committed Jul 21, 2019
1 parent 0602f08 commit a8c2e29
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 85 deletions.
8 changes: 5 additions & 3 deletions osdep/macOS_mpv_helper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,11 @@ class MPVHelper: NSObject {
sendWarning("Invalid ICC profile data.")
return
}
let iccSize = iccData.count
iccData.withUnsafeMutableBytes { (u8Ptr: UnsafeMutablePointer<UInt8>) in
let iccBstr = bstrdup(nil, bstr(start: u8Ptr, len: iccSize))
iccData.withUnsafeMutableBytes { (ptr: UnsafeMutableRawBufferPointer) in
guard let baseAddress = ptr.baseAddress, ptr.count > 0 else { return }

let u8Ptr = baseAddress.assumingMemoryBound(to: UInt8.self)
let iccBstr = bstrdup(nil, bstr(start: u8Ptr, len: ptr.count))
var icc = mpv_byte_array(data: iccBstr.start, size: iccBstr.len)
let params = mpv_render_param(type: MPV_RENDER_PARAM_ICC_PROFILE, data: &icc)
mpv_render_context_set_parameter(mpvRenderContext, params)
Expand Down
69 changes: 64 additions & 5 deletions osdep/macOS_swift_compat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,68 @@
*/

#if !HAVE_MACOS_10_14_FEATURES
let NSAppearanceNameDarkAqua = "NSAppearanceNameDarkAqua"
let NSAppearanceNameAccessibilityHighContrastAqua = "NSAppearanceNameAccessibilityAqua"
let NSAppearanceNameAccessibilityHighContrastDarkAqua = "NSAppearanceNameAccessibilityDarkAqua"
let NSAppearanceNameAccessibilityHighContrastVibrantLight = "NSAppearanceNameAccessibilityVibrantLight"
let NSAppearanceNameAccessibilityHighContrastVibrantDark = "NSAppearanceNameAccessibilityVibrantDark"
extension NSAppearance.Name {
static let darkAqua: NSAppearance.Name = NSAppearance.Name(rawValue: "NSAppearanceNameDarkAqua")
static let accessibilityHighContrastAqua: NSAppearance.Name = NSAppearance.Name(rawValue: "NSAppearanceNameAccessibilityAqua")
static let accessibilityHighContrastDarkAqua: NSAppearance.Name = NSAppearance.Name(rawValue: "NSAppearanceNameAccessibilityDarkAqua")
static let accessibilityHighContrastVibrantLight: NSAppearance.Name = NSAppearance.Name(rawValue: "NSAppearanceNameAccessibilityVibrantLight")
static let accessibilityHighContrastVibrantDark: NSAppearance.Name = NSAppearance.Name(rawValue: "NSAppearanceNameAccessibilityVibrantDark")
}
#endif

extension NSPasteboard.PasteboardType {

static let fileURLCompat: NSPasteboard.PasteboardType = {
if #available(OSX 10.13, *) {
return .fileURL
} else {
return NSPasteboard.PasteboardType(kUTTypeURL as String)
}
} ()

static let URLCompat: NSPasteboard.PasteboardType = {
if #available(OSX 10.13, *) {
return .URL
} else {
return NSPasteboard.PasteboardType(kUTTypeFileURL as String)
}
} ()
}

#if !swift(>=5.0)
extension Data {

mutating func withUnsafeMutableBytes<Type>(_ body: (UnsafeMutableRawBufferPointer) throws -> Type) rethrows -> Type {
let dataCount = count
return try withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) throws -> Type in
try body(UnsafeMutableRawBufferPointer(start: ptr, count: dataCount))
}
}
}
#endif

#if !swift(>=4.2)
extension NSDraggingInfo {

var draggingPasteboard: NSPasteboard {
get { return draggingPasteboard() }
}
}
#endif

#if !swift(>=4.1)
extension Array {

func compactMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
return try self.flatMap(transform)
}
}

extension NSWindow.Level {

static func +(left: NSWindow.Level, right: Int) -> NSWindow.Level {
return NSWindow.Level(left.rawValue + right)
}
}
#endif

6 changes: 5 additions & 1 deletion osdep/macOS_swift_extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@

import Cocoa

extension NSDeviceDescriptionKey {
static let screenNumber = NSDeviceDescriptionKey("NSScreenNumber")
}

extension NSScreen {

public var displayID: CGDirectDisplayID {
get {
return deviceDescription["NSScreenNumber"] as? CGDirectDisplayID ?? 0
return deviceDescription[.screenNumber] as? CGDirectDisplayID ?? 0
}
}

Expand Down
39 changes: 15 additions & 24 deletions video/out/cocoa-cb/events_view.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,9 @@ class EventsView: NSView {
init(cocoaCB ccb: CocoaCB) {
cocoaCB = ccb
super.init(frame: NSMakeRect(0, 0, 960, 480))
autoresizingMask = [.viewWidthSizable, .viewHeightSizable]
autoresizingMask = [.width, .height]
wantsBestResolutionOpenGLSurface = true
register(forDraggedTypes: [ NSFilenamesPboardType,
NSURLPboardType,
NSPasteboardTypeString ])
registerForDraggedTypes([ .fileURLCompat, .URLCompat, .string ])
}

required init?(coder: NSCoder) {
Expand All @@ -60,11 +58,8 @@ class EventsView: NSView {
}

override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
guard let types = sender.draggingPasteboard().types else { return [] }
if types.contains(NSFilenamesPboardType) ||
types.contains(NSURLPboardType) ||
types.contains(NSPasteboardTypeString)
{
guard let types = sender.draggingPasteboard.types else { return [] }
if types.contains(.fileURLCompat) || types.contains(.URLCompat) || types.contains(.string) {
return .copy
}
return []
Expand All @@ -81,21 +76,17 @@ class EventsView: NSView {
}

override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
let pb = sender.draggingPasteboard()
guard let types = sender.draggingPasteboard().types else { return false }
if types.contains(NSFilenamesPboardType) {
if let files = pb.propertyList(forType: NSFilenamesPboardType) as? [Any] {
let pb = sender.draggingPasteboard
guard let types = pb.types else { return false }

if types.contains(.fileURLCompat) || types.contains(.URLCompat) {
if let urls = pb.readObjects(forClasses: [NSURL.self]) as? [URL] {
let files = urls.map { $0.absoluteString }
EventsResponder.sharedInstance().handleFilesArray(files)
return true
}
} else if types.contains(NSURLPboardType) {
if var url = pb.propertyList(forType: NSURLPboardType) as? [String] {
url = url.filter{ !$0.isEmpty }
EventsResponder.sharedInstance().handleFilesArray(url)
return true
}
} else if types.contains(NSPasteboardTypeString) {
guard let str = pb.string(forType: NSPasteboardTypeString) else { return false }
} 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") {
Expand Down Expand Up @@ -220,15 +211,15 @@ class EventsView: NSView {
var delta: Double
var cmd: Int32

if fabs(event.deltaY) >= fabs(event.deltaX) {
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_RIGHT : SWIFT_WHEEL_LEFT;
}

mpv.putAxis(cmd, delta: fabs(delta))
mpv.putAxis(cmd, delta: abs(delta))
}

override func scrollWheel(with event: NSEvent) {
Expand All @@ -244,7 +235,7 @@ class EventsView: NSView {
let deltaY = modifiers.contains(.shift) ? event.scrollingDeltaX : event.scrollingDeltaY
var mpkey: Int32

if fabs(deltaY) >= fabs(deltaX) {
if abs(deltaY) >= abs(deltaX) {
mpkey = deltaY > 0 ? SWIFT_WHEEL_UP : SWIFT_WHEEL_DOWN;
} else {
mpkey = deltaX > 0 ? SWIFT_WHEEL_RIGHT : SWIFT_WHEEL_LEFT;
Expand Down
22 changes: 11 additions & 11 deletions video/out/cocoa-cb/title_bar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class TitleBar: NSVisualEffectView {
get { return NSWindow.frameRect(forContentRect: CGRect.zero, styleMask: .titled).size.height }
}
var buttons: [NSButton] {
get { return ([.closeButton, .miniaturizeButton, .zoomButton] as [NSWindowButton]).flatMap { cocoaCB.window?.standardWindowButton($0) } }
get { return ([.closeButton, .miniaturizeButton, .zoomButton] as [NSWindow.ButtonType]).compactMap { cocoaCB.window?.standardWindowButton($0) } }
}

override var material: NSVisualEffectView.Material {
Expand Down Expand Up @@ -57,7 +57,7 @@ class TitleBar: NSVisualEffectView {
super.init(frame: f)
alphaValue = 0
blendingMode = .withinWindow
autoresizingMask = [.viewWidthSizable, .viewMinYMargin]
autoresizingMask = [.width, .minYMargin]
systemBar?.alphaValue = 0
state = .followsWindowActiveState
wantsLayer = true
Expand Down Expand Up @@ -148,7 +148,7 @@ class TitleBar: NSVisualEffectView {
}
}

func hide() {
@objc func hide() {
guard let window = cocoaCB.window else { return }
if window.isInFullscreen && !window.isAnimating {
alphaValue = 0
Expand All @@ -175,26 +175,26 @@ class TitleBar: NSVisualEffectView {
func appearanceFrom(string: String) -> NSAppearance? {
switch string {
case "1", "aqua":
return NSAppearance(named: NSAppearanceNameAqua)
return NSAppearance(named: .aqua)
case "3", "vibrantLight":
return NSAppearance(named: NSAppearanceNameVibrantLight)
return NSAppearance(named: .vibrantLight)
case "4", "vibrantDark":
return NSAppearance(named: NSAppearanceNameVibrantDark)
return NSAppearance(named: .vibrantDark)
default: break
}

if #available(macOS 10.14, *) {
switch string {
case "2", "darkAqua":
return NSAppearance(named: NSAppearanceNameDarkAqua)
return NSAppearance(named: .darkAqua)
case "5", "aquaHighContrast":
return NSAppearance(named: NSAppearanceNameAccessibilityHighContrastAqua)
return NSAppearance(named: .accessibilityHighContrastAqua)
case "6", "darkAquaHighContrast":
return NSAppearance(named: NSAppearanceNameAccessibilityHighContrastDarkAqua)
return NSAppearance(named: .accessibilityHighContrastDarkAqua)
case "7", "vibrantLightHighContrast":
return NSAppearance(named: NSAppearanceNameAccessibilityHighContrastVibrantLight)
return NSAppearance(named: .accessibilityHighContrastVibrantLight)
case "8", "vibrantDarkHighContrast":
return NSAppearance(named: NSAppearanceNameAccessibilityHighContrastVibrantDark)
return NSAppearance(named: .accessibilityHighContrastVibrantDark)
case "0", "auto": fallthrough
default:
return nil
Expand Down
28 changes: 14 additions & 14 deletions video/out/cocoa-cb/window.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Window: NSWindow, NSWindowDelegate {
override var canBecomeKey: Bool { return true }
override var canBecomeMain: Bool { return true }

override var styleMask: NSWindowStyleMask {
override var styleMask: NSWindow.StyleMask {
get { return super.styleMask }
set {
let responder = firstResponder
Expand All @@ -72,7 +72,7 @@ class Window: NSWindow, NSWindowDelegate {

// workaround for an AppKit bug where the NSWindow can't be placed on a
// none Main screen NSScreen outside the Main screen's frame bounds
if let wantedScreen = screen, screen != NSScreen.main() {
if let wantedScreen = screen, screen != NSScreen.main {
var absoluteWantedOrigin = contentRect.origin
absoluteWantedOrigin.x += wantedScreen.frame.origin.x
absoluteWantedOrigin.y += wantedScreen.frame.origin.y
Expand Down Expand Up @@ -255,26 +255,26 @@ class Window: NSWindow, NSWindowDelegate {
}

func setOnTop(_ state: Bool, _ ontopLevel: Any) {
let stdLevel = Int(CGWindowLevelForKey(.normalWindow))
let stdLevel: NSWindow.Level = .normal

if state {
if ontopLevel is Int {
switch ontopLevel as? Int {
case .some(-1):
level = Int(CGWindowLevelForKey(.floatingWindow))
level = .floating
case .some(-2):
level = Int(CGWindowLevelForKey(.statusWindow))+1
level = .statusBar + 1
default:
level = ontopLevel as? Int ?? stdLevel
level = NSWindow.Level(ontopLevel as? Int ?? stdLevel.rawValue)
}
} else {
switch ontopLevel as? String {
case .some("window"):
level = Int(CGWindowLevelForKey(.floatingWindow))
level = .floating
case .some("system"):
level = Int(CGWindowLevelForKey(.statusWindow))+1
level = .statusBar + 1
default:
level = Int(ontopLevel as? String ?? "") ?? stdLevel
level = NSWindow.Level(Int(ontopLevel as? String ?? "") ?? stdLevel.rawValue)
}
}
collectionBehavior.remove(.transient)
Expand Down Expand Up @@ -410,7 +410,7 @@ class Window: NSWindow, NSWindowDelegate {
return frameRect
}

guard let ts: NSScreen = tScreen ?? screen ?? NSScreen.main() else {
guard let ts: NSScreen = tScreen ?? screen ?? NSScreen.main else {
return frameRect
}
var nf: NSRect = frameRect
Expand Down Expand Up @@ -443,9 +443,9 @@ class Window: NSWindow, NSWindowDelegate {
return nf
}

func setNormalWindowSize() { setWindowScale(1.0) }
func setHalfWindowSize() { setWindowScale(0.5) }
func setDoubleWindowSize() { setWindowScale(2.0) }
@objc func setNormalWindowSize() { setWindowScale(1.0) }
@objc func setHalfWindowSize() { setWindowScale(0.5) }
@objc func setDoubleWindowSize() { setWindowScale(2.0) }

func setWindowScale(_ scale: Double) {
mpv.commandAsync(["osd-auto", "set", "window-scale", "\(scale)"])
Expand Down Expand Up @@ -480,7 +480,7 @@ class Window: NSWindow, NSWindowDelegate {
cocoaCB.layer?.inLiveResize = false
}

func windowShouldClose(_ sender: Any) -> Bool {
func windowShouldClose(_ sender: NSWindow) -> Bool {
cocoa_put_key(SWIFT_KEY_CLOSE_WIN)
return false
}
Expand Down
Loading

0 comments on commit a8c2e29

Please sign in to comment.