Skip to content

Commit bead4b2

Browse files
authored
use NSStatusItem to indicate im and toggle (#263)
1 parent 9710135 commit bead4b2

File tree

7 files changed

+66
-2
lines changed

7 files changed

+66
-2
lines changed

macosfrontend/macosfrontend.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,31 @@ namespace fcitx {
2626
MacosFrontend::MacosFrontend(Instance *instance)
2727
: instance_(instance),
2828
focusGroup_("macos", instance->inputContextManager()) {
29+
eventHandler_ = instance_->watchEvent(
30+
EventType::InputContextUpdateUI, EventWatcherPhase::Default,
31+
[=, this](Event &event) {
32+
if (auto ic = instance->mostRecentInputContext()) {
33+
auto engine = instance->inputMethodEngine(ic);
34+
auto entry = instance->inputMethodEntry(ic);
35+
std::string display;
36+
if (engine) {
37+
auto subModeLabel = engine->subModeLabel(*entry, *ic);
38+
auto name =
39+
entry->label().empty() ? entry->name() : entry->label();
40+
if (subModeLabel.empty()) {
41+
display = std::move(name);
42+
} else {
43+
display = std::move(subModeLabel);
44+
}
45+
} else {
46+
display = "🐧";
47+
}
48+
if (statusItemText != display) {
49+
statusItemText = std::move(display);
50+
SwiftFrontend::setStatusItemText(statusItemText);
51+
}
52+
}
53+
});
2954
reloadConfig();
3055
}
3156

macosfrontend/macosfrontend.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ class MacosFrontend : public AddonInstance {
9191
static const inline std::string ConfPath = "conf/macosfrontend.conf";
9292

9393
FocusGroup focusGroup_; // ensure there is at most one active ic
94-
std::vector<std::unique_ptr<HandlerTableEntry<EventHandler>>>
95-
eventHandlers_;
94+
std::unique_ptr<HandlerTableEntry<EventHandler>> eventHandler_;
95+
std::string statusItemText;
9696

9797
inline MacosInputContext *findIC(ICUUID);
9898
void useAppDefaultIM(const std::string &appId);

macosfrontend/macosfrontend.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ public func setController(_ ctrl: Any) {
1414
controller = ctrl as? IMKInputController
1515
}
1616

17+
private var statusItemCallback: ((String) -> Void)? = nil
18+
19+
public func setStatusItemCallback(_ callback: @escaping (String) -> Void) {
20+
statusItemCallback = callback
21+
}
22+
23+
public func setStatusItemText(_ text: String) {
24+
statusItemCallback?(text)
25+
}
26+
1727
private func commitString(_ client: IMKTextInput, _ string: String) {
1828
client.insertText(string, replacementRange: NSRange(location: NSNotFound, length: NSNotFound))
1929
}

src/controller.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ class FcitxInputController: IMKInputController {
4343
// Do not clear in deinit, otherwise it will crash with
4444
// "Simultaneous accesses to 0x100e05650, but modification requires exclusive access."
4545
setController(self)
46+
setStatusItemCallback { text in
47+
// No concrete evidence that this needs to be on main thread but just to be safe.
48+
DispatchQueue.main.async {
49+
if let button = AppDelegate.statusItem?.button {
50+
button.title = text
51+
}
52+
}
53+
}
4654
}
4755

4856
deinit {
@@ -320,3 +328,7 @@ struct FcitxAction: Codable {
320328
return items
321329
}
322330
}
331+
332+
func toggleInputMethod() {
333+
Fcitx.toggleInputMethod()
334+
}

src/fcitx-public.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ void imSetGroups(const char *json) noexcept;
2929

3030
std::string imGetCurrentIMName() noexcept;
3131
void imSetCurrentIM(const char *imName) noexcept;
32+
void toggleInputMethod() noexcept;
3233

3334
// Returns a json array of Input Methods.
3435
// type InputMethod := {uniqueName:str, name:str, nativeName:str,

src/fcitx.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,10 @@ void imSetCurrentIM(const char *imName) noexcept {
357357
[=](Fcitx &fcitx) { fcitx.instance()->setCurrentInputMethod(imName); });
358358
}
359359

360+
void toggleInputMethod() noexcept {
361+
return with_fcitx([=](Fcitx &fcitx) { return fcitx.instance()->toggle(); });
362+
}
363+
360364
std::string imGetCurrentIMName() noexcept {
361365
return with_fcitx(
362366
[=](Fcitx &fcitx) { return fcitx.instance()->currentInputMethod(); });

src/server.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,20 @@ private func signalHandler(signal: Int32) {
3939
class AppDelegate: NSObject, NSApplicationDelegate {
4040
static var server = IMKServer()
4141
static var notificationDelegate = NotificationDelegate()
42+
static var statusItem: NSStatusItem?
4243

4344
func applicationDidFinishLaunching(_ notification: Notification) {
4445
redirectStderr()
4546

4647
signal(SIGTERM, signalHandler)
4748

49+
AppDelegate.statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
50+
51+
if let button = AppDelegate.statusItem?.button {
52+
button.action = #selector(handleStatusItemClick)
53+
button.target = self
54+
}
55+
4856
AppDelegate.server = IMKServer(
4957
name: Bundle.main.infoDictionary?["InputMethodConnectionName"] as? String,
5058
bundleIdentifier: Bundle.main.bundleIdentifier)
@@ -59,4 +67,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
5967
func applicationWillTerminate(_ notification: Notification) {
6068
stop_fcitx_thread()
6169
}
70+
71+
@objc func handleStatusItemClick() {
72+
toggleInputMethod()
73+
}
6274
}

0 commit comments

Comments
 (0)