From f29eee535699e7912ce8d15528af818ce1d1f4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20W=C3=BClker?= Date: Tue, 17 Jun 2025 13:14:41 +0200 Subject: [PATCH] Make layout build a display list when the highlighted DOM node changed (#37501) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Highlights from the devtools trigger reflows. Previously, incremental layout would notice that nothing about the box tree changed and skip generating a new display list. This caused the highlights to never be painted. Forcing a new DL in this case makes reflows that happen *while* there is a highlighted DOM node (which did not change since the last reflow) slightly less efficient. We could check if the highlighted node changed and only force a new display list if it did, but I'm not sure if `OpaqueNode`s can be compared like that. It also seems like a very niche issue. Testing: This is hard to test for, so there are no tests. Fixes https://github.com/servo/servo/issues/37500. Signed-off-by: Simon Wülker --- components/layout/layout_impl.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/components/layout/layout_impl.rs b/components/layout/layout_impl.rs index 77f5a70582e..7507e705d30 100644 --- a/components/layout/layout_impl.rs +++ b/components/layout/layout_impl.rs @@ -181,6 +181,11 @@ pub struct LayoutThread { /// Debug options, copied from configuration to this `LayoutThread` in order /// to avoid having to constantly access the thread-safe global options. debug: DebugOptions, + + /// Tracks the node that was highlighted by the devtools during the last reflow. + /// + /// If this changed, then we need to create a new display list. + previously_highlighted_dom_node: Cell>, } pub struct LayoutFactoryImpl(); @@ -555,6 +560,7 @@ impl LayoutThread { stylist: Stylist::new(device, QuirksMode::NoQuirks), resolved_images_cache: Default::default(), debug: opts::get().debug.clone(), + previously_highlighted_dom_node: Cell::new(None), } } @@ -648,6 +654,12 @@ impl LayoutThread { &snapshot_map, ); + if self.previously_highlighted_dom_node.get() != reflow_request.highlighted_dom_node { + // Need to manually force layout to build a new display list regardless of whether the box tree + // changed or not. + self.need_new_display_list.set(true); + } + let mut layout_context = LayoutContext { id: self.id, origin: reflow_request.origin.clone(), @@ -992,6 +1004,8 @@ impl LayoutThread { self.have_ever_generated_display_list.set(true); self.need_new_display_list.set(false); + self.previously_highlighted_dom_node + .set(reflow_request.highlighted_dom_node); true }