diff options
author | Clark Gaebel <cgaebel@mozilla.com> | 2014-10-28 09:35:24 -0700 |
---|---|---|
committer | Clark Gaebel <cgaebel@mozilla.com> | 2014-10-28 09:35:24 -0700 |
commit | 432071b70305212e5c7bfd4f261e52a44ca83406 (patch) | |
tree | b8e77c9e394f4ed15aaf099f481d03f1608c75cb /components/layout/layout_task.rs | |
parent | 9e94ecf99cff7c57275ab39c7b11870e55756d63 (diff) | |
download | servo-432071b70305212e5c7bfd4f261e52a44ca83406.tar.gz servo-432071b70305212e5c7bfd4f261e52a44ca83406.zip |
Layout: Fix resize (which just plain doesn't work right now).
Currently, both restyle/flow construction _and_ reflow are skipped
during resize. Reflow should not be in that list. This patch fixes
that.
Diffstat (limited to 'components/layout/layout_task.rs')
-rw-r--r-- | components/layout/layout_task.rs | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index db47f9e5801..5524d8ec00a 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -11,6 +11,7 @@ use context::SharedLayoutContext; use flow::{Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use flow; use flow_ref::FlowRef; +use incremental::{Reflow, Repaint}; use layout_debug; use parallel::UnsafeFlow; use parallel; @@ -478,9 +479,13 @@ impl LayoutTask { } /// Retrieves the flow tree root from the root node. - fn get_layout_root(&self, node: LayoutNode) -> FlowRef { + fn try_get_layout_root(&self, node: LayoutNode) -> Option<FlowRef> { let mut layout_data_ref = node.mutate_layout_data(); - let layout_data = layout_data_ref.as_mut().expect("no layout data for root node"); + let layout_data = + match layout_data_ref.as_mut() { + None => return None, + Some(layout_data) => layout_data, + }; let result = layout_data.data.flow_construction_result.swap_out(); @@ -494,11 +499,16 @@ impl LayoutTask { flow.set_absolute_descendants(abs_descendants); flow } - _ => fail!("Flow construction didn't result in a flow at the root of the tree!"), + _ => return None, }; flow.mark_as_root(); - flow + + Some(flow) + } + + fn get_layout_root(&self, node: LayoutNode) -> FlowRef { + self.try_get_layout_root(node).expect("no layout root") } /// Performs layout constraint solving. @@ -580,6 +590,7 @@ impl LayoutTask { // http://www.w3.org/TR/css-device-adapt/#actual-viewport let viewport_size = data.window_size.initial_viewport; + let old_screen_size = rw_data.screen_size; let current_screen_size = Size2D(Au::from_frac32_px(viewport_size.width.get()), Au::from_frac32_px(viewport_size.height.get())); rw_data.screen_size = current_screen_size; @@ -595,12 +606,23 @@ impl LayoutTask { let mut needs_dirtying = false; needs_dirtying |= rw_data.stylesheet_dirty; + let mut needs_reflow = false; + needs_reflow |= current_screen_size != old_screen_size; + + // If the entire flow tree is invalid, then it will be reflowed anyhow. + needs_reflow &= !needs_dirtying; + unsafe { if needs_dirtying { LayoutTask::dirty_all_nodes(node); } } + if needs_reflow { + self.try_get_layout_root(*node).map( + |mut flow| LayoutTask::reflow_all_nodes(flow.deref_mut())); + } + rw_data.stylesheet_dirty = false; let mut layout_root = profile(time::LayoutStyleRecalcCategory, @@ -771,15 +793,21 @@ impl LayoutTask { } unsafe fn dirty_all_nodes(node: &mut LayoutNode) { - // TODO(cgaebel): mark nodes which are sensitive to media queries as - // "changed": - // > node.set_changed(true); - node.set_dirty(true); - node.set_dirty_siblings(true); - node.set_dirty_descendants(true); - - for mut kid in node.children() { - LayoutTask::dirty_all_nodes(&mut kid); + for node in node.traverse_preorder() { + // TODO(cgaebel): mark nodes which are sensitive to media queries as + // "changed": + // > node.set_changed(true); + node.set_dirty(true); + node.set_dirty_siblings(true); + node.set_dirty_descendants(true); + } + } + + fn reflow_all_nodes(flow: &mut Flow) { + flow::mut_base(flow).restyle_damage.insert(Reflow | Repaint); + + for child in flow::child_iter(flow) { + LayoutTask::reflow_all_nodes(child); } } |