64fd133dd5c0b5508b0f33ee2ef2d6e0e3ffd705
[WebKit-https.git] / Source / WebKit2 / UIProcess / mac / ViewGestureController.h
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
36 #define ENABLE_VIEW_GESTURE_CONTROLLER_TRACING 1
37
38 OBJC_CLASS CALayer;
39
40 #if PLATFORM(IOS)
41 OBJC_CLASS UIView;
42 OBJC_CLASS WKSwipeTransitionController;
43 OBJC_CLASS WKWebView;
44 OBJC_CLASS _UINavigationInteractiveTransitionBase;
45 OBJC_CLASS _UIViewControllerOneToOneTransitionContext;
46 OBJC_CLASS _UIViewControllerTransitionContext;
47 #else
48 OBJC_CLASS NSEvent;
49 OBJC_CLASS NSView;
50 OBJC_CLASS WKSwipeCancellationTracker;
51 #endif
52
53 namespace WebCore {
54 class IOSurface;
55 }
56
57 namespace WebKit {
58
59 class ViewSnapshot;
60 class WebBackForwardListItem;
61 class WebPageProxy;
62
63 class ViewGestureController : private IPC::MessageReceiver {
64     WTF_MAKE_NONCOPYABLE(ViewGestureController);
65 public:
66     ViewGestureController(WebPageProxy&);
67     ~ViewGestureController();
68     
69     enum class ViewGestureType {
70         None,
71 #if PLATFORM(MAC)
72         Magnification,
73         SmartMagnification,
74 #endif
75         Swipe
76     };
77     
78     enum class SwipeTransitionStyle {
79         Overlap,
80         Push
81     };
82     
83     enum class SwipeDirection {
84         Left,
85         Right
86     };
87
88     enum class PendingSwipeReason {
89         None,
90         WebCoreMayScroll,
91         InsufficientMagnitude
92     };
93     
94 #if PLATFORM(MAC)
95     double magnification() const;
96
97     void handleMagnificationGesture(double scale, WebCore::FloatPoint origin);
98     void handleSmartMagnificationGesture(WebCore::FloatPoint origin);
99
100     bool handleScrollWheelEvent(NSEvent *);
101     void wheelEventWasNotHandledByWebCore(NSEvent *);
102
103     void setCustomSwipeViews(Vector<RetainPtr<NSView>> views) { m_customSwipeViews = WTF::move(views); }
104     void setCustomSwipeViewsTopContentInset(float topContentInset) { m_customSwipeViewsTopContentInset = topContentInset; }
105     WebCore::FloatRect windowRelativeBoundsForCustomSwipeViews() const;
106     void setDidMoveSwipeSnapshotCallback(void(^)(CGRect));
107
108     void endActiveGesture();
109
110     bool shouldIgnorePinnedState() { return m_shouldIgnorePinnedState; }
111     void setShouldIgnorePinnedState(bool ignore) { m_shouldIgnorePinnedState = ignore; }
112
113     void didFirstVisuallyNonEmptyLayoutForMainFrame();
114     void didFinishLoadForMainFrame();
115     void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType);
116 #else
117     void installSwipeHandler(UIView *gestureRecognizerView, UIView *swipingView);
118     void setAlternateBackForwardListSourceView(WKWebView *);
119     bool canSwipeInDirection(SwipeDirection);
120     void beginSwipeGesture(_UINavigationInteractiveTransitionBase *, SwipeDirection);
121     void endSwipeGesture(WebBackForwardListItem* targetItem, _UIViewControllerTransitionContext *, bool cancelled);
122     void willCommitPostSwipeTransitionLayerTree(bool);
123     void setRenderTreeSize(uint64_t);
124 #endif
125
126     void removeSwipeSnapshot();
127
128 private:
129     // IPC::MessageReceiver.
130     virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override;
131
132     void swipeSnapshotWatchdogTimerFired();
133
134 #if PLATFORM(MAC)
135     // Message handlers.
136     void didCollectGeometryForMagnificationGesture(WebCore::FloatRect visibleContentBounds, bool frameHandlesMagnificationGesture);
137     void didCollectGeometryForSmartMagnificationGesture(WebCore::FloatPoint origin, WebCore::FloatRect renderRect, WebCore::FloatRect visibleContentBounds, bool isReplacedElement, double viewportMinimumScale, double viewportMaximumScale);
138     void didHitRenderTreeSizeThreshold();
139     void removeSwipeSnapshotAfterRepaint();
140     void activeLoadMonitoringTimerFired();
141
142     void endMagnificationGesture();
143     WebCore::FloatPoint scaledMagnificationOrigin(WebCore::FloatPoint origin, double scale);
144
145     void trackSwipeGesture(NSEvent *, SwipeDirection);
146     void beginSwipeGesture(WebBackForwardListItem* targetItem, SwipeDirection);
147     void handleSwipeGesture(WebBackForwardListItem* targetItem, double progress, SwipeDirection);
148     void endSwipeGesture(WebBackForwardListItem* targetItem, bool cancelled);
149     bool deltaIsSufficientToBeginSwipe(NSEvent *);
150     bool scrollEventCanBecomeSwipe(NSEvent *, SwipeDirection&);
151     bool shouldUseSnapshotForSize(ViewSnapshot&, WebCore::FloatSize swipeLayerSize, float topContentInset);
152
153     CALayer *determineSnapshotLayerParent() const;
154     CALayer *determineLayerAdjacentToSnapshotForParent(SwipeDirection, CALayer *snapshotLayerParent) const;
155     void applyDebuggingPropertiesToSwipeViews();
156     void didMoveSwipeSnapshotLayer();
157 #endif
158
159     WebPageProxy& m_webPageProxy;
160     ViewGestureType m_activeGestureType;
161
162     RunLoop::Timer<ViewGestureController> m_swipeWatchdogTimer;
163
164 #if USE(IOSURFACE)
165     RefPtr<WebCore::IOSurface> m_currentSwipeSnapshotSurface;
166 #endif
167
168 #if PLATFORM(MAC)
169     RunLoop::Timer<ViewGestureController> m_swipeWatchdogAfterFirstVisuallyNonEmptyLayoutTimer;
170     RunLoop::Timer<ViewGestureController> m_swipeActiveLoadMonitoringTimer;
171
172     double m_magnification;
173     WebCore::FloatPoint m_magnificationOrigin;
174
175     WebCore::FloatRect m_lastSmartMagnificationUnscaledTargetRect;
176     bool m_lastMagnificationGestureWasSmartMagnification;
177     WebCore::FloatPoint m_lastSmartMagnificationOrigin;
178
179     WebCore::FloatRect m_visibleContentRect;
180     bool m_visibleContentRectIsValid;
181     bool m_frameHandlesMagnificationGesture;
182
183     RetainPtr<WKSwipeCancellationTracker> m_swipeCancellationTracker;
184     RetainPtr<CALayer> m_swipeLayer;
185     RetainPtr<CALayer> m_swipeSnapshotLayer;
186     Vector<RetainPtr<CALayer>> m_currentSwipeLiveLayers;
187
188     SwipeTransitionStyle m_swipeTransitionStyle;
189     Vector<RetainPtr<NSView>> m_customSwipeViews;
190     float m_customSwipeViewsTopContentInset;
191     WebCore::FloatRect m_currentSwipeCustomViewBounds;
192
193     // If we need to wait for content to decide if it is going to consume
194     // the scroll event that would have started a swipe, we'll fill these in.
195     PendingSwipeReason m_pendingSwipeReason;
196     SwipeDirection m_pendingSwipeDirection;
197     WebCore::FloatSize m_cumulativeDeltaForPendingSwipe;
198
199     void (^m_didMoveSwipeSnapshotCallback)(CGRect);
200
201     bool m_shouldIgnorePinnedState;
202
203     bool m_swipeWaitingForVisuallyNonEmptyLayout;
204     bool m_swipeWaitingForRenderTreeSizeThreshold;
205     bool m_swipeWaitingForRepaint;
206     bool m_swipeInProgress;
207 #else    
208     UIView *m_liveSwipeView;
209     RetainPtr<UIView> m_liveSwipeViewClippingView;
210     RetainPtr<UIView> m_snapshotView;
211     RetainPtr<UIView> m_transitionContainerView;
212     RetainPtr<WKSwipeTransitionController> m_swipeInteractiveTransitionDelegate;
213     RetainPtr<_UIViewControllerOneToOneTransitionContext> m_swipeTransitionContext;
214     uint64_t m_snapshotRemovalTargetRenderTreeSize;
215     bool m_shouldRemoveSnapshotWhenTargetRenderTreeSizeHit;
216     WeakObjCPtr<WKWebView> m_alternateBackForwardListSourceView;
217     RefPtr<WebPageProxy> m_webPageProxyForBackForwardListForCurrentSwipe;
218     uint64_t m_gesturePendingSnapshotRemoval;
219 #if ENABLE(VIEW_GESTURE_CONTROLLER_TRACING)
220     Vector<String> m_logEntries;
221 #endif
222 #endif
223 };
224
225 } // namespace WebKit
226
227 #endif // ViewGestureController_h