UI process side scrollbars for UI side compositing on Mac
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 7 Jan 2019 20:10:55 +0000 (20:10 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 7 Jan 2019 20:10:55 +0000 (20:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193106

Reviewed by Tim Horton.

Source/WebCore:

* page/FrameView.cpp:
(WebCore::FrameView::paintScrollCorner):
* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated):

Pass scrollbar host layers and the dark appearance bit to the scrolling tree.

* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::verticalScrollbarLayerForFrameView):
(WebCore::ScrollingCoordinator::horizontalScrollbarLayerForFrameView):
* page/scrolling/ScrollingCoordinator.h:
(WebCore::ScrollableAreaParameters::ScrollableAreaParameters):
(WebCore::ScrollableAreaParameters::operator== const):
* page/scrolling/ScrollingStateFrameScrollingNode.cpp:
(WebCore::ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode):
(WebCore::ScrollingStateFrameScrollingNode::setScrollbarLayers):
* page/scrolling/ScrollingStateFrameScrollingNode.h:
* page/scrolling/ScrollingTreeFrameScrollingNode.h:
* page/scrolling/ScrollingTreeScrollingNode.h:
(WebCore::ScrollingTreeScrollingNode::scrollableAreaSize const):
(WebCore::ScrollingTreeScrollingNode::totalContentsSize const):
(WebCore::ScrollingTreeScrollingNode::useDarkAppearanceForScrollbars const):
(WebCore::ScrollingTreeScrollingNode::lastCommittedScrollPosition const):
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
* platform/ScrollableArea.cpp:
(WebCore::ScrollableArea::useDarkAppearanceForScrollbars const):

Factor into a function as this is used in several places.

* platform/ScrollableArea.h:
* platform/mac/NSScrollerImpDetails.h:
* platform/mac/ScrollAnimatorMac.mm:
(-[WebScrollerImpDelegate effectiveAppearanceForScrollerImp:]):
* platform/mac/ScrollbarThemeMac.h:

Source/WebKit:

This patch implements Mac scrollbars on UI process side using the low level NSScrollerImp/NSScrollerPairImp
SPIs. With this patch scrollbars mostly work for the main frame and also render (but can't be interacted with)
for the subframes.

This is based on the similar code for web process side scrollbars in ScrollAnimatorMac. There is quite a bit of
copy code as there is no way to share nicely. One of these will eventually go away anyway.

* Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
(ArgumentCoder<ScrollingStateFrameScrollingNode>::encode):
(ArgumentCoder<ScrollingStateFrameScrollingNode>::decode):
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<ScrollableAreaParameters>::encode):
(IPC::ArgumentCoder<ScrollableAreaParameters>::decode):
* UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h:
* UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::connectStateNodeLayers):
(WebKit::RemoteScrollingCoordinatorProxy::handleMouseEvent):
* UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
* UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:
(WebKit::RemoteScrollingTree::createScrollingTreeNode):
(WebKit::RemoteScrollingTree::handleMouseEvent):
* UIProcess/RemoteLayerTree/RemoteScrollingTree.h:
* UIProcess/RemoteLayerTree/mac: Added.
* UIProcess/RemoteLayerTree/mac/ScrollerMac.h: Added.

Wraps NSScrollerImp for vertical or horizontal scrollbar.

(WebKit::ScrollerMac::pair):
(WebKit::ScrollerMac::orientation const):
(WebKit::ScrollerMac::hostLayer const):
(WebKit::ScrollerMac::scrollerImp):
* UIProcess/RemoteLayerTree/mac/ScrollerMac.mm: Added.
(-[WKScrollbarPartAnimation initWithScroller:featureToAnimate:animateFrom:animateTo:duration:]):
(-[WKScrollbarPartAnimation startAnimation]):
(-[WKScrollbarPartAnimation setStartValue:]):
(-[WKScrollbarPartAnimation setEndValue:]):
(-[WKScrollbarPartAnimation setCurrentProgress:]):
(-[WKScrollbarPartAnimation invalidate]):
(-[WKScrollerImpDelegate initWithScroller:]):
(-[WKScrollerImpDelegate cancelAnimations]):
(-[WKScrollerImpDelegate scrollerPair]):
(-[WKScrollerImpDelegate convertRectToBacking:]):
(-[WKScrollerImpDelegate convertRectFromBacking:]):
(-[WKScrollerImpDelegate layer]):
(-[WKScrollerImpDelegate mouseLocationInScrollerForScrollerImp:]):
(-[WKScrollerImpDelegate convertRectToLayer:]):
(-[WKScrollerImpDelegate shouldUseLayerPerPartForScrollerImp:]):
(-[WKScrollerImpDelegate effectiveAppearanceForScrollerImp:]):
(-[WKScrollerImpDelegate setUpAlphaAnimation:scrollerPainter:part:animateAlphaTo:duration:]):
(-[WKScrollerImpDelegate scrollerImp:animateKnobAlphaTo:duration:]):
(-[WKScrollerImpDelegate scrollerImp:animateTrackAlphaTo:duration:]):
(-[WKScrollerImpDelegate scrollerImp:animateUIStateTransitionWithDuration:]):
(-[WKScrollerImpDelegate scrollerImp:animateExpansionTransitionWithDuration:]):
(-[WKScrollerImpDelegate scrollerImp:overlayScrollerStateChangedTo:]):
(-[WKScrollerImpDelegate invalidate]):
(WebKit::ScrollerMac::ScrollerMac):
(WebKit::ScrollerMac::~ScrollerMac):
(WebKit::ScrollerMac::attach):
(WebKit::ScrollerMac::setHostLayer):
(WebKit::ScrollerMac::updatePosition):
(WebKit::ScrollerMac::convertFromContent const):
* UIProcess/RemoteLayerTree/mac/ScrollerPairMac.h: Added.
(WebKit::ScrollerPairMac::verticalScroller):
(WebKit::ScrollerPairMac::horizontalScroller):
(WebKit::ScrollerPairMac::scrollerImpPair):
(WebKit::ScrollerPairMac::lastKnownMousePosition const):
* UIProcess/RemoteLayerTree/mac/ScrollerPairMac.mm: Added.

Wraps NSScrollerPairImp and owns the vertical and horizontal scrollers.

(-[WKScrollerImpPairDelegate initWithScrollerPair:]):
(-[WKScrollerImpPairDelegate invalidate]):
(-[WKScrollerImpPairDelegate contentAreaRectForScrollerImpPair:]):
(-[WKScrollerImpPairDelegate inLiveResizeForScrollerImpPair:]):
(-[WKScrollerImpPairDelegate mouseLocationInContentAreaForScrollerImpPair:]):
(-[WKScrollerImpPairDelegate scrollerImpPair:convertContentPoint:toScrollerImp:]):
(-[WKScrollerImpPairDelegate scrollerImpPair:setContentAreaNeedsDisplayInRect:]):
(-[WKScrollerImpPairDelegate scrollerImpPair:updateScrollerStyleForNewRecommendedScrollerStyle:]):
(WebKit::ScrollerPairMac::ScrollerPairMac):
(WebKit::ScrollerPairMac::~ScrollerPairMac):
(WebKit::ScrollerPairMac::handleWheelEvent):
(WebKit::ScrollerPairMac::handleMouseEvent):
(WebKit::ScrollerPairMac::updatePositions):
(WebKit::ScrollerPairMac::contentsSize const):
(WebKit::ScrollerPairMac::visibleContentsRect const):
(WebKit::ScrollerPairMac::useDarkAppearance const):
* UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.cpp: Added.

Special node for UI side Mac scrolling. Owns ScrollerPairMac instance.

(WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::ScrollingTreeFrameScrollingNodeRemoteMac):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::~ScrollingTreeFrameScrollingNodeRemoteMac):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::create):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::commitStateBeforeChildren):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::setScrollLayerPosition):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::handleWheelEvent):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::handleMouseEvent):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::scrollingTree const):
* UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.h: Added.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::handleMouseEvent):
* WebKit.xcodeproj/project.pbxproj:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239689 268f45cc-cd09-0410-ab3c-d52691b4dbfc

35 files changed:
Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
Source/WebCore/page/scrolling/ScrollingCoordinator.h
Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.cpp
Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.h
Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.h
Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h
Source/WebCore/platform/ScrollableArea.cpp
Source/WebCore/platform/ScrollableArea.h
Source/WebCore/platform/mac/NSScrollerImpDetails.h
Source/WebCore/platform/mac/ScrollAnimatorMac.mm
Source/WebCore/platform/mac/ScrollbarThemeMac.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Source/WebKit/SourcesCocoa.txt
Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.h
Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerMac.h [new file with mode: 0644]
Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerMac.mm [new file with mode: 0644]
Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerPairMac.h [new file with mode: 0644]
Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerPairMac.mm [new file with mode: 0644]
Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.cpp [new file with mode: 0644]
Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.h [new file with mode: 0644]
Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalService.mm
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/mac/PageClientImplMac.mm
Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm
Source/WebKit/WebKit.xcodeproj/project.pbxproj

index d1fc8f8..b6677d6 100644 (file)
@@ -1,3 +1,45 @@
+2019-01-07  Antti Koivisto  <antti@apple.com>
+
+        UI process side scrollbars for UI side compositing on Mac
+        https://bugs.webkit.org/show_bug.cgi?id=193106
+
+        Reviewed by Tim Horton.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::paintScrollCorner):
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated):
+
+        Pass scrollbar host layers and the dark appearance bit to the scrolling tree.
+
+        * page/scrolling/ScrollingCoordinator.cpp:
+        (WebCore::ScrollingCoordinator::verticalScrollbarLayerForFrameView):
+        (WebCore::ScrollingCoordinator::horizontalScrollbarLayerForFrameView):
+        * page/scrolling/ScrollingCoordinator.h:
+        (WebCore::ScrollableAreaParameters::ScrollableAreaParameters):
+        (WebCore::ScrollableAreaParameters::operator== const):
+        * page/scrolling/ScrollingStateFrameScrollingNode.cpp:
+        (WebCore::ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode):
+        (WebCore::ScrollingStateFrameScrollingNode::setScrollbarLayers):
+        * page/scrolling/ScrollingStateFrameScrollingNode.h:
+        * page/scrolling/ScrollingTreeFrameScrollingNode.h:
+        * page/scrolling/ScrollingTreeScrollingNode.h:
+        (WebCore::ScrollingTreeScrollingNode::scrollableAreaSize const):
+        (WebCore::ScrollingTreeScrollingNode::totalContentsSize const):
+        (WebCore::ScrollingTreeScrollingNode::useDarkAppearanceForScrollbars const):
+        (WebCore::ScrollingTreeScrollingNode::lastCommittedScrollPosition const):
+        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.h:
+        * platform/ScrollableArea.cpp:
+        (WebCore::ScrollableArea::useDarkAppearanceForScrollbars const):
+
+        Factor into a function as this is used in several places.
+
+        * platform/ScrollableArea.h:
+        * platform/mac/NSScrollerImpDetails.h:
+        * platform/mac/ScrollAnimatorMac.mm:
+        (-[WebScrollerImpDelegate effectiveAppearanceForScrollerImp:]):
+        * platform/mac/ScrollbarThemeMac.h:
+
 2019-01-07  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Native caret shows up alongside the page's caret when requesting desktop site on jsfiddle.net
index df0e105..d25a7e6 100644 (file)
@@ -3958,10 +3958,8 @@ void FrameView::paintScrollCorner(GraphicsContext& context, const IntRect& corne
     }
 
 #if PLATFORM(MAC)
-    // If dark appearance is used or the overlay style is light (because of a dark page background), set the dark apppearance.
     // Keep this in sync with ScrollAnimatorMac's effectiveAppearanceForScrollerImp:.
-    bool useDarkAppearance = this->useDarkAppearance() || scrollbarOverlayStyle() == WebCore::ScrollbarOverlayStyleLight;
-    LocalDefaultSystemAppearance localAppearance(useDarkAppearance);
+    LocalDefaultSystemAppearance localAppearance(useDarkAppearanceForScrollbars());
 #endif
 
     ScrollView::paintScrollCorner(context, cornerRect);
index 4f98009..2976b56 100644 (file)
@@ -154,7 +154,7 @@ public:
 
     // In the future when any ScrollableArea can have a node in th ScrollingTree, this should
     // become a virtual function on ScrollableArea.
-    uint64_t scrollLayerID() const;
+    uint64_t scrollLayerID() const override;
     ScrollableArea* scrollableAreaForScrollLayerID(uint64_t) const;
 
     WEBCORE_EXPORT void enterCompositingMode();
@@ -653,6 +653,9 @@ public:
     void invalidateControlTints() { traverseForPaintInvalidation(GraphicsContext::PaintInvalidationReasons::InvalidatingControlTints); }
     void invalidateImagesWithAsyncDecodes() { traverseForPaintInvalidation(GraphicsContext::PaintInvalidationReasons::InvalidatingImagesWithAsyncDecodes); }
 
+    GraphicsLayer* layerForHorizontalScrollbar() const final;
+    GraphicsLayer* layerForVerticalScrollbar() const final;
+
 protected:
     bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) final;
     void scrollContentsSlowPath(const IntRect& updateRect) final;
@@ -724,8 +727,6 @@ private:
     IntRect scrollableAreaBoundingBox(bool* = nullptr) const final;
     bool scrollAnimatorEnabled() const final;
     GraphicsLayer* layerForScrolling() const final;
-    GraphicsLayer* layerForHorizontalScrollbar() const final;
-    GraphicsLayer* layerForVerticalScrollbar() const final;
     GraphicsLayer* layerForScrollCorner() const final;
 #if ENABLE(RUBBER_BANDING)
     GraphicsLayer* layerForOverhangAreas() const final;
index f630938..9d802d3 100644 (file)
@@ -136,7 +136,7 @@ void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView)
     auto* verticalScrollbar = frameView.verticalScrollbar();
     auto* horizontalScrollbar = frameView.horizontalScrollbar();
     node->setScrollerImpsFromScrollbars(verticalScrollbar, horizontalScrollbar);
-    
+
     node->setFrameScaleFactor(frameView.frame().frameScaleFactor());
     node->setHeaderHeight(frameView.headerHeight());
     node->setFooterHeight(frameView.footerHeight());
@@ -174,6 +174,7 @@ void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView)
     scrollParameters.hasEnabledVerticalScrollbar = verticalScrollbar && verticalScrollbar->enabled();
     scrollParameters.horizontalScrollbarMode = frameView.horizontalScrollbarMode();
     scrollParameters.verticalScrollbarMode = frameView.verticalScrollbarMode();
+    scrollParameters.useDarkAppearanceForScrollbars = frameView.useDarkAppearanceForScrollbars();
 
     node->setScrollableAreaParameters(scrollParameters);
 }
@@ -228,6 +229,8 @@ void AsyncScrollingCoordinator::frameViewRootLayerDidChange(FrameView& frameView
     node->setHeaderLayer(headerLayerForFrameView(frameView));
     node->setFooterLayer(footerLayerForFrameView(frameView));
     node->setScrollBehaviorForFixedElements(frameView.scrollBehaviorForFixedElements());
+    node->setVerticalScrollbarLayer(frameView.layerForVerticalScrollbar());
+    node->setHorizontalScrollbarLayer(frameView.layerForHorizontalScrollbar());
 }
 
 bool AsyncScrollingCoordinator::requestScrollPositionUpdate(FrameView& frameView, const IntPoint& scrollPosition)
@@ -465,13 +468,22 @@ void AsyncScrollingCoordinator::scrollableAreaScrollbarLayerDidChange(Scrollable
     ASSERT(isMainThread());
     ASSERT(m_page);
 
-    if (&scrollableArea != static_cast<ScrollableArea*>(m_page->mainFrame().view()))
-        return;
+    auto* node = m_scrollingStateTree->stateNodeForID(scrollableArea.scrollLayerID());
+    if (is<ScrollingStateFrameScrollingNode>(node)) {
+        auto& scrollingNode = downcast<ScrollingStateFrameScrollingNode>(*node);
+        if (orientation == VerticalScrollbar)
+            scrollingNode.setVerticalScrollbarLayer(scrollableArea.layerForVerticalScrollbar());
+        else
+            scrollingNode.setHorizontalScrollbarLayer(scrollableArea.layerForHorizontalScrollbar());
 
-    if (orientation == VerticalScrollbar)
-        scrollableArea.verticalScrollbarLayerDidChange();
-    else
-        scrollableArea.horizontalScrollbarLayerDidChange();
+    }
+
+    if (&scrollableArea == m_page->mainFrame().view()) {
+        if (orientation == VerticalScrollbar)
+            scrollableArea.verticalScrollbarLayerDidChange();
+        else
+            scrollableArea.horizontalScrollbarLayerDidChange();
+    }
 }
 
 ScrollingNodeID AsyncScrollingCoordinator::attachToStateTree(ScrollingNodeType nodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID, size_t childIndex)
index a258ed1..614b670 100644 (file)
@@ -91,24 +91,16 @@ enum class ScrollingLayerPositionAction {
 };
 
 struct ScrollableAreaParameters {
-    ScrollElasticity horizontalScrollElasticity;
-    ScrollElasticity verticalScrollElasticity;
+    ScrollElasticity horizontalScrollElasticity { ScrollElasticityNone };
+    ScrollElasticity verticalScrollElasticity { ScrollElasticityNone };
 
-    ScrollbarMode horizontalScrollbarMode;
-    ScrollbarMode verticalScrollbarMode;
+    ScrollbarMode horizontalScrollbarMode { ScrollbarAuto };
+    ScrollbarMode verticalScrollbarMode { ScrollbarAuto };
 
-    bool hasEnabledHorizontalScrollbar;
-    bool hasEnabledVerticalScrollbar;
-    
-    ScrollableAreaParameters()
-        : horizontalScrollElasticity(ScrollElasticityNone)
-        , verticalScrollElasticity(ScrollElasticityNone)
-        , horizontalScrollbarMode(ScrollbarAuto)
-        , verticalScrollbarMode(ScrollbarAuto)
-        , hasEnabledHorizontalScrollbar(false)
-        , hasEnabledVerticalScrollbar(false)
-    {
-    }
+    bool hasEnabledHorizontalScrollbar { false };
+    bool hasEnabledVerticalScrollbar { false };
+
+    bool useDarkAppearanceForScrollbars { false };
 
     bool operator==(const ScrollableAreaParameters& other) const
     {
@@ -117,7 +109,8 @@ struct ScrollableAreaParameters {
             && horizontalScrollbarMode == other.horizontalScrollbarMode
             && verticalScrollbarMode == other.verticalScrollbarMode
             && hasEnabledHorizontalScrollbar == other.hasEnabledHorizontalScrollbar
-            && hasEnabledVerticalScrollbar == other.hasEnabledVerticalScrollbar;
+            && hasEnabledVerticalScrollbar == other.hasEnabledVerticalScrollbar
+            && useDarkAppearanceForScrollbars == other.useDarkAppearanceForScrollbars;
     }
 };
 
index 01c36d6..23d14ca 100644 (file)
@@ -79,6 +79,12 @@ ScrollingStateFrameScrollingNode::ScrollingStateFrameScrollingNode(const Scrolli
 
     if (hasChangedProperty(FooterLayer))
         setFooterLayer(stateNode.footerLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
+
+    if (hasChangedProperty(VerticalScrollbarLayer))
+        setVerticalScrollbarLayer(stateNode.verticalScrollbarLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
+
+    if (hasChangedProperty(HorizontalScrollbarLayer))
+        setHorizontalScrollbarLayer(stateNode.horizontalScrollbarLayer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
 }
 
 ScrollingStateFrameScrollingNode::~ScrollingStateFrameScrollingNode() = default;
@@ -224,6 +230,24 @@ void ScrollingStateFrameScrollingNode::setFooterLayer(const LayerRepresentation&
     setPropertyChanged(FooterLayer);
 }
 
+void ScrollingStateFrameScrollingNode::setVerticalScrollbarLayer(const LayerRepresentation& layer)
+{
+    if (layer == m_verticalScrollbarLayer)
+        return;
+
+    m_verticalScrollbarLayer = layer;
+    setPropertyChanged(VerticalScrollbarLayer);
+}
+
+void ScrollingStateFrameScrollingNode::setHorizontalScrollbarLayer(const LayerRepresentation& layer)
+{
+    if (layer == m_horizontalScrollbarLayer)
+        return;
+
+    m_horizontalScrollbarLayer = layer;
+    setPropertyChanged(HorizontalScrollbarLayer);
+}
+
 void ScrollingStateFrameScrollingNode::setFixedElementsLayoutRelativeToFrame(bool fixedElementsLayoutRelativeToFrame)
 {
     if (fixedElementsLayoutRelativeToFrame == m_fixedElementsLayoutRelativeToFrame)
index 0fbc4ff..13b3415 100644 (file)
@@ -57,6 +57,8 @@ public:
         FooterHeight,
         HeaderLayer,
         FooterLayer,
+        VerticalScrollbarLayer,
+        HorizontalScrollbarLayer,
         PainterForScrollbar,
         BehaviorForFixedElements,
         TopContentInset,
@@ -119,6 +121,12 @@ public:
     const LayerRepresentation& footerLayer() const { return m_footerLayer; }
     WEBCORE_EXPORT void setFooterLayer(const LayerRepresentation&);
 
+    const LayerRepresentation& verticalScrollbarLayer() const { return m_verticalScrollbarLayer; }
+    WEBCORE_EXPORT void setVerticalScrollbarLayer(const LayerRepresentation&);
+
+    const LayerRepresentation& horizontalScrollbarLayer() const { return m_horizontalScrollbarLayer; }
+    WEBCORE_EXPORT void setHorizontalScrollbarLayer(const LayerRepresentation&);
+
     bool fixedElementsLayoutRelativeToFrame() const { return m_fixedElementsLayoutRelativeToFrame; }
     WEBCORE_EXPORT void setFixedElementsLayoutRelativeToFrame(bool);
 
@@ -142,6 +150,8 @@ private:
     LayerRepresentation m_contentShadowLayer;
     LayerRepresentation m_headerLayer;
     LayerRepresentation m_footerLayer;
+    LayerRepresentation m_verticalScrollbarLayer;
+    LayerRepresentation m_horizontalScrollbarLayer;
 
 #if PLATFORM(MAC)
     RetainPtr<NSScrollerImp> m_verticalScrollerImp;
index 95395b2..7b08a67 100644 (file)
@@ -80,7 +80,7 @@ protected:
     ScrollBehaviorForFixedElements scrollBehaviorForFixedElements() const { return m_behaviorForFixed; }
 
 private:
-    void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
+    WEBCORE_EXPORT void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
 
     FloatRect m_layoutViewport;
     FloatPoint m_minLayoutViewportOrigin;
index f6de783..70bd81d 100644 (file)
@@ -63,6 +63,8 @@ public:
     virtual void updateLayersAfterDelegatedScroll(const FloatPoint&) { }
 
     virtual FloatPoint scrollPosition() const = 0;
+    const FloatSize& scrollableAreaSize() const { return m_scrollableAreaSize; }
+    const FloatSize& totalContentsSize() const { return m_totalContentsSize; }
 
 #if ENABLE(CSS_SCROLL_SNAP)
     const Vector<float>& horizontalSnapOffsets() const { return m_snapOffsetsInfo.horizontalSnapOffsets; }
@@ -75,6 +77,8 @@ public:
     void setCurrentVerticalSnapPointIndex(unsigned index) { m_currentVerticalSnapPointIndex = index; }
 #endif
 
+    bool useDarkAppearanceForScrollbars() const { return m_scrollableAreaParameters.useDarkAppearanceForScrollbars; }
+
 protected:
     ScrollingTreeScrollingNode(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
 
@@ -84,8 +88,6 @@ protected:
     virtual void setScrollLayerPosition(const FloatPoint&, const FloatRect& layoutViewport) = 0;
 
     FloatPoint lastCommittedScrollPosition() const { return m_lastCommittedScrollPosition; }
-    const FloatSize& scrollableAreaSize() const { return m_scrollableAreaSize; }
-    const FloatSize& totalContentsSize() const { return m_totalContentsSize; }
     const FloatSize& reachableContentsSize() const { return m_reachableContentsSize; }
     const LayoutRect& parentRelativeScrollableRect() const { return m_parentRelativeScrollableRect; }
     const IntPoint& scrollOrigin() const { return m_scrollOrigin; }
index 2c8190d..5faf3fb 100644 (file)
@@ -37,12 +37,12 @@ OBJC_CLASS CALayer;
 
 namespace WebCore {
 
-class ScrollingTreeFrameScrollingNodeMac : public ScrollingTreeFrameScrollingNode, private ScrollControllerClient {
+class WEBCORE_EXPORT ScrollingTreeFrameScrollingNodeMac : public ScrollingTreeFrameScrollingNode, private ScrollControllerClient {
 public:
-    WEBCORE_EXPORT static Ref<ScrollingTreeFrameScrollingNode> create(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
+    static Ref<ScrollingTreeFrameScrollingNode> create(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
     virtual ~ScrollingTreeFrameScrollingNodeMac();
 
-private:
+protected:
     ScrollingTreeFrameScrollingNodeMac(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
 
     void releaseReferencesToScrollerImpsOnTheMainThread();
@@ -96,6 +96,7 @@ private:
 
     unsigned exposedUnfilledArea() const;
 
+private:
     ScrollController m_scrollController;
 
     RetainPtr<CALayer> m_scrollLayer;
index 9462921..efb76e8 100644 (file)
@@ -367,6 +367,12 @@ void ScrollableArea::setScrollbarOverlayStyle(ScrollbarOverlayStyle overlayStyle
     }
 }
 
+bool ScrollableArea::useDarkAppearanceForScrollbars() const
+{
+    // If dark appearance is used or the overlay style is light (because of a dark page background), set the dark appearance.
+    return useDarkAppearance() || scrollbarOverlayStyle() == WebCore::ScrollbarOverlayStyleLight;
+}
+
 void ScrollableArea::invalidateScrollbar(Scrollbar& scrollbar, const IntRect& rect)
 {
     if (&scrollbar == horizontalScrollbar()) {
index e15ec3f..f2c08f9 100644 (file)
@@ -141,6 +141,9 @@ public:
     bool hasOverlayScrollbars() const;
     WEBCORE_EXPORT virtual void setScrollbarOverlayStyle(ScrollbarOverlayStyle);
     ScrollbarOverlayStyle scrollbarOverlayStyle() const { return static_cast<ScrollbarOverlayStyle>(m_scrollbarOverlayStyle); }
+    bool useDarkAppearanceForScrollbars() const;
+
+    virtual uint64_t scrollLayerID() const { return 0; }
 
     // This getter will create a ScrollAnimator if it doesn't already exist.
     WEBCORE_EXPORT ScrollAnimator& scrollAnimator() const;
@@ -279,7 +282,7 @@ public:
 
     // Computes the double value for the scrollbar's current position and the current overhang amount.
     // This function is static so that it can be called from the main thread or the scrolling thread.
-    static void computeScrollbarValueAndOverhang(float currentPosition, float totalSize, float visibleSize, float& doubleValue, float& overhangAmount);
+    WEBCORE_EXPORT static void computeScrollbarValueAndOverhang(float currentPosition, float totalSize, float visibleSize, float& doubleValue, float& overhangAmount);
 
     // Let subclasses provide a way of asking for and servicing scroll
     // animations.
index 5313806..1ad3e31 100644 (file)
 
 namespace WebCore {
 
-class ScrollerStyle {
+class WEBCORE_EXPORT ScrollerStyle {
 public:
     static NSScrollerStyle recommendedScrollerStyle();
 
-    WEBCORE_EXPORT static void setUseOverlayScrollbars(bool);
+    static void setUseOverlayScrollbars(bool);
     
 private:
     static Optional<bool> m_useOverlayScrollbars;
index d08cc59..c9143ee 100644 (file)
@@ -535,9 +535,8 @@ enum FeatureToAnimate {
     if (!_scrollbar)
         return [NSAppearance currentAppearance];
 
-    // If dark appearance is used or the overlay style is light (because of a dark page background), return the dark apppearance.
     // Keep this in sync with FrameView::paintScrollCorner.
-    bool useDarkAppearance = _scrollbar->scrollableArea().useDarkAppearance() || _scrollbar->scrollableArea().scrollbarOverlayStyle() == WebCore::ScrollbarOverlayStyleLight;
+    bool useDarkAppearance = _scrollbar->scrollableArea().useDarkAppearanceForScrollbars();
     return [NSAppearance appearanceNamed:useDarkAppearance ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua];
 }
 #endif
index 3f0c0b5..74aa4fd 100644 (file)
@@ -29,6 +29,8 @@
 
 #if PLATFORM(MAC)
 
+OBJC_CLASS CALayer;
+
 namespace WebCore {
 
 class ScrollbarThemeMac : public ScrollbarThemeComposite {
index 47f682b..6cfd088 100644 (file)
@@ -1,3 +1,113 @@
+2019-01-07  Antti Koivisto  <antti@apple.com>
+
+        UI process side scrollbars for UI side compositing on Mac
+        https://bugs.webkit.org/show_bug.cgi?id=193106
+
+        Reviewed by Tim Horton.
+
+        This patch implements Mac scrollbars on UI process side using the low level NSScrollerImp/NSScrollerPairImp
+        SPIs. With this patch scrollbars mostly work for the main frame and also render (but can't be interacted with)
+        for the subframes.
+
+        This is based on the similar code for web process side scrollbars in ScrollAnimatorMac. There is quite a bit of
+        copy code as there is no way to share nicely. One of these will eventually go away anyway.
+
+        * Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
+        (ArgumentCoder<ScrollingStateFrameScrollingNode>::encode):
+        (ArgumentCoder<ScrollingStateFrameScrollingNode>::decode):
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<ScrollableAreaParameters>::encode):
+        (IPC::ArgumentCoder<ScrollableAreaParameters>::decode):
+        * UIProcess/RemoteLayerTree/RemoteLayerTreeNode.h:
+        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
+        (WebKit::RemoteScrollingCoordinatorProxy::connectStateNodeLayers):
+        (WebKit::RemoteScrollingCoordinatorProxy::handleMouseEvent):
+        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.h:
+        * UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:
+        (WebKit::RemoteScrollingTree::createScrollingTreeNode):
+        (WebKit::RemoteScrollingTree::handleMouseEvent):
+        * UIProcess/RemoteLayerTree/RemoteScrollingTree.h:
+        * UIProcess/RemoteLayerTree/mac: Added.
+        * UIProcess/RemoteLayerTree/mac/ScrollerMac.h: Added.
+
+        Wraps NSScrollerImp for vertical or horizontal scrollbar.
+
+        (WebKit::ScrollerMac::pair):
+        (WebKit::ScrollerMac::orientation const):
+        (WebKit::ScrollerMac::hostLayer const):
+        (WebKit::ScrollerMac::scrollerImp):
+        * UIProcess/RemoteLayerTree/mac/ScrollerMac.mm: Added.
+        (-[WKScrollbarPartAnimation initWithScroller:featureToAnimate:animateFrom:animateTo:duration:]):
+        (-[WKScrollbarPartAnimation startAnimation]):
+        (-[WKScrollbarPartAnimation setStartValue:]):
+        (-[WKScrollbarPartAnimation setEndValue:]):
+        (-[WKScrollbarPartAnimation setCurrentProgress:]):
+        (-[WKScrollbarPartAnimation invalidate]):
+        (-[WKScrollerImpDelegate initWithScroller:]):
+        (-[WKScrollerImpDelegate cancelAnimations]):
+        (-[WKScrollerImpDelegate scrollerPair]):
+        (-[WKScrollerImpDelegate convertRectToBacking:]):
+        (-[WKScrollerImpDelegate convertRectFromBacking:]):
+        (-[WKScrollerImpDelegate layer]):
+        (-[WKScrollerImpDelegate mouseLocationInScrollerForScrollerImp:]):
+        (-[WKScrollerImpDelegate convertRectToLayer:]):
+        (-[WKScrollerImpDelegate shouldUseLayerPerPartForScrollerImp:]):
+        (-[WKScrollerImpDelegate effectiveAppearanceForScrollerImp:]):
+        (-[WKScrollerImpDelegate setUpAlphaAnimation:scrollerPainter:part:animateAlphaTo:duration:]):
+        (-[WKScrollerImpDelegate scrollerImp:animateKnobAlphaTo:duration:]):
+        (-[WKScrollerImpDelegate scrollerImp:animateTrackAlphaTo:duration:]):
+        (-[WKScrollerImpDelegate scrollerImp:animateUIStateTransitionWithDuration:]):
+        (-[WKScrollerImpDelegate scrollerImp:animateExpansionTransitionWithDuration:]):
+        (-[WKScrollerImpDelegate scrollerImp:overlayScrollerStateChangedTo:]):
+        (-[WKScrollerImpDelegate invalidate]):
+        (WebKit::ScrollerMac::ScrollerMac):
+        (WebKit::ScrollerMac::~ScrollerMac):
+        (WebKit::ScrollerMac::attach):
+        (WebKit::ScrollerMac::setHostLayer):
+        (WebKit::ScrollerMac::updatePosition):
+        (WebKit::ScrollerMac::convertFromContent const):
+        * UIProcess/RemoteLayerTree/mac/ScrollerPairMac.h: Added.
+        (WebKit::ScrollerPairMac::verticalScroller):
+        (WebKit::ScrollerPairMac::horizontalScroller):
+        (WebKit::ScrollerPairMac::scrollerImpPair):
+        (WebKit::ScrollerPairMac::lastKnownMousePosition const):
+        * UIProcess/RemoteLayerTree/mac/ScrollerPairMac.mm: Added.
+
+        Wraps NSScrollerPairImp and owns the vertical and horizontal scrollers.
+
+        (-[WKScrollerImpPairDelegate initWithScrollerPair:]):
+        (-[WKScrollerImpPairDelegate invalidate]):
+        (-[WKScrollerImpPairDelegate contentAreaRectForScrollerImpPair:]):
+        (-[WKScrollerImpPairDelegate inLiveResizeForScrollerImpPair:]):
+        (-[WKScrollerImpPairDelegate mouseLocationInContentAreaForScrollerImpPair:]):
+        (-[WKScrollerImpPairDelegate scrollerImpPair:convertContentPoint:toScrollerImp:]):
+        (-[WKScrollerImpPairDelegate scrollerImpPair:setContentAreaNeedsDisplayInRect:]):
+        (-[WKScrollerImpPairDelegate scrollerImpPair:updateScrollerStyleForNewRecommendedScrollerStyle:]):
+        (WebKit::ScrollerPairMac::ScrollerPairMac):
+        (WebKit::ScrollerPairMac::~ScrollerPairMac):
+        (WebKit::ScrollerPairMac::handleWheelEvent):
+        (WebKit::ScrollerPairMac::handleMouseEvent):
+        (WebKit::ScrollerPairMac::updatePositions):
+        (WebKit::ScrollerPairMac::contentsSize const):
+        (WebKit::ScrollerPairMac::visibleContentsRect const):
+        (WebKit::ScrollerPairMac::useDarkAppearance const):
+        * UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.cpp: Added.
+
+        Special node for UI side Mac scrolling. Owns ScrollerPairMac instance.
+
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::ScrollingTreeFrameScrollingNodeRemoteMac):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::~ScrollingTreeFrameScrollingNodeRemoteMac):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::create):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::commitStateBeforeChildren):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::setScrollLayerPosition):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::handleWheelEvent):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::handleMouseEvent):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteMac::scrollingTree const):
+        * UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.h: Added.
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::handleMouseEvent):
+        * WebKit.xcodeproj/project.pbxproj:
+
 2019-01-07  Brian Burg  <bburg@apple.com>
 
         Unwanted page navigation after showing & dismissing contextual menu with control-click
index 29924fb..404a600 100644 (file)
@@ -164,6 +164,12 @@ void ArgumentCoder<ScrollingStateFrameScrollingNode>::encode(Encoder& encoder, c
 
     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer))
         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.contentShadowLayer());
+
+    if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::VerticalScrollbarLayer))
+        encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.verticalScrollbarLayer());
+
+    if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::HorizontalScrollbarLayer))
+        encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.horizontalScrollbarLayer());
 }
 
 void ArgumentCoder<ScrollingStateOverflowScrollingNode>::encode(Encoder& encoder, const ScrollingStateOverflowScrollingNode& node)
@@ -269,6 +275,20 @@ bool ArgumentCoder<ScrollingStateFrameScrollingNode>::decode(Decoder& decoder, S
         node.setContentShadowLayer(layerID);
     }
 
+    if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::VerticalScrollbarLayer)) {
+        GraphicsLayer::PlatformLayerID layerID;
+        if (!decoder.decode(layerID))
+            return false;
+        node.setVerticalScrollbarLayer(layerID);
+    }
+
+    if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::HorizontalScrollbarLayer)) {
+        GraphicsLayer::PlatformLayerID layerID;
+        if (!decoder.decode(layerID))
+            return false;
+        node.setHorizontalScrollbarLayer(layerID);
+    }
+
     return true;
 }
 
index e64b007..fb36a6a 100644 (file)
@@ -2111,6 +2111,8 @@ void ArgumentCoder<ScrollableAreaParameters>::encode(Encoder& encoder, const Scr
 
     encoder << parameters.hasEnabledHorizontalScrollbar;
     encoder << parameters.hasEnabledVerticalScrollbar;
+
+    encoder << parameters.useDarkAppearanceForScrollbars;
 }
 
 bool ArgumentCoder<ScrollableAreaParameters>::decode(Decoder& decoder, ScrollableAreaParameters& params)
@@ -2129,7 +2131,10 @@ bool ArgumentCoder<ScrollableAreaParameters>::decode(Decoder& decoder, Scrollabl
         return false;
     if (!decoder.decode(params.hasEnabledVerticalScrollbar))
         return false;
-    
+
+    if (!decoder.decode(params.useDarkAppearanceForScrollbars))
+        return false;
+
     return true;
 }
 
index a5855ba..a4336a0 100644 (file)
@@ -446,6 +446,10 @@ UIProcess/Plugins/mac/PluginInfoStoreMac.mm
 UIProcess/Plugins/mac/PluginProcessManagerMac.mm
 UIProcess/Plugins/mac/PluginProcessProxyMac.mm
 
+UIProcess/RemoteLayerTree/mac/ScrollerMac.mm
+UIProcess/RemoteLayerTree/mac/ScrollerPairMac.mm
+UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.cpp
+
 UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm
 UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm
 UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm
index 88d52b1..00ae5c6 100644 (file)
@@ -35,6 +35,8 @@ OBJC_CLASS UIView;
 
 namespace WebKit {
 
+class RemoteLayerTreeScrollbars;
+
 class RemoteLayerTreeNode {
     WTF_MAKE_FAST_ALLOCATED;
 public:
index ab64595..a367e15 100644 (file)
@@ -125,6 +125,12 @@ void RemoteScrollingCoordinatorProxy::connectStateNodeLayers(ScrollingStateTree&
 
             if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterLayer))
                 scrollingStateNode.setFooterLayer(layerTreeHost.layerForID(scrollingStateNode.footerLayer()));
+
+            if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::VerticalScrollbarLayer))
+                scrollingStateNode.setVerticalScrollbarLayer(layerTreeHost.layerForID(scrollingStateNode.verticalScrollbarLayer()));
+
+            if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::HorizontalScrollbarLayer))
+                scrollingStateNode.setHorizontalScrollbarLayer(layerTreeHost.layerForID(scrollingStateNode.horizontalScrollbarLayer()));
             break;
         }
         case ScrollingNodeType::Overflow: {
@@ -148,6 +154,11 @@ bool RemoteScrollingCoordinatorProxy::handleWheelEvent(const PlatformWheelEvent&
     return result == ScrollingTree::DidHandleEvent; // FIXME: handle other values.
 }
 
+void RemoteScrollingCoordinatorProxy::handleMouseEvent(const WebCore::PlatformMouseEvent& event)
+{
+    m_scrollingTree->handleMouseEvent(event);
+}
+
 TrackingType RemoteScrollingCoordinatorProxy::eventTrackingTypeForPoint(const AtomicString& eventName, IntPoint p) const
 {
     return m_scrollingTree->eventTrackingTypeForPoint(eventName, p);
index 4eddab6..b32d79f 100644 (file)
@@ -66,7 +66,8 @@ public:
 
     // FIXME: expose the tree and pass this to that?
     bool handleWheelEvent(const WebCore::PlatformWheelEvent&);
-    
+    void handleMouseEvent(const WebCore::PlatformMouseEvent&);
+
     WebCore::ScrollingNodeID rootScrollingNodeID() const;
 
     const RemoteLayerTreeHost* layerTreeHost() const;
index 4358f79..a7fcea8 100644 (file)
@@ -37,7 +37,7 @@
 #include "ScrollingTreeOverflowScrollingNodeIOS.h"
 #include <WebCore/ScrollingTreeFrameScrollingNodeIOS.h>
 #else
-#include <WebCore/ScrollingTreeFrameScrollingNodeMac.h>
+#include "ScrollingTreeFrameScrollingNodeRemoteMac.h"
 #endif
 
 namespace WebKit {
@@ -117,7 +117,7 @@ Ref<ScrollingTreeNode> RemoteScrollingTree::createScrollingTreeNode(ScrollingNod
 #if PLATFORM(IOS_FAMILY)
         return ScrollingTreeFrameScrollingNodeIOS::create(*this, nodeType, nodeID);
 #else
-        return ScrollingTreeFrameScrollingNodeMac::create(*this, nodeType, nodeID);
+        return ScrollingTreeFrameScrollingNodeRemoteMac::create(*this, nodeType, nodeID);
 #endif
     case ScrollingNodeType::Overflow:
 #if PLATFORM(IOS_FAMILY)
@@ -140,6 +140,15 @@ void RemoteScrollingTree::currentSnapPointIndicesDidChange(ScrollingNodeID nodeI
     m_scrollingCoordinatorProxy.currentSnapPointIndicesDidChange(nodeID, horizontal, vertical);
 }
 
+void RemoteScrollingTree::handleMouseEvent(const WebCore::PlatformMouseEvent& event)
+{
+#if ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC)
+    static_cast<ScrollingTreeFrameScrollingNodeRemoteMac&>(*rootNode()).handleMouseEvent(event);
+#else
+    UNUSED_PARAM(event);
+#endif
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(ASYNC_SCROLLING)
index 969f560..685b4f5 100644 (file)
 #include <WebCore/ScrollingConstraints.h>
 #include <WebCore/ScrollingTree.h>
 
+namespace WebCore {
+class PlatformMouseEvent;
+};
+
 namespace WebKit {
 
 class RemoteScrollingCoordinatorProxy;
@@ -43,6 +47,8 @@ public:
     bool isRemoteScrollingTree() const override { return true; }
     EventResult tryToHandleWheelEvent(const WebCore::PlatformWheelEvent&) override;
 
+    void handleMouseEvent(const WebCore::PlatformMouseEvent&);
+
     const RemoteScrollingCoordinatorProxy& scrollingCoordinatorProxy() const { return m_scrollingCoordinatorProxy; }
 
     void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, const Optional<WebCore::FloatPoint>& layoutViewportOrigin, WebCore::ScrollingLayerPositionAction = WebCore::ScrollingLayerPositionAction::Sync) override;
diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerMac.h b/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerMac.h
new file mode 100644 (file)
index 0000000..824758c
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if PLATFORM(MAC)
+
+#include <WebCore/FloatPoint.h>
+#include <wtf/RetainPtr.h>
+
+OBJC_CLASS CALayer;
+OBJC_CLASS NSScrollerImp;
+OBJC_CLASS WKScrollerImpDelegate;
+
+namespace WebKit {
+
+class ScrollerPairMac;
+
+class ScrollerMac {
+public:
+    enum class Orientation { Vertical, Horizontal };
+    
+    ScrollerMac(ScrollerPairMac&, Orientation);
+
+    ~ScrollerMac();
+
+    void attach();
+
+    ScrollerPairMac& pair() { return m_pair; }
+
+    Orientation orientation() const { return m_orientation; }
+
+    CALayer *hostLayer() const { return m_hostLayer.get(); }
+    void setHostLayer(CALayer *);
+
+    NSScrollerImp *scrollerImp() { return m_scrollerImp.get(); }
+
+    WebCore::FloatPoint convertFromContent(const WebCore::FloatPoint&) const;
+
+    void updateValues();
+
+private:
+    ScrollerPairMac& m_pair;
+    const Orientation m_orientation;
+
+    RetainPtr<CALayer> m_hostLayer;
+    RetainPtr<NSScrollerImp> m_scrollerImp;
+    RetainPtr<WKScrollerImpDelegate> m_scrollerImpDelegate;
+};
+
+}
+
+#endif
diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerMac.mm b/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerMac.mm
new file mode 100644 (file)
index 0000000..d964f57
--- /dev/null
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollerMac.h"
+
+#if PLATFORM(MAC)
+
+#include "ScrollerPairMac.h"
+#include <QuartzCore/CALayer.h>
+#include <WebCore/FloatPoint.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/NSScrollerImpDetails.h>
+#include <WebCore/PlatformWheelEvent.h>
+#include <pal/spi/mac/NSScrollerImpSPI.h>
+#include <wtf/BlockObjCExceptions.h>
+
+enum class FeatureToAnimate {
+    KnobAlpha,
+    TrackAlpha,
+    UIStateTransition,
+    ExpansionTransition
+};
+
+@interface WKScrollbarPartAnimation : NSAnimation {
+    WebKit::ScrollerMac* _scroller;
+    FeatureToAnimate _featureToAnimate;
+    CGFloat _startValue;
+    CGFloat _endValue;
+}
+- (id)initWithScroller:(WebKit::ScrollerMac*)scroller featureToAnimate:(FeatureToAnimate)featureToAnimate animateFrom:(CGFloat)startValue animateTo:(CGFloat)endValue duration:(NSTimeInterval)duration;
+@end
+
+@implementation WKScrollbarPartAnimation
+
+- (id)initWithScroller:(WebKit::ScrollerMac*)scroller featureToAnimate:(FeatureToAnimate)featureToAnimate animateFrom:(CGFloat)startValue animateTo:(CGFloat)endValue duration:(NSTimeInterval)duration
+{
+    self = [super initWithDuration:duration animationCurve:NSAnimationEaseInOut];
+    if (!self)
+        return nil;
+
+    _scroller = scroller;
+    _featureToAnimate = featureToAnimate;
+    _startValue = startValue;
+    _endValue = endValue;
+
+    [self setAnimationBlockingMode:NSAnimationNonblocking];
+
+    return self;
+}
+
+- (void)startAnimation
+{
+    ASSERT(_scroller);
+
+    [super startAnimation];
+}
+
+- (void)setStartValue:(CGFloat)startValue
+{
+    _startValue = startValue;
+}
+
+- (void)setEndValue:(CGFloat)endValue
+{
+    _endValue = endValue;
+}
+
+- (void)setCurrentProgress:(NSAnimationProgress)progress
+{
+    [super setCurrentProgress:progress];
+
+    CGFloat currentValue;
+    if (_startValue > _endValue)
+        currentValue = 1 - progress;
+    else
+        currentValue = progress;
+
+    switch (_featureToAnimate) {
+    case FeatureToAnimate::KnobAlpha:
+        [_scroller->scrollerImp() setKnobAlpha:currentValue];
+        break;
+    case FeatureToAnimate::TrackAlpha:
+        [_scroller->scrollerImp() setTrackAlpha:currentValue];
+        break;
+    case FeatureToAnimate::UIStateTransition:
+        [_scroller->scrollerImp() setUiStateTransitionProgress:currentValue];
+        break;
+    case FeatureToAnimate::ExpansionTransition:
+        [_scroller->scrollerImp() setExpansionTransitionProgress:currentValue];
+        break;
+    }
+}
+
+- (void)invalidate
+{
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    [self stopAnimation];
+    END_BLOCK_OBJC_EXCEPTIONS;
+    _scroller = nullptr;
+}
+
+@end
+
+@interface WKScrollerImpDelegate : NSObject<NSAnimationDelegate, NSScrollerImpDelegate> {
+    WebKit::ScrollerMac* _scroller;
+
+    RetainPtr<WKScrollbarPartAnimation> _knobAlphaAnimation;
+    RetainPtr<WKScrollbarPartAnimation> _trackAlphaAnimation;
+    RetainPtr<WKScrollbarPartAnimation> _uiStateTransitionAnimation;
+    RetainPtr<WKScrollbarPartAnimation> _expansionTransitionAnimation;
+}
+- (id)initWithScroller:(WebKit::ScrollerMac*)scroller;
+- (void)cancelAnimations;
+@end
+
+@implementation WKScrollerImpDelegate
+
+- (id)initWithScroller:(WebKit::ScrollerMac*)scroller
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    _scroller = scroller;
+    return self;
+}
+
+- (void)cancelAnimations
+{
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    [_knobAlphaAnimation stopAnimation];
+    [_trackAlphaAnimation stopAnimation];
+    [_uiStateTransitionAnimation stopAnimation];
+    [_expansionTransitionAnimation stopAnimation];
+    END_BLOCK_OBJC_EXCEPTIONS;
+}
+
+- (NSRect)convertRectToBacking:(NSRect)aRect
+{
+    return aRect;
+}
+
+- (NSRect)convertRectFromBacking:(NSRect)aRect
+{
+    return aRect;
+}
+
+- (CALayer *)layer
+{
+    return nil;
+}
+
+- (NSPoint)mouseLocationInScrollerForScrollerImp:(NSScrollerImp *)scrollerImp
+{
+    if (!_scroller)
+        return NSZeroPoint;
+
+    ASSERT_UNUSED(scrollerImp, scrollerImp == _scroller->scrollerImp());
+
+    return _scroller->convertFromContent(_scroller->pair().lastKnownMousePosition());
+}
+
+- (NSRect)convertRectToLayer:(NSRect)rect
+{
+    return rect;
+}
+
+- (BOOL)shouldUseLayerPerPartForScrollerImp:(NSScrollerImp *)scrollerImp
+{
+    UNUSED_PARAM(scrollerImp);
+
+    return true;
+}
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
+- (NSAppearance *)effectiveAppearanceForScrollerImp:(NSScrollerImp *)scrollerImp
+{
+    UNUSED_PARAM(scrollerImp);
+
+    if (!_scroller)
+        return [NSAppearance currentAppearance];
+
+    return [NSAppearance appearanceNamed:_scroller->pair().useDarkAppearance() ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua];
+}
+#endif
+
+- (void)setUpAlphaAnimation:(RetainPtr<WKScrollbarPartAnimation>&)scrollbarPartAnimation featureToAnimate:(FeatureToAnimate)featureToAnimate animateAlphaTo:(CGFloat)newAlpha duration:(NSTimeInterval)duration
+{
+    // If we are currently animating, ┬ástop
+    if (scrollbarPartAnimation) {
+        [scrollbarPartAnimation stopAnimation];
+        scrollbarPartAnimation = nil;
+    }
+
+    scrollbarPartAnimation = adoptNS([[WKScrollbarPartAnimation alloc] initWithScroller:_scroller
+        featureToAnimate:featureToAnimate
+        animateFrom:featureToAnimate == FeatureToAnimate::KnobAlpha ? [_scroller->scrollerImp() knobAlpha] : [_scroller->scrollerImp() trackAlpha]
+        animateTo:newAlpha
+        duration:duration]);
+    [scrollbarPartAnimation startAnimation];
+}
+
+- (void)scrollerImp:(NSScrollerImp *)scrollerImp animateKnobAlphaTo:(CGFloat)newKnobAlpha duration:(NSTimeInterval)duration
+{
+    if (!_scroller)
+        return;
+
+    ASSERT_UNUSED(scrollerImp, scrollerImp == _scroller->scrollerImp());
+    [self setUpAlphaAnimation:_knobAlphaAnimation featureToAnimate:FeatureToAnimate::KnobAlpha animateAlphaTo:newKnobAlpha duration:duration];
+}
+
+- (void)scrollerImp:(NSScrollerImp *)scrollerImp animateTrackAlphaTo:(CGFloat)newTrackAlpha duration:(NSTimeInterval)duration
+{
+    if (!_scroller)
+        return;
+
+    ASSERT_UNUSED(scrollerImp, scrollerImp == _scroller->scrollerImp());
+    [self setUpAlphaAnimation:_trackAlphaAnimation featureToAnimate:FeatureToAnimate::TrackAlpha animateAlphaTo:newTrackAlpha duration:duration];
+}
+
+- (void)scrollerImp:(NSScrollerImp *)scrollerImp animateUIStateTransitionWithDuration:(NSTimeInterval)duration
+{
+    if (!_scroller)
+        return;
+
+    ASSERT(scrollerImp == _scroller->scrollerImp());
+
+    // UIStateTransition always animates to 1. In case an animation is in progress this avoids a hard transition.
+    [scrollerImp setUiStateTransitionProgress:1 - [scrollerImp uiStateTransitionProgress]];
+
+    if (!_uiStateTransitionAnimation) {
+        _uiStateTransitionAnimation = adoptNS([[WKScrollbarPartAnimation alloc] initWithScroller:_scroller
+            featureToAnimate:FeatureToAnimate::UIStateTransition
+            animateFrom:[scrollerImp uiStateTransitionProgress]
+            animateTo:1.0
+            duration:duration]);
+    } else {
+        // If we don't need to initialize the animation, just reset the values in case they have changed.
+        [_uiStateTransitionAnimation setStartValue:[scrollerImp uiStateTransitionProgress]];
+        [_uiStateTransitionAnimation setEndValue:1.0];
+        [_uiStateTransitionAnimation setDuration:duration];
+    }
+    [_uiStateTransitionAnimation startAnimation];
+}
+
+- (void)scrollerImp:(NSScrollerImp *)scrollerImp animateExpansionTransitionWithDuration:(NSTimeInterval)duration
+{
+    if (!_scroller)
+        return;
+
+    ASSERT(scrollerImp == _scroller->scrollerImp());
+
+    // ExpansionTransition always animates to 1. In case an animation is in progress this avoids a hard transition.
+    [scrollerImp setExpansionTransitionProgress:1 - [scrollerImp expansionTransitionProgress]];
+
+    if (!_expansionTransitionAnimation) {
+        _expansionTransitionAnimation = adoptNS([[WKScrollbarPartAnimation alloc] initWithScroller:_scroller
+            featureToAnimate:FeatureToAnimate::ExpansionTransition
+            animateFrom:[scrollerImp expansionTransitionProgress]
+            animateTo:1.0
+            duration:duration]);
+    } else {
+        // If we don't need to initialize the animation, just reset the values in case they have changed.
+        [_expansionTransitionAnimation setStartValue:[scrollerImp uiStateTransitionProgress]];
+        [_expansionTransitionAnimation setEndValue:1.0];
+        [_expansionTransitionAnimation setDuration:duration];
+    }
+    [_expansionTransitionAnimation startAnimation];
+}
+
+- (void)scrollerImp:(NSScrollerImp *)scrollerImp overlayScrollerStateChangedTo:(NSOverlayScrollerState)newOverlayScrollerState
+{
+    UNUSED_PARAM(scrollerImp);
+    UNUSED_PARAM(newOverlayScrollerState);
+}
+
+- (void)invalidate
+{
+    _scroller = nil;
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    [_knobAlphaAnimation invalidate];
+    [_trackAlphaAnimation invalidate];
+    [_uiStateTransitionAnimation invalidate];
+    [_expansionTransitionAnimation invalidate];
+    END_BLOCK_OBJC_EXCEPTIONS;
+}
+
+@end
+
+namespace WebKit {
+
+ScrollerMac::ScrollerMac(ScrollerPairMac& pair, Orientation orientation)
+    : m_pair(pair)
+    , m_orientation(orientation)
+{
+}
+
+ScrollerMac::~ScrollerMac()
+{
+    [m_scrollerImpDelegate invalidate];
+    [m_scrollerImp setDelegate:nil];
+}
+
+void ScrollerMac::attach()
+{
+    m_scrollerImpDelegate = adoptNS([[WKScrollerImpDelegate alloc] initWithScroller:this]);
+
+    NSScrollerStyle newStyle = [m_pair.scrollerImpPair() scrollerStyle];
+    m_scrollerImp = [NSScrollerImp scrollerImpWithStyle:newStyle controlSize:NSControlSizeRegular horizontal:m_orientation == Orientation::Horizontal replacingScrollerImp:nil];
+    [m_scrollerImp setDelegate:m_scrollerImpDelegate.get()];
+}
+
+void ScrollerMac::setHostLayer(CALayer *layer)
+{
+    if (m_hostLayer == layer)
+        return;
+
+    m_hostLayer = layer;
+
+    [m_scrollerImp setLayer:layer];
+
+    if (m_orientation == Orientation::Vertical)
+        [m_pair.scrollerImpPair() setVerticalScrollerImp:layer ? m_scrollerImp.get() : nil];
+    else
+        [m_pair.scrollerImpPair() setHorizontalScrollerImp:layer ?  m_scrollerImp.get() : nil];
+}
+
+void ScrollerMac::updateValues()
+{
+    auto values = m_pair.valuesForOrientation(m_orientation);
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+    [m_scrollerImp setEnabled:!!m_hostLayer];
+    [m_scrollerImp setBoundsSize:NSSizeFromCGSize([m_hostLayer bounds].size)];
+    [m_scrollerImp setDoubleValue:values.value];
+    [m_scrollerImp setPresentationValue:values.value];
+    [m_scrollerImp setKnobProportion:values.proportion];
+
+    END_BLOCK_OBJC_EXCEPTIONS;
+}
+
+WebCore::FloatPoint ScrollerMac::convertFromContent(const WebCore::FloatPoint& point) const
+{
+    return WebCore::FloatPoint { [m_hostLayer convertPoint:point fromLayer:[m_hostLayer superlayer]] };
+}
+
+}
+
+#endif
diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerPairMac.h b/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerPairMac.h
new file mode 100644 (file)
index 0000000..f0725a0
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if PLATFORM(MAC)
+
+#include "ScrollerMac.h"
+#include <WebCore/FloatRect.h>
+#include <WebCore/FloatSize.h>
+
+OBJC_CLASS NSScrollerImpPair;
+OBJC_CLASS WKScrollerImpPairDelegate;
+
+namespace WebCore {
+class PlatformMouseEvent;
+class PlatformWheelEvent;
+class ScrollingTreeScrollingNode;
+}
+
+namespace WebKit {
+
+class ScrollerPairMac {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    ScrollerPairMac(WebCore::ScrollingTreeScrollingNode&);
+
+    ~ScrollerPairMac();
+
+    ScrollerMac& verticalScroller() { return m_verticalScroller; }
+    ScrollerMac& horizontalScroller() { return m_horizontalScroller; }
+
+    void handleWheelEvent(const WebCore::PlatformWheelEvent&);
+    void handleMouseEvent(const WebCore::PlatformMouseEvent&);
+
+    void updateValues();
+
+    WebCore::FloatSize visibleSize() const;
+    WebCore::IntPoint lastKnownMousePosition() const { return m_lastKnownMousePosition; }
+    bool useDarkAppearance() const;
+
+    struct Values {
+        float value;
+        float proportion;
+    };
+    Values valuesForOrientation(ScrollerMac::Orientation);
+
+    NSScrollerImpPair *scrollerImpPair() { return m_scrollerImpPair.get(); }
+
+private:
+    WebCore::ScrollingTreeScrollingNode& m_scrollingNode;
+
+    ScrollerMac m_verticalScroller;
+    ScrollerMac m_horizontalScroller;
+
+    WebCore::FloatSize m_contentSize;
+    WebCore::FloatRect m_visibleContentRect;
+
+    WebCore::IntPoint m_lastKnownMousePosition;
+    Optional<WebCore::FloatPoint> m_lastScrollPosition;
+
+    RetainPtr<NSScrollerImpPair> m_scrollerImpPair;
+    RetainPtr<WKScrollerImpPairDelegate> m_scrollerImpPairDelegate;
+};
+
+}
+
+#endif
diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerPairMac.mm b/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollerPairMac.mm
new file mode 100644 (file)
index 0000000..9b9f678
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollerPairMac.h"
+
+#if PLATFORM(MAC)
+
+#include "RemoteScrollingTree.h"
+#include <WebCore/FloatPoint.h>
+#include <WebCore/IntRect.h>
+#include <WebCore/NSScrollerImpDetails.h>
+#include <WebCore/PlatformMouseEvent.h>
+#include <WebCore/PlatformWheelEvent.h>
+#include <WebCore/ScrollTypes.h>
+#include <WebCore/ScrollableArea.h>
+#include <WebCore/ScrollingTreeScrollingNode.h>
+#include <pal/spi/mac/NSScrollerImpSPI.h>
+
+@interface WKScrollerImpPairDelegate : NSObject <NSScrollerImpPairDelegate> {
+    WebKit::ScrollerPairMac* _scrollerPair;
+}
+- (id)initWithScrollerPair:(WebKit::ScrollerPairMac*)scrollerPair;
+@end
+
+@implementation WKScrollerImpPairDelegate
+
+- (id)initWithScrollerPair:(WebKit::ScrollerPairMac*)scrollerPair
+{
+    self = [super init];
+    if (!self)
+        return nil;
+
+    _scrollerPair = scrollerPair;
+    return self;
+}
+
+- (void)invalidate
+{
+    _scrollerPair = nullptr;
+}
+
+- (NSRect)contentAreaRectForScrollerImpPair:(NSScrollerImpPair *)scrollerImpPair
+{
+    UNUSED_PARAM(scrollerImpPair);
+    if (!_scrollerPair)
+        return NSZeroRect;
+
+    auto size = _scrollerPair->visibleSize();
+    return NSMakeRect(0, 0, size.width(), size.height());
+}
+
+- (BOOL)inLiveResizeForScrollerImpPair:(NSScrollerImpPair *)scrollerImpPair
+{
+    // FIMXE: Not implemented.
+    return NO;
+}
+
+- (NSPoint)mouseLocationInContentAreaForScrollerImpPair:(NSScrollerImpPair *)scrollerImpPair
+{
+    UNUSED_PARAM(scrollerImpPair);
+    if (!_scrollerPair)
+        return NSZeroPoint;
+
+    return _scrollerPair->lastKnownMousePosition();
+}
+
+- (NSPoint)scrollerImpPair:(NSScrollerImpPair *)scrollerImpPair convertContentPoint:(NSPoint)pointInContentArea toScrollerImp:(NSScrollerImp *)scrollerImp
+{
+    UNUSED_PARAM(scrollerImpPair);
+
+    if (!_scrollerPair || !scrollerImp)
+        return NSZeroPoint;
+
+    WebKit::ScrollerMac* scroller = nullptr;
+    if ([scrollerImp isHorizontal])
+        scroller = &_scrollerPair->horizontalScroller();
+    else
+        scroller = &_scrollerPair->verticalScroller();
+
+    ASSERT(scrollerImp == scroller->scrollerImp());
+
+    return scroller->convertFromContent(WebCore::IntPoint(pointInContentArea));
+}
+
+- (void)scrollerImpPair:(NSScrollerImpPair *)scrollerImpPair setContentAreaNeedsDisplayInRect:(NSRect)rect
+{
+    UNUSED_PARAM(scrollerImpPair);
+    UNUSED_PARAM(rect);
+}
+
+- (void)scrollerImpPair:(NSScrollerImpPair *)scrollerImpPair updateScrollerStyleForNewRecommendedScrollerStyle:(NSScrollerStyle)newRecommendedScrollerStyle
+{
+    [scrollerImpPair setScrollerStyle:newRecommendedScrollerStyle];
+}
+
+@end
+
+namespace WebKit {
+
+ScrollerPairMac::ScrollerPairMac(WebCore::ScrollingTreeScrollingNode& node)
+    : m_scrollingNode(node)
+    , m_verticalScroller(*this, ScrollerMac::Orientation::Vertical)
+    , m_horizontalScroller(*this, ScrollerMac::Orientation::Horizontal)
+{
+    m_scrollerImpPairDelegate = adoptNS([[WKScrollerImpPairDelegate alloc] initWithScrollerPair:this]);
+
+    m_scrollerImpPair = adoptNS([[NSScrollerImpPair alloc] init]);
+    [m_scrollerImpPair.get() setDelegate:m_scrollerImpPairDelegate.get()];
+    [m_scrollerImpPair setScrollerStyle:WebCore::ScrollerStyle::recommendedScrollerStyle()];
+
+    m_verticalScroller.attach();
+    m_horizontalScroller.attach();
+}
+
+ScrollerPairMac::~ScrollerPairMac()
+{
+    [m_scrollerImpPairDelegate invalidate];
+    [m_scrollerImpPair setDelegate:nil];
+}
+
+void ScrollerPairMac::handleWheelEvent(const WebCore::PlatformWheelEvent& event)
+{
+    switch (event.phase()) {
+    case WebCore::PlatformWheelEventPhaseBegan:
+        [m_scrollerImpPair beginScrollGesture];
+        break;
+    case WebCore::PlatformWheelEventPhaseEnded:
+    case WebCore::PlatformWheelEventPhaseCancelled:
+        [m_scrollerImpPair endScrollGesture];
+        break;
+    case WebCore::PlatformWheelEventPhaseMayBegin:
+        [m_scrollerImpPair beginScrollGesture];
+        [m_scrollerImpPair contentAreaScrolled];
+        break;
+    default:
+        break;
+    }
+}
+
+void ScrollerPairMac::handleMouseEvent(const WebCore::PlatformMouseEvent& event)
+{
+    if (event.type() != WebCore::PlatformEvent::MouseMoved)
+        return;
+
+    m_lastKnownMousePosition = event.position();
+    [m_scrollerImpPair mouseMovedInContentArea];
+}
+
+void ScrollerPairMac::updateValues()
+{
+    auto position = m_scrollingNode.scrollPosition();
+
+    if (position != m_lastScrollPosition) {
+        if (m_lastScrollPosition) {
+            auto delta = position - *m_lastScrollPosition;
+            [m_scrollerImpPair contentAreaScrolledInDirection:NSMakePoint(delta.width(), delta.height())];
+        }
+        m_lastScrollPosition = position;
+    }
+
+    m_verticalScroller.updateValues();
+    m_horizontalScroller.updateValues();
+}
+
+WebCore::FloatSize ScrollerPairMac::visibleSize() const
+{
+    return m_scrollingNode.scrollableAreaSize();
+}
+
+bool ScrollerPairMac::useDarkAppearance() const
+{
+    return m_scrollingNode.useDarkAppearanceForScrollbars();
+}
+
+ScrollerPairMac::Values ScrollerPairMac::valuesForOrientation(ScrollerMac::Orientation orientation)
+{
+    float position;
+    float totalSize;
+    float visibleSize;
+    if (orientation == ScrollerMac:: Orientation::Vertical) {
+        position = m_scrollingNode.scrollPosition().y();
+        totalSize = m_scrollingNode.totalContentsSize().height();
+        visibleSize = m_scrollingNode.scrollableAreaSize().height();
+    } else {
+        position = m_scrollingNode.scrollPosition().x();
+        totalSize = m_scrollingNode.totalContentsSize().width();
+        visibleSize = m_scrollingNode.scrollableAreaSize().width();
+    }
+
+    float value;
+    float overhang;
+    WebCore::ScrollableArea::computeScrollbarValueAndOverhang(position, totalSize, visibleSize, value, overhang);
+
+    float proportion = totalSize ? (visibleSize - overhang) / totalSize : 1;
+
+    return { value, proportion };
+}
+
+}
+
+#endif
diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.cpp b/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.cpp
new file mode 100644 (file)
index 0000000..90866dc
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollingTreeFrameScrollingNodeRemoteMac.h"
+
+#if ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC)
+
+#include "RemoteScrollingTree.h"
+#include "ScrollerPairMac.h"
+
+namespace WebKit {
+
+ScrollingTreeFrameScrollingNodeRemoteMac::ScrollingTreeFrameScrollingNodeRemoteMac(WebCore::ScrollingTree& tree, WebCore::ScrollingNodeType nodeType, WebCore::ScrollingNodeID nodeID)
+    : WebCore::ScrollingTreeFrameScrollingNodeMac(tree, nodeType, nodeID)
+    , m_scrollerPair(std::make_unique<ScrollerPairMac>(*this))
+{
+}
+
+ScrollingTreeFrameScrollingNodeRemoteMac::~ScrollingTreeFrameScrollingNodeRemoteMac()
+{
+}
+
+Ref<ScrollingTreeFrameScrollingNodeRemoteMac> ScrollingTreeFrameScrollingNodeRemoteMac::create(WebCore::ScrollingTree& tree, WebCore::ScrollingNodeType nodeType, WebCore::ScrollingNodeID nodeID)
+{
+    return adoptRef(*new ScrollingTreeFrameScrollingNodeRemoteMac(tree, nodeType, nodeID));
+}
+
+void ScrollingTreeFrameScrollingNodeRemoteMac::commitStateBeforeChildren(const WebCore::ScrollingStateNode& stateNode)
+{
+    WebCore::ScrollingTreeFrameScrollingNodeMac::commitStateBeforeChildren(stateNode);
+    const auto& scrollingStateNode = downcast<WebCore::ScrollingStateFrameScrollingNode>(stateNode);
+
+    if (scrollingStateNode.hasChangedProperty(WebCore::ScrollingStateFrameScrollingNode::VerticalScrollbarLayer))
+        m_scrollerPair->verticalScroller().setHostLayer(scrollingStateNode.verticalScrollbarLayer());
+
+    if (scrollingStateNode.hasChangedProperty(WebCore::ScrollingStateFrameScrollingNode::HorizontalScrollbarLayer))
+        m_scrollerPair->horizontalScroller().setHostLayer(scrollingStateNode.horizontalScrollbarLayer());
+
+    m_scrollerPair->updateValues();
+}
+
+void ScrollingTreeFrameScrollingNodeRemoteMac::setScrollLayerPosition(const WebCore::FloatPoint& position, const WebCore::FloatRect& layoutViewport)
+{
+    ScrollingTreeFrameScrollingNodeMac::setScrollLayerPosition(position, layoutViewport);
+
+    m_scrollerPair->updateValues();
+}
+
+void ScrollingTreeFrameScrollingNodeRemoteMac::handleWheelEvent(const WebCore::PlatformWheelEvent& wheelEvent)
+{
+    ScrollingTreeFrameScrollingNodeMac::handleWheelEvent(wheelEvent);
+
+    m_scrollerPair->handleWheelEvent(wheelEvent);
+}
+
+void ScrollingTreeFrameScrollingNodeRemoteMac::handleMouseEvent(const WebCore::PlatformMouseEvent& mouseEvent)
+{
+    m_scrollerPair->handleMouseEvent(mouseEvent);
+}
+
+}
+
+#endif
diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.h b/Source/WebKit/UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.h
new file mode 100644 (file)
index 0000000..f2c32b5
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC)
+
+#include <WebCore/ScrollingTreeFrameScrollingNodeMac.h>
+
+namespace WebKit {
+
+class ScrollerPairMac;
+
+class ScrollingTreeFrameScrollingNodeRemoteMac : public WebCore::ScrollingTreeFrameScrollingNodeMac {
+public:
+    WEBCORE_EXPORT static Ref<ScrollingTreeFrameScrollingNodeRemoteMac> create(WebCore::ScrollingTree&, WebCore::ScrollingNodeType, WebCore::ScrollingNodeID);
+    virtual ~ScrollingTreeFrameScrollingNodeRemoteMac();
+
+    void handleMouseEvent(const WebCore::PlatformMouseEvent&);
+
+private:
+    ScrollingTreeFrameScrollingNodeRemoteMac(WebCore::ScrollingTree&, WebCore::ScrollingNodeType, WebCore::ScrollingNodeID);
+
+    void commitStateBeforeChildren(const WebCore::ScrollingStateNode&) override;
+    void handleWheelEvent(const WebCore::PlatformWheelEvent&) override;
+    void setScrollLayerPosition(const WebCore::FloatPoint& position, const WebCore::FloatRect& layoutViewport) override;
+
+    std::unique_ptr<ScrollerPairMac> m_scrollerPair;
+};
+
+}
+
+#endif // ENABLE(ASYNC_SCROLLING) && PLATFORM(MAC)
index d4ff83f..f40696c 100644 (file)
@@ -47,7 +47,7 @@ bool LocalService::isAvailable()
 #if !PLATFORM(IOS_FAMILY)
     return false;
 #else
-    if (!RuntimeEnabledFeatures::sharedFeatures().webAuthenticationLocalAuthenticatorEnabled())
+    if (!WebCore::RuntimeEnabledFeatures::sharedFeatures().webAuthenticationLocalAuthenticatorEnabled())
         return false;
 
     auto context = adoptNS([allocLAContextInstance() init]);
index 5769c7d..a298e3f 100644 (file)
@@ -2198,6 +2198,11 @@ void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
     if (!isValid())
         return;
 
+#if ENABLE(ASYNC_SCROLLING) && PLATFORM(COCOA)
+    if (m_scrollingCoordinatorProxy)
+        m_scrollingCoordinatorProxy->handleMouseEvent(platform(event));
+#endif
+
     // If we receive multiple mousemove or mouseforcechanged events and the most recent mousemove or mouseforcechanged event
     // (respectively) has not yet been sent to WebProcess for processing, remove the pending mouse event and insert the new
     // event in the queue.
index 6c5cb9c..a0cefdd 100644 (file)
@@ -94,7 +94,7 @@
 @end
 
 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
-@interface NSWindow (WebNSWindowDetails)
+@interface NSWindow (WebNSWindowLayerHostingDetails)
 - (BOOL)_hostsLayersInWindowServer;
 @end
 #endif
index 0f76b8d..e5d4119 100644 (file)
@@ -91,7 +91,7 @@ enum FullScreenState : NSInteger {
     ExitingFullScreen,
 };
 
-@interface NSWindow (WebNSWindowDetails)
+@interface NSWindow (WebNSWindowFullScreenDetails)
 - (void)exitFullScreenMode:(id)sender;
 - (void)enterFullScreenMode:(id)sender;
 @end
index 7e7e927..00a1c5f 100644 (file)
                E1E552C316AE065E004ED653 /* SandboxInitializationParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SandboxInitializationParameters.h; sourceTree = "<group>"; };
                E1EE53DC11F8CF9F00CCBEE4 /* InjectedBundlePageEditorClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundlePageEditorClient.h; sourceTree = "<group>"; };
                E1EE53E611F8CFFB00CCBEE4 /* InjectedBundlePageEditorClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundlePageEditorClient.cpp; sourceTree = "<group>"; };
+               E404907021DE65F70037F0DB /* ScrollerPairMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollerPairMac.h; sourceTree = "<group>"; };
+               E404907121DE65F70037F0DB /* ScrollingTreeFrameScrollingNodeRemoteMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingTreeFrameScrollingNodeRemoteMac.cpp; sourceTree = "<group>"; };
+               E404907221DE65F70037F0DB /* ScrollerPairMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollerPairMac.mm; sourceTree = "<group>"; };
+               E404907321DE65F70037F0DB /* ScrollingTreeFrameScrollingNodeRemoteMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeFrameScrollingNodeRemoteMac.h; sourceTree = "<group>"; };
+               E404907421DE65F70037F0DB /* ScrollerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollerMac.mm; sourceTree = "<group>"; };
+               E404907521DE65F70037F0DB /* ScrollerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollerMac.h; sourceTree = "<group>"; };
                E413F59B1AC1ADB600345360 /* NetworkCacheEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheEntry.h; sourceTree = "<group>"; };
                E413F59E1AC1AF9D00345360 /* NetworkCacheEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheEntry.cpp; sourceTree = "<group>"; };
                E42E060B1AA7440D00B11699 /* NetworkCacheIOChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheIOChannel.h; sourceTree = "<group>"; };
                2D1551A91F5A9B420006E3FE /* RemoteLayerTree */ = {
                        isa = PBXGroup;
                        children = (
+                               E404906F21DE65D70037F0DB /* mac */,
                                2D1551AA1F5A9BA70006E3FE /* ios */,
                                1AB16AE01648656D00290D62 /* RemoteLayerTreeDrawingAreaProxy.h */,
                                0FF24A2F1879E4FE003ABF0C /* RemoteLayerTreeDrawingAreaProxy.messages.in */,
                        name = PDF;
                        sourceTree = "<group>";
                };
+               E404906F21DE65D70037F0DB /* mac */ = {
+                       isa = PBXGroup;
+                       children = (
+                               E404907521DE65F70037F0DB /* ScrollerMac.h */,
+                               E404907421DE65F70037F0DB /* ScrollerMac.mm */,
+                               E404907021DE65F70037F0DB /* ScrollerPairMac.h */,
+                               E404907221DE65F70037F0DB /* ScrollerPairMac.mm */,
+                               E404907121DE65F70037F0DB /* ScrollingTreeFrameScrollingNodeRemoteMac.cpp */,
+                               E404907321DE65F70037F0DB /* ScrollingTreeFrameScrollingNodeRemoteMac.h */,
+                       );
+                       path = mac;
+                       sourceTree = "<group>";
+               };
                E489D2821A0A2BE80078C06A /* cache */ = {
                        isa = PBXGroup;
                        children = (