webdriver: Move NewWebView, FocusWebView, GetWindowSize, and SetWindowSize to servoshell (#37555)

Follow up to: https://github.com/servo/servo/pull/36714
Moving webdriver [context
commands](https://www.w3.org/TR/webdriver2/#contexts) to be handled in
embedder:

- [x] New Window command - `WebdriverCommandMsg::NewWebView`
- [x]  Switch To Window command - `WebdriverCommandMsg::FocusWebView`
- [x] Resizing commands

cc: @xiaochengh

---------

Signed-off-by: batu_hoang <longvatrong111@gmail.com>
This commit is contained in:
batu_hoang 2025-06-25 18:29:34 +08:00 committed by GitHub
parent 5ea003752a
commit d970584332
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 148 additions and 97 deletions

View file

@ -19,7 +19,7 @@ use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize};
use servo::{
AllowOrDenyRequest, AuthenticationRequest, FilterPattern, FormControl, GamepadHapticEffectType,
KeyboardEvent, LoadStatus, PermissionRequest, Servo, ServoDelegate, ServoError, SimpleDialog,
WebDriverCommandMsg, WebView, WebViewBuilder, WebViewDelegate,
WebDriverCommandMsg, WebDriverLoadStatus, WebView, WebViewBuilder, WebViewDelegate,
};
use url::Url;
@ -37,6 +37,13 @@ pub(crate) enum AppState {
ShuttingDown,
}
/// A collection of [`IpcSender`]s that are used to asynchronously communicate
/// to a WebDriver server with information about application state.
#[derive(Clone, Default)]
struct WebDriverSenders {
pub load_status_senders: HashMap<WebViewId, IpcSender<WebDriverLoadStatus>>,
}
pub(crate) struct RunningAppState {
/// A handle to the Servo instance of the [`RunningAppState`]. This is not stored inside
/// `inner` so that we can keep a reference to Servo in order to spin the event loop,
@ -48,6 +55,7 @@ pub(crate) struct RunningAppState {
/// A [`Receiver`] for receiving commands from a running WebDriver server, if WebDriver
/// was enabled.
webdriver_receiver: Option<Receiver<WebDriverCommandMsg>>,
webdriver_senders: RefCell<WebDriverSenders>,
inner: RefCell<RunningAppStateInner>,
}
@ -99,6 +107,7 @@ impl RunningAppState {
servo,
servoshell_preferences,
webdriver_receiver,
webdriver_senders: RefCell::default(),
inner: RefCell::new(RunningAppStateInner {
webviews: HashMap::default(),
creation_order: Default::default(),
@ -112,7 +121,13 @@ impl RunningAppState {
}
}
pub(crate) fn new_toplevel_webview(self: &Rc<Self>, url: Url) {
pub(crate) fn create_and_focus_toplevel_webview(self: &Rc<Self>, url: Url) {
let webview = self.create_toplevel_webview(url);
webview.focus();
webview.raise_to_top(true);
}
pub(crate) fn create_toplevel_webview(self: &Rc<Self>, url: Url) -> WebView {
let webview = WebViewBuilder::new(self.servo())
.url(url)
.hidpi_scale_factor(self.inner().window.hidpi_scale_factor())
@ -120,10 +135,8 @@ impl RunningAppState {
.build();
webview.notify_theme_change(self.inner().window.theme());
webview.focus();
webview.raise_to_top(true);
self.add(webview);
self.add(webview.clone());
webview
}
pub(crate) fn inner(&self) -> Ref<RunningAppStateInner> {
@ -382,6 +395,17 @@ impl RunningAppState {
webview.notify_scroll_event(location, origin);
});
}
pub(crate) fn set_load_status_sender(
&self,
webview_id: WebViewId,
sender: IpcSender<WebDriverLoadStatus>,
) {
self.webdriver_senders
.borrow_mut()
.load_status_senders
.insert(webview_id, sender);
}
}
struct ServoShellServoDelegate;
@ -507,8 +531,19 @@ impl WebViewDelegate for RunningAppState {
self.inner().window.set_cursor(cursor);
}
fn notify_load_status_changed(&self, _webview: servo::WebView, _status: LoadStatus) {
fn notify_load_status_changed(&self, webview: servo::WebView, status: LoadStatus) {
self.inner_mut().need_update = true;
if status == LoadStatus::Complete {
if let Some(sender) = self
.webdriver_senders
.borrow_mut()
.load_status_senders
.remove(&webview.id())
{
let _ = sender.send(WebDriverLoadStatus::Complete);
}
}
}
fn notify_fullscreen_state_changed(&self, _webview: servo::WebView, fullscreen_state: bool) {