Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# TypeSwitch

TypeSwitch 根据前台应用的规则选择输入法,并在输入法可用性变化后恢复所需的切换。

## 领域语言

**输入法切换与恢复**:根据当前前台应用及其规则确定目标输入法,并处理切换尝试、输入法目录恢复与前台重试的完整过程。

**切换尝试**:针对某个应用和目标输入法发起的一次程序切换。已经选中目标输入法与实际完成一次切换是不同的结果。

**输入法目录**:TypeSwitch 获取到的可用输入法集合。尚未获取或获取失败,不等于集合为空,也不等于某个输入法已被删除。

**前台重试**:重新确认当前前台应用,再按该应用当时的规则尝试切换;不是无条件重放此前应用的切换。

**跟随上次**:记住某个应用上次使用的输入法,并在该应用再次成为前台应用时将其作为切换目标。程序切换自身的目标通知不能被误当作新的手动选择。
38 changes: 7 additions & 31 deletions TypeSwitch/Sources/App/AppFeature+MenuState.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import Foundation

extension AppFeature.State {
var currentFrontmostBundleId: String? { switching.currentFrontmostBundleId }
var inputMethodCatalogStatus: SwitchingFeature.State.InputMethodCatalogStatus { switching.inputMethodCatalogStatus }
var inputMethods: [InputMethod] { switching.inputMethods }
var lastSwitchAttempt: SwitchingFeature.State.LastSwitchAttempt? { switching.lastSwitchAttempt }

struct InputMethodDiagnostic: Equatable {
enum Kind: Equatable {
case catalogEmpty
Expand Down Expand Up @@ -70,14 +75,7 @@ extension AppFeature.State {
}
}

var fallbackStrategy: InputMethodStrategy {
switch fallbackRuleStore.strategy {
case .followLast, .ignored:
return .none
case .none, .fixed:
return fallbackRuleStore.strategy
}
}
var fallbackStrategy: InputMethodStrategy { switching.fallbackStrategy }

var fallbackSelectedLabel: String? {
if fallbackStrategy == .none {
Expand Down Expand Up @@ -112,7 +110,7 @@ extension AppFeature.State {

guard let lastSwitchAttempt,
currentFrontmostBundleId == lastSwitchAttempt.bundleId,
isCurrentTarget(lastSwitchAttempt),
switching.isCurrentTarget(lastSwitchAttempt),
case .failed(let error) = lastSwitchAttempt.outcome
else {
return nil
Expand Down Expand Up @@ -399,28 +397,6 @@ extension AppFeature.State {
inputMethods.first(where: { $0.id == inputMethodId })?.name
}

func isCurrentTarget(_ attempt: LastSwitchAttempt) -> Bool {
let appStrategy = strategy(for: attempt.bundleId)
switch attempt.ruleSource {
case .app:
return inputMethodId(for: appStrategy) == attempt.inputMethodId
case .fallback:
return appStrategy == .none
&& inputMethodId(for: fallbackStrategy) == attempt.inputMethodId
}
}

private func inputMethodId(for strategy: InputMethodStrategy) -> String? {
switch strategy {
case .fixed(let inputMethodId):
return inputMethodId
case .followLast(let lastInputMethodId):
return lastInputMethodId
case .ignored, .none:
return nil
}
}

private var unavailableInputMethodLabel: String {
inputMethodCatalogStatus == .ready
? TypeSwitchStrings.InputMethod.deletedOption
Expand Down
Loading
Loading