From a50232f06cf02dd8eccd81352d9cf72a01eae576 Mon Sep 17 00:00:00 2001 From: Jia Sui Date: Mon, 28 Sep 2026 18:28:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(engine):=20set=5Fwubi=5Fmixed=5Fpinyin=20?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E5=A4=8D=E4=BD=8D=20z=20=E9=80=9A=E9=85=8D?= =?UTF-8?q?=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- engine/core/ime_session.h | 4 ++++ engine/core/input_session.cpp | 5 +++++ engine/core/input_session.h | 3 +++ engine/core/session.cpp | 5 ++++- .../tests/src/test_wubi_mixed_input_session.cpp | 17 +++++++++++++++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/engine/core/ime_session.h b/engine/core/ime_session.h index e9fb4bdf..726200ec 100644 --- a/engine/core/ime_session.h +++ b/engine/core/ime_session.h @@ -36,6 +36,10 @@ class ImeSession rescoring_context_ = std::move(context); } void set_wubi_input_options(metasequoia::WubiInputOptions options); + const metasequoia::WubiInputOptions &wubi_input_options() const + { + return wubi_options_; + } void replace_shuangpin_raw_input(const std::string &raw_input, const std::string &raw_input_with_cases); void replace_quanpin_raw_input(const std::string &raw_input, const std::string &raw_input_with_cases); void replace_wubi_raw_input(const std::string &raw_input, const std::string &raw_input_with_cases); diff --git a/engine/core/input_session.cpp b/engine/core/input_session.cpp index 38bdffd6..71d8b155 100644 --- a/engine/core/input_session.cpp +++ b/engine/core/input_session.cpp @@ -474,6 +474,11 @@ void InputSession::set_wubi_input_options(metasequoia::WubiInputOptions options) } } +const metasequoia::WubiInputOptions &InputSession::wubi_input_options() const +{ + return engine_.wubi_input_options(); +} + const MixedExpressiveOptions &InputSession::mixed_expressive_options() const { return mixed_expressive_options_; diff --git a/engine/core/input_session.h b/engine/core/input_session.h index bf028e38..aa9cfbb7 100644 --- a/engine/core/input_session.h +++ b/engine/core/input_session.h @@ -68,6 +68,9 @@ class InputSession const EnglishInputOptions &english_input_options() const; void set_mixed_expressive_options(MixedExpressiveOptions options); void set_wubi_input_options(metasequoia::WubiInputOptions options); + // 读回当前五笔设置:公开 Session 的运行期开关要按字段改,不能整份覆盖(否则会把另一个 + // 独立开关复位)。 + const metasequoia::WubiInputOptions &wubi_input_options() const; const MixedExpressiveOptions &mixed_expressive_options() const; void set_dedicated_english_mode(bool enabled); bool dedicated_english_mode() const; diff --git a/engine/core/session.cpp b/engine/core/session.cpp index 773874a4..6e43b638 100644 --- a/engine/core/session.cpp +++ b/engine/core/session.cpp @@ -158,7 +158,10 @@ void Session::set_dedicated_english(bool enabled) } void Session::set_wubi_mixed_pinyin(bool enabled) { - impl_->session.set_wubi_input_options(WubiInputOptions{enabled}); + // 只改混输这一个开关:整份构造 WubiInputOptions 会把运行期已生效的 z 通配一起复位。 + metasequoia::WubiInputOptions options = impl_->session.wubi_input_options(); + options.mixed_pinyin = enabled; + impl_->session.set_wubi_input_options(options); } SessionSnapshot Session::snapshot() const { diff --git a/engine/tests/src/test_wubi_mixed_input_session.cpp b/engine/tests/src/test_wubi_mixed_input_session.cpp index ffa1ea3b..0e380d07 100644 --- a/engine/tests/src/test_wubi_mixed_input_session.cpp +++ b/engine/tests/src/test_wubi_mixed_input_session.cpp @@ -331,6 +331,23 @@ int main() require(!matched.snapshot().candidates.empty(), "The four-letter code answered with nothing."); require(matched.snapshot().candidates.front().scheme == SchemeType::Wubi, "A code the wubi table answered was not tagged as wubi."); + + // set_wubi_mixed_pinyin must leave the sibling z-wildcard setting alone: a host that + // enabled wildcard at construction and toggles mixed at runtime keeps wildcard working. + SessionOptions wildcard; + wildcard.paths = prepare_runtime_paths(resources, root / "user-z", root / "cache-z", "v1"); + wildcard.scheme = SchemeType::Wubi; + wildcard.wubi.z_wildcard = true; + Session z_session(wildcard); + z_session.set_wubi_mixed_pinyin(true); + for (const char letter : std::string("wz")) + { + z_session.character(letter); + } + const auto &z_candidates = z_session.snapshot().candidates; + require(std::any_of(z_candidates.begin(), z_candidates.end(), + [](const WordItem &item) { return item.word == "你好"; }), + "Toggling mixed pinyin reset the z wildcard setting."); } } catch (const std::exception &error)