diff options
author | Euclid Ye <yezhizhenjiakang@gmail.com> | 2025-02-14 16:14:57 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-14 08:14:57 +0000 |
commit | 03fc54e682bceebeece0ee556c25b8c9b897726f (patch) | |
tree | 5dc3d2f1ba2c6ec8b4af1b3cfc77c01488d91b9b | |
parent | 9b3e23633d6115659f4a1534a4a400f952f01e43 (diff) | |
download | servo-03fc54e682bceebeece0ee556c25b8c9b897726f.tar.gz servo-03fc54e682bceebeece0ee556c25b8c9b897726f.zip |
layout: Implement overflow scroll support for different axes (#35414)
* layout: Add AxesScrollSensitivity to enable control of scroll in axis
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout_2013: Be compatible with AxesScrollSensitivity
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: update struct AxesScrollSensitivity to euclid::Vector2D
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* display_list: implement From<Overflow> for ScrollSensitivity
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: simplify and reuse scroll related logic
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout_2013: simplify and reuse scroll related logic
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout, layout_2013: revert AxesScrollSensitivity to pair struct
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: Reimport ComputedOverflow as #35103 depends on it
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: Add AxesOverflow to replace PhysicalVec
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: implement scroll of viewport for different axes
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* layout: explicitly handle overflow match
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
* Update components/shared/webrender/Cargo.toml
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
---------
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | components/layout/display_list/builder.rs | 18 | ||||
-rw-r--r-- | components/layout/display_list/items.rs | 4 | ||||
-rw-r--r-- | components/layout/display_list/webrender_helpers.rs | 8 | ||||
-rw-r--r-- | components/layout_2020/display_list/mod.rs | 4 | ||||
-rw-r--r-- | components/layout_2020/display_list/stacking_context.rs | 22 | ||||
-rw-r--r-- | components/layout_2020/flow/root.rs | 34 | ||||
-rw-r--r-- | components/layout_2020/fragment_tree/fragment_tree.rs | 4 | ||||
-rw-r--r-- | components/layout_2020/style_ext.rs | 25 | ||||
-rw-r--r-- | components/shared/script/tests/compositor.rs | 12 | ||||
-rw-r--r-- | components/shared/webrender/Cargo.toml | 1 | ||||
-rw-r--r-- | components/shared/webrender/display_list.rs | 41 |
12 files changed, 111 insertions, 63 deletions
diff --git a/Cargo.lock b/Cargo.lock index 08433628d0d..3b10400efb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8611,6 +8611,7 @@ dependencies = [ "serde", "servo-media", "servo_geometry", + "style", "surfman", "webrender_api", ] diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index 6a4e31b6fa6..9ed59e15f94 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -51,7 +51,7 @@ use webrender_api::{ FilterOp, GlyphInstance, ImageRendering, LineStyle, NinePatchBorder, NinePatchBorderSource, NormalBorder, PropertyBinding, StickyOffsetBounds, }; -use webrender_traits::display_list::ScrollSensitivity; +use webrender_traits::display_list::AxesScrollSensitivity; use super::StackingContextId; use crate::block::BlockFlow; @@ -2535,14 +2535,6 @@ impl BlockFlow { return; } - let sensitivity = if StyleOverflow::Hidden == self.fragment.style.get_box().overflow_x && - StyleOverflow::Hidden == self.fragment.style.get_box().overflow_y - { - ScrollSensitivity::Script - } else { - ScrollSensitivity::ScriptAndInputEvents - }; - let border_widths = self .fragment .style @@ -2572,7 +2564,13 @@ impl BlockFlow { parent_index: self.clipping_and_scrolling().scrolling, clip, content_rect: Rect::new(content_box.origin, content_size).to_layout(), - node_type: ClipScrollNodeType::ScrollFrame(sensitivity, external_id), + node_type: ClipScrollNodeType::ScrollFrame( + AxesScrollSensitivity { + x: self.fragment.style.get_box().overflow_x.into(), + y: self.fragment.style.get_box().overflow_y.into(), + }, + external_id, + ), scroll_node_id: None, clip_chain_id: None, }); diff --git a/components/layout/display_list/items.rs b/components/layout/display_list/items.rs index d65b9ea6ba7..06280e04afa 100644 --- a/components/layout/display_list/items.rs +++ b/components/layout/display_list/items.rs @@ -32,7 +32,7 @@ use webrender_api::{ FilterOp, GlyphInstance, GradientStop, ImageKey, MixBlendMode, PrimitiveFlags, Shadow, SpatialId, StickyOffsetBounds, TransformStyle, }; -use webrender_traits::display_list::{ScrollSensitivity, ScrollTreeNodeId}; +use webrender_traits::display_list::{AxesScrollSensitivity, ScrollTreeNodeId}; use super::StackingContextId; @@ -353,7 +353,7 @@ pub enum ClipType { #[derive(Clone, Debug, PartialEq, Serialize)] pub enum ClipScrollNodeType { Placeholder, - ScrollFrame(ScrollSensitivity, ExternalScrollId), + ScrollFrame(AxesScrollSensitivity, ExternalScrollId), StickyFrame(StickyFrameData), Clip(ClipType), } diff --git a/components/layout/display_list/webrender_helpers.rs b/components/layout/display_list/webrender_helpers.rs index 692c11b83e5..ff13b1f9d53 100644 --- a/components/layout/display_list/webrender_helpers.rs +++ b/components/layout/display_list/webrender_helpers.rs @@ -17,7 +17,8 @@ use webrender_api::{ ReferenceFrameKind, SpaceAndClipInfo, SpatialId, SpatialTreeItemKey, }; use webrender_traits::display_list::{ - CompositorDisplayListInfo, ScrollSensitivity, ScrollTreeNodeId, ScrollableNodeInfo, + AxesScrollSensitivity, CompositorDisplayListInfo, ScrollSensitivity, ScrollTreeNodeId, + ScrollableNodeInfo, }; use crate::display_list::items::{ @@ -167,7 +168,10 @@ impl DisplayList { content_size, webrender_pipeline, epoch, - ScrollSensitivity::ScriptAndInputEvents, + AxesScrollSensitivity { + x: ScrollSensitivity::ScriptAndInputEvents, + y: ScrollSensitivity::ScriptAndInputEvents, + }, ), ); diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs index 7dc3823d437..e3a1155ae3a 100644 --- a/components/layout_2020/display_list/mod.rs +++ b/components/layout_2020/display_list/mod.rs @@ -36,7 +36,7 @@ use webrender_api::{ ImageRendering, NinePatchBorder, NinePatchBorderSource, }; use webrender_traits::display_list::{ - CompositorDisplayListInfo, ScrollSensitivity, ScrollTreeNodeId, + AxesScrollSensitivity, CompositorDisplayListInfo, ScrollTreeNodeId, }; use wr::units::LayoutVector2D; @@ -101,7 +101,7 @@ impl DisplayList { content_size: units::LayoutSize, pipeline_id: wr::PipelineId, epoch: wr::Epoch, - root_scroll_sensitivity: ScrollSensitivity, + root_scroll_sensitivity: AxesScrollSensitivity, ) -> Self { Self { wr: wr::DisplayListBuilder::new(pipeline_id), diff --git a/components/layout_2020/display_list/stacking_context.rs b/components/layout_2020/display_list/stacking_context.rs index f9d4af53dac..fbebb7ecf43 100644 --- a/components/layout_2020/display_list/stacking_context.rs +++ b/components/layout_2020/display_list/stacking_context.rs @@ -26,7 +26,7 @@ use style::values::specified::box_::DisplayOutside; use style::Zero; use webrender_api::units::{LayoutPoint, LayoutRect, LayoutTransform, LayoutVector2D}; use webrender_api::{self as wr, BorderRadius}; -use webrender_traits::display_list::{ScrollSensitivity, ScrollTreeNodeId, ScrollableNodeInfo}; +use webrender_traits::display_list::{AxesScrollSensitivity, ScrollTreeNodeId, ScrollableNodeInfo}; use wr::units::{LayoutPixel, LayoutSize}; use wr::{ClipChainId, SpatialTreeItemKey, StickyOffsetBounds}; @@ -38,8 +38,8 @@ use crate::fragment_tree::{ BoxFragment, ContainingBlockManager, Fragment, FragmentFlags, FragmentTree, PositioningFragment, SpecificLayoutInfo, }; -use crate::geom::{AuOrAuto, PhysicalRect, PhysicalSides, PhysicalVec}; -use crate::style_ext::ComputedValuesExt; +use crate::geom::{AuOrAuto, PhysicalRect, PhysicalSides}; +use crate::style_ext::{AxesOverflow, ComputedValuesExt}; #[derive(Clone)] pub(crate) struct ContainingBlock { @@ -212,7 +212,7 @@ impl DisplayList { external_id: wr::ExternalScrollId, content_rect: LayoutRect, clip_rect: LayoutRect, - scroll_sensitivity: ScrollSensitivity, + scroll_sensitivity: AxesScrollSensitivity, ) -> ScrollTreeNodeId { let spatial_tree_item_key = self.get_next_spatial_tree_item_key(); @@ -1373,7 +1373,7 @@ impl BoxFragment { } // TODO: merge this function with style.effective_overflow() - fn used_overflow(&self) -> PhysicalVec<ComputedOverflow> { + fn used_overflow(&self) -> AxesOverflow { let mut overflow = self.style.effective_overflow(); let is_replaced_element = self.base.flags.contains(FragmentFlags::IS_REPLACED); @@ -1483,12 +1483,12 @@ impl BoxFragment { display_list.wr.pipeline_id, ); - let sensitivity = - if ComputedOverflow::Hidden == overflow.x && ComputedOverflow::Hidden == overflow.y { - ScrollSensitivity::Script - } else { - ScrollSensitivity::ScriptAndInputEvents - }; + let overflow = self.style.effective_overflow(); + + let sensitivity = AxesScrollSensitivity { + x: overflow.x.into(), + y: overflow.y.into(), + }; let content_rect = self.scrollable_overflow().to_webrender(); diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index 0f51c5f626d..b95f9f0dadf 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -13,7 +13,7 @@ use style::dom::OpaqueNode; use style::properties::ComputedValues; use style::values::computed::Overflow; use style_traits::CSSPixel; -use webrender_traits::display_list::ScrollSensitivity; +use webrender_traits::display_list::AxesScrollSensitivity; use crate::cell::ArcRefCell; use crate::context::LayoutContext; @@ -40,8 +40,8 @@ pub struct BoxTree { /// <https://drafts.csswg.org/css-backgrounds/#special-backgrounds> canvas_background: CanvasBackground, - /// Whether or not the root element should be sensitive to scrolling input events. - sensitive_to_scroll_input: bool, + /// Whether or not the viewport should be sensitive to scrolling input events in two axes + scroll_sensitivity: AxesScrollSensitivity, } impl BoxTree { @@ -54,7 +54,7 @@ impl BoxTree { // Zero box for `:root { display: none }`, one for the root element otherwise. assert!(boxes.len() <= 1); - // From https://drafts.csswg.org/css-overflow/#propdef-overflow: + // From https://drafts.csswg.org/css-overflow/#overflow-propagation: // > UAs must apply the overflow-* values set on the root element to the viewport when the // > root element’s display value is not none. However, when the root element is an [HTML] // > html element (including XML syntax for HTML) whose overflow value is visible (in both @@ -62,12 +62,13 @@ impl BoxTree { // > none, user agents must instead apply the overflow-* values of the first such child // > element to the viewport. The element from which the value is propagated must then have a // > used overflow value of visible. - // - // TODO: This should handle when different overflow is set multiple axes, which requires the - // compositor scroll tree to allow setting a value per axis. let root_style = root_element.style(context); - let mut root_overflow = root_style.effective_overflow().y; - if root_overflow == Overflow::Visible && !root_style.get_box().display.is_none() { + let root_overflow = root_style.effective_overflow(); + let mut viewport_overflow = root_overflow; + if root_overflow.x == Overflow::Visible && + root_overflow.y == Overflow::Visible && + !root_style.get_box().display.is_none() + { for child in iter_child_nodes(root_element) { if !child .to_threadsafe() @@ -79,7 +80,7 @@ impl BoxTree { let style = child.style(context); if !style.get_box().display.is_none() { - root_overflow = style.effective_overflow().y; + viewport_overflow = style.effective_overflow(); break; } } @@ -93,7 +94,10 @@ impl BoxTree { contains_floats, }, canvas_background: CanvasBackground::for_root_element(context, root_element), - sensitive_to_scroll_input: root_overflow != Overflow::Hidden, + scroll_sensitivity: AxesScrollSensitivity { + x: viewport_overflow.x.to_scrollable().into(), + y: viewport_overflow.y.to_scrollable().into(), + }, } } @@ -392,18 +396,12 @@ impl BoxTree { acc.union(&child_overflow) }); - let root_scroll_sensitivity = if self.sensitive_to_scroll_input { - ScrollSensitivity::ScriptAndInputEvents - } else { - ScrollSensitivity::Script - }; - FragmentTree { root_fragments, scrollable_overflow, initial_containing_block: physical_containing_block, canvas_background: self.canvas_background.clone(), - root_scroll_sensitivity, + root_scroll_sensitivity: self.scroll_sensitivity, } } } diff --git a/components/layout_2020/fragment_tree/fragment_tree.rs b/components/layout_2020/fragment_tree/fragment_tree.rs index 7bc01f994f0..5d682227648 100644 --- a/components/layout_2020/fragment_tree/fragment_tree.rs +++ b/components/layout_2020/fragment_tree/fragment_tree.rs @@ -9,7 +9,7 @@ use fxhash::FxHashSet; use style::animation::AnimationSetKey; use style::dom::OpaqueNode; use webrender_api::units; -use webrender_traits::display_list::ScrollSensitivity; +use webrender_traits::display_list::AxesScrollSensitivity; use super::{ContainingBlockManager, Fragment, Tag}; use crate::display_list::StackingContext; @@ -38,7 +38,7 @@ pub struct FragmentTree { pub(crate) canvas_background: CanvasBackground, /// Whether or not the root element is sensitive to scroll input events. - pub root_scroll_sensitivity: ScrollSensitivity, + pub root_scroll_sensitivity: AxesScrollSensitivity, } impl FragmentTree { diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs index a1986ba3152..fcbbd2d575b 100644 --- a/components/layout_2020/style_ext.rs +++ b/components/layout_2020/style_ext.rs @@ -30,8 +30,8 @@ use webrender_api as wr; use crate::dom_traversal::Contents; use crate::fragment_tree::FragmentFlags; use crate::geom::{ - AuOrAuto, LengthPercentageOrAuto, LogicalSides, LogicalVec2, PhysicalSides, PhysicalSize, - PhysicalVec, Size, Sizes, + AuOrAuto, LengthPercentageOrAuto, LogicalSides, LogicalVec2, PhysicalSides, PhysicalSize, Size, + Sizes, }; use crate::table::TableLayoutStyle; use crate::{ContainingBlock, IndefiniteContainingBlock}; @@ -52,6 +52,11 @@ pub(crate) enum DisplayGeneratingBox { /// <https://drafts.csswg.org/css-display-3/#layout-specific-display> LayoutInternal(DisplayLayoutInternal), } +#[derive(Clone, Copy, Debug)] +pub struct AxesOverflow { + pub x: Overflow, + pub y: Overflow, +} impl DisplayGeneratingBox { pub(crate) fn display_inside(&self) -> DisplayInside { @@ -301,7 +306,7 @@ pub(crate) trait ComputedValuesExt { ) -> LogicalSides<LengthPercentageOrAuto<'_>>; fn has_transform_or_perspective(&self, fragment_flags: FragmentFlags) -> bool; fn effective_z_index(&self, fragment_flags: FragmentFlags) -> i32; - fn effective_overflow(&self) -> PhysicalVec<Overflow>; + fn effective_overflow(&self) -> AxesOverflow; fn establishes_block_formatting_context(&self) -> bool; fn establishes_stacking_context(&self, fragment_flags: FragmentFlags) -> bool; fn establishes_scroll_container(&self) -> bool; @@ -517,7 +522,7 @@ impl ComputedValuesExt for ComputedValues { /// Get the effective overflow of this box. The property only applies to block containers, /// flex containers, and grid containers. And some box types only accept a few values. /// <https://www.w3.org/TR/css-overflow-3/#overflow-control> - fn effective_overflow(&self) -> PhysicalVec<Overflow> { + fn effective_overflow(&self) -> AxesOverflow { let style_box = self.get_box(); let overflow_x = style_box.overflow_x; let overflow_y = style_box.overflow_y; @@ -547,9 +552,15 @@ impl ComputedValuesExt for ComputedValues { _ => false, }; if ignores_overflow { - PhysicalVec::new(Overflow::Visible, Overflow::Visible) + AxesOverflow { + x: Overflow::Visible, + y: Overflow::Visible, + } } else { - PhysicalVec::new(overflow_x, overflow_y) + AxesOverflow { + x: overflow_x, + y: overflow_y, + } } } @@ -583,6 +594,8 @@ impl ComputedValuesExt for ComputedValues { /// Whether or not the `overflow` value of this style establishes a scroll container. fn establishes_scroll_container(&self) -> bool { + // Checking one axis suffices, because the computed value ensures that + // either both axes are scrollable, or none is scrollable. self.effective_overflow().x.is_scrollable() } diff --git a/components/shared/script/tests/compositor.rs b/components/shared/script/tests/compositor.rs index ee3fd72ad49..c648d5ff681 100644 --- a/components/shared/script/tests/compositor.rs +++ b/components/shared/script/tests/compositor.rs @@ -6,7 +6,7 @@ use euclid::Size2D; use webrender_api::units::LayoutVector2D; use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, SpatialId}; use webrender_traits::display_list::{ - ScrollSensitivity, ScrollTree, ScrollTreeNodeId, ScrollableNodeInfo, + AxesScrollSensitivity, ScrollSensitivity, ScrollTree, ScrollTreeNodeId, ScrollableNodeInfo, }; fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId { @@ -27,7 +27,10 @@ fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId { Some(ScrollableNodeInfo { external_id: ExternalScrollId(num_nodes as u64, pipeline_id), scrollable_size: Size2D::new(100.0, 100.0), - scroll_sensitivity: ScrollSensitivity::ScriptAndInputEvents, + scroll_sensitivity: AxesScrollSensitivity { + x: ScrollSensitivity::ScriptAndInputEvents, + y: ScrollSensitivity::ScriptAndInputEvents, + }, offset: LayoutVector2D::zero(), }), ) @@ -158,7 +161,10 @@ fn test_scroll_tree_chain_through_overflow_hidden() { .scroll_info .as_mut() .map(|info| { - info.scroll_sensitivity = ScrollSensitivity::Script; + info.scroll_sensitivity = AxesScrollSensitivity { + x: ScrollSensitivity::Script, + y: ScrollSensitivity::Script, + }; }); let (scrolled_id, offset) = scroll_tree diff --git a/components/shared/webrender/Cargo.toml b/components/shared/webrender/Cargo.toml index bed2dcf0f46..40270bfc126 100644 --- a/components/shared/webrender/Cargo.toml +++ b/components/shared/webrender/Cargo.toml @@ -26,4 +26,5 @@ webrender_api = { workspace = true } serde = { workspace = true } servo_geometry = { path = "../../geometry" } servo-media = { workspace = true } +style = { workspace = true } surfman = { workspace = true, features = ["sm-x11"] } diff --git a/components/shared/webrender/display_list.rs b/components/shared/webrender/display_list.rs index 78e8e9492f6..4733e6c4024 100644 --- a/components/shared/webrender/display_list.rs +++ b/components/shared/webrender/display_list.rs @@ -6,17 +6,38 @@ use embedder_traits::Cursor; use serde::{Deserialize, Serialize}; +use style::values::specified::Overflow; use webrender_api::units::{LayoutSize, LayoutVector2D}; use webrender_api::{Epoch, ExternalScrollId, PipelineId, ScrollLocation, SpatialId}; -/// The scroll sensitivity of a scroll node ie whether it can be scrolled due to input event and -/// script events or only script events. +/// The scroll sensitivity of a scroll node in a particular axis ie whether it can be scrolled due to +/// input events and script events or only script events. #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] pub enum ScrollSensitivity { /// This node can be scrolled by input and script events. ScriptAndInputEvents, /// This node can only be scrolled by script events. Script, + /// This node cannot be scrolled. + None, +} + +/// Convert [Overflow] to [ScrollSensitivity]. +impl From<Overflow> for ScrollSensitivity { + fn from(overflow: Overflow) -> Self { + match overflow { + Overflow::Hidden => ScrollSensitivity::Script, + Overflow::Scroll | Overflow::Auto => ScrollSensitivity::ScriptAndInputEvents, + Overflow::Visible | Overflow::Clip => ScrollSensitivity::None, + } + } +} + +/// The [ScrollSensitivity] of particular node in the vertical and horizontal axes. +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)] +pub struct AxesScrollSensitivity { + pub x: ScrollSensitivity, + pub y: ScrollSensitivity, } /// Information that Servo keeps alongside WebRender display items @@ -57,7 +78,7 @@ pub struct ScrollableNodeInfo { pub scrollable_size: LayoutSize, /// Whether this `ScrollableNode` is sensitive to input events. - pub scroll_sensitivity: ScrollSensitivity, + pub scroll_sensitivity: AxesScrollSensitivity, /// The current offset of this scroll node. pub offset: LayoutVector2D, @@ -119,7 +140,9 @@ impl ScrollTreeNode { None => return None, }; - if info.scroll_sensitivity != ScrollSensitivity::ScriptAndInputEvents { + if info.scroll_sensitivity.x != ScrollSensitivity::ScriptAndInputEvents && + info.scroll_sensitivity.y != ScrollSensitivity::ScriptAndInputEvents + { return None; } @@ -150,11 +173,15 @@ impl ScrollTreeNode { let scrollable_height = info.scrollable_size.height; let original_layer_scroll_offset = info.offset; - if scrollable_width > 0. { + if scrollable_width > 0. && + info.scroll_sensitivity.x == ScrollSensitivity::ScriptAndInputEvents + { info.offset.x = (info.offset.x + delta.x).min(0.0).max(-scrollable_width); } - if scrollable_height > 0. { + if scrollable_height > 0. && + info.scroll_sensitivity.y == ScrollSensitivity::ScriptAndInputEvents + { info.offset.y = (info.offset.y + delta.y).min(0.0).max(-scrollable_height); } @@ -288,7 +315,7 @@ impl CompositorDisplayListInfo { content_size: LayoutSize, pipeline_id: PipelineId, epoch: Epoch, - root_scroll_sensitivity: ScrollSensitivity, + root_scroll_sensitivity: AxesScrollSensitivity, ) -> Self { let mut scroll_tree = ScrollTree::default(); let root_reference_frame_id = scroll_tree.add_scroll_tree_node( |