chrome_render_widget_host_view_mac_history_swiper.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_RENDERER_HOST_CHROME_RENDER_WIDGET_HOST_VIEW_MAC_HISTORY_SWIPER_
6#define CHROME_BROWSER_RENDERER_HOST_CHROME_RENDER_WIDGET_HOST_VIEW_MAC_HISTORY_SWIPER_
7
8#import <Cocoa/Cocoa.h>
9
10@class HistorySwiper;
11@protocol HistorySwiperDelegate
12// Return NO from this method is the view/render_widget_host should not
13// allow history swiping.
14- (BOOL)shouldAllowHistorySwiping;
15// The history overlay is added to the view returning from this method.
16- (NSView*)viewThatWantsHistoryOverlay;
17@end
18
19namespace history_swiper {
20enum NavigationDirection {
21  kBackwards = 0,
22  kForwards,
23};
24} // history_swiper
25
26// Responsible for maintaining state for 2-finger swipe history navigation.
27// Relevant blink/NSWindow touch events must be passed to this class.
28// We want to be able to cancel history swipes if the user's swipe has a lot of
29// vertical motion. The API [NSEvent trackSwipeEventWithOptions] doesn't give
30// vertical swipe distance, and it swallows the touch events so that we can't
31// independently gather them either. Instead of using that api, we manually
32// track all touch events using the low level APIs touches*WithEvent:
33@class HistoryOverlayController;
34@interface HistorySwiper : NSObject {
35 @private
36  // If the viewport is scrolled all the way to the left or right.
37  // Used for history swiping.
38  BOOL isPinnedLeft_;
39  BOOL isPinnedRight_;
40
41  // If the main frame has a horizontal scrollbar.
42  // Used for history swiping.
43  BOOL hasHorizontalScrollbar_;
44
45  // If a scroll event came back unhandled from the renderer. Set to |NO| at
46  // the start of a scroll gesture, and then to |YES| if a scroll event comes
47  // back unhandled from the renderer.
48  // Used for history swiping.
49  BOOL gotUnhandledWheelEvent_;
50
51  // This controller will exist if and only if the UI is in history swipe mode.
52  HistoryOverlayController* historyOverlay_;
53  // Each gesture received by the window is given a unique id.
54  // The id is monotonically increasing.
55  int currentGestureId_;
56  // The location of the fingers when the gesture started.
57  NSPoint gestureStartPoint_;
58  // The current location of the fingers in the gesture.
59  NSPoint gestureCurrentPoint_;
60  // A flag that indicates that there is an ongoing gesture.
61  // The method [NSEvent touchesMatchingPhase:inView:] is only valid for events
62  // that are part of a gesture.
63  BOOL inGesture_;
64  // Each time a new gesture begins, we must get a new start point.
65  // This ivar determines whether the start point is valid.
66  int gestureStartPointValid_;
67  // The id of the last gesture that we processed as a history swipe.
68  int lastProcessedGestureId_;
69  // A flag that indicates that we cancelled the history swipe for the current
70  // gesture.
71  BOOL historySwipeCancelled_;
72  // A flag that indicates the user's intended direction with the history swipe.
73  history_swiper::NavigationDirection historySwipeDirection_;
74  // A flag that indicates whether the gesture has its direction inverted.
75  BOOL historySwipeDirectionInverted_;
76
77  id<HistorySwiperDelegate> delegate_;
78
79  // Magic mouse and touchpad swipe events are identical except magic mouse
80  // events do not generate NSTouch callbacks. Since we rely on NSTouch
81  // callbacks to determine vertical scrolling, magic mouse swipe events use an
82  // entirely different set of logic.
83  //
84  // The two event types do not play well together. Just calling the API
85  // `[NSEvent trackSwipeEventWithOptions:]` will block touches{Began, Moved, *}
86  // callbacks for a non-deterministic period of time (even after the swipe has
87  // completed).
88  BOOL receivedTouch_;
89  // Cumulative scroll delta since scroll gesture start. Only valid during
90  // scroll gesture handling. Used for history swiping.
91  NSSize mouseScrollDelta_;
92}
93
94// Many event types are passed in, but the only one we care about is
95// NSScrollWheel. We look at the phase to determine whether to trigger history
96// swiping
97- (BOOL)handleEvent:(NSEvent*)event;
98- (void)gotUnhandledWheelEvent;
99- (void)scrollOffsetPinnedToLeft:(BOOL)left toRight:(BOOL)right;
100- (void)setHasHorizontalScrollbar:(BOOL)hasHorizontalScrollbar;
101
102// The event passed in is a gesture event, and has touch data associated with
103// the trackpad.
104- (void)touchesBeganWithEvent:(NSEvent*)event;
105- (void)touchesMovedWithEvent:(NSEvent*)event;
106- (void)touchesCancelledWithEvent:(NSEvent*)event;
107- (void)touchesEndedWithEvent:(NSEvent*)event;
108- (void)beginGestureWithEvent:(NSEvent*)event;
109- (void)endGestureWithEvent:(NSEvent*)event;
110
111// Designated initializer.
112- (id)initWithDelegate:(id<HistorySwiperDelegate>)delegate;
113
114@property (nonatomic, assign) id<HistorySwiperDelegate> delegate;
115
116@end
117
118// Exposed only for unit testing, do not call directly.
119@interface HistorySwiper (PrivateExposedForTesting)
120+ (void)resetMagicMouseState;
121@end
122
123#endif // CHROME_BROWSER_RENDERER_HOST_CHROME_RENDER_WIDGET_HOST_VIEW_MAC_HISTORY_SWIPER_
124