mirror of
https://github.com/servo/servo.git
synced 2025-08-18 11:55:39 +01:00
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:
parent
5ea003752a
commit
d970584332
8 changed files with 148 additions and 97 deletions
|
@ -182,7 +182,7 @@ impl App {
|
|||
self.servoshell_preferences.clone(),
|
||||
webdriver_receiver,
|
||||
));
|
||||
running_state.new_toplevel_webview(self.initial_url.clone().into_url());
|
||||
running_state.create_and_focus_toplevel_webview(self.initial_url.clone().into_url());
|
||||
|
||||
if let Some(ref mut minibrowser) = self.minibrowser {
|
||||
minibrowser.update(window.winit_window().unwrap(), &running_state, "init");
|
||||
|
@ -310,7 +310,7 @@ impl App {
|
|||
},
|
||||
MinibrowserEvent::NewWebView => {
|
||||
minibrowser.update_location_dirty(false);
|
||||
state.new_toplevel_webview(Url::parse("servo:newtab").unwrap());
|
||||
state.create_and_focus_toplevel_webview(Url::parse("servo:newtab").unwrap());
|
||||
},
|
||||
MinibrowserEvent::CloseWebView(id) => {
|
||||
minibrowser.update_location_dirty(false);
|
||||
|
@ -333,16 +333,69 @@ impl App {
|
|||
match msg {
|
||||
WebDriverCommandMsg::IsWebViewOpen(webview_id, sender) => {
|
||||
let context = running_state.webview_by_id(webview_id);
|
||||
sender.send(context.is_some()).unwrap();
|
||||
|
||||
if let Err(error) = sender.send(context.is_some()) {
|
||||
warn!("Failed to send response of IsWebViewOpein: {error}");
|
||||
}
|
||||
},
|
||||
webdriver_msg @ WebDriverCommandMsg::IsBrowsingContextOpen(..) => {
|
||||
running_state.forward_webdriver_command(webdriver_msg);
|
||||
},
|
||||
WebDriverCommandMsg::NewWebView(response_sender, load_status_sender) => {
|
||||
let new_webview =
|
||||
running_state.create_toplevel_webview(Url::parse("auto:blank").unwrap());
|
||||
|
||||
if let Err(error) = response_sender.send(new_webview.id()) {
|
||||
warn!("Failed to send response of NewWebview: {error}");
|
||||
}
|
||||
|
||||
running_state.set_load_status_sender(new_webview.id(), load_status_sender);
|
||||
},
|
||||
WebDriverCommandMsg::CloseWebView(webview_id) => {
|
||||
running_state.close_webview(webview_id);
|
||||
},
|
||||
WebDriverCommandMsg::GetWindowSize(..) |
|
||||
WebDriverCommandMsg::FocusWebView(..) |
|
||||
WebDriverCommandMsg::FocusWebView(webview_id) => {
|
||||
if let Some(webview) = running_state.webview_by_id(webview_id) {
|
||||
webview.focus();
|
||||
}
|
||||
|
||||
// TODO: send a response to the WebDriver
|
||||
// so it knows when the focus has finished.
|
||||
},
|
||||
WebDriverCommandMsg::GetWindowSize(_webview_id, response_sender) => {
|
||||
let window = self
|
||||
.windows
|
||||
.values()
|
||||
.next()
|
||||
.expect("Should have at least one window in servoshell");
|
||||
|
||||
if let Err(error) = response_sender.send(window.screen_geometry().size) {
|
||||
warn!("Failed to send response of GetWindowSize: {error}");
|
||||
}
|
||||
},
|
||||
WebDriverCommandMsg::SetWindowSize(webview_id, size, size_sender) => {
|
||||
let Some(webview) = running_state.webview_by_id(webview_id) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let window = self
|
||||
.windows
|
||||
.values()
|
||||
.next()
|
||||
.expect("Should have at least one window in servoshell");
|
||||
|
||||
let size = window.request_resize(&webview, size);
|
||||
if let Err(error) = size_sender.send(size.unwrap_or_default()) {
|
||||
warn!("Failed to send window size: {error}");
|
||||
}
|
||||
},
|
||||
WebDriverCommandMsg::GetFocusedWebView(sender) => {
|
||||
let focused_webview = running_state.focused_webview();
|
||||
if let Err(error) = sender.send(focused_webview.map(|w| w.id())) {
|
||||
warn!("Failed to send response of GetFocusedWebView: {error}");
|
||||
};
|
||||
},
|
||||
WebDriverCommandMsg::GetViewportSize(..) |
|
||||
WebDriverCommandMsg::LoadUrl(..) |
|
||||
WebDriverCommandMsg::ScriptCommand(..) |
|
||||
WebDriverCommandMsg::SendKeys(..) |
|
||||
|
@ -350,9 +403,7 @@ impl App {
|
|||
WebDriverCommandMsg::MouseButtonAction(..) |
|
||||
WebDriverCommandMsg::MouseMoveAction(..) |
|
||||
WebDriverCommandMsg::WheelScrollAction(..) |
|
||||
WebDriverCommandMsg::SetWindowSize(..) |
|
||||
WebDriverCommandMsg::TakeScreenshot(..) |
|
||||
WebDriverCommandMsg::NewWebView(..) |
|
||||
WebDriverCommandMsg::Refresh(..) => {
|
||||
warn!(
|
||||
"WebDriverCommand {:?} is still not moved from constellation to embedder",
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -394,7 +394,7 @@ impl Window {
|
|||
}
|
||||
})
|
||||
.shortcut(CMD_OR_CONTROL, 'T', || {
|
||||
state.new_toplevel_webview(Url::parse("servo:newtab").unwrap());
|
||||
state.create_and_focus_toplevel_webview(Url::parse("servo:newtab").unwrap());
|
||||
})
|
||||
.shortcut(CMD_OR_CONTROL, 'Q', || state.servo().start_shutting_down())
|
||||
.otherwise(|| handled = false);
|
||||
|
|
|
@ -336,11 +336,11 @@ impl RunningAppState {
|
|||
}),
|
||||
});
|
||||
|
||||
app_state.new_toplevel_webview(initial_url);
|
||||
app_state.create_and_focus_toplevel_webview(initial_url);
|
||||
app_state
|
||||
}
|
||||
|
||||
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 = WebViewBuilder::new(&self.servo)
|
||||
.url(url)
|
||||
.hidpi_scale_factor(self.inner().hidpi_scale_factor)
|
||||
|
|
|
@ -228,7 +228,7 @@ impl ServoAction {
|
|||
},
|
||||
NewWebview(xcomponent, window) => {
|
||||
servo.pause_compositor();
|
||||
servo.new_toplevel_webview("about:blank".parse().unwrap());
|
||||
servo.create_and_focus_toplevel_webview("about:blank".parse().unwrap());
|
||||
let (window_handle, _, coordinates) =
|
||||
simpleservo::get_raw_window_handle(xcomponent.0, window.0);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue