diff --git a/patch/patch.cfg b/patch/patch.cfg index fc50a013e..830bf76e5 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -324,4 +324,10 @@ patches = [ 'name': 'plugin_info_webkit_2015', 'path': '../third_party/WebKit/', }, + { + # Fix issue with display of auto-hide scrollbars on macOS. + # https://bugs.chromium.org/p/chromium/issues/detail?id=644144#c14 + 'name': 'webkit_scroll_mac_644144', + 'path': '../', + }, ] diff --git a/patch/patches/webkit_scroll_mac_644144.patch b/patch/patches/webkit_scroll_mac_644144.patch new file mode 100644 index 000000000..a7665deff --- /dev/null +++ b/patch/patches/webkit_scroll_mac_644144.patch @@ -0,0 +1,153 @@ +diff --git third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp +index 8d74cdc8..c7fb4bb 100644 +--- third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp ++++ third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp +@@ -57,22 +57,23 @@ void ObjectPaintInvalidator::objectWillBeDestroyed(const LayoutObject& object) { + locationInBackingMap().remove(&object); + } + +-// TODO(trchen): Use std::function when available. +-template +-void traverseNonCompositingDescendantsInPaintOrder( ++using LayoutObjectTraversalFunctor = std::function; ++ ++static void traverseNonCompositingDescendantsInPaintOrder( + const LayoutObject&, + const LayoutObjectTraversalFunctor&); + +-template +-void traverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationContainer( ++static void ++traverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationContainer( + const LayoutObject& object, + const LayoutObjectTraversalFunctor& functor) { +- // |object| is a paint invalidation container but is not a stacking context, +- // so the paint invalidation container of stacked descendants don't belong to +- // |object| but belong to an ancestor. This function traverses all such +- // descendants. ++ // |object| is a paint invalidation container, but is not a stacking context ++ // or is a non-block, so the paint invalidation container of stacked ++ // descendants may not belong to |object| but belong to an ancestor. This ++ // function traverses all such descendants. See Case 1a and Case 2 below for ++ // details. + DCHECK(object.isPaintInvalidationContainer() && +- !object.styleRef().isStackingContext()); ++ (!object.styleRef().isStackingContext() || !object.isLayoutBlock())); + + LayoutObject* descendant = object.nextInPreOrder(&object); + while (descendant) { +@@ -82,28 +83,45 @@ void traverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationContai + // invalidation container in the same situation as |object|, or its paint + // invalidation container is in such situation. Keep searching until a + // stacked layer is found. +- descendant = descendant->nextInPreOrder(&object); ++ if (!object.isLayoutBlock() && descendant->isFloating()) { ++ // Case 1a (rare): However, if the descendant is a floating object below ++ // a composited non-block object, the subtree may belong to an ancestor ++ // in paint order, thus recur into the subtree. Note that for ++ // performance, we don't check whether the floating object's container ++ // is above or under |object|, so we may traverse more than expected. ++ // Example: ++ // ++ //
" ++ //
++ traverseNonCompositingDescendantsInPaintOrder(*descendant, functor); ++ descendant = descendant->nextInPreOrderAfterChildren(&object); ++ } else { ++ descendant = descendant->nextInPreOrder(&object); ++ } + } else if (!descendant->isPaintInvalidationContainer()) { + // Case 2: The descendant is stacked and is not composited. + // The invalidation container of its subtree is our ancestor, + // thus recur into the subtree. + traverseNonCompositingDescendantsInPaintOrder(*descendant, functor); + descendant = descendant->nextInPreOrderAfterChildren(&object); +- } else if (descendant->styleRef().isStackingContext()) { ++ } else if (descendant->styleRef().isStackingContext() && ++ descendant->isLayoutBlock()) { + // Case 3: The descendant is an invalidation container and is a stacking + // context. No objects in the subtree can have invalidation container + // outside of it, thus skip the whole subtree. ++ // This excludes non-block because there might be floating objects under ++ // the descendant belonging to some ancestor in paint order (Case 1a). + descendant = descendant->nextInPreOrderAfterChildren(&object); + } else { + // Case 4: The descendant is an invalidation container but not a stacking +- // context. This is the same situation as |object|, thus keep searching. ++ // context, or the descendant is a non-block stacking context. ++ // This is the same situation as |object|, thus keep searching. + descendant = descendant->nextInPreOrder(&object); + } + } + } + +-template +-void traverseNonCompositingDescendantsInPaintOrder( ++static void traverseNonCompositingDescendantsInPaintOrder( + const LayoutObject& object, + const LayoutObjectTraversalFunctor& functor) { + functor(object); +@@ -112,14 +130,18 @@ void traverseNonCompositingDescendantsInPaintOrder( + if (!descendant->isPaintInvalidationContainer()) { + functor(*descendant); + descendant = descendant->nextInPreOrder(&object); +- } else if (descendant->styleRef().isStackingContext()) { ++ } else if (descendant->styleRef().isStackingContext() && ++ descendant->isLayoutBlock()) { + // The descendant is an invalidation container and is a stacking context. + // No objects in the subtree can have invalidation container outside of + // it, thus skip the whole subtree. ++ // This excludes non-blocks because there might be floating objects under ++ // the descendant belonging to some ancestor in paint order (Case 1a). + descendant = descendant->nextInPreOrderAfterChildren(&object); + } else { +- // If a paint invalidation container is not a stacking context, +- // some of its descendants may belong to the parent container. ++ // If a paint invalidation container is not a stacking context, or the ++ // descendant is a non-block stacking context, some of its descendants may ++ // belong to the parent container. + traverseNonCompositingDescendantsBelongingToAncestorPaintInvalidationContainer( + *descendant, functor); + descendant = descendant->nextInPreOrderAfterChildren(&object); +@@ -127,6 +149,17 @@ void traverseNonCompositingDescendantsInPaintOrder( + } + } + ++static void setPaintingLayerNeedsRepaintDuringTraverse( ++ const LayoutObject& object) { ++ if (object.hasLayer() && ++ toLayoutBoxModelObject(object).hasSelfPaintingLayer()) { ++ toLayoutBoxModelObject(object).layer()->setNeedsRepaint(); ++ } else if (object.isFloating() && object.parent() && ++ !object.parent()->isLayoutBlock()) { ++ object.paintingLayer()->setNeedsRepaint(); ++ } ++} ++ + void ObjectPaintInvalidator:: + invalidateDisplayItemClientsIncludingNonCompositingDescendants( + PaintInvalidationReason reason) { +@@ -137,9 +170,7 @@ void ObjectPaintInvalidator:: + slowSetPaintingLayerNeedsRepaint(); + traverseNonCompositingDescendantsInPaintOrder( + m_object, [reason](const LayoutObject& object) { +- if (object.hasLayer() && +- toLayoutBoxModelObject(object).hasSelfPaintingLayer()) +- toLayoutBoxModelObject(object).layer()->setNeedsRepaint(); ++ setPaintingLayerNeedsRepaintDuringTraverse(object); + object.invalidateDisplayItemClients(reason); + }); + } +@@ -177,10 +208,10 @@ void ObjectPaintInvalidator:: + // share the same paintInvalidationContainer. + const LayoutBoxModelObject& paintInvalidationContainer = + m_object.containerForPaintInvalidation(); ++ slowSetPaintingLayerNeedsRepaint(); + traverseNonCompositingDescendantsInPaintOrder( + m_object, [&paintInvalidationContainer](const LayoutObject& object) { +- if (object.hasLayer()) +- toLayoutBoxModelObject(object).layer()->setNeedsRepaint(); ++ setPaintingLayerNeedsRepaintDuringTraverse(object); + ObjectPaintInvalidator(object).invalidatePaintOfPreviousVisualRect( + paintInvalidationContainer, PaintInvalidationSubtree); + });