mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Rate limit resize events
This commit is contained in:
parent
a06d45f2a5
commit
c41ff73847
5 changed files with 78 additions and 5 deletions
|
@ -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 => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
enum Event {
|
||||
ResizeEvent(uint, uint),
|
||||
ResizeEvent(uint, uint, pipes::Chan<()>),
|
||||
ReflowEvent
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Msg>;
|
||||
|
||||
|
@ -56,8 +57,6 @@ fn OSMain(dom_event_chan: pipes::SharedChan<Event>) -> OSMain {
|
|||
|
||||
fn mainloop(mode: Mode, po: comm::Port<Msg>, dom_event_chan: pipes::SharedChan<Event>) {
|
||||
|
||||
let dom_event_chan = @move dom_event_chan;
|
||||
|
||||
let key_handlers: @DVec<pipes::Chan<()>> = @DVec();
|
||||
|
||||
let window;
|
||||
|
@ -90,12 +89,18 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>, dom_event_chan: pipes::SharedChan<E
|
|||
|
||||
let done = @mut false;
|
||||
|
||||
let resize_rate_limiter = @ResizeRateLimiter(move dom_event_chan);
|
||||
|
||||
#macro[
|
||||
[#moov[x],
|
||||
unsafe { let y <- *ptr::addr_of(x); y }]
|
||||
];
|
||||
|
||||
let check_for_messages = fn@() {
|
||||
|
||||
// Periodically check if content responded to our last resize event
|
||||
resize_rate_limiter.check_resize_response();
|
||||
|
||||
// Handle messages
|
||||
#debug("osmain: peeking");
|
||||
while po.peek() {
|
||||
|
@ -136,7 +141,7 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>, dom_event_chan: pipes::SharedChan<E
|
|||
check_for_messages();
|
||||
|
||||
#debug("osmain: window resized to %d,%d", width as int, height as int);
|
||||
dom_event_chan.send(ResizeEvent(width as uint, height as uint));
|
||||
resize_rate_limiter.window_resized(width as uint, height as uint);
|
||||
}
|
||||
|
||||
do glut::display_func() {
|
||||
|
|
66
src/servo/platform/resize_rate_limiter.rs
Normal file
66
src/servo/platform/resize_rate_limiter.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*!
|
||||
A little class that rate limits the number of resize events sent to the content task
|
||||
based on how fast content dispatches those events. It waits until each event is handled
|
||||
before sending the next. If the window is resized multiple times before an event is handled
|
||||
then some events will never be sent.
|
||||
*/
|
||||
|
||||
use dom::event::{Event, ResizeEvent};
|
||||
|
||||
pub struct ResizeRateLimiter {
|
||||
/// The channel we send resize events on
|
||||
/* priv */ dom_event_chan: pipes::SharedChan<Event>,
|
||||
/// The port we are waiting on for a response to the last resize event
|
||||
/* priv */ mut last_response_port: Option<pipes::Port<()>>,
|
||||
/// The next window resize event we should fire
|
||||
/* priv */ mut next_resize_event: Option<(uint, uint)>
|
||||
}
|
||||
|
||||
pub fn ResizeRateLimiter(dom_event_chan: pipes::SharedChan<Event>) -> 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);
|
||||
}
|
||||
}
|
|
@ -95,6 +95,7 @@ pub mod html {
|
|||
pub mod platform {
|
||||
pub mod base;
|
||||
pub mod osmain;
|
||||
priv mod resize_rate_limiter;
|
||||
}
|
||||
|
||||
pub mod text {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue