Skip to content
Permalink
Browse files
InteractionRegion UI-side layers should be grouped by originating ele…
…ment

https://bugs.webkit.org/show_bug.cgi?id=240766

Reviewed by Wenson Hsieh.

* Source/WebCore/page/InteractionRegion.cpp:
(WebCore::regionForElement):
* Source/WebCore/page/InteractionRegion.h:
(WebCore::operator==):
(WebCore::InteractionRegion::encode const):
(WebCore::InteractionRegion::decode):
Store and transmit an ElementIdentifier for each InteractionRegion.

* Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeInteractionRegionLayers.mm:
(WebKit::updateLayersForInteractionRegions):
Apply it to the layer.

Canonical link: https://commits.webkit.org/250842@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294616 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
hortont424 committed May 21, 2022
1 parent 0d63a64 commit 00360b3d7cf9208c8748c6a5ec5041405f75a59d
Showing 3 changed files with 23 additions and 10 deletions.
@@ -56,17 +56,18 @@ static FloatRect absoluteBoundingRectForRange(const SimpleRange& range)

static std::optional<InteractionRegion> regionForElement(Element& element)
{
auto& frameView = *element.document().frame()->view();
auto& mainFrameView = *element.document().frame()->mainFrame().view();
Ref document = element.document();
Ref frameView = *document->frame()->view();
Ref mainFrameView = *document->frame()->mainFrame().view();

IntRect frameClipRect;
#if PLATFORM(IOS_FAMILY)
frameClipRect = enclosingIntRect(frameView.exposedContentRect());
frameClipRect = enclosingIntRect(frameView->exposedContentRect());
#else
if (auto viewExposedRect = frameView.viewExposedRect())
if (auto viewExposedRect = frameView->viewExposedRect())
frameClipRect = enclosingIntRect(*viewExposedRect);
else
frameClipRect = frameView.visibleContentRect();
frameClipRect = frameView->visibleContentRect();
#endif

auto* renderer = element.renderer();
@@ -75,8 +76,10 @@ static std::optional<InteractionRegion> regionForElement(Element& element)

Vector<FloatRect> rectsInContentCoordinates;
InteractionRegion region;

region.elementIdentifier = document->identifierForElement(element);

auto linkRange = makeRangeSelectingNode(element);

if (linkRange)
region.hasLightBackground = estimatedBackgroundColorForRange(*linkRange, *element.document().frame()).luminance() > 0.5;

@@ -100,7 +103,7 @@ static std::optional<InteractionRegion> regionForElement(Element& element)
if (rectsInContentCoordinates.isEmpty())
rectsInContentCoordinates = { renderer->absoluteBoundingBoxRect() };

auto layoutArea = mainFrameView.layoutSize().area();
auto layoutArea = mainFrameView->layoutSize().area();
rectsInContentCoordinates = compactMap(rectsInContentCoordinates, [&] (auto rect) -> std::optional<FloatRect> {
if (rect.area() > layoutArea / 2)
return std::nullopt;
@@ -115,7 +118,7 @@ static std::optional<InteractionRegion> regionForElement(Element& element)
for (auto rect : rectsInContentCoordinates) {
auto contentsRect = rect;

if (&frameView != &mainFrameView)
if (frameView.ptr() != mainFrameView.ptr())
contentsRect.intersect(frameClipRect);

if (contentsRect.isEmpty())
@@ -25,6 +25,7 @@

#pragma once

#include "ElementIdentifier.h"
#include "FloatRect.h"
#include "Region.h"

@@ -42,6 +43,7 @@ namespace WebCore {
class Page;

struct InteractionRegion {
ElementIdentifier elementIdentifier;
Region regionInLayerCoordinates;
bool hasLightBackground { false };
float borderRadius { 0 };
@@ -54,7 +56,8 @@ struct InteractionRegion {

inline bool operator==(const InteractionRegion& a, const InteractionRegion& b)
{
return a.regionInLayerCoordinates == b.regionInLayerCoordinates
return a.elementIdentifier == b.elementIdentifier
&& a.regionInLayerCoordinates == b.regionInLayerCoordinates
&& a.hasLightBackground == b.hasLightBackground
&& a.borderRadius == b.borderRadius;
}
@@ -66,6 +69,7 @@ WTF::TextStream& operator<<(WTF::TextStream&, const InteractionRegion&);
template<class Encoder>
void InteractionRegion::encode(Encoder& encoder) const
{
encoder << elementIdentifier;
encoder << regionInLayerCoordinates;
encoder << hasLightBackground;
encoder << borderRadius;
@@ -74,6 +78,11 @@ void InteractionRegion::encode(Encoder& encoder) const
template<class Decoder>
std::optional<InteractionRegion> InteractionRegion::decode(Decoder& decoder)
{
std::optional<ElementIdentifier> elementIdentifier;
decoder >> elementIdentifier;
if (!elementIdentifier)
return std::nullopt;

std::optional<Region> regionInLayerCoordinates;
decoder >> regionInLayerCoordinates;
if (!regionInLayerCoordinates)
@@ -90,6 +99,7 @@ std::optional<InteractionRegion> InteractionRegion::decode(Decoder& decoder)
return std::nullopt;

return { {
WTFMove(*elementIdentifier),
WTFMove(*regionInLayerCoordinates),
WTFMove(*hasLightBackground),
WTFMove(*borderRadius)
@@ -114,7 +114,7 @@ void updateLayersForInteractionRegions(CALayer *layer, const RemoteLayerTreeTran
[interactionRegionLayer setBackgroundColor:cachedCGColor({ WebCore::SRGBA<float>(0, 1, 0, .3) }).get()];

setInteractionRegion(interactionRegionLayer.get(), region);
configureLayerForInteractionRegion(interactionRegionLayer.get(), @"WKInteractionRegion");
configureLayerForInteractionRegion(interactionRegionLayer.get(), makeString("WKInteractionRegion-"_s, String::number(region.elementIdentifier.toUInt64())));

[layer addSublayer:interactionRegionLayer.get()];
}

0 comments on commit 00360b3

Please sign in to comment.