script task only exits when the root pipeline exits

This commit is contained in:
Tim Kuehn 2013-09-21 15:37:30 -04:00
parent c56b015623
commit 99f125bb64
3 changed files with 49 additions and 12 deletions

View file

@ -217,7 +217,7 @@ impl Pipeline {
pub fn exit(&self) { pub fn exit(&self) {
// Script task handles shutting down layout, as well // Script task handles shutting down layout, as well
self.script_chan.send(script_task::ExitMsg); self.script_chan.send(script_task::ExitMsg(self.id));
let (response_port, response_chan) = comm::stream(); let (response_port, response_chan) = comm::stream();
self.render_chan.send(render_task::ExitMsg(response_chan)); self.render_chan.send(render_task::ExitMsg(response_chan));

View file

@ -212,7 +212,7 @@ impl Window {
match timer_port.recv() { match timer_port.recv() {
TimerMessage_Close => break, TimerMessage_Close => break,
TimerMessage_Fire(td) => script_chan.send(FireTimerMsg(id, td)), TimerMessage_Fire(td) => script_chan.send(FireTimerMsg(id, td)),
TimerMessage_TriggerExit => script_chan.send(ExitMsg), TimerMessage_TriggerExit => script_chan.send(ExitMsg(id)),
} }
} }
} }
@ -225,7 +225,6 @@ impl Window {
}; };
unsafe { unsafe {
// TODO(tkuehn): This just grabs the top-level page. Need to handle subframes.
let cache = ptr::to_unsafe_ptr(win.get_wrappercache()); let cache = ptr::to_unsafe_ptr(win.get_wrappercache());
win.wrap_object_shared(cx, ptr::null()); //XXXjdm proper scope win.wrap_object_shared(cx, ptr::null()); //XXXjdm proper scope
let global = (*cache).wrapper; let global = (*cache).wrapper;

View file

@ -71,7 +71,7 @@ pub enum ScriptMsg {
/// Notifies script that window has been resized but to not take immediate action. /// Notifies script that window has been resized but to not take immediate action.
ResizeInactiveMsg(PipelineId, Size2D<uint>), ResizeInactiveMsg(PipelineId, Size2D<uint>),
/// Exits the constellation. /// Exits the constellation.
ExitMsg, ExitMsg(PipelineId),
} }
pub struct NewLayoutInfo { pub struct NewLayoutInfo {
@ -171,6 +171,28 @@ impl PageTree {
stack: ~[self], stack: ~[self],
} }
} }
// must handle root case separately
pub fn remove(&mut self, id: PipelineId) -> Option<PageTree> {
let remove_idx = {
self.inner.mut_iter()
.enumerate()
.find(|&(_idx, ref page_tree)| page_tree.page.id == id)
.map(|&(idx, _)| idx)
};
match remove_idx {
Some(idx) => return Some(self.inner.remove(idx)),
None => {
for page_tree in self.inner.mut_iter() {
match page_tree.remove(id) {
found @ Some(_) => return found,
None => (), // keep going...
}
}
}
}
None
}
} }
impl<'self> Iterator<@mut Page> for PageTreeIterator<'self> { impl<'self> Iterator<@mut Page> for PageTreeIterator<'self> {
@ -494,9 +516,8 @@ impl ScriptTask {
NavigateMsg(direction) => self.handle_navigate_msg(direction), NavigateMsg(direction) => self.handle_navigate_msg(direction),
ReflowCompleteMsg(id, reflow_id) => self.handle_reflow_complete_msg(id, reflow_id), ReflowCompleteMsg(id, reflow_id) => self.handle_reflow_complete_msg(id, reflow_id),
ResizeInactiveMsg(id, new_size) => self.handle_resize_inactive_msg(id, new_size), ResizeInactiveMsg(id, new_size) => self.handle_resize_inactive_msg(id, new_size),
ExitMsg => { ExitMsg(id) => {
self.handle_exit_msg(); if self.handle_exit_msg(id) { return false }
return false
}, },
ResizeMsg(*) => fail!("should have handled ResizeMsg already"), ResizeMsg(*) => fail!("should have handled ResizeMsg already"),
} }
@ -603,12 +624,29 @@ impl ScriptTask {
} }
/// Handles a request to exit the script task and shut down layout. /// Handles a request to exit the script task and shut down layout.
fn handle_exit_msg(&mut self) { /// Returns true if the script task should shut down and false otherwise.
fn handle_exit_msg(&mut self, id: PipelineId) -> bool {
// If root is being exited, shut down all pages
if self.page_tree.page.id == id {
for page in self.page_tree.iter() { for page in self.page_tree.iter() {
page.join_layout(); page.join_layout();
page.layout_chan.send(layout_interface::ExitMsg); page.layout_chan.send(layout_interface::ExitMsg);
} }
self.compositor.close(); return true
}
// otherwise find just the matching page and exit all sub-pages
match self.page_tree.remove(id) {
Some(ref mut page_tree) => {
for page in page_tree.iter() {
page.join_layout();
page.layout_chan.send(layout_interface::ExitMsg);
}
return false
}
None => fail!("ScriptTask: Received exit message from
pipeline whose id is not in page tree"),
}
} }
/// The entry point to document loading. Defines bindings, sets up the window and document /// The entry point to document loading. Defines bindings, sets up the window and document