Commit Graph
39 Commits
Author SHA1 Message Date
ZacharyZhang-NY c5890058db feat(reload): reload the active tab with Cmd/Ctrl+R 2026-07-10 16:55:25 -04:00
ZacharyZhang-NY 18fe57ddc6 fix(servo): reconcile the loading state through redirects and pushState 2026-07-10 16:28:06 -04:00
ZacharyZhang-NY b422ac1631 fix(permissions): make profile snapshots authoritative 2026-07-09 21:56:36 -04:00
ZacharyZhang-NY c28ec2bee8 feat(servo): isolate profiles with hardware sidecars 2026-07-09 20:27:22 -04:00
ZacharyZhang-NY 78dc86b18e feat(servo): upgrade to latest secure upstream snapshot 2026-07-09 16:00:50 -04:00
ZacharyZhang-NYandClaude Opus 4.8 d150da5bd0 fix(servo): enable variable fonts so weight/width axes render
Like CSS Grid, Servo's `Preferences::default()` ships
`layout_variable_fonts_enabled: false`. `Servo::new` forwards it to Stylo
(`layout.variable_fonts.enabled`), and with the gate off Stylo ignores
`font-variation-settings` and variable weight/width axes: a variable font
renders only its default instance, so every requested weight looks
identical. Modern sites lean on variable fonts (Inter, Roboto Flex,
system New York/SF), so text rendered at the wrong weight versus Chrome.

servo-fonts already drives variations through HarfBuzz, so enabling the
pref is the real fix. Verified with a `@font-face` page using a variable
font at `font-variation-settings: "wght" 200` vs `"wght" 900`: identical
weight before, distinctly light vs black after.

runtime.rs 473 lines (<500). fmt/audit/clippy clean; software_host real-
Servo test passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 14:08:41 -04:00
ZacharyZhang-NYandClaude Opus 4.8 b1fd8ab3f8 refactor(servo): extract paint coordination into runtime_paint
`runtime.rs` had grown past the 500-line ceiling enforced by
`scripts/audit_source_lines.sh` once the grid-pref comment landed (522
lines). Peel the repaint/present pair — `paint_without_readback`,
`paint_without_readback_with_completion`, the private `paint_webview`,
and `paint_with_readback` — into a sibling `runtime_paint.rs`, exactly
the `paint.rs` boundary the embedding architecture doc prescribes.

`runtime_paint` is a child module of `runtime` (declared via `#[path]`,
mirroring `runtime_context`), so it keeps access to the private
`SoftwareServoHost` fields and the `webview()` / `wait_for_paint_completion`
/ `read_rendered_frame` helpers without widening any visibility. No
behaviour change: public API and call sites are identical.

runtime.rs 522 -> 469 lines. Build + clippy clean; full workspace test
suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 13:17:00 -04:00
ZacharyZhang-NYandClaude Opus 4.8 3d36cb25bf fix(servo): enable CSS Grid so grid layouts stop collapsing
`Preferences::default()` is Servo's conservative library default and
ships `layout_grid_enabled: false`. `Servo::new` forwards prefs to Stylo
(`prefs::set` -> `stylo_static_prefs::set_pref!("layout.grid.enabled")`),
so with the gate off Stylo blockifies `display: grid`: every grid
container collapses to `display: block` and grid-based page layouts
stack into a single column — the "broken" rendering reported on modern
sites.

`ely_servo_preferences()` only flipped `dom_intersection_observer_enabled`
and inherited the grid default, so ELY rendered grid pages collapsed
while Servo's own servoshell (which enables the pref) renders them
correctly. The layout path is implemented — servo-layout drives
`DisplayInside::Grid` through Taffy — so enabling the pref is the real
fix, not a workaround.

Verified with a deterministic `display: grid; grid-template-columns:
1fr 1fr 1fr` page: 9 stacked full-width bars before, a 3x3 grid after.
Wikipedia/HN/GitHub/google.com re-checked unchanged; full workspace
test suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 13:07:50 -04:00
ZacharyZhang-NY aa8182bec4 update 2026-05-21 15:44:26 -04:00
ZacharyZhang-NY d1e811b724 fix(servo): resize through WebView only, never the rendering context
Servo's reference embedder (\`examples/winit_minimal.rs\`) handles
resize with a single call: \`webview.resize(new_size)\`. The Servo
paint pipeline behind that call:

  1. early-returns if \`rendering_context.size() == new_size\`,
  2. otherwise calls \`rendering_context.resize\` itself,
  3. updates \`webview_renderer.rect\` so the compositor relays out
     the page at the new device viewport,
  4. sends \`transaction.set_document_view(...)\` so WebRender's
     document viewport matches the surface,
  5. flags the painter \`needs_repaint(RepaintReason::Resize)\`.

Our \`runtime.rs::resize\` called \`webview.rendering_context.resize\`
*before* \`webview.webview.resize\`. surfman accepted the new size, so
the painter saw \`rendering_context.size() == new_size\` and took the
early-return path — steps 3, 4, and 5 never ran. The compositor
kept the original (creation-time) viewport rect while we presented
a much larger surface. The page ended up laid out for a tiny
viewport and either rendered into the top-left of a sea of cleared
background (StableLance) or never painted any pipeline at all
(google.com appeared totally blank).

Drop the direct \`rendering_context.resize\` call and route through
\`WebView::resize\` exactly as the reference embedder does. The
debounce in \`record_viewport_size\` still collapses a sidebar /
window-edge animation into a single trailing-edge resize, so we
also avoid hammering Servo with per-frame surface mutations.
2026-05-18 15:30:55 -04:00
ZacharyZhang-NY 68a4507dbe update 2026-05-18 13:58:36 -04:00
ZacharyZhang-NY dbfcbdb377 perf(sidecar): use payloadless hardware frames after warmup 2026-05-16 02:50:11 -04:00
ZacharyZhang-NY 42dc9af66c perf(sidecar): skip redundant paint barriers 2026-05-16 01:25:37 -04:00
ZacharyZhang-NY 90c029eddb Move Servo IPC off UI thread
Root cause of the post-tab lag: the GPUI 16 ms timer was calling
`WebSurfaceRuntime::ensure_tab` and `tick` on the UI thread, and each
call did a synchronous `serde_json` write plus `read_line` against the
Servo sidecar over stdin/stdout. With even one visible tab, every
frame stalled on cross-process IPC.

Introduce `web_surface_worker.rs` — a per-profile worker thread that
owns the `ServoLiveClient`, drains a coalescing request queue
(latest Ensure/Poll per tab wins, no unbounded growth), and ships
results back through a `std::sync::mpsc` channel. `WebSurfaceRuntime`
now submits work non-blockingly and drains responses in `tick`; the
UI thread never blocks on the sidecar.

Adjacent in-flight cleanup riding along: hardware IOSurface
rendering-context completion (sidecar `live_protocol`,
`hardware_rendering_context`, GPUI BGRA surface shader), CSS viewport
size + device pixel ratio plumbing into `ServoLiveFrame`, and the
Send opt-ins for `CVPixelBuffer`-bearing types so frames can cross
the thread boundary.
2026-05-15 16:41:40 -04:00
ZacharyZhang-NY ac84a80d9e Close Servo live sessions for removed tabs 2026-05-13 02:41:54 -04:00
ZacharyZhang-NY 6ce5df83a8 Skip hardware live readback 2026-05-13 01:41:58 -04:00
ZacharyZhang-NY 316bf6f9a4 Split Servo live rendering modules 2026-05-12 23:38:13 -04:00
ZacharyZhang-NY 0db1caad69 Route web surface scrolls to Servo hit point 2026-05-12 23:29:40 -04:00
ZacharyZhang-NY 42b4e8c87b T15: paint barrier — pump event loop until framebuffer is consistent
`webview.paint()` dispatches a render command to Servo's paint thread
asynchronously, so the subsequent `read_to_image()` raced the paint
thread and reliably returned cleared-white pixels on data: URLs (T10.8).
Clear `has_pending_frame` before dispatching paint, then spin the Servo
event loop until `notify_new_frame_ready` re-arms it or 32 ms elapse
(override via `ELY_PAINT_BARRIER_MS`). Bench: software path now ships
real RGBA bytes for 60 frames instead of all-white.
2026-05-11 00:57:35 -04:00
ZacharyZhang-NY b70fa71a9f T13: push display scale factor into Servo's hidpi so Retina pages lay out at logical CSS dimensions 2026-05-11 00:46:32 -04:00
ZacharyZhang-NY 07b9c9da01 T10.3: publish IOSurfaceHandle once per surface, current_surface_id per frame 2026-05-10 23:17:05 -04:00
ZacharyZhang-NY a7d3e896bb Wire the vendored hardware context into SoftwareServoHost
`HardwareOffscreenContext` was vendored in 048c5df but the host's
per-webview `new_rendering_context` still hard-wired
`servo::SoftwareRenderingContext`. This commit threads a
`RenderingContextKind` enum through the host so existing call sites
keep their software path, and new callers can opt into the hardware
path through `SoftwareServoHost::new_with_config_dir_and_kind(...)`.

Three changes, kept tightly scoped:

  * `runtime.rs` gains a public `RenderingContextKind { Software,
    Hardware }` enum and a new constructor that takes it. The
    existing `new` and `new_with_config_dir` keep their signatures
    and default to `Software`, so the sidecar binary and the
    integration tests pick up zero behavioural change. The
    private `new_rendering_context` moves from a free function to a
    `&self` method so it can read `self.rendering_context_kind` and
    dispatch — `Software` constructs `SoftwareRenderingContext` as
    before, `Hardware` constructs the vendored
    `HardwareOffscreenContext`. When the `hardware-render` feature
    isn't compiled in, the `Hardware` arm returns
    `ServoHostError::HardwareRenderUnavailable` instead of silently
    falling back; the new constructor also rejects the request
    up-front before touching the global Servo runtime flag.

  * `error.rs` gains `HardwareRenderUnavailable` so the wrong-feature
    path is a typed error, not a panic.

  * `lib.rs` exports `RenderingContextKind` alongside
    `SoftwareServoHost` so downstream code (next commit will be the
    sidecar's `--rendering-context` CLI flag and the live.rs
    plumbing) can name the variant directly.

This is purely an extension point — no existing call path changes,
no existing test asserts on the new enum. The next commit will add
the sidecar CLI flag and wire `live.rs::run_live` to pass the kind
through to the host so users can pick the path at startup. The
follow-up commits then extract the IOSurface from the hardware
surfman surface and bridge it across the IPC channel to GPUI's
Metal renderer, deleting the host-side `Vec<u8>` from the per-frame
hot path entirely (full plan in docs/t10-iosurface-plan.md).

cargo test -p ely_servo_host --features servo-engine --lib: 2 passed.
cargo test -p ely_servo_host --features servo-engine --test sidecar: 9 passed.
cargo test -p ely_servo_host --features servo-engine,hardware-render
  --test hardware_rendering_context: 1 passed.
cargo test --bin ely_app: 120 passed, 0 failed, 2 ignored.
2026-05-10 20:55:35 -04:00
ZacharyZhang-NY 6314e1f777 Make WebView input invariant a property of the dispatch path
Servo's hit-test silently absorbs notify_input_event on a hidden or
unfocused WebView. Today show()+focus() are called at creation and on
the first-navigate rebuild, but every later sibling-WebView creation
also calls focus() — silently stealing focus from the foreground tab.
load() (later navigates), resize, set_page_zoom, and paint never
re-focus, so a click on the visible tab can land on an unreachable
WebView and disappear.

Move the invariant from a state spread across creation/navigation/
tab-switching into a property of the dispatch path itself: a private
webview_for_input(id) helper re-asserts show()+focus() and returns
the WebView; click/hover/drag/touch_tap/scroll/type_text all go
through it. The cosmetic show/focus calls in create_webview_in_context
and the navigate-rebuild branch stay (first-frame paint), now annotated
to point to webview_for_input as the input-path owner.

Not a complete fix on its own. focus() goes through constellation_proxy
asynchronously (servo crate webview.rs:352), so debug_assert!(focused())
right after focus() would race the constellation — doc comment is the
only guard. Sidecar integration tests pass 9/9 but only exercise
single-WebView sessions; multi-tab focus stealing on Google / YouTube /
Twitter still needs human verification in the live shell. Linus's
critique of the GPUI-side data structure (PerTabSurface Option-as-queue
+ Ensure bundling config+input+frame) is a separate layer untouched
by this change.

Pre-existing tests/software_host.rs::manages_real_servo_webview_lifecycle
already times out on https://servo.org/ with state=Complete but
has_pending_frame=false on b8795bf without this change, so unrelated.
2026-05-10 13:59:04 -04:00
ZacharyZhang-NY 22ba8517d1 Show + focus the Servo WebView so it stops dropping every input event
Root cause: Servo's WebView is hidden+unfocused by default. notify_input_event
on a hidden WebView runs paint() hit-test, which returns no hit, and Servo
silently absorbs the event as "already handled". Eleven prior commits all
patched the GPUI side of input forwarding while every event landed in
exactly that black hole.

Fix: webview.show() + webview.focus() immediately after WebViewBuilder::build
in create_webview_in_context, and again in navigate() only on the
should_create_initial_document branch (the load() branch keeps existing
visibility+focus, otherwise a background tab finishing navigation would
steal focus from the foreground tab — Linus correctness ask).

Also unblocks the sidecar binary build, which had been frozen at the
May 9 13:53 stale binary because servo-engine feature was broken on two
fronts:

- ServoHost trait was missing the hover() method that the SoftwareServoHost
  impl declared (regression from "Plug three holes" commit eb58ce7).
- Servo SDK renamed Key::Enter / Backspace / Tab / Escape / Delete /
  Arrow{Up,Down,Left,Right} / Home / End / Page{Up,Down} to
  Key::Named(NamedKey::*). keyboard.rs updated to match.

Sidecar binary rebuilt: 335 MB at May 10 01:44. The earlier 11 commits
were never reaching users because they couldn't recompile the sidecar
without these two upstream-API repairs.
2026-05-10 01:46:39 -04:00
ZacharyZhang-NY eb58ce75da Plug three holes in Servo input forwarding
1. Scroll no longer wipes keyboard focus. Servo holds DOM focus across
   wheel events; the shell was clearing keyboard_focus and typed_texts
   on every scroll, so a focused input went deaf the moment the user
   scrolled. Scroll still drops the buffered click point because that
   coordinate is captured against the pre-scroll viewport.

2. Mouse-down hands focus to the shell's root focus handle (in
   addition to mouse-up's existing click forwarding). The user can now
   start typing the moment they press the page, instead of having to
   first complete a click round-trip to escape the omnibar's focus.

3. Sidecar hover() honors the requesting webview_id instead of
   defaulting to the first webview in the map, so multi-tab sidecars
   no longer pipe every hover into tab #1.
2026-05-10 00:51:37 -04:00
ZacharyZhang-NY 4c6d9c757a Add mouse hover tracking across the Servo input pipeline
Without continuous MouseMove events, Servo never updates hover state:
no cursor changes over links, no :hover CSS effects, no mouseenter
JavaScript events. The web page appears completely non-interactive.

Track mouse position from GPUI on_mouse_move through the full IPC
pipeline to Servo. Hover position is included with each ensure
request so Servo updates hover state at frame rate (~60fps).
2026-05-09 16:21:43 -04:00
ZacharyZhang-NY 1faa7423c1 Add Servo page zoom support 2026-05-09 12:32:44 -04:00
ZacharyZhang-NY 4ed1666ece Scope Servo permissions by profile origin 2026-05-08 23:47:05 -04:00
ZacharyZhang-NY 8334fcbd6e Wire sidecar profile data isolation 2026-05-08 22:10:10 -04:00
ZacharyZhang-NY cb115b61fe Bridge Servo screenshot capture 2026-05-08 16:06:26 -04:00
ZacharyZhang-NY 660d9f54e2 Bridge Servo webview resize 2026-05-08 15:22:05 -04:00
ZacharyZhang-NY 0ea43e8b81 Bridge Servo mouse drag input 2026-05-08 15:15:38 -04:00
ZacharyZhang-NY 7a09967d19 Bridge Servo touch tap input 2026-05-08 15:00:06 -04:00
ZacharyZhang-NY 292824dc10 Bridge Servo keyboard text input 2026-05-08 14:36:48 -04:00
ZacharyZhang-NY b786073826 Bridge Servo click input 2026-05-08 14:23:12 -04:00
ZacharyZhang-NY 7178174e20 Add Servo scroll snapshots 2026-05-08 13:54:56 -04:00
ZacharyZhang-NY 5f0773a043 Add Servo site compatibility frame smoke 2026-05-08 12:08:57 -04:00
ZacharyZhang-NY 57b3beef57 Prepare Servo context before painting 2026-05-08 00:06:51 -04:00
ZacharyZhang-NY b787486f8e Add Servo engine host runtime 2026-05-07 18:47:37 -04:00