Skip to content

Keep node cards and connection lines on the same compositing path - #322

Merged
dovvnloading merged 1 commit into
mainfrom
fix/dark-mode-edge-compositing
Aug 14, 2026
Merged

Keep node cards and connection lines on the same compositing path#322
dovvnloading merged 1 commit into
mainfrom
fix/dark-mode-edge-compositing

Conversation

@dovvnloading

Copy link
Copy Markdown
Owner

Problem

While dragging a node, its connection line can visibly trail or stutter instead of staying pinned to the node. The problem was reported as dark-mode-only: switching the app to the light theme makes it disappear.

The two behaviors have one explanation. Node cards are moved by the graphics processor as independent layers - the browser quietly promotes them to that fast path once their position starts changing every frame. The connection lines live in a drawing layer that is redrawn on the main processor. Content traveling by two different routes to the screen can arrive a frame out of step, and when it does, the line lags the node it is attached to. A thin bright line on a near-black background makes each misstep obvious; the identical misstep on a white background is nearly invisible. Dark mode does not cause the problem - it reveals it. This is also why measurements of the page's internal layout kept reporting the line perfectly attached while the screen showed otherwise: the divergence happens after layout, at the final composition step.

Change

One stylesheet addition: declare will-change: transform on both the node wrappers and the connection layer. This tells the browser up front to give both the same treatment, instead of promoting nodes to a separate path partway through a drag gesture. No behavior, markup, or code-path changes - the drawing pipeline is simply aligned from the first frame.

Test plan

  • Production build succeeds with the change
  • Verify in the desktop app, dark theme: drag a connected node slowly around the canvas and confirm the connection stays pinned to the node - this is the reporter's reproduction and requires visual confirmation on the affected machine

Node cards move as GPU-composited layers - the browser promotes them on
its own once their position changes every frame of a drag - while the
connection lines live in an SVG layer that is re-rasterized on the main
thread. Those are two different routes to the screen, and when they fall
a frame out of step the connection visibly trails or stutters against
the node it is attached to. The thin bright stroke on a near-black
background makes every misstep obvious in the dark theme; the identical
misstep is nearly invisible against the light theme, which is why the
problem was reported as dark-mode-only while measurements of the page's
internal geometry kept showing the two perfectly attached.

Declaring will-change on both the node wrappers and the connection layer
makes the browser assign both to the compositing path from the first
frame, instead of flipping nodes onto a separate one partway through a
gesture.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dovvnloading
dovvnloading merged commit 68aa49e into main Aug 14, 2026
dovvnloading added a commit that referenced this pull request Aug 14, 2026
… frame (#323)

Recent WebView2 builds hand independently-composited page layers to the
Windows compositor to assemble on screen. A node card being dragged
lives on its own such layer, while its connection lines are redrawn into
a different one, and Windows can apply the card's movement one display
frame before the freshly drawn connection arrives - the line visibly
steps out of sync with the node it is attached to. Everything measured
inside the renderer (layout geometry, frame captures) shows the two
perfectly attached, because the divergence happens below the renderer at
window composition; a thin bright line on the dark theme's near-black
background makes each misstep obvious while the same misstep is nearly
invisible on the light theme, which is why the report was dark-only.

The launcher now disables delegated composition for the app's WebView2
instance, making the renderer assemble the complete frame itself before
handing one finished image to Windows. The flag is appended in front of
any WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS the user already set and is
ignored by runtimes that predate the feature.

Also reverts the will-change stylesheet addition from #322: promoting
more layers cannot help under this mechanism and only increases the
number of independently-composited surfaces.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
dovvnloading added a commit that referenced this pull request Aug 14, 2026
These three changes were attempts at the drag artifact that were not
confirmed to work before shipping, and the most recent one made things
worse: with #324 in place the connection lag became visible in the light
theme as well, where it had previously been unnoticeable.

The most likely cause of that regression is the composition flag. The
audit behind #324 established that the flag added in #323 never reached
the browser, because the window library passes a conflicting switch and
duplicate switches resolve last-one-wins. #324 corrected the delivery,
so disabling delegated composition took effect for the first time - and
it applies to both themes equally, which matches the report exactly. The
stroke width increase and the explicit high-quality smoothing hint in
the same change also affect both themes and cannot be ruled out.

This restores graphlink_desktop.py, styles.css and gl-vars-dev.css to
their state as of #321. The measured performance fixes in #319, #320 and
#321 are untouched.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@dovvnloading
dovvnloading deleted the fix/dark-mode-edge-compositing branch August 15, 2026 14:41
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