mirror of
https://github.com/servo/servo.git
synced 2025-08-19 04:15:33 +01:00
servo: Track async webview focus operations (#38243)
https://github.com/servo/servo/pull/38160 added a webdriver-specific API to support waiting on focus operations to complete. These changes replace that with a generalized pattern, where a unique ID is created for each focus operation and the embedder can receive notifications about each focus operation when it is complete, regardless of whether the focus was actually changed. Testing: Existing test coverage from https://github.com/servo/servo/pull/38160/ is unchanged. --------- Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
0b8986c8da
commit
be38bd4636
9 changed files with 99 additions and 77 deletions
|
@ -380,7 +380,8 @@ impl App {
|
|||
},
|
||||
WebDriverCommandMsg::FocusWebView(webview_id, response_sender) => {
|
||||
if let Some(webview) = running_state.webview_by_id(webview_id) {
|
||||
webview.focus_from_webdriver(response_sender);
|
||||
let focus_id = webview.focus();
|
||||
running_state.set_pending_focus(focus_id, response_sender);
|
||||
}
|
||||
},
|
||||
WebDriverCommandMsg::GetWindowRect(_webview_id, response_sender) => {
|
||||
|
@ -478,21 +479,13 @@ impl App {
|
|||
WebDriverCommandMsg::GoBack(webview_id, load_status_sender) => {
|
||||
if let Some(webview) = running_state.webview_by_id(webview_id) {
|
||||
let traversal_id = webview.go_back(1);
|
||||
running_state.set_pending_traversal(
|
||||
webview_id,
|
||||
traversal_id,
|
||||
load_status_sender,
|
||||
);
|
||||
running_state.set_pending_traversal(traversal_id, load_status_sender);
|
||||
}
|
||||
},
|
||||
WebDriverCommandMsg::GoForward(webview_id, load_status_sender) => {
|
||||
if let Some(webview) = running_state.webview_by_id(webview_id) {
|
||||
let traversal_id = webview.go_forward(1);
|
||||
running_state.set_pending_traversal(
|
||||
webview_id,
|
||||
traversal_id,
|
||||
load_status_sender,
|
||||
);
|
||||
running_state.set_pending_traversal(traversal_id, load_status_sender);
|
||||
}
|
||||
},
|
||||
// Key events don't need hit test so can be forwarded to constellation for now
|
||||
|
|
|
@ -18,10 +18,11 @@ use servo::ipc_channel::ipc::IpcSender;
|
|||
use servo::webrender_api::ScrollLocation;
|
||||
use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize};
|
||||
use servo::{
|
||||
AllowOrDenyRequest, AuthenticationRequest, FilterPattern, FormControl, GamepadHapticEffectType,
|
||||
KeyboardEvent, LoadStatus, PermissionRequest, Servo, ServoDelegate, ServoError, SimpleDialog,
|
||||
TraversalId, WebDriverCommandMsg, WebDriverJSResult, WebDriverJSValue, WebDriverLoadStatus,
|
||||
WebDriverUserPrompt, WebView, WebViewBuilder, WebViewDelegate,
|
||||
AllowOrDenyRequest, AuthenticationRequest, FilterPattern, FocusId, FormControl,
|
||||
GamepadHapticEffectType, KeyboardEvent, LoadStatus, PermissionRequest, Servo, ServoDelegate,
|
||||
ServoError, SimpleDialog, TraversalId, WebDriverCommandMsg, WebDriverJSResult,
|
||||
WebDriverJSValue, WebDriverLoadStatus, WebDriverUserPrompt, WebView, WebViewBuilder,
|
||||
WebViewDelegate,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
|
@ -45,7 +46,8 @@ pub(crate) enum AppState {
|
|||
struct WebDriverSenders {
|
||||
pub load_status_senders: HashMap<WebViewId, IpcSender<WebDriverLoadStatus>>,
|
||||
pub script_evaluation_interrupt_sender: Option<IpcSender<WebDriverJSResult>>,
|
||||
pub pending_traversals: HashMap<WebViewId, (TraversalId, IpcSender<WebDriverLoadStatus>)>,
|
||||
pub pending_traversals: HashMap<TraversalId, IpcSender<WebDriverLoadStatus>>,
|
||||
pub pending_focus: HashMap<FocusId, IpcSender<bool>>,
|
||||
}
|
||||
|
||||
pub(crate) struct RunningAppState {
|
||||
|
@ -267,7 +269,9 @@ impl RunningAppState {
|
|||
.and_then(|id| inner.webviews.get(id));
|
||||
|
||||
match last_created {
|
||||
Some(last_created_webview) => last_created_webview.focus(),
|
||||
Some(last_created_webview) => {
|
||||
last_created_webview.focus();
|
||||
},
|
||||
None => self.servo.start_shutting_down(),
|
||||
}
|
||||
}
|
||||
|
@ -446,16 +450,22 @@ impl RunningAppState {
|
|||
});
|
||||
}
|
||||
|
||||
pub(crate) fn set_pending_focus(&self, focus_id: FocusId, sender: IpcSender<bool>) {
|
||||
self.webdriver_senders
|
||||
.borrow_mut()
|
||||
.pending_focus
|
||||
.insert(focus_id, sender);
|
||||
}
|
||||
|
||||
pub(crate) fn set_pending_traversal(
|
||||
&self,
|
||||
webview_id: WebViewId,
|
||||
traversal_id: TraversalId,
|
||||
sender: IpcSender<WebDriverLoadStatus>,
|
||||
) {
|
||||
self.webdriver_senders
|
||||
.borrow_mut()
|
||||
.pending_traversals
|
||||
.insert(webview_id, (traversal_id, sender));
|
||||
.insert(traversal_id, sender);
|
||||
}
|
||||
|
||||
pub(crate) fn set_load_status_sender(
|
||||
|
@ -539,13 +549,11 @@ impl WebViewDelegate for RunningAppState {
|
|||
}
|
||||
}
|
||||
|
||||
fn notify_traversal_complete(&self, webview: servo::WebView, traversal_id: TraversalId) {
|
||||
fn notify_traversal_complete(&self, _webview: servo::WebView, traversal_id: TraversalId) {
|
||||
let mut webdriver_state = self.webdriver_senders.borrow_mut();
|
||||
if let Entry::Occupied(entry) = webdriver_state.pending_traversals.entry(webview.id()) {
|
||||
if entry.get().0 == traversal_id {
|
||||
let (_, sender) = entry.remove();
|
||||
let _ = sender.send(WebDriverLoadStatus::Complete);
|
||||
}
|
||||
if let Entry::Occupied(entry) = webdriver_state.pending_traversals.entry(traversal_id) {
|
||||
let sender = entry.remove();
|
||||
let _ = sender.send(WebDriverLoadStatus::Complete);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -638,6 +646,14 @@ impl WebViewDelegate for RunningAppState {
|
|||
self.close_webview(webview.id());
|
||||
}
|
||||
|
||||
fn notify_focus_complete(&self, webview: servo::WebView, focus_id: FocusId) {
|
||||
let mut webdriver_state = self.webdriver_senders.borrow_mut();
|
||||
if let Entry::Occupied(entry) = webdriver_state.pending_focus.entry(focus_id) {
|
||||
let sender = entry.remove();
|
||||
let _ = sender.send(webview.focused());
|
||||
}
|
||||
}
|
||||
|
||||
fn notify_focus_changed(&self, webview: servo::WebView, focused: bool) {
|
||||
let mut inner_mut = self.inner_mut();
|
||||
if focused {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue