diff --git a/Packages/DanielGalasko_FolderMonitor/Package.swift b/Packages/DanielGalasko_FolderMonitor/Package.swift index 4865aadc..5ad788c9 100644 --- a/Packages/DanielGalasko_FolderMonitor/Package.swift +++ b/Packages/DanielGalasko_FolderMonitor/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "FolderMonitor", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/Fuziki_NSAttributedTextView/Package.swift b/Packages/Fuziki_NSAttributedTextView/Package.swift index aea4a03a..d8ca8ecc 100644 --- a/Packages/Fuziki_NSAttributedTextView/Package.swift +++ b/Packages/Fuziki_NSAttributedTextView/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "NSAttributedTextView", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/Jad_BookmarkManager/Package.swift b/Packages/Jad_BookmarkManager/Package.swift index 8bd10900..a1c2d487 100644 --- a/Packages/Jad_BookmarkManager/Package.swift +++ b/Packages/Jad_BookmarkManager/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "BookmarkManager", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/Jad_BookmarkManager/Sources/BookmarkManager/BookmarkManager.swift b/Packages/Jad_BookmarkManager/Sources/BookmarkManager/BookmarkManager.swift index abc60b64..113dc01d 100644 --- a/Packages/Jad_BookmarkManager/Sources/BookmarkManager/BookmarkManager.swift +++ b/Packages/Jad_BookmarkManager/Sources/BookmarkManager/BookmarkManager.swift @@ -34,10 +34,8 @@ public class BookmarkManager { if fileExists(url) { do { let fileData = try Data(contentsOf: url) - if let fileBookmarks = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(fileData) as! [URL: Data]? { - for bookmark in fileBookmarks { - restoreBookmark(key: bookmark.key, value: bookmark.value) - } + try (NSKeyedUnarchiver.unarchivedObject(ofClass: NSDictionary.self, from: fileData) as? [URL: Data])?.forEach { bookmark in + restoreBookmark(key: bookmark.key, value: bookmark.value) } } catch { NSLog("Couldn't load bookmarks") @@ -82,12 +80,7 @@ public class BookmarkManager { } private func getBookmarkURL() -> URL? { - let urls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask) - if let appSupportURL = urls.last { - let url = appSupportURL.appendingPathComponent("Bookmarks.dict") - return url - } - return nil + FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).last?.appendingPathComponent("Bookmarks.dict") } private func fileExists(_ url: URL) -> Bool { diff --git a/Packages/Qwertyyb_ShiftKeyUpChecker/Package.swift b/Packages/Qwertyyb_ShiftKeyUpChecker/Package.swift index 54cb3213..ac3d267c 100644 --- a/Packages/Qwertyyb_ShiftKeyUpChecker/Package.swift +++ b/Packages/Qwertyyb_ShiftKeyUpChecker/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "ShiftKeyUpChecker", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/RMJay_LineReader/Package.swift b/Packages/RMJay_LineReader/Package.swift index 4a091f6e..cb0f5e79 100644 --- a/Packages/RMJay_LineReader/Package.swift +++ b/Packages/RMJay_LineReader/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "LineReader", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_CandidateWindow/Package.swift b/Packages/vChewing_CandidateWindow/Package.swift index 31e8a625..352c7ce8 100644 --- a/Packages/vChewing_CandidateWindow/Package.swift +++ b/Packages/vChewing_CandidateWindow/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "CandidateWindow", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_CandidateWindow/Sources/CandidateWindow/CtlCandidate.swift b/Packages/vChewing_CandidateWindow/Sources/CandidateWindow/CtlCandidate.swift index 076ff3c7..3ae3ebef 100644 --- a/Packages/vChewing_CandidateWindow/Sources/CandidateWindow/CtlCandidate.swift +++ b/Packages/vChewing_CandidateWindow/Sources/CandidateWindow/CtlCandidate.swift @@ -17,7 +17,7 @@ open class CtlCandidate: NSWindowController, CtlCandidateProtocol { open var reverseLookupResult: [String] = [] open func highlightedColor() -> NSColor { - var result = NSColor.alternateSelectedControlColor + var result = NSColor.controlAccentColor var colorBlendAmount: Double = NSApplication.isDarkMode ? 0.3 : 0.0 if #available(macOS 10.14, *), !NSApplication.isDarkMode, locale == "zh-Hant" { colorBlendAmount = 0.15 diff --git a/Packages/vChewing_CocoaExtension/Package.swift b/Packages/vChewing_CocoaExtension/Package.swift index 6ef2987c..6a746eb0 100644 --- a/Packages/vChewing_CocoaExtension/Package.swift +++ b/Packages/vChewing_CocoaExtension/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "CocoaExtension", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_Hotenka/Package.swift b/Packages/vChewing_Hotenka/Package.swift index 38908028..eaee0be8 100644 --- a/Packages/vChewing_Hotenka/Package.swift +++ b/Packages/vChewing_Hotenka/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "Hotenka", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_IMKUtils/Package.swift b/Packages/vChewing_IMKUtils/Package.swift index 1c011df8..358381c7 100644 --- a/Packages/vChewing_IMKUtils/Package.swift +++ b/Packages/vChewing_IMKUtils/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "IMKUtils", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_LangModelAssembly/Package.swift b/Packages/vChewing_LangModelAssembly/Package.swift index 90e4cc06..d9216023 100644 --- a/Packages/vChewing_LangModelAssembly/Package.swift +++ b/Packages/vChewing_LangModelAssembly/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "LangModelAssembly", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_MainAssembly/Package.swift b/Packages/vChewing_MainAssembly/Package.swift index 391dab5c..f1f8b0d9 100644 --- a/Packages/vChewing_MainAssembly/Package.swift +++ b/Packages/vChewing_MainAssembly/Package.swift @@ -1,10 +1,10 @@ -// swift-tools-version:5.3 +// swift-tools-version:5.7 import PackageDescription let package = Package( name: "MainAssembly", platforms: [ - .macOS(.v10_13), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/AppDelegate.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/AppDelegate.swift index df14fc23..42e4e77b 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/AppDelegate.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/AppDelegate.swift @@ -13,9 +13,10 @@ import FolderMonitor import Shared import Uninstaller import UpdateSputnik +import UserNotifications @objc(AppDelegate) -public class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate { +public class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDelegate { public static let shared = AppDelegate() private var folderMonitor = FolderMonitor( @@ -58,12 +59,11 @@ extension AppDelegate { // MARK: - Public Functions public extension AppDelegate { - func userNotificationCenter(_: NSUserNotificationCenter, shouldPresent _: NSUserNotification) -> Bool { - true - } - func applicationWillFinishLaunching(_: Notification) { - NSUserNotificationCenter.default.delegate = self + UNUserNotificationCenter.current().delegate = self + + UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: { _, _ in }) + PrefMgr.shared.fixOddPreferences() // 一旦發現與使用者半衰模組的觀察行為有關的崩潰標記被開啟: @@ -72,14 +72,17 @@ public extension AppDelegate { if PrefMgr.shared.failureFlagForUOMObservation { LMMgr.relocateWreckedUOMData() PrefMgr.shared.failureFlagForUOMObservation = false - let userNotification = NSUserNotification() - userNotification.title = NSLocalizedString("vChewing", comment: "") - userNotification.informativeText = NSLocalizedString( + let msgPackage = UNMutableNotificationContent() + msgPackage.title = NSLocalizedString("vChewing", comment: "") + msgPackage.body = NSLocalizedString( "vChewing crashed while handling previously loaded UOM observation data. These data files are cleaned now to ensure the usability.", comment: "" ) - userNotification.soundName = NSUserNotificationDefaultSoundName - NSUserNotificationCenter.default.deliver(userNotification) + msgPackage.sound = .defaultCritical + UNUserNotificationCenter.current().add( + .init(identifier: "vChewing.notification.uomCrash", content: msgPackage, trigger: nil), + withCompletionHandler: nil + ) } if !PrefMgr.shared.onlyLoadFactoryLangModelsIfNeeded { LMMgr.loadDataModelsOnAppDelegate() } @@ -125,14 +128,15 @@ public extension AppDelegate { alert.addButton(withTitle: NSLocalizedString("Not Now", comment: "")) let result = alert.runModal() NSApp.popup() - if result == NSApplication.ModalResponse.alertFirstButtonReturn { - NSWorkspace.shared.openFile( - LMMgr.dataFolderPath(isDefaultFolder: true), withApplication: "Finder" - ) - Uninstaller.uninstall( - isSudo: false, selfKill: true, defaultDataFolderPath: LMMgr.dataFolderPath(isDefaultFolder: true) - ) - } + guard result == NSApplication.ModalResponse.alertFirstButtonReturn else { return } + let url = URL(fileURLWithPath: LMMgr.dataFolderPath(isDefaultFolder: true)) + guard let finderURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.apple.finder") else { return } + let configuration = NSWorkspace.OpenConfiguration() + configuration.promptsUserIfNeeded = true + NSWorkspace.shared.open([url], withApplicationAt: finderURL, configuration: configuration) + Uninstaller.uninstall( + isSudo: false, selfKill: true, defaultDataFolderPath: LMMgr.dataFolderPath(isDefaultFolder: true) + ) } /// 檢查該程式本身的記憶體佔用量。 @@ -143,13 +147,19 @@ public extension AppDelegate { switch currentMemorySize { case 768...: vCLog("WARNING: EXCESSIVE MEMORY FOOTPRINT (\(currentMemorySize)MB).") - let userNotification = NSUserNotification() - userNotification.title = NSLocalizedString("vChewing", comment: "") - userNotification.informativeText = NSLocalizedString( + let msgPackage = UNMutableNotificationContent() + msgPackage.title = NSLocalizedString("vChewing", comment: "") + msgPackage.body = NSLocalizedString( "vChewing is rebooted due to a memory-excessive-usage problem. If convenient, please inform the developer that you are having this issue, stating whether you are using an Intel Mac or Apple Silicon Mac. An NSLog is generated with the current memory footprint size.", comment: "" ) - NSUserNotificationCenter.default.deliver(userNotification) + UNUserNotificationCenter.current().add( + .init( + identifier: "vChewing.notification.memoryExcessiveUsage", + content: msgPackage, trigger: nil + ), + withCompletionHandler: nil + ) DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { NSApp.terminate(self) } diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/LMMgr_PhraseEditorDelegate.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/LMMgr_PhraseEditorDelegate.swift index 39a7aaee..ec3558d1 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/LMMgr_PhraseEditorDelegate.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/LMMgr_PhraseEditorDelegate.swift @@ -17,8 +17,8 @@ import Shared extension LMMgr: PhraseEditorDelegate { public var currentInputMode: Shared.InputMode { IMEApp.currentInputMode } - public func openPhraseFile(mode: Shared.InputMode, type: vChewingLM.ReplacableUserDataType, app: String) { - Self.openPhraseFile(fromURL: Self.userDictDataURL(mode: mode, type: type), app: app) + public func openPhraseFile(mode: Shared.InputMode, type: vChewingLM.ReplacableUserDataType, appIdentifier: String) { + Self.openPhraseFile(fromURL: Self.userDictDataURL(mode: mode, type: type), appIdentifier: appIdentifier) } public func consolidate(text strProcessed: inout String, pragma shouldCheckPragma: Bool) { diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/LMMgr_Utilities.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/LMMgr_Utilities.swift index 48836072..5a39cb52 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/LMMgr_Utilities.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/LMMgr_Utilities.swift @@ -311,50 +311,29 @@ public extension LMMgr { } static func openUserDictFile(type: vChewingLM.ReplacableUserDataType, dual: Bool = false, alt: Bool) { - let app: String = alt ? "" : "Finder" - openPhraseFile(fromURL: userDictDataURL(mode: IMEApp.currentInputMode, type: type), app: app) + let appIdentifier: String = alt ? "" : "Finder" + openPhraseFile(fromURL: userDictDataURL(mode: IMEApp.currentInputMode, type: type), appIdentifier: appIdentifier) guard dual else { return } - openPhraseFile(fromURL: userDictDataURL(mode: IMEApp.currentInputMode.reversed, type: type), app: app) + openPhraseFile(fromURL: userDictDataURL(mode: IMEApp.currentInputMode.reversed, type: type), appIdentifier: appIdentifier) } /// 用指定應用開啟指定檔案。 /// - Remark: 如果你的 App 有 Sandbox 處理過的話,請勿給 app 傳入 "vim" 參數,因為 Sandbox 會阻止之。 /// - Parameters: /// - url: 檔案 URL。 - /// - app: 指定 App 應用的 binary 檔案名稱。 - static func openPhraseFile(fromURL url: URL, app: String = "") { + /// - appIdentifier: 指定 App 應用的 bundle identifier 名稱。 + static func openPhraseFile(fromURL url: URL, appIdentifier: String = "") { if !Self.checkIfUserFilesExistBeforeOpening() { return } DispatchQueue.main.async { - switch app { - case "vim": - let process = Process() - let pipe = Pipe() - process.executableURL = URL(fileURLWithPath: "/bin/sh/") - process.arguments = ["-c", "open '/usr/bin/vim'", "'\(url.path)'"] - process.standardOutput = pipe - process.standardError = pipe - process.terminationHandler = { process in - vCLog("\ndidFinish: \(!process.isRunning)") - } - let fileHandle = pipe.fileHandleForReading - do { - try process.run() - } catch { - NSWorkspace.shared.openFile(url.path, withApplication: "TextEdit") - } - do { - if let theData = try fileHandle.readToEnd(), - let outStr = String(data: theData, encoding: .utf8) - { - vCLog(outStr) - } - } catch {} + switch appIdentifier { case "Finder": NSWorkspace.shared.activateFileViewerSelecting([url]) default: - if !NSWorkspace.shared.openFile(url.path, withApplication: app) { - NSWorkspace.shared.openFile(url.path, withApplication: "TextEdit") - } + guard let textEditURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.apple.TextEdit") else { return } + let toolURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: appIdentifier) ?? textEditURL + let configuration = NSWorkspace.OpenConfiguration() + configuration.promptsUserIfNeeded = true + NSWorkspace.shared.open([url], withApplicationAt: toolURL, configuration: configuration) } } } diff --git a/Packages/vChewing_Megrez/Package.swift b/Packages/vChewing_Megrez/Package.swift index 704ca0c5..04ba3748 100644 --- a/Packages/vChewing_Megrez/Package.swift +++ b/Packages/vChewing_Megrez/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "Megrez", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_NotifierUI/Package.swift b/Packages/vChewing_NotifierUI/Package.swift index f78707cf..529a6df8 100644 --- a/Packages/vChewing_NotifierUI/Package.swift +++ b/Packages/vChewing_NotifierUI/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "NotifierUI", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_PhraseEditorUI/Package.swift b/Packages/vChewing_PhraseEditorUI/Package.swift index 068c748b..90af0f0d 100644 --- a/Packages/vChewing_PhraseEditorUI/Package.swift +++ b/Packages/vChewing_PhraseEditorUI/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "PhraseEditorUI", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_PhraseEditorUI/Sources/PhraseEditorUI/PhraseEditorDelegate.swift b/Packages/vChewing_PhraseEditorUI/Sources/PhraseEditorUI/PhraseEditorDelegate.swift index 6569cd53..30a9585f 100644 --- a/Packages/vChewing_PhraseEditorUI/Sources/PhraseEditorUI/PhraseEditorDelegate.swift +++ b/Packages/vChewing_PhraseEditorUI/Sources/PhraseEditorUI/PhraseEditorDelegate.swift @@ -17,6 +17,6 @@ public protocol PhraseEditorDelegate { -> String func checkIfPhrasePairExists(userPhrase: String, mode: Shared.InputMode, key unigramKey: String) -> Bool func consolidate(text strProcessed: inout String, pragma shouldCheckPragma: Bool) - func openPhraseFile(mode: Shared.InputMode, type: vChewingLM.ReplacableUserDataType, app: String) + func openPhraseFile(mode: Shared.InputMode, type: vChewingLM.ReplacableUserDataType, appIdentifier: String) func tagOverrides(in strProcessed: inout String, mode: Shared.InputMode) } diff --git a/Packages/vChewing_PhraseEditorUI/Sources/PhraseEditorUI/PhraseEditorUI.swift b/Packages/vChewing_PhraseEditorUI/Sources/PhraseEditorUI/PhraseEditorUI.swift index 4dd177e2..7be7f9ef 100644 --- a/Packages/vChewing_PhraseEditorUI/Sources/PhraseEditorUI/PhraseEditorUI.swift +++ b/Packages/vChewing_PhraseEditorUI/Sources/PhraseEditorUI/PhraseEditorUI.swift @@ -186,8 +186,8 @@ public struct VwrPhraseEditorUI: View { } private func callExternalAppToOpenPhraseFile() { - let app: String = NSEvent.keyModifierFlags.contains(.option) ? "TextEdit" : "Finder" - delegate?.openPhraseFile(mode: selInputMode, type: selUserDataType, app: app) + let app: String = NSEvent.keyModifierFlags.contains(.option) ? "com.apple.TextEdit" : "com.apple.finder" + delegate?.openPhraseFile(mode: selInputMode, type: selUserDataType, appIdentifier: app) } // MARK: - Main View. diff --git a/Packages/vChewing_PinyinPhonaConverter/Package.swift b/Packages/vChewing_PinyinPhonaConverter/Package.swift index 2a4a2a5b..59aac5f3 100644 --- a/Packages/vChewing_PinyinPhonaConverter/Package.swift +++ b/Packages/vChewing_PinyinPhonaConverter/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "PinyinPhonaConverter", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_PopupCompositionBuffer/Package.swift b/Packages/vChewing_PopupCompositionBuffer/Package.swift index 854c61ee..ce22f279 100644 --- a/Packages/vChewing_PopupCompositionBuffer/Package.swift +++ b/Packages/vChewing_PopupCompositionBuffer/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "PopupCompositionBuffer", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_Shared/Package.swift b/Packages/vChewing_Shared/Package.swift index 5d6e6afc..e48fceb6 100644 --- a/Packages/vChewing_Shared/Package.swift +++ b/Packages/vChewing_Shared/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "Shared", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_SwiftExtension/Package.swift b/Packages/vChewing_SwiftExtension/Package.swift index 8dd734e9..72e2fbff 100644 --- a/Packages/vChewing_SwiftExtension/Package.swift +++ b/Packages/vChewing_SwiftExtension/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "SwiftExtension", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftExtension.swift b/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftExtension.swift index cbadb025..177bb5ac 100644 --- a/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftExtension.swift +++ b/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftExtension.swift @@ -223,19 +223,6 @@ public extension BinaryInteger { } } -// MARK: - File Handle API Compatibility for macOS 10.15.3 and Earlier. - -@available(macOS, deprecated: 10.15.4) -extension FileHandle { - public func read(upToCount count: Int) throws -> Data? { - readData(ofLength: count) - } - - public func readToEnd() throws -> Data? { - readDataToEndOfFile() - } -} - // MARK: - Index Revolver (only for Array) // Further discussion: https://forums.swift.org/t/62847 diff --git a/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftUIExtension.swift b/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftUIExtension.swift index 90376095..3627d6df 100644 --- a/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftUIExtension.swift +++ b/Packages/vChewing_SwiftExtension/Sources/SwiftExtension/SwiftUIExtension.swift @@ -32,7 +32,6 @@ public extension Binding { // Ref: https://stackoverflow.com/a/63217861 @available(macOS 10.15, *) -@available(macOS, obsoleted: 11) struct Tooltip: NSViewRepresentable { let tooltip: String @@ -47,9 +46,8 @@ struct Tooltip: NSViewRepresentable { } @available(macOS 10.15, *) -@available(macOS, obsoleted: 11) -extension View { - public func help(_ tooltip: String) -> some View { +public extension View { + func help(_ tooltip: String) -> some View { overlay(Tooltip(tooltip: tooltip)) } } diff --git a/Packages/vChewing_Tekkon/Package.swift b/Packages/vChewing_Tekkon/Package.swift index ff68866d..ec9538d3 100644 --- a/Packages/vChewing_Tekkon/Package.swift +++ b/Packages/vChewing_Tekkon/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "Tekkon", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_TooltipUI/Package.swift b/Packages/vChewing_TooltipUI/Package.swift index 5a736fd9..ef56e02f 100644 --- a/Packages/vChewing_TooltipUI/Package.swift +++ b/Packages/vChewing_TooltipUI/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "TooltipUI", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_Uninstaller/Package.swift b/Packages/vChewing_Uninstaller/Package.swift index 8a76a744..e05019d7 100644 --- a/Packages/vChewing_Uninstaller/Package.swift +++ b/Packages/vChewing_Uninstaller/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "Uninstaller", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Packages/vChewing_UpdateSputnik/Package.swift b/Packages/vChewing_UpdateSputnik/Package.swift index dfa62829..9d45a389 100644 --- a/Packages/vChewing_UpdateSputnik/Package.swift +++ b/Packages/vChewing_UpdateSputnik/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "UpdateSputnik", platforms: [ - .macOS(.v10_11), + .macOS(.v11), ], products: [ .library( diff --git a/Source/Modules/SessionCtl_Menu.swift b/Source/Modules/SessionCtl_Menu.swift index a8311332..3cc84df5 100644 --- a/Source/Modules/SessionCtl_Menu.swift +++ b/Source/Modules/SessionCtl_Menu.swift @@ -233,9 +233,10 @@ public extension SessionCtl { @objc func showCheatSheet(_: Any? = nil) { guard let url = Bundle.main.url(forResource: "shortcuts", withExtension: "html") else { return } - DispatchQueue.main.async { - NSWorkspace.shared.openFile(url.path, withApplication: "Safari") - } + guard let safariURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.apple.Safari") else { return } + let configuration = NSWorkspace.OpenConfiguration() + configuration.promptsUserIfNeeded = true + NSWorkspace.shared.open([url], withApplicationAt: safariURL, configuration: configuration) } @objc func showClientListMgr(_: Any? = nil) { @@ -380,13 +381,18 @@ public extension SessionCtl { if !LMMgr.userDataFolderExists { return } - NSWorkspace.shared.openFile( - LMMgr.dataFolderPath(isDefaultFolder: false), withApplication: "Finder" - ) + let url = URL(fileURLWithPath: LMMgr.dataFolderPath(isDefaultFolder: false)) + guard let finderURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.apple.finder") else { return } + let configuration = NSWorkspace.OpenConfiguration() + configuration.promptsUserIfNeeded = true + NSWorkspace.shared.open([url], withApplicationAt: finderURL, configuration: configuration) } @objc func openAppSupportFolderFromContainer(_: Any? = nil) { - NSWorkspace.shared.openFile(LMMgr.appSupportURL.path, withApplication: "Finder") + guard let finderURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.apple.finder") else { return } + let configuration = NSWorkspace.OpenConfiguration() + configuration.promptsUserIfNeeded = true + NSWorkspace.shared.open([LMMgr.appSupportURL], withApplicationAt: finderURL, configuration: configuration) } @objc func openUserPhrases(_: Any? = nil) { diff --git a/Source/Modules/WindowControllers/CtlClientListMgr.swift b/Source/Modules/WindowControllers/CtlClientListMgr.swift index 28d7d6af..9220f489 100644 --- a/Source/Modules/WindowControllers/CtlClientListMgr.swift +++ b/Source/Modules/WindowControllers/CtlClientListMgr.swift @@ -8,6 +8,7 @@ import AppKit import MainAssembly +import UniformTypeIdentifiers class CtlClientListMgr: NSWindowController, NSTableViewDelegate, NSTableViewDataSource { @IBOutlet var tblClients: NSTableView! @@ -33,7 +34,7 @@ class CtlClientListMgr: NSWindowController, NSTableViewDelegate, NSTableViewData window?.setPosition(vertical: .center, horizontal: .right, padding: 20) localize() tblClients.delegate = self - tblClients.registerForDraggedTypes([.init(rawValue: kUTTypeFileURL as String)]) + tblClients.registerForDraggedTypes([.fileURL]) tblClients.allowsMultipleSelection = true tblClients.dataSource = self tblClients.action = #selector(onItemClicked(_:)) @@ -125,7 +126,7 @@ extension CtlClientListMgr { ) dlgOpenPath.showsResizeIndicator = true dlgOpenPath.allowsMultipleSelection = true - dlgOpenPath.allowedFileTypes = ["app"] + dlgOpenPath.allowedContentTypes = [UTType.applicationBundle] dlgOpenPath.allowsOtherFileTypes = false dlgOpenPath.showsHiddenFiles = true dlgOpenPath.canChooseFiles = true @@ -240,7 +241,7 @@ extension CtlClientListMgr { neta info: NSDraggingInfo, onError: @escaping () -> Void?, handler: (([URL]) -> Void)? = nil ) { let board = info.draggingPasteboard - let type = NSPasteboard.PasteboardType(rawValue: kUTTypeApplicationBundle as String) + let type = UTType.applicationBundle let options: [NSPasteboard.ReadingOptionKey: Any] = [ .urlReadingFileURLsOnly: true, .urlReadingContentsConformToTypes: [type], diff --git a/Source/Modules/WindowControllers/CtlPrefWindow.swift b/Source/Modules/WindowControllers/CtlPrefWindow.swift index ea785684..9f4352fe 100644 --- a/Source/Modules/WindowControllers/CtlPrefWindow.swift +++ b/Source/Modules/WindowControllers/CtlPrefWindow.swift @@ -431,7 +431,7 @@ class CtlPrefWindow: NSWindowController, NSWindowDelegate { dlgOpenFile.canChooseFiles = true dlgOpenFile.canChooseDirectories = false dlgOpenFile.allowsMultipleSelection = false - dlgOpenFile.allowedFileTypes = ["cin2", "vcin", "cin"] + dlgOpenFile.allowedContentTypes = ["cin2", "vcin", "cin"].compactMap { .init(filenameExtension: $0) } dlgOpenFile.allowsOtherFileTypes = true let bolPreviousPathValidity = LMMgr.checkCassettePathValidity( diff --git a/Source/Modules/WindowControllers/CtlPrefWindow_PhraseEditor.swift b/Source/Modules/WindowControllers/CtlPrefWindow_PhraseEditor.swift index 7abdcb4f..936e3fc5 100644 --- a/Source/Modules/WindowControllers/CtlPrefWindow_PhraseEditor.swift +++ b/Source/Modules/WindowControllers/CtlPrefWindow_PhraseEditor.swift @@ -198,7 +198,7 @@ extension CtlPrefWindow: NSTextViewDelegate, NSTextFieldDelegate { DispatchQueue.main.async { [weak self] in guard let self = self else { return } let app: String = NSEvent.keyModifierFlags.contains(.option) ? "TextEdit" : "Finder" - LMMgr.shared.openPhraseFile(mode: self.selInputMode, type: self.selUserDataType, app: app) + LMMgr.shared.openPhraseFile(mode: self.selInputMode, type: self.selUserDataType, appIdentifier: app) } }