mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +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.
|
// TODO: actually perform DOM event dispatch.
|
||||||
fn handle_event(event: Event) -> bool {
|
fn handle_event(event: Event) -> bool {
|
||||||
match event {
|
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);
|
debug!("content got resize event: %u, %u", new_width, new_height);
|
||||||
self.window_size = Size2D(new_width, new_height);
|
self.window_size = Size2D(new_width, new_height);
|
||||||
match copy self.document {
|
match copy self.document {
|
||||||
|
@ -338,6 +338,7 @@ impl Content {
|
||||||
self.relayout(document, &self.doc_url.get());
|
self.relayout(document, &self.doc_url.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
response_chan.send(());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ReflowEvent => {
|
ReflowEvent => {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
enum Event {
|
enum Event {
|
||||||
ResizeEvent(uint, uint),
|
ResizeEvent(uint, uint, pipes::Chan<()>),
|
||||||
ReflowEvent
|
ReflowEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ use task::TaskBuilder;
|
||||||
use vec::push;
|
use vec::push;
|
||||||
use pipes::Chan;
|
use pipes::Chan;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use resize_rate_limiter::ResizeRateLimiter;
|
||||||
|
|
||||||
pub type OSMain = comm::Chan<Msg>;
|
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>) {
|
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 key_handlers: @DVec<pipes::Chan<()>> = @DVec();
|
||||||
|
|
||||||
let window;
|
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 done = @mut false;
|
||||||
|
|
||||||
|
let resize_rate_limiter = @ResizeRateLimiter(move dom_event_chan);
|
||||||
|
|
||||||
#macro[
|
#macro[
|
||||||
[#moov[x],
|
[#moov[x],
|
||||||
unsafe { let y <- *ptr::addr_of(x); y }]
|
unsafe { let y <- *ptr::addr_of(x); y }]
|
||||||
];
|
];
|
||||||
|
|
||||||
let check_for_messages = fn@() {
|
let check_for_messages = fn@() {
|
||||||
|
|
||||||
|
// Periodically check if content responded to our last resize event
|
||||||
|
resize_rate_limiter.check_resize_response();
|
||||||
|
|
||||||
// Handle messages
|
// Handle messages
|
||||||
#debug("osmain: peeking");
|
#debug("osmain: peeking");
|
||||||
while po.peek() {
|
while po.peek() {
|
||||||
|
@ -136,7 +141,7 @@ fn mainloop(mode: Mode, po: comm::Port<Msg>, dom_event_chan: pipes::SharedChan<E
|
||||||
check_for_messages();
|
check_for_messages();
|
||||||
|
|
||||||
#debug("osmain: window resized to %d,%d", width as int, height as int);
|
#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() {
|
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 platform {
|
||||||
pub mod base;
|
pub mod base;
|
||||||
pub mod osmain;
|
pub mod osmain;
|
||||||
|
priv mod resize_rate_limiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod text {
|
pub mod text {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue