fix(desktop): keep caret after agent mention in WebKitGTK - #5235
Conversation
The hidden "@" prefix of an agent mention (`.agent-mention-at-hidden`) was collapsed with `display: inline-block; width: 0`. WebKitGTK — the Tauri webview on Linux — mis-measures the caret rect for a text position adjacent to a collapsed inline-block box and snaps the caret to the box's content origin. Because the following agent chip carries left padding for its bot icon, the caret rendered visually *inside* the chip (e.g. "F|izz") even though the ProseMirror selection was correctly positioned after the whole mention. Collapse the "@" as plain inline text via `display: inline; font-size: 0` instead. This keeps zero advance width (no layout shift; the chip's left edge is unchanged) while leaving the caret on the normal inline-text path, which WebKit positions correctly. Chromium already rendered the caret correctly with either rule, so this is a defensive engine-agnostic change with no visible effect there. Applies to the message composer, which carries the `message-markdown` class so the agent-mention styles apply while editing. Co-authored-by: Kevin Chung <chung@squareup.com> Signed-off-by: Kevin Chung <chung@squareup.com>
Before / after — caret placementIllustration of the reported symptom vs. the fix. Underlying text is
Verified in a Chromium box-model harness that both rules collapse the Regression originThis is a regression. Screenshot is committed to the PR branch ( |
Co-authored-by: Kevin Chung <chung@squareup.com> Signed-off-by: Kevin Chung <chung@squareup.com>
|
Closing per Kevin Chung's request — another contributor is picking up this work. Note for whoever takes over: the caret bug is a regression from #1052, which rewrote .agent-mention-at-hidden from 'font-size:0' to a zero-width 'display:inline-block; width:0' that WebKitGTK snaps the caret onto. Reverting to the inline font-size:0 collapse fixes it. |

Problem
After typing
@and selecting a person/agent in the composer, the text caret lands in the middle of the mention chip (e.g.F|izz) instead of after it, on the Buzz Desktop app (Tauri/WebKitGTK on Linux).Reported by Kevin Chung with a screenshot showing the caret between
Fandizz.Root cause
Agent mentions are rendered via inline decorations (
mentionHighlightExtension.ts): the literal@gets a.agent-mention-at-hiddenclass and the name gets a.mention-chip.agent-mention-highlightchip whose left padding holds the bot-icon::before..agent-mention-at-hiddencollapsed the@withdisplay: inline-block; width: 0; overflow: hidden. WebKitGTK mis-measures the caret rect for a text position adjacent to a collapsed inline-block box and snaps the caret to the box's content origin. Because the following chip carries left padding for its icon, the caret rendered visually inside the chip — even though the ProseMirror selection was correctly positioned after the whole@Fizzmention (verified inuseRichTextEditor.replacePlainTextRange/useMentions.insertMention: the model caret is correct).Chromium positions the caret correctly with either rule, so the bug is WebKitGTK-specific — the same engine-difference class as the emoji-loupe issue (#5229).
Fix
Collapse the
@as plain inline text viadisplay: inline; font-size: 0instead of a zero-width inline-block. This keeps zero advance width (no layout shift; the chip's left edge is unchanged — verified at x=292px in both variants) while leaving the caret on the normal inline-text path, which WebKit positions correctly.Single-file, CSS-only, defensive change in
desktop/src/shared/styles/globals/markdown.css.Validation
tscclean,biome checkclean on the changed file, 4535/4535 unit tests pass.@to zero width and leave the chip position identical (no regression / no visible effect in Chromium).Honest caveat
I can't run WebKitGTK locally (agent-browser only offers Chromium here), so I couldn't reproduce the actual mid-chip caret in-engine. The fix targets the documented WebKit caret-snapping behavior around collapsed inline-block boxes and is verified to be a no-op layout change in Chromium. Please confirm on a real Buzz Desktop build that the caret now lands after the mention.