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 io::{read_whole_file, println};
import result::{ok, err}; import result::{ok, err};
import dom::base::NodeScope; import dom::base::{Node, NodeScope};
import dom::event::{Event, ResizeEvent}; import dom::event::{Event, ResizeEvent};
import dom::rcu::WriterMethods; import dom::rcu::WriterMethods;
import dom::style; import dom::style;
import dom::style::Stylesheet;
import gfx::renderer::Sink; import gfx::renderer::Sink;
import parser::html_lexer::spawn_html_lexer_task; import parser::html_lexer::spawn_html_lexer_task;
import parser::css_builder::build_stylesheet; 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> { class Content<S:Sink send copy> {
let sink: S; let sink: S;
let layout: Layout; let layout: Layout;
@ -65,6 +76,8 @@ class Content<S:Sink send copy> {
let scope: NodeScope; let scope: NodeScope;
let jsrt: jsrt; let jsrt: jsrt;
let mut document: option<Document>;
new(layout: Layout, sink: S, from_master: port<ControlMsg>) { new(layout: Layout, sink: S, from_master: port<ControlMsg>) {
self.layout = layout; self.layout = layout;
self.sink = sink; self.sink = sink;
@ -74,6 +87,8 @@ class Content<S:Sink send copy> {
self.scope = NodeScope(); self.scope = NodeScope();
self.jsrt = jsrt(); self.jsrt = jsrt();
self.document = none;
self.sink.add_event_listener(self.event_port.chan()); self.sink.add_event_listener(self.event_port.chan());
} }
@ -103,23 +118,15 @@ class Content<S:Sink send copy> {
// with any previous documents. // with any previous documents.
let stream = spawn_html_lexer_task(copy filename); let stream = spawn_html_lexer_task(copy filename);
let (root, style_port) = build_dom(self.scope, stream); let (root, style_port) = build_dom(self.scope, stream);
// Collect the css stylesheet
let css_rules = style_port.recv(); let css_rules = style_port.recv();
// Apply the css rules to the dom tree: // Apply the css rules to the dom tree:
#debug["%?", css_rules]; #debug["%?", css_rules];
// Now, join the layout so that they will see the latest let document = Document(root, css_rules);
// changes we have made. self.relayout(document);
join_layout(self.scope, self.layout); 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; 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 { fn handle_event(event: Event) -> bool {
alt event { alt event {
ResizeEvent(new_width, new_height) { ResizeEvent(new_width, new_height) {
#debug("content got resize event: %d, %d", 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; ret true;
} }
} }

View File

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