WebKit2 swipe gesture should report the position of the snapshot to the client
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Aug 2014 01:23:52 +0000 (01:23 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Aug 2014 01:23:52 +0000 (01:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=136308
rdar://problem/18105827

Reviewed by Simon Fraser.

* UIProcess/API/Cocoa/WKViewPrivate.h:
* UIProcess/API/mac/WKView.mm:
(-[WKView _setDidMoveSwipeSnapshotCallback:]):
Add _setDidMoveSwipeSnapshotCallback, and plumb it to ViewGestureController.
Callers provide a block which is called whenever ViewGestureController moves the
swipe *snapshot* layer around.

* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.h:
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::boundsOfLayerInLayerBackedWindowCoordinates):
* UIProcess/mac/WebPageProxyMac.mm:
(WebKit::WebPageProxy::boundsOfLayerInLayerBackedWindowCoordinates):
Expose a Mac-only way to get the bounds of a given CALayer in window coordinates,
respecting transforms. This only works for layer-backed windows because
it uses CA in order to do the mapping respecting transforms.

* UIProcess/mac/ViewGestureController.h:
* UIProcess/mac/ViewGestureControllerMac.mm:
(WebKit::ViewGestureController::ViewGestureController):
(WebKit::ViewGestureController::~ViewGestureController):
(WebKit::ViewGestureController::setDidMoveSwipeSnapshotCallback):
Do the Block_copy and Block_release dance to keep our copy of the callback block.

(WebKit::ViewGestureController::beginSwipeGesture):
(WebKit::ViewGestureController::handleSwipeGesture):
(WebKit::ViewGestureController::didMoveSwipeSnapshotLayer):
When the swipe snapshot layer moves around, call the block.

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

Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h
Source/WebKit2/UIProcess/API/mac/WKView.mm
Source/WebKit2/UIProcess/PageClient.h
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/mac/PageClientImpl.h
Source/WebKit2/UIProcess/mac/PageClientImpl.mm
Source/WebKit2/UIProcess/mac/ViewGestureController.h
Source/WebKit2/UIProcess/mac/ViewGestureControllerMac.mm
Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm

index d80cfb5..b5d1973 100644 (file)
@@ -1,5 +1,43 @@
 2014-08-27  Tim Horton  <timothy_horton@apple.com>
 
+        WebKit2 swipe gesture should report the position of the snapshot to the client
+        https://bugs.webkit.org/show_bug.cgi?id=136308
+        rdar://problem/18105827
+
+        Reviewed by Simon Fraser.
+
+        * UIProcess/API/Cocoa/WKViewPrivate.h:
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView _setDidMoveSwipeSnapshotCallback:]):
+        Add _setDidMoveSwipeSnapshotCallback, and plumb it to ViewGestureController.
+        Callers provide a block which is called whenever ViewGestureController moves the
+        swipe *snapshot* layer around.
+
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/mac/PageClientImpl.h:
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::boundsOfLayerInLayerBackedWindowCoordinates):
+        * UIProcess/mac/WebPageProxyMac.mm:
+        (WebKit::WebPageProxy::boundsOfLayerInLayerBackedWindowCoordinates):
+        Expose a Mac-only way to get the bounds of a given CALayer in window coordinates,
+        respecting transforms. This only works for layer-backed windows because
+        it uses CA in order to do the mapping respecting transforms.
+
+        * UIProcess/mac/ViewGestureController.h:
+        * UIProcess/mac/ViewGestureControllerMac.mm:
+        (WebKit::ViewGestureController::ViewGestureController):
+        (WebKit::ViewGestureController::~ViewGestureController):
+        (WebKit::ViewGestureController::setDidMoveSwipeSnapshotCallback):
+        Do the Block_copy and Block_release dance to keep our copy of the callback block.
+
+        (WebKit::ViewGestureController::beginSwipeGesture):
+        (WebKit::ViewGestureController::handleSwipeGesture):
+        (WebKit::ViewGestureController::didMoveSwipeSnapshotLayer):
+        When the swipe snapshot layer moves around, call the block.
+
+2014-08-27  Tim Horton  <timothy_horton@apple.com>
+
         Occasional crashes in commitTransientZoom's transaction completion block
         https://bugs.webkit.org/show_bug.cgi?id=136309
         <rdar://problem/17215064>
index f8aaf00..3b52a1f 100644 (file)
 // The top content inset is applied in the window's coordinate space, to the union of the custom swipe view's frames.
 - (void)_setCustomSwipeViewsTopContentInset:(float)topContentInset;
 - (BOOL)_tryToSwipeWithEvent:(NSEvent *)event ignoringPinnedState:(BOOL)ignoringPinnedState;
+// The rect returned is always that of the snapshot, not necessarily the swiping layer. This only works for layer-backed windows.
+- (void)_setDidMoveSwipeSnapshotCallback:(void(^)(CGRect swipeSnapshotRectInWindowCoordinates))callback;
 
 #endif
 
index bbde7fe..758bc91 100644 (file)
@@ -4080,6 +4080,15 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path)
     return handledEvent;
 }
 
+- (void)_setDidMoveSwipeSnapshotCallback:(void(^)(CGRect))callback
+{
+    if (!_data->_allowsBackForwardNavigationGestures)
+        return;
+
+    [self _ensureGestureController];
+    _data->_gestureController->setDidMoveSwipeSnapshotCallback(callback);
+}
+
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
 
 - (void)_setAutomaticallyAdjustsContentInsets:(BOOL)automaticallyAdjustsContentInsets
index d781fcf..3684609 100644 (file)
@@ -231,6 +231,8 @@ public:
     virtual void recommendedScrollbarStyleDidChange(int32_t newStyle) = 0;
     virtual void removeNavigationGestureSnapshot() = 0;
 
+    virtual CGRect boundsOfLayerInLayerBackedWindowCoordinates(CALayer *) const = 0;
+
     virtual ColorSpaceData colorSpace() = 0;
 
 #if USE(APPKIT)
index 770941e..bdf68bf 100644 (file)
@@ -509,6 +509,7 @@ public:
 
     WKView* wkView() const;
     void intrinsicContentSizeDidChange(const WebCore::IntSize& intrinsicContentSize);
+    CGRect boundsOfLayerInLayerBackedWindowCoordinates(CALayer *) const;
 #endif
 #endif // PLATFORM(COCOA)
 #if PLATFORM(EFL)
index 75eb214..a7a2e2f 100644 (file)
@@ -108,7 +108,9 @@ private:
     virtual WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) = 0;
     virtual WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) = 0;
 #endif
-        
+
+    CGRect boundsOfLayerInLayerBackedWindowCoordinates(CALayer *layer) const;
+
     virtual void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled);
 
     virtual PassRefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy*);
index 3c96e7e..68102c1 100644 (file)
@@ -742,6 +742,14 @@ void PageClientImpl::removeNavigationGestureSnapshot()
     [m_wkView _removeNavigationGestureSnapshot];
 }
 
+CGRect PageClientImpl::boundsOfLayerInLayerBackedWindowCoordinates(CALayer *layer) const
+{
+    CALayer *windowContentLayer = static_cast<NSView *>(m_wkView.window.contentView).layer;
+    ASSERT(windowContentLayer);
+
+    return [windowContentLayer convertRect:layer.bounds fromLayer:layer];
+}
+
 } // namespace WebKit
 
 #endif // PLATFORM(MAC)
index 8435754..b3906dd 100644 (file)
@@ -100,6 +100,7 @@ public:
     void setCustomSwipeViews(Vector<RetainPtr<NSView>> views) { m_customSwipeViews = WTF::move(views); }
     void setCustomSwipeViewsTopContentInset(float topContentInset) { m_customSwipeViewsTopContentInset = topContentInset; }
     WebCore::FloatRect windowRelativeBoundsForCustomSwipeViews() const;
+    void setDidMoveSwipeSnapshotCallback(void(^)(CGRect));
 
     void endActiveGesture();
 
@@ -148,6 +149,7 @@ private:
     CALayer *determineSnapshotLayerParent() const;
     CALayer *determineLayerAdjacentToSnapshotForParent(SwipeDirection, CALayer *snapshotLayerParent) const;
     void applyDebuggingPropertiesToSwipeViews();
+    void didMoveSwipeSnapshotLayer();
 #endif
 
     WebPageProxy& m_webPageProxy;
@@ -189,6 +191,8 @@ private:
     SwipeDirection m_pendingSwipeDirection;
     WebCore::FloatSize m_cumulativeDeltaForPendingSwipe;
 
+    void (^m_didMoveSwipeSnapshotCallback)(CGRect);
+
     bool m_shouldIgnorePinnedState;
 
     bool m_swipeWaitingForVisuallyNonEmptyLayout;
index 041d521..9b71b9b 100644 (file)
@@ -106,6 +106,7 @@ ViewGestureController::ViewGestureController(WebPageProxy& webPageProxy)
     , m_swipeTransitionStyle(SwipeTransitionStyle::Overlap)
     , m_customSwipeViewsTopContentInset(0)
     , m_pendingSwipeReason(PendingSwipeReason::None)
+    , m_didMoveSwipeSnapshotCallback(nullptr)
     , m_shouldIgnorePinnedState(false)
     , m_swipeWaitingForVisuallyNonEmptyLayout(false)
     , m_swipeWaitingForRenderTreeSizeThreshold(false)
@@ -123,6 +124,11 @@ ViewGestureController::~ViewGestureController()
     if (m_activeGestureType == ViewGestureType::Swipe)
         removeSwipeSnapshot();
 
+    if (m_didMoveSwipeSnapshotCallback) {
+        Block_release(m_didMoveSwipeSnapshotCallback);
+        m_didMoveSwipeSnapshotCallback = nullptr;
+    }
+
     m_webPageProxy.process().removeMessageReceiver(Messages::ViewGestureController::messageReceiverName(), m_webPageProxy.pageID());
 }
 
@@ -315,6 +321,13 @@ bool ViewGestureController::deltaIsSufficientToBeginSwipe(NSEvent *event)
     return true;
 }
 
+void ViewGestureController::setDidMoveSwipeSnapshotCallback(void(^callback)(CGRect))
+{
+    if (m_didMoveSwipeSnapshotCallback)
+        Block_release(m_didMoveSwipeSnapshotCallback);
+    m_didMoveSwipeSnapshotCallback = Block_copy(callback);
+}
+
 bool ViewGestureController::handleScrollWheelEvent(NSEvent *event)
 {
     if (event.phase == NSEventPhaseEnded) {
@@ -595,6 +608,8 @@ void ViewGestureController::beginSwipeGesture(WebBackForwardListItem* targetItem
         [snapshotLayerParent insertSublayer:m_swipeLayer.get() below:layerAdjacentToSnapshot];
     else
         [snapshotLayerParent insertSublayer:m_swipeLayer.get() above:layerAdjacentToSnapshot];
+
+    didMoveSwipeSnapshotLayer();
 }
 
 void ViewGestureController::handleSwipeGesture(WebBackForwardListItem* targetItem, double progress, SwipeDirection direction)
@@ -613,8 +628,10 @@ void ViewGestureController::handleSwipeGesture(WebBackForwardListItem* targetIte
     double swipingLayerOffset = floor(width * progress);
 
     if (m_swipeTransitionStyle == SwipeTransitionStyle::Overlap) {
-        if (direction == SwipeDirection::Right)
+        if (direction == SwipeDirection::Right) {
             [m_swipeLayer setTransform:CATransform3DMakeTranslation(width + swipingLayerOffset, 0, 0)];
+            didMoveSwipeSnapshotLayer();
+        }
     } else if (m_swipeTransitionStyle == SwipeTransitionStyle::Push)
         [m_swipeLayer setTransform:CATransform3DMakeTranslation((direction == SwipeDirection::Left ? -width : width) + swipingLayerOffset, 0, 0)];
 
@@ -627,6 +644,14 @@ void ViewGestureController::handleSwipeGesture(WebBackForwardListItem* targetIte
     }
 }
 
+void ViewGestureController::didMoveSwipeSnapshotLayer()
+{
+    if (!m_didMoveSwipeSnapshotCallback)
+        return;
+
+    m_didMoveSwipeSnapshotCallback(m_webPageProxy.boundsOfLayerInLayerBackedWindowCoordinates(m_swipeLayer.get()));
+}
+
 void ViewGestureController::endSwipeGesture(WebBackForwardListItem* targetItem, bool cancelled)
 {
     ASSERT(m_activeGestureType == ViewGestureType::Swipe);
index 63d42c5..115cd11 100644 (file)
@@ -663,6 +663,11 @@ void WebPageProxy::showSelectionServiceMenu(const IPC::DataReference& selectionA
 }
 #endif
 
+CGRect WebPageProxy::boundsOfLayerInLayerBackedWindowCoordinates(CALayer *layer) const
+{
+    return m_pageClient.boundsOfLayerInLayerBackedWindowCoordinates(layer);
+}
+
 } // namespace WebKit
 
 #endif // PLATFORM(MAC)