Commit graph

171 commits

Author SHA1 Message Date
Andreas Kling
83b293e4f2 LibCore: Keep main event loops alive
Add an explicit initializer for process-lifetime event loops and use it
for browser, helper service, and utility main loops. This preserves weak
event loop references for cross-thread users while making main thread
loop lifetime independent of normal program teardown.
2026-06-05 09:18:39 +02:00
Sam Atkins
121105eb83 LibWebView+WebContent: Pass DOM inspection options
Extend the existing DOM node inspection request with an options payload
and carry it through the browser process, WebView, IPC, and WebContent.
This lets later DevTools requests forward Firefox's top-level flags
without changing any inspected-node behavior yet.
2026-06-04 20:54:33 +01:00
Timothy Flynn
7fc71e563b LibWebView+UI: Reduce boilerplate to update the bookmarks bar display
We currently use LibWebView's Application as the entry point to learn
about the bookmarks bar being shown/hidden, and propagate that through
virtual methods. At the time this was added, AppKit's Tab window and
Qt's BrowserWindow did not have a settings observer. They do now, so
let's skip a couple of middle-men.

For AppKit, we change the settings observer to just (weakly) store the
Tab instance so that we don't have to add callback functions for each
setting.
2026-06-03 18:14:12 -04:00
Timothy Flynn
83105b8349 LibWebView+UI/Qt: Move the show menu bar setting to LibWebView settings 2026-06-03 18:14:12 -04:00
Timothy Flynn
43175e5a07 LibWebView: Don't hard-exit for failed content blocker list reads
We currently just log an "open" failure from LibMain with no extra info.
Even once the source is discovered, the user then has no way to fix the
issue other than to manually find and edit the settings JSON. Let's log
the error and move on.
2026-06-02 14:32:06 -04:00
Sam Atkins
cbbd2e173e LibDevTools+LibWebView: Support DevTools URL navigation
Firefox's remote toolbox exposes an editable URL field for tab
descriptors. Submitting that field sends navigateTo to the tab
descriptor rather than the frame target.

Handle the request in the tab actor, route it through the DevTools
delegate, and reuse WebView's URL sanitizing and load path. Add protocol
coverage so the toolbar navigation request stays wired up.
2026-06-01 15:09:25 +01:00
Sam Atkins
be3cc9ec39 LibDevTools+LibWebView: Support DevTools history navigation
Firefox's inspector toolbar sends goBack and goForward requests to the
tab descriptor when the descriptor advertises navigation support. Thread
those requests through the DevTools delegate and reuse the existing
WebView session-history traversal path.

Keep the legacy frame-target requests working too, matching Firefox's
window-global target compatibility surface. Add protocol coverage for
both entry points so the advertised trait and deltas stay locked down.
2026-06-01 15:09:25 +01:00
Sam Atkins
7c1e911fa9 LibDevTools+LibWebView: Support DevTools page reloads
Firefox reloads remote targets through the tab descriptor's
reloadDescriptor request. We advertised support for that request, but
left it unhandled, so Firefox could clear inspector state without
causing Ladybird to reload the page.

Route reloadDescriptor, and the legacy frame target reload request,
through the DevTools delegate to WebView's reload path. This lets the
existing navigation notifications publish the replacement inspector root
after the reload completes.
2026-06-01 15:09:25 +01:00
Timothy Flynn
f0ac723539 LibWebView: Add settings and actions to control vertical tabs
This adds a setting to enable vertical tabs and to expand/collapse them
if enabled. This setting is hidden for UIs that do not support them
(which is every UI as of this commit).
2026-05-31 21:24:57 +02:00
Aliaksandr Kalenik
758688a7a1 LibWebView+UI: Replay display metadata after Compositor restart
Compositor recovery recreated contexts and replayed viewport sizes,
but it left the restarted helper with the default display metadata. A
recovered context could fall back to a 60 Hz timer instead of the
window's current display id and refresh rate until the frontend later
observed a screen change.

Store the display id in the shared view state, alongside the existing
maximum frame rate, and replay both values while restoring view state
after reconnect.
2026-05-31 20:07:58 +01:00
Aliaksandr Kalenik
538a1522dc Compositor+LibWebView: Add debug action to crash Compositor
This is very useful for making sure Compositor process recovery works
correctly.
2026-05-31 20:07:58 +01:00
Aliaksandr Kalenik
7c47643da6 Compositor+LibWeb+LibWebView: Simplify compositor context IDs
Page-presenting compositor contexts still carried a separate tagged ID
namespace and Browser-side page/context maps even though page IDs are
now allocated globally by the UI process. That made context
registration keep two ways to describe the same relationship and
forced compositor IPC to pass an extra presentation bit.

Use each page ID directly as its page-presenting compositor context ID
and allocate non-page compositor contexts from the same Browser-owned
counter. The registration path now sends only the optional page ID, and
Compositor infers client presentation from that page ID.
2026-05-30 17:30:00 +01:00
Aliaksandr Kalenik
626dc6ff3f LibWebView+WebContent: Make page IDs browser-assigned
Page IDs were allocated independently by each WebContent PageHost,
starting at zero for every process. That made them unsuitable as a
global identity for page-presenting compositor contexts, because the
same numeric page ID could exist in multiple WebContent processes.

Move page ID allocation to WebView::Application and initialize each
WebContent process with its browser-assigned first page ID over IPC.
New view requests now get a browser-assigned page ID before
WebContent creates the PageClient, and PageHost no longer owns a
local page counter.

This gives page-presenting compositor contexts a stable global page
identity, which will allow their context IDs to be derived from page
IDs and simplify compositor context allocation in a follow-up.
2026-05-30 17:30:00 +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
Luke Wilde
9be221abff LibWebView: Let Settings clear HSTS policies 2026-05-29 22:23:33 +02:00
Luke Wilde
08766d47f4 LibWeb+LibHTTP+LibWebView: Implement HSTS
When an HTTPS response carries a Strict-Transport-Security header, the
received policy is now respected. Subsequent HTTP requests to a known
HSTS host are upgraded to HTTPS before the fetch algorithm makes
further decisions such as CORS and mixed content.

Fixes tpexpress.co.uk, where an XHR redirects HTTPS -> HTTP -> HTTPS,
relying on a HSTS policy received on the document response to avoid the
CORS failure.
2026-05-29 22:23:33 +02:00
Sam Atkins
3a332b23e5 LibWebView: Wire node picker state to hit testing
LibWebView owns the active page connection and bridges the DevTools
delegate to WebContent. Track picker state there, translate UI hover,
preview, pick, and cancel requests into hit-test IPC, and forward the
resulting node ids back through the DevTools callback.

Keeping the request bookkeeping in LibWebView also lets the platform UI
frontends share the same picker behavior.
2026-05-29 17:01:34 +01:00
Timothy Flynn
aeb52da835 LibWebView+WebContent: Add a debug menu item to crash the current page
I've had this sitting around in a git stash for a while. Sometimes it is
useful to be able to answer "what happens if we crash right now".
2026-05-29 10:46:27 -04:00
Timothy Flynn
89d54a6c99 LibWebView: Add an option to show the advanced debug menu
As we approach an alpha release, it will generally make less sense to
show all of the debug options in the application menu. Add a persistent
setting to show this menu, disabled by default.
2026-05-29 10:46:27 -04:00
Aliaksandr Kalenik
6598fb838d LibWebView+Compositor+UI: Send display metadata to Compositor
The browser process forwards the maximum frame rate to WebContent, but
the compositor process had no copy of that display timing metadata or
the display identity needed by compositor-local vsync.

Add one compositor control IPC message carrying the optional display ID
and refresh rate together, and store both values on each compositor
context.
2026-05-28 23:12:35 +01:00
Sam Atkins
2000fd38c1 DevTools+WebContent: Support the flexbox highlighter 2026-05-28 12:58:46 +01:00
Sam Atkins
0229fd9ee1 WebContent+LibWebView: Add flexbox inspection plumbing 2026-05-28 12:58:46 +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
Timothy Flynn
793e7dd01b LibWeb+LibWebView+UI: Update the selection keyboard on selection changes
When the selected text on a page changes, update the system selection
clipboard on supported systems (if primary pasting is enabled).
2026-05-27 13:33:44 -04:00
Timothy Flynn
082281da62 LibWebView+UI: Disable primary paste on unsupported systems
A selection clipboard is not available on all systems. The UI now
controls whether this feature is available.
2026-05-27 13:33:44 -04:00
Timothy Flynn
adf5e0a226 LibWeb+LibWebView+UI: Use the system selection text for primary pasting
Commit 218d82cb65 added support for
pasting text with the middle mouse button. But primary pasting is
actually meant to interact with the "selection" clipboard, not the
text clipboard.
2026-05-27 13:33:44 -04:00
Sam Atkins
2e430bb0b4 DevTools: Add grid layout WebContent plumbing
Add IPC structures and requests for inspecting grid layout data from
WebContent.

WebView forwards the async replies to LibDevTools and exposes the grid
highlighter hooks used by the protocol layer.

Parse Firefox grid highlighter options in WebContent and store them with
the active grid highlight.
2026-05-27 17:47:50 +01:00
Ali Mohammad Pur
842e8a6796 LibWasm+LibWeb: Add per-module wasm compile stats 2026-05-27 09:52:34 +02:00
Aliaksandr Kalenik
e10345c4e3 Compositor+LibWebView: Tolerate stale UI mouse contexts
Browser UI input can race with compositor context teardown during tab
close. The control connection may ask the compositor to handle, scroll,
or forward a mouse event after WebContent has already destroyed the
context. Treating that as an invariant crashes the compositor even
though the event is stale.

Make the UI-facing mouse handling and async scroll entry points return
false when the context is gone. Mouse forwarding now reports whether it
actually dispatched the event, letting LibWebView fall back to direct
WebContent IPC and preserve the normal input-event acknowledgement flow.
2026-05-25 20:36:33 +01:00
Aliaksandr Kalenik
805e2fa7b3 LibWebView+WebContent: Remove compositor thread option
Remove the command-line option that allowed Browser to start
WebContent with the in-process compositor thread instead of the
Compositor helper process. The compositor process is now the default
path, so the opt-out flag and the matching WebContent selector only kept
the old thread mode reachable.

With that option gone, simplify Browser and WebContent startup to wire
each WebContent process to the Compositor process directly. The old
local Browser-to-WebContent compositor IPC setup and its fallback input
and ready-to-paint branches are no longer needed.
2026-05-25 00:45:24 +02:00
Aliaksandr Kalenik
74e77a0e19 LibWebView+WebContent: Enable the compositor process by default
The compositor process is stable enough to run by default now.
2026-05-24 17:40:44 +01:00
Andreas Kling
5fef343164 LibWebView: Load content blocker lists from settings
Add a content_blocking.list_paths advanced setting backed by a JSON
array. This lets content blocker list paths avoid splitting one string.
The about:settings editor presents array values as one path per line.
It persists them as arrays.

Load configured paths before command-line paths so temporary lists can
still be appended for a single browser session.
2026-05-24 16:59:59 +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
9479bc8d7f LibWebView+WebContent: Add feature-gated Compositor process backend
We are moving toward an architecture where the browser owns a single
process that holds the GPU context, so Skia resources can be shared
across every renderer and WebContent processes can be sandboxed away
from direct GPU access. A dedicated Compositor helper process is the
first step. The earlier commits laid the foundation; this one turns the
helper on as a selectable backend, gated behind
--enable-compositor-process so the existing in-process path stays the
shipping default.

Default topology -- one compositor per WebContent, in-process:

      +---------+
      | Browser |
      +---------+
      /    |    \
     v     v     v
   +---+ +---+ +---+    each WebContent runs its own
   |WC | |WC | |WC |    CompositorThread on a dedicated
   |+C+| |+C+| |+C+|    thread, with its own GPU context.
   +---+ +---+ +---+

Opt-in topology -- one single-threaded Compositor, shared by all WCs:

   +---------+   control   +-------------------+
   | Browser |<----------->|    Compositor     |
   +---------+             |  (single thread,  |
   /    |    \             |   single GPU ctx, |
  v     v     v    data    |   shared by all   |
 [WC] [WC] [WC] ---------->|   connected WCs)  |
                           +-------------------+

Three IPC channels carry the work in the opt-in topology. The
existing Browser<->WebContent channel gains context allocation.
A new Browser<->Compositor channel carries context lifetime,
viewport, UI input, and presentation acks plus backing-store and
frame upcalls. A new WebContent<->Compositor channel carries
display lists, scroll state, video, compositor surfaces, async
scrolling, presentation, and screenshots, with upcalls for
delegated input and compositor loss.
2026-05-22 19:50:42 +01:00
Aliaksandr Kalenik
3eae2c0f3e LibWebView+WebContent: Allocate compositor contexts in Browser
The helper process is a Browser-owned singleton, so Browser has to be
the source of truth for which contexts exist: it is the only party that
can register them with the helper, route backing-store and presentation
upcalls back to the right WebContent and page, and reap them when a
WebContent crashes. Move id allocation into Browser and have WebContent
ask for ids over IPC, so the runtime switch in the next commit only has
to select the backend. Behavior is preserved because Browser reproduces
the previous deterministic-vs-fresh allocation logic and the in-process
compositor still owns rendering.
2026-05-22 19:50:42 +01:00
Aliaksandr Kalenik
bfc9bf80d9 Compositor+LibWebView+WebContent: Scaffold opt-in Compositor process
The compositor is moving into a dedicated helper process. That requires
a process to launch, channels for Browser and WebContent to talk to it
over, and client proxies on each side. Land all of that as an inert
scaffold first, gated behind --enable-compositor-process, so the default
rendering path is unchanged and later commits can fill in the protocol,
the service-side state, and the runtime switch against a stable target.
2026-05-22 19:50:42 +01:00
Andreas Kling
6be5e80025 LibWebView: Share content blocker lists as buffers
Add a repeatable blocker-list option that reads local list files in the
browser process. The files are concatenated into one buffer and shared
with WebContent through the content blocker IPC path when view options
are applied.

Parse the buffer in WebContent and reject malformed UTF-8 without
replacing the currently installed rules.
2026-05-21 21:16:56 +02:00
Andreas Kling
46e1a08742 LibWeb: Rename ContentFilter to ContentBlocker
Rename the local content blocking implementation and its tests from
ContentFilter to ContentBlocker while keeping the existing substring
matcher backend and behavior.

Update the WebContent IPC method, WebView option names, debug toggle,
and default config file name to use content blocker terminology.
2026-05-21 21:16:56 +02:00
Aliaksandr Kalenik
9eee1f4488 LibWebView+WebContent: Enable async scrolling by default
Async scrolling is now correct enough to run by default, so keep it
enabled in normal browsing and test coverage to catch the remaining
issues.
2026-05-15 01:54:15 +02:00
Sam Atkins
9b53baa652 LibWebView: Track recently closed tabs and windows
Maintain a stack of URLs and when they were closed, and allow popping
the most recent one.

These are stored directly on HistoryStore instead of its Storage object,
because they should never persist regardless of which backend we're
using. Even so, we still clear them along with other history data.
2026-05-13 11:03:41 +01:00
jeetsh4h
44476de9c5 UI+LibWebView: Implement "Open Link in New Window" 2026-05-13 05:00:50 -05:00
Andreas Kling
6aa6b0972f LibWebView: Report active clean WebContent exits as crashes
Only treat a clean WebContent exit as intentional when the process no
longer has any attached views. If WebContent exits with status 0 while a
view is still attached, notify that view just like any other renderer
crash so test-web can complete the active test instead of leaving it
unresolved.

Also mark the Unix-only exit status parameter as used on Windows, where
we cannot decode a wait status.
2026-05-12 20:57:08 +02:00
Andreas Kling
a031d00695 WebContent: Exit cleanly when browser IPC disconnects
Exit WebContent immediately when either browser-side IPC peer
disconnects. Plumb Unix process exit status through LibWebView so the
browser process can tell clean owner-driven shutdown apart from renderer
crashes.

This keeps nonzero exits and signal deaths reported as crashes, while
letting status 0 exits disappear without making test-web report the page
as crashed.
2026-05-12 20:57:08 +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
Timothy Flynn
de0e7878fc LibWebView: Mark the debug process command line option mode as required
If this flag is present, there must be an argument provided. Commit
11f82ee3b7 marked this flag as optional,
which then meant an equals sign was required to specify the process to
be debugged.
2026-05-11 09:29:29 -04:00
Timothy Flynn
b221d7fe8b LibWeb+LibWebView+WebContent+UI: Add an action to cut text 2026-05-07 09:13:06 -04:00
Timothy Flynn
c4cef88c1a LibWebView: Don't invoke the selected-text IPC twice for menu activation
This second invocation was mistakenly added in 7385569a02.
2026-05-07 09:13:06 -04:00
Andreas Kling
c919f1c28f LibWebView: Add style invalidation counter dump option
Add --dump-style-invalidation-counters=N to Ladybird and propagate it
to WebContent helper processes.

When enabled, WebContent dumps the current document style invalidation
counters with dbgln() after every N recorded style invalidations. This
makes it possible to collect the counters while browsing without adding
temporary C++ logging.
2026-04-30 00:24:04 +02:00
Andreas Kling
072a3bdb90 RequestServer: Add diagnostic wire-activity logging
Per-request and per-connection logging that surfaces enough detail
to diagnose where time goes when a page load misbehaves. Gated by a
new REQUESTSERVER_WIRE_DEBUG cmakedefine.

Documentation/RequestServerWireLogging.md describes each label
(wire/wire+/wire++/wire^, wire-batch, wire-stall, wire-burst,
wire-pipe-pressure, LibDNS wire-dns, UI wire-cookie) and how to read
them.
2026-04-26 17:59:52 +02:00
Timothy Flynn
83eda625d5 LibWebView: Remove new tab page URL from sanitize_urls API
This used to come from UI-specific settings (e.g. QSettings). But it's
stored in LibWebView now, so we don't need callers to provide it.
2026-04-24 20:17:23 +02:00