mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #22051 - mandreyel:track-focused-bc-of-each-tlbc, r=cbrewster
Update Constellation to track each browser's focused browsing context Since there may be multiple browsers (top-level browsing contexts), each has a focused browsing context. However, we were not keeping track of each browser's focused browsing context, so e.g when switching tabs the `Constellation::focused_browsing_context_id` would not be set to the switched-to browser's focused browsing context. This PR introduces a `browser_ids` `HashMap` in constellation, that maps each of the top-level browsing context's ids to their currently focused browsing context's id, so that when the active browser is changed with the `SelectBrowser` message, we can look up and restore the selected browser's focused browsing context. This is a wip. For one, I'm not a fan of adding another hash map to constellation, and since there already is a hash map for keeping track of a browser's joint session history, we could introduce some `Browser` struct to hold data for a browser like its session history and focused browsing context (and possibly more later). But wanted to implement the bare-bones logic to first ensure correctness and will refactor later. Also, we may need new tests but I'm not sure. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #17401 (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22051) <!-- Reviewable:end -->
This commit is contained in:
commit
ddc85098af
1 changed files with 116 additions and 76 deletions
|
@ -155,6 +155,18 @@ use timer_scheduler::TimerScheduler;
|
||||||
use webrender_api;
|
use webrender_api;
|
||||||
use webvr_traits::{WebVREvent, WebVRMsg};
|
use webvr_traits::{WebVREvent, WebVRMsg};
|
||||||
|
|
||||||
|
/// Servo supports tabs (referred to as browsers), so `Constellation` needs to
|
||||||
|
/// store browser specific data for bookkeeping.
|
||||||
|
struct Browser {
|
||||||
|
/// The currently focused browsing context in this browser for key events.
|
||||||
|
/// The focused pipeline is the current entry of the focused browsing
|
||||||
|
/// context.
|
||||||
|
focused_browsing_context_id: BrowsingContextId,
|
||||||
|
|
||||||
|
/// The joint session history for this browser.
|
||||||
|
session_history: JointSessionHistory,
|
||||||
|
}
|
||||||
|
|
||||||
/// The `Constellation` itself. In the servo browser, there is one
|
/// The `Constellation` itself. In the servo browser, there is one
|
||||||
/// constellation, which maintains all of the browser global data.
|
/// constellation, which maintains all of the browser global data.
|
||||||
/// In embedded applications, there may be more than one constellation,
|
/// In embedded applications, there may be more than one constellation,
|
||||||
|
@ -201,13 +213,17 @@ pub struct Constellation<Message, LTF, STF> {
|
||||||
/// constellation to send messages to the compositor thread.
|
/// constellation to send messages to the compositor thread.
|
||||||
compositor_proxy: CompositorProxy,
|
compositor_proxy: CompositorProxy,
|
||||||
|
|
||||||
/// The last frame tree sent to WebRender.
|
/// The last frame tree sent to WebRender, denoting the browser (tab) user
|
||||||
|
/// has currently selected. This also serves as the key to retrieve data
|
||||||
|
/// about the current active browser from `browsers`.
|
||||||
active_browser_id: Option<TopLevelBrowsingContextId>,
|
active_browser_id: Option<TopLevelBrowsingContextId>,
|
||||||
|
|
||||||
|
/// Bookkeeping data for all browsers in constellation.
|
||||||
|
browsers: HashMap<TopLevelBrowsingContextId, Browser>,
|
||||||
|
|
||||||
/// Channels for the constellation to send messages to the public
|
/// Channels for the constellation to send messages to the public
|
||||||
/// resource-related threads. There are two groups of resource
|
/// resource-related threads. There are two groups of resource threads: one
|
||||||
/// threads: one for public browsing, and one for private
|
/// for public browsing, and one for private browsing.
|
||||||
/// browsing.
|
|
||||||
public_resource_threads: ResourceThreads,
|
public_resource_threads: ResourceThreads,
|
||||||
|
|
||||||
/// Channels for the constellation to send messages to the private
|
/// Channels for the constellation to send messages to the private
|
||||||
|
@ -273,10 +289,8 @@ pub struct Constellation<Message, LTF, STF> {
|
||||||
/// to become same-origin, at which point they can share DOM objects.
|
/// to become same-origin, at which point they can share DOM objects.
|
||||||
event_loops: HashMap<Host, Weak<EventLoop>>,
|
event_loops: HashMap<Host, Weak<EventLoop>>,
|
||||||
|
|
||||||
joint_session_histories: HashMap<TopLevelBrowsingContextId, JointSessionHistory>,
|
/// The set of all the pipelines in the browser. (See the `pipeline` module
|
||||||
|
/// for more details.)
|
||||||
/// The set of all the pipelines in the browser.
|
|
||||||
/// (See the `pipeline` module for more details.)
|
|
||||||
pipelines: HashMap<PipelineId, Pipeline>,
|
pipelines: HashMap<PipelineId, Pipeline>,
|
||||||
|
|
||||||
/// The set of all the browsing contexts in the browser.
|
/// The set of all the browsing contexts in the browser.
|
||||||
|
@ -289,11 +303,6 @@ pub struct Constellation<Message, LTF, STF> {
|
||||||
/// we store a `SessionHistoryChange` object for the navigation in progress.
|
/// we store a `SessionHistoryChange` object for the navigation in progress.
|
||||||
pending_changes: Vec<SessionHistoryChange>,
|
pending_changes: Vec<SessionHistoryChange>,
|
||||||
|
|
||||||
/// The currently focused browsing context for key events. The focused
|
|
||||||
/// pipeline is the current entry of the focused browsing
|
|
||||||
/// context.
|
|
||||||
focused_browsing_context_id: Option<BrowsingContextId>,
|
|
||||||
|
|
||||||
/// Pipeline IDs are namespaced in order to avoid name collisions,
|
/// Pipeline IDs are namespaced in order to avoid name collisions,
|
||||||
/// and the namespaces are allocated by the constellation.
|
/// and the namespaces are allocated by the constellation.
|
||||||
next_pipeline_namespace_id: PipelineNamespaceId,
|
next_pipeline_namespace_id: PipelineNamespaceId,
|
||||||
|
@ -591,6 +600,7 @@ where
|
||||||
embedder_proxy: state.embedder_proxy,
|
embedder_proxy: state.embedder_proxy,
|
||||||
compositor_proxy: state.compositor_proxy,
|
compositor_proxy: state.compositor_proxy,
|
||||||
active_browser_id: None,
|
active_browser_id: None,
|
||||||
|
browsers: HashMap::new(),
|
||||||
debugger_chan: state.debugger_chan,
|
debugger_chan: state.debugger_chan,
|
||||||
devtools_chan: state.devtools_chan,
|
devtools_chan: state.devtools_chan,
|
||||||
bluetooth_thread: state.bluetooth_thread,
|
bluetooth_thread: state.bluetooth_thread,
|
||||||
|
@ -601,14 +611,12 @@ where
|
||||||
swmanager_receiver: swmanager_receiver,
|
swmanager_receiver: swmanager_receiver,
|
||||||
swmanager_sender: sw_mgr_clone,
|
swmanager_sender: sw_mgr_clone,
|
||||||
event_loops: HashMap::new(),
|
event_loops: HashMap::new(),
|
||||||
joint_session_histories: HashMap::new(),
|
|
||||||
pipelines: HashMap::new(),
|
pipelines: HashMap::new(),
|
||||||
browsing_contexts: HashMap::new(),
|
browsing_contexts: HashMap::new(),
|
||||||
pending_changes: vec![],
|
pending_changes: vec![],
|
||||||
// We initialize the namespace at 2, since we reserved
|
// We initialize the namespace at 2, since we reserved
|
||||||
// namespace 0 for the embedder, and 0 for the constellation
|
// namespace 0 for the embedder, and 0 for the constellation
|
||||||
next_pipeline_namespace_id: PipelineNamespaceId(2),
|
next_pipeline_namespace_id: PipelineNamespaceId(2),
|
||||||
focused_browsing_context_id: None,
|
|
||||||
time_profiler_chan: state.time_profiler_chan,
|
time_profiler_chan: state.time_profiler_chan,
|
||||||
mem_profiler_chan: state.mem_profiler_chan,
|
mem_profiler_chan: state.mem_profiler_chan,
|
||||||
window_size: WindowSizeData {
|
window_size: WindowSizeData {
|
||||||
|
@ -964,14 +972,9 @@ where
|
||||||
self.handle_get_pipeline(browsing_context_id, resp_chan);
|
self.handle_get_pipeline(browsing_context_id, resp_chan);
|
||||||
},
|
},
|
||||||
FromCompositorMsg::GetFocusTopLevelBrowsingContext(resp_chan) => {
|
FromCompositorMsg::GetFocusTopLevelBrowsingContext(resp_chan) => {
|
||||||
let focus_browsing_context = self.focused_browsing_context_id
|
// The focused browsing context's top-level browsing context is
|
||||||
.and_then(|ctx_id| self.browsing_contexts.get(&ctx_id))
|
// the active browser's id itself.
|
||||||
.map(|ctx| ctx.top_level_id)
|
let _ = resp_chan.send(self.active_browser_id);
|
||||||
.filter(|&top_level_ctx_id| {
|
|
||||||
let ctx_id = BrowsingContextId::from(top_level_ctx_id);
|
|
||||||
self.browsing_contexts.contains_key(&ctx_id)
|
|
||||||
});
|
|
||||||
let _ = resp_chan.send(focus_browsing_context);
|
|
||||||
},
|
},
|
||||||
FromCompositorMsg::Keyboard(key_event) => {
|
FromCompositorMsg::Keyboard(key_event) => {
|
||||||
self.handle_key_msg(key_event);
|
self.handle_key_msg(key_event);
|
||||||
|
@ -1650,12 +1653,13 @@ where
|
||||||
let is_private = false;
|
let is_private = false;
|
||||||
let is_visible = true;
|
let is_visible = true;
|
||||||
|
|
||||||
if self.focused_browsing_context_id.is_none() {
|
// Register this new top-level browsing context id as a browser and set
|
||||||
self.focused_browsing_context_id = Some(browsing_context_id);
|
// its focused browsing context to be itself.
|
||||||
}
|
self.browsers.insert(top_level_browsing_context_id, Browser {
|
||||||
|
focused_browsing_context_id: browsing_context_id,
|
||||||
|
session_history: JointSessionHistory::new(),
|
||||||
|
});
|
||||||
|
|
||||||
self.joint_session_histories
|
|
||||||
.insert(top_level_browsing_context_id, JointSessionHistory::new());
|
|
||||||
self.new_pipeline(
|
self.new_pipeline(
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
browsing_context_id,
|
browsing_context_id,
|
||||||
|
@ -1687,6 +1691,10 @@ where
|
||||||
) {
|
) {
|
||||||
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
|
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
|
||||||
self.close_browsing_context(browsing_context_id, ExitPipelineMode::Normal);
|
self.close_browsing_context(browsing_context_id, ExitPipelineMode::Normal);
|
||||||
|
self.browsers.remove(&top_level_browsing_context_id);
|
||||||
|
if self.active_browser_id == Some(top_level_browsing_context_id) {
|
||||||
|
self.active_browser_id = None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_iframe_size_msg(
|
fn handle_iframe_size_msg(
|
||||||
|
@ -1966,7 +1974,10 @@ where
|
||||||
|
|
||||||
assert!(!self.pipelines.contains_key(&new_pipeline_id));
|
assert!(!self.pipelines.contains_key(&new_pipeline_id));
|
||||||
self.pipelines.insert(new_pipeline_id, pipeline);
|
self.pipelines.insert(new_pipeline_id, pipeline);
|
||||||
self.joint_session_histories.insert(new_top_level_browsing_context_id, JointSessionHistory::new());
|
self.browsers.insert(new_top_level_browsing_context_id, Browser {
|
||||||
|
focused_browsing_context_id: new_browsing_context_id,
|
||||||
|
session_history: JointSessionHistory::new(),
|
||||||
|
});
|
||||||
self.add_pending_change(SessionHistoryChange {
|
self.add_pending_change(SessionHistoryChange {
|
||||||
top_level_browsing_context_id: new_top_level_browsing_context_id,
|
top_level_browsing_context_id: new_top_level_browsing_context_id,
|
||||||
browsing_context_id: new_browsing_context_id,
|
browsing_context_id: new_browsing_context_id,
|
||||||
|
@ -2558,9 +2569,9 @@ where
|
||||||
sender: IpcSender<u32>,
|
sender: IpcSender<u32>,
|
||||||
) {
|
) {
|
||||||
let length = self
|
let length = self
|
||||||
.joint_session_histories
|
.browsers
|
||||||
.get(&top_level_browsing_context_id)
|
.get(&top_level_browsing_context_id)
|
||||||
.map(JointSessionHistory::history_length)
|
.map(|browser| browser.session_history.history_length())
|
||||||
.unwrap_or(1);
|
.unwrap_or(1);
|
||||||
let _ = sender.send(length as u32);
|
let _ = sender.send(length as u32);
|
||||||
}
|
}
|
||||||
|
@ -2631,7 +2642,11 @@ where
|
||||||
fn handle_key_msg(&mut self, event: KeyboardEvent) {
|
fn handle_key_msg(&mut self, event: KeyboardEvent) {
|
||||||
// Send to the focused browsing contexts' current pipeline. If it
|
// Send to the focused browsing contexts' current pipeline. If it
|
||||||
// doesn't exist, fall back to sending to the compositor.
|
// doesn't exist, fall back to sending to the compositor.
|
||||||
match self.focused_browsing_context_id {
|
let focused_browsing_context_id = self
|
||||||
|
.active_browser_id
|
||||||
|
.and_then(|browser_id| self.browsers.get(&browser_id))
|
||||||
|
.map(|browser| browser.focused_browsing_context_id);
|
||||||
|
match focused_browsing_context_id {
|
||||||
Some(browsing_context_id) => {
|
Some(browsing_context_id) => {
|
||||||
let event = CompositorEvent::KeyboardEvent(event);
|
let event = CompositorEvent::KeyboardEvent(event);
|
||||||
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
|
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
|
||||||
|
@ -2644,9 +2659,10 @@ where
|
||||||
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
|
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
|
||||||
let result = match self.pipelines.get(&pipeline_id) {
|
let result = match self.pipelines.get(&pipeline_id) {
|
||||||
Some(pipeline) => pipeline.event_loop.send(msg),
|
Some(pipeline) => pipeline.event_loop.send(msg),
|
||||||
None => {
|
None => return debug!(
|
||||||
return debug!("Pipeline {:?} got key event after closure.", pipeline_id)
|
"Pipeline {:?} got key event after closure.",
|
||||||
},
|
pipeline_id
|
||||||
|
),
|
||||||
};
|
};
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
self.handle_send_error(pipeline_id, e);
|
self.handle_send_error(pipeline_id, e);
|
||||||
|
@ -2741,11 +2757,25 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_focus_msg(&mut self, pipeline_id: PipelineId) {
|
fn handle_focus_msg(&mut self, pipeline_id: PipelineId) {
|
||||||
let browsing_context_id = match self.pipelines.get(&pipeline_id) {
|
let (browsing_context_id, top_level_browsing_context_id) =
|
||||||
Some(pipeline) => pipeline.browsing_context_id,
|
match self.pipelines.get(&pipeline_id) {
|
||||||
None => return warn!("Pipeline {:?} focus parent after closure.", pipeline_id),
|
Some(pipeline) => (
|
||||||
|
pipeline.browsing_context_id,
|
||||||
|
pipeline.top_level_browsing_context_id,
|
||||||
|
),
|
||||||
|
None => return warn!("Pipeline {:?} focus parent after closure.", pipeline_id),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update the focused browsing context in its browser in `browsers`.
|
||||||
|
match self.browsers.get_mut(&top_level_browsing_context_id) {
|
||||||
|
Some(browser) => {
|
||||||
|
browser.focused_browsing_context_id = browsing_context_id;
|
||||||
|
},
|
||||||
|
None => return warn!(
|
||||||
|
"Browser {} for focus msg does not exist",
|
||||||
|
top_level_browsing_context_id
|
||||||
|
),
|
||||||
};
|
};
|
||||||
self.focused_browsing_context_id = Some(browsing_context_id);
|
|
||||||
|
|
||||||
// Focus parent iframes recursively
|
// Focus parent iframes recursively
|
||||||
self.focus_parent_pipeline(browsing_context_id);
|
self.focus_parent_pipeline(browsing_context_id);
|
||||||
|
@ -2970,11 +3000,8 @@ where
|
||||||
// LoadData of inner frames are ignored and replaced with the LoadData
|
// LoadData of inner frames are ignored and replaced with the LoadData
|
||||||
// of the parent.
|
// of the parent.
|
||||||
|
|
||||||
let session_history = match self
|
let session_history = match self.browsers.get(&top_level_browsing_context_id) {
|
||||||
.joint_session_histories
|
Some(browser) => &browser.session_history,
|
||||||
.get(&top_level_browsing_context_id)
|
|
||||||
{
|
|
||||||
Some(session_history) => session_history,
|
|
||||||
None => {
|
None => {
|
||||||
return warn!(
|
return warn!(
|
||||||
"Session history does not exist for {}",
|
"Session history does not exist for {}",
|
||||||
|
@ -3120,9 +3147,13 @@ where
|
||||||
|
|
||||||
// If the currently focused browsing context is a child of the browsing
|
// If the currently focused browsing context is a child of the browsing
|
||||||
// context in which the page is being loaded, then update the focused
|
// context in which the page is being loaded, then update the focused
|
||||||
// browsing context to that one.
|
// browsing context to be the one where the page is being loaded.
|
||||||
if self.focused_browsing_context_is_descendant_of(change.browsing_context_id) {
|
if self.focused_browsing_context_is_descendant_of(change.browsing_context_id) {
|
||||||
self.focused_browsing_context_id = Some(change.browsing_context_id);
|
self.browsers
|
||||||
|
.entry(change.top_level_browsing_context_id)
|
||||||
|
.and_modify(|browser| {
|
||||||
|
browser.focused_browsing_context_id = change.browsing_context_id
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let (old_pipeline_id, top_level_id) =
|
let (old_pipeline_id, top_level_id) =
|
||||||
|
@ -3169,24 +3200,17 @@ where
|
||||||
let (pipelines_to_close, states_to_close) = if let Some(replace_reloader) =
|
let (pipelines_to_close, states_to_close) = if let Some(replace_reloader) =
|
||||||
change.replace
|
change.replace
|
||||||
{
|
{
|
||||||
let session_history = self
|
self.get_joint_session_history(change.top_level_browsing_context_id)
|
||||||
.joint_session_histories
|
.replace_reloader(
|
||||||
.entry(change.top_level_browsing_context_id)
|
replace_reloader.clone(),
|
||||||
.or_insert(JointSessionHistory::new());
|
NeedsToReload::No(change.new_pipeline_id),
|
||||||
session_history.replace_reloader(
|
);
|
||||||
replace_reloader.clone(),
|
|
||||||
NeedsToReload::No(change.new_pipeline_id),
|
|
||||||
);
|
|
||||||
|
|
||||||
match replace_reloader {
|
match replace_reloader {
|
||||||
NeedsToReload::No(pipeline_id) => (Some(vec![pipeline_id]), None),
|
NeedsToReload::No(pipeline_id) => (Some(vec![pipeline_id]), None),
|
||||||
NeedsToReload::Yes(..) => (None, None),
|
NeedsToReload::Yes(..) => (None, None),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let session_history = self
|
|
||||||
.joint_session_histories
|
|
||||||
.entry(change.top_level_browsing_context_id)
|
|
||||||
.or_insert(JointSessionHistory::new());
|
|
||||||
let diff = SessionHistoryDiff::BrowsingContextDiff {
|
let diff = SessionHistoryDiff::BrowsingContextDiff {
|
||||||
browsing_context_id: change.browsing_context_id,
|
browsing_context_id: change.browsing_context_id,
|
||||||
new_reloader: NeedsToReload::No(change.new_pipeline_id),
|
new_reloader: NeedsToReload::No(change.new_pipeline_id),
|
||||||
|
@ -3196,7 +3220,9 @@ where
|
||||||
let mut pipelines_to_close = vec![];
|
let mut pipelines_to_close = vec![];
|
||||||
let mut states_to_close = HashMap::new();
|
let mut states_to_close = HashMap::new();
|
||||||
|
|
||||||
let diffs_to_close = session_history.push_diff(diff);
|
let diffs_to_close = self
|
||||||
|
.get_joint_session_history(change.top_level_browsing_context_id)
|
||||||
|
.push_diff(diff);
|
||||||
|
|
||||||
for diff in diffs_to_close {
|
for diff in diffs_to_close {
|
||||||
match diff {
|
match diff {
|
||||||
|
@ -3270,7 +3296,11 @@ where
|
||||||
&self,
|
&self,
|
||||||
browsing_context_id: BrowsingContextId
|
browsing_context_id: BrowsingContextId
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.focused_browsing_context_id.map_or(false, |focus_ctx_id| {
|
let focused_browsing_context_id = self
|
||||||
|
.active_browser_id
|
||||||
|
.and_then(|browser_id| self.browsers.get(&browser_id))
|
||||||
|
.map(|browser| browser.focused_browsing_context_id);
|
||||||
|
focused_browsing_context_id.map_or(false, |focus_ctx_id| {
|
||||||
focus_ctx_id == browsing_context_id || self
|
focus_ctx_id == browsing_context_id || self
|
||||||
.fully_active_descendant_browsing_contexts_iter(browsing_context_id)
|
.fully_active_descendant_browsing_contexts_iter(browsing_context_id)
|
||||||
.any(|nested_ctx| nested_ctx.id == focus_ctx_id)
|
.any(|nested_ctx| nested_ctx.id == focus_ctx_id)
|
||||||
|
@ -3433,10 +3463,7 @@ where
|
||||||
//
|
//
|
||||||
// If there is no focus browsing context yet, the initial page has
|
// If there is no focus browsing context yet, the initial page has
|
||||||
// not loaded, so there is nothing to save yet.
|
// not loaded, so there is nothing to save yet.
|
||||||
let top_level_browsing_context_id = self.focused_browsing_context_id
|
let top_level_browsing_context_id = match self.active_browser_id {
|
||||||
.and_then(|ctx_id| self.browsing_contexts.get(&ctx_id))
|
|
||||||
.map(|ctx| ctx.top_level_id);
|
|
||||||
let top_level_browsing_context_id = match top_level_browsing_context_id {
|
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
None => return ReadyToSave::NoTopLevelBrowsingContext,
|
None => return ReadyToSave::NoTopLevelBrowsingContext,
|
||||||
};
|
};
|
||||||
|
@ -3719,17 +3746,23 @@ where
|
||||||
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
top_level_browsing_context_id: TopLevelBrowsingContextId,
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
) {
|
) {
|
||||||
let load_data = match self.pipelines.get(&pipeline_id) {
|
match self.browsers.get_mut(&top_level_browsing_context_id) {
|
||||||
Some(pipeline) => pipeline.load_data.clone(),
|
Some(browser) => {
|
||||||
None => return,
|
let load_data = match self.pipelines.get(&pipeline_id) {
|
||||||
|
Some(pipeline) => pipeline.load_data.clone(),
|
||||||
|
None => return warn!("Discarding closed pipeline {}", pipeline_id),
|
||||||
|
};
|
||||||
|
browser.session_history.replace_reloader(
|
||||||
|
NeedsToReload::No(pipeline_id),
|
||||||
|
NeedsToReload::Yes(pipeline_id, load_data),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
None => return warn!(
|
||||||
|
"Discarding pipeline {} after browser {} closure",
|
||||||
|
pipeline_id,
|
||||||
|
top_level_browsing_context_id,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
self.joint_session_histories
|
|
||||||
.entry(top_level_browsing_context_id)
|
|
||||||
.or_insert(JointSessionHistory::new())
|
|
||||||
.replace_reloader(
|
|
||||||
NeedsToReload::No(pipeline_id),
|
|
||||||
NeedsToReload::Yes(pipeline_id, load_data),
|
|
||||||
);
|
|
||||||
self.close_pipeline(
|
self.close_pipeline(
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
DiscardBrowsingContext::No,
|
DiscardBrowsingContext::No,
|
||||||
|
@ -3848,9 +3881,16 @@ where
|
||||||
&mut self,
|
&mut self,
|
||||||
top_level_id: TopLevelBrowsingContextId,
|
top_level_id: TopLevelBrowsingContextId,
|
||||||
) -> &mut JointSessionHistory {
|
) -> &mut JointSessionHistory {
|
||||||
self.joint_session_histories
|
&mut self.browsers
|
||||||
.entry(top_level_id)
|
.entry(top_level_id)
|
||||||
.or_insert(JointSessionHistory::new())
|
// This shouldn't be necessary since `get_joint_session_history` is
|
||||||
|
// invoked for existing browsers but we need this to satisfy the
|
||||||
|
// type system.
|
||||||
|
.or_insert_with(|| Browser {
|
||||||
|
focused_browsing_context_id: BrowsingContextId::from(top_level_id),
|
||||||
|
session_history: JointSessionHistory::new(),
|
||||||
|
})
|
||||||
|
.session_history
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a browsing context to a sendable form to pass to the compositor
|
// Convert a browsing context to a sendable form to pass to the compositor
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue