Skip to content

Commit

Permalink
Merge pull request #60 from qwertyyb/feature/status-icon
Browse files Browse the repository at this point in the history
feat: 添加状态栏指示
  • Loading branch information
qwertyyb authored Jun 7, 2022
2 parents 24831a3 + 230a14e commit 49569a7
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 15 deletions.
4 changes: 4 additions & 0 deletions Fire.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
451E6056232E24A5007B0463 /* FireInputController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451E6055232E24A5007B0463 /* FireInputController.swift */; };
451E605D232E3A3C007B0463 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 451E605C232E3A3C007B0463 /* MainMenu.xib */; };
451E605F232E400B007B0463 /* Fire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451E605E232E400B007B0463 /* Fire.swift */; };
453377E52849E76A0064E4F2 /* StatusBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453377E42849E76A0064E4F2 /* StatusBar.swift */; };
45449B4C23535ED000C9EFEF /* InputMethodKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 451E6058232E2787007B0463 /* InputMethodKit.framework */; };
45577E502543F03F0064325B /* build.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45577E4F2543F03F0064325B /* build.swift */; };
45577E562543F4060064325B /* wb_table.txt in Resources */ = {isa = PBXBuildFile; fileRef = 45577E552543F4060064325B /* wb_table.txt */; };
Expand Down Expand Up @@ -83,6 +84,7 @@
451E6058232E2787007B0463 /* InputMethodKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = InputMethodKit.framework; path = System/Library/Frameworks/InputMethodKit.framework; sourceTree = SDKROOT; };
451E605C232E3A3C007B0463 /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; };
451E605E232E400B007B0463 /* Fire.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fire.swift; sourceTree = "<group>"; };
453377E42849E76A0064E4F2 /* StatusBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBar.swift; sourceTree = "<group>"; };
45577E4F2543F03F0064325B /* build.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = build.swift; sourceTree = "<group>"; };
45577E552543F4060064325B /* wb_table.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wb_table.txt; sourceTree = "<group>"; };
45577E5F25442E240064325B /* TableBuilder */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TableBuilder; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -195,6 +197,7 @@
673A400B253D9FE70003901E /* InputSource.swift */,
45577EAF254575480064325B /* types.swift */,
45ACDE1A2841C52500658F46 /* Bridging-Header.h */,
453377E42849E76A0064E4F2 /* StatusBar.swift */,
);
path = Fire;
sourceTree = "<group>";
Expand Down Expand Up @@ -479,6 +482,7 @@
45DCE62226A31F140009FED1 /* ApplicationSettingCache.swift in Sources */,
459DE990232EB26600A3ACD1 /* CandidatesView.swift in Sources */,
45DB6EC727E5B8FE00A39925 /* ThemeConfig.swift in Sources */,
453377E52849E76A0064E4F2 /* StatusBar.swift in Sources */,
673C4178254697E400F462A3 /* TipsWindow.swift in Sources */,
677A0874254BD47D000B58D4 /* ToastWindow.swift in Sources */,
);
Expand Down
1 change: 1 addition & 0 deletions Fire/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {

var fire: Fire!
var statistics: Statistics!
let statusBar = StatusBar.shared

func installInputSource() {
print("install input source")
Expand Down
28 changes: 24 additions & 4 deletions Fire/Fire.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Fire: NSObject {

// 逻辑
static let candidateInserted = Notification.Name("Fire.candidateInserted")
static let inputModeChanged = Notification.Name("Fire.inputModeChanged")

private var database: OpaquePointer?
private var queryStatement: OpaquePointer?
Expand All @@ -57,6 +58,23 @@ class Fire: NSObject {
close()
}

func toggleInputMode(_ nextInputMode: InputMode? = nil) {
if nextInputMode != nil, self.inputMode == nextInputMode {
return
}
let oldVal = self.inputMode
if let nextInputMode = nextInputMode, nextInputMode != self.inputMode {
self.inputMode = nextInputMode
} else {
self.inputMode = inputMode == .enUS ? .zhhans : .enUS
}
NotificationCenter.default.post(name: Fire.inputModeChanged, object: nil, userInfo: [
"oldVal": oldVal,
"val": self.inputMode,
"label": self.inputMode == .enUS ? "" : ""
])
}

private func getStatementSql() -> String {
let candidateCount = Defaults[.candidateCount]
// 比显示的候选词数量多查一个,以此判断有没有下一页
Expand Down Expand Up @@ -96,7 +114,12 @@ class Fire: NSObject {
}

func prepareStatement() {
sqlite3_open_v2(getDatabaseURL().path, &database, SQLITE_OPEN_READWRITE, nil)
if database == nil {
sqlite3_open_v2(getDatabaseURL().path, &database, SQLITE_OPEN_READWRITE, nil)
}
if queryStatement != nil {
sqlite3_finalize(queryStatement)
}
if sqlite3_prepare_v2(database, getStatementSql(), -1, &queryStatement, nil) == SQLITE_OK {
print("prepare ok")
print(sqlite3_bind_parameter_index(queryStatement, ":code"))
Expand Down Expand Up @@ -145,8 +168,6 @@ class Fire: NSObject {
sqlite3_bind_parameter_index(queryStatement, ":offset"),
Int32((page - 1) * Defaults[.candidateCount])
)
let strp = sqlite3_expanded_sql(queryStatement)!
print(String(cString: strp))
while sqlite3_step(queryStatement) == SQLITE_ROW {
let code = String.init(cString: sqlite3_column_text(queryStatement, 0))
let text = String.init(cString: sqlite3_column_text(queryStatement, 1))
Expand All @@ -161,7 +182,6 @@ class Fire: NSObject {
if candidates.isEmpty {
candidates.append(Candidate(code: origin, text: origin, type: "wb", isPlaceholder: true))
}

return (candidates, hasNext: allCount > count)
}

Expand Down
15 changes: 10 additions & 5 deletions Fire/FireInputController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class FireInputController: IMKInputController {
// 把当前未上屏的原始code上屏处理
insertText(_originalString)

inputMode = inputMode == .zhhans ? InputMode.enUS : InputMode.zhhans
Fire.shared.toggleInputMode()

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

Expand Down Expand Up @@ -336,7 +336,12 @@ class FireInputController: IMKInputController {
}
}),
(Fire.prevPageBtnTapped, { _ in self.curPage = self.curPage > 1 ? self.curPage - 1 : 1 }),
(Fire.nextPageBtnTapped, { _ in self.curPage = self._hasNext ? self.curPage + 1 : self.curPage })
(Fire.nextPageBtnTapped, { _ in self.curPage = self._hasNext ? self.curPage + 1 : self.curPage }),
(Fire.inputModeChanged, { notification in
if self._originalString.count > 0, notification.userInfo?["val"] as? InputMode == InputMode.enUS {
self.insertText(self._originalString)
}
})
]
}

Expand All @@ -348,15 +353,15 @@ class FireInputController: IMKInputController {
if let appSetting = Defaults[.appSettings][identifier],
let mode = InputMode(rawValue: appSetting.inputModeSetting.rawValue) {
print("[FireInputController] activeClientInputMode from setting : \(identifier), \(mode)")
inputMode = mode
Fire.shared.toggleInputMode(mode)
return
}
if !Defaults[.keepAppInputMode] { return }
// 启用APP缓存设置
if let appSetting = Fire.shared.appSettingCache.get(bundleIdentifier: identifier),
let mode = InputMode(rawValue: appSetting.inputModeSetting.rawValue) {
print("[FireInputController] activeClientInputMode from cache: \(identifier), \(mode)")
inputMode = mode
Fire.shared.toggleInputMode(mode)
}
}

Expand All @@ -372,7 +377,7 @@ class FireInputController: IMKInputController {
forName: observer.name, object: nil, queue: nil, using: observer.callback
))}
if Defaults[.disableEnMode] {
inputMode = .zhhans
Fire.shared.toggleInputMode(.zhhans)
return
}

Expand Down
6 changes: 3 additions & 3 deletions Fire/InputSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ class InputSource {
}

private func findInputSource(forUsage: InputSourceUsage = .enable) -> (inputSource: TISInputSource, sourceID: NSString)? {
let sourceList = TISCreateInputSourceList(nil, true).takeUnretainedValue()
let sourceList = TISCreateInputSourceList(nil, true).takeRetainedValue() as NSArray

for index in 0...CFArrayGetCount(sourceList)-1 {
for index in 0..<sourceList.count {
let inputSource = Unmanaged<TISInputSource>.fromOpaque(CFArrayGetValueAtIndex(
sourceList, index)).takeUnretainedValue()
if let result = transformTargetSource(inputSource) {
Expand Down Expand Up @@ -104,7 +104,7 @@ class InputSource {
}

func isSelected() -> Bool {
guard let result = findInputSource() else {
guard let result = findInputSource(forUsage: .selected) else {
return false
}
let unsafeIsSelected = TISGetInputSourceProperty(
Expand Down
4 changes: 4 additions & 0 deletions Fire/Preferences/GeneralPane.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct GeneralPane: View {
@Default(.zKeyQuery) private var zKeyQuery
@Default(.toggleInputModeKey) private var toggleInputModeKey
@Default(.disableEnMode) private var disableEnMode
@Default(.showInputModeStatus) private var showInputModeStatus

var body: some View {
Preferences.Container(contentWidth: 450.0) {
Expand Down Expand Up @@ -76,6 +77,9 @@ struct GeneralPane: View {
}
GroupBox(label: Text("中英文切换")) {
VStack(alignment: .leading, spacing: 12) {
HStack {
Toggle("状态栏显示", isOn: $showInputModeStatus)
}
HStack {
Toggle("禁止切换英文", isOn: $disableEnMode)
}
Expand Down
82 changes: 82 additions & 0 deletions Fire/StatusBar.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//
// StatusBar.swift
// Fire
//
// Created by 虚幻 on 2022/6/3.
// Copyright © 2022 qwertyyb. All rights reserved.
//

import Foundation
import AppKit
import Carbon
import Combine
import Defaults

class StatusBar {
static let shared = StatusBar()

let statusItem: NSStatusItem
private var inputSourceChangedSubscription: AnyCancellable?
private var inputModeChangedSubscription: AnyCancellable?
private var showInputModeStatusSubscript: AnyCancellable?
private init() {
// 输入法变化时,根据当前选中状态切换显示
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
statusItem.button?.title = ""
statusItem.button?.action = #selector(changeInputMode)
statusItem.button?.target = self

refreshVisibleStatus()

startEventsListener()

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

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()
}

private func refreshTitle() {
statusItem.button?.title = Fire.shared.inputMode == .zhhans ? "" : ""
}

private func refreshVisibleStatus() {
statusItem.isVisible = Defaults[.showInputModeStatus] && InputSource.shared.isSelected()
}
}
13 changes: 10 additions & 3 deletions Fire/Utils/Statistics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,13 @@ class Statistics {
sqlite3_finalize(insertStatement)
insertStatement = nil
} else {
sqlite3_finalize(insertStatement)
insertStatement = nil
print("errmsg: \(String(cString: sqlite3_errmsg(database)!))")
}
} else {
sqlite3_finalize(insertStatement)
insertStatement = nil
print("prepare_errmsg: \(String(cString: sqlite3_errmsg(database)!))")
}
NotificationCenter.default.post(name: Statistics.updated, object: nil)
Expand Down Expand Up @@ -130,10 +134,13 @@ class Statistics {
private func getVersion() -> Int32 {
let sql = "PRAGMA user_version"
var stmt: OpaquePointer?
if sqlite3_prepare_v2(database, sql, -1, &stmt, nil) == SQLITE_OK
&& sqlite3_step(stmt) == SQLITE_ROW {
return sqlite3_column_int(stmt, 0)
if sqlite3_prepare_v2(database, sql, -1, &stmt, nil) == SQLITE_OK,
sqlite3_step(stmt) == SQLITE_ROW {
let version = sqlite3_column_int(stmt, 0)
sqlite3_finalize(stmt)
return version
}
sqlite3_finalize(stmt)
return 0
}

Expand Down
1 change: 1 addition & 0 deletions Fire/types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ extension Defaults.Keys {
"inputModeTipWindowType",
default: InputModeTipWindowType.centerScreen
)
static let showInputModeStatus = Key<Bool>("showInputModeStatus", default: true)

// 主题
static let themeConfig = Key<ThemeConfig>("themeConfig", default: defaultThemeConfig)
Expand Down

0 comments on commit 49569a7

Please sign in to comment.