webdriver: Focus WebView asynchronously (#39241)

#38160 added a webdriver-specific API to support waiting on focus
operations to complete. Later, #38243 added a unique id to track each
focus operation.

Back then we wait on focusing webview in webdriver hoping to improve
stability, but it does not matter as it turns out later. #39086 also
focuses browsing context asynchronously.

This PR would make webdriver's focusing-webview behaviour same as human
interaction.

Testing: 
[Before 1](https://github.com/yezhizhen/servo/actions/runs/17598288280),
[Before 2](https://github.com/yezhizhen/servo/actions/runs/17598289360),
[Before 3](https://github.com/yezhizhen/servo/actions/runs/17598290532)
[After 1](https://github.com/yezhizhen/servo/actions/runs/17598282988),
[After 2](https://github.com/yezhizhen/servo/actions/runs/17598280603),
[After 3](https://github.com/yezhizhen/servo/actions/runs/17589228530)

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
This commit is contained in:
Euclid Ye 2025-09-10 15:36:53 +08:00 committed by GitHub
parent 433a6bf47b
commit 726b456120
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 42 additions and 124 deletions

View file

@ -131,10 +131,10 @@ use devtools_traits::{
use embedder_traits::resources::{self, Resource};
use embedder_traits::user_content_manager::UserContentManager;
use embedder_traits::{
AnimationState, CompositorHitTestResult, EmbedderMsg, EmbedderProxy, FocusId,
FocusSequenceNumber, InputEvent, JSValue, JavaScriptEvaluationError, JavaScriptEvaluationId,
KeyboardEvent, MediaSessionActionType, MediaSessionEvent, MediaSessionPlaybackState,
MouseButton, MouseButtonAction, MouseButtonEvent, ScriptToEmbedderChan, Theme, ViewportDetails,
AnimationState, CompositorHitTestResult, EmbedderMsg, EmbedderProxy, FocusSequenceNumber,
InputEvent, JSValue, JavaScriptEvaluationError, JavaScriptEvaluationId, KeyboardEvent,
MediaSessionActionType, MediaSessionEvent, MediaSessionPlaybackState, MouseButton,
MouseButtonAction, MouseButtonEvent, ScriptToEmbedderChan, Theme, ViewportDetails,
WebDriverCommandMsg, WebDriverCommandResponse, WebDriverLoadStatus, WebDriverScriptCommand,
};
use euclid::Size2D;
@ -1432,8 +1432,8 @@ where
}
self.handle_panic(webview_id, error, None);
},
EmbedderToConstellationMessage::FocusWebView(webview_id, focus_id) => {
self.handle_focus_web_view(webview_id, focus_id);
EmbedderToConstellationMessage::FocusWebView(webview_id) => {
self.handle_focus_web_view(webview_id);
},
EmbedderToConstellationMessage::BlurWebView => {
self.webviews.unfocus();
@ -2871,13 +2871,13 @@ where
}
#[servo_tracing::instrument(skip_all)]
fn handle_focus_web_view(&mut self, webview_id: WebViewId, focus_id: FocusId) {
fn handle_focus_web_view(&mut self, webview_id: WebViewId) {
let focused = self.webviews.focus(webview_id).is_ok();
if !focused {
warn!("{webview_id}: FocusWebView on unknown top-level browsing context");
}
self.embedder_proxy
.send(EmbedderMsg::WebViewFocused(webview_id, focus_id, focused));
.send(EmbedderMsg::WebViewFocused(webview_id, focused));
}
#[servo_tracing::instrument(skip_all)]
@ -4235,11 +4235,8 @@ where
// Focus the top-level browsing context.
let focused = self.webviews.focus(webview_id);
self.embedder_proxy.send(EmbedderMsg::WebViewFocused(
webview_id,
FocusId::new(),
focused.is_ok(),
));
self.embedder_proxy
.send(EmbedderMsg::WebViewFocused(webview_id, focused.is_ok()));
// If a container with a non-null nested browsing context is focused,
// the nested browsing context's active document becomes the focused