diff --git a/src/servo/content/content_task.rs b/src/servo/content/content_task.rs index 83b1bce8d6f..a2746b93391 100644 --- a/src/servo/content/content_task.rs +++ b/src/servo/content/content_task.rs @@ -326,7 +326,7 @@ impl Content { // TODO: actually perform DOM event dispatch. fn handle_event(event: Event) -> bool { match event { - ResizeEvent(new_width, new_height) => { + ResizeEvent(new_width, new_height, response_chan) => { debug!("content got resize event: %u, %u", new_width, new_height); self.window_size = Size2D(new_width, new_height); match copy self.document { @@ -338,6 +338,7 @@ impl Content { self.relayout(document, &self.doc_url.get()); } } + response_chan.send(()); return true; } ReflowEvent => { diff --git a/src/servo/dom/event.rs b/src/servo/dom/event.rs index 0ca5e3abc9a..d5e45ca01d9 100644 --- a/src/servo/dom/event.rs +++ b/src/servo/dom/event.rs @@ -1,5 +1,5 @@ enum Event { - ResizeEvent(uint, uint), + ResizeEvent(uint, uint, pipes::Chan<()>), ReflowEvent } diff --git a/src/servo/platform/osmain.rs b/src/servo/platform/osmain.rs index 7d607f917f4..7c0ee701bae 100644 --- a/src/servo/platform/osmain.rs +++ b/src/servo/platform/osmain.rs @@ -15,6 +15,7 @@ use task::TaskBuilder; use vec::push; use pipes::Chan; use std::cell::Cell; +use resize_rate_limiter::ResizeRateLimiter; pub type OSMain = comm::Chan; @@ -56,8 +57,6 @@ fn OSMain(dom_event_chan: pipes::SharedChan) -> OSMain { fn mainloop(mode: Mode, po: comm::Port, dom_event_chan: pipes::SharedChan) { - let dom_event_chan = @move dom_event_chan; - let key_handlers: @DVec> = @DVec(); let window; @@ -90,12 +89,18 @@ fn mainloop(mode: Mode, po: comm::Port, dom_event_chan: pipes::SharedChan, dom_event_chan: pipes::SharedChan, + /// The port we are waiting on for a response to the last resize event + /* priv */ mut last_response_port: Option>, + /// The next window resize event we should fire + /* priv */ mut next_resize_event: Option<(uint, uint)> +} + +pub fn ResizeRateLimiter(dom_event_chan: pipes::SharedChan) -> ResizeRateLimiter { + ResizeRateLimiter { + dom_event_chan: move dom_event_chan, + last_response_port: None, + next_resize_event: None + } +} + +impl ResizeRateLimiter { + fn window_resized(width: uint, height: uint) { + match self.last_response_port { + None => { + assert self.next_resize_event.is_none(); + self.send_event(width, height); + } + Some(*) => { + if self.last_response_port.get_ref().peek() { + self.send_event(width, height); + self.next_resize_event = None; + } else { + if self.next_resize_event.is_some() { + warn!("osmain: content can't keep up. skipping resize event"); + } + self.next_resize_event = Some((width, height)); + } + } + } + } + + fn check_resize_response() { + match self.next_resize_event { + Some((copy width, copy height)) => { + assert self.last_response_port.is_some(); + if self.last_response_port.get_ref().peek() { + self.send_event(width, height); + self.next_resize_event = None; + } + } + None => () + } + } + + priv fn send_event(width: uint, height: uint) { + let (chan, port) = pipes::stream(); + self.dom_event_chan.send(ResizeEvent(width, height, move chan)); + self.last_response_port = Some(move port); + } +} diff --git a/src/servo/servo.rc b/src/servo/servo.rc index 48534322e69..e98814ee18a 100755 --- a/src/servo/servo.rc +++ b/src/servo/servo.rc @@ -95,6 +95,7 @@ pub mod html { pub mod platform { pub mod base; pub mod osmain; + priv mod resize_rate_limiter; } pub mod text {