Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6450)

Unified Diff: chrome/browser/renderer_host/render_widget_host_view_mac.mm

Issue 7618036: mac: Only let two-finger-scrolling trigger history if web doesn't swallow gesture (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/renderer_host/render_widget_host_view_mac.mm
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
index badd17fd62903c1344f9bf37e044bb381ca78ff9..a6aa41e739153e3c8da6d4ce69c63b305766d36f 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
@@ -20,6 +20,8 @@
#import "chrome/browser/renderer_host/accelerated_plugin_view_mac.h"
#import "chrome/browser/renderer_host/text_input_client_mac.h"
#include "chrome/browser/spellchecker/spellchecker_platform_engine.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
#import "chrome/browser/ui/cocoa/rwhvm_editcommand_helper.h"
#import "chrome/browser/ui/cocoa/view_id_util.h"
#include "chrome/common/render_messages.h"
@@ -56,6 +58,46 @@ using WebKit::WebMouseEvent;
using WebKit::WebMouseWheelEvent;
using WebKit::WebGestureEvent;
+// Forward-declare symbols that are part of the 10.7 SDK.
+#if !defined(MAC_OS_X_VERSION_10_7) || \
+ MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
+
+enum {
+ NSEventPhaseNone = 0, // event not associated with a phase.
+ NSEventPhaseBegan = 0x1 << 0,
+ NSEventPhaseStationary = 0x1 << 1,
+ NSEventPhaseChanged = 0x1 << 2,
+ NSEventPhaseEnded = 0x1 << 3,
+ NSEventPhaseCancelled = 0x1 << 4,
+};
+typedef NSUInteger NSEventPhase;
+
+enum {
+ NSEventSwipeTrackingLockDirection = 0x1 << 0,
+ NSEventSwipeTrackingClampGestureAmount = 0x1 << 1
+};
+typedef NSUInteger NSEventSwipeTrackingOptions;
+
+
+@interface NSEvent(LionAPI)
Robert Sesek 2011/08/15 14:46:27 nit: space before (
Nico 2011/08/15 16:39:46 Done.
+// This is in the appkit 10.7 release notes, but not in
Mark Mentovai 2011/08/15 14:43:57 If this comment were true, this declaration should
Nico 2011/08/15 16:39:46 You're right. It's not documented at http://develo
+// the public nsevent headers?
++ (BOOL)isSwipeTrackingFromScrollEventsEnabled;
+
+- (NSEventPhase)phase;
+- (CGFloat)scrollingDeltaX;
+- (CGFloat)scrollingDeltaY;
+- (void)trackSwipeEventWithOptions:(NSEventSwipeTrackingOptions)options
+ dampenAmountThresholdMin:(CGFloat)minDampenThreshold
+ max:(CGFloat)maxDampenThreshold
+ usingHandler:(void (^)(CGFloat gestureAmount,
Mark Mentovai 2011/08/15 14:43:57 You must #include "chrome/browser/mac/closure_bloc
Nico 2011/08/15 16:39:46 Good news: I was aware of that and thought I had d
+ NSEventPhase phase,
+ BOOL isComplete,
+ BOOL *stop))trackingHandler;
+@end
+
+#endif // 10.7
+
static inline int ToWebKitModifiers(NSUInteger flags) {
int modifiers = 0;
if (flags & NSControlKeyMask) modifiers |= WebInputEvent::ControlKey;
@@ -1018,6 +1060,22 @@ void RenderWidgetHostViewMac::SetVisuallyDeemphasized(const SkColor* color,
// This is not used on mac.
}
+void RenderWidgetHostViewMac::UnhandledWheelEvent(
+ const WebKit::WebMouseWheelEvent& event) {
+ [cocoa_view_ setGotUnhandledWheelEvent:YES];
+}
+
+void RenderWidgetHostViewMac::SetHasHorizontalScrollbar(
+ bool has_horizontal_scrollbar) {
+ [cocoa_view_ setHasHorizontalScrollbar:has_horizontal_scrollbar];
+}
+
+void RenderWidgetHostViewMac::SetScrollOffsetPinning(
+ bool is_pinned_to_left, bool is_pinned_to_right) {
+ [cocoa_view_ setPinnedLeft:is_pinned_to_left];
+ [cocoa_view_ setPinnedRight:is_pinned_to_right];
+}
+
void RenderWidgetHostViewMac::ShutdownHost() {
shutdown_factory_.RevokeAll();
render_widget_host_->Shutdown();
@@ -1101,6 +1159,10 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
@synthesize selectedRange = selectedRange_;
@synthesize markedRange = markedRange_;
+@synthesize gotUnhandledWheelEvent = gotUnhandledWheelEvent_;
+@synthesize isPinnedLeft = isPinnedLeft_;
+@synthesize isPinnedRight = isPinnedRight_;
+@synthesize hasHorizontalScrollbar = hasHorizontalScrollbar_;
- (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r {
self = [super initWithFrame:NSZeroRect];
@@ -1497,9 +1559,72 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
[NSCursor setHiddenUntilMouseMoves:YES];
}
-- (void)scrollWheel:(NSEvent *)theEvent {
+- (void)scrollWheel:(NSEvent*)theEvent {
[self cancelChildPopups];
+ bool canUseLionApis = [theEvent respondsToSelector:@selector(phase)];
Mark Mentovai 2011/08/15 14:43:57 Stick with a BOOL for this one because that’s the
Nico 2011/08/15 16:39:46 Done.
+
+ // Scroll events always go to the web first, and can only trigger history
+ // swiping if they come back unhandled.
+ if (canUseLionApis && [theEvent phase] == NSEventPhaseBegan) {
Mark Mentovai 2011/08/15 14:43:57 Is there any reason you don’t wrap this block and
+ totalScrollDelta_ = NSZeroSize;
+ gotUnhandledWheelEvent_ = false;
Mark Mentovai 2011/08/15 14:43:57 This property is a BOOL, so use NO.
+ }
+
+ if (canUseLionApis && // Must be the first condition!
Mark Mentovai 2011/08/15 14:43:57 (continued from line 1569) …it’d eliminate this t
Robert Sesek 2011/08/15 14:46:27 Is there any reason to not put this and the previo
Nico 2011/08/15 16:39:46 The reason was indentation. I moved the history tr
+ gotUnhandledWheelEvent_ &&
+ [NSEvent isSwipeTrackingFromScrollEventsEnabled] &&
Robert Sesek 2011/08/15 14:46:27 Doing this the proper way means that you can use t
+ [theEvent phase] == NSEventPhaseChanged) {
+ totalScrollDelta_.width += [theEvent scrollingDeltaX];
+ totalScrollDelta_.height += [theEvent scrollingDeltaY];
+
+ bool isHorizontalGesture =
Robert Sesek 2011/08/15 14:46:27 über/optional-nit: Cocoa BOOLs?
+ fabs(totalScrollDelta_.width) > fabs(totalScrollDelta_.height);
Mark Mentovai 2011/08/15 14:43:57 #include <cmath> and use std::abs instead of fabs.
Robert Sesek 2011/08/15 14:46:27 std::abs
Nico 2011/08/15 16:39:46 Done.
+
+ bool isRightScroll = [theEvent scrollingDeltaX] < 0;
+ bool goForward = isRightScroll;
+
+ if (isHorizontalGesture &&
+ // If "forward" is inactive and the user rubber-bands to the right,
+ // "isPinnedLeft" will be false. When the user then rubber-bands to
+ // the left in the same gesture, that should trigger history
+ // immediately if there's no scrollbar, hence the check for
+ // hasHorizontalScrollbar_.
+ // One would think we have to check canGoBack / canGoForward here, but
+ // that's actually done in the renderer
+ // (ChromeClientImpl::shouldRubberBand()), when it decides if it should
+ // rubberband or send back an event unhandled.
+ (((isPinnedLeft_ || !hasHorizontalScrollbar_) && !isRightScroll) ||
Mark Mentovai 2011/08/15 14:43:57 I think you can simplify this entire thing by pull
Nico 2011/08/15 16:39:46 Done.
+ ((isPinnedRight_ || !hasHorizontalScrollbar_) && isRightScroll))) {
+ // The way this api works: gestureAmount is between -1 and 1 (float). If
+ // the user does the gesture for more than about 25% (i.e. < -0.25 or >
+ // 0.25) and then lets go, it is accepted, we get a NSEventPhaseEnded,
+ // and after that the block is called with amounts animating towards 1
+ // (or -1, depending on the direction). If the user lets go below that
+ // threshold, we get NSEventPhaseCancelled, and the amount animates
+ // toward 0.
+ [theEvent trackSwipeEventWithOptions:0
+ dampenAmountThresholdMin:-1
Mark Mentovai 2011/08/15 14:43:57 Nit: align colons.
Mark Mentovai 2011/08/15 14:43:57 Do you know how AppKit uses these values? I suppos
Nico 2011/08/15 16:39:46 Done.
Nico 2011/08/15 16:39:46 I don't really understand what these values do. I
+ max:1
+ usingHandler:^(CGFloat gestureAmount,
+ NSEventPhase phase,
+ BOOL isComplete,
Robert Sesek 2011/08/15 14:46:27 Why do you not reference isComplete in this? Are y
Nico 2011/08/15 16:39:46 Yes. The way this works is that as soon as the use
+ BOOL *stop) {
+ // |gestureAmount| obeys -[NSEvent isDirectionInvertedFromDevice]
+ // automatically.
+ // TODO(thakis): UI.
+ Browser* browser = BrowserList::GetLastActive();
+ if (phase == NSEventPhaseEnded && browser) {
+ if (goForward)
+ browser->GoForward(CURRENT_TAB);
+ else
+ browser->GoBack(CURRENT_TAB);
+ }
+ }];
+ return;
+ }
+ }
+
const WebMouseWheelEvent& event =
WebInputEventFactory::mouseWheelEvent(theEvent, self);
if (renderWidgetHostView_->render_widget_host_)

Powered by Google App Engine
This is Rietveld 408576698