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

Unified Diff: chrome/browser/ui/cocoa/browser_window_controller.mm

Issue 7488023: [Mac] Add two-finger gesture support for Lion, which respects the system preference. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 5 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/ui/cocoa/browser_window_controller.mm
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm
index e1d8109199c0f37b0dae5e53b03e584bb728429c..70ed3644d5df0888278302440d4a2d64cb72b7dd 100644
--- a/chrome/browser/ui/cocoa/browser_window_controller.mm
+++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -5,6 +5,7 @@
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#include <Carbon/Carbon.h>
+#include <numeric>
#include "base/command_line.h"
#include "base/mac/mac_util.h"
@@ -141,7 +142,6 @@
// longer indicate that the window is shrinking from an apparent zoomed state)
// and if it's set we continue to constrain the resize.
-
@interface NSWindow (NSPrivateApis)
// Note: These functions are private, use -[NSObject respondsToSelector:]
// before calling them.
@@ -1705,6 +1705,71 @@ typedef NSInteger NSWindowAnimationBehavior;
- (void)beginGestureWithEvent:(NSEvent*)event {
totalMagnifyGestureAmount_ = 0;
currentZoomStepDelta_ = 0;
+
+ // On Lion, there's support controlled by a System Preference for two- and
+ // three-finger navigational gestures. If set to allow three-finger gestures,
+ // the system gesture recognizer will automatically call |-swipeWithEvent:|
+ // and that will be handled as it would be on Snow Leopard. The two-finger
+ // gesture does not do this, so it must be manually recogniezd. See the note
Nico 2011/07/22 20:21:14 recognized mnemonic: "i before e except around z"
Robert Sesek 2011/07/22 20:26:23 I fixed sooo many typos before I uploaded this. I'
+ // inside |-recognizeTwoFingerGestures| for detailed information on the
+ // interaction of the different preferences.
+ NSSet* touches = [event touchesMatchingPhase:NSTouchPhaseAny
+ inView:nil];
+ if ([self recognizeTwoFingerGestures] && [touches count] >= 2) {
+ twoFingerGestureTouches_.reset([[NSMutableDictionary alloc] init]);
+ for (NSTouch* touch in touches) {
+ [twoFingerGestureTouches_ setObject:touch forKey:touch.identity];
+ }
+ }
+}
+
+- (void)endGestureWithEvent:(NSEvent*)event {
+ // This method only needs to process gesture events for two-finger navigation.
+ if (!twoFingerGestureTouches_.get())
+ return;
+
+ // When a multi-touch gesture ends, only one touch will be in the "End" phase.
+ // Other touches will be in "Moved" or "Unknown" phases. So long as one is
+ // ended, which it is by virtue of this method being called, the gesture can
+ // be committed so long as the magnitude is great enough.
Nico 2011/07/22 20:21:14 So two-finger drag followed by lifting one finger
Robert Sesek 2011/07/22 20:26:23 Yeah; it's funky but is also what Safari does. I t
+ NSSet* touches = [event touchesMatchingPhase:NSTouchPhaseAny
+ inView:nil];
+
+ // Store the touch data locally and reset the ivar so that new gestures can
+ // begin.
+ scoped_nsobject<NSDictionary> beginTouches(
+ twoFingerGestureTouches_.release());
+
+ // Construct a vector of magnitudes. Since gesture events do not have the
+ // |-deltaX| property set, this creates the X magnitude for each finger.
+ std::vector<CGFloat> magnitudes;
+ for (NSTouch* touch in touches) {
+ NSTouch* beginTouch = [beginTouches objectForKey:touch.identity];
+ if (!beginTouch)
+ continue;
Nico 2011/07/22 20:21:14 Does this ever happen in practice? I'd assume ever
Robert Sesek 2011/07/22 20:26:23 Yes, it can. You can add new fingers mid-gesture.
+
+ // The |normalizedPosition| scaled from (0,1).
Nico 2011/07/22 20:21:14 "is scaled"?
Robert Sesek 2011/07/22 20:26:23 Done.
+ magnitudes.push_back(touch.normalizedPosition.x -
+ beginTouch.normalizedPosition.x);
+ }
+
+ // Need at least two points to gesture.
+ if (magnitudes.size() < 2)
+ return;
+
+ CGFloat sum = std::accumulate(magnitudes.begin(), magnitudes.end(), 0.0f);
+ int command_id = 0;
+ if (sum > 0.3)
+ command_id = IDC_FORWARD;
+ else if (sum < -0.3)
+ command_id = IDC_BACK;
+ else
+ return;
+
+ if (browser_->command_updater()->IsCommandEnabled(command_id)) {
+ browser_->ExecuteCommandWithDisposition(command_id,
+ event_utils::WindowOpenDispositionFromNSEvent(event));
+ }
}
// Delegate method called when window is resized.

Powered by Google App Engine
This is Rietveld 408576698