mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Combine resize events for each pipeline and process when layout is idle
This commit is contained in:
parent
5aa207a7f7
commit
5b684659ff
2 changed files with 71 additions and 24 deletions
|
@ -3,7 +3,6 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use compositing::{CompositorChan, SetIds, SetLayerClipRect};
|
use compositing::{CompositorChan, SetIds, SetLayerClipRect};
|
||||||
use script::dom::event::ResizeEvent;
|
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::comm;
|
use std::comm;
|
||||||
|
@ -18,7 +17,7 @@ use servo_msg::constellation_msg::{InitLoadUrlMsg, LoadIframeUrlMsg, LoadUrlMsg}
|
||||||
use servo_msg::constellation_msg::{Msg, NavigateMsg, NavigationType, IFrameUnsandboxed};
|
use servo_msg::constellation_msg::{Msg, NavigateMsg, NavigationType, IFrameUnsandboxed};
|
||||||
use servo_msg::constellation_msg::{PipelineId, RendererReadyMsg, ResizedWindowMsg, SubpageId};
|
use servo_msg::constellation_msg::{PipelineId, RendererReadyMsg, ResizedWindowMsg, SubpageId};
|
||||||
use servo_msg::constellation_msg;
|
use servo_msg::constellation_msg;
|
||||||
use script::script_task::{SendEventMsg, ResizeInactiveMsg, ExecuteMsg};
|
use script::script_task::{ResizeMsg, ResizeInactiveMsg, ExecuteMsg};
|
||||||
use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
|
use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
|
||||||
use servo_net::resource_task::ResourceTask;
|
use servo_net::resource_task::ResourceTask;
|
||||||
use servo_net::resource_task;
|
use servo_net::resource_task;
|
||||||
|
@ -409,9 +408,10 @@ impl Constellation {
|
||||||
subpage id. This should not be possible.") == subpage_id {
|
subpage id. This should not be possible.") == subpage_id {
|
||||||
child_frame_tree.rect = Some(rect.clone());
|
child_frame_tree.rect = Some(rect.clone());
|
||||||
let Rect { size: Size2D { width, height }, _ } = rect;
|
let Rect { size: Size2D { width, height }, _ } = rect;
|
||||||
pipeline.script_chan.send(SendEventMsg(pipeline.id.clone(),
|
pipeline.script_chan.send(ResizeMsg(pipeline.id.clone(), Size2D {
|
||||||
ResizeEvent(width as uint,
|
width: width as uint,
|
||||||
height as uint)));
|
height: height as uint
|
||||||
|
}));
|
||||||
self.compositor_chan.send(SetLayerClipRect(pipeline.id, rect));
|
self.compositor_chan.send(SetLayerClipRect(pipeline.id, rect));
|
||||||
already_sent.insert(pipeline.id.clone());
|
already_sent.insert(pipeline.id.clone());
|
||||||
break;
|
break;
|
||||||
|
@ -720,9 +720,7 @@ impl Constellation {
|
||||||
fn handle_resized_window_msg(&mut self, new_size: Size2D<uint>) {
|
fn handle_resized_window_msg(&mut self, new_size: Size2D<uint>) {
|
||||||
let mut already_seen = HashSet::new();
|
let mut already_seen = HashSet::new();
|
||||||
for &@FrameTree { pipeline: pipeline, _ } in self.current_frame().iter() {
|
for &@FrameTree { pipeline: pipeline, _ } in self.current_frame().iter() {
|
||||||
let Size2D { width, height } = new_size;
|
pipeline.script_chan.send(ResizeMsg(pipeline.id.clone(), new_size));
|
||||||
pipeline.script_chan.send(SendEventMsg(pipeline.id.clone(),
|
|
||||||
ResizeEvent(width, height)));
|
|
||||||
already_seen.insert(pipeline.id.clone());
|
already_seen.insert(pipeline.id.clone());
|
||||||
}
|
}
|
||||||
for frame_tree in self.navigation_context.previous.iter()
|
for frame_tree in self.navigation_context.previous.iter()
|
||||||
|
|
|
@ -63,6 +63,8 @@ pub enum ScriptMsg {
|
||||||
NavigateMsg(NavigationDirection),
|
NavigateMsg(NavigationDirection),
|
||||||
/// Sends a DOM event.
|
/// Sends a DOM event.
|
||||||
SendEventMsg(PipelineId, Event_),
|
SendEventMsg(PipelineId, Event_),
|
||||||
|
/// Window resized. Sends a DOM event eventually, but first we combine events.
|
||||||
|
ResizeMsg(PipelineId, Size2D<uint>),
|
||||||
/// Fires a JavaScript timeout.
|
/// Fires a JavaScript timeout.
|
||||||
FireTimerMsg(PipelineId, ~TimerData),
|
FireTimerMsg(PipelineId, ~TimerData),
|
||||||
/// Notifies script that reflow is finished.
|
/// Notifies script that reflow is finished.
|
||||||
|
@ -128,6 +130,9 @@ pub struct Page {
|
||||||
url: Option<(Url, bool)>,
|
url: Option<(Url, bool)>,
|
||||||
|
|
||||||
next_subpage_id: SubpageId,
|
next_subpage_id: SubpageId,
|
||||||
|
|
||||||
|
/// Pending resize event, if any.
|
||||||
|
resize_event: Option<Size2D<uint>>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PageTree {
|
pub struct PageTree {
|
||||||
|
@ -152,6 +157,7 @@ impl PageTree {
|
||||||
js_info: None,
|
js_info: None,
|
||||||
url: None,
|
url: None,
|
||||||
next_subpage_id: SubpageId(0),
|
next_subpage_id: SubpageId(0),
|
||||||
|
resize_event: None,
|
||||||
},
|
},
|
||||||
inner: ~[],
|
inner: ~[],
|
||||||
}
|
}
|
||||||
|
@ -406,7 +412,7 @@ impl ScriptTask {
|
||||||
/// Starts the script task. After calling this method, the script task will loop receiving
|
/// Starts the script task. After calling this method, the script task will loop receiving
|
||||||
/// messages on its port.
|
/// messages on its port.
|
||||||
pub fn start(&mut self) {
|
pub fn start(&mut self) {
|
||||||
while self.handle_msg() {
|
while self.handle_msgs() {
|
||||||
// Go on...
|
// Go on...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -440,9 +446,49 @@ impl ScriptTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles an incoming control message.
|
/// Handle incoming control messages.
|
||||||
fn handle_msg(&mut self) -> bool {
|
fn handle_msgs(&mut self) -> bool {
|
||||||
match self.port.recv() {
|
// Handle pending resize events.
|
||||||
|
// Gather them first to avoid a double mut borrow on self.
|
||||||
|
let mut resizes = ~[];
|
||||||
|
for page in self.page_tree.iter() {
|
||||||
|
// Only process a resize if layout is idle.
|
||||||
|
if page.layout_join_port.is_none() {
|
||||||
|
match page.resize_event.take() {
|
||||||
|
Some(size) => resizes.push((page.id, size)),
|
||||||
|
None => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (id, Size2D { width, height }) in resizes.move_iter() {
|
||||||
|
self.handle_event(id, ResizeEvent(width, height));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store new resizes, and gather all other events.
|
||||||
|
let mut sequential = ~[];
|
||||||
|
loop {
|
||||||
|
// Receive at least one message so we don't spinloop.
|
||||||
|
let event = self.port.recv();
|
||||||
|
match event {
|
||||||
|
ResizeMsg(id, size) => {
|
||||||
|
let page = self.page_tree.find(id).expect("resize sent to nonexistent pipeline").page;
|
||||||
|
page.resize_event = Some(size);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
sequential.push(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break if there are no more messages.
|
||||||
|
if !self.port.peek() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the gathered events.
|
||||||
|
for msg in sequential.move_iter() {
|
||||||
|
match msg {
|
||||||
// TODO(tkuehn) need to handle auxiliary layouts for iframes
|
// TODO(tkuehn) need to handle auxiliary layouts for iframes
|
||||||
AttachLayoutMsg(new_layout_info) => self.handle_new_layout(new_layout_info),
|
AttachLayoutMsg(new_layout_info) => self.handle_new_layout(new_layout_info),
|
||||||
LoadMsg(id, url) => self.load(id, url),
|
LoadMsg(id, url) => self.load(id, url),
|
||||||
|
@ -455,8 +501,11 @@ impl ScriptTask {
|
||||||
ExitMsg => {
|
ExitMsg => {
|
||||||
self.handle_exit_msg();
|
self.handle_exit_msg();
|
||||||
return false
|
return false
|
||||||
|
},
|
||||||
|
ResizeMsg(*) => fail!("should have handled ResizeMsg already"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue