Commit Graph

314 Commits

Author SHA1 Message Date
Aliaksandr Kalenik
4ddba48e13 LibIPC+LibWebView: Remove MultiServer
MultiServer was inherited from SerenityOS where it was used in many
places. Now that BrowserProcess is its only consumer, inline the
connection acceptance logic directly into BrowserProcess and remove
the abstraction.
2026-03-20 23:23:28 +01:00
Andreas Kling
30f108ba36 LibJS: Remove C++ lexer, use Rust tokenizer for syntax highlighting
Delete Lexer.cpp/h and Token.cpp, replacing all tokenization with a
new rust_tokenize() FFI function that calls back for each token.

Rewrite SyntaxHighlighter.cpp and js.cpp REPL to use the Rust
tokenizer. The token type and category enums in Token.h now mirror
the Rust definitions in token.rs.

Move is_syntax_character/is_whitespace/is_line_terminator helpers
into RegExpConstructor.cpp as static functions, since they were only
used there.
2026-03-19 21:55:10 -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
Zaggy1024
d0a38bd046 WebContent: Remove the sync result from did_request_fullscreen_window
This was unused.
2026-03-17 18:58:37 -05:00
Aliaksandr Kalenik
19627bba54 LibIPC: Return TransportHandle directly from create_paired()
Previously, `create_paired()` returned two full Transport objects, and
callers would immediately call `from_transport()` on the remote side to
extract its underlying fd. This wasted resources: the remote
Transport's IO thread, wakeup pipes, and send queue were initialized
only to be torn down without ever sending or receiving a message.

Now `create_paired()` returns `{Transport, TransportHandle}` — the
remote side is born as a lightweight handle containing just the raw fd,
skipping all unnecessary initialization.

Also replace `release_underlying_transport_for_transfer()` (which
returned a raw int fd) with `release_for_transfer()` (which returns a
TransportHandle directly), hiding the socket implementation detail
from callers including MessagePort.
2026-03-14 18:25:18 +01:00
Aliaksandr Kalenik
db9652643a LibIPC+LibWeb+LibWebView: Remove clone_from_transport() API
Replace clone_from_transport() (which dup()s the FD) with
from_transport() (which releases the FD) in the WebWorkerClient
call site. The UI process never uses the WebWorkerClient connection
after spawning — it only passes the transport to WebContent — so
releasing instead of cloning is safe and simpler.

This removes clone_from_transport() from TransportHandle, and
clone_for_transfer() from TransportSocket/TransportSocketWindows,
as they no longer have any callers.
2026-03-13 15:34:15 +01:00
Aliaksandr Kalenik
7c8bdccc26 LibIPC+LibWebView: Remove raw fd accessors from TransportHandle
Now that auxiliary service sockets are sent over IPC rather than passed
as command-line arguments, TransportHandle no longer needs to expose raw
file descriptors or manage close-on-exec flags. Remove fd() and
clear_close_on_exec(), and simplify the connect helpers accordingly.
2026-03-12 20:32:55 +01:00
Aliaksandr Kalenik
429847e843 LibWeb+LibWebView+WebWorker: Send service sockets to workers over IPC
Instead of passing RequestServer and ImageDecoder socket FDs as
command-line arguments to WebWorker, send them over the main IPC channel
after launch. The worker-agent handoff now carries all three transport
handles (worker, RequestServer, ImageDecoder) so the connection path
matches WebContent.
2026-03-12 20:32:55 +01:00
Aliaksandr Kalenik
ff95e47802 LibWeb+LibWebView+WebContent: Send service sockets over IPC channel
Instead of passing RequestServer and ImageDecoder socket FDs as
command-line arguments to WebContent, send them over the main IPC
channel after launch. This unifies initial connection and reconnection
into a single code path.
2026-03-12 20:32:55 +01:00
Aliaksandr Kalenik
3bea3908b2 LibIPC+LibWeb+LibWebView+Services: Add IPC::TransportHandle
Add IPC::TransportHandle as an abstraction for passing IPC
transports through .ipc messages. This replaces IPC::File at
all sites where a transport (not a generic file) is being
transferred between processes.

TransportHandle provides from_transport(),
clone_from_transport(), and create_transport() methods that
encapsulate the fd-to-socket-to-transport conversion in one
place. This is preparatory work for Mach port support on
macOS -- when that lands, only TransportHandle's internals
need to change while all .ipc definitions and call sites
remain untouched.
2026-03-12 20:32:55 +01:00
Aliaksandr Kalenik
2e881978af LibIPC+LibWeb+LibWebView+Services: Add Transport::create_paired()
Consolidate the repeated socketpair + adopt + configure pattern from
4 call sites into a single Transport::create_paired() factory method.
This fixes inconsistent error handling and socket configuration across
call sites, and prepares for future mach port support on macOS.
2026-03-11 14:42:24 +01:00
Timothy Flynn
809ef1ac6e Base+LibWebView: Organize the settings page into tabs
The tabless page with an ever-growing list of vertical cards was getting
a bit disorganized. This moves each section of the settings page to be
its own tab, with buttons to switch tabs. Some of this presented the
opportunity to migrate settings from popup dialogs to be directly in the
tab, such as the disk cache settings.

The global "restore defaults" button has also been removed. The more
settings we have, the less sense such a button makes sense. Individual
settings can have a reset option where it makes sense.
2026-03-05 10:00:32 -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
Andreas Kling
b20d14970f LibWeb: Flatten Platform::FontPlugin by merging WebView::FontPlugin
WebView::FontPlugin was the only implementation of the abstract
FontPlugin base class. Its dependencies (LibGfx, LibCore) are
already visible to LibWeb.

Remove the virtual dispatch by making FontPlugin concrete and
absorbing the WebView::FontPlugin implementation directly.
2026-02-28 15:32:14 +01:00
Luke Wilde
6491c6bb90 test-web: Reset viewport size after each test 2026-02-23 18:44:26 +00: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
Simon Farre
bc17805b2b LibWeb: Implement requestFullscreen algorithm
The required functionality to exit fullscreen will be in a followup
commit.
2026-02-23 18:44:26 +00:00
Simon Farre
44e0735d9b LibWebView+UI/Qt: Allow WebContent to enter/exit the fullscreen UI
These IPC methods should be expanded in the future to allow WebContent
to specify what UI elements should be kept/removed, for example, the
navigation UI.
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
Shannon Booth
1be69479a6 LibURL+Elsewhere: Consider file:// origins opaque by default
This aligns our behaviour closer to other browsers, which
_mostly_ consider file scheme URLs as opaque. For test
purposes, allow overriding this behaviour with a commandline
flag.
2026-02-21 23:00:57 +01:00
Timothy Flynn
17a420cf97 test-web: Handle WebContent process changes during cross-site navigation
Commit 84db5d8c1c introduced the ability
to load tests over an http:// URL instead of a file:// URL. Each time
this happens, we switch to a new WebContent process due to site
isolation. Our WebContent output capture was not handling this.

For some reason, this was causing a wide array of test failures and
timeouts. Often, the failures were accompanied by the content of the
files loaded over HTTP being dumped to stdout. It's not quite clear
what was going on here.
2026-02-20 11:41:28 -05:00
Timothy Flynn
8ad1c72ed3 LibWeb+LibWebView+Services: Add a flag to enable experimental interfaces
This adds the --expose-experimental-interfaces command line flag to
enable experimental IDL interfaces. Any IDL interface with Experimental
in its exposed attributes will be disabled by default.

The problem is that by stubbing out or partially implementing interfaces
in LibWeb, we actually make some sites behave worse. For example, the
OffscreenCanvas interface being exposed makes sites believe we fully
support it, even though we don't. If the interface was not exposed,
these sites may fall back to ordinary canvas objects. Similarly, to
use YouTube, we currently have to patch out MSE interfaces.

This flag will allow developers to iteratively work on features,
without breaking such sites. We enable experimental interfaces during
tests.
2026-02-17 22:17:50 +01:00
Timothy Flynn
b357d3c3c8 LibWebView+WebContent: Move test-mode special handling to the UI process
We will need to propagate test mode behavior to both the WebContent and
WebWorker processes. By moving this handling to the UI process, we will
only need to update one location.
2026-02-17 22:17:50 +01:00
Andreas Kling
e87f889e31 Everywhere: Abandon Swift adoption
After making no progress on this for a very long time, let's acknowledge
it's not going anywhere and remove it from the codebase.
2026-02-17 10:48:09 -05:00
Luke Wilde
0e958ca8d5 LibWebView+UI/AppKit: Present IOSurfaces directly
Instead of copying the Bitmap that wraps the IOSurface, we can just
present the IOSurface directly. This significantly reduces CPU usage in
the UI process, particularly at high refresh rates such as 120Hz where
it would saturate a full CPU core.

This is done by using CAMetalLayer and blitting the IOSurface to the
next drawable buffer, which handles triple buffering, locking the
IOSurface and vsync automatically. This also allows the Metal HUD to
work, but the only accurate stat is the frame intervals/FPS because
it's in the UI layer, not WebContent. However, that's still useful
to detect frame drops.
2026-02-16 14:57:17 +00:00
Luke Wilde
10b5ccc931 WebContent+LibWebView: Add endpoint to request top level closure
This will allow the UI to request WebContent to properly close the top
level traversable when closing a tab. For example, this allows the site
to ask if the user is sure they want to leave, closes WebSocket
connections and more.
2026-02-14 23:26:10 +00:00
Andreas Kling
0f7df5f213 LibImageDecoderClient+LibWebView: Add animation session client API
Implement the client side of streaming animation decode sessions.
The ImageDecoderClient handles new IPC messages for frame delivery
and failure reporting, and the ImageCodecPlugin bridges this
through the platform abstraction layer used by LibWeb.
2026-02-13 18:34:24 +01:00
Timothy Flynn
7d60d0bfb7 LibHTTP+LibWebView+RequestServer: Allow users to set disk cache limits
This adds a settings box to about:settings to allow users to limit the
disk cache size. This will override the default 5 GiB limit. We do not
automatically delete cache data if the new limit is suddenly less than
the used disk space; this will happen on the next request. This allows
multiple changes to the settings in a row without thrashing the cache.

In the future, we can add more toggles, such as disabling the disk
cache altogether.
2026-02-13 10:20:52 -05:00
Timothy Flynn
e6c008a269 LibWeb+RequestServer: Attach HTTP cookie headers from RequestServer
We currently attach HTTP cookie headers from LibWeb within Fetch. This
has the downside that the cookie IPC, and the infrastructure around it,
are all synchronous. This blocks the WebContent process entirely while
the cookie is being retrieved, for every request on a page.

We now attach cookie headers from RequestServer. The state machine in
RequestServer::Request allows us to easily do this work asynchronously.
We can also skip this work entirely when the response is served from
disk cache.

Note that we will continue to parse cookies in the WebContent process.
If something goes awry during parsing. we limit the damage to that
process, instead of the UI or RequestServer.

Also note that WebSocket requests still have cookie headers attached
attached from LibWeb. This will be handled in a future patch.

In the future, we may want to introduce a memory cache for cookies in
RequestServer to avoid IPC altogether as able.
2026-02-10 12:21:20 +01:00
Timothy Flynn
8d97389038 LibHTTP+Everywhere: Move the cookie implementation to LibHTTP
This will allow parsing cookies outside of LibWeb.

LibHTTP is basically becoming the home of HTTP WG specs.
2026-02-10 12:21:20 +01:00
Adam Colvin
2df5a7bb31 LibJS: Add source locations to console.trace()
LibJS+DevTools: Implement console.trace() with source locations

- Add Console::TraceFrame struct with source location data
- Implement Console::trace() to gather stack information
- Add WebView::StackFrame and ConsoleTrace for IPC
- Implement DevToolsConsoleClient::printer() for traces
- Update FrameActor to format traces for DevTools
- Update WorkerDebugConsoleClient trace handling
- Update ReplConsoleClient to format trace output
2026-02-06 11:58:07 +00:00
Timothy Flynn
0482b6bb57 LibWeb+LibWebView+WebContent: Implement versioning for document cookies
This patch introduces a cookie cache in the WebContent process to reduce
blocking IPC calls when JS accesses document.cookie. The UI process now
maintains a cookie version counter per-domain in shared memory. When JS
reads document.cookie, we check whether we have a valid cached cookie by
comparing the current shared version to the last used version. If they
match, the cached cookie is returned without IPC.

This optimization is based on Chromium's shared versioning, in which it
was observed that 87% of document.cookie accesses were redundant. See:
https://blog.chromium.org/2024/06/introducing-shared-memory-versioning-to.html

Note that this cache only supports document.cookie, not HTTP Cookie
headers. HTTP cookies are attached to requests with varying URLs and
paths. The cookies that match the document URL might not match the
request URL, which we wouldn't know from WebContent. So attaching the
cached document cookie would be incorrect.

On https://twinings.co.uk, we see approximately 600 document.cookie
requests while the page loads. This patch reduces the time spent in
the document.cookie getter from ~45ms to 2-3ms.
2026-02-05 07:28:07 -05:00
Timothy Flynn
f322e8a29c LibWebView+UI: Add a context menu item to download images
This introduces a simple FileDownloader to download files in the UI
process from RequestServer. We use this to download the context menu
image - this download is likely to hit the disk cache.
2026-02-05 07:27:34 -05:00
Timothy Flynn
70482687a2 LibWebView+UI: Always ask the user where to save screenshots
We currently always save screenshots to the Downloads folder. We will
now always ask for a save location.

This will just let an upcoming feature to save images from web pages
behave the same way. We will want the user to be able to choose a file
name, since the file name from the URL might be nonsense or already
exist.
2026-02-05 07:27:34 -05:00
Callum Law
b55023fad3 LibGfx+LibWeb: Resolve font features per font rather than per element
Previously we would resolve font features
(https://drafts.csswg.org/css-fonts-4/#feature-variation-precedence)
per element, while this works for the current subset of the font feature
resolution algorithm that we support, some as yet unimplemented parts
require us to know whether we are resolving against a CSS @font-face
rule, and if so which one (e.g. applying descriptors from the @font-face
rule, deciding which @font-feature-values rules to apply, etc).

To achieve this we store the data required to resolve font features in a
struct and pass that to `FontComputer` which resolves the font features
and stores them with the computed `Font`.

We no longer need to invalidate the font shaping cache when features
change since the features are defined per font (and therefore won't ever
change).
2026-02-02 14:11:43 +00:00
Callum Law
5917a8c1c8 LibGfx+LibWeb: Allow setting FontVariationSettings for default font
While our default font supporting variations is unlikely, this is
nevertheless required for our fallback font to be considered equal to
it's non-default/fallback equivalent (i.e. `font-family: serif`) which
in turn is required for LineBuilder to merge chunks into a single
fragment.
2026-02-02 14:11:43 +00:00
Andreas Kling
64d033b31a LibWebView+test-web: Print heap explorer URL after dumping GC graph
When dumping a GC graph, we now write the output as a .js file
containing `var GC_GRAPH_DUMP = <json>;` instead of raw JSON.
This allows gc-heap-explorer.html to load the dump via a
dynamically created <script> element, avoiding CORS restrictions
that prevent file:// pages from fetching other file:// URLs.

After dumping, both the browser and test-web print a clickable
file:// URL that opens the heap explorer with the dump pre-loaded.

The heap explorer's drag-and-drop file picker also accepts both
the new .js format and plain .json files.
2026-02-01 22:46:09 +01:00
Andreas Kling
34ae80d602 WebContent+LibWebView: Send GC graphs etc over IPC as shared memory
These can get very large, exceeding the new IPC message size limits.
Instead of serializing them into messages (which was silly anyway)
we now send them as Core::AnonymousBuffer which uses shared memory.
2026-02-01 22:46:09 +01:00
Timothy Flynn
76eb5b2fa6 LibWeb+LibWebView+WebContent: Perform cookie URL filtering in the UI
When cookies change or expire, we currently send a list of all changed
cookies to all WebContent processes. We then filter that list in the
WebContent process for cookies that match the page's URL before sending
out cookie change events to JS.

We now perform this filtering in the UI process, so each WebContent
process only receives the cookies it would be interested in, if any.
This serves two purposes:

1. Less IPC chatter.
2. This will let each ViewImplementation know that its cookie value has
   actually changed.

(2) is for an upcoming change that will introduce a cookie cache, and
will allow each view to know it should bust that cache.

Note that for this filtering to work, we must iterate ViewImplementation
instances rather than WebContentClient in order to have the view's URL.
We must then associate the IPC with the view's page ID.

No changes to the /cookiestore WPT subtests.
2026-02-01 08:31:58 -05:00
Timothy Flynn
a5cabf341b LibWeb+LibWebView: Extract the cookie-matching spec steps to a helper
These were repeated in the CookieStore, and will be needed again for an
upcoming feature.
2026-01-30 07:36:13 -05:00
Timothy Flynn
37ced4f0ba LibWebView: Remove CookieJar::store_cookie helper
This had a single caller who did nothing but invoke it.
2026-01-30 07:36:13 -05:00
Timothy Flynn
c6cb963a92 LibWeb+LibWebView: Update our cookie implementation to the latest RFC
These seem to largely be editorial changes. See:
https://author-tools.ietf.org/iddiff?url1=draft-ietf-httpbis-rfc6265bis-15&url2=draft-ietf-httpbis-rfc6265bis-22&difftype=--html

I've also updated the spec links to use the "datatracker.ietf.org" URL
rather than the "www.ietf.org" URL as the former has better dark-mode
support and more handy sidebar links.
2026-01-30 07:36:13 -05:00
Jelle Raaijmakers
beced191a7 LibWebView: Use NonnullRawPtr for registered views
These pointers are always non-null.
2026-01-30 12:41:55 +01:00
Jelle Raaijmakers
9b1049be0c LibWebView: Use ::unchecked_append() for view IDs 2026-01-30 12:41:55 +01:00
Jelle Raaijmakers
ffc61e2042 LibWebView: Unregister view before creating a new WebContent process
If a did_paint message is in-flight and we create a new process when
navigating to another website, we would still have the view registered
with the client when eventually the stale did_paint message is handled.
In server_did_paint, we retrieve the client which points to the new
process, not the original process the view was registered for.

At that point, there might not be any queued rasterization tasks in the
RenderingThread for the new process, causing a crash because of:

  VERIFY(m_queued_rasterization_tasks >= 1 && ..);

Fix this by unregistering the view before proceeding with a new
WebContent process.
2026-01-30 12:41:55 +01:00
Zaggy1024
e2635af2ed Everywhere: Move the thread name parameter for Thread constructors
The name parameter formats very poorly when a lambda is passed to
Thread, so let's instead put it first now that all Threads are named.
2026-01-26 15:51:46 -06:00
Timothy Flynn
6120b3b918 LibWeb+LibWebView+WebWorker: Enable the HTTP memory cache in workers
This is expected by WPT. For this to work, we must be able to determine
the network partition key for shared worker environments. So we now set
a top-level origin for these environments, with a FIXME to implement it
in accordance with the Client-Side Storage Partitioning spec.
2026-01-22 07:05:06 -05:00
Shannon Booth
c6fab541b7 LibWeb: Fix storage set broadcast event never broadcasting old value
We had skipped some steps in the spec and were:
 * Always broadcasting an old value of null, instead of what it
   actually was previously.
 * Still broadcasting a storage event even if the value had
   not changed in storage compared to the last value.

Fix both issues by returning what the old value is in the setter and
implementing the missing logic.
2026-01-21 22:27:59 +01:00
Tim Ledbetter
3e704e0fd6 LibGfx+LibWeb: Fall back to system fonts for missing glyphs
When rendering text, if none of the fonts in the cascade list contain a
glyph for a given code point, we now query Skia's font manager to find
a system font that can render it.
2026-01-21 14:01:35 +01:00
Sam Atkins
cdf55ea371 WebContent+LibWebView: Rename --layout-test-mode flag to --test-mode
This name has been outdated for a while, as it's enabled when running
any kind of test, not just layout tests.
2026-01-20 06:58:16 -05:00