Commit graph

112 commits

Author SHA1 Message Date
Andreas Kling
67030ceead LibWebView: Complete WebDriver same-document traversals
Complete pending WebDriver navigation waits when WebContent confirms
that a same-document history traversal step was applied. These
traversals do not always produce a load event, and waiting only for a
later session history snapshot could let the WebDriver command return
before the UI had observed the applied step.

This keeps the WebDriver session history test from racing into later
commands while a previous same-document traversal is still settling.
2026-06-14 17:38:44 +02:00
Andreas Kling
24f37c6732 LibWebView: Keep browser history in the UI process
Use the LibWebView history mirror to preserve traversable session
history across WebContent process swaps. WebContent reports snapshots to
the UI process, and new renderers can be seeded from the mirror.

Browser back and forward now resolve through the UI-owned used history
steps. WebContent still runs the spec traversal path when the current
renderer has enough matching state to do so.

Handle canceled and no-op UI navigations without leaving speculative
history entries or pending WebDriver waits behind. Preserve traversal
precheck state across synchronous IPC shutdown, and avoid overwriting a
restored target entry's persisted scroll state before the document has
adopted that entry.
2026-06-14 17:38:44 +02:00
Sam Atkins
0b9e59f61f LibDevTools: Allow editing Web Storage
Firefox sends the same storage actor mutation requests for Web Storage
that it uses for cookies. Handle addItem, editItem, removeItem, and
removeAll for localStorage and sessionStorage actors.

Apply the changes through the browser-process storage jar and emit the
matching store update packets so the Storage panel stays current after a
DevTools-initiated edit.
2026-06-11 16:08:33 +01:00
Sam Atkins
a75e9f23db LibWeb+LibDevTools: Report Web Storage changes
Firefox keeps the Storage panel current by sending store update packets
when localStorage or sessionStorage changes. Forward successful Web
Storage mutations to the storage actors and emit the matching update or
clear packet.

Use listener IDs for storage updates so the local and session storage
actors can subscribe independently.
2026-06-11 16:08:33 +01:00
Sam Atkins
ddb4bdadd7 LibDevTools: Populate DevTools Web Storage
Firefox exposes localStorage and sessionStorage through the same
storage actor protocol used by cookies. Add matching resources for the
current tab so the Storage panel can list key/value pairs.

Read the values through WebContent rather than directly from the
browser process. Session storage lives in LibWeb, and using the same
path for both stores keeps the actor independent of the backing store.
2026-06-11 16:08:33 +01:00
Sam Atkins
47204bd3dd LibDevTools: Report cookie storage changes
Firefox keeps the Storage table current through storesUpdate messages
from the storage actor. Forward browser cookie change notifications to
the cookies actor and classify visible rows against a fresh cookie
snapshot.

The existing cookie-change notifications report cookies that are
relevant to a specific page, whereas DevTools wants all cookies
relevant for a host, so we end up having to provide two different sets
of cookies to `notify_cookies_changed()`.
2026-06-11 15:03:47 +01:00
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
Tim Ledbetter
cdb8762c8f LibWebView: Add a --screenshot-path option
This option saves screenshots to the given location.
2026-06-07 00:20:19 +12:00
Callum Law
52db9e9e5d LibWebView: Remove Native.css
The last user (the built-in inspector) was removed in 810d04b.
2026-06-05 12:59:00 +01: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
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
Andreas Kling
3ae41f1ac8 LibWebView: Normalize wheel deltas to CSS pixels
Platform wheel deltas describe movement in the view, not in page CSS
pixels. Convert them by page zoom before dispatch so physical scrolling
covers a smaller page area when zoomed in.

Do this before the UI-side async scrolling shortcut so compositor
scrolling and main-thread fallback scrolling use the same delta. Also
avoid applying the Qt device pixel ratio while converting angle-only
wheel input, since LibWeb later handles device-pixel scaling itself.
2026-06-01 10:00:19 +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
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
Andreas Kling
75211c4160 LibWebView: Preserve old frame across process swaps
Keep the outgoing front bitmap as the backup image before replacing the
WebContent process for cross-site navigation. This lets the view keep
painting the old page until the new process presents its first frame,
rather than falling back to a flat background during loading.
2026-05-27 20:57:38 +02:00
Andreas Kling
39f8101a7d LibWebView: Track forced color scheme for fallback fills
Remember the preferred color scheme selected through the debug menu when
choosing the web view fallback background. Keep using an explicit forced
scheme even if the platform theme changes underneath it.
2026-05-27 20:57:38 +02:00
Andreas Kling
43b9cfe5a9 LibWebView: Avoid white initial web view fills in dark mode
Seed the page background fallback from the platform color scheme before
WebContent has painted. Update the same fallback when the platform theme
changes, and when the preferred color scheme is forced through the debug
menu, so unpainted web view areas use the matching Canvas color.
2026-05-27 20:57:38 +02: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
Andreas Kling
e0e8460c47 UI: Update page visibility when switching tabs
Send hidden and visible system visibility updates from explicit tab
switch paths instead of relying only on widget show and hide events. Tab
containers can keep inactive web views mapped, which leaves documents
visible from WebContent's perspective and lets animated images keep
running in background tabs.

Use AppKit window occlusion state rather than the app-wide active tab.
That keeps still-visible background windows in the visible document
state. Avoid resending duplicate visibility updates from
ViewImplementation so existing widget visibility notifications remain
harmless.
2026-05-27 18:44:42 +02:00
Andreas Kling
42f89bb679 LibWebView: Fast-close pages without beforeunload prompts
Track whether WebContent still needs a beforeunload check and let the
frontends immediately remove a tab or window when no prompt can be
shown. WebContent still receives the close request so pagehide, unload,
and cleanup steps can run.

When the visible view is removed immediately, keep detached ownership of
the WebContent page until it reports that the top-level traversable
closed. If no acknowledgement arrives, release detached ownership and
ask ProcessManager to shut down the unused WebContent process.
2026-05-26 20:40:25 +02:00
Andreas Kling
2eb14f2c2f LibWebView: Mark compositor viewport updates as resizing
Tell the compositor that viewport updates from handle_resize are part of
a resize operation. This keeps the compositor backing store manager on
its padded live-resize path instead of forcing an exact-size backing
store allocation for every browser window resize tick.
2026-05-26 16:24:25 +02: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
Andreas Kling
8be96396d9 LibWebView: Use page background color while resizing
Notify the UI process with the solid canvas background color recorded
for the top-level document. This is the Canvas system color with the
effective document background composited over it, matching the color
used before normal painting.

Store that color on the view and use it when AppKit, Qt, and Gtk need
to fill areas exposed while an older bitmap is still on screen during a
window resize.
2026-05-24 23:41:41 +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
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
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
Andreas Kling
99129f37a2 LibWeb: Handle viewport scrollbar drags in the compositor
Route mouse events over the compositor IPC path while async scrolling is
enabled, and let the compositor capture viewport scrollbar drags before
the main-thread event path sees them. Dragging mutates the compositor
scroll tree and schedules an async-scroll present, so the viewport thumb
and content can move without a main-thread round trip.

Keep normal main-thread event handling for misses and preserve the wheel
bypass behavior for page events.
2026-05-13 13:15:45 +02:00
jeetsh4h
44476de9c5 UI+LibWebView: Implement "Open Link in New Window" 2026-05-13 05:00:50 -05:00
Aliaksandr Kalenik
0a41859ae9 LibWeb+LibWebView: Feed async scroll deltas in device pixels
The synchronous wheel path treats wheel deltas as CSS-pixel scroll
distances, while the async compositor scroll tree mutates scroll state
stored in device pixels. Passing the same unscaled delta into the
compositor made async scrolling advance too little whenever
device pixels per CSSPixel was greater than 1, so scrolling felt slower
than with async scrolling disabled.

Convert wheel deltas before crossing the compositor boundary and make
the compositor IPC carry only the device-pixel position and delta it
needs. This keeps AsyncScrollTree device-pixel native and makes async
viewport scrolling match the synchronous path across high-DPI displays
and page zoom levels.
2026-05-12 22:35:54 +02:00
Andreas Kling
780083a0e2 LibWeb: Add compositor debug logging
Trace the compositor state transitions that matter once presentation and
async scrolling share one path: page registration, backing-store swaps,
did_paint delivery, ready_to_paint acknowledgements, wheel admission,
and deferred presents waiting for reusable bitmaps.

Keep the logs under COMPOSITOR_DEBUG and use the [Compositor] prefix
consistently. The trace is about ownership and backpressure instead of
dumping every wheel event detail, so stalls can be diagnosed without
reintroducing noisy async-scrolling-only logging.
2026-05-12 20:57:08 +02:00
Andreas Kling
5d4137173a LibWebView: Route wheel bypasses over Compositor IPC
Send the experimental UI-process wheel bypass to WebContent over the
Compositor IPC connection instead of adding a separate async scrolling
transport. This keeps bypass admission on the channel that owns bitmaps
and ready_to_paint acknowledgements.

If the compositor rejects the wheel, LibWebView falls back to regular
input delivery. If it accepts, mark the queued DOM event as having
already performed its default action so dispatch preserves ordering
without scrolling twice.
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
Timothy Flynn
b221d7fe8b LibWeb+LibWebView+WebContent+UI: Add an action to cut text 2026-05-07 09:13:06 -04:00
Andreas Kling
c7e24fce2f LibWebView: Persist and restore zoom level per host
Remember the zoom level for each host so that returning to a site
restores the zoom the user previously chose, matching what other
browsers have done for years.

When the user zooms in, zooms out, or resets the zoom, the resulting
level is written to Settings keyed by the current page's host. On
navigation, when a view's URL host changes, the stored level for the
new host is applied (or the global default if there is no override).

Per-host zoom changes are broadcast through the SettingsObserver so
that two tabs viewing the same host stay in sync as soon as the user
adjusts zoom in either one. Zoom changes from within the page (such
as internals.setBrowserZoom hook) and the WebContent restart path do
not persist, only user-initiated zoom changes do.
2026-05-05 13:53:59 +02:00
Timothy Flynn
fdbdb0ecd2 LibWebView+UI: Show an error page when we cannot sanitize a URL
Previously, if search was disabled, entering non-URL text would just
silently drop the search query (and on Qt, we would reload the current
URL). We now detect that the query did not result in a navigation and
load an error page instead, which directs the user to enable search.
2026-04-24 20:17:23 +02:00
Andreas Kling
87b6703054 LibWebView: Persist page metadata in history
Record visits as soon as a page produces useful metadata such as a
title or favicon so pages that never finish loading still become
autocomplete candidates.

Store favicons in the history schema from the start instead of
introducing an upgrade path inside this series, and cover persisted
metadata behavior in TestHistoryStore.
2026-04-16 21:01:28 +02:00
Timothy Flynn
79893b9cef LibWeb+LibWebView+WebContent: Add a setting to control autoscrolling 2026-04-13 13:01:45 -04:00
Aliaksandr Kalenik
75af441bff Everywhere: Replace SharedBackingStore with Gfx::SharedImage
Generalize the backing store sharing abstraction into SharedImage, which
represents shared GPU memory independently of Skia and can be used to
share memory between different processes or different GPU contexts.
2026-04-09 01:18:59 +02:00
Andreas Kling
9d2dd7b95b LibWebView: Don't always close WebContent on cross-site navigation
When a page opens a popup, the child tab shares the parent's
WebContent process via initialize_client_as_child(). Both tabs
register as views on the same WebContentClient.

If the child tab then does a cross-site navigation,
create_new_process_for_cross_site_navigation() would call
unregister_view() (correct) and then unconditionally send
CloseServer (wrong). This killed the WebContent process even
though the parent tab was still using it.

The unconditional async_close_server() predates the shared-process
popup model. It is no longer needed since unregister_view() already
sends CloseServer when the last view is removed.
2026-04-01 20:59:01 +02:00
Timothy Flynn
2025e6e523 LibWebView: Integrate bookmarks into the application menus and settings
This adds application menus and actions to display and manage bookmarks.
These menus will be used by the UIs to generate concrete widgets.
2026-03-24 12:04:50 -04:00
Timothy Flynn
58791db818 AK+LibWeb: Move generation of random UUIDs into AK
This will let us use this more outside of LibWeb more easily.

Stop handling tiny OOM while we are here.
2026-03-24 12:04:50 -04:00
Aliaksandr Kalenik
3cb644500e Everywhere: Send IOSurface backing stores via main IPC route on macOS
Now that LibIPC uses Mach ports for transport on macOS, IOSurface port
rights can be sent as regular IPC message attachments instead of through
a separate ad-hoc Mach message side-channel. Introduce
Web::SharedBackingStore that wraps either a MachPort (macOS) or
ShareableBitmap (other platforms) with IPC encode/decode support,
unifying backing store allocation into the existing
did_allocate_backing_stores IPC message.
2026-03-23 23:22:38 +01:00
Aliaksandr Kalenik
c6d740ea41 Everywhere: Remove dynamic Mach bootstrap registration on macOS
Registering multiple Mach port names with the bootstrap server at
runtime is not how macOS expects it to be used — the bootstrap server
is meant for static services, and the only reason we used it originally
was so child processes could reach back to the UI process.

Remove bootstrap_transport_over_socket(), which had both sides register
dynamic names with the bootstrap server and exchange them over a socket.
Instead, WebDriver and BrowserProcess connections now go through
MachPortServer instances directly. When a non-child process contacts a
MachPortServer, the server creates a port pair on demand (detected via
sysctl ppid check) and returns the local half immediately. This keeps
bootstrap server usage limited to the one original case: child processes
looking up their parent's MachPortServer.

WebDriver Session now runs its own MachPortServer per session.
--webdriver-content-path becomes --webdriver-mach-server-name on macOS.
Spare WebContent launches are skipped when a WebDriver session is active
to avoid bootstrap races.
2026-03-23 18:50:48 +01:00
Zaggy1024
01224dedde LibWebView: Actually set the fullscreen flag when entering fullscreen
Somehow this disappeared from #8461.
2026-03-20 20:28:32 -05:00
Zaggy1024
ac69815740 Everywhere: Add an is_fullscreen parameter to set_viewport
This will be used by the UIs to notify WebContent when fullscreen for
content is entered or exited.
2026-03-17 18:58:37 -05:00
Timothy Flynn
ae8181b467 LibWeb+LibWebView+UI: Add a context menu item to toggle fullscreen state 2026-03-01 15:41:43 -06:00
Simon Farre
04d1e2bf3d LibWeb: Implement exitFullscreen algorithm
Exiting fullscreen from the UI will be added in future commits.
2026-02-23 18:44:26 +00:00
Jelle Raaijmakers
1cc29c669a WebContent: Combine viewport size and DPR into a single IPC message
The set_viewport_size and set_device_pixel_ratio IPC messages were sent
separately, potentially causing a race condition when the DPR changes
(e.g. moving a window between screens): the DPR message would arrive
and use a stale viewport size, computing a temporarily wrong CSS
viewport. Combine both into a single set_viewport IPC that updates the
device viewport size and DPR together.
2026-02-23 15:22:12 +01:00