18 Commits

Author SHA1 Message Date
74607afef8 test: the take-back byte is read back off the wire
ipc_response_fragmented_and_truncated already packed del = 2 and sent
the frame a byte at a time; it checked the commit and the preedit and
never looked at the field the v2 wire was widened for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 16:17:27 +09:00
910bf51347 ipc, srv, gtk: the client's text goes over and a take-back comes back
The engine can reach a Hanja reading back into the text the client
already holds, but only if the frontend hands that text over and can
take some of it away again.  GTK 3 has both: retrieve-surrounding
brings the text around the cursor and delete-surrounding removes runes
before it, and a widget that answers neither leaves the text empty, so
nothing is ever reached into or taken from it.

The wire grows a control frame for the text, sent like the caret only
when it changes, and one byte in every response for the runes to take
back.  That byte moves the length fields along, so the version goes to
2: an old daemon and a new module, either way round, fail the handshake
and the module falls through to GtkIMContextSimple rather than misread
a frame.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 14:31:31 +09:00
88ad5f7630 engine: the one capability is a flag
Cclientpreedit was a one-bit mask that every producer set as "want ?
Cclientpreedit : 0" and every consumer masked out again; nothing else
was ever going to join it.  Keyreq carries clientpre, an int that says
whether the client draws the preedit, and the engine and the XIM
context keep it under that name.
2026-08-17 10:57:15 +09:00
33023d7f51 ipc: a modifier keysym is no key
Shift, Control, and their kin were mapped to special keys that the
engine then had a range and a check to ignore, and the GTK module made a
round trip to the daemon for each press.  ipckeysym maps them to key 0,
which was already the "no key" every frontend and the engine skip;
Kmodfirst, Kmodlast, and ismodkey go.
2026-08-17 10:56:03 +09:00
97a838eda1 engine: the Japanese keyboard's own keys; keypad arrows move through candidates
半角/全角, ひらがな/カタカナ, 変換, and 無変換 committed the reading and did
nothing, like any function key.  They now stand for what a Japanese
keyboard means by them: toggling Japanese and English, switching kana
modes, converting (or turning Japanese on), and turning it off; the
Korean keys became a switch of the same shape.  The keypad's arrows
and page keys, with NumLock off, fold onto the plain ones as its Enter
and Tab already did.
2026-08-17 01:29:07 +09:00
333300b297 ipc: fold Shift+Tab and the keypad Enter and Tab onto Tab and Enter
Shift+Tab arrives from every frontend as ISO_Left_Tab (0xfe20), which
has no Unicode value and lies outside the function keysym range, so
ipckeysym gave key 0 and the documented Shift-Tab wrap through search
results never reached the engine; GTK moved focus instead. KP_Enter and
KP_Tab likewise became unknown special keys, so the keypad Enter
committed the reading and passed a newline instead of taking the
highlighted candidate.
2026-08-16 20:22:17 +09:00
795f11be22 test: one engine pump and one preedit check for the white-box suites
server_test, ibus_test and xim_adapter_test each ran their own copy of
the same alt loop that stands in for imthread, and two of them had
private checkstr/checkenginepreedit variants. test_util.c now provides
Pump (trace, optional hold on a chosen op, stop) in its own proc so a
test may block in socket I/O while the engine runs, and test.h declares
the engine hooks once; every .c includes dat.h and fn.h itself as the
rest of the tree does. server_test's three copies of fixture setup and
teardown became serverbegin/serverend.
2026-08-16 16:30:32 +09:00
eb0f88f764 ipc: strip machinery no peer uses; keep client state in one Keyreq
ipc.c: an AF_UNIX nonblocking connect completes at once or fails with
EAGAIN, so the EINPROGRESS/poll/SO_ERROR path and the fcntl juggling
were dead; the deadline plumbing checked a clock that cannot fail and
re-tested the deadline before every transfer although only waitfd
blocks; readfield's truncation and discard loop served the unit test,
since every caller owns char[Ipcfieldmax+1]; NULL-argument checks on
in-tree encoders are gone (peer validation stays). The primary key frame
is Ipckey, not 'legacy'; ipckeysym names the keysym mapping.

srv.c: the per-connection capability and caret already lived in the
persistent Keyreq; the mirror locals and 'negotiated' flag guarded a
protocol rule no client relied on. proccreate never fails in libthread.

gtk: focus-out no longer round-trips a reset before closing the socket
that releases the engine; the caret dedup compares the packed frame;
srvconnect's preedit no-ops and the insimple flag are gone.
2026-08-16 15:53:08 +09:00
43b469f70b ipc: share one keysym and modifier mapping across frontends
The keysym-to-engine-key rule lived in ibus.c, xim/xim.c and gtk/main.c,
and the copies disagreed: GTK sent keypad digits as special keys while
IBus and XIM sent '1'..'9'. Modifiers were rebuilt bit by bit in two
places although Mmask already is the X core layout; only the virtual
Super bit (26) that GDK and IBus set needs folding. ipckey/ipcmod in
ipc.c serve the daemon, the module and the tests.
2026-08-16 15:47:47 +09:00
8df43cecd8 fix(ipc): reject unconnected backlog clients 2026-08-14 22:46:29 +09:00
534ddcd9bb fix(ipc): preserve legacy preedit and bound client waits 2026-08-14 22:17:59 +09:00
6a58b63223 ipc: negotiate preedit capability and caret messages 2026-08-14 18:53:14 +09:00
a03efcf6bf test: cover IPC response framing 2026-08-12 16:11:22 +09:00
432df3730c fix: harden the per-user IPC endpoint 2026-08-12 16:08:23 +09:00
5ba5cf209c fix: assign one active engine owner 2026-08-12 15:41:46 +09:00
2ae87a3926 emoji: repair one-shot candidate selection 2026-08-12 02:08:01 +09:00
82276bf37f strengthen core unit tests
Add table-driven dictionary miss and language-switch state coverage, regress stale candidates after backspace, and clear them before dictionary refresh. Keep IPC and runtime-created file checks outside the unit runner.
2026-08-11 21:12:23 +09:00
42823420ab add focused unit and map checks 2026-08-11 19:35:11 +09:00