Skip to content

Commit 0e791a3

Browse files
committed
implement commitComposition to distinguish switch app and switch abc; fix double commit on switch abc
1 parent e60b1c2 commit 0e791a3

File tree

5 files changed

+40
-36
lines changed

5 files changed

+40
-36
lines changed

macosfrontend/macosfrontend-public.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ ICUUID create_input_context(const char *appId, id client,
1515
const char *accentColor) noexcept;
1616
void destroy_input_context(ICUUID uuid) noexcept;
1717
void focus_in(ICUUID uuid, bool isPassword) noexcept;
18-
std::string focus_out(ICUUID uuid) noexcept;
18+
std::string commit_composition(ICUUID uuid) noexcept;
19+
void focus_out(ICUUID uuid) noexcept;

macosfrontend/macosfrontend.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,7 @@ std::string MacosFrontend::keyEvent(ICUUID uuid, const Key &key, bool isRelease,
141141
auto timeEventPtr = timeEvent.release();
142142
}
143143

144-
auto state = ic->getState(keyEvent.accepted());
145-
ic->resetState();
146-
return state;
144+
return ic->popState(keyEvent.accepted());
147145
}
148146

149147
MacosInputContext *MacosFrontend::findIC(ICUUID uuid) {
@@ -212,7 +210,7 @@ void MacosFrontend::focusIn(ICUUID uuid, bool isPassword) {
212210
useAppDefaultIM(program);
213211
}
214212

215-
std::string MacosFrontend::focusOut(ICUUID uuid) {
213+
std::string MacosFrontend::commitComposition(ICUUID uuid) {
216214
auto *ic = findIC(uuid);
217215
if (!ic)
218216
return "{}";
@@ -230,13 +228,18 @@ std::string MacosFrontend::focusOut(ICUUID uuid) {
230228
// At this stage panel is still shown. If removed, a following backspace
231229
// will commit a BS character in VSCode.
232230
ic->setDummyPreedit(false);
233-
auto state = ic->getState(false);
231+
auto state = ic->popState(false);
234232
ic->isSyncEvent = false;
235233

234+
return state;
235+
}
236+
237+
void MacosFrontend::focusOut(ICUUID uuid) {
238+
auto *ic = findIC(uuid);
239+
if (!ic)
240+
return;
236241
FCITX_INFO() << "Focus out " << ic->program();
237242
ic->focusOut();
238-
239-
return state;
240243
}
241244

242245
MacosInputContext::MacosInputContext(MacosFrontend *frontend,
@@ -274,13 +277,14 @@ void MacosInputContext::updatePreeditImpl() {
274277
state_.caretPos = preedit.cursor();
275278
}
276279

277-
std::string MacosInputContext::getState(bool accepted) {
280+
std::string MacosInputContext::popState(bool accepted) {
278281
nlohmann::json j;
279282
j["commit"] = state_.commit;
280283
j["preedit"] = state_.preedit;
281284
j["caretPos"] = state_.caretPos;
282285
j["dummyPreedit"] = state_.dummyPreedit;
283286
j["accepted"] = accepted;
287+
resetState();
284288
return j.dump();
285289
}
286290

@@ -345,7 +349,12 @@ void focus_in(ICUUID uuid, bool isPassword) noexcept {
345349
});
346350
}
347351

348-
std::string focus_out(ICUUID uuid) noexcept {
349-
return with_fcitx(
350-
[=](Fcitx &fcitx) { return fcitx.frontend()->focusOut(uuid); });
352+
std::string commit_composition(ICUUID uuid) noexcept {
353+
return with_fcitx([=](Fcitx &fcitx) {
354+
return fcitx.frontend()->commitComposition(uuid);
355+
});
356+
}
357+
358+
void focus_out(ICUUID uuid) noexcept {
359+
with_fcitx([=](Fcitx &fcitx) { return fcitx.frontend()->focusOut(uuid); });
351360
}

macosfrontend/macosfrontend.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ class MacosFrontend : public AddonInstance {
8383
std::string keyEvent(ICUUID, const Key &key, bool isRelease,
8484
bool isPassword);
8585
void focusIn(ICUUID, bool isPassword);
86-
std::string focusOut(ICUUID);
86+
std::string commitComposition(ICUUID uuid);
87+
void focusOut(ICUUID);
8788

8889
private:
8990
Instance *instance_;
@@ -138,7 +139,7 @@ class MacosInputContext : public InputContext {
138139
void setDummyPreedit(bool dummyPreedit) {
139140
state_.dummyPreedit = dummyPreedit;
140141
}
141-
std::string getState(bool accepted);
142+
std::string popState(bool accepted);
142143
// Shows whether we are processing a sync event (mainly key down) that needs
143144
// to return a bool to indicate if it's handled. In this case, commit and
144145
// preedit need to be set in batch synchronously before returning. Otherwise

macosfrontend/macosfrontend.swift

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ private var currentPreedit = ""
66

77
private let zeroWidthSpace = "\u{200B}"
88

9-
public var hasCaret = false
10-
119
private var controller: IMKInputController? = nil
1210

1311
public func setController(_ ctrl: Any) {
@@ -60,16 +58,11 @@ private func setPreedit(_ client: IMKTextInput, _ preedit: String, _ caretPosUtf
6058

6159
public func commitAndSetPreeditSync(
6260
_ client: IMKTextInput, _ commit: String, _ preedit: String, _ caretPos: Int,
63-
_ dummyPreedit: Bool, focusOut: Bool = false
61+
_ dummyPreedit: Bool
6462
) {
6563
if !commit.isEmpty {
6664
commitString(client, commit)
6765
}
68-
// Setting preedit on focus out may cause IMK stall for seconds. High possibility
69-
// to reproduce by having no caret on a Safari page and Cmd+T to open a new Tab.
70-
if focusOut && !hasCaret {
71-
return
72-
}
7366
// Without client preedit, Backspace bypasses IM in Terminal, every key
7467
// is both processed by IM and passed to client in iTerm, so we force a
7568
// dummy client preedit here.
@@ -135,7 +128,6 @@ public func getCaretCoordinates(
135128
forCharacterIndex: followCaret ? (isEnd ? u16pos - 1 : u16pos) : 0,
136129
lineHeightRectangle: &rect)
137130
if rect.width == 0 && rect.height == 0 {
138-
hasCaret = false
139131
return false
140132
}
141133
x.pointee = Double(NSMinX(rect))
@@ -144,6 +136,5 @@ public func getCaretCoordinates(
144136
if followCaret && isEnd {
145137
x.pointee += 10
146138
}
147-
hasCaret = true
148139
return true
149140
}

src/controller.swift

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,24 @@ class FcitxInputController: IMKInputController {
6363
uuid = create_input_context(appId, client, accentColor)
6464
}
6565

66-
func processRes(_ client: IMKTextInput, _ res: String, focusOut: Bool = false) -> Bool {
66+
override func commitComposition(_ sender: Any!) {
67+
guard let client = client as? IMKTextInput else {
68+
return
69+
}
70+
let res = String(commit_composition(uuid))
71+
// Maybe commit and clear preedit synchronously if user switches to ABC by Ctrl+Space.
72+
// For Rime with CapsLock, the result will depend on ascii_composer/switch_key/Caps_Lock instead of fcitx5-rime config.
73+
let _ = processRes(client, res)
74+
}
75+
76+
func processRes(_ client: IMKTextInput, _ res: String) -> Bool {
6777
guard let data = res.data(using: .utf8),
6878
let response = try? JSONDecoder().decode(SyncResponse.self, from: data)
6979
else {
7080
return false
7181
}
7282
commitAndSetPreeditSync(
73-
client, response.commit, response.preedit, response.caretPos, response.dummyPreedit,
74-
focusOut: focusOut)
83+
client, response.commit, response.preedit, response.caretPos, response.dummyPreedit)
7584
return response.accepted
7685
}
7786

@@ -181,26 +190,19 @@ class FcitxInputController: IMKInputController {
181190
}
182191
}
183192

193+
// activateServer is called when app is in foreground but not necessarily a text field is selected.
184194
override func activateServer(_ client: Any!) {
185195
// overrideKeyboard is needed for pressing space to play in Shotcut.
186196
if let client = client as? IMKTextInput {
187197
client.overrideKeyboard(withKeyboardNamed: "com.apple.keylayout.ABC")
188198
}
189-
// activateServer is called when app is in foreground but not necessarily a text field is selected.
190-
hasCaret = false
191199
// Make sure status bar is updated on click password input, before first key event.
192200
let isPassword = getSecureInputInfo(isOnFocus: true)
193201
focus_in(uuid, isPassword)
194202
}
195203

196204
override func deactivateServer(_ client: Any!) {
197-
guard let client = client as? IMKTextInput else {
198-
return
199-
}
200-
let res = String(focus_out(uuid))
201-
// Maybe commit and clear preedit synchronously if user switches to ABC by Ctrl+Space.
202-
let _ = processRes(client, res, focusOut: true)
203-
hasCaret = false
205+
focus_out(uuid)
204206
}
205207

206208
override func menu() -> NSMenu! {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy