Insert at the caret, line breaks and controls, the maximum length and
surrogate pair boundaries, a clipboard of megabytes, invalid UTF-8, a
paste while no dialog captures the keyboard and while a composition is
shown.
Edit, edit, commit, then discard with Enter and Escape; editing keys
waiting for the input method; cursor and selection offsets counted in
characters and clamped; a composition dropped when the dialog finishes,
closes or is force-closed; malformed and cut preedits. The title's buffer
only ever holds the accepted committed text.
A paste is inserted like typed text: the dialog's maximum length applies
and a cut never splits a surrogate pair, and line breaks are dropped as
they are for typed text.
The dialog registers a preedit sink and keeps the composition in its own
state, shown through the keyboard view and never inserted into the text
or the buffer the title reads. A commit ends it; Enter and Escape discard
it instead of accepting or cancelling; editing keys wait for the input
method. Finishing or closing the dialog drops it.
Add the preedit text with its cursor and selection (UTF-16 offsets into
the preedit) to ImeKeyboardView. Empty means no composition, which leaves
the view as it was.
A dialog has no sceImeOpen session to queue into, so it needs the
composition delivered the way it gets typed text: through a registered
sink. The sink receives the decoded preedit and the cursor and selection
SDL reported, and is only called while no session is open.
Insert at the caret as one update, single-line and multi-line breaks,
control characters, the maximum length and surrogate pair boundaries, the
text filter running once, a clipboard of megabytes, invalid UTF-8, a
paste while nothing captures the keyboard and a paste while the input
method holds a composition.
Add ImePublishPaste, which turns a clipboard into UTF-16 (invalid bytes
replaced, controls stripped, line breaks kept only for a multi-line
session, bounded to 64 KiB) and queues it as one input. It is inserted at
the caret like typed text: one text filter call, one text update event,
the session's maximum length, and a cut that never splits a surrogate
pair. It is ignored while no session or dialog captures the keyboard.
Edit, edit, commit, discard with Escape and Enter, edit keys left to the
input method, a close that drops the composition, and a malformed or cut
preedit. A preedit never reaches the text, the buffers, the filter or the
events.
A sceImeOpen session has no panel to show a composition in, so the
preedit is only tracked: it never enters the text, the input and work
buffers, the text filter or the events the title receives. While one is
active Enter and Escape discard it instead of sending press-enter or
press-close, and the editing keys are left to the input method. A commit
(SDL text input) ends it and is inserted as usual.
A composition (preedit) is text the input method still owns. Keep it
apart from committed text: it records the cursor and selection as UTF-16
offsets converted from the character counts SDL reports, and a routing
function decides what the dialog does with each host input while one is
shown. A commit ends it; Enter and Escape discard it instead of accepting
or cancelling the dialog; editing keys and paste are left to the input
method until it ends.
Add the two kinds and the start and length a composition event carries to
ImeHostInput. Both session and dialog consumers accept them and do nothing
yet, so typed input is unchanged.
Check valid and invalid UTF-8, the incomplete tail of a cut preedit,
control and line-break handling for single-line and multi-line fields,
and that a huge clipboard is bounded without splitting a code point or a
surrogate pair.
The host keyboard path decodes SDL text with a strict decoder that throws,
which suits the 32-byte text events but not text that comes from outside
the window. Add header-only helpers that decode without throwing (invalid
bytes become U+FFFD, an incomplete tail can be dropped for text cut at a
fixed size), strip control characters, normalise line breaks and bound a
clipboard to 64 KiB on a code point boundary.
Run 41245658018 (b9bf246ea2). linux: agc_shader_disk_cache_large_file skips
when the runner has under 3 GiB free and check_skips.py did not list that
reason. windows: guest_timed_wait_cpu aborted on a runner scheduling hiccup
(latency bound exceeded, #13710 made it serial but it is still timing-based).
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Failing run 41243690457 (main daa8d64e45), flaky on main (10 of 56 builds), predates #13581/#13713. The queue worker stores idle results after a 50 ms quiet period; the fixture took the GPU mutex 5 ms after seeing a pending result, so on a loaded runner the real idle store interleaved with the fixture's own staged stores. The two scenarios now retry (10 attempts, cleanup in a destructor); the last attempt still throws its own message.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
#13736 merged the WebRtcOpus encoder functions. Count 390 pending
exports, as the merged Export.cpp has 390 NotImplemented stubs.
Co-Authored-By: Claude Opus 5.5 <[email protected]>