mirror of
https://github.com/servo/servo.git
synced 2025-08-15 02:15:33 +01:00
script: Move point_in_initial_containing_block
calculation to script (#38520)
Instead of calculating this value in the compositor, calculate it in `ScriptThread` now that it is straightforward to get this value from the layout spatial tree. This allows removing some tricky callback code in the Compositor. Testing: This shouldn't change any observable behavior so is covered by existing tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
9d4004135b
commit
005164df4a
4 changed files with 18 additions and 53 deletions
|
@ -259,20 +259,15 @@ impl ServoRenderer {
|
||||||
self.shutdown_state.get()
|
self.shutdown_state.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn hit_test_at_point<'a>(
|
pub(crate) fn hit_test_at_point(&self, point: DevicePoint) -> Vec<CompositorHitTestResult> {
|
||||||
&self,
|
self.hit_test_at_point_with_flags(point, HitTestFlags::empty())
|
||||||
point: DevicePoint,
|
|
||||||
details_for_pipeline: impl Fn(PipelineId) -> Option<&'a PipelineDetails>,
|
|
||||||
) -> Vec<CompositorHitTestResult> {
|
|
||||||
self.hit_test_at_point_with_flags(point, HitTestFlags::empty(), details_for_pipeline)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: split this into first half (global) and second half (one for whole compositor, one for webview)
|
// TODO: split this into first half (global) and second half (one for whole compositor, one for webview)
|
||||||
pub(crate) fn hit_test_at_point_with_flags<'a>(
|
pub(crate) fn hit_test_at_point_with_flags(
|
||||||
&self,
|
&self,
|
||||||
point: DevicePoint,
|
point: DevicePoint,
|
||||||
flags: HitTestFlags,
|
flags: HitTestFlags,
|
||||||
details_for_pipeline: impl Fn(PipelineId) -> Option<&'a PipelineDetails>,
|
|
||||||
) -> Vec<CompositorHitTestResult> {
|
) -> Vec<CompositorHitTestResult> {
|
||||||
// DevicePoint and WorldPoint are the same for us.
|
// DevicePoint and WorldPoint are the same for us.
|
||||||
let world_point = WorldPoint::from_untyped(point.to_untyped());
|
let world_point = WorldPoint::from_untyped(point.to_untyped());
|
||||||
|
@ -286,26 +281,14 @@ impl ServoRenderer {
|
||||||
results
|
results
|
||||||
.items
|
.items
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|item| {
|
.map(|item| {
|
||||||
let pipeline_id = item.pipeline.into();
|
let pipeline_id = item.pipeline.into();
|
||||||
let details = details_for_pipeline(pipeline_id)?;
|
|
||||||
|
|
||||||
let offset = details
|
|
||||||
.scroll_tree
|
|
||||||
.scroll_offset(pipeline_id.root_scroll_id())
|
|
||||||
.unwrap_or_default();
|
|
||||||
let point_in_initial_containing_block =
|
|
||||||
(item.point_in_viewport + offset).to_untyped();
|
|
||||||
|
|
||||||
let external_scroll_id = ExternalScrollId(item.tag.0, item.pipeline);
|
let external_scroll_id = ExternalScrollId(item.tag.0, item.pipeline);
|
||||||
Some(CompositorHitTestResult {
|
CompositorHitTestResult {
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
point_in_viewport: Point2D::from_untyped(item.point_in_viewport.to_untyped()),
|
point_in_viewport: Point2D::from_untyped(item.point_in_viewport.to_untyped()),
|
||||||
point_relative_to_initial_containing_block: Point2D::from_untyped(
|
|
||||||
point_in_initial_containing_block,
|
|
||||||
),
|
|
||||||
external_scroll_id,
|
external_scroll_id,
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -1112,19 +1095,6 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn details_for_pipeline(&self, pipeline_id: PipelineId) -> Option<&PipelineDetails> {
|
|
||||||
let webview_id = self
|
|
||||||
.global
|
|
||||||
.borrow()
|
|
||||||
.pipeline_to_webview_map
|
|
||||||
.get(&pipeline_id)
|
|
||||||
.cloned()?;
|
|
||||||
self.webview_renderers
|
|
||||||
.get(webview_id)?
|
|
||||||
.pipelines
|
|
||||||
.get(&pipeline_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if any animation callbacks (ie `requestAnimationFrame`) are waiting for a response.
|
/// Returns true if any animation callbacks (ie `requestAnimationFrame`) are waiting for a response.
|
||||||
fn animation_callbacks_running(&self) -> bool {
|
fn animation_callbacks_running(&self) -> bool {
|
||||||
self.webview_renderers
|
self.webview_renderers
|
||||||
|
@ -1604,9 +1574,8 @@ impl IOCompositor {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let details_for_pipeline = |pipeline_id| self.details_for_pipeline(pipeline_id);
|
|
||||||
let Some(hit_test_result) = global
|
let Some(hit_test_result) = global
|
||||||
.hit_test_at_point(last_mouse_move_position, details_for_pipeline)
|
.hit_test_at_point(last_mouse_move_position)
|
||||||
.first()
|
.first()
|
||||||
.cloned()
|
.cloned()
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -337,11 +337,10 @@ impl WebViewRenderer {
|
||||||
};
|
};
|
||||||
|
|
||||||
// If we can't find a pipeline to send this event to, we cannot continue.
|
// If we can't find a pipeline to send this event to, we cannot continue.
|
||||||
let get_pipeline_details = |pipeline_id| self.pipelines.get(&pipeline_id);
|
|
||||||
let Some(result) = self
|
let Some(result) = self
|
||||||
.global
|
.global
|
||||||
.borrow()
|
.borrow()
|
||||||
.hit_test_at_point(point, get_pipeline_details)
|
.hit_test_at_point(point)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.nth(0)
|
.nth(0)
|
||||||
else {
|
else {
|
||||||
|
@ -852,12 +851,10 @@ impl WebViewRenderer {
|
||||||
ScrollLocation::Start | ScrollLocation::End => scroll_location,
|
ScrollLocation::Start | ScrollLocation::End => scroll_location,
|
||||||
};
|
};
|
||||||
|
|
||||||
let get_pipeline_details = |pipeline_id| self.pipelines.get(&pipeline_id);
|
let hit_test_results = self
|
||||||
let hit_test_results = self.global.borrow().hit_test_at_point_with_flags(
|
.global
|
||||||
cursor,
|
.borrow()
|
||||||
HitTestFlags::FIND_ALL,
|
.hit_test_at_point_with_flags(cursor, HitTestFlags::FIND_ALL);
|
||||||
get_pipeline_details,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Iterate through all hit test results, processing only the first node of each pipeline.
|
// Iterate through all hit test results, processing only the first node of each pipeline.
|
||||||
// This is needed to propagate the scroll events from a pipeline representing an iframe to
|
// This is needed to propagate the scroll events from a pipeline representing an iframe to
|
||||||
|
|
|
@ -2611,6 +2611,10 @@ impl Window {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.nth(0)?;
|
.nth(0)?;
|
||||||
|
|
||||||
|
let point_in_frame = compositor_hit_test_result.point_in_viewport;
|
||||||
|
let point_relative_to_initial_containing_block =
|
||||||
|
point_in_frame + self.scroll_offset().cast_unit();
|
||||||
|
|
||||||
// SAFETY: This is safe because `Window::query_elements_from_point` has ensured that
|
// SAFETY: This is safe because `Window::query_elements_from_point` has ensured that
|
||||||
// layout has run and any OpaqueNodes that no longer refer to real nodes are gone.
|
// layout has run and any OpaqueNodes that no longer refer to real nodes are gone.
|
||||||
let address = UntrustedNodeAddress(result.node.0 as *const c_void);
|
let address = UntrustedNodeAddress(result.node.0 as *const c_void);
|
||||||
|
@ -2618,9 +2622,8 @@ impl Window {
|
||||||
node: unsafe { from_untrusted_node_address(address) },
|
node: unsafe { from_untrusted_node_address(address) },
|
||||||
cursor: result.cursor,
|
cursor: result.cursor,
|
||||||
point_in_node: result.point_in_target,
|
point_in_node: result.point_in_target,
|
||||||
point_in_frame: compositor_hit_test_result.point_in_viewport,
|
point_in_frame,
|
||||||
point_relative_to_initial_containing_block: compositor_hit_test_result
|
point_relative_to_initial_containing_block,
|
||||||
.point_relative_to_initial_containing_block,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -884,10 +884,6 @@ pub struct CompositorHitTestResult {
|
||||||
/// The hit test point in the item's viewport.
|
/// The hit test point in the item's viewport.
|
||||||
pub point_in_viewport: Point2D<f32, CSSPixel>,
|
pub point_in_viewport: Point2D<f32, CSSPixel>,
|
||||||
|
|
||||||
/// The hit test point relative to the root scroll node content origin / initial
|
|
||||||
/// containing block.
|
|
||||||
pub point_relative_to_initial_containing_block: Point2D<f32, CSSPixel>,
|
|
||||||
|
|
||||||
/// The [`ExternalScrollId`] of the scroll tree node associated with this hit test item.
|
/// The [`ExternalScrollId`] of the scroll tree node associated with this hit test item.
|
||||||
pub external_scroll_id: ExternalScrollId,
|
pub external_scroll_id: ExternalScrollId,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue