diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-04-06 19:34:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-06 17:34:18 +0000 |
commit | 0caa271176d4670eb06bedd05cdffb24df08fc4f (patch) | |
tree | 9a0c3431dcf7ac31cfbdc1f801c9f4ef3dda6ae7 /components/shared/compositing/tests | |
parent | e74a042efdf01ab2ff32e82e203bd1d954b599bd (diff) | |
download | servo-0caa271176d4670eb06bedd05cdffb24df08fc4f.tar.gz servo-0caa271176d4670eb06bedd05cdffb24df08fc4f.zip |
`compositing`: Combine `webrender_traits` and `compositing_traits` (#36372)
These two traits both exposed different parts of the compositing API,
but now that the compositor doesn't depend directly on `script` any
longer and the `script_traits` crate has been split into the
`constellation_traits` crate, this can be finally be cleaned up without
causing circular dependencies. In addition, some unit tests for the
`IOPCompositor`'s scroll node tree are also moved into
`compositing_traits` as well.
Testing: This just combines two crates, so no new tests are necessary.
Fixes: #35984.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/shared/compositing/tests')
-rw-r--r-- | components/shared/compositing/tests/compositor.rs | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/components/shared/compositing/tests/compositor.rs b/components/shared/compositing/tests/compositor.rs new file mode 100644 index 00000000000..4d2ecfd99c9 --- /dev/null +++ b/components/shared/compositing/tests/compositor.rs @@ -0,0 +1,188 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use base::id::ScrollTreeNodeId; +use compositing_traits::display_list::{ + AxesScrollSensitivity, ScrollSensitivity, ScrollTree, ScrollableNodeInfo, +}; +use euclid::Size2D; +use webrender_api::units::LayoutVector2D; +use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, SpatialId}; + +fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId { + let pipeline_id = PipelineId(0, 0); + let num_nodes = tree.nodes.len(); + let parent = if num_nodes > 0 { + Some(ScrollTreeNodeId { + index: num_nodes - 1, + spatial_id: SpatialId::new(num_nodes - 1, pipeline_id), + }) + } else { + None + }; + + tree.add_scroll_tree_node( + parent.as_ref(), + SpatialId::new(num_nodes, pipeline_id), + Some(ScrollableNodeInfo { + external_id: ExternalScrollId(num_nodes as u64, pipeline_id), + scrollable_size: Size2D::new(100.0, 100.0), + scroll_sensitivity: AxesScrollSensitivity { + x: ScrollSensitivity::ScriptAndInputEvents, + y: ScrollSensitivity::ScriptAndInputEvents, + }, + offset: LayoutVector2D::zero(), + }), + ) +} + +#[test] +fn test_scroll_tree_simple_scroll() { + let mut scroll_tree = ScrollTree::default(); + let pipeline_id = PipelineId(0, 0); + let id = add_mock_scroll_node(&mut scroll_tree); + + let (scrolled_id, offset) = scroll_tree + .scroll_node_or_ancestor( + &id, + ScrollLocation::Delta(LayoutVector2D::new(-20.0, -40.0)), + ) + .unwrap(); + let expected_offset = LayoutVector2D::new(-20.0, -40.0); + assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id)); + assert_eq!(offset, expected_offset); + assert_eq!(scroll_tree.get_node(&id).offset(), Some(expected_offset)); + + let (scrolled_id, offset) = scroll_tree + .scroll_node_or_ancestor(&id, ScrollLocation::Delta(LayoutVector2D::new(20.0, 40.0))) + .unwrap(); + let expected_offset = LayoutVector2D::new(0.0, 0.0); + assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id)); + assert_eq!(offset, expected_offset); + assert_eq!(scroll_tree.get_node(&id).offset(), Some(expected_offset)); + + // Scroll offsets must be negative. + let result = scroll_tree + .scroll_node_or_ancestor(&id, ScrollLocation::Delta(LayoutVector2D::new(20.0, 40.0))); + assert!(result.is_none()); + assert_eq!( + scroll_tree.get_node(&id).offset(), + Some(LayoutVector2D::new(0.0, 0.0)) + ); +} + +#[test] +fn test_scroll_tree_simple_scroll_chaining() { + let mut scroll_tree = ScrollTree::default(); + + let pipeline_id = PipelineId(0, 0); + let parent_id = add_mock_scroll_node(&mut scroll_tree); + let unscrollable_child_id = + scroll_tree.add_scroll_tree_node(Some(&parent_id), SpatialId::new(1, pipeline_id), None); + + let (scrolled_id, offset) = scroll_tree + .scroll_node_or_ancestor( + &unscrollable_child_id, + ScrollLocation::Delta(LayoutVector2D::new(-20.0, -40.0)), + ) + .unwrap(); + let expected_offset = LayoutVector2D::new(-20.0, -40.0); + assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id)); + assert_eq!(offset, expected_offset); + assert_eq!( + scroll_tree.get_node(&parent_id).offset(), + Some(expected_offset) + ); + + let (scrolled_id, offset) = scroll_tree + .scroll_node_or_ancestor( + &unscrollable_child_id, + ScrollLocation::Delta(LayoutVector2D::new(-10.0, -15.0)), + ) + .unwrap(); + let expected_offset = LayoutVector2D::new(-30.0, -55.0); + assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id)); + assert_eq!(offset, expected_offset); + assert_eq!( + scroll_tree.get_node(&parent_id).offset(), + Some(expected_offset) + ); + assert_eq!(scroll_tree.get_node(&unscrollable_child_id).offset(), None); +} + +#[test] +fn test_scroll_tree_chain_when_at_extent() { + let mut scroll_tree = ScrollTree::default(); + + let pipeline_id = PipelineId(0, 0); + let parent_id = add_mock_scroll_node(&mut scroll_tree); + let child_id = add_mock_scroll_node(&mut scroll_tree); + + let (scrolled_id, offset) = scroll_tree + .scroll_node_or_ancestor(&child_id, ScrollLocation::End) + .unwrap(); + + let expected_offset = LayoutVector2D::new(0.0, -100.0); + assert_eq!(scrolled_id, ExternalScrollId(1, pipeline_id)); + assert_eq!(offset, expected_offset); + assert_eq!( + scroll_tree.get_node(&child_id).offset(), + Some(expected_offset) + ); + + // The parent will have scrolled because the child is already at the extent + // of its scroll area in the y axis. + let (scrolled_id, offset) = scroll_tree + .scroll_node_or_ancestor( + &child_id, + ScrollLocation::Delta(LayoutVector2D::new(0.0, -10.0)), + ) + .unwrap(); + let expected_offset = LayoutVector2D::new(0.0, -10.0); + assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id)); + assert_eq!(offset, expected_offset); + assert_eq!( + scroll_tree.get_node(&parent_id).offset(), + Some(expected_offset) + ); +} + +#[test] +fn test_scroll_tree_chain_through_overflow_hidden() { + let mut scroll_tree = ScrollTree::default(); + + // Create a tree with a scrollable leaf, but make its `scroll_sensitivity` + // reflect `overflow: hidden` ie not responsive to non-script scroll events. + let pipeline_id = PipelineId(0, 0); + let parent_id = add_mock_scroll_node(&mut scroll_tree); + let overflow_hidden_id = add_mock_scroll_node(&mut scroll_tree); + scroll_tree + .get_node_mut(&overflow_hidden_id) + .scroll_info + .as_mut() + .map(|info| { + info.scroll_sensitivity = AxesScrollSensitivity { + x: ScrollSensitivity::Script, + y: ScrollSensitivity::Script, + }; + }); + + let (scrolled_id, offset) = scroll_tree + .scroll_node_or_ancestor( + &overflow_hidden_id, + ScrollLocation::Delta(LayoutVector2D::new(-20.0, -40.0)), + ) + .unwrap(); + let expected_offset = LayoutVector2D::new(-20.0, -40.0); + assert_eq!(scrolled_id, ExternalScrollId(0, pipeline_id)); + assert_eq!(offset, expected_offset); + assert_eq!( + scroll_tree.get_node(&parent_id).offset(), + Some(expected_offset) + ); + assert_eq!( + scroll_tree.get_node(&overflow_hidden_id).offset(), + Some(LayoutVector2D::new(0.0, 0.0)) + ); +} |