Chromium Code Reviews| 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_) |