From b090ec65eafa713656da398ee11ea25a2e2de5fb Mon Sep 17 00:00:00 2001 From: qwertyyb Date: Fri, 8 Nov 2024 16:50:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=85=BC=E5=AE=B9=20MacOS=2015.1=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=20#137?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Fire.xcodeproj/project.pbxproj | 8 +++++--- Fire/Fire.swift | 2 ++ Fire/FireInputController.swift | 6 +++++- Fire/FireInputServer.swift | 31 ++++++++++++++++++------------- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/Fire.xcodeproj/project.pbxproj b/Fire.xcodeproj/project.pbxproj index f66a940..946f89c 100644 --- a/Fire.xcodeproj/project.pbxproj +++ b/Fire.xcodeproj/project.pbxproj @@ -629,12 +629,13 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Fire/Fire.entitlements; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Mac Developer"; + CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEPLOYMENT_LOCATION = YES; - DEVELOPMENT_TEAM = T68XK6867P; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=macosx*]" = T68XK6867P; DSTROOT = "$HOME/Library/Input Methods"; ENABLE_HARDENED_RUNTIME = YES; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -661,6 +662,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.qwertyyb.inputmethod.Fire; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "Fire/Bridging-Header.h"; diff --git a/Fire/Fire.swift b/Fire/Fire.swift index a3e5522..fc19874 100644 --- a/Fire/Fire.swift +++ b/Fire/Fire.swift @@ -56,9 +56,11 @@ class Fire: NSObject { func toastCurrentMode() { let text = inputMode == .enUS ? "英" : "中" + NSLog("[Fire] ToastCurrentMode: \(text)") // 针对当前界面没有输入框,或者有输入框,但是有可能导致提示窗超出屏幕无法显示的场景,不显示提示窗 let position = CandidatesWindow.shared.inputController?.getOriginPoint() ?? NSPoint.zero + NSLog("[Fire] ToastCurrentMode position: \(position)") let isVisible = NSScreen.screens.contains { screen in let frame = screen.frame diff --git a/Fire/FireInputController.swift b/Fire/FireInputController.swift index c04b021..7988437 100644 --- a/Fire/FireInputController.swift +++ b/Fire/FireInputController.swift @@ -84,9 +84,13 @@ class FireInputController: IMKInputController { // 中文输入模式下,markedRange 会跟随输入字符变化 // 不同APP下,对selectedRange的location处理不同,有的把location放在组字区后,比如备忘录APP,有的把location放在组字区前,比如Chrome浏览器,此处根据大小判断一下 let selectedRange = client().selectedRange() - let markedRange = client().markedRange() + var markedRange = client().markedRange() // 默认认为 location 在组字区后 + if (markedRange.location > 1000000) { + markedRange = NSRange(location: 0, length: 0) + } var previousLocation = selectedRange.location - markedRange.length - 1 + // 某些场景下,markedRange的location和length不正常,此处按大小判断一下 if selectedRange.location < markedRange.location + markedRange.length { // selectedRange的location在组字区前 previousLocation = selectedRange.location - 1 diff --git a/Fire/FireInputServer.swift b/Fire/FireInputServer.swift index fdce668..9229777 100644 --- a/Fire/FireInputServer.swift +++ b/Fire/FireInputServer.swift @@ -13,18 +13,18 @@ extension FireInputController { /** * 根据当前输入的应用改变输入模式 */ - private func activeCurrentClientInputMode() -> Bool { + private func restoreCurrentClientInputMode() -> Bool { let currentMode = Fire.shared.inputMode guard let identifier = client()?.bundleIdentifier() else { return false } if let appSetting = Defaults[.appSettings][identifier], let mode = InputMode(rawValue: appSetting.inputModeSetting.rawValue) { - NSLog("[FireInputController] activeClientInputMode from setting : \(identifier), \(mode)") + NSLog("[FireInputController] restoreClientInputMode from setting : \(identifier), \(mode)") Fire.shared.toggleInputMode(mode, showTip: false) return currentMode != Fire.shared.inputMode } // 启用APP缓存设置 if Defaults[.keepAppInputMode], let mode = InputModeCache.shared.get(identifier) { - NSLog("[FireInputController] activeClientInputMode from cache: \(identifier), \(mode)") + NSLog("[FireInputController] restoreClientInputMode from cache: \(identifier), \(mode)") Fire.shared.toggleInputMode(mode, showTip: false) return currentMode != Fire.shared.inputMode } @@ -33,22 +33,22 @@ extension FireInputController { private func savePreviousClientInputMode() { if Defaults[.keepAppInputMode], - let identifier = CandidatesWindow.shared.inputController?.client()?.bundleIdentifier(), + let controller = CandidatesWindow.shared.inputController, + let identifier = controller.client()?.bundleIdentifier(), Defaults[.appSettings][identifier] == nil { + NSLog("[Fire] saveClientInputMode \(identifier), \(inputMode)") // 缓存当前输入模式 InputModeCache.shared.put(identifier, inputMode) } } - func previousClientHandler() { - clean() - savePreviousClientInputMode() - } - override func activateServer(_ sender: Any!) { NSLog("[FireInputController] activate server: \(client()?.bundleIdentifier() ?? sender.debugDescription)") - - previousClientHandler() + + // 这个保存动作之所以不在 deactivateServer 中做,主要是因为 activateServer 和 deactivateServer 的调用顺序不固定 + // 而 inputMode 是全局的,如果是 activateServer 先调用,则会写入 inputMode + // 在后调用 deactivateServer 中保存 inputMode 时,保存的已经不是之前的 inputMode 了 + savePreviousClientInputMode() CandidatesWindow.shared.inputController = self @@ -56,15 +56,20 @@ extension FireInputController { return } - let changed = activeCurrentClientInputMode() + let changed = restoreCurrentClientInputMode() if changed && Defaults[.appInputModeTipShowTime] != .none || Defaults[.appInputModeTipShowTime] == .always { - Fire.shared.toastCurrentMode() + // 在 MacOS 15.1 上当切换应用时,如果目标应用没有输入框聚焦,直接调用 toastCurrentMode 会卡顿 3 秒左右 + // 经过验证在 async 中调用才不会卡顿 + DispatchQueue.main.async { + Fire.shared.toastCurrentMode() + } } } override func deactivateServer(_ sender: Any!) { insertOriginText() clean() +// saveClientInputMode() NSLog("[FireInputController] deactivate server: \(client()?.bundleIdentifier() ?? "no client deactivate")") } }