fix: terminal IME raw Latin on Linux (#1375), display-math tag overlap (#1402); v0.9.73 - #1404
Merged
Merged
Conversation
On WebKitGTK with fcitx5, compositionstart never fires (the instrumented trace in #948), so every IME commit arrives as an orphan compositionend. WebKit's Editor::setComposition inserts the confirmed text as insertFromComposition with isComposing=true, then dispatches compositionend with no start guard. Neither the gate's input path nor xterm's _inputEvent takes an insertFromComposition insert, so the orphan end is the only carrier. The gate committed an orphan end's e.data only when it was non-ASCII. Chinese commits got through; the raw Latin text Rime's Enter confirms (claude, raw pinyin) was dropped, and the textarea clear left xterm's finalizer nothing to send. An orphan end now commits its e.data even when ASCII, unless xterm's keydown path already wrote that keystroke in the same task (the same write-derived ownership rule input() uses; the claim is read, not spent). The F2 hazard the old rule guarded, a stale textarea, stays excluded because an orphan end never reads the textarea diff. Tests replay the WebKitGTK sequence: raw Latin and pinyin commit, CJK commits once, same word in a later task commits again, a same-task re-fire does not, a keystroke xterm already wrote is not doubled, an expired claim does not block, and a started composition's ASCII result still commits. Mutating the ownership check fails exactly the no-double case. The flicker and misplaced candidate window reported in the same issue are not addressed here. Refs #1375
…ge (#1402) A display equation with \tag{1} rendered its number on top of the last term. KaTeX places the tag with position: absolute; right: 0 inside .katex-html, which fills .katex-display. VMark's math previews are flex containers, so .katex-display becomes a flex item and shrink-wraps to the equation; right: 0 then resolves to the equation's own edge. This is #1376 again. That fix set width: 100% under .math-block-preview, a class no renderer produces: every $$ block is a $$math$$ code block drawn by codePreview into .code-block-preview.latex-preview (rendered) or .code-block-live-preview (editing), both flex. Its test pinned the dead selector and stayed green while users still saw the overlap. The rule now lives unscoped in styles/katexFixes.css, which both main.tsx and the export CSS bundle load, so every display-math container gets it. The redundant scoped width in latex.css is removed. Centring is unchanged: KaTeX centres display math with its own text-align: center. displayMathTag.test.ts asserts the class instead of a selector: the unscoped rule exists and is loaded by app and export; the flex containers are derived from the renderers that create them; no stylesheet under src gives .katex-display another width; no rule re-places the tag by hand. Against the old CSS the unscoped-rule assertion failed. Closes #1402 Refs #1376
The node-tier displayMathTag.test.ts can only read stylesheets, because jsdom computes no layout. That is how #1376 shipped as fixed while users still saw the overlap: its rule and its test both named a class nothing renders. This real-WebKit test loads the stylesheets the app loads (katex.min.css, katexFixes.css, code-preview.css), renders through the preview's own renderLatex and sanitizeKatex, and measures inside both containers codePreview creates (.code-block-preview.latex-preview and .code-block-live-preview): the tag's right edge meets the container's content edge and its left edge clears the equation. The failure is constructed, not assumed: one case forces .katex-display back to width: auto and asserts the probe sees the overlap, so a measurement that always reported "at the edge" cannot make the other cases pass vacuously. KaTeX 0.18 names the elements .katex-tag and .katex-base; the first run failed loudly on the older .tag / .base selectors before measuring anything. Refs #1402 Refs #1376
CI's lint:deps rejected the test at src/plugins/latex/: importing plugins/codePreview/code-preview.css from the latex plugin is a cross-plugin edge under the plugin-isolation rule. The test measures codePreview's containers, and codePreview is the fence-preview hub the rule licenses to import the latex plugin, so it now lives beside code-preview.css and imports it relatively. Content is unchanged apart from the header, which records why it lives there. The test was committed after the local check:predelta run, and only a hand-picked subset of gates saw it; lint:deps was not in that subset. Refs #1402
This was referenced Sep 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two user-reported fixes and the 0.9.73 version bump, in one PR so the release pays one CI cycle.
fix(terminal)claude, raw pinyin)choreCargo.lock)fix(math)\tag{1}on display math rendered on top of the last term; #1376's fix had never reached the rendering pathtest(math)Policy Gates (Required)
.claude/rules/40-version-bump.md§4). Each fix is its own commit.Linked Issue
Type of Change
What Changed
#1375: orphan
compositionendwith ASCII textOn WebKitGTK with fcitx5,
compositionstartnever fires (#948's instrumented trace). WebKit'sEditor::setCompositioninserts the confirmed text asinsertFromComposition(isComposing: true) and then dispatchescompositionendwith no start guard, so every commit is an orphan end. The gate'sinput()path and xterm's_inputEventboth ignoreinsertFromComposition, so the orphan end is the only carrier, andimeGateMachine.compositionEndcommitted itse.dataonly when non-ASCII. Chinese got through; raw Latin was dropped.e.dataeven when ASCII, unless xterm's keydown path already wrote that keystroke in the same task (the write-derived ownership ruleinput()uses; the claim is read, not spent).GDK_BACKEND=x11experiment.#1402: display-math
\tagoverlap, class-wideKaTeX places the tag with
position: absolute; right: 0inside.katex-html, which fills.katex-display. VMark's math previews are flex containers, so.katex-displayshrink-wraps to the equation andright: 0lands on the last term. #1376's fix setwidth: 100%under.math-block-preview, a class no renderer produces; every$$…$$block renders into.code-block-preview.latex-previewor.code-block-live-preview.styles/katexFixes.css, loaded bymain.tsxand the export CSS bundle, so every display-math container (current, future, export) gets it. The redundant scoped width inlatex.cssis removed.displayMathTag.test.tsasserts the class, not a selector: unscoped rule present and loaded by app and export; flex containers derived from the renderers; no stylesheet narrows.katex-display; no hand-placed tag.displayMathTag.webkit.test.tsmeasures it: real stylesheets, realrenderLatex+sanitizeKatex, both containers. A constructed case forceswidth: autoand asserts the probe sees the overlap.Validation
pnpm check:alllocally. It ran green (exit 0) before the [Bug] latex数学公式不能正确渲染公式编号 \tag{} #1402 commits; the final tree was confirmed bypnpm check:predelta(44/44 gates) plus the targeted runs below. CI's required checks gate the merge.expected [](the drop)vitest related, both stylesheets)width: autoon.code-block-preview.latex-preview .katex-displaypnpm lint:test-typespnpm check:predelta(final tree)The WebKit test first landed in
src/plugins/latex/, where CI'slint:depsrejected its import ofcode-preview.cssas a cross-plugin edge (plugin-isolation). It now lives insrc/plugins/codePreview/, the fence-preview hub the rule licenses to import the latex plugin;lint:depsis clean and the test still passes 3/3.UI Evidence (if applicable)
No screenshot attached. The #1402 layout is asserted by
displayMathTag.webkit.test.ts, which runs in CI'swebkitjob. The reporter's before/expected screenshots are in #1402.PR Checklist