From 831e09ea4ee2a9c366d669993b3ea0e9597b4542 Mon Sep 17 00:00:00 2001 From: Qijia Liu Date: Thu, 25 Dec 2025 21:33:59 -0500 Subject: [PATCH] Swift 6 --- CMakeLists.txt | 1 + src/config/about.swift | 3 ++- src/config/menu.swift | 2 ++ src/config/optionviews.swift | 3 +++ src/config/plugin.swift | 8 +++++++- src/config/ui.swift | 2 ++ 6 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 79bc29c..e331dff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ set(F5M_TARGET "${CMAKE_OSX_ARCHITECTURES}-apple-macos${CMAKE_OSX_DEPLOYMENT_TAR add_compile_options(-target "${F5M_TARGET}") add_link_options(-target "${F5M_TARGET}") +set(CMAKE_Swift_LANGUAGE_VERSION 6) # Disallow InitializeSwift to execute link_directories which adds Xcode paths to rpath. set(SWIFT_LIBRARY_SEARCH_PATHS "") include(InitializeSwift) diff --git a/src/config/about.swift b/src/config/about.swift index 494870f..a8c41c9 100644 --- a/src/config/about.swift +++ b/src/config/about.swift @@ -294,8 +294,9 @@ struct AboutView: View { // It's necessary to disable not only for cleaning up. // Without this, if user cancels sudo prompt and try again, UI will hang. disableInputMethod() + let userDataParam = removeUserData ? "true" : "false" DispatchQueue.global().async { - if !sudo("uninstall", removeUserData ? "true" : "false", uninstallLog) { + if !sudo("uninstall", userDataParam, uninstallLog) { DispatchQueue.main.async { uninstalling = false uninstallFailed = true diff --git a/src/config/menu.swift b/src/config/menu.swift index 9500b71..f95fabf 100644 --- a/src/config/menu.swift +++ b/src/config/menu.swift @@ -12,6 +12,7 @@ func restartAndReconnect(_ actionBetween: (() -> Void)? = nil) { } // Don't call it synchronously in SwiftUI as it will make IM temporarily unavailable in focused client. +@MainActor func restartProcess() { NSApp.terminate(nil) } @@ -41,6 +42,7 @@ extension FcitxInputController { openWindow("plugin", PluginManager.self) } + @MainActor @objc func restart(_: Any? = nil) { restartProcess() } diff --git a/src/config/optionviews.swift b/src/config/optionviews.swift index 162508b..5602480 100644 --- a/src/config/optionviews.swift +++ b/src/config/optionviews.swift @@ -454,6 +454,7 @@ struct UnsupportedOptionView: OptionView { } } +@MainActor func buildViewImpl(label: String, option: any Option) -> any OptionView { if let option = option as? BooleanOption { return BooleanOptionView(label: label, model: option) @@ -506,6 +507,7 @@ func buildViewImpl(label: String, option: any Option) -> any OptionView { } } +@MainActor func buildViewImpl(config: Config) -> any OptionView { switch config.kind { case .group(let children): @@ -515,6 +517,7 @@ func buildViewImpl(config: Config) -> any OptionView { } } +@MainActor func buildView(config: Config) -> AnyView { AnyView(buildViewImpl(config: config)) } diff --git a/src/config/plugin.swift b/src/config/plugin.swift index 9b8040b..1d195f4 100644 --- a/src/config/plugin.swift +++ b/src/config/plugin.swift @@ -5,6 +5,7 @@ import SwiftUI import SwiftyJSON import UniformTypeIdentifiers +@MainActor struct Plugin: Identifiable, Hashable { let id: String let category: String @@ -13,12 +14,14 @@ struct Plugin: Identifiable, Hashable { var dependencies: [String] = [] } -private var pluginMap = officialPlugins.reduce(into: [String: Plugin]()) { result, plugin in +private let pluginMap = officialPlugins.reduce(into: [String: Plugin]()) { result, plugin in result[plugin.id] = plugin } // fcitx5 doesn't unload addons from memory, so once loaded, we have to restart process to use an updated version. +@MainActor private var inMemoryPlugins = [String]() +@MainActor private var needsRestart = false private func getInstalledPlugins() -> [Plugin] { @@ -46,6 +49,7 @@ private func getAutoAddIms(_ plugin: String) -> [String] { return json["input_methods"].arrayValue.map { $0.stringValue } } +@MainActor class PluginVM: ObservableObject { @Published private(set) var installedPlugins = [Plugin]() @Published private(set) var availablePlugins = [Plugin]() @@ -233,6 +237,8 @@ struct PluginView: View { pluginVM.dataAvailable.removeAll() var countedPlugins = Set() + + @MainActor func helper(_ plugin: String) { if countedPlugins.contains(plugin) { return diff --git a/src/config/ui.swift b/src/config/ui.swift index 7692a4c..ca2c4cc 100644 --- a/src/config/ui.swift +++ b/src/config/ui.swift @@ -25,6 +25,7 @@ extension View { } } +@MainActor func footer(reset: @escaping () -> Void, apply: @escaping () -> Void, close: @escaping () -> Void) -> some View { @@ -143,6 +144,7 @@ struct SelectFileButton