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.
This commit is contained in:
2026-05-10 00:51:37 -04:00
parent 84ec12e471
commit eb58ce75da
7 changed files with 51 additions and 16 deletions
@@ -9,9 +9,9 @@ use std::{
use ely_domain::{DEFAULT_ZOOM_PERCENT, ProfileId, TabId, UrlText};
use ely_servo_host::{
KeyboardTextRequest, MouseClickRequest, NavigationRequest, PageZoomRequest, PermissionDecision,
PermissionRequest, RenderedFrame, ResizeRequest, ScrollRequest, ServoHost, ServoHostError,
ServoSurfaceSize, SoftwareServoHost, WebViewSnapshot, WebViewState,
KeyboardTextRequest, MouseClickRequest, MouseHoverRequest, NavigationRequest, PageZoomRequest,
PermissionDecision, PermissionRequest, RenderedFrame, ResizeRequest, ScrollRequest, ServoHost,
ServoHostError, ServoSurfaceSize, SoftwareServoHost, WebViewSnapshot, WebViewState,
};
use serde::{Deserialize, Serialize};
use thiserror::Error;
@@ -230,7 +230,7 @@ fn apply_input(
}
if let (Some(x), Some(y)) = (hover_x, hover_y) {
host.hover(x, y)?;
host.hover(MouseHoverRequest { webview_id: session.webview_id.clone(), x, y })?;
changed = true;
}
+7
View File
@@ -242,6 +242,13 @@ pub struct MouseClickRequest {
pub y: u32,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct MouseHoverRequest {
pub webview_id: WebViewId,
pub x: u32,
pub y: u32,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct MouseDragRequest {
pub webview_id: WebViewId,
+4 -3
View File
@@ -15,9 +15,10 @@ mod runtime_webview;
pub use error::ServoHostError;
pub use host::{
KeyboardTextRequest, MouseClickRequest, MouseDragRequest, NavigationRequest, PageZoomRequest,
PermissionDecision, PermissionRequest, RenderedFrame, RenderedFrameSummary, ResizeRequest,
ScreenshotRequest, ScrollRequest, ServoHost, TouchTapRequest, WebViewSnapshot, WebViewState,
KeyboardTextRequest, MouseClickRequest, MouseDragRequest, MouseHoverRequest,
NavigationRequest, PageZoomRequest, PermissionDecision, PermissionRequest, RenderedFrame,
RenderedFrameSummary, ResizeRequest, ScreenshotRequest, ScrollRequest, ServoHost,
TouchTapRequest, WebViewSnapshot, WebViewState,
};
#[cfg(feature = "servo-engine")]
pub use runtime::{ServoSurfaceSize, SoftwareServoHost};
+11 -7
View File
@@ -20,9 +20,10 @@ use servo::{
use url::Url;
use crate::{
KeyboardTextRequest, MouseClickRequest, MouseDragRequest, NavigationRequest, PageZoomRequest,
PermissionDecision, PermissionRequest, RenderedFrame, ResizeRequest, ScreenshotRequest,
ScrollRequest, ServoHost, ServoHostError, TouchTapRequest, WebViewSnapshot, WebViewState,
KeyboardTextRequest, MouseClickRequest, MouseDragRequest, MouseHoverRequest,
NavigationRequest, PageZoomRequest, PermissionDecision, PermissionRequest, RenderedFrame,
ResizeRequest, ScreenshotRequest, ScrollRequest, ServoHost, ServoHostError, TouchTapRequest,
WebViewSnapshot, WebViewState,
runtime_input::{
send_keyboard_text, send_mouse_click, send_mouse_drag, send_mouse_hover, send_touch_tap,
},
@@ -196,10 +197,13 @@ impl ServoHost for SoftwareServoHost {
Ok(())
}
fn hover(&mut self, x: u32, y: u32) -> Result<(), ServoHostError> {
if let Some(webview) = self.webviews.values().next() {
send_mouse_hover(&webview.webview, x, y);
}
fn hover(&mut self, request: MouseHoverRequest) -> Result<(), ServoHostError> {
let webview = self
.webviews
.get(&request.webview_id)
.ok_or_else(|| ServoHostError::WebViewNotFound { id: request.webview_id.clone() })?;
send_mouse_hover(&webview.webview, request.x, request.y);
Ok(())
}