Commit graph

79609 commits

Author SHA1 Message Date
Tim Ledbetter
a87f7b9561 LibWeb: Account for visual viewport when scrolling a target into view
This ensures the correct portion of the screen is scrolled into view
when the window is pinch-zoomed.
2026-06-22 14:47:17 +02:00
sideshowbarker
5440f0797b WebDriver: Tolerate a WebContent process swap during load-url-from-ui
Problem: Intermittent TestWebDriverSessionHistory crashes in CI.

Cause: A process-swap navigation driven through the load-url-from-ui
test hook (introduced in 24f37c6732 / #10085) could tear down the
WebContent process before it replied to the sync LoadUrlFromUi message,
tripping an assert — even though the result is still delivered over the
driver-execution-complete channel separately. (The reply’s just an ACK.)

Fix: Send the message with send_sync_but_allow_failure. Treat a dropped
reply as the swap proceeding. Nothing’s lost: WebContent sends the async
completion before this, and early errors return before any swap.
2026-06-22 14:46:35 +02:00
sideshowbarker
2e86169246 Tests: Serialize Worker-echo messages to eliminate an ordering race
Problem: The Worker-echo.html test flakes under load in CI on the
Sanitizer runners, printing its messages out of order.

Cause: The test asserts a fixed order for messages arriving over two
separate ports: “loaded” over the Worker’s own port, and the channel
messages over the transferred MessagePort. Those two race, with no
cross-port ordering guarantee. So the printed order is nondeterministic.

Fix: Sequence each message explicitly with an awaited helper — the same
approach used for SharedWorker-reuse in #9669 — so the printed order is
deterministic. port2 is left unstarted until after “loaded”.
2026-06-22 14:46:00 +02:00
Tim Ledbetter
0ec95a606f LibWeb: Use computed display value for ::first-letter layout wrappers
Previously, `::first-letter` elements were always wrapped in an inline
box, meaning these elements were not correctly blockified when floated.
2026-06-22 09:43:07 +02:00
Tim Ledbetter
2f84f89874 LibWeb: Drop non-typesetting properties from pseudo element allowlist 2026-06-22 09:43:07 +02:00
Tim Ledbetter
cd29e3013d LibWeb: Remove block properties from inline typesetting allow list 2026-06-22 09:43:07 +02:00
Tim Ledbetter
9b06a79b81 LibWeb: Add missing properties to pseudo element allow list 2026-06-22 09:43:07 +02:00
Andreas Kling
117cef4e92 UI/Qt: Accept all standard back/forward shortcuts
Use Qt's platform shortcut bindings for back and forward navigation
instead of only installing the primary binding. On macOS this keeps
Command-[ and Command-] while also accepting Command-Left and
Command-Right.
2026-06-22 01:13:53 +02:00
Andreas Kling
b91ff9ebfd UI/Qt: Keep macOS app alive without windows
Disable Qt quit-on-last-window behavior on macOS and install an
application-level menu so useful commands remain available after the
last browser window closes.

Reuse shared application actions and menus for Settings, Bookmarks,
History, Help, and global appearance controls. Centralize window-aware
commands such as New Tab, New Window, Open File, Open Location, and
Reopen Recently Closed so the browser window and windowless app menu
use the same behavior. Keep the location editor focused for new blank
windows after the native window has been activated.
2026-06-22 01:13:53 +02:00
Andreas Kling
d707d112a2 UI/Qt: Resize frameless macOS windows manually
Disable AppKit's native resize handling for client-side decorated macOS
windows so AppKit does not show a resize cursor for points it will not
deliver to Ladybird. Reapply this after Qt creates the native surface,
since Qt may restore the resizable style mask during Cocoa window setup.

Handle the resize gesture in BrowserWindow instead, with thin side edges
and a slightly larger corner target that avoids the rounded corner
cutouts.
2026-06-22 01:13:53 +02:00
Andreas Kling
202159be18 UI: Share macOS web selection color
Move the active macOS web selection color into LibWebView so AppKit
and Qt use the same value when building the WebContent system palette.
Qt now also asks AppKit for inactive selection colors on macOS, matching
the AppKit frontend while leaving other Qt platforms on QPalette.
2026-06-22 01:13:53 +02:00
Andreas Kling
4b2f404da1 UI/Qt: Honor AppKit window drag gesture
macOS can be configured to drag windows with Cmd+Ctrl+click via
NSWindowShouldDragOnGesture. AppKit does not see its usual titlebar
drag path for our frameless Qt windows, so handle the native mouse
down in the AppKit event filter when that default is enabled.

Forward the event to performWindowDragWithEvent before Qt turns it into
normal widget input. This restores the system gesture without changing
behavior for users who have not enabled the default.
2026-06-22 01:13:53 +02:00
Andreas Kling
702904f6b3 UI/Qt: Restore AppKit focus before focusing location edit
After web content has focus on macOS, its native QRhiWidget can
remain the AppKit first responder even after Qt focuses the location
edit.

Make the top-level Qt content view first responder before focusing the
location edit so keyboard input returns to chrome.
2026-06-22 01:13:53 +02:00
Andreas Kling
2f0fe26ce9 UI/Qt: Preview non-prefix autocomplete suggestions
Allow highlighted rows that are not valid inline completions to preview
their full suggestion text in the location editor. This covers history
entries matched by title or URL substring, while ordinary typing stays
on the inline-only path.

Keep automatic inline autocomplete text when Escape closes the popup.
Escape still cancels hovered or keyboard-selected preview text.
2026-06-22 01:13:53 +02:00
Andreas Kling
3fcd9d83a1 UI/Qt: Avoid stale autocomplete activation
Remember which query produced the visible autocomplete popup rows, and
only activate selected rows when the visible popup still belongs to the
current query.

When Enter is pressed while fresh results are pending, rerun
autocomplete for the current query and activate once matching results
arrive. Ignore late completions after focus leaves. Avoid canceling
autocomplete while its completion callback activates the pending result.
2026-06-22 01:13:53 +02:00
Andreas Kling
375da3e66d UI/Qt: Show autocomplete when focusing location edit
Open the autocomplete popup when the location editor is focused
through the browser action, such as Cmd+L. Keep the selected URL text
intact by skipping inline completion for that explicit popup request.

Position the native popup again after its first show so Qt has realized
the tooltip window before the final placement, avoiding the brief macOS
Y-coordinate jump.
2026-06-22 01:13:53 +02:00
Tim Ledbetter
e2d223b305 Documentation: Add glslang-tools as a dependency for Ubuntu
This is needed for WebGL to work on Ubuntu.
2026-06-22 00:37:03 +02:00
sideshowbarker
9402a6e4e1 LibWeb: Saturate CSSPixels unary negation at the i32 minimum
Problem: UBSan crash when computing layout for an element with a giant
negative inset.

Cause: CSSPixels::operator-() returned from_raw(-raw_value()), and
negating the i32 minimum overflows int.

Fix: Negate with saturating_sub(0, raw_value()) — matching the
saturating arithmetic already used by the other CSSPixels operators.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/9997
2026-06-21 15:44:07 +02:00
sideshowbarker
86f75e1e35 LibWeb: Saturate list-item ordinal numbering at the i32 bounds
Problem: Crash when loading an ordered list whose numbering reaches the
i32 limit; e.g. <ol start="2147483647"> with two or more items.

Cause: Element::ordinal_value() kept its numbering in a Checked<i32>
and stepped it once per list item. When the numbering already sits at
the i32 maximum (or minimum, for a reversed list whose value attribute
pins it there), the increment overflowed the Checked value.

Fix: Keep the numbering in a plain i32 instead, and step it with
AK::saturating_add and AK::saturating_sub — so it clamps at the i32
bounds, rather than overflowing.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/10003
2026-06-21 14:48:23 +02:00
sideshowbarker
9ffd3e48c3 LibWeb: Don’t crash on a detached publicExponent in generateKey
Problem: Crash when generating an RSA key — or serializing one —
whose publicExponent is a typed array whose backing ArrayBuffer has
been detached; for example, by calling transfer() on it.

Cause: Two places with big_integer_from_api_big_integer() reading the
bytes of the backing ArrayBuffer directly. But reading the bytes of a
detached buffer aborts.

Fix: Read the bytes with WebIDL get_buffer_source_copy() — which yields
an empty copy for a detached, or OOB resizable, buffer. The empty array
is already mapped to zero — so generation rejects the zero exponent with
an error, rather than crashing.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/9991
2026-06-21 14:04:01 +02:00
Callum Law
9183c2a029 LibWeb: Bail on unresolved percentages in resolve_value
Previously we assumed that if the calculation had been simplified to a
single `NumericCalculationNode` that we could resolve it - this isn't
the case if we have a percentage that should be resolved to a different
type.

Fixes #10209
2026-06-21 08:18:50 +01:00
Tim Ledbetter
360bfd66f6 LibWeb: Apply the font-variant-emoji property to font selection 2026-06-20 23:51:46 +02:00
Tim Ledbetter
57103da08d LibGfx+LibWeb: Make emoji font fallback presentation-aware
Previously, font selection ignored the Unicode emoji presentation of a
code point. Emoji-capable code points were always resolved through
pre-baked color emoji and symbol fonts. Text-default code points which
lacked the `Emoji_Presentation` property, were therefore rendered as
color emoji rather than text. We now classify each code point's default
presentation from its `Emoji_Presentation` property and any trailing
variation selector.
2026-06-20 23:51:46 +02:00
Tim Ledbetter
bebcf95883 LibGfx: Remove bogus early return from Font::is_emoji_font() 2026-06-20 23:51:46 +02:00
sideshowbarker
5af7dadd40 Tests: Wait for beforeunload before the script-back cancel assertion
Problem: TestWebDriverSessionHistory flakes on slow (Sanitizer) CI
runners. The subtest checking that cancellation of a script-initiated
cross-site “back” by a beforeunload handler intermittently failed the
assertion “Expected beforeunload to cancel script-initiated cross-site
history.back(), got [url_b, 0]”. scriptBeforeUnloadCount was 0, not 1.

Cause: history.back() appends its traversal to the traversable’s session
history queue and returns immediately. So the beforeunload prompt to
unload runs async. The test read scriptBeforeUnloadCount in a separate
execute_script right after — with no wait. So on a slow runner, the read
beats the dispatch, and sees 0. Every other script-initiated navigation
in the test waits for its target document to load — and the “refresh”
beforeunload check already polls. But the canceled “back” loads no
target document — and this one waited for nothing.

Fix: Poll with wait_for_script_result until the page is still on /b and
window.scriptBeforeUnloadCount has incremented, before asserting the
final state — mirroring the “refresh” beforeunload check.
2026-06-20 23:50:57 +02:00
Andreas Kling
2bf1f41805 LibWeb: Make computed properties immutable
Move CSS animation values into a mutable overlay on computed properties
and make base computed style data immutable after construction. Base
style mutation now goes through a builder that is consumed on publish,
so installed styles no longer expose mutation APIs.

Build new base style data for inherited style updates instead of cloning
and mutating installed computed properties. Element-specific computed
style adjustments now run before publication, while animation and
transition updates continue to mutate only the animated overlay.
2026-06-20 23:43:17 +02:00
sideshowbarker
d7c08964cb LibJS: Throw rather than crashing on a deep prototype-chain get
Problem: Converting an object with a pathologically-deep prototype chain
to a primitive was segfaulting.

Cause: Object::internal_get implements [[Get]] by recursing into the
prototype’s [[Get]] (parent->internal_get) when the property isn’t an
own property. For a sufficiently deep prototype chain, that C++
recursion exhausts the native stack, and segfaults. The bytecode
interpreter’s call-stack limit doesn’t cover this native recursion.

Fix: Before recursing into the prototype in Object::internal_get, check
VM::did_reach_stack_space_limit(), and throw a CallStackSizeExceeded
InternalError — the same way the interpreter and other recursive runtime
operations guard the native stack. The deep-chain get now throws a
catchable call-stack-size-exceeded error, rather than crashing.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/3584
2026-06-20 23:34:33 +02:00
sideshowbarker
a237fbc24f LibJS: Add a regression test for binding environment type confusion
Issue #3622 documents a now-no-longer reproducible type-confusion/OOB
bug. This just adds the POC from that issue as a regression test.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/3622
2026-06-20 23:34:19 +02:00
Shannon Booth
7b0dd6ab30 LibTextCodec: Use encoding_rs for legacy codecs
Replace the generated C++ legacy codec implementations with a
small Rust wrapper around encoding_rs.

This keeps the existing LibTextCodec API while moving label lookup,
legacy decode/encode, validation, and streaming decoder state to Rust.
The generated index data and generator are no longer needed.

It also fixes several TextDecoder EOF cases due to a more correct
implementation. encoding_rs finalizes decoders according to the
Encoding Standard, so incomplete UTF-8/Big5 tails and malformed
UTF-16 surrogate tails produce the required single replacement at
end-of-queue instead of being dropped, buffered, or double-counted
by our old hand-written decoders.
2026-06-20 21:56:43 +02:00
Shannon Booth
250842d36a LibURL: Use encoding_rs for form URL encoding
Replace the Rust URL form-encoding callback bridge into C++ TextCodec
with a direct encoding_rs encoder.

This keeps percent-encode-after-encoding entirely in Rust and removes
liburl_rust's dependency on LibTextCodec.

It also happens to fix ISO-2022-JP URL encoding of literal U+FFFD.

The LibTextCodec reverse lookup treats generated 0xFFFD table holes as
real JIS0208 mappings, so literal U+FFFD skipped the encoder-error
path. encoding_rs treats U+FFFD as unmappable, so URL encoding emits
the required numeric character reference.
2026-06-20 21:56:43 +02:00
Shannon Booth
3a0f857cc1 Tests: Import some encoding related WPT tests 2026-06-20 21:56:43 +02:00
Shannon Booth
62e4da6d3e LibTextCodec: Make StreamingDecoder own decoder lookup
Pass an encoding label to StreamingDecoder instead of requiring
callers to pre-resolve a Decoder reference.

This removes redundant decoder_for() plumbing from callers and lets
StreamingDecoder hide how chunked decoder state is represented.
2026-06-20 21:56:43 +02:00
Shannon Booth
ebc439f0f2 LibWeb/Infra: Add some missing AK includes
To prevent my clangd from complaining.
2026-06-20 21:56:43 +02:00
Shannon Booth
be6192dab2 LibWeb: Avoid TextCodec when parsing JSON bytes
Use String::from_utf8_with_replacement_character() directly for Infra's
parse JSON bytes algorithm instead of constructing a more generic
TextCodec UTF-8 decoder.
2026-06-20 21:56:43 +02:00
Shannon Booth
c907338ab3 Test/LibTextCodec: Remove noisy test debug log 2026-06-20 21:56:43 +02:00
Shannon Booth
73ec316214 Tests/LibTextCodec: Do not refer to concrete encoders/decoders
Which allows for their removal from the header file once the
implementation is ported to rust.
2026-06-20 21:56:43 +02:00
Shannon Booth
c982385ffe LibTextCodec: Remove unused PDFDocEncoding
PDFDocEncoding has no remaining users left. Remove the decoder and
label plumbing. Retarget the lazy source-code decoding regression
test to Windows-1252 so it still covers non-UTF source decoding.
2026-06-20 21:56:43 +02:00
Andreas Kling
784ca98041 LibSandbox: Allow listing read-write directories
Include directory read access in Landlock read-write directory rules.
Without it, paths such as /dev/dri could be writable but not enumerable
after sandboxing, which made Mesa fail while probing GPU devices.

Allow the Compositor to open /dev/udmabuf as well when the device is
present, matching the other GPU device nodes exposed to the process.
2026-06-19 19:12:26 +02:00
Andreas Kling
b759954486 Compositor: Allow GPU driver executable mappings on Linux
Let the Linux Compositor sandbox permit writable executable mappings
used lazily by GPU drivers after WebGL context creation. Keep this
allowance scoped to the Compositor process so WebContent retains the
existing memory mapping restrictions.
2026-06-19 19:12:26 +02:00
Andreas Kling
523cdab7d9 LibWeb: Don't serialize UnresolvedStyleValue comparison text when unused
UnresolvedStyleValue::create() serialized the component values into a
comparison string unconditionally, but the result is only used when the
caller supplied separate original source text. On the common path that
serialization (including float formatting of every numeric token) was
computed and immediately discarded.

Move the serialization into the branch that actually uses it. This is
hot during var() substitution, where many intermediate
UnresolvedStyleValues are created and never compared.
2026-06-19 18:47:04 +02:00
Aliaksandr Kalenik
1a0f8d4372 LibIPC: Coalesce Mach read notifications
TransportMachPort wrote to its event-loop notification pipe for every
received message. Large bursts could spend significant time in the IO
thread just waking the main loop, even when a previous read notification
was still pending and would already drain the queued messages.

Track whether a read notification is pending while holding the incoming
queue mutex, and only write a new pipe byte when the queue needs a wake.
EOF still schedules a notification, and synchronous waiters continue to
use the condition variable for every arrival.
2026-06-19 18:21:06 +02:00
Aliaksandr Kalenik
5c3e61efb6 Compositor: Rasterize nested contexts during replay
Nested compositor contexts used the same vsync scheduling path as
top-level contexts. That made iframe presents depend on a context's own
timer instead of the display refresh rate, and screenshots needed a
separate descendant flush to avoid stale child surfaces.

Keep top-level contexts on vsync, but make nested contexts dirty their
containing context instead of scheduling themselves. When a composited
child surface is resolved, synchronously rasterize the child if it has
a pending frame, using a separate display-list player so recursive
replay does not reuse the active player state. This lets screenshots and
normal presentation share the same child-surface update path.
2026-06-19 17:09:44 +02:00
Ali Mohammad Pur
b3f3d68291 LibWeb+LibWasm: Keep WebAssembly cache storage stable
These need to stay in place across rehashes so we can avoid querying
their address on every collection cycle.
2026-06-19 17:01:47 +02:00
Ali Mohammad Pur
530c95fde5 LibWasm: Remove all gc, function-refs and EH test exceptions 2026-06-19 17:01:47 +02:00
Ali Mohammad Pur
8a74f52571 LibWasm: Partially implement the (new) exception handling proposal
This implements try_table and throw_ref execution in the interpreter.
2026-06-19 17:01:47 +02:00
Ali Mohammad Pur
16d1486cc9 LibWasm: Implement the wasm-gc instruction set in the BC interpreter 2026-06-19 17:01:47 +02:00
Ali Mohammad Pur
87961e3c92 LibWasm: Back wasm-gc aggregate instances with the LibGC heap 2026-06-19 17:01:47 +02:00
Ali Mohammad Pur
76f17f7703 LibGC: Add support for coordinated multi-heap collection
Allow having separate GC heaps and implement coordinated marking between
them; this is useful for keeping wasm and js GC heaps separated with a
clear boundary.
2026-06-19 17:01:47 +02:00
Ali Mohammad Pur
62cb073ada LibWasm: Validate the wasm-gc and function-references instructions
Actual implementations are still trap-on-exec.
2026-06-19 17:01:47 +02:00
Ali Mohammad Pur
42c0a430f5 LibWasm: Implement the spec's type matching relations 2026-06-19 17:01:47 +02:00