Skip to content

Commit 4eb3946

Browse files
authored
Add a new API setBufferWithRestoreCallback to quickphrase (#1232)
Whenever an input method want to temporarily enter quickphrase, we allow quickphrase to restore to engine, if user change buffer into a specified state.
1 parent c52876d commit 4eb3946

File tree

5 files changed

+80
-6
lines changed

5 files changed

+80
-6
lines changed

src/modules/quickphrase/quickphrase.cpp

+41-6
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ class QuickPhraseState : public InputContextProperty {
4141
InputBuffer buffer_;
4242
QuickPhrase *q_;
4343

44+
std::string originalBuffer_;
45+
QuickPhraseRestoreCallback restoreCallback_;
46+
4447
bool typed_ = false;
4548
std::string text_;
4649
std::string prefix_;
@@ -57,6 +60,8 @@ class QuickPhraseState : public InputContextProperty {
5760
prefix_.clear();
5861
str_.clear();
5962
alt_.clear();
63+
originalBuffer_.clear();
64+
restoreCallback_ = nullptr;
6065
key_ = Key(FcitxKey_None);
6166
ic->inputPanel().reset();
6267
ic->updatePreedit();
@@ -222,18 +227,29 @@ QuickPhrase::QuickPhrase(Instance *instance)
222227
return;
223228
}
224229
if (keyEvent.key().check(FcitxKey_BackSpace)) {
230+
keyEvent.accept();
225231
if (state->buffer_.empty()) {
226232
state->reset(inputContext);
227233
} else {
228234
if (state->buffer_.backspace()) {
235+
if (state->restoreCallback_ &&
236+
state->buffer_.cursor() == state->buffer_.size() &&
237+
state->buffer_.userInput() ==
238+
state->originalBuffer_) {
239+
auto callback = std::move(state->restoreCallback_);
240+
auto original = std::move(state->originalBuffer_);
241+
state->reset(inputContext);
242+
callback(inputContext, original);
243+
return;
244+
}
245+
229246
if (state->buffer_.empty()) {
230247
state->reset(inputContext);
231248
} else {
232249
updateUI(inputContext);
233250
}
234251
}
235252
}
236-
keyEvent.accept();
237253
return;
238254
}
239255
if (keyEvent.key().check(FcitxKey_Delete)) {
@@ -256,28 +272,32 @@ QuickPhrase::QuickPhrase(Instance *instance)
256272
if (key.check(FcitxKey_Home) || key.check(FcitxKey_KP_Home)) {
257273
state->buffer_.setCursor(0);
258274
keyEvent.accept();
259-
return updateUI(inputContext);
275+
updateUI(inputContext);
276+
return;
260277
}
261278
if (key.check(FcitxKey_End) || key.check(FcitxKey_KP_End)) {
262279
state->buffer_.setCursor(state->buffer_.size());
263280
keyEvent.accept();
264-
return updateUI(inputContext);
281+
updateUI(inputContext);
282+
return;
265283
}
266284
if (key.check(FcitxKey_Left) || key.check(FcitxKey_KP_Left)) {
267285
auto cursor = state->buffer_.cursor();
268286
if (cursor > 0) {
269287
state->buffer_.setCursor(cursor - 1);
270288
}
271289
keyEvent.accept();
272-
return updateUI(inputContext);
290+
updateUI(inputContext);
291+
return;
273292
}
274293
if (key.check(FcitxKey_Right) || key.check(FcitxKey_KP_Right)) {
275294
auto cursor = state->buffer_.cursor();
276295
if (cursor < state->buffer_.size()) {
277296
state->buffer_.setCursor(cursor + 1);
278297
}
279298
keyEvent.accept();
280-
return updateUI(inputContext);
299+
updateUI(inputContext);
300+
return;
281301
}
282302
}
283303
if (!state->typed_ && !state->str_.empty() &&
@@ -294,7 +314,8 @@ QuickPhrase::QuickPhrase(Instance *instance)
294314

295315
// compose is invalid, ignore it.
296316
if (!compose) {
297-
return event.accept();
317+
event.accept();
318+
return;
298319
}
299320

300321
if (!compose->empty()) {
@@ -539,6 +560,20 @@ void QuickPhrase::setBuffer(InputContext *ic, const std::string &text) {
539560
updateUI(ic);
540561
}
541562

563+
void QuickPhrase::setBufferWithRestoreCallback(
564+
InputContext *ic, const std::string &text, const std::string &original,
565+
QuickPhraseRestoreCallback callback) {
566+
auto *state = ic->propertyFor(&factory_);
567+
if (!state->enabled_) {
568+
return;
569+
}
570+
state->buffer_.clear();
571+
state->buffer_.type(text);
572+
state->originalBuffer_ = original;
573+
state->restoreCallback_ = std::move(callback);
574+
updateUI(ic);
575+
}
576+
542577
class QuickPhraseModuleFactory : public AddonFactory {
543578
AddonInstance *create(AddonManager *manager) override {
544579
return new QuickPhrase(manager->instance());

src/modules/quickphrase/quickphrase.h

+4
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class QuickPhrase final : public AddonInstance {
7878
const std::string &prefix, const std::string &str,
7979
const std::string &alt, const Key &key);
8080
void setBuffer(InputContext *ic, const std::string &text);
81+
void setBufferWithRestoreCallback(InputContext *ic, const std::string &text,
82+
const std::string &original,
83+
QuickPhraseRestoreCallback callback);
8184

8285
std::unique_ptr<HandlerTableEntry<QuickPhraseProviderCallback>>
8386
addProvider(QuickPhraseProviderCallback);
@@ -90,6 +93,7 @@ class QuickPhrase final : public AddonInstance {
9093
FCITX_ADDON_EXPORT_FUNCTION(QuickPhrase, addProvider);
9194
FCITX_ADDON_EXPORT_FUNCTION(QuickPhrase, addProviderV2);
9295
FCITX_ADDON_EXPORT_FUNCTION(QuickPhrase, setBuffer);
96+
FCITX_ADDON_EXPORT_FUNCTION(QuickPhrase, setBufferWithRestoreCallback);
9397

9498
void setSelectionKeys(QuickPhraseAction action);
9599

src/modules/quickphrase/quickphrase_public.h

+10
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ using QuickPhraseAddCandidateCallbackV2 =
4040
using QuickPhraseProviderCallbackV2 =
4141
std::function<bool(InputContext *ic, const std::string &,
4242
const QuickPhraseAddCandidateCallbackV2 &)>;
43+
using QuickPhraseRestoreCallback =
44+
std::function<void(InputContext *ic, const std::string &buffer)>;
4345

4446
} // namespace fcitx
4547

@@ -52,6 +54,14 @@ FCITX_ADDON_DECLARE_FUNCTION(QuickPhrase, trigger,
5254
const std::string &alt, const Key &key));
5355
FCITX_ADDON_DECLARE_FUNCTION(QuickPhrase, setBuffer,
5456
void(InputContext *ic, const std::string &text));
57+
// Set buffer with a restore callback.
58+
// If after "backspace", the current buffer is restore to the original value,
59+
// the callback will be invoked, to allow input method to restore the buffer to
60+
// original state.
61+
FCITX_ADDON_DECLARE_FUNCTION(QuickPhrase, setBufferWithRestoreCallback,
62+
void(InputContext *ic, const std::string &text,
63+
const std::string &original,
64+
QuickPhraseRestoreCallback callback));
5565

5666
FCITX_ADDON_DECLARE_FUNCTION(
5767
QuickPhrase, addProvider,

test/testquickphrase.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "fcitx-utils/macros.h"
1515
#include "fcitx-utils/testing.h"
1616
#include "fcitx/addonmanager.h"
17+
#include "fcitx/inputcontext.h"
1718
#include "fcitx/instance.h"
1819
#include "fcitx/userinterface.h"
1920
#include "quickphrase_public.h"
@@ -194,6 +195,28 @@ void testProviderV2(Instance *instance) {
194195
});
195196
}
196197

198+
void testRestoreCallback(Instance *instance) {
199+
instance->eventDispatcher().schedule([instance]() {
200+
auto *testfrontend = instance->addonManager().addon("testfrontend");
201+
auto uuid =
202+
testfrontend->call<ITestFrontend::createInputContext>("testapp");
203+
auto *ic = instance->inputContextManager().findByUUID(uuid);
204+
auto *quickphrase = instance->addonManager().addon("quickphrase");
205+
quickphrase->call<IQuickPhrase::trigger>(ic, "", "", "", "", Key());
206+
bool restore = false;
207+
quickphrase->call<IQuickPhrase::setBufferWithRestoreCallback>(
208+
ic, "ABC.", "ABC",
209+
[&restore](InputContext * /*ic*/, const std::string &origin) {
210+
FCITX_ASSERT(origin == "ABC");
211+
restore = true;
212+
});
213+
FCITX_ASSERT(!restore);
214+
FCITX_ASSERT(testfrontend->call<ITestFrontend::sendKeyEvent>(
215+
uuid, Key(FcitxKey_BackSpace), false));
216+
FCITX_ASSERT(restore);
217+
});
218+
}
219+
197220
int main() {
198221
setupTestingEnvironment(
199222
FCITX5_BINARY_DIR,
@@ -210,6 +233,7 @@ int main() {
210233
testInit(&instance);
211234
testBasic(&instance);
212235
testProviderV2(&instance);
236+
testRestoreCallback(&instance);
213237
instance.eventDispatcher().schedule([&instance]() {
214238
handle.reset();
215239
instance.exit();

testing/testfrontend/testfrontend_public.h

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define _TESTFRONTEND_TESTFRONTEND_PUBLIC_H_
99

1010
#include <string>
11+
#include <fcitx-utils/key.h>
1112
#include <fcitx/addoninstance.h>
1213
#include <fcitx/inputcontext.h>
1314

0 commit comments

Comments
 (0)