servo: Fix reshaping window callback

Source-Repo: https://github.com/servo/servo
Source-Revision: 12a05daa5da455b5888d5b393a924fc1384e7c24
This commit is contained in:
Patrick Walton 2012-07-12 17:28:10 -07:00
parent acac40ea41
commit 55891cada2
2 changed files with 81 additions and 38 deletions

View File

@ -13,10 +13,11 @@ import task::{spawn, spawn_listener};
import io::{read_whole_file, println};
import result::{ok, err};
import dom::base::NodeScope;
import dom::base::{Node, NodeScope};
import dom::event::{Event, ResizeEvent};
import dom::rcu::WriterMethods;
import dom::style;
import dom::style::Stylesheet;
import gfx::renderer::Sink;
import parser::html_lexer::spawn_html_lexer_task;
import parser::css_builder::build_stylesheet;
@ -56,6 +57,16 @@ fn join_layout(scope: NodeScope, layout: Layout) {
}
}
class Document {
let root: Node;
let css_rules: Stylesheet;
new(root: Node, +css_rules: Stylesheet) {
self.root = root;
self.css_rules = css_rules;
}
}
class Content<S:Sink send copy> {
let sink: S;
let layout: Layout;
@ -65,6 +76,8 @@ class Content<S:Sink send copy> {
let scope: NodeScope;
let jsrt: jsrt;
let mut document: option<Document>;
new(layout: Layout, sink: S, from_master: port<ControlMsg>) {
self.layout = layout;
self.sink = sink;
@ -74,6 +87,8 @@ class Content<S:Sink send copy> {
self.scope = NodeScope();
self.jsrt = jsrt();
self.document = none;
self.sink.add_event_listener(self.event_port.chan());
}
@ -103,23 +118,15 @@ class Content<S:Sink send copy> {
// with any previous documents.
let stream = spawn_html_lexer_task(copy filename);
let (root, style_port) = build_dom(self.scope, stream);
// Collect the css stylesheet
let css_rules = style_port.recv();
// Apply the css rules to the dom tree:
#debug["%?", css_rules];
// Now, join the layout so that they will see the latest
// changes we have made.
join_layout(self.scope, self.layout);
let document = Document(root, css_rules);
self.relayout(document);
self.document = some(document);
// Send new document and relevant styles to layout
self.layout.send(BuildMsg(root, css_rules));
// Indicate that reader was forked so any further
// changes will be isolated.
self.scope.reader_forked();
ret true;
}
@ -150,10 +157,34 @@ class Content<S:Sink send copy> {
}
}
fn relayout(document: Document) {
#debug("content: performing relayout");
// Now, join the layout so that they will see the latest
// changes we have made.
join_layout(self.scope, self.layout);
// Send new document and relevant styles to layout
// FIXME: Put CSS rules in an arc or something.
self.layout.send(BuildMsg(document.root, document.css_rules));
// Indicate that reader was forked so any further
// changes will be isolated.
self.scope.reader_forked();
}
fn handle_event(event: Event) -> bool {
alt event {
ResizeEvent(new_width, new_height) {
#debug("content got resize event: %d, %d", new_width, new_height);
alt copy self.document {
none {
// Nothing to do.
}
some(document) {
self.relayout(document);
}
}
ret true;
}
}

View File

@ -34,13 +34,13 @@ fn OSMain() -> OSMain {
}
fn mainloop(po: port<Msg>) {
let mut key_handlers: [chan<()>] = [];
let key_handlers: @dvec<chan<()>> = @dvec();
let event_listeners: @dvec<chan<Event>> = @dvec();
glut::init();
glut::init_display_mode(glut::DOUBLE);
let surfaces = surface_set();
let surfaces = @surface_set();
let window = glut::create_window("Servo");
glut::reshape_window(window, 800, 600);
@ -55,37 +55,26 @@ fn mainloop(po: port<Msg>) {
let scene = @mut layers::scene::Scene(layers::layers::ImageLayerKind(image_layer),
Size2D(800.0f32, 600.0f32));
do glut::reshape_func(window) |width, height| {
#debug("osmain: window resized to %d,%d", width as int, height as int);
for event_listeners.each |event_listener| {
event_listener.send(ResizeEvent(width as int, height as int));
}
}
loop {
do glut::display_func() {
#debug("osmain: drawing to screen");
layers::rendergl::render_scene(context, *scene);
glut::swap_buffers();
glut::post_redisplay();
}
let done = @mut false;
let check_for_messages = fn@() {
// Handle messages
#debug("osmain: peeking");
if po.peek() {
alt check po.recv() {
alt po.recv() {
AddKeyHandler(key_ch) {
key_handlers += [key_ch];
key_handlers.push(key_ch);
}
AddEventListener(event_listener) {
event_listeners.push(event_listener);
}
BeginDrawing(sender) {
lend_surface(surfaces, sender);
lend_surface(*surfaces, sender);
}
Draw(sender, dt) {
return_surface(surfaces, dt);
lend_surface(surfaces, sender);
#debug("osmain: received new frame");
return_surface(*surfaces, dt);
lend_surface(*surfaces, sender);
let mut image_data;
unsafe {
@ -97,15 +86,38 @@ fn mainloop(po: port<Msg>) {
@layers::layers::Image(800, 600, layers::layers::RGB24Format,
layers::util::convert_rgb32_to_rgb24(image_data));
image_layer.set_image(image);
glut::post_redisplay();
}
exit { break; }
exit {
*done = true;
}
}
}
};
do glut::reshape_func(window) |width, height| {
check_for_messages();
#debug("osmain: window resized to %d,%d", width as int, height as int);
for event_listeners.each |event_listener| {
event_listener.send(ResizeEvent(width as int, height as int));
}
}
do glut::display_func() {
check_for_messages();
#debug("osmain: drawing to screen");
layers::rendergl::render_scene(context, *scene);
glut::swap_buffers();
glut::post_redisplay();
}
while !*done {
#debug("osmain: running GLUT check loop");
glut::check_loop();
}
destroy_surface(surfaces.s1.surf);
destroy_surface(surfaces.s2.surf);
}
@ -199,7 +211,7 @@ fn mk_surface() -> surface {
}
}
fn destroy_surface(surface: surface) {
fn destroy_surface(+surface: surface) {
AzReleaseDrawTarget(surface.az_target);
cairo_surface_destroy(surface.cairo_surf);
}