chrome_render_widget_host_view_mac_history_swiper.h revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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 { 20 21enum NavigationDirection { 22 kBackwards = 0, 23 kForwards, 24}; 25 26enum GestureHandledState { 27 kPending, // Still waiting to determine whether the gesture was handled. 28 kHandled, // At least 1 event in the gesture was handled by blink. 29 kUnhandled, // No events so far have been handled by blink. 30}; 31 32} // history_swiper 33 34// Responsible for maintaining state for 2-finger swipe history navigation. 35// Relevant blink/NSWindow touch events must be passed to this class. 36// We want to be able to cancel history swipes if the user's swipe has a lot of 37// vertical motion. The API [NSEvent trackSwipeEventWithOptions] doesn't give 38// vertical swipe distance, and it swallows the touch events so that we can't 39// independently gather them either. Instead of using that api, we manually 40// track all touch events using the low level APIs touches*WithEvent: 41@class HistoryOverlayController; 42@interface HistorySwiper : NSObject { 43 @private 44 // Whether blink has handled the gesture. This enum gets reset to kPending 45 // whenever a new gesture starts. History swiping is only enabled if blink 46 // has never handled any of the events in the gesture. 47 history_swiper::GestureHandledState gestureHandledState_; 48 49 // This controller will exist if and only if the UI is in history swipe mode. 50 HistoryOverlayController* historyOverlay_; 51 // Each gesture received by the window is given a unique id. 52 // The id is monotonically increasing. 53 int currentGestureId_; 54 // The location of the fingers when the gesture started. 55 NSPoint gestureStartPoint_; 56 // The current location of the fingers in the gesture. 57 NSPoint gestureCurrentPoint_; 58 // A flag that indicates that there is an ongoing gesture. 59 // The method [NSEvent touchesMatchingPhase:inView:] is only valid for events 60 // that are part of a gesture. 61 BOOL inGesture_; 62 // Each time a new gesture begins, we must get a new start point. 63 // This ivar determines whether the start point is valid. 64 int gestureStartPointValid_; 65 // The id of the last gesture that we processed as a history swipe. 66 int lastProcessedGestureId_; 67 // A flag that indicates that we cancelled the history swipe for the current 68 // gesture. 69 BOOL historySwipeCancelled_; 70 // A flag that indicates the user's intended direction with the history swipe. 71 history_swiper::NavigationDirection historySwipeDirection_; 72 // A flag that indicates whether the gesture has its direction inverted. 73 BOOL historySwipeDirectionInverted_; 74 75 id<HistorySwiperDelegate> delegate_; 76 77 // Magic mouse and touchpad swipe events are identical except magic mouse 78 // events do not generate NSTouch callbacks. Since we rely on NSTouch 79 // callbacks to determine vertical scrolling, magic mouse swipe events use an 80 // entirely different set of logic. 81 // 82 // The two event types do not play well together. Just calling the API 83 // `[NSEvent trackSwipeEventWithOptions:]` will block touches{Began, Moved, *} 84 // callbacks for a non-deterministic period of time (even after the swipe has 85 // completed). 86 BOOL receivedTouch_; 87 // Cumulative scroll delta since scroll gesture start. Only valid during 88 // scroll gesture handling. Used for history swiping. 89 NSSize mouseScrollDelta_; 90} 91 92// Many event types are passed in, but the only one we care about is 93// NSScrollWheel. We look at the phase to determine whether to trigger history 94// swiping 95- (BOOL)handleEvent:(NSEvent*)event; 96- (void)gotWheelEventConsumed:(BOOL)consumed; 97 98// The event passed in is a gesture event, and has touch data associated with 99// the trackpad. 100- (void)touchesBeganWithEvent:(NSEvent*)event; 101- (void)touchesMovedWithEvent:(NSEvent*)event; 102- (void)touchesCancelledWithEvent:(NSEvent*)event; 103- (void)touchesEndedWithEvent:(NSEvent*)event; 104- (void)beginGestureWithEvent:(NSEvent*)event; 105- (void)endGestureWithEvent:(NSEvent*)event; 106 107// These methods control whether a given view is allowed to rubberband in the 108// given direction. This is inversely related to whether the view is allowed to 109// 2-finger history swipe in the given direction. 110- (BOOL)canRubberbandLeft:(NSView*)view; 111- (BOOL)canRubberbandRight:(NSView*)view; 112 113// Designated initializer. 114- (id)initWithDelegate:(id<HistorySwiperDelegate>)delegate; 115 116@property (nonatomic, assign) id<HistorySwiperDelegate> delegate; 117 118@end 119 120// Exposed only for unit testing, do not call directly. 121@interface HistorySwiper (PrivateExposedForTesting) 122+ (void)resetMagicMouseState; 123@end 124 125#endif // CHROME_BROWSER_RENDERER_HOST_CHROME_RENDER_WIDGET_HOST_VIEW_MAC_HISTORY_SWIPER_ 126