Skip to content

base: read the pointer only under hovered text, and ask no frame for a closed popup - #3431

Merged
sunli829 merged 2 commits into
mainfrom
fast-hover-only-pointer-reads
Oct 12, 2026
Merged

sunli829 merged 2 commits into
mainfrom
fast-hover-only-pointer-reads

Conversation

@sunli829

Copy link
Copy Markdown
Collaborator

Background

Allsum users reported high CPU when dragging the scrollbar of a longer AI chat conversation. Under gpui-fast's retained views, whatever did not change since the last frame is drawn from it; two things in gpui-base kept a long list of rendered markdown from ever being unchanged. Both changes are in gpui-base (AGENTS.md asks for an explicit request before changing Base; this was requested as part of the Allsum investigation).

Changes

  • text/inline.rs: read the pointer only under hovered text. Inline::paint read window.mouse_position() on every paint to find the link under the pointer. Reading the pointer makes the text depend on every pointer move, so a scrollbar drag, or any mouse move, drew every paragraph of the transcript again. It now reads the pointer only when its own hitbox is hovered; text not under the pointer has no link under it, so the result is the same.
  • popup.rs: a closed popup asks for no frame. A Popup asked for an animation frame the first time it measured its trigger, so that its content could be placed on the next frame. A closed popup has no content to place, yet every list row coming into view with one asked for a frame, and a list whose rows ask for frames is kept off its scroll layer. It now asks only when it has content; opened later, it places its content at once from the trigger bounds it already noted.

Measurements

In Allsum, with the gpui-fast fixes (longbridge/gpui-fast#56) and longbridge/ai-chat#438: turning off the inline-text change raised scrollbar-drag CPU from ~19 % to ~38 %; turning off the popup change raised it to ~27.5 %. With everything, wheel 47 % → 22 % and drag 32 % → 20 % against main.

Tests

  • New a_closed_popup_asks_for_no_frame_and_opens_at_once (a closed popup renders its view once; opened, its content is placed on that frame).
  • Not yet run locally: resolving the workspace needs the quickjs git dependency, whose fetch is still in progress here. The changed code compiles (built into Allsum on top of 02daace). I will update this once the tests have run.

🤖 Generated with Claude Code

…a closed popup

Two things that kept a long list of rendered markdown, as an AI chat
transcript is, from being drawn from last frame under gpui-fast's
retained views:

- Inline text read the pointer's position on every paint to find the link
  under it, which made every paragraph depend on every pointer move: a
  scrollbar drag or any mouse move drew the whole transcript again. It now
  reads the pointer only when its own hitbox is hovered; text not under
  the pointer has no link under it.
- A popup asked for an animation frame the first time it measured its
  trigger, so that its content could be placed on the next frame. A
  closed popup has no content to place, and every row coming into view
  with one asked for a frame, which keeps a list off its scroll layer. It
  now asks only when it has content; opened later, it places the content
  at once from the bounds it already noted.
@sunli829
sunli829 marked this pull request as ready for review October 12, 2026 02:36
a_closed_popup_asks_for_no_frame_and_opens_at_once did not compile: it
called cx.run_until_parked() while the window it had added still
borrowed cx. Compiled, it still could not tell the change apart: it
counted the root view's renders, and upstream GPUI renders the root view
on every draw, so the count was three with or without the popup asking
for a frame.

It now asks the window how many next-frame callbacks the first draw
left (Window::simulate_next_frame): none for a closed popup, one if it
still asks for a frame.
@sunli829
sunli829 merged commit 45b0bbf into main Oct 12, 2026
16 checks passed
@sunli829
sunli829 deleted the fast-hover-only-pointer-reads branch October 12, 2026 05:31
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