Skip to content

LibWeb: Drop the post-pass anchor-inset writeback into computed values - #10943

Merged
kalenikaliaksandr merged 1 commit into
LadybirdBrowser:masterfrom
kalenikaliaksandr:drop-anchor-inset-writeback
Jul 31, 2026
Merged

LibWeb: Drop the post-pass anchor-inset writeback into computed values#10943
kalenikaliaksandr merged 1 commit into
LadybirdBrowser:masterfrom
kalenikaliaksandr:drop-anchor-inset-writeback

Conversation

@kalenikaliaksandr

Copy link
Copy Markdown
Member

Once the outermost layout pass returned, the bridge rewrote the computed inset values of every anchor-positioned box, replacing their anchor() functions with the pixel values the pass had resolved. The writeback dates from when the style itself was the carrier of resolved anchor insets: resolution overwrote the inset properties so that every later read, inside or after the pass, would see resolved pixels.

Since 0d42286 the pass no longer works that way. Resolved anchor insets go into a per-pass override store, and every inset read inside the pass is masked by that store, so the pass is self-sufficient and the writeback could only matter to code running after layout. Neither of its two remaining consumers actually wants it:

  • getComputedStyle reports resolved insets through the used-value path, which reads the box model of the laid-out box. It does not need resolved pixels smuggled into computed values.

  • Later layout passes are actively harmed by it. With resolved pixels persisted in computed values, a relayout that skipped style recalc reused the previous pass's anchor positions even if the anchor had moved since, and the resolution early-out then cleared the stored default-anchor scroll shift without re-establishing it, silently losing scroll compensation.

So the writeback machinery can simply go: the deferred-inset batch and its recording callback, the bridge's pending vector, and the writeback in ActiveLayoutPassScope's destructor. Anchor insets now resolve fresh in every pass from the pristine computed values, fixing the stale anchor positions and the lost scroll shift, and computed values become immutable from the moment a layout pass first reads them until the next style recalculation.

Once the outermost layout pass returned, the bridge rewrote the
computed inset values of every anchor-positioned box, replacing their
anchor() functions with the pixel values the pass had resolved. The
writeback dates from when the style itself was the carrier of resolved
anchor insets: resolution overwrote the inset properties so that every
later read, inside or after the pass, would see resolved pixels.

Since 0d42286 the pass no longer works that way. Resolved anchor
insets go into a per-pass override store, and every inset read inside
the pass is masked by that store, so the pass is self-sufficient and
the writeback could only matter to code running after layout. Neither
of its two remaining consumers actually wants it:

- getComputedStyle reports resolved insets through the used-value
  path, which reads the box model of the laid-out box. It does not
  need resolved pixels smuggled into computed values.

- Later layout passes are actively harmed by it. With resolved pixels
  persisted in computed values, a relayout that skipped style recalc
  reused the previous pass's anchor positions even if the anchor had
  moved since, and the resolution early-out then cleared the stored
  default-anchor scroll shift without re-establishing it, silently
  losing scroll compensation.

So the writeback machinery can simply go: the deferred-inset batch and
its recording callback, the bridge's pending vector, and the writeback
in ActiveLayoutPassScope's destructor. Anchor insets now resolve fresh
in every pass from the pristine computed values, fixing the stale
anchor positions and the lost scroll shift, and computed values become
immutable from the moment a layout pass first reads them until the
next style recalculation.
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ed314902-66eb-4724-a382-4d71d5d65e23

📥 Commits

Reviewing files that changed from the base of the PR and between ab080c2 and dea56e9.

📒 Files selected for processing (4)
  • Libraries/LibWeb/Layout/LayoutRustBridge.cpp
  • Libraries/LibWeb/Rust/src/layout/abspos_engine.rs
  • Libraries/LibWeb/Rust/src/layout/formatting_context.rs
  • Libraries/LibWeb/Rust/src/layout/layout_state.rs
💤 Files with no reviewable changes (3)
  • Libraries/LibWeb/Rust/src/layout/formatting_context.rs
  • Libraries/LibWeb/Rust/src/layout/abspos_engine.rs
  • Libraries/LibWeb/Rust/src/layout/layout_state.rs

📝 Walkthrough

Walkthrough

Deferred resolved-anchor-inset storage, callbacks, commit reporting, and pass-end application were removed. Absolute-position layout continues to update resolved anchor insets directly.

Changes

Anchor-inset writeback

Layer / File(s) Summary
Remove deferred inset state and callbacks
Libraries/LibWeb/Rust/src/layout/layout_state.rs, Libraries/LibWeb/Rust/src/layout/formatting_context.rs
LayoutState no longer stores, merges, or reports deferred resolved anchor insets. The formatting-context FFI no longer exposes the deferred-inset structure or callback.
Use direct inset replacement
Libraries/LibWeb/Rust/src/layout/abspos_engine.rs, Libraries/LibWeb/Layout/LayoutRustBridge.cpp
Absolute-position layout retains direct resolved-inset replacement. ActiveLayoutPassScope no longer applies deferred insets when the outermost pass ends.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: tcl3

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description directly explains the removal of deferred anchor-inset writeback and its intended layout and scroll-compensation fixes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kalenikaliaksandr
kalenikaliaksandr enabled auto-merge (rebase) July 31, 2026 02:39
@kalenikaliaksandr
kalenikaliaksandr merged commit 6e068c8 into LadybirdBrowser:master Jul 31, 2026
15 checks passed
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