Improve inter-document focus handling (#36649)

*Describe the changes that this pull request makes here. This will be
the commit message.*
rewritten the PR #28571
Implement
[Window#focus](https://html.spec.whatwg.org/multipage/#dom-window-focus),
[Window#blur](https://html.spec.whatwg.org/multipage/#dom-window-blur)
Testing: WPT
Fixes: #8981 #9421

---------

Signed-off-by: kongbai1996 <1782765876@qq.com>
Co-authored-by: yvt <i@yvt.jp>
This commit is contained in:
Fuguo 2025-04-30 12:37:53 +08:00 committed by GitHub
parent 27570987fd
commit 0c0ee04b8e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 1123 additions and 242 deletions

View file

@ -50,8 +50,9 @@ use devtools_traits::{
};
use embedder_traits::user_content_manager::UserContentManager;
use embedder_traits::{
CompositorHitTestResult, EmbedderMsg, InputEvent, MediaSessionActionType, MouseButton,
MouseButtonAction, MouseButtonEvent, Theme, ViewportDetails, WebDriverScriptCommand,
CompositorHitTestResult, EmbedderMsg, FocusSequenceNumber, InputEvent, MediaSessionActionType,
MouseButton, MouseButtonAction, MouseButtonEvent, Theme, ViewportDetails,
WebDriverScriptCommand,
};
use euclid::Point2D;
use euclid::default::Rect;
@ -124,7 +125,7 @@ use crate::dom::customelementregistry::{
CallbackReaction, CustomElementDefinition, CustomElementReactionStack,
};
use crate::dom::document::{
Document, DocumentSource, FocusType, HasBrowsingContext, IsHTMLDocument, TouchEventResult,
Document, DocumentSource, FocusInitiator, HasBrowsingContext, IsHTMLDocument, TouchEventResult,
};
use crate::dom::element::Element;
use crate::dom::globalscope::GlobalScope;
@ -1803,8 +1804,14 @@ impl ScriptThread {
ScriptThreadMessage::RemoveHistoryStates(pipeline_id, history_states) => {
self.handle_remove_history_states(pipeline_id, history_states)
},
ScriptThreadMessage::FocusIFrame(parent_pipeline_id, frame_id) => {
self.handle_focus_iframe_msg(parent_pipeline_id, frame_id, can_gc)
ScriptThreadMessage::FocusIFrame(parent_pipeline_id, frame_id, sequence) => {
self.handle_focus_iframe_msg(parent_pipeline_id, frame_id, sequence, can_gc)
},
ScriptThreadMessage::FocusDocument(pipeline_id, sequence) => {
self.handle_focus_document_msg(pipeline_id, sequence, can_gc)
},
ScriptThreadMessage::Unfocus(pipeline_id, sequence) => {
self.handle_unfocus_msg(pipeline_id, sequence, can_gc)
},
ScriptThreadMessage::WebDriverScriptCommand(pipeline_id, msg) => {
self.handle_webdriver_msg(pipeline_id, msg, can_gc)
@ -2513,6 +2520,7 @@ impl ScriptThread {
&self,
parent_pipeline_id: PipelineId,
browsing_context_id: BrowsingContextId,
sequence: FocusSequenceNumber,
can_gc: CanGc,
) {
let document = self
@ -2532,7 +2540,65 @@ impl ScriptThread {
return;
};
document.request_focus(Some(&iframe_element_root), FocusType::Parent, can_gc);
if document.get_focus_sequence() > sequence {
debug!(
"Disregarding the FocusIFrame message because the contained sequence number is \
too old ({:?} < {:?})",
sequence,
document.get_focus_sequence()
);
return;
}
document.request_focus(Some(&iframe_element_root), FocusInitiator::Remote, can_gc);
}
fn handle_focus_document_msg(
&self,
pipeline_id: PipelineId,
sequence: FocusSequenceNumber,
can_gc: CanGc,
) {
if let Some(doc) = self.documents.borrow().find_document(pipeline_id) {
if doc.get_focus_sequence() > sequence {
debug!(
"Disregarding the FocusDocument message because the contained sequence number is \
too old ({:?} < {:?})",
sequence,
doc.get_focus_sequence()
);
return;
}
doc.request_focus(None, FocusInitiator::Remote, can_gc);
} else {
warn!(
"Couldn't find document by pipleline_id:{pipeline_id:?} when handle_focus_document_msg."
);
}
}
fn handle_unfocus_msg(
&self,
pipeline_id: PipelineId,
sequence: FocusSequenceNumber,
can_gc: CanGc,
) {
if let Some(doc) = self.documents.borrow().find_document(pipeline_id) {
if doc.get_focus_sequence() > sequence {
debug!(
"Disregarding the Unfocus message because the contained sequence number is \
too old ({:?} < {:?})",
sequence,
doc.get_focus_sequence()
);
return;
}
doc.handle_container_unfocus(can_gc);
} else {
warn!(
"Couldn't find document by pipleline_id:{pipeline_id:?} when handle_unfocus_msg."
);
}
}
fn handle_post_message_msg(