Paint unified diff decorations only for the damaged lines - #2897
Open
vogella wants to merge 1 commit into
Open
Conversation
Contributor
vogella
force-pushed
the
unified-diff-paint-visible-only
branch
from
September 4, 2026 07:52
c922697 to
b8c918d
Compare
The unified diff paint listener queried StyledText for the bounds of every line of every hunk on each repaint. With inlined annotations the widget has variable line heights, so each query lays out lines that are not on screen, and a repaint costs O(document): on a 1.7 MB file opening a diff blocked the UI for seconds and each page scroll for a good part of a second. Clip the loop to the lines inside the paint event's damaged rectangle, so a repaint is proportional to what is visible. The line header code mining also re-derived the line range of every detailed diff from copies of the hunk text while drawing. Resolve these ranges once when the mining is created, off the UI thread, and reuse the split lines and Document across the detailed diffs of one hunk. Assisted-by: multiple AI agents and layers of automated tooling 🤖
vogella
force-pushed
the
unified-diff-paint-visible-only
branch
from
September 4, 2026 16:04
b8c918d to
05f922c
Compare
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.
The unified diff paint listener asked StyledText for the bounds of every line of every hunk on each repaint, on-screen or not. Because the overlay puts the widget into variable line height mode, each of those queries lays out lines that are never shown, so a repaint costs O(document) and a large file with many hunks becomes unusable: on a 1.7 MB file, opening a diff blocked the UI for seconds and every page scroll for a good part of a second.
The paint listener now clips its loop to the lines inside the paint event's damaged rectangle, so a repaint is proportional to what is visible. The line header code mining additionally resolves the line range of each detailed diff once when the mining is created, off the UI thread, instead of re-deriving it from copies of the hunk text while drawing.
Verified in a running SDK against the same file with 251 hunks: the paint listener no longer appears in the UI thread profile at all (previously 29 samples across open, 8 page scrolls and one edit), and the UI block per 8 page scrolls dropped from 125 ms to 3 ms on Linux/GTK. UnifiedDiffManagerTest and UnifiedDiffTextTest pass.