fix(web): avoid forced layouts in mouse glow discovery - #1809
Merged
Conversation
MouseGlowService measured every composed-path ancestor while resolving a glow surface, potentially forcing two synchronous layouts per element. It then measured the selected surface and ordinary stacking host again. This could enter Blink flex layout repeatedly while session content was mounting, eventually causing a WebView2 STATUS_ACCESS_VIOLATION. Detect candidates from styles and semantics, measure only the selected surface, and keep normal overlays fixed under document.body. Preserve local positioning for actual floating layers and reuse an existing rect when the floating surface is its own host. The regression originated in 1ec2213 (GCWing#1743).
Closed
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.
Summary
document.body; retain local positioning for actual floating layers.Type and Areas
Type:
Regression fix
Areas:
Web UI, mouse-follow glow
Motivation / Impact
BitFun 0.2.14 could crash its WebView2 renderer with
STATUS_ACCESS_VIOLATIONwhen the mouse-follow glow was enabled and the userrepeatedly switched between the Session and Settings scenes. Disabling the
effect prevented reproduction.
The native dump ended in:
requestAnimationFrame -> getBoundingClientRect -> Blink Flex layout -> OutOfFlowLayoutPart::LayoutCandidatesMouseGlowService.findSurface()walked the full composed ancestor path onpointer frames. For each candidate it could call
getBoundingClientRect()inboth divider and automatic-surface detection, then measure the selected surface
and an ordinary stacking-context host again. Session mounting and virtualized
content updates made these synchronous layout reads enter unstable Blink flex
layout repeatedly.
The regression was introduced in
1ec22139/ PR #1743, which addedthe pointer-follow glow and its geometry-based ancestor discovery and overlay
host selection. The follow-up
e3169ccf/ PR #1757 consolidated theancestor style scan, but retained the per-candidate geometry reads.
The fix classifies candidates using computed styles, attributes, roles, and
class semantics. Geometry validation is deferred until one surface has been
selected. Ordinary stacking contexts no longer become overlay hosts, avoiding
the final SceneViewport flex-host measurement. Dialogs, listboxes, popovers,
and other actual floating layers retain local hosting.
No functional change is intended for the glow setting or normal pointer
tracking. Users should see the same effect with less layout work and without
the renderer crash.
Verification
pnpm --dir src/web-ui run test:run src/infrastructure/mouse-glow/core/MouseGlowService.test.tspnpm run type-check:webgit diff --cached --checkSession/Settings switching:
Reviewer Notes
Normal surfaces now use viewport coordinates with the fixed overlay hosted by
document.body, even when they are inside transformed or stacking-contextancestors. Actual floating layers still use local coordinates so their clipping
and z-order behavior is preserved.
Divider line-shape validation now runs against the final selected rect instead
of during ancestor discovery.
All temporary runtime probes and the debug receiver were removed after manual
confirmation.
Checklist