1/* 2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef ViewGestureController_h 27#define ViewGestureController_h 28 29#include "MessageReceiver.h" 30#include "SameDocumentNavigationType.h" 31#include "WeakObjCPtr.h" 32#include <WebCore/FloatRect.h> 33#include <wtf/RetainPtr.h> 34#include <wtf/RunLoop.h> 35 36OBJC_CLASS CALayer; 37 38#if PLATFORM(IOS) 39OBJC_CLASS UIView; 40OBJC_CLASS WKSwipeTransitionController; 41OBJC_CLASS WKWebView; 42OBJC_CLASS _UIViewControllerTransitionContext; 43OBJC_CLASS _UINavigationInteractiveTransitionBase; 44#else 45OBJC_CLASS NSEvent; 46OBJC_CLASS NSView; 47OBJC_CLASS WKSwipeCancellationTracker; 48#endif 49 50namespace WebCore { 51class IOSurface; 52} 53 54namespace WebKit { 55 56class ViewSnapshot; 57class WebBackForwardListItem; 58class WebPageProxy; 59 60class ViewGestureController : private IPC::MessageReceiver { 61 WTF_MAKE_NONCOPYABLE(ViewGestureController); 62public: 63 ViewGestureController(WebPageProxy&); 64 ~ViewGestureController(); 65 66 enum class ViewGestureType { 67 None, 68#if PLATFORM(MAC) 69 Magnification, 70 SmartMagnification, 71#endif 72 Swipe 73 }; 74 75 enum class SwipeTransitionStyle { 76 Overlap, 77 Push 78 }; 79 80 enum class SwipeDirection { 81 Left, 82 Right 83 }; 84 85 enum class PendingSwipeReason { 86 None, 87 WebCoreMayScroll, 88 InsufficientMagnitude 89 }; 90 91#if PLATFORM(MAC) 92 double magnification() const; 93 94 void handleMagnificationGesture(double scale, WebCore::FloatPoint origin); 95 void handleSmartMagnificationGesture(WebCore::FloatPoint origin); 96 97 bool handleScrollWheelEvent(NSEvent *); 98 void wheelEventWasNotHandledByWebCore(NSEvent *); 99 100 void setCustomSwipeViews(Vector<RetainPtr<NSView>> views) { m_customSwipeViews = WTF::move(views); } 101 void setCustomSwipeViewsTopContentInset(float topContentInset) { m_customSwipeViewsTopContentInset = topContentInset; } 102 WebCore::FloatRect windowRelativeBoundsForCustomSwipeViews() const; 103 void setDidMoveSwipeSnapshotCallback(void(^)(CGRect)); 104 105 void endActiveGesture(); 106 107 bool shouldIgnorePinnedState() { return m_shouldIgnorePinnedState; } 108 void setShouldIgnorePinnedState(bool ignore) { m_shouldIgnorePinnedState = ignore; } 109 110 void didFirstVisuallyNonEmptyLayoutForMainFrame(); 111 void didFinishLoadForMainFrame(); 112 void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType); 113#else 114 void installSwipeHandler(UIView *gestureRecognizerView, UIView *swipingView); 115 void setAlternateBackForwardListSourceView(WKWebView *); 116 bool canSwipeInDirection(SwipeDirection); 117 void beginSwipeGesture(_UINavigationInteractiveTransitionBase *, SwipeDirection); 118 void endSwipeGesture(WebBackForwardListItem* targetItem, _UIViewControllerTransitionContext *, bool cancelled); 119 void willCommitPostSwipeTransitionLayerTree(bool); 120 void setRenderTreeSize(uint64_t); 121#endif 122 123 void removeSwipeSnapshot(); 124 125private: 126 // IPC::MessageReceiver. 127 virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; 128 129 void swipeSnapshotWatchdogTimerFired(); 130 131#if PLATFORM(MAC) 132 // Message handlers. 133 void didCollectGeometryForMagnificationGesture(WebCore::FloatRect visibleContentBounds, bool frameHandlesMagnificationGesture); 134 void didCollectGeometryForSmartMagnificationGesture(WebCore::FloatPoint origin, WebCore::FloatRect renderRect, WebCore::FloatRect visibleContentBounds, bool isReplacedElement, double viewportMinimumScale, double viewportMaximumScale); 135 void didHitRenderTreeSizeThreshold(); 136 void removeSwipeSnapshotAfterRepaint(); 137 void activeLoadMonitoringTimerFired(); 138 139 void endMagnificationGesture(); 140 WebCore::FloatPoint scaledMagnificationOrigin(WebCore::FloatPoint origin, double scale); 141 142 void trackSwipeGesture(NSEvent *, SwipeDirection); 143 void beginSwipeGesture(WebBackForwardListItem* targetItem, SwipeDirection); 144 void handleSwipeGesture(WebBackForwardListItem* targetItem, double progress, SwipeDirection); 145 void endSwipeGesture(WebBackForwardListItem* targetItem, bool cancelled); 146 bool deltaIsSufficientToBeginSwipe(NSEvent *); 147 bool scrollEventCanBecomeSwipe(NSEvent *, SwipeDirection&); 148 bool shouldUseSnapshotForSize(ViewSnapshot&, WebCore::FloatSize swipeLayerSize, float topContentInset); 149 150 CALayer *determineSnapshotLayerParent() const; 151 CALayer *determineLayerAdjacentToSnapshotForParent(SwipeDirection, CALayer *snapshotLayerParent) const; 152 void applyDebuggingPropertiesToSwipeViews(); 153 void didMoveSwipeSnapshotLayer(); 154#endif 155 156 WebPageProxy& m_webPageProxy; 157 ViewGestureType m_activeGestureType; 158 159 RunLoop::Timer<ViewGestureController> m_swipeWatchdogTimer; 160 161#if USE(IOSURFACE) 162 RefPtr<WebCore::IOSurface> m_currentSwipeSnapshotSurface; 163#endif 164 165#if PLATFORM(MAC) 166 RunLoop::Timer<ViewGestureController> m_swipeWatchdogAfterFirstVisuallyNonEmptyLayoutTimer; 167 RunLoop::Timer<ViewGestureController> m_swipeActiveLoadMonitoringTimer; 168 169 double m_magnification; 170 WebCore::FloatPoint m_magnificationOrigin; 171 172 WebCore::FloatRect m_lastSmartMagnificationUnscaledTargetRect; 173 bool m_lastMagnificationGestureWasSmartMagnification; 174 WebCore::FloatPoint m_lastSmartMagnificationOrigin; 175 176 WebCore::FloatRect m_visibleContentRect; 177 bool m_visibleContentRectIsValid; 178 bool m_frameHandlesMagnificationGesture; 179 180 RetainPtr<WKSwipeCancellationTracker> m_swipeCancellationTracker; 181 RetainPtr<CALayer> m_swipeLayer; 182 RetainPtr<CALayer> m_swipeSnapshotLayer; 183 Vector<RetainPtr<CALayer>> m_currentSwipeLiveLayers; 184 185 SwipeTransitionStyle m_swipeTransitionStyle; 186 Vector<RetainPtr<NSView>> m_customSwipeViews; 187 float m_customSwipeViewsTopContentInset; 188 WebCore::FloatRect m_currentSwipeCustomViewBounds; 189 190 // If we need to wait for content to decide if it is going to consume 191 // the scroll event that would have started a swipe, we'll fill these in. 192 PendingSwipeReason m_pendingSwipeReason; 193 SwipeDirection m_pendingSwipeDirection; 194 WebCore::FloatSize m_cumulativeDeltaForPendingSwipe; 195 196 void (^m_didMoveSwipeSnapshotCallback)(CGRect); 197 198 bool m_shouldIgnorePinnedState; 199 200 bool m_swipeWaitingForVisuallyNonEmptyLayout; 201 bool m_swipeWaitingForRenderTreeSizeThreshold; 202 bool m_swipeWaitingForRepaint; 203 bool m_swipeInProgress; 204#else 205 UIView *m_liveSwipeView; 206 RetainPtr<UIView> m_liveSwipeViewClippingView; 207 RetainPtr<UIView> m_snapshotView; 208 RetainPtr<UIView> m_transitionContainerView; 209 RetainPtr<WKSwipeTransitionController> m_swipeInteractiveTransitionDelegate; 210 uint64_t m_snapshotRemovalTargetRenderTreeSize; 211 bool m_shouldRemoveSnapshotWhenTargetRenderTreeSizeHit; 212 WeakObjCPtr<WKWebView> m_alternateBackForwardListSourceView; 213 RefPtr<WebPageProxy> m_webPageProxyForBackForwardListForCurrentSwipe; 214#endif 215}; 216 217} // namespace WebKit 218 219#endif // ViewGestureController_h 220