Skip to content

fix(linux): C++20 build + FFI ImeResult struct-size fix for the Fcitx5 addon - #409

Open
trongnguyenbinh wants to merge 3 commits into
khaphanspace:mainfrom
trongnguyenbinh:fix/linux-fcitx5-cpp20-abi
Open

fix(linux): C++20 build + FFI ImeResult struct-size fix for the Fcitx5 addon#409
trongnguyenbinh wants to merge 3 commits into
khaphanspace:mainfrom
trongnguyenbinh:fix/linux-fcitx5-cpp20-abi

Conversation

@trongnguyenbinh

Copy link
Copy Markdown

Mô tả

Sửa để bộ gõ chạy đúng trên Linux / Fcitx5 (test trên Ubuntu). Trước đó addon Linux gõ telex không biến đổi ký tự — gõ dd ra dd thay vì đ.

Gồm 2 fix + 1 test, chỉ đụng platforms/linux/ (không thay đổi Rust core hay macOS):

  1. Build C++20platforms/linux/CMakeLists.txt
    Fcitx5 5.1.19 dùng std::source_location + consteval trong macro log (FCITX_*LOG*) → cần C++20; addon đang để C++17 nên không build được. Bump CMAKE_CXX_STANDARD 17 → 20.

  2. FFI struct-size mismatchplatforms/linux/src/RustBridge.{h,cpp}
    Rust core khai ImeResult.chars: [u32; 256] (struct 1028 byte, field actionoffset 1024), nhưng phía C++ khai chars[32] (132 byte, đọc actionoffset 128) → luôn đọc action = 0mọi phím bị passthrough, không convert. Sửa chars[32] → [256], static_assert(132 → 1028), và bỏ giới hạn i < 32 trong vòng copy UTF-8. static_assert cũ chỉ kiểm tra kích thước phía C++ nên mismatch bị "im lặng".

  3. E2E selftestplatforms/linux/selftest.sh + selftest_dbus.py
    Dựng một fcitx5 cô lập qua DBus, bơm chuỗi phím telex bằng ProcessKeyEvent, dựng lại text từ CommitString/DeleteSurroundingText rồi assert. Đây là guard bắt đúng loại lỗi ABI ở (2) — test FFI thuần (chỉ gọi hàm) không bắt được.

Loại thay đổi

  • 🐛 Sửa lỗi

Testing

Test trên Ubuntu (Fcitx5 5.1.19). Build lại trên nhánh main mới nhất của repo gốc → build OK, chạy platforms/linux/selftest.sh:

=== gonhanh telex E2E selftest (live fcitx5 over DBus) ===
  [PASS] 'dd'      -> 'đ'
  [PASS] 'aa'      -> 'â'
  [PASS] 'as'      -> 'á'
  [PASS] 'oo'      -> 'ô'
  [PASS] 'ow'      -> 'ơ'
  [PASS] 'ddaay'   -> 'đây'
  [PASS] 'ddungs'  -> 'đúng'
  [PASS] 'vieejt'  -> 'việt'
  [PASS] 'tieengs' -> 'tiếng'
=== ALL PASS ===

Checklist

  • Đã test end-to-end trên Ubuntu (selftest 9/9 PASS)
  • Không đụng Rust core → cargo test / cargo fmt / cargo clippy không bị ảnh hưởng (chỉ sửa C++ Linux port)
  • CHANGELOG.md — repo hiện chưa có file này nên bỏ qua; maintainer bổ sung nếu cần

Đóng góp từ môi trường Linux (Ubuntu) — mình dùng bộ gõ này với fcitx5 hằng ngày. Nếu maintainer muốn tách nhỏ commit hay chỉnh thêm, mình sẵn sàng.

Trọng Nguyễn and others added 3 commits July 17, 2026 14:10
Fcitx5 5.1.x FCITX_LOGC uses std::source_location + consteval meta-strings
(needs C++20). Building at C++17 failed 'template argument invalid' on the
Engine.cpp log macros. Verified: rebuild produces gonhanh.so cleanly.
The Linux Fcitx5 addon declared the FFI result struct with chars[32]
(132 bytes), but the Rust core's #[repr(C)] Result uses chars: [u32; MAX]
with MAX=256 (1028 bytes). The compile-time static_assert only checked the
C++ side (132), so the mismatch was silent.

Consequence: the addon read `action` at byte offset 128, while Rust writes
it at offset 1024. Every ime_key_ext() result was read as action=0 (None),
so the addon passed every keystroke through untransformed — telex never
converted (e.g. "dd" stayed "dd" instead of becoming "đ").

Fix: chars[256], static_assert(1028), rename _pad -> flags (matches Rust,
carries key_consumed bit), and remove the stale i<32 cap in the UTF-8 copy
loop. Verified via a direct libgonhanh_core FFI harness: dd->đ, aa->â.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds selftest.sh + selftest_dbus.py: a reusable, automated end-to-end test
that drives a REAL fcitx5 + the gonhanh addon over DBus (no human GUI typing).

selftest.sh spins up a private, isolated fcitx5 in its own dbus-run-session
with a throwaway config where gonhanh is the only input method, so it never
touches the user's live input session. selftest_dbus.py creates an input
context, activates gonhanh, injects telex keysyms via ProcessKeyEvent, and
reconstructs the visible text from CommitString / DeleteSurroundingText /
ForwardKey signals plus passthrough keys — then asserts telex->Vietnamese.

Covers dd->đ, aa->â, as->á, oo->ô, ow->ơ, ddaay->đây, ddungs->đúng,
vieejt->việt, tieengs->tiếng. Exit 0 iff all pass. This is the automated
regression guard that would have caught the chars[32] ABI bug (FFI-layer
checks alone missed it).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant