layout: Use the viewport size as the background-attachment: fixed positioning area (#37097)

This fixes the combination of `background-attachment: fixed` and
`no-repeat`. The positioning of the background should be relative to the
viewport, so using an infinite rectangle breaks things like `center`.

I'm not sure what the original motivation of using an infinite rectangle
here
and it doesn't seem to break any tests to stop using it.

Testing: This fixes `/css/CSS2/backgrounds/background-bg-pos-206.xht`.
Fixes #37082.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-05-24 11:45:53 +02:00 committed by GitHub
parent 78f74d0d5e
commit 57b99d641e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 5 additions and 15 deletions

View file

@ -3,7 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use app_units::Au; use app_units::Au;
use euclid::{Point2D, Size2D, Vector2D}; use euclid::{Size2D, Vector2D};
use style::computed_values::background_attachment::SingleComputedValue as BackgroundAttachment; use style::computed_values::background_attachment::SingleComputedValue as BackgroundAttachment;
use style::computed_values::background_clip::single_value::T as Clip; use style::computed_values::background_clip::single_value::T as Clip;
use style::computed_values::background_origin::single_value::T as Origin; use style::computed_values::background_origin::single_value::T as Origin;
@ -15,7 +15,6 @@ use style::values::specified::background::{
}; };
use webrender_api::{self as wr, units}; use webrender_api::{self as wr, units};
use wr::ClipChainId; use wr::ClipChainId;
use wr::units::LayoutSize;
use crate::replaced::NaturalSizes; use crate::replaced::NaturalSizes;
@ -66,8 +65,7 @@ impl<'a> BackgroundPainter<'a> {
if &BackgroundAttachment::Fixed == if &BackgroundAttachment::Fixed ==
get_cyclic(&background.background_attachment.0, layer_index) get_cyclic(&background.background_attachment.0, layer_index)
{ {
let viewport_size = builder.compositor_info.viewport_size; return builder.compositor_info.viewport_size.into();
return units::LayoutRect::from_origin_and_size(Point2D::origin(), viewport_size);
} }
match get_cyclic(&background.background_clip.0, layer_index) { match get_cyclic(&background.background_clip.0, layer_index) {
@ -132,6 +130,7 @@ impl<'a> BackgroundPainter<'a> {
pub(super) fn positioning_area( pub(super) fn positioning_area(
&self, &self,
fragment_builder: &'a super::BuilderForBoxFragment, fragment_builder: &'a super::BuilderForBoxFragment,
builder: &mut super::DisplayListBuilder,
layer_index: usize, layer_index: usize,
) -> units::LayoutRect { ) -> units::LayoutRect {
if let Some(positioning_area_override) = self.positioning_area_override { if let Some(positioning_area_override) = self.positioning_area_override {
@ -150,14 +149,7 @@ impl<'a> BackgroundPainter<'a> {
Origin::PaddingBox => *fragment_builder.padding_rect(), Origin::PaddingBox => *fragment_builder.padding_rect(),
Origin::BorderBox => fragment_builder.border_rect, Origin::BorderBox => fragment_builder.border_rect,
}, },
BackgroundAttachment::Fixed => { BackgroundAttachment::Fixed => builder.compositor_info.viewport_size.into(),
// This isn't the viewport size because that rects larger than the viewport might be
// transformed down into areas smaller than the viewport.
units::LayoutRect::from_origin_and_size(
Point2D::origin(),
LayoutSize::new(f32::MAX, f32::MAX),
)
},
} }
} }
} }
@ -170,7 +162,7 @@ pub(super) fn layout_layer(
natural_sizes: NaturalSizes, natural_sizes: NaturalSizes,
) -> Option<BackgroundLayer> { ) -> Option<BackgroundLayer> {
let painting_area = painter.painting_area(fragment_builder, builder, layer_index); let painting_area = painter.painting_area(fragment_builder, builder, layer_index);
let positioning_area = painter.positioning_area(fragment_builder, layer_index); let positioning_area = painter.positioning_area(fragment_builder, builder, layer_index);
let common = painter.common_properties(fragment_builder, builder, layer_index, painting_area); let common = painter.common_properties(fragment_builder, builder, layer_index, painting_area);
// https://drafts.csswg.org/css-backgrounds/#background-size // https://drafts.csswg.org/css-backgrounds/#background-size

View file

@ -1,2 +0,0 @@
[background-bg-pos-206.xht]
expected: FAIL