fix(fcitx5): Fallback sang preedit mode cho sandbox apps (Flatpak/Snap) — Fix #18#19
fix(fcitx5): Fallback sang preedit mode cho sandbox apps (Flatpak/Snap) — Fix #18#19dvchd wants to merge 3 commits into
Conversation
…ndingText Flatpak/Snap apps (e.g. OnlyOffice Flathub, Firefox snap) do not support the SurroundingText capability due to sandboxing. Previously, the direct commit mode would call commitString() for every keystroke but could not call deleteSurroundingText() to correct previously committed characters. This caused doubled characters: e.g. typing 'tieeng' produced 'Goõ tieengếng Vieêệt' instead of 'Gõ tiếng Việt'. Fix: at runtime, detect missing SurroundingText capability and route these apps through the existing preedit mode (same code path used for terminal emulators). Preedit mode maintains an internal buffer and only calls commitString() when a word boundary is reached, ensuring characters are committed atomically without needing deleteSurroundingText. Additionally, updatePreeditDisplay() now also sets server-side preedit (setPreedit) alongside client-side preedit (setClientPreedit), so apps that don't support ClientPreedit still see feedback via the Fcitx5 panel. Fixes: marixdev#18 See-also: marixdev#18
📝 WalkthroughWalkthroughUpdated vnkey-fcitx5 input handling: preedit display now updates both client and editor preedit, and character/backspace processing computes surrounding-text capability to choose between preedit-buffer maintenance or direct-commit flows, with capability-guarded deletion and warning logs when surrounding text is unavailable. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@vnkey-fcitx5/src/vnkey-fcitx5.cpp`:
- Around line 1073-1074: Remove the redundant redeclaration of hasSurrounding
inside the same if-block: keep the initial declaration "bool hasSurrounding =
ic_->capabilityFlags().test(CapabilityFlag::SurroundingText);" (used with
usePreedit and isTerminal_) and delete the second declaration later in the block
(the duplicate that causes redeclaration); ensure subsequent code uses the
original hasSurrounding variable and adjust references if necessary.
- Around line 873-886: commitPreedit currently clears only the internal preedit_
but leaves the server-side inputPanel preedit visible; update commitPreedit to
call ic_->inputPanel().setPreedit(Text()) (or
ic_->inputPanel().setPreedit(Text()) followed by ic_->updatePreedit() for
safety) so the panel is explicitly cleared when committing, referencing the
commitPreedit function, the preedit_ member, and
inputPanel().setPreedit()/updatePreedit() calls to locate and modify the code.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1249f52b-36ee-4931-b56d-d89ee1345a1f
📒 Files selected for processing (1)
vnkey-fcitx5/src/vnkey-fcitx5.cpp
The direct commit code path already has hasSurrounding declared earlier in the same function scope (line 1073). Remove the duplicate declaration at line 1108 to fix compilation error.
1e9ad52 to
2849ff8
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
vnkey-fcitx5/src/vnkey-fcitx5.cpp (1)
874-885:⚠️ Potential issue | 🟠 MajorClear the server-side preedit when
commitPreedit()finishes.Lines 874 and 885 now populate
ic_->inputPanel().setPreedit(...), butfcitx::VnKeyState::commitPreedit(bool)still only clearspreedit_. In the sandbox path this leaves the last composition visible in the Fcitx panel after a commit until some laterupdatePreeditDisplay()orreset()happens.Please clear the panel-side preedit inside
fcitx::VnKeyState::commitPreedit(bool)as soon aspreedit_is emptied, or callupdatePreeditDisplay()immediately afterpreedit_.clear().🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@vnkey-fcitx5/src/vnkey-fcitx5.cpp` around lines 874 - 885, In fcitx::VnKeyState::commitPreedit(bool) you currently only clear the internal preedit_ buffer; update the server-side panel immediately as well by clearing the input panel preedit when preedit_ is emptied (e.g. call ic_->inputPanel().setPreedit(Text()) and/or ic_->inputPanel().setClientPreedit(Text()) or simply invoke updatePreeditDisplay() right after preedit_.clear()); ensure the change occurs in commitPreedit so sandboxed apps using server-side preedit no longer show the last composition after commit.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@vnkey-fcitx5/src/vnkey-fcitx5.cpp`:
- Around line 874-885: In fcitx::VnKeyState::commitPreedit(bool) you currently
only clear the internal preedit_ buffer; update the server-side panel
immediately as well by clearing the input panel preedit when preedit_ is emptied
(e.g. call ic_->inputPanel().setPreedit(Text()) and/or
ic_->inputPanel().setClientPreedit(Text()) or simply invoke
updatePreeditDisplay() right after preedit_.clear()); ensure the change occurs
in commitPreedit so sandboxed apps using server-side preedit no longer show the
last composition after commit.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b88c8211-5f6f-443e-8705-ac4133ede282
📒 Files selected for processing (1)
vnkey-fcitx5/src/vnkey-fcitx5.cpp
After committing preedit text, also clear both client-side (setClientPreedit) and server-side (setPreedit) inputPanel preedit to prevent stale text from lingering on the Fcitx5 panel. This is particularly important for sandbox apps (Flatpak/Snap) that don't support ClientPreedit and rely on the server-side preedit display.
CodeRabbit Review ResponseFinding 1:
|
🧪 Bài kiểm thử tích hợp tự động (Cấp độ 2+)Mình đã tạo 2 nhánh test riêng biệt để chứng minh bug tồn tại và fix hoạt động đúng, tách bạch rõ ràng. 📂 Hai nhánh test
🔴 Nhánh
|
| # | Bộ test | Kết quả |
|---|---|---|
| 1 | Sandbox == Normal (7 từ Telex) | ✅ byte-identical |
| 2 | Issue #18: câu nhiều từ | ✅ 34 bytes, match |
| 3 | Sandbox: 0 deleteSurroundingText | ✅ an toàn |
| 4 | Normal: vẫn dùng deleteSurroundingText | ✅ không ảnh hưởng |
| 5 | Backspace trong sandbox | ✅ |
| 6 | commitPreedit xóa cả 2 kênh | ✅ |
| 7 | Terminal == Sandbox | ✅ |
| 8 | UTF-8 integrity | ✅ |
| 9 | Word boundary commit | ✅ |
cd tests/sandbox && make test # trên nhánh test/after-fix🏗 Kiến trúc test
test/before-fix (master)
└── SandboxSimulator → mô phỏng code CŨ → output SAI (bug confirmed)
└── Gọi deleteSurroundingText() → silent fail → ký tự nhân đôi
test/after-fix (fix branch)
├── FixedSandboxSimulator → mô phỏng code MỚI → output ĐÚNG (fix verified)
│ └── Fallback sang preedit mode → không gọi deleteSurroundingText()
└── Fix code trong vnkey-fcitx5.cpp (3 commits)
Cả hai nhánh đều link tới thật libvnkey_engine.a (Rust FFI staticlib) — engine không bị mock.
Vấn đề
Issue: #18 — Không gõ được tiếng Việt trên Gnome Ubuntu 25.10
Khi dùng VnKey Fcitx5 với các ứng dụng chạy trong sandbox (Flatpak/Snap) như OnlyOffice Flathub 9.3.1 hay Firefox snap 149, bộ gõ không hoạt động đúng. Kết quả gõ bị nhân đôi ký tự: gõ
tieengratieengếngthay vìtiếng.Nguyên nhân (Root Cause)
Fcitx5 addon sử dụng 2 chế độ xử lý phím:
deleteSurroundingText()để sửa ký tự cũ khi engine yêu cầu backspace.commitString()khi hoàn thành từ.Flatpak/Snap sandbox cách ly Input Context, khiến capability
SurroundingTextkhông khả dụng. Direct commit mode gọicommitString()cho mỗi keystroke nhưng không thể gọideleteSurroundingText()→ ký tự cũ không bị xóa → nhân đôi.Giải pháp đã áp dụng (Fix 3 — Runtime capability check)
Tại runtime, kiểm tra capability
SurroundingTextcủa Input Context. Nếu thiếu, tự động chuyển sang preedit mode (code path đã có sẵn cho terminal emulators).Thay đổi trong
vnkey-fcitx5.cpp:SurroundingText, fallback sang preedit modeupdatePreeditDisplay(): Thêm server-sidesetPreedit()song song vớisetClientPreedit(), giúp app không hỗ trợ client preedit vẫn thấy feedback qua Fcitx5 panelcommitPreedit(): Clear cả client-side và server-side preedit panel sau khi commit text, tránh text cũ sót lại trên Fcitx5 panel (đặc biệt quan trọng cho sandbox apps chỉ dùng server-side preedit)Ưu điểm: Tự động — không cần hardcode tên app, ít thay đổi code, tái dụng code path đã kiểm chứng.
Các phương án dự phòng đã cân nhắc
/snap/,/.flatpak-info)forwardKey()khi thiếu SurroundingTextreset()mỗi lần→ Fix 3 được chọn vì nó tự động, an toàn, và tận dụng code đã có.
Testing
Automated
vnkey-engine(Rust): 38/38 integration tests passedvnkey-fcitx5(C++): Build thành cônglibvnkey.so— 0 warnings, 0 errorsManual test (cần thực hiện trên Ubuntu + Fcitx5)
cd vnkey-engine && cargo build --releasecd vnkey-fcitx5 && mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && makesudo cp libvnkey.so /usr/lib/x86_64-linux-gnu/fcitx5/ && fcitx5 -r -dtieengs→ nên ratiếngxin chaof→ nên raxin chàoFiles changed
vnkey-fcitx5/src/vnkey-fcitx5.cpp(+32, -6)