Commit Graph

19 Commits

Author SHA1 Message Date
4ac0625c6b wl: the input-method frontend
zwp_input_method_v2 over one connection, in one process: activate,
deactivate and content type applied at done, whose count is the serial a
commit must carry.  The keyboard is grabbed at every activate and
released at every deactivate, because sway hands keys to the grab holder
without asking whether the input method is active, and a grab held while
inactive would take every key in the session.  Keys come as evdev codes,
go through xkb and the Compose table the other frontends already share,
and reach the engine as an ipckeysym and a modifier mask; the grab's
modifiers go on to the virtual keyboard as well, since wlroots derives no
state from a virtual keyboard's own keys.  A key the engine does not eat
goes back as a key, not as text, and whatever is still down is released
when the context goes.  A password or a PIN purpose never reaches the
engine at all.

No popup yet: the X11 one still owns drawc, and with no Keycaret from us
it follows the pointer.

Checked by hand under headless sway 1.12 with a GTK3 entry driven by
wtype: ascii passes through, Ctrl+s selects Korean, rk shows the preedit
and Enter commits 가 and lets the Return on, Ctrl+c arrives with its
modifier, focus moving between two clients re-grabs and keeps typing, a
password entry types literally, a second strans says so and stops, and
WAYLAND_DISPLAY without a compositor falls back to XIM.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 19:17:27 +09:00
ef7fb627c6 compose: one Compose table for the XIM and IBus frontends
An IBus client throws away a dead key its engine did not take — the GTK
module's own comment says so, and Qt does the same — so é and ü were
lost in every IBus application, while XIM composed them with a table of
its own.  That table moves to compose.c, which both frontends now use;
xim.c is the shorter for it.

A finished sequence is text, not a key: the engine is asked to hand back
what it had pending, and the composed text follows it, so the composed
character can no longer land before the syllable typed before it.
2026-08-17 12:16:07 +09:00
abaea77248 engine: look dictionaries up synchronously
The dictionary thread ran in imthread's own proc, so a lookup could
only start once the engine blocked, and it was a trie probe anyway; the
emoji and Hanja searches already called dictlookup directly. The
request/result channels, sequence numbers, staleness checks and the
second draw per Japanese key are gone; dictqjp fills the candidates
in place. Emit.dict and Lang.dictq only ever triggered lookups for
Vietnamese, which has no dictionary. dictlookup(Lang*, key, out, max)
returns the count. The Hanja lookup no longer pre-checks for a single
syllable; a reading either has an entry or it does not.
2026-08-16 16:02:09 +09:00
c7718ece52 data: one trie for maps and dictionaries, one loader
The hash map served a single exact-match lookup that the trie already
answers, at the price of a second container, a second file loader with
its own drift, and a Str-to-UTF-8 conversion on every chain probe. The
files are small (kanji.dict is 7.5k lines), so the trie holds both.
trieopen validates keys and each space-separated value word against Str
and reports path:line; trielookup takes the Str every caller holds and
treats a nil trie as an unloaded map; trienew/trieput exist for tests.
The overflow guards on growth, Trie.root (always 0) and the per-language
init loop written twice are gone.
2026-08-16 15:56: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
a637f457f7 fix(xim): honor reset and X11 keyboard state 2026-08-14 22:34:37 +09:00
4e07699460 xim: run server inside strans 2026-08-14 16:16:27 +09:00
08369e718e popup: use system fonts exclusively 2026-08-14 15:17:00 +09:00
335783ebe5 daemon: claim ipc endpoint before ibus publication 2026-08-14 01:02:17 +09:00
e01a991de4 remove: drop Wayland frontend 2026-08-13 21:25:12 +09:00
f46d51b539 renderer: use direct FreeType with explicit font files 2026-08-13 20:40:38 +09:00
91931196e2 refactor: simplify the Plan 9 runtime loop 2026-08-12 17:26:55 +09:00
368e6adcd4 fix: keep the headless daemon running 2026-08-12 16:22:58 +09:00
103f2ec448 fix: harden small core containers 2026-08-12 15:54:16 +09:00
7629ec5fe8 add wayland support 2026-05-28 17:28:47 +09:00
3a203766d5 add ibus supprot 2026-05-28 15:17:31 +09:00
884ba56619 optimize rendering 2026-02-08 18:10:21 +09:00
874b941439 add emoji font.
fix: 97ae9b1709
2025-12-28 19:50:38 +09:00
dcd1147638 first commit 2025-12-23 20:21:56 +09:00