Commit graph

211 commits

Author SHA1 Message Date
sideshowbarker
a82c7939d9 LibWeb+UI/AppKit: Implement macOS IME support
This makes macOS IME input in web content work as expected.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/9712
2026-06-08 10:23:14 +09:00
Andreas Kling
570ea59277 LibWeb: Run same-document commit handlers during entry update
Move Navigation API commit handler completion into a helper. This lets
same-document entry updates run currententrychange before the intercept
handlers. Keep same-document traversals from aborting the ongoing
NavigateEvent before that entry update runs.

Add text coverage for intercepted and non-intercepted same-document
history traversals updating the Navigation API current entry before
navigatesuccess.
2026-06-06 11:34:50 +02:00
Andreas Kling
164ed80244 Meta: Enable exit-time destructor warnings for libraries
Enable -Wexit-time-destructors for all in-tree library targets and
update process-lifetime library statics so they no longer register
exit-time destructors. Long-lived caches, lookup tables, singleton
registries, and generated constants now use NeverDestroyed or leaked
references where the data is intended to live until process exit.

Update LibWeb, LibLine, and the binding generators so regenerated
sources follow the same rule instead of reintroducing destructed
statics.
2026-06-04 19:20:49 +02:00
sideshowbarker
898be8badb LibWeb: Cancel the async-scroll hover update when the document changes
Problem: A document loaded into a navigable just after a previous
document in that navigable had been async-scrolling could receive hover
and mouseover/mouseout boundary events which nothing in that document
triggered. In our CI, that manifested as an intermittent flake/failure
of the async-scrolling/hover-updates-after-async-scroll.html test —
whose first mouseover count came up one short: A leftover refresh had
moved hover onto the target before the test added its listeners.

Cause: A navigable tears down a document’s input state implicitly: Its
hover target and mousedown target are GC::Weak references that null
themselves once the document is collected. The post-scroll hover refresh
wasn’t getting that automatic teardown. It runs off a Core::Timer that’s
stopped when the navigable is destroyed — but was *not* being stopped
when the navigable swaps in a new active document. So, a scroll in one
document left a refresh that fired against the next.

Fix: Cancel the pending refresh when the navigable’s active document
changes — the same boundary at which the weak references null. That
gives the timer the same teardown the rest of the input state already
has — with no per-document tracking state.
2026-06-04 11:06:14 +02:00
Aliaksandr Kalenik
5595efd46b LibWeb: Avoid display list rebuilds for VV changes
Visual viewport scroll and pinch zoom used to invalidate the full
accumulated visual context tree and display list, even though those
changes only modify the root visual viewport transform. That forced a
full display list rerecord before sending updated compositor state.

Patch the reserved visual viewport AVC node in place instead.
VisualViewport marks the tree for compositor update without
invalidating the display list, and Navigable sends the replacement tree
through the new IPC path before updating scroll state.
2026-06-03 02:12:39 +01:00
Aliaksandr Kalenik
78cda6a97e LibWeb: Reserve visual viewport AVC root
The accumulated visual context tree used index 0 as a null sentinel, so
visual viewport transforms were only represented by adding a normal
transform node when the transform was non-identity. That made callers
treat index 0 as a special no-context value and kept the tree shape
dependent on the visual viewport state.

Reserve index 0 as the visual viewport transform node instead. AVC
traversal, display-list replay, hit testing, debug dumping, and root
paint state now treat that node as a real root. Rebaseline the affected
display-list and async-scrolling text expectations so the explicit root
node appears in AVC dumps.
2026-06-03 02:12:39 +01:00
Andreas Kling
60847b9937 LibWeb: Respect page client focus for navigables
Make navigable focus depend on whether the page client currently has
system focus. WebContent already receives focus changes from the UI
process, but LibWeb did not consult that state when deciding whether the
top-level traversable was focused.

Repaint the text caret when WebContent focus changes so a focused text
control stops showing an active caret as soon as browser chrome takes
focus, and resets the blink cycle when page focus returns.
2026-06-03 02:53:37 +02:00
Aliaksandr Kalenik
d725c36129 LibWeb: Store cached display list commands without resources
Cached display list command sequences used to carry their own
DisplayListResourceStorage. That kept resource ID sets and referenced
fonts, images, video frames, and nested display lists alive on every
cached phase, even though the command bytes already contain enough
information to discover those references when they are needed.

This makes cached command sequences store only command bytes. Resource
references are collected transiently from those bytes when a cache entry
is installed or invalidated. The navigable's central display list
resource storage now keeps cache reference counts, so compositor pruning
retains resources used by live cached commands without duplicating
storage in each sequence.
2026-05-31 00:21:25 +01:00
Andreas Kling
acc86e9eb1 LibWeb: Add a caret hit-test debug overlay
Add a debug-menu toggle for caret hit testing at the mouse position.
Paint the insertion rect and log the result so selection bugs can be
inspected without temporary probes.

Request frames and repaint invalidation when the overlay state changes.
Also repaint when the caret rect moves within the same text node.
2026-05-30 13:50:48 +02:00
sideshowbarker
03f6f25b11 LibWeb: Skip user-select:none when extracting selected text
Problem: Select All (Ctrl+A or the context menu) followed by Ctrl+C
unexpectedly copies text from elements with user-select:none — breaking
compat with Chrome and Firefox, which both exclude user-select:none
content from the clipboard.

Cause: Navigable::selected_text() walks the selection range via
visible_text_in_range() and concatenates each text node’s data. The walk
filters out nodes without a layout, but not nodes whose used value of
user-select is ‘none’.

Fix: Add a user-select check at each visible_text_in_range() walk point.
The Selection range itself is left unchanged. Selection.toString() still
returns the full text per spec — but the clipboard-extraction path now
excludes user-select: none subtrees, per spec
2026-05-28 12:15:21 +01:00
Aliaksandr Kalenik
790d5c0489 Compositor: Drop redundant context state
CompositorState treats presence in m_contexts as the lifetime state
for a compositor context. create_context() creates the entry and
destroy_context() removes it, so ContextState::is_registered duplicated
the map membership invariant.

The top-level-traversable bit was also duplicate information. The
only compositor use was backing-store padding while a window resize is
in progress, and page-presenting contexts are already identified by
PagePresentationRegistration::Yes. Normalize resize-in-progress to No
for non-page-presenting contexts, then remove the flag from
CompositorState, the backing-store API, and the compositor IPC boundary.
2026-05-27 20:29:36 +01:00
Aliaksandr Kalenik
b36e6c9b97 Compositor+LibWeb: Pass AVC trees separately from display lists
Display lists owned the accumulated visual context tree through a
ref-counted pointer. That tied visual-context state to display-list
lifetime and made compositor updates treat the two as one unit, even
though AVC trees need to become independently updateable compositor
state.

Make accumulated visual context trees plain versioned values, have each
display list store the compatible tree version, and pass the matching
tree alongside display-list updates and replay calls. Replay verifies
that the provided tree matches the display list before executing it.

This prepares the compositor for receiving AVC tree updates separately
from display-list updates: it now accepts the tree as a separate update
parameter, stores it next to the display list, and uses that stored tree
for replay and async-scroll hit testing. Nested display-list resources
carry their own tree snapshots for the same version check.
2026-05-27 18:29:42 +01:00
Andreas Kling
2bdb35aad5 LibWeb: Preserve full invalidation for pixel ratio changes
Reuse the existing display-list invalidation signal from viewport
updates to distinguish ordinary resizes from DPR and zoom changes.
The latter still need full style invalidation because snapped border
and outline widths depend on device_pixels_per_css_pixel even when
style does not otherwise depend on viewport metrics.

Add a text test for changing devicePixelRatio with subpixel border
and outline widths.
2026-05-25 19:18:10 +02:00
Andreas Kling
ceb25e10d4 LibWeb: Avoid full viewport resize style invalidations
Use the viewport metric dependency flags to restyle only elements whose
computed values can change after a viewport resize. Descendants that
inherit changed values are reached through the existing inherited-style
update path.

Keep targeted style reads correct by treating pending media query
evaluation as style dirtiness. Seed the style computer with the latest
viewport before resolving pending animated style, so viewport-unit
keyframes do not use stale metrics.

Share pseudo-element recomputation with inherited-style updates, so
pseudos stay current when their originating element changes only via
inherited values.

Schedule animated style updates when inherited style recomputation can
affect existing animations.

Add viewport resize coverage for media queries, inherited font metrics,
monospace font-size recascade, line-height percentages, font-relative
and pending viewport-unit animations, inherited pseudo-elements, direct
pseudo viewport dependencies, and canvas currentColor reads.
2026-05-25 11:35:35 +02:00
Aliaksandr Kalenik
399db4a213 LibWeb+WebContent: Simplify compositor context creation
CompositorHost still accepted page presentation metadata so the old
in-process compositor path could register new contexts while
constructing the LibWeb handle. With the compositor process as the only
backend, context allocation and service registration already happen
before LibWeb creates the handle.

Make CompositorHost::create_context() take only the allocated context id
and remove the private register_context() hook. Navigable no longer
computes page metadata for the host, and WebContent no longer carries a
erification-only registration override.
2026-05-25 00:45:24 +02:00
Aliaksandr Kalenik
ab54d2bd22 LibWeb+WebContent: Remove async scroll adoption deferral hook
The compositor thread used to need a way for LibWeb to postpone
adopting async scroll offsets when the thread had already presented
newer state. The compositor process implementation never defers this
path, so the hook became a hardcoded false result after the thread code
was removed.

Remove the host callback and let Navigable always consume the pending
async scroll updates from the compositor process before running
rendering-update observers.
2026-05-25 00:45:24 +02:00
Aliaksandr Kalenik
6c162d8b5d LibWeb+LibWebView+WebContent: Recover after Compositor process crashes
The browser previously treated the out-of-process Compositor as fatal.

Restart the shared Compositor from the browser process, reconnect
process-backed WebContent clients, recreate compositor contexts, restore
viewport state, and ask WebContent to repaint and republish canvas and
media resources. WebContent now marks its compositor connection lost,
returns conservative values for synchronous compositor queries while
reconnecting, and drops outgoing updates until the replacement transport
arrives.

Synchronous input queries through the compositor control connection now
use fallible IPC. If the Compositor exits after the open check or before
the sync reply arrives, scroll and mouse handling report that the
Compositor did not handle the event and let the normal WebContent
fallback run.

Mouse events queued while the Compositor is unavailable now fall back to
direct WebContent dispatch. This keeps input completion in step with the
pending-event queue.

Recovery is capped at three automatic restarts. If the restart limit is
exceeded, if restart, reconnect, or context recreation fails, or if the
replacement Compositor exits during active recovery, the browser crashes
instead of switching process-backed views to a fallback path.
2026-05-24 03:35:07 +01:00
Aliaksandr Kalenik
579de06b78 LibWeb: Rename m_rendering_thread_display_list_* to m_compositor_*
"Rendering thread" is the old name for what is now called the
compositor. Rename these Navigable members to reflect the current
terminology:
2026-05-23 18:13:29 +01:00
Aliaksandr Kalenik
4742a02975 LibWeb+WebContent: Split compositor context id allocation from creation
Once the compositor lives in another process, the helper has to know a
context's id before any per-context message about it can be dispatched.
Today the id is minted inside CompositorHost::create_context and
returned to the caller, so it cannot be named ahead of time.

Untangle allocation from creation so Browser can mint the id and hand it
down through the call chain into both the local host and the future
remote host with no special case. The id helpers also move into a public
header so LibWeb, WebContent, and the upcoming service share one
encoding for the page-presenting bit. Behavior is preserved; the
in-process compositor still owns rendering.
2026-05-22 19:50:42 +01:00
Andreas Kling
75375e8cef LibWeb: Update hover after async scrolling stops
Remember the last mouse or wheel position seen by the event handler.
Schedule a hover refresh once async scrolling goes idle.
This lets hover state and boundary events follow content under a
stationary pointer after scrolling has stopped.

Add a text test that keeps hover on the old target while scrolling is
active. It then checks that hover moves after the idle update without
extra mousemove or pointermove events.
2026-05-22 14:33:39 +02:00
Aliaksandr Kalenik
6b912038d3 LibWeb+WebContent: Route compositor through in-process IPC
LibWeb still exposed the concrete CompositorThread to Page,
Navigable, and EventHandler, so compositor IPC would have leaked the
thread implementation into callers. The old thread APIs also bundled
page presentation callbacks and main-thread wakeups into the same
object, which made it awkward for WebContent to put an actor boundary
in between.

Introduce CompositorHost and context handles as the caller-facing API,
and move shared compositor protocol values out of CompositorThread. Add
WebContentCompositor IPC endpoints and route PageHost through a paired
in-process transport. The actor owns CompositorThread with explicit
main-thread and UI presentation clients, while screenshot completion is
serialized on the WebContent event loop using request IDs.

The intention for introducing IPC here is to prepare for moving the
compositor thread into a separate process.
2026-05-21 11:45:06 +01:00
Shannon Booth
de6aec04e8 LibGC: Default-construct ConservativeVector from the global heap 2026-05-20 20:37:55 +02:00
Andreas Kling
8eb74bf747 LibWeb+LibWebView: Preserve crashed page URLs on crash
Load the browser-generated crash page as a synthetic response for the
URL that was active when WebContent exited. This keeps the session
history entry, response URL, and created Document aligned with the same
navigation URL, so reload targets the original page without creating a
local document for an HTTP(S) history entry.

Suppress history metadata updates from the generated page and declare
an inert rel=icon. Fallback favicon loading now follows the HTML
condition that no link with the icon keyword exists, which avoids the
credentialed /favicon.ico request from the crashed origin.
2026-05-20 20:17:45 +02:00
Aliaksandr Kalenik
262a2796b2 LibWeb: Paint iframe surfaces through compositor queue order
Represent main-thread presents as compositor commands so iframe presents
remain ordered before later parent display-list and present work. Nested
painting now enqueues the child present without blocking the main
thread.

When a nested present publishes to a compositor surface owned by another
context on the same page thread, update that target context directly
inside the compositor loop. This keeps the iframe surface available
before the queued parent present replays its display list.
2026-05-18 20:11:31 +02:00
Aliaksandr Kalenik
81b5b343d9 LibWeb: Share WebContent compositor thread across pages
Move compositor-thread ownership to WebContent's PageHost so every Page
object in one WebContent process registers its navigables on the same
compositor thread. This covers auxiliary pages created by window.open(),
while worker and SVG helper pages continue to skip compositor thread
creation.

Keep page presentation keyed by page id. Each presenting context records
the page id it presents for, and static compositor entry points route
ready-to-paint, async scrolling, and viewport scrollbar events to that
page's presenting context on the shared thread.
2026-05-18 20:11:31 +02:00
Aliaksandr Kalenik
93bbdf1f55 LibWeb: Use compositor surface IDs for embedded content
Display lists kept canvas and nested navigable content alive through
ExternalContentSource objects. That made the resource graph depend on
process-local object identity instead of a stable surface handle, which
blocks compositor process isolation and made teardown-sensitive embedded
content harder to reason about.

Allocate CompositorSurfaceId values for canvases and child navigables,
publish their backing stores to the owning compositor, and paint them
with DrawCompositorSurface. Child navigables now publish to parent
compositors by CompositorContextId instead of raw object pointers, so
the in-process path uses the same stable addressing model required by a
remote compositor.

Clear and skip stale child surfaces during teardown, preserve Skia
canvas state while drawing compositor surfaces, and add display-list
coverage for canvas and iframe compositor surfaces. The nested navigable
async-scrolling baseline now expects DrawCompositorSurface.
2026-05-18 15:27:59 +02:00
Andreas Kling
541828dbb1 LibWeb: Respect overflow axes for wheel scrolling
Keep the compositor scroll node max offset as the real scroll range,
even for axes that cannot be scrolled by wheel input. Track wheel
scrollability separately so hidden axes are skipped during async wheel
scrolling without clamping away an existing programmatic offset.

Use the viewport-propagated root and body overflow values when deciding
whether viewport axes accept wheel input. Apply wheel deltas only on
axes that can be wheel-scrolled in async metadata and main-thread wheel
default actions, while preserving CSSOM scroll offsets on hidden axes.

Add async scrolling coverage for hidden-axis wheel targeting, preserved
programmatic hidden-axis offsets, and body overflow-x: hidden blocking a
horizontal viewport wheel scroll despite pseudo-element overflow.
2026-05-17 14:19:36 +02:00
Aliaksandr Kalenik
8906011a6b LibWeb: Synchronize display list resources via transactions
Display lists used to own the resource storage needed to replay their
command bytes. That kept the compositor tied to in-process object
ownership: sending a display list update also meant sharing the same
resource container with the recording side.

Move resource storage out of DisplayList and make display list updates
carry a transaction of resources to add and remove. Navigable now tracks
the resources referenced by the current display list, sends only the
delta to the compositor, and trims its recording-side storage to the
active set. The compositor applies those transactions to its own storage
before replacing the cached display list.

This still carries in-process resource objects, but it puts the
ownership boundary in the right place. Command bytes and resource
lifetime are now synchronized explicitly, which is the shape needed
before the compositor can receive serializable resource updates across a
process boundary.
2026-05-16 19:35:24 +02:00
Aliaksandr Kalenik
fd823becd7 LibWeb: Move backing store management into compositor thread
BackingStoreManager was owned by Navigable and allocated on the GC heap,
which left backing-store sizing decisions on the main thread even though
the compositor thread was already responsible for allocating the actual
surfaces. That split ownership makes it harder to isolate the compositor
behind a process boundary.

Move the manager into LibWeb's compositor code and let CompositorThread
thread data own it. The main thread now reports viewport size changes
through a compositor command, and the compositor uses that message to
decide when to resize and publish backing stores. The delayed shrink
timer remains with the main-thread CompositorThread facade so it can use
the Core event loop, but it now only sends another viewport-size update.

This removes the GC edge from Navigable, drops stale WebContent includes
and keeps the existing resize padding and delayed shrink behavior.
2026-05-16 16:36:05 +02:00
Aliaksandr Kalenik
649296ec07 LibWeb: Defer stale main-thread frames during async scroll
While an async scroll present was pending, the main thread could still
record and submit a display list from a stale scroll state before the
compositor-presented frame had reached the UI process. That stale
snapshot could replace the compositor-side scroll state and cause
visible back-and-forth jumps.

Check the async-scroll present defer condition before recording the
frame. The existing post-record check remains in place for races that
become pending while recording is in progress.
2026-05-16 14:50:46 +02:00
Aliaksandr Kalenik
429b7fc809 LibWeb: Rebase pending async scrolls over main-thread state
Async scrolling kept only the compositor-visible absolute scroll offset
for pending scrolls. If script changed the same scrolling box before
the main thread adopted the pending offset, adoption could write the
stale absolute compositor offset back to the DOM and lose the script
update.

Track the unadopted compositor delta alongside the absolute offset
used for compositor presentation. When fresh scroll state reaches the
compositor, and when the main thread adopts pending async scrolls,
apply that delta on top of the current main-thread offset instead of
assigning the old absolute value.

Adoption can run during the event-loop scroll steps, before the later
rendering-update layout pass has made paintables safe to query. Keep
element adoption on the stored DOM scroll offset and apply viewport
deltas through the navigable, so a dirty layout tree does not trip the
paintable freshness invariant.

The async scrolling text test covers the script-scroll race and also
dirties layout before adoption. The old paintable-box adoption path
crashed in that case.
2026-05-15 21:13:18 +02:00
Aliaksandr Kalenik
f743263871 LibWeb: Let internals.wheel await async scroll adoption
Async scrolling tests used requestAnimationFrame() as a proxy for the
compositor thread to return pending scroll updates to the main thread.
That waited for a rendering opportunity, so tests could observe stale
DOM scroll offsets when the compositor update had not been adopted yet.

Make internals.wheel() return a promise that resolves after a tracked
async scroll operation has been applied by Navigable. Tracking is opt-in
from the internals test API, so regular page wheel input and compositor
IPC keep the boolean async-scroll path without allocating operation IDs.
Tracked test scrolls are the only operations that record completions.

Update async scrolling and wheel propagation tests to await the wheel
promise directly instead of relying on animation frame timing in tests.
2026-05-15 19:10:27 +02:00
Luke Wilde
de35994fc2 LibJS+LibWeb: Use the unified Visitor for Variant-holding members 2026-05-15 08:51:17 +02:00
Aliaksandr Kalenik
d353954993 LibWeb: Adopt async scroll offsets for nested scroll nodes
Nested scroll nodes were present in the async scroll tree, but the
compositor rejected any non-viewport wheel target and tracked only one
pending viewport offset. That prevented element scrollports from being
scrolled asynchronously and made compositor-side offsets impossible to
adopt after the main thread rebuilt scroll state.

Let async wheel commands target any scroll node selected by the tree.
Store every offset produced by a compositor scroll and reapply pending
offsets by stable ID across display-list and scroll-state updates. The
main thread now adopts viewport, element and pseudo-element offsets
before rendering-update observers run, including scroll event
bookkeeping for element scrollers.

Carry the wheel hit-test rejection reason through the enqueue path while
doing this, so main-thread and blocking-wheel regions remain explicit
rather than being collapsed into a missing target. Existing nested
async-scrolling text tests cover the successful nested scroll path.
2026-05-14 19:41:32 +02:00
Aliaksandr Kalenik
82b016ed19 LibWeb: Rebuild async scrolling from display list
Use compositor hit-test commands in the display list to rebuild async
wheel targets, and serialize the async scroll metadata needed to
reconstruct AsyncScrollingState from the same display-list snapshot.

Driving the async scroll tree off the display list rather than a
separately collected tree has a few benefits:

- No additional full paintable tree traversal is required, since the
  information needed by the compositor is gathered while recording
  the display list.
- The display list is already serializable, so the async scroll tree
  no longer needs its own serialization path.
- It is more debuggable, as the existing display list dump now also
  covers the data used to reconstruct the async scroll tree.
- In the future we will want to include other areas that can
  interfere with hit-testing; recording them during display list
  construction makes it straightforward to preserve a hit-testing
  order that matches painting order.
2026-05-13 18:36:07 +02:00
Andreas Kling
76fc843978 LibWeb: Run observers after compositor-only scrolls
Adopt pending async viewport scroll offsets before the rendering update
runs scroll steps and IntersectionObserver updates. Queue a rendering
update after the compositor applies an async viewport scroll so
compositor-only wheel scrolling can notify observers without waiting for
unrelated main-thread work.
2026-05-13 15:00:31 +02:00
Andreas Kling
d4c645b7a4 LibWeb: Preserve async scroll offset across scroll updates
Keep compositor-side scroll snapshots aligned with async viewport
scrolling when main-thread scroll state arrives while an async viewport
offset is pending. A stale scroll-state-only update could otherwise
replace the snapshot used for display list replay and wheel hit-testing
with an older viewport offset, even though the compositor had already
presented newer async scroll positions.

Teach AsyncScrollTree to set a node scroll offset directly and use it
when reconciling both display-list and scroll-state updates. Recompute
the main-thread viewport rect after display list recording as pending
async scroll adoption can move the viewport before presentation.
2026-05-13 11:00:59 +02:00
Andreas Kling
f07b55c2df LibWeb: Scroll the viewport on the compositor thread
Use the snapshot from the previous commit to let CompositorThread apply
experimental viewport wheel deltas when async scrolling is enabled. The
event handler first performs synchronous admission on the main thread,
then enqueues a compositor scroll command instead of mutating live
document scroll state directly.

Rasterize accepted scrolls through the same compositor presentation
path added earlier. The compositor stores the newest async viewport
offset so the next main-thread display-list recording can adopt it
before repainting, preventing older paints from snapping the visible
position backward.

Keep DOM wheel dispatch on the main thread. When the compositor already
performed the default action, dispatch the wheel as non-cancelable and
suppress a second default scroll. Non-viewport targets, nested
scrollers, and pages with blocking wheel listeners stay synchronous.
2026-05-12 20:57:08 +02:00
Andreas Kling
1b810a5e15 LibWeb: Present frames through Compositor IPC
Introduce a dedicated Compositor IPC channel between the UI process and
WebContent. Use it for backing-store setup, presented bitmap delivery,
and bitmap-specific ready_to_paint acknowledgements.

This makes CompositorThread the single owner of frame presentation
bookkeeping before async scrolling starts producing frames without the
main thread.

Remove old paint and backing-store messages from WebContentClient and
PageClient so the UI process no longer observes two presentation
protocols.
2026-05-12 20:57:08 +02:00
Andreas Kling
584b2748ee LibWeb: Move RenderingThread into Compositor
Create Libraries/LibWeb/Compositor and make the existing rendering
thread the first owner in that subsystem. Rename RenderingThread to
CompositorThread so later commits can grow it into the presentation
owner without leaving that vocabulary in HTML.

Keep display-list rasterization and delivery behavior unchanged in this
commit. Add COMPOSITOR_DEBUG to AK/Debug.h.in in the same step so
compositor diagnostics live beside the rest of the project-wide debug
toggles from the start of the stack.
2026-05-12 20:57:08 +02:00
Aliaksandr Kalenik
671cc8595a LibWeb: Send scroll-state-only updates to the rendering thread
When nothing invalidates the display list between frames, push only an
updated scroll state snapshot to the rendering thread instead of
handing it the display list again.

This is preparation for moving rendering to a separate process, where
sending the display list across the process boundary on every frame
would be expensive.
2026-05-11 22:52:38 +02:00
Timothy Flynn
b221d7fe8b LibWeb+LibWebView+WebContent+UI: Add an action to cut text 2026-05-07 09:13:06 -04:00
Aliaksandr Kalenik
568b7ce7ea LibWeb: Make Paintable tree ref-counted
The Paintable tree and its supplemental painting data structures were
GC allocated because that was the easiest way to manage it and avoid
leaks introduced by ref cycles. This included the Paintable subclasses
themselves plus StackingContext, ChromeWidget, Scrollbar, ResizeHandle,
and scroll-frame state.

We are now trying to reduce GC allocation churn on layout and painting
updates, so keeping this short-lived rendering tree outside the JS heap
is a better fit. Move Paintable to RefCountedTreeNode, make painting
helpers ref-counted or weakly reference Paintables, and update the
layout and event-handler call sites to use RefPtr/WeakPtr ownership.
2026-05-07 15:03:44 +02:00
Jelle Raaijmakers
b488b7e7b1 LibWeb: Propagate line box borders debug toggle to child navigables
Only the top navigable received this setting; existing and new
descendant navigables never showed these debug boxes.
2026-05-05 23:47:23 +02:00
Aliaksandr Kalenik
5854bf10e6 LibWeb: Give the rendering thread its own Skia backend context
Sharing a single SkiaBackendContext between the main thread and the
rendering thread forces locking around every GPU operation. Now that
ImmutableBitmaps are context-neutral, the SkImage cache is per-painter,
and PaintingSurface accepts an explicit context, have the rendering
thread create its own GPU context on startup and use it for the
display-list player and backing store allocation.

This sets up the next commit to remove the cross-thread locking
machinery entirely.
2026-05-04 20:12:21 +02:00
Andreas Kling
e5b9dbbe96 LibWeb: Run inform_the_navigation_api_about_aborting inline
The spec says to run inline if on the navigable's active window's
relevant agent's event loop, otherwise queue. WebContent is always on
the main thread event loop, so this collapses to "always inline".
Queueing here let the abort cancel a navigate event created later in
the same task, instead of the one it was queued for.
2026-04-27 17:24:13 +02:00
Shannon Booth
8642801889 LibWeb: Set fragment scripting mode from the context document
This corresponds with the editorial change to the HTML standard
introducing the parsing mode enum of:

01c45cede

And a follow up normative change of:

508706c80

Making fragment parsing derive its scripting mode from the context
document.
2026-04-14 23:01:36 +02:00
Aliaksandr Kalenik
d9eec0d204 LibWeb: Replace ScrollStateSnapshotByDisplayList with a plain snapshot
Cleanup following the per-Navigable rasterization split: since each
Navigable now rasterizes its own display list independently, the HashMap
keyed on display list was always populated with exactly one entry. Pass
the ScrollStateSnapshot directly through the display list player and
rendering thread instead.
2026-04-07 15:09:43 +02:00
Aliaksandr Kalenik
ad2ee4fe7a LibWeb: Rasterize each Navigable independently on its own thread
Previously, iframes were rasterized synchronously as nested display
lists inside their parent's display list: the parent's paint walk called
record_display_list() on each hosted iframe document and emitted a
PaintNestedDisplayList command that the player would recurse into. Only
the top-level traversable's RenderingThread was ever active, even though
every Navigable already owned one.

The motivation for splitting this apart:
- Work in the outer document no longer has to be re-recorded when only
  an iframe changes. The parent's cached display list now references the
  iframe's rasterized output live via an ExternalContentSource, so an
  iframe invalidation just needs the parent's display list replayed, not
  re-recorded.
- Each iframe now has a self-contained rasterization pipeline, which is
  prep work for moving iframes into separate sandboxed processes.
2026-04-07 15:09:43 +02:00
Shannon Booth
bb0f244667 LibWeb: Remove ShadowRealm HTML integration 2026-04-05 13:57:58 +02:00