summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorerikchen@google.com <erikchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-11 02:48:44 +0000
committererikchen@google.com <erikchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-11 02:48:44 +0000
commit756d4dd9706d14afdc2465260b20e047b01deab2 (patch)
tree72c369b3b24d085d5bdc78d453c3b27e4aac21dd /content
parentd66e2fd0194cf3a5155dd606c416e20107b9b21a (diff)
downloadchromium_src-756d4dd9706d14afdc2465260b20e047b01deab2.zip
chromium_src-756d4dd9706d14afdc2465260b20e047b01deab2.tar.gz
chromium_src-756d4dd9706d14afdc2465260b20e047b01deab2.tar.bz2
Mac: History swiping can be cancelled with vertical motion.
Users accidentally initiate history swiping (which requires horizontal motion) when they intend to scroll content (which requires vertical motion). Once the browser enters history swiping mode, subsequent vertical motions are discarded. This change causes the browser to continue to observe vertical motions, and if the user's horizontal swipe gains sufficient vertical motion, breaks out of history swipe mode and into content swipe mode. This CL enables touch events for the RWHVMac. I stopped using the API trackSwipeEventWithOptions, since the block callback discards vertical motion, and the method prevents the window from receiving touches. Instead, I record all touches received by the window, and manually track the user's horizontal and/or vertical motion. Another independent change is that 2-finger swipe zone required to initiate horizontal swipe mode was reduced. (Diagonal 45 degree swipes now initiate content scrolling, rather than history swiping). BUG=138175 TEST=Populate the browser's navigation history by visiting many different urls. Use a 2-finger horizontal swipe on the track pad to begin a back/forward navigation. Without lifting your fingers, swipe vertically. The history swipe should be cancelled, and the content on the page should be scrolled. This change should not have any effect on existing vertical content scrolling. Interesting edge cases: Users use both short horizontal 2-finger flicks, and long horizontal 2-finger swipes to navigate forwards/backwards. This behavior should not be affected. When the content does not occupy the full horizontal space (try reducing the browser window horizontal size by dragging the right side close to the left side), horizontal swipes should swipe the content horizontally, rather than triggering the history-swipe mode. Review URL: https://codereview.chromium.org/87573003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239976 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac.mm63
-rw-r--r--content/browser/renderer_host/render_widget_host_view_mac_unittest.mm6
-rw-r--r--content/public/browser/render_widget_host_view_mac_delegate.h14
3 files changed, 73 insertions, 10 deletions
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index aae648c..9b5de7f 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -2013,7 +2013,6 @@ void RenderWidgetHostViewMac::FrameSwapped() {
// RenderWidgetHostViewCocoa ---------------------------------------------------
@implementation RenderWidgetHostViewCocoa
-
@synthesize selectedRange = selectedRange_;
@synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_;
@synthesize markedRange = markedRange_;
@@ -2022,6 +2021,7 @@ void RenderWidgetHostViewMac::FrameSwapped() {
- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r {
self = [super initWithFrame:NSZeroRect];
if (self) {
+ self.acceptsTouchEvents = YES;
editCommand_helper_.reset(new RenderWidgetHostViewMacEditCommandHelper);
editCommand_helper_->AddEditingSelectorsToClass([self class]);
@@ -2075,8 +2075,8 @@ void RenderWidgetHostViewMac::FrameSwapped() {
}
- (void)scrollOffsetPinnedToLeft:(BOOL)left toRight:(BOOL)right {
- if (delegate_ && [delegate_ respondsToSelector:
- @selector(scrollOffsetPinnedToLeft:toRight:)]) {
+ if (delegate_ && [delegate_
+ respondsToSelector:@selector(scrollOffsetPinnedToLeft:toRight:)]) {
[delegate_ scrollOffsetPinnedToLeft:left toRight:right];
}
}
@@ -2542,6 +2542,47 @@ void RenderWidgetHostViewMac::FrameSwapped() {
}
}
+- (void)beginGestureWithEvent:(NSEvent*)event {
+ [delegate_ beginGestureWithEvent:event];
+}
+- (void)endGestureWithEvent:(NSEvent*)event {
+ [delegate_ endGestureWithEvent:event];
+}
+- (void)touchesMovedWithEvent:(NSEvent*)event {
+ [delegate_ touchesMovedWithEvent:event];
+}
+- (void)touchesBeganWithEvent:(NSEvent*)event {
+ [delegate_ touchesBeganWithEvent:event];
+}
+- (void)touchesCancelledWithEvent:(NSEvent*)event {
+ [delegate_ touchesCancelledWithEvent:event];
+}
+- (void)touchesEndedWithEvent:(NSEvent*)event {
+ [delegate_ touchesEndedWithEvent:event];
+}
+
+// This method handles 2 different types of hardware events.
+// (Apple does not distinguish between them).
+// a. Scrolling the middle wheel of a mouse.
+// b. Swiping on the track pad.
+//
+// This method is responsible for 2 types of behavior:
+// a. Scrolling the content of window.
+// b. Navigating forwards/backwards in history.
+//
+// This is a brief description of the logic:
+// 1. If the content can be scrolled, scroll the content.
+// (This requires a roundtrip to blink to determine whether the content
+// can be scrolled.)
+// Once this logic is triggered, the navigate logic cannot be triggered
+// until the gesture finishes.
+// 2. If the user is making a horizontal swipe, start the navigate
+// forward/backwards UI.
+// Once this logic is triggered, the user can either cancel or complete
+// the gesture. If the user completes the gesture, all remaining touches
+// are swallowed, and not allowed to scroll the content. If the user
+// cancels the gesture, all remaining touches are forwarded to the content
+// scroll logic. The user cannot trigger the navigation logic again.
- (void)scrollWheel:(NSEvent*)event {
if (delegate_ && [delegate_ respondsToSelector:@selector(handleEvent:)]) {
BOOL handled = [delegate_ handleEvent:event];
@@ -2556,13 +2597,14 @@ void RenderWidgetHostViewMac::FrameSwapped() {
if (base::mac::IsOSLionOrLater() && [event phase] == NSEventPhaseBegan &&
!endWheelMonitor_) {
endWheelMonitor_ =
- [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask
- handler:^(NSEvent* blockEvent) {
- [self shortCircuitScrollWheelEvent:blockEvent];
- return blockEvent;
- }];
+ [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask
+ handler:^(NSEvent* blockEvent) {
+ [self shortCircuitScrollWheelEvent:blockEvent];
+ return blockEvent;
+ }];
}
+ // This is responsible for content scrolling!
if (renderWidgetHostView_->render_widget_host_) {
const WebMouseWheelEvent& webEvent =
WebInputEventFactory::mouseWheelEvent(event, self);
@@ -2994,8 +3036,9 @@ void RenderWidgetHostViewMac::FrameSwapped() {
}
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
- if (delegate_ && [delegate_ respondsToSelector:
- @selector(validateUserInterfaceItem:isValidItem:)]) {
+ if (delegate_ &&
+ [delegate_ respondsToSelector:@selector(validateUserInterfaceItem:
+ isValidItem:)]) {
BOOL valid;
BOOL known = [delegate_ validateUserInterfaceItem:item
isValidItem:&valid];
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index 69252d4..2515496 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -83,6 +83,12 @@ typedef NSUInteger NSEventPhase;
- (void)gotUnhandledWheelEvent {
unhandledWheelEventReceived_ = true;
}
+- (void)touchesBeganWithEvent:(NSEvent*)event{}
+- (void)touchesMovedWithEvent:(NSEvent*)event{}
+- (void)touchesCancelledWithEvent:(NSEvent*)event{}
+- (void)touchesEndedWithEvent:(NSEvent*)event{}
+- (void)beginGestureWithEvent:(NSEvent*)event{}
+- (void)endGestureWithEvent:(NSEvent*)event{}
@end
diff --git a/content/public/browser/render_widget_host_view_mac_delegate.h b/content/public/browser/render_widget_host_view_mac_delegate.h
index 4e79fcb..6bcf744 100644
--- a/content/public/browser/render_widget_host_view_mac_delegate.h
+++ b/content/public/browser/render_widget_host_view_mac_delegate.h
@@ -16,6 +16,7 @@
// Like any Objective-C delegate, it is not retained by the delegator object.
// The delegator object will call the -viewGone: method when it is going away.
+@class NSEvent;
@protocol RenderWidgetHostViewMacDelegate
@optional
// Notification that the view is gone.
@@ -41,6 +42,19 @@
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item
isValidItem:(BOOL*)valid;
+@required
+// Notification of when a gesture begins/ends.
+- (void)beginGestureWithEvent:(NSEvent*)event;
+- (void)endGestureWithEvent:(NSEvent*)event;
+
+// This is a low level API which provides touches associated with an event.
+// It is used in conjunction with gestures to determine finger placement
+// on the trackpad.
+- (void)touchesMovedWithEvent:(NSEvent*)event;
+- (void)touchesBeganWithEvent:(NSEvent*)event;
+- (void)touchesCancelledWithEvent:(NSEvent*)event;
+- (void)touchesEndedWithEvent:(NSEvent*)event;
+
@end
#endif // CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_VIEW_MAC_DELEGATE_H_