Skip to content

Commit

Permalink
fix: 修复菜单栏的中英文状态显示按钮位置不能保存的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
qwertyyb committed Nov 11, 2023
1 parent 2ec5206 commit b45d475
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Fire.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
67C9A0542AB53F79000B5281 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 67C9A0532AB53F79000B5281 /* Sparkle */; };
67C9A0582AB5429B000B5281 /* sqlite3.c in Sources */ = {isa = PBXBuildFile; fileRef = 67C9A0562AB5429B000B5281 /* sqlite3.c */; };
67C9A05B2AB5445E000B5281 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67C9A05A2AB5445E000B5281 /* Security.framework */; };
67F0B0D32AFFC282006F835D /* StatusBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67F0B0D22AFFC282006F835D /* StatusBarController.swift */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand Down Expand Up @@ -116,6 +117,7 @@
67C9A0562AB5429B000B5281 /* sqlite3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sqlite3.c; sourceTree = "<group>"; };
67C9A0572AB5429B000B5281 /* sqlite3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sqlite3.h; sourceTree = "<group>"; };
67C9A05A2AB5445E000B5281 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
67F0B0D22AFFC282006F835D /* StatusBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -203,6 +205,7 @@
45B76CA82AEA6042009AFABD /* PunctuationConversion.swift */,
67C9A0022AB53E83000B5281 /* InputSource.swift */,
67C9A0012AB53E83000B5281 /* MainMenu.xib */,
67F0B0D22AFFC282006F835D /* StatusBarController.swift */,
67C9A0042AB53E83000B5281 /* StatusBar.swift */,
67C9A0082AB53E83000B5281 /* types.swift */,
67C9A0032AB53E83000B5281 /* Utils.swift */,
Expand Down Expand Up @@ -433,6 +436,7 @@
67C9A03C2AB53ED3000B5281 /* StatisticsPane.swift in Sources */,
67C9A0322AB53ED3000B5281 /* CandidatesView.swift in Sources */,
67C9A00B2AB53E83000B5281 /* Utils.swift in Sources */,
67F0B0D32AFFC282006F835D /* StatusBarController.swift in Sources */,
67C9A0402AB53ED3000B5281 /* ApplicationPane.swift in Sources */,
67C9A0132AB53EB0000B5281 /* build.swift in Sources */,
67C9A0422AB53ED3000B5281 /* ThesaurusPane.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion Fire/StatusBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class StatusBar {
private var showInputModeStatusSubscript: AnyCancellable?
private init() {
// 输入法变化时,根据当前选中状态切换显示
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
statusItem = StatusBarController.system.statusItem(autosaveName: "status-indicator", width: NSStatusItem.variableLength)
statusItem.button?.title = ""
statusItem.button?.action = #selector(changeInputMode)
statusItem.button?.target = self
Expand Down
71 changes: 71 additions & 0 deletions Fire/StatusBarController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// StatusItemController.swift
// Battery Thing
//
// Created by Curtis Hard on 14/07/2021.
//

import Foundation
import AppKit

// 实践发现NSStatusItem.autosaveName 在设置 isVisible=false 或 true后,并不能恢复到原来的位置,同下面这个issue
// https://github.com/feedback-assistant/reports/issues/200
// 也是同样使用了这个issue中 @curthard89 的方法来解决这个问题
class StatusBarController: NSObject {
static var system = StatusBarController()

lazy private(set) var items = Set<NSStatusItem>()
private let defaults = UserDefaults.standard

deinit {
for item in items {
removeObserver(autosaveName: item.autosaveName)
}
}

func removeStatusItem(_ item: NSStatusItem) {
items.remove(item)
}

func statusItem(autosaveName: NSStatusItem.AutosaveName,
width: CGFloat) -> NSStatusItem {
// it is important we load the default and then add an observer
// before we ask the os for the item as the item will instantly
// remove the user preference
addObserver(autosaveName: autosaveName)
let item = NSStatusBar.system.statusItem(withLength: width)
items.insert(item)

// this is the line that will cause the bug
item.autosaveName = autosaveName
return item
}


fileprivate func defaultsKey(_ autosaveName: NSStatusItem.AutosaveName) -> String {
return "NSStatusItem Preferred Position \(autosaveName)"
}

fileprivate func addObserver(autosaveName string: NSStatusItem.AutosaveName) {
let options: NSKeyValueObservingOptions = [.new, .old]
defaults.addObserver(self, forKeyPath: defaultsKey(string),
options: options,
context: nil)
}

fileprivate func removeObserver(autosaveName: NSStatusItem.AutosaveName) {
defaults.removeObserver(self, forKeyPath: defaultsKey(autosaveName))
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
// settings .autosaveName on the item after it has been created will
// cause null to be set for the position, this will simply write back
// the old value to the defaults
if let dict = change, dict[.newKey] is NSNull, let oldPosition = dict[.oldKey] {
defaults.set(oldPosition, forKey: keyPath!)
}
}

}

0 comments on commit b45d475

Please sign in to comment.