diff --git a/osdep/macOS_mpv_helper.swift b/osdep/macOS_mpv_helper.swift index 35435835de..fdc458e834 100644 --- a/osdep/macOS_mpv_helper.swift +++ b/osdep/macOS_mpv_helper.swift @@ -177,9 +177,11 @@ class MPVHelper: NSObject { sendWarning("Invalid ICC profile data.") return } - let iccSize = iccData.count - iccData.withUnsafeMutableBytes { (u8Ptr: UnsafeMutablePointer) 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) diff --git a/osdep/macOS_swift_compat.swift b/osdep/macOS_swift_compat.swift index 1a57a1e1c3..381398e1bf 100644 --- a/osdep/macOS_swift_compat.swift +++ b/osdep/macOS_swift_compat.swift @@ -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(_ body: (UnsafeMutableRawBufferPointer) throws -> Type) rethrows -> Type { + let dataCount = count + return try withUnsafeMutableBytes { (ptr: UnsafeMutablePointer) 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(_ 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 + diff --git a/osdep/macOS_swift_extensions.swift b/osdep/macOS_swift_extensions.swift index 7929d48f9a..1e30cf4df7 100644 --- a/osdep/macOS_swift_extensions.swift +++ b/osdep/macOS_swift_extensions.swift @@ -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 } } diff --git a/video/out/cocoa-cb/events_view.swift b/video/out/cocoa-cb/events_view.swift index 9c30e32ca0..59441d9793 100644 --- a/video/out/cocoa-cb/events_view.swift +++ b/video/out/cocoa-cb/events_view.swift @@ -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) { @@ -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 [] @@ -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") { @@ -220,7 +211,7 @@ 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 { @@ -228,7 +219,7 @@ class EventsView: NSView { 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) { @@ -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; diff --git a/video/out/cocoa-cb/title_bar.swift b/video/out/cocoa-cb/title_bar.swift index f5979c71e9..f961b1908a 100644 --- a/video/out/cocoa-cb/title_bar.swift +++ b/video/out/cocoa-cb/title_bar.swift @@ -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 { @@ -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 @@ -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 @@ -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 diff --git a/video/out/cocoa-cb/window.swift b/video/out/cocoa-cb/window.swift index dc7762c5af..2f87711d22 100644 --- a/video/out/cocoa-cb/window.swift +++ b/video/out/cocoa-cb/window.swift @@ -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 @@ -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 @@ -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) @@ -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 @@ -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)"]) @@ -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 } diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift index 21f6d3f95d..b08f102964 100644 --- a/video/out/cocoa_cb_common.swift +++ b/video/out/cocoa_cb_common.swift @@ -29,7 +29,7 @@ class CocoaCB: NSObject { var cursorHidden: Bool = false var cursorVisibilityWanted: Bool = true - var isShuttingDown: Bool = false + @objc var isShuttingDown: Bool = false var title: String = "mpv" { didSet { if let window = window { window.title = title } } @@ -52,7 +52,7 @@ class CocoaCB: NSObject { let queue: DispatchQueue = DispatchQueue(label: "io.mpv.queue") - init(_ mpvHandle: OpaquePointer) { + @objc init(_ mpvHandle: OpaquePointer) { mpv = MPVHelper(mpvHandle) super.init() layer = VideoLayer(cocoaCB: self) @@ -97,7 +97,7 @@ class CocoaCB: NSObject { mpv.sendError("Something went wrong, no View was initialized") exit(1) } - guard let targetScreen = getScreenBy(id: Int(opts.screen_id)) ?? NSScreen.main() else { + guard let targetScreen = getScreenBy(id: Int(opts.screen_id)) ?? NSScreen.main else { mpv.sendError("Something went wrong, no Screen was found") exit(1) } @@ -135,7 +135,7 @@ class CocoaCB: NSObject { func updateWindowSize(_ vo: UnsafeMutablePointer) { let opts: mp_vo_opts = vo.pointee.opts.pointee - guard let targetScreen = getScreenBy(id: Int(opts.screen_id)) ?? NSScreen.main() else { + guard let targetScreen = getScreenBy(id: Int(opts.screen_id)) ?? NSScreen.main else { mpv.sendWarning("Couldn't update Window size, no Screen available") return } @@ -170,7 +170,7 @@ class CocoaCB: NSObject { let opts: mp_vo_opts = vo.pointee.opts.pointee CVDisplayLinkCreateWithActiveCGDisplays(&link) - guard let screen = getScreenBy(id: Int(opts.screen_id)) ?? NSScreen.main(), + guard let screen = getScreenBy(id: Int(opts.screen_id)) ?? NSScreen.main, let link = self.link else { mpv.sendWarning("Couldn't start DisplayLink, no Screen or DisplayLink available") @@ -279,18 +279,19 @@ class CocoaCB: NSObject { // the polinomial approximation for apple lmu value -> lux was empirically // derived by firefox developers (Apple provides no documentation). // https://bugzilla.mozilla.org/show_bug.cgi?id=793728 - let power_c4 = 1 / pow(10, 27) - let power_c3 = 1 / pow(10, 19) - let power_c2 = 1 / pow(10, 12) - let power_c1 = 1 / pow(10, 5) + let power_c4: Double = 1 / pow(10, 27) + let power_c3: Double = 1 / pow(10, 19) + let power_c2: Double = 1 / pow(10, 12) + let power_c1: Double = 1 / pow(10, 5) - let term4 = -3.0 * power_c4 * pow(Decimal(v), 4) - let term3 = 2.6 * power_c3 * pow(Decimal(v), 3) - let term2 = -3.4 * power_c2 * pow(Decimal(v), 2) - let term1 = 3.9 * power_c1 * Decimal(v) + let lum = Double(v) + let term4: Double = -3.0 * power_c4 * pow(lum, 4.0) + let term3: Double = 2.6 * power_c3 * pow(lum, 3.0) + let term2: Double = -3.4 * power_c2 * pow(lum, 2.0) + let term1: Double = 3.9 * power_c1 * lum - let lux = Int(ceil( Double((term4 + term3 + term2 + term1 - 0.19) as NSNumber))) - return Int(lux > 0 ? lux : 0) + let lux = Int(ceil(term4 + term3 + term2 + term1 - 0.19)) + return lux > 0 ? lux : 0 } var lightSensorCallback: IOServiceInterestCallback = { (ctx, service, messageType, messageArgument) -> Void in @@ -370,14 +371,13 @@ class CocoaCB: NSObject { } func getScreenBy(id screenID: Int) -> NSScreen? { - guard let screens = NSScreen.screens() else { return nil} - if screenID >= screens.count { + if screenID >= NSScreen.screens.count { mpv.sendInfo("Screen ID \(screenID) does not exist, falling back to current device") return nil } else if screenID < 0 { return nil } - return screens[screenID] + return NSScreen.screens[screenID] } func getWindowGeometry(forScreen targetScreen: NSScreen, @@ -486,7 +486,7 @@ class CocoaCB: NSObject { var count: Int32 = 0 let screen = ccb.window != nil ? ccb.window?.screen : ccb.getScreenBy(id: Int(opts.screen_id)) ?? - NSScreen.main() + NSScreen.main let displayName = screen?.displayName ?? "Unknown" SWIFT_TARRAY_STRING_APPEND(nil, &array, &count, ta_xstrdup(nil, displayName)) @@ -545,7 +545,7 @@ class CocoaCB: NSObject { } } - func processEvent(_ event: UnsafePointer) { + @objc func processEvent(_ event: UnsafePointer) { switch event.pointee.event_id { case MPV_EVENT_SHUTDOWN: shutdown() diff --git a/waftools/detections/compiler_swift.py b/waftools/detections/compiler_swift.py index 956fff8870..1759052d53 100644 --- a/waftools/detections/compiler_swift.py +++ b/waftools/detections/compiler_swift.py @@ -21,9 +21,9 @@ def __add_swift_flags(ctx): verRe = re.compile("(?i)version\s?([\d.]+)") ctx.env.SWIFT_VERSION = verRe.search(__run([ctx.env.SWIFT, '-version'])).group(1) - # the -swift-version parameter is only supported on swift 3.1 and newer - if StrictVersion(ctx.env.SWIFT_VERSION) >= StrictVersion("3.1"): - ctx.env.SWIFT_FLAGS.extend([ "-swift-version", "3" ]) + # prevent possible breakages with future swift versions + if StrictVersion(ctx.env.SWIFT_VERSION) >= StrictVersion("6.0"): + ctx.env.SWIFT_FLAGS.extend([ "-swift-version", "5" ]) if ctx.is_debug_build(): ctx.env.SWIFT_FLAGS.append("-g") @@ -109,7 +109,7 @@ def __find_swift_library(ctx): ctx.end_msg(False) enableStatic = getattr(ctx.options, 'enable_swift-static') - if (enableStatic or enableStatic == None) and 'SWIFT_LIB_STATIC' in swift_libraries: + if (enableStatic) and 'SWIFT_LIB_STATIC' in swift_libraries: __add_static_swift_library_linking_flags(ctx, swift_libraries['SWIFT_LIB_STATIC']) else: __add_dynamic_swift_library_linking_flags(ctx, swift_libraries['SWIFT_LIB_DYNAMIC']) @@ -136,7 +136,6 @@ def __find_macos_sdk(ctx): sdk_version = __run(['xcrun', '--sdk', 'macosx', '--show-sdk-version' ]) if sdk: - ctx.end_msg(sdk) ctx.env.MACOS_SDK = sdk build_version = '10.10.0' @@ -161,6 +160,8 @@ def __find_macos_sdk(ctx): ctx.env.MACOS_SDK_VERSION = build_version else: ctx.env.MACOS_SDK_VERSION = sdk_version + + ctx.end_msg(sdk + ' (version found: ' + ctx.env.MACOS_SDK_VERSION + ')') else: ctx.end_msg(False) diff --git a/wscript b/wscript index 0670e50a66..925f8702be 100644 --- a/wscript +++ b/wscript @@ -129,7 +129,8 @@ build_options = [ 'name': '--swift-static', 'desc': 'static Swift linking', 'deps': 'os-darwin', - 'func': check_ctx_vars('SWIFT_LIB_STATIC') + 'func': check_ctx_vars('SWIFT_LIB_STATIC'), + 'default': 'disable' } ] @@ -958,7 +959,7 @@ standalone_features = [ }, { 'name': '--macos-cocoa-cb', 'desc': 'macOS opengl-cb backend', - 'deps': 'cocoa && swift', + 'deps': 'cocoa && swift', 'func': check_true } ]