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_) |