Skip to content

Commit

Permalink
feat: 从其它输入法切到当前输入法时,显示提示窗; 在切换应用时,输入模式有变化,显示提示窗
Browse files Browse the repository at this point in the history
  • Loading branch information
qwertyyb committed Apr 28, 2023
1 parent c5970f2 commit 23efdef
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 49 deletions.
35 changes: 33 additions & 2 deletions Fire/Fire.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ extension UserDefaults {
}
}

internal let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)

class Fire: NSObject {
// 逻辑
static let candidateInserted = Notification.Name("Fire.candidateInserted")
Expand All @@ -51,6 +49,16 @@ class Fire: NSObject {
return nil
}

override init() {
super.init()
_ = InputSource.shared.onSelectChanged { selected in
StatusBar.shared.refresh()
if selected {
self.toastCurrentMode()
}
}
}

func toggleInputMode(_ nextInputMode: InputMode? = nil) {
if nextInputMode != nil, self.inputMode == nextInputMode {
return
Expand All @@ -61,13 +69,36 @@ class Fire: NSObject {
} else {
self.inputMode = inputMode == .enUS ? .zhhans : .enUS
}
toastCurrentMode()
StatusBar.shared.refresh()
NotificationCenter.default.post(name: Fire.inputModeChanged, object: nil, userInfo: [
"oldVal": oldVal,
"val": self.inputMode,
"label": self.inputMode == .enUS ? "" : ""
])
}

func toastCurrentMode() {
let text = inputMode == .enUS ? "" : ""

// 针对当前界面没有输入框,或者有输入框,但是有可能导致提示窗超出屏幕无法显示的场景,兜底在鼠标前显示提示窗
var position = CandidatesWindow.shared.inputController?.getOriginPoint() ?? NSPoint.zero

let isVisible = NSScreen.screens.contains { screen in
let frame = screen.frame
return frame.minX < position.x && position.x < frame.maxX
&& frame.minY < position.y && position.y < frame.maxY
}

NSLog("position: \(position), \(isVisible), \(NSEvent.mouseLocation)")

if !isVisible {
position = NSPoint(x: NSEvent.mouseLocation.x - 30, y: NSEvent.mouseLocation.y)
}

Utils.shared.toast?.show(text, position: position)
}

var server: IMKServer = IMKServer.init(name: kConnectionName, bundleIdentifier: Bundle.main.bundleIdentifier)
func getCandidates(origin: String = String(), page: Int = 1) -> (candidates: [Candidate], hasNext: Bool) {
if origin.count <= 0 {
Expand Down
7 changes: 1 addition & 6 deletions Fire/FireInputController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,6 @@ class FireInputController: IMKInputController {
insertText(_originalString)

Fire.shared.toggleInputMode()

let text = inputMode == .zhhans ? "" : ""

// 在输入坐标处,显示中英切换提示
Utils.shared.toast?.show(text, position: getOriginPoint())
return true
}
// 监听.flagsChanged事件只为切换中英文,其它情况不处理
Expand Down Expand Up @@ -389,7 +384,7 @@ class FireInputController: IMKInputController {
}

// 获取当前输入的光标位置
private func getOriginPoint() -> NSPoint {
func getOriginPoint() -> NSPoint {
let xd: CGFloat = 0
let yd: CGFloat = 4
var rect = NSRect()
Expand Down
21 changes: 14 additions & 7 deletions Fire/FireInputServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,22 @@ extension FireInputController {
/**
* 根据当前输入的应用改变输入模式
*/
private func activeCurrentClientInputMode() {
guard let identifier = client()?.bundleIdentifier() else { return }
private func activeCurrentClientInputMode() -> 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) {
print("[FireInputController] activeClientInputMode from setting : \(identifier), \(mode)")
Fire.shared.toggleInputMode(mode)
return
return currentMode != Fire.shared.inputMode
}
// 启用APP缓存设置
if Defaults[.keepAppInputMode], let mode = inputModeCache[identifier] {
print("[FireInputController] activeClientInputMode from cache: \(identifier), \(mode)")
Fire.shared.toggleInputMode(mode)
}
print("[FireInputController] activeClientInputMode from cache: \(identifier), \(mode)")
Fire.shared.toggleInputMode(mode)
return currentMode != Fire.shared.inputMode
}
return false
}

private func savePreviousClientInputMode() {
Expand All @@ -53,7 +56,11 @@ extension FireInputController {
return
}

activeCurrentClientInputMode()
let changed = activeCurrentClientInputMode()

if changed {
Fire.shared.toastCurrentMode()
}
}
override func deactivateServer(_ sender: Any!) {
clean()
Expand Down
42 changes: 8 additions & 34 deletions Fire/StatusBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ class StatusBar {
static let shared = StatusBar()

let statusItem: NSStatusItem
private var inputSourceChangedSubscription: AnyCancellable?
private var inputModeChangedSubscription: AnyCancellable?
private var showInputModeStatusSubscript: AnyCancellable?
private init() {
// 输入法变化时,根据当前选中状态切换显示
Expand All @@ -28,46 +26,16 @@ class StatusBar {

refreshVisibleStatus()

startEventsListener()

showInputModeStatusSubscript = Defaults.publisher(.showInputModeStatus).sink { event in
if event.newValue {
self.startEventsListener()
} else {
self.stopEventListener()
}
self.refreshVisibleStatus()
showInputModeStatusSubscript = Defaults.publisher(.showInputModeStatus).sink { _ in
self.refresh()
}
}

deinit {
stopEventListener()
showInputModeStatusSubscript?.cancel()
showInputModeStatusSubscript = nil
}

private func startEventsListener() {
stopEventListener()
inputSourceChangedSubscription = DistributedNotificationCenter.default()
.publisher(for: Notification.Name(kTISNotifySelectedKeyboardInputSourceChanged as String))
.sink { _ in
self.statusItem.isVisible = InputSource.shared.isSelected()
}

// inputMode变化时,刷新标题
inputModeChangedSubscription = NotificationCenter.default.publisher(for: Fire.inputModeChanged)
.sink { _ in
self.refreshTitle()
}
}

private func stopEventListener() {
inputSourceChangedSubscription?.cancel()
inputModeChangedSubscription?.cancel()
inputModeChangedSubscription = nil
inputSourceChangedSubscription = nil
}

@objc func changeInputMode() {
Fire.shared.toggleInputMode()
}
Expand All @@ -77,6 +45,12 @@ class StatusBar {
}

private func refreshVisibleStatus() {
NSLog("StatusBar.refreshVisibleStatus: \(InputSource.shared.isSelected())")
statusItem.isVisible = Defaults[.showInputModeStatus] && InputSource.shared.isSelected()
}

func refresh() {
refreshVisibleStatus()
refreshTitle()
}
}
2 changes: 2 additions & 0 deletions Fire/types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import Defaults
import Sparkle
import SwiftUI

internal let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)

enum CandidatesDirection: Int, Decodable, Encodable {
case vertical
case horizontal
Expand Down

0 comments on commit 23efdef

Please sign in to comment.