aboutsummaryrefslogtreecommitdiffstats
path: root/components/shared/embedder/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/shared/embedder/lib.rs')
-rw-r--r--components/shared/embedder/lib.rs75
1 files changed, 74 insertions, 1 deletions
diff --git a/components/shared/embedder/lib.rs b/components/shared/embedder/lib.rs
index 5f1171859dc..c87fa9019ef 100644
--- a/components/shared/embedder/lib.rs
+++ b/components/shared/embedder/lib.rs
@@ -14,7 +14,7 @@ pub mod user_content_manager;
mod webdriver;
use std::ffi::c_void;
-use std::fmt::{Debug, Error, Formatter};
+use std::fmt::{Debug, Display, Error, Formatter};
use std::path::PathBuf;
use std::sync::Arc;
@@ -784,3 +784,76 @@ pub enum AnimationState {
/// No animations are active but callbacks are queued
NoAnimationCallbacksPresent,
}
+
+/// A sequence number generated by a script thread for its pipelines. The
+/// constellation attaches the target pipeline's last seen `FocusSequenceNumber`
+/// to every focus-related message it sends.
+///
+/// This is used to resolve the inconsistency that occurs due to bidirectional
+/// focus state synchronization and provide eventual consistency. Example:
+///
+/// ```text
+/// script constellation
+/// -----------------------------------------------------------------------
+/// send ActivateDocument ----------> receive ActivateDocument
+/// ,---- send FocusDocument
+/// |
+/// focus an iframe |
+/// send Focus -----------------|---> receive Focus
+/// | focus the iframe's content document
+/// receive FocusDocument <-----' send FocusDocument to the content pipeline --> ...
+/// unfocus the iframe
+/// focus the document
+///
+/// Final state: Final state:
+/// the iframe is not focused the iframe is focused
+/// ```
+///
+/// When the above sequence completes, from the script thread's point of view,
+/// the iframe is unfocused, but from the constellation's point of view, the
+/// iframe is still focused.
+///
+/// This inconsistency can be resolved by associating a sequence number to each
+/// message. Whenever a script thread initiates a focus operation, it generates
+/// and sends a brand new sequence number. The constellation attaches the
+/// last-received sequence number to each message it sends. This way, the script
+/// thread can discard out-dated incoming focus messages, and eventually, all
+/// actors converge to the consistent state which is determined based on the
+/// last focus message received by the constellation.
+///
+/// ```text
+/// script constellation
+/// -----------------------------------------------------------------------
+/// send ActivateDocument ----------> receive ActivateDocument
+/// ,---- send FocusDocument (0)
+/// |
+/// seq_number += 1 |
+/// focus an iframe |
+/// send Focus (1) -------------|---> receive Focus (1)
+/// | focus the iframe's content document
+/// receive FocusDocument (0) <-' send FocusDocument to the content pipeline --> ...
+/// ignore it because 0 < 1
+///
+/// Final state: Final state:
+/// the iframe is focused the iframe is focused
+/// ```
+#[derive(
+ Clone,
+ Copy,
+ Debug,
+ Default,
+ Deserialize,
+ Eq,
+ Hash,
+ MallocSizeOf,
+ PartialEq,
+ Serialize,
+ PartialOrd,
+)]
+pub struct FocusSequenceNumber(pub u64);
+
+impl Display for FocusSequenceNumber {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
+ Display::fmt(&self.0, f)
+ }
+}