Each filter drew its row again from its own input event, and the redraw
took the focused field out of the page and put it back (the routing
header's replaceChildren; the keys filter's whole renderProviders, which
made a new field; the plugins page's draw, which made a new head). An IME
committing while the field was out wrote its text twice.
replaceKeeping (app.js) replaces a box's children but leaves a node
already there in place. The routing header redraws around its filter, the
keys filter redraws its list around the filter instead of the whole
Providers page, and the plugins page keeps one head and one search field
and redraws around them. Everything around each field is still drawn
again, so a language switch, Select, and the counts follow as before.
The cause was found by KuaaMU in #1056, which stopped the routing header
being rebuilt while its shape was the same. That kept a language switch
from reaching the header and left the two sibling filters; this carries
over the diagnosis and fixes all three by not moving the field at all.
Verified: internal/gui/tests/filter-ime.test.cjs types into each field
through an IME in Chromium (CDP Input.imeSetComposition, then
Input.insertText) and by key in WebKit, in en/zh/ja/de at 1100px and
440px: 48/48 pass. Against origin/main's assets 48/48 fail (routing:
'1122', field out 4 times; keys and plugins: field taken out). Reverting
only routing.js, only plugins.js, or only the keys filter's oninput fails
exactly that field's 16 tests. Full GUI suite (both engines): 3326/3350;
the 24 failures (codex-auto-reset, mobile-web, old-webkit,
profile-confirm, purpose-filter, routing-failed-open, session-identity,
text-size) fail the same on origin/main. go build -tags nogui and go test
./internal/gui pass.
Co-authored-by: KuaaMU <KuaaMU@users.noreply.github.com>