compositor: Do not allow script to scroll beyond node boundaries (#37412)

The compositor was accepting scroll offsets from the ScriptThread
without checking their boundaries. In some cases this could cause a
temporary discrepancy with the rendered scroll offset. This change makes
it so that all offset updates for scroll ayers in the compositor do not
scroll past the scroll boundaries of the node.

Testing: Two new tests pass with this change:
 - `/css/css-position/sticky/position-sticky-left-003.html`
 -  `/css/css-position/sticky/position-sticky-top-003.html`

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-06-12 19:32:50 +02:00 committed by GitHub
parent b28e796647
commit 29fc878e15
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 142 additions and 107 deletions

View file

@ -15,7 +15,9 @@ use base::cross_process_instant::CrossProcessInstant;
use base::id::{PipelineId, WebViewId};
use base::{Epoch, WebRenderEpochToU16};
use bitflags::bitflags;
use compositing_traits::display_list::{CompositorDisplayListInfo, HitTestInfo, ScrollTree};
use compositing_traits::display_list::{
CompositorDisplayListInfo, HitTestInfo, ScrollTree, ScrollType,
};
use compositing_traits::rendering_context::RenderingContext;
use compositing_traits::{
CompositionPipeline, CompositorMsg, ImageUpdate, SendableFrameTree, WebViewTrait,
@ -738,22 +740,22 @@ impl IOCompositor {
};
let offset = LayoutVector2D::new(point.x, point.y);
if !pipeline_details
let Some(offset) = pipeline_details
.scroll_tree
.set_scroll_offsets_for_node_with_external_scroll_id(
external_scroll_id,
-offset,
ScrollType::Script,
)
{
warn!("Could not scroll not with id: {external_scroll_id:?}");
else {
return;
}
};
let mut txn = Transaction::new();
txn.set_scroll_offsets(
external_scroll_id,
vec![SampledScrollOffset {
offset,
offset: -offset,
generation: 0,
}],
);