This commit splits out synchronization primitives from LibThreading into
LibSync. This is because LibThreading depends on LibCore, while LibCore
needs the synchronization primitives from LibThreading. This worked
while they were header only, but when I tried to add an implementation
file it ran into the circular dependency. To abstract away the pthread
implementation using cpp files is necessary so the synchronization
primitives were moved to a separate library.
Attach cached JavaScript bytecode sidecars to HTTP response headers so
WebContent can materialize classic and module scripts directly from a
decoded cache blob on cache hits.
Carry the disk cache vary key with the sidecar and reuse it when storing
fresh bytecode, avoiding mismatches against the augmented network
request headers used to create the cache entry.
Keep CORS-filtered module responses intact for status, MIME, and script
creation checks. Read bytecode sidecar data only from the internal
response, and treat decode or materialization failure as a cache miss
that falls back to normal source compilation.
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.
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.
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.
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.
Implement bookmark import/export in about:bookmarks using Netscape
bookmark HTML in JavaScript.
Import parsed items into BookmarkStore under an "Imported Bookmarks"
folder, and treat internal WebUI about: pages as potentially
trustworthy so SecureContext APIs are available there.
Passing the browser command line and executable path to every WebContent
process just in case we load about:version always felt a bit weird. We
now use the WebUI framework to load this information on demand.
Synthesize an extra AutocompleteSuggestion at the top of the Search
Suggestions section whenever there is a configured search engine and
the typed query is not URL-shaped.
Use the query as the row's primary text, carry a "Search with <engine>"
subtitle, and render that subtitle in the AppKit and Qt popups so the
explicit search fallback stays visible and readable even when history
fills the list.
Some navigations report the same URL more than once through
WebContentClient::did_change_url(). Forwarding those duplicate updates
into the frontend turned an internal no-op into visible UI churn,
including location bar resets and AppKit focus stealing.
Treat repeated URL notifications as a no-op inside LibWebView so
frontends only react to real URL changes.
Route the existing Clear Browsing Data dialog through HistoryStore's
time-range deletion path as well. That makes the Settings action
remove visited pages from persisted history and from history-backed
address bar suggestions instead of only touching cache and site data.
Add a history checkbox to the dialog, thread its state through the
Settings WebUI message, and cover remove_entries_accessed_since() for
both transient and persisted stores in TestHistoryStore.
Replace the frontend-facing Vector<String> flow with structured
AutocompleteSuggestion objects carrying source, section, title,
and favicon metadata.
Build merged history and literal-URL rows in LibWebView, deduplicate
equivalent URL suggestions, move the autocomplete URL helpers out
of URL.h, and update the history and URL tests around the new model.
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.
Teach LibWebView autocomplete to query HistoryStore before falling back
to remote engines and move the wiring out of the AppKit frontend.
Refine matching so scheme and www. boilerplate do not dominate results,
short title and substring queries stay quiet, and history tracing can
explain what the ranking code is doing.
Add a HistoryStore abstraction with transient and persisted backends,
normalize recorded URLs, and skip non-browsable schemes.
Cover lookup and persistence in TestHistoryStore so history-driven
features can share one backend.
Route BroadcastChannel messages over IPC so matching channels can
receive them across WebContent and WebWorker processes, rather than only
within a single process.
Each channel now serializes its payload, sends it upward over IPC, and
receiving processes deliver it locally after matching by storage key and
channel name.
Now that we detect and handle child processes exiting, we should see
less "Trying to post_message during IPC shutdown" VERIFY failures that
crash the UI process.
Co-authored-by: Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
There is no direct equivalent to SIGCHILD on Windows. The closest we
can get is monitoring a specific process, given a known pid. On Unix
there is no single solution to be able to do that in LibCore's
EventLoopImplementationUnix. For Linux there's a SYS_pidfd_open syscall
that can integrate into poll(), but on macOS a kqueue would be needed.
Given macOS uses EventLoopImplementationUnix for the headless view
implementation, we currently can't create a fully cross-platform
abstaction at the Event Loop level to match what Windows needs to do.
ProcessMonitor's purpose is to abstract away the Unix vs Windows
behaviour avoiding more inlined ifdef soup in ProcessManager.
Track the last modification time on every BookmarkItem. The timestamp
is updated when editing a bookmark or folder, moving an item, or
updating a favicon. This aligns with the Netscape bookmark HTML format
used by Chromium and Firefox for bookmark export/import
(LAST_MODIFIED attribute).
Store a creation timestamp on every BookmarkItem, for both bookmarks
and folders.
This aligns with the Netscape bookmark HTML format used by Chromium
and Firefox for bookmark export/import (ADD_DATE attribute).
Previously, `--headless=screenshot` always took a screenshot after 1
second. This option allows the user to specify the number of seconds to
wait before taking the screenshot.
This page renders the bookmarks as a tree and hook context menu events
up to the UI's bookmarks bar context menus to allow editing bookmarks.
Users can also drag-and-drop bookmark items around.
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.
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.
Move MachPortServer from LibWebView into LibIPC as MachBootstrapListener
and move the Mach message structs from MachMessageTypes.h into LibIPC.
These types are IPC infrastructure, not UI or platform concerns.
Consolidating them in LibIPC keeps the Mach bootstrap handshake
self-contained in a single library and removes LibWebView's dependency
on LibThreading.
Previously, the bootstrap handshake used a two-state machine
(WaitingForPorts / WaitingForReplyPort) to handle a race: the parent
registering transport ports and the child sending a bootstrap request
could arrive in either order, so whichever came first stored its half
and the second completed the handshake.
Eliminate the race by holding a mutex across spawn() and
register_child_transport(). Since the child cannot send a bootstrap
request before it exists, and the lock isn't released until its
transport is registered, handle_bootstrap_request() is guaranteed to
find the entry. This reduces the pending map to a simple pid-to-ports
lookup and collapses the two-variant state into two straightforward
branches: known child, or on-demand (non-child) caller like WebDriver.
This patch adds BookmarkStore to manage bookmarks stored in a JSON file
in the application settings directory. It supports both folders and
bookmarks. It does not yet support arbitrary editing of bookmarks, other
than updating stored favicons.