Use explicit WebRender hit test items in legacy layout (#29981)

Including hit tests in non-hit test display list items is no longer
supported in upstream WebRender, so this change switches legacy layout
to always use explicit hit test display list items.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2023-07-17 11:11:09 +02:00 committed by GitHub
parent c86faae371
commit cf78bd7a0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 15 deletions

View file

@ -153,53 +153,71 @@ impl DisplayItem {
.clipping .clipping
.unwrap_or(clip_and_scroll_indices.scrolling); .unwrap_or(clip_and_scroll_indices.scrolling);
let current_clip_id = state.webrender_clip_id_for_index(internal_clip_id.to_index()); let current_clip_id = state.webrender_clip_id_for_index(internal_clip_id.to_index());
let hit_test_bounds = self.bounds().intersection(&self.base().clip_rect);
let mut build_common_item_properties = |base: &BaseDisplayItem| { let build_common_item_properties = |base: &BaseDisplayItem| {
let tag = match base.metadata.cursor {
Some(cursor) => {
let hit_test_index = state.compositor_info.add_hit_test_info(
base.metadata.node.0 as u64,
Some(cursor),
current_scroll_node_id,
);
Some((hit_test_index as u64, 0u16))
},
None => None,
};
CommonItemProperties { CommonItemProperties {
clip_rect: base.clip_rect, clip_rect: base.clip_rect,
spatial_id: current_scroll_node_id.spatial_id, spatial_id: current_scroll_node_id.spatial_id,
clip_id: ClipId::ClipChain(current_clip_id), clip_id: ClipId::ClipChain(current_clip_id),
// TODO(gw): Make use of the WR backface visibility functionality. // TODO(gw): Make use of the WR backface visibility functionality.
flags: PrimitiveFlags::default(), flags: PrimitiveFlags::default(),
hit_info: tag, hit_info: None,
} }
}; };
let mut push_hit_test = |base: &BaseDisplayItem| {
let bounds = match hit_test_bounds {
Some(bounds) => bounds,
None => return,
};
let cursor = match base.metadata.cursor {
Some(cursor) => cursor,
None => return,
};
let hit_test_index = state.compositor_info.add_hit_test_info(
base.metadata.node.0 as u64,
Some(cursor),
current_scroll_node_id,
);
let mut common = build_common_item_properties(base);
common.hit_info = Some((hit_test_index as u64, 0u16));
common.clip_rect = bounds;
builder.push_hit_test(&common);
};
match *self { match *self {
DisplayItem::Rectangle(ref mut item) => { DisplayItem::Rectangle(ref mut item) => {
item.item.common = build_common_item_properties(&item.base); item.item.common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
builder.push_item(&WrDisplayItem::Rectangle(item.item)); builder.push_item(&WrDisplayItem::Rectangle(item.item));
IsContentful(false) IsContentful(false)
}, },
DisplayItem::Text(ref mut item) => { DisplayItem::Text(ref mut item) => {
item.item.common = build_common_item_properties(&item.base); item.item.common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
builder.push_item(&WrDisplayItem::Text(item.item)); builder.push_item(&WrDisplayItem::Text(item.item));
builder.push_iter(item.data.iter()); builder.push_iter(item.data.iter());
IsContentful(true) IsContentful(true)
}, },
DisplayItem::Image(ref mut item) => { DisplayItem::Image(ref mut item) => {
item.item.common = build_common_item_properties(&item.base); item.item.common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
builder.push_item(&WrDisplayItem::Image(item.item)); builder.push_item(&WrDisplayItem::Image(item.item));
IsContentful(true) IsContentful(true)
}, },
DisplayItem::RepeatingImage(ref mut item) => { DisplayItem::RepeatingImage(ref mut item) => {
item.item.common = build_common_item_properties(&item.base); item.item.common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
builder.push_item(&WrDisplayItem::RepeatingImage(item.item)); builder.push_item(&WrDisplayItem::RepeatingImage(item.item));
IsContentful(true) IsContentful(true)
}, },
DisplayItem::Border(ref mut item) => { DisplayItem::Border(ref mut item) => {
item.item.common = build_common_item_properties(&item.base); item.item.common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
if !item.data.is_empty() { if !item.data.is_empty() {
builder.push_stops(item.data.as_ref()); builder.push_stops(item.data.as_ref());
} }
@ -208,28 +226,33 @@ impl DisplayItem {
}, },
DisplayItem::Gradient(ref mut item) => { DisplayItem::Gradient(ref mut item) => {
item.item.common = build_common_item_properties(&item.base); item.item.common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
builder.push_stops(item.data.as_ref()); builder.push_stops(item.data.as_ref());
builder.push_item(&WrDisplayItem::Gradient(item.item)); builder.push_item(&WrDisplayItem::Gradient(item.item));
IsContentful(false) IsContentful(false)
}, },
DisplayItem::RadialGradient(ref mut item) => { DisplayItem::RadialGradient(ref mut item) => {
item.item.common = build_common_item_properties(&item.base); item.item.common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
builder.push_stops(item.data.as_ref()); builder.push_stops(item.data.as_ref());
builder.push_item(&WrDisplayItem::RadialGradient(item.item)); builder.push_item(&WrDisplayItem::RadialGradient(item.item));
IsContentful(false) IsContentful(false)
}, },
DisplayItem::Line(ref mut item) => { DisplayItem::Line(ref mut item) => {
item.item.common = build_common_item_properties(&item.base); item.item.common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
builder.push_item(&WrDisplayItem::Line(item.item)); builder.push_item(&WrDisplayItem::Line(item.item));
IsContentful(false) IsContentful(false)
}, },
DisplayItem::BoxShadow(ref mut item) => { DisplayItem::BoxShadow(ref mut item) => {
item.item.common = build_common_item_properties(&item.base); item.item.common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
builder.push_item(&WrDisplayItem::BoxShadow(item.item)); builder.push_item(&WrDisplayItem::BoxShadow(item.item));
IsContentful(false) IsContentful(false)
}, },
DisplayItem::PushTextShadow(ref mut item) => { DisplayItem::PushTextShadow(ref mut item) => {
let common = build_common_item_properties(&item.base); let common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
builder.push_shadow( builder.push_shadow(
&SpaceAndClipInfo { &SpaceAndClipInfo {
spatial_id: common.spatial_id, spatial_id: common.spatial_id,
@ -246,6 +269,7 @@ impl DisplayItem {
}, },
DisplayItem::Iframe(ref mut item) => { DisplayItem::Iframe(ref mut item) => {
let common = build_common_item_properties(&item.base); let common = build_common_item_properties(&item.base);
push_hit_test(&item.base);
builder.push_iframe( builder.push_iframe(
item.bounds, item.bounds,
common.clip_rect, common.clip_rect,

View file

@ -281,8 +281,12 @@ impl Fragment {
return; return;
} }
let mut common = builder.common_properties(rect.to_webrender(), &fragment.parent_style); let common = builder.common_properties(rect.to_webrender(), &fragment.parent_style);
common.hit_info = builder.hit_info(&fragment.parent_style, fragment.base.tag, Cursor::Text);
let hit_info = builder.hit_info(&fragment.parent_style, fragment.base.tag, Cursor::Text);
let mut hit_test_common = common.clone();
hit_test_common.hit_info = hit_info;
builder.wr().push_hit_test(&hit_test_common);
let color = fragment.parent_style.clone_color(); let color = fragment.parent_style.clone_color();
let font_metrics = &fragment.font_metrics; let font_metrics = &fragment.font_metrics;