Skip to content

Commit 6e22d34

Browse files
committed
Make use of new commitStringWithCursor API
1 parent 2b64744 commit 6e22d34

File tree

13 files changed

+82
-51
lines changed

13 files changed

+82
-51
lines changed

app/src/main/cpp/androidfrontend/androidfrontend.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010

1111
namespace fcitx {
1212

13-
class AndroidInputContext : public InputContext {
13+
class AndroidInputContext : public InputContextV2 {
1414
public:
1515
AndroidInputContext(AndroidFrontend *frontend,
1616
InputContextManager &inputContextManager,
1717
int uid,
1818
const std::string &pkgName)
19-
: InputContext(inputContextManager, pkgName),
19+
: InputContextV2(inputContextManager, pkgName),
2020
frontend_(frontend),
2121
uid_(uid) {
2222
created();
@@ -30,7 +30,11 @@ class AndroidInputContext : public InputContext {
3030
[[nodiscard]] const char *frontend() const override { return "androidfrontend"; }
3131

3232
void commitStringImpl(const std::string &text) override {
33-
frontend_->commitString(text);
33+
frontend_->commitString(text, -1);
34+
}
35+
36+
void commitStringWithCursorImpl(const std::string &text, size_t cursor) override {
37+
frontend_->commitString(text, static_cast<int>(cursor));
3438
}
3539

3640
void forwardKeyImpl(const ForwardKeyEvent &key) override {
@@ -202,8 +206,8 @@ void AndroidFrontend::forwardKey(const Key &key, bool isRelease) {
202206
keyEventCallback(sym, key.states(), Key::keySymToUnicode(sym), isRelease, -1);
203207
}
204208

205-
void AndroidFrontend::commitString(const std::string &str) {
206-
commitStringCallback(str);
209+
void AndroidFrontend::commitString(const std::string &str, const int cursor) {
210+
commitStringCallback(str, cursor);
207211
}
208212

209213
void AndroidFrontend::updateCandidateList(const std::vector<std::string> &candidates, const int size) {

app/src/main/cpp/androidfrontend/androidfrontend.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class AndroidFrontend : public AddonInstance {
1717
Instance *instance() { return instance_; }
1818

1919
void updateCandidateList(const std::vector<std::string> &candidates, const int size);
20-
void commitString(const std::string &str);
20+
void commitString(const std::string &str, const int cursor);
2121
void updateClientPreedit(const Text &clientPreedit);
2222
void updateInputPanel(const Text &preedit, const Text &auxUp, const Text &auxDown);
2323
void releaseInputContext(const int uid);
@@ -77,7 +77,7 @@ class AndroidFrontend : public AddonInstance {
7777
void handleStatusAreaUpdate();
7878

7979
CandidateListCallback candidateListCallback = [](const std::vector<std::string> &, const int) {};
80-
CommitStringCallback commitStringCallback = [](const std::string &) {};
80+
CommitStringCallback commitStringCallback = [](const std::string &, const int) {};
8181
ClientPreeditCallback preeditCallback = [](const Text &) {};
8282
InputPanelCallback inputPanelAuxCallback = [](const fcitx::Text &, const fcitx::Text &, const Text &) {};
8383
KeyEventCallback keyEventCallback = [](const int, const uint32_t, const uint32_t, const bool, const int) {};

app/src/main/cpp/androidfrontend/androidfrontend_public.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <fcitx-utils/key.h>
66

77
typedef std::function<void(const std::vector<std::string> &, const int)> CandidateListCallback;
8-
typedef std::function<void(const std::string &)> CommitStringCallback;
8+
typedef std::function<void(const std::string &, const int)> CommitStringCallback;
99
typedef std::function<void(const fcitx::Text &)> ClientPreeditCallback;
1010
typedef std::function<void(const fcitx::Text &, const fcitx::Text &, const fcitx::Text &)> InputPanelCallback;
1111
typedef std::function<void(const int, const uint32_t, const uint32_t, const bool, const int)> KeyEventCallback;

app/src/main/cpp/androidkeyboard/androidkeyboard.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
#include "androidkeyboard.h"
1212

13-
#define FCITX_KEYBOARD_MAX_BUFFER 20
14-
1513
namespace fcitx {
1614

1715
namespace {
@@ -85,17 +83,17 @@ void AndroidKeyboardEngine::keyEvent(const InputMethodEntry &entry, KeyEvent &ev
8583

8684
// check if we can select candidate.
8785
if (auto candList = inputContext->inputPanel().candidateList()) {
88-
int idx = key.keyListIndex(selectionKeys_);
86+
const int idx = key.keyListIndex(selectionKeys_);
8987
if (idx >= 0 && idx < candList->size()) {
9088
event.filterAndAccept();
9189
candList->candidate(idx).select(inputContext);
9290
return;
9391
}
9492
}
9593

96-
bool validSym = isValidSym(key);
94+
const bool validSym = isValidSym(key);
9795

98-
static KeyList FCITX_HYPHEN_APOS = {Key(FcitxKey_minus), Key(FcitxKey_apostrophe)};
96+
static const KeyList FCITX_HYPHEN_APOS = {Key(FcitxKey_minus), Key(FcitxKey_apostrophe)};
9997
// check for valid character
10098
if (key.isSimple() || validSym) {
10199
// prepend space before input next word
@@ -173,7 +171,7 @@ std::vector<InputMethodEntry> AndroidKeyboardEngine::listInputMethods() {
173171
void AndroidKeyboardEngine::reloadConfig() {
174172
readAsIni(config_, ConfPath);
175173
selectionKeys_.clear();
176-
KeySym syms[] = {
174+
const std::array<KeySym, 10> syms{
177175
FcitxKey_1, FcitxKey_2, FcitxKey_3, FcitxKey_4, FcitxKey_5,
178176
FcitxKey_6, FcitxKey_7, FcitxKey_8, FcitxKey_9, FcitxKey_0,
179177
};
@@ -252,7 +250,7 @@ void AndroidKeyboardEngine::updateCandidate(const InputMethodEntry &entry, Input
252250
results = spell()->call<ISpell::hintForDisplay>(entry.languageCode(),
253251
SpellProvider::Default,
254252
state->buffer_.userInput(),
255-
20);
253+
SpellCandidateSize);
256254
}
257255
auto candidateList = std::make_unique<CommonCandidateList>();
258256
for (const auto &result: results) {
@@ -267,10 +265,10 @@ void AndroidKeyboardEngine::updateCandidate(const InputMethodEntry &entry, Input
267265
}
268266

269267
void AndroidKeyboardEngine::updateUI(InputContext *inputContext) {
270-
auto *state = inputContext->propertyFor(&factory_);
271-
Text preedit(preeditString(inputContext), TextFormatFlag::Underline);
272-
preedit.setCursor(static_cast<int>(state->buffer_.cursorByChar()));
273-
inputContext->inputPanel().setClientPreedit(preedit);
268+
auto [preedit, cursor] = preeditWithCursor(inputContext);
269+
Text clientPreedit(preedit, TextFormatFlag::Underline);
270+
clientPreedit.setCursor(static_cast<int>(cursor));
271+
inputContext->inputPanel().setClientPreedit(clientPreedit);
274272
// we don't want preedit here ...
275273
// if (!inputContext->capabilityFlags().test(CapabilityFlag::Preedit)) {
276274
// inputContext->inputPanel().setPreedit(preedit);
@@ -296,15 +294,15 @@ bool AndroidKeyboardEngine::updateBuffer(InputContext *inputContext, const std::
296294
}
297295

298296
auto &buffer = state->buffer_;
299-
auto preedit = preeditString(inputContext);
297+
auto [preedit, cursor] = preeditWithCursor(inputContext);
300298
if (preedit != buffer.userInput()) {
301299
buffer.clear();
302300
buffer.type(preedit);
303301
}
304302

305303
buffer.type(chr);
306304

307-
if (buffer.size() >= FCITX_KEYBOARD_MAX_BUFFER) {
305+
if (buffer.size() >= MaxBufferSize) {
308306
commitBuffer(inputContext);
309307
return true;
310308
}
@@ -314,11 +312,15 @@ bool AndroidKeyboardEngine::updateBuffer(InputContext *inputContext, const std::
314312
}
315313

316314
void AndroidKeyboardEngine::commitBuffer(InputContext *inputContext) {
317-
auto preedit = preeditString(inputContext);
315+
auto [preedit, cursor] = preeditWithCursor(inputContext);
318316
if (preedit.empty()) {
319317
return;
320318
}
321-
inputContext->commitString(preedit);
319+
if (auto icv2 = dynamic_cast<InputContextV2 *>(inputContext)) {
320+
icv2->commitStringWithCursor(preedit, cursor);
321+
} else {
322+
inputContext->commitString(preedit);
323+
}
322324
resetState(inputContext);
323325
inputContext->inputPanel().reset();
324326
inputContext->updatePreedit();
@@ -330,13 +332,13 @@ bool AndroidKeyboardEngine::supportHint(const std::string &language) {
330332
return hasSpell;
331333
}
332334

333-
std::string AndroidKeyboardEngine::preeditString(InputContext *inputContext) {
335+
std::pair<std::string, size_t> AndroidKeyboardEngine::preeditWithCursor(InputContext *inputContext) {
334336
auto *state = inputContext->propertyFor(&factory_);
335-
return state->buffer_.userInput();
337+
return {state->buffer_.userInput(), state->buffer_.cursorByChar()};
336338
}
337339

338340
void AndroidKeyboardEngine::invokeActionImpl(const InputMethodEntry &entry, InvokeActionEvent &event) {
339-
int cursor = event.cursor();
341+
const int cursor = event.cursor();
340342
auto inputContext = event.inputContext();
341343
auto *state = inputContext->propertyFor(&factory_);
342344
if (event.action() != InvokeActionEvent::Action::LeftClick

app/src/main/cpp/androidkeyboard/androidkeyboard.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ struct AndroidKeyboardEngineState : public InputContextProperty {
5050

5151
class AndroidKeyboardEngine final : public InputMethodEngineV3 {
5252
public:
53+
static int constexpr MaxBufferSize = 20;
54+
static int constexpr SpellCandidateSize = 20;
55+
5356
AndroidKeyboardEngine(Instance *instance);
5457
~AndroidKeyboardEngine() = default;
5558

@@ -100,7 +103,7 @@ class AndroidKeyboardEngine final : public InputMethodEngineV3 {
100103

101104
private:
102105
bool supportHint(const std::string &language);
103-
std::string preeditString(InputContext *inputContext);
106+
std::pair<std::string, size_t> preeditWithCursor(InputContext *inputContext);
104107

105108
Instance *instance_;
106109
AndroidKeyboardEngineConfig config_;

app/src/main/cpp/native-lib.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,12 @@ Java_org_fcitx_fcitx5_android_core_Fcitx_startupFcitx(JNIEnv *env, jclass clazz,
564564
env->SetObjectArrayElement(vararg, 1, *candidatesArray);
565565
env->CallStaticVoidMethod(GlobalRef->Fcitx, GlobalRef->HandleFcitxEvent, 0, *vararg);
566566
};
567-
auto commitStringCallback = [](const std::string &str) {
567+
auto commitStringCallback = [](const std::string &str, const int cursor) {
568568
auto env = GlobalRef->AttachEnv();
569-
auto vararg = JRef<jobjectArray>(env, env->NewObjectArray(1, GlobalRef->String, nullptr));
569+
auto stringCursor = JRef(env, env->NewObject(GlobalRef->Integer, GlobalRef->IntegerInit, cursor));
570+
auto vararg = JRef<jobjectArray>(env, env->NewObjectArray(2, GlobalRef->Object, nullptr));
570571
env->SetObjectArrayElement(vararg, 0, JString(env, str));
572+
env->SetObjectArrayElement(vararg, 1, stringCursor);
571573
env->CallStaticVoidMethod(GlobalRef->Fcitx, GlobalRef->HandleFcitxEvent, 1, *vararg);
572574
};
573575
auto preeditCallback = [](const fcitx::Text &clientPreedit) {

app/src/main/java/org/fcitx/fcitx5/android/core/FcitxEvent.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ sealed class FcitxEvent<T>(open val data: T) {
3535
}
3636
}
3737

38-
data class CommitStringEvent(override val data: String) :
39-
FcitxEvent<String>(data) {
38+
data class CommitStringEvent(override val data: Data) :
39+
FcitxEvent<CommitStringEvent.Data>(data) {
4040
override val eventType: EventType
4141
get() = EventType.Commit
42+
43+
data class Data(val text: String, val cursor: Int)
4244
}
4345

4446
data class ClientPreeditEvent(override val data: FormattedText) :
@@ -157,7 +159,12 @@ sealed class FcitxEvent<T>(open val data: T) {
157159
params[1] as Array<String>
158160
)
159161
)
160-
EventType.Commit -> CommitStringEvent(params[0] as String)
162+
EventType.Commit -> CommitStringEvent(
163+
CommitStringEvent.Data(
164+
params[0] as String,
165+
params[1] as Int
166+
)
167+
)
161168
EventType.ClientPreedit -> ClientPreeditEvent(params[0] as FormattedText)
162169
EventType.InputPanel -> InputPanelEvent(
163170
InputPanelEvent.Data(

app/src/main/java/org/fcitx/fcitx5/android/data/prefs/AppPrefs.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ class AppPrefs(private val sharedPreferences: SharedPreferences) {
3030

3131
inner class Advanced : ManagedPreferenceCategory(R.string.advanced, sharedPreferences) {
3232
val ignoreSystemCursor = switch(R.string.ignore_sys_cursor, "ignore_system_cursor", true)
33-
val resetCursorAfterCommit =
34-
switch(R.string.reset_cursor_after_commit, "reset_cursor_after_commit", true)
3533
val hideKeyConfig = switch(R.string.hide_key_config, "hide_key_config", true)
3634
val disableAnimation = switch(R.string.disable_animation, "disable_animation", false)
3735
val vivoKeypressWorkaround = switch(
@@ -363,7 +361,6 @@ class AppPrefs(private val sharedPreferences: SharedPreferences) {
363361
internal.verboseLog,
364362
internal.editorInfoInspector,
365363
advanced.ignoreSystemCursor,
366-
advanced.resetCursorAfterCommit,
367364
advanced.disableAnimation,
368365
advanced.vivoKeypressWorkaround
369366
).forEach {

app/src/main/java/org/fcitx/fcitx5/android/input/FcitxInputMethodService.kt

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
8585
private var highlightColor: Int = 0x66008577 // material_deep_teal_500 with alpha 0.4
8686

8787
private val ignoreSystemCursor by AppPrefs.getInstance().advanced.ignoreSystemCursor
88-
private val resetCursor by AppPrefs.getInstance().advanced.resetCursorAfterCommit
8988

9089
private val inlineSuggestions by AppPrefs.getInstance().keyboard.inlineSuggestions
9190

@@ -126,7 +125,7 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
126125
private fun handleFcitxEvent(event: FcitxEvent<*>) {
127126
when (event) {
128127
is FcitxEvent.CommitStringEvent -> {
129-
commitText(event.data)
128+
commitText(event.data.text, event.data.cursor)
130129
}
131130
is FcitxEvent.KeyEvent -> event.data.let event@{
132131
if (it.states.virtual) {
@@ -223,24 +222,31 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
223222
}
224223
}
225224

226-
fun commitText(text: String) {
225+
fun commitText(text: String, cursor: Int = -1) {
226+
val ic = currentInputConnection ?: return
227+
val targetCursor = if (cursor == -1) text.length else cursor
228+
val currentCursor = selection.current.start - composing.start
229+
// when composing text equals commit content, finish composing text as-is
227230
if (composing.isNotEmpty() && composingText.toString() == text) {
228-
// when composing text equals commit content, finish composing text as-is
229-
val cursor = composing.end
230-
resetComposingState()
231-
currentInputConnection?.finishComposingText()
232-
if (resetCursor) {
233-
selection.predict(cursor)
234-
currentInputConnection?.setSelection(cursor, cursor)
231+
if (targetCursor != currentCursor) {
232+
val c = composing.start + targetCursor
233+
selection.predict(c)
234+
ic.setSelection(c, c)
235235
}
236+
resetComposingState()
237+
ic.finishComposingText()
236238
return
237239
}
238240
// committed text should replace composing (if any), replace selected range (if any),
239241
// or simply prepend before cursor
240242
val start = if (composing.isEmpty()) selection.latest.start else composing.start
241-
selection.predict(start + text.length)
242243
resetComposingState()
243-
currentInputConnection?.commitText(text, 1)
244+
ic.commitText(text, 1)
245+
if (targetCursor != currentCursor) {
246+
val c = start + targetCursor
247+
selection.predict(c)
248+
ic.setSelection(c, c)
249+
}
244250
}
245251

246252
private fun sendDownKeyEvent(eventTime: Long, keyEventCode: Int, metaState: Int = 0) {
@@ -596,6 +602,18 @@ class FcitxInputMethodService : LifecycleInputMethodService() {
596602
ic.endBatchEdit()
597603
}
598604

605+
/**
606+
* Finish composing text and leave cursor position as-is.
607+
* Also updates internal composing state of [FcitxInputMethodService].
608+
*/
609+
fun finishComposing() {
610+
val ic = currentInputConnection ?: return
611+
if (composing.isEmpty()) return
612+
composing.clear()
613+
composingText = FormattedText.Empty
614+
ic.finishComposingText()
615+
}
616+
599617
@SuppressLint("RestrictedApi")
600618
@RequiresApi(Build.VERSION_CODES.R)
601619
override fun onCreateInlineSuggestionsRequest(uiExtras: Bundle): InlineSuggestionsRequest? {

app/src/main/java/org/fcitx/fcitx5/android/input/keyboard/CommonKeyActionListener.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class CommonKeyActionListener :
5959
reset()
6060
} else if (inputMethodEntryCached.uniqueName.let { it == "keyboard-us" || it == "unikey" }) {
6161
// androidkeyboard clears composing on reset, but we want to commit it as-is
62-
service.currentInputConnection?.finishComposingText()
62+
service.finishComposing()
6363
reset()
6464
} else {
6565
if (!select(0)) reset()

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