From 12a05daa5da455b5888d5b393a924fc1384e7c24 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 12 Jul 2012 17:28:10 -0700 Subject: [PATCH] Fix reshaping window callback --- src/servo/content.rs | 55 ++++++++++++++++++++++++------- src/servo/platform/osmain.rs | 64 +++++++++++++++++++++--------------- 2 files changed, 81 insertions(+), 38 deletions(-) diff --git a/src/servo/content.rs b/src/servo/content.rs index 63b06597124..791fde5ea23 100644 --- a/src/servo/content.rs +++ b/src/servo/content.rs @@ -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 { let sink: S; let layout: Layout; @@ -65,6 +76,8 @@ class Content { let scope: NodeScope; let jsrt: jsrt; + let mut document: option; + new(layout: Layout, sink: S, from_master: port) { self.layout = layout; self.sink = sink; @@ -74,6 +87,8 @@ class Content { self.scope = NodeScope(); self.jsrt = jsrt(); + self.document = none; + self.sink.add_event_listener(self.event_port.chan()); } @@ -103,23 +118,15 @@ class Content { // 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 { } } + 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; } } diff --git a/src/servo/platform/osmain.rs b/src/servo/platform/osmain.rs index 70b15d3f622..c6607f6506a 100644 --- a/src/servo/platform/osmain.rs +++ b/src/servo/platform/osmain.rs @@ -34,13 +34,13 @@ fn OSMain() -> OSMain { } fn mainloop(po: port) { - let mut key_handlers: [chan<()>] = []; + let key_handlers: @dvec> = @dvec(); let event_listeners: @dvec> = @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) { 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) { @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); }