Skip to content

Keep the remote cursor in place while another user types - #75

Merged
markusressel merged 1 commit into
masterfrom
fix/remote-cursor-flicker
Nov 1, 2026
Merged

markusressel merged 1 commit into
masterfrom
fix/remote-cursor-flicker

Conversation

@markusressel

Copy link
Copy Markdown
Member

The name label of another user flickered on every change while that user typed (seen on build-474 while someone typed in the web client).

Cause. KodeEditor stores the TextLayoutResult from onTextLayout in state and passes it to the overlay. After a remote change, the overlay composes once with the new peer positions but the old layout, because the new layout only arrives during measure. DocumentSyncSession resolves the peers against the new text in the same main-thread message as the text update. For a cursor at the end of a line, where people usually type, offset p+1 in the old layout is the start of the next line, so the label jumped there for one frame and back. The presence and cursor resolution was not the cause: the web client sends cursors on the character after the caret, and those already exist when the presence arrives.

Fix. RemotePeersOverlay now gets the current editor text. Through LaidOutPeers, it keeps drawing the peers that belong to the laid-out text until the new text is laid out. KodeEditor needs no change, because its overlay docs already require indices within the laid-out text.

Test. RemotePeersOverlayTest runs Robolectric with native graphics (new test dependencies: robolectric 4.16, compose ui-test-junit4, ui-test-manifest). It renders CodeEditorLayout and steps frame by frame while a peer types "!!!" at the end of a line. It records the label position after each frame.

  • Before the fix: (64,16) (64,16) (24,0) (72,16) .... The label goes to the start of the next line once per change.
  • After the fix: the label stays on its line and only moves right.

🤖 Generated with Claude Code

KodeEditor hands the overlay the layout of the previous text for one
frame after the text changed, while the sync session has already
resolved the peers against the new text. A cursor at the end of a line,
where people usually type, then landed on the start of the next line for
that frame, so the name label jumped with every remote change.

The overlay now draws the peers that belong to the laid out text and
switches to the new peers once the new text is laid out.

A Robolectric Compose test steps through the frames while another user
types at the end of a line. It failed before this change and passes now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@markusressel
markusressel merged commit edbb51c into master Nov 1, 2026
2 checks passed
@markusressel
markusressel deleted the fix/remote-cursor-flicker branch November 1, 2026 00:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant