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.
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.
The live-mode `poll_frame` budgeted 60 ms for Servo to paint after
each `Ensure` request. That value was set when the only thing being
applied was navigation, where the GPUI tick timer (16 ms cadence) would
backfill missed frames quickly. Once we started forwarding clicks and
typing through the same `Ensure`, 60 ms was tighter than the
software renderer needs to handle MouseDown + MouseUp + layout +
paint on a real page like google.com — so the response carried the
pre-click frame and the user saw no visible reaction.
Bump the budget to 250 ms. That covers the click → focus-ring paint
cycle on the software backend without making nav slower (`apply_layout`
exits early on stable size, so unchanged ensures still return on the
first poll).
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).
Enter, Backspace, Tab, Escape, Delete, arrow keys, Home, End,
PageUp, PageDown now forward to Servo. Previously only printable
characters reached the web engine, making forms unusable.