Skip to content

Commit 2b3633b

Browse files
committed
Explicitly clear the preedit upon reset
Firefox relies on that to function properly. Fixes openvanilla#243
1 parent a869319 commit 2b3633b

1 file changed

Lines changed: 29 additions & 14 deletions

File tree

src/McBopomofo.cpp

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -647,28 +647,43 @@ void McBopomofoEngine::activate(const fcitx::InputMethodEntry& entry,
647647

648648
void McBopomofoEngine::reset(const fcitx::InputMethodEntry& /*unused*/,
649649
fcitx::InputContextEvent& event) {
650+
state_ = std::make_unique<InputStates::Empty>();
651+
652+
fcitx::InputContext* context = event.inputContext();
653+
if (context == nullptr) {
654+
return;
655+
}
656+
657+
// Reset the UI.
658+
context->inputPanel().reset();
659+
context->updateUserInterface(fcitx::UserInterfaceComponent::InputPanel);
660+
661+
// Explicitly reset the preedit when it's focus-out or reset. Force-commit
662+
// any residue upon all other reset events. McBopomofo users expect residue
663+
// to be committed upon IME switch. It would be ideal if focus-out or reset
664+
// also force-commits, but unfortunately different apps handle those two
665+
// events differently. Gnome Terminal force-commits any residue by itself but
666+
// Chrome clears everything. Some apps (e.g. Firefox) even rely on an explicit
667+
// preedit for those events to be handled correctly. Given how this is beyond
668+
// our control, the approach here is likely the most sensible.
650669
if (event.type() == fcitx::EventType::InputContextFocusOut ||
651670
event.type() == fcitx::EventType::InputContextReset) {
652-
// If this is a FocusOutEvent, we let fcitx5 do its own clean up, and so we
653-
// just force the state machine to go back to the empty state. The
654-
// FocusOutEvent will cause the preedit buffer to be force-committed anyway.
655-
//
656-
// Note: We don't want to call enterNewState() with EmptyIgnoringPrevious
657-
// state because we don't want to clean the preedit ourselves (which would
658-
// cause nothing to be force-committed as the focus is switched, and that
659-
// would cause user to lose what they've entered). We don't want to call
660-
// enterNewState() with Empty state, either, because that would trigger
661-
// commit of existing preedit buffer, resulting in double commit of the same
662-
// text.
663-
state_ = std::make_unique<InputStates::Empty>();
664671
keyHandler_->reset();
672+
673+
bool useClientPreedit =
674+
context->capabilityFlags().test(fcitx::CapabilityFlag::Preedit);
675+
if (useClientPreedit) {
676+
context->inputPanel().setClientPreedit(fcitx::Text{});
677+
} else {
678+
context->inputPanel().setPreedit(fcitx::Text{});
679+
}
680+
context->inputPanel().setAuxDown(fcitx::Text{});
681+
context->updatePreedit();
665682
} else {
666-
fcitx::InputContext* context = event.inputContext();
667683
keyHandler_->handleForceCommitAndReset(
668684
[this, context](std::unique_ptr<InputState> next) {
669685
enterNewState(context, std::move(next));
670686
});
671-
state_ = std::make_unique<InputStates::Empty>();
672687
}
673688
}
674689

0 commit comments

Comments
 (0)