From bd2252ea559db6d95a9eae12913ff4d2e8472c78 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Thu, 21 Jan 2016 09:40:21 -0800 Subject: [PATCH] Extend NativeWindow to track touch-based scroll events on OS X In N1, we want to implement the famous "swipe to archive" action on threads in the user's inbox. Chrome exposes `scroll` and `wheel` events, but these aren't sufficient to implement the interaction because the element needs to "snap" when the user lifts their fingers from the trackpad, not when they / we stop receiving `wheel` / `scroll` events. These events may stop before the user lifts their fingers, or continue after the user has lifted their fingers if they had enough momentum for the gesture to continue. This exposes BrowserWindow `scroll-touch-down` and `scroll-touch-up`, which fire immeditaely when the user touches two fingers to the trackpad, and again when the user lifts their fingers. Combined with the existing wheel event should allow for "swipe-to-archive" and other similar interactions. Note: This is only implemented on Mac OS X and the events don't fire unless you're using a trackpad! Related: #1486, #2683, https://github.com/nylas/N1/issues/541 --- atom/browser/api/atom_api_window.cc | 8 ++++++++ atom/browser/api/atom_api_window.h | 2 ++ atom/browser/native_window.cc | 10 ++++++++++ atom/browser/native_window.h | 2 ++ atom/browser/native_window_mac.mm | 19 +++++++++++++++++++ atom/browser/native_window_observer.h | 2 ++ 6 files changed, 43 insertions(+) diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 09d88ed..ef38490 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -227,6 +227,14 @@ void Window::OnWindowLeaveFullScreen() { Emit("leave-full-screen"); } +void Window::OnWindowScrollTouchUp() { + Emit("scroll-touch-up"); +} + +void Window::OnWindowScrollTouchDown() { + Emit("scroll-touch-down"); +} + void Window::OnWindowEnterHtmlFullScreen() { Emit("enter-html-full-screen"); } diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index d8e2596..12eec04 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -65,6 +65,8 @@ class Window : public mate::TrackableObject, void OnWindowResize() override; void OnWindowMove() override; void OnWindowMoved() override; + void OnWindowScrollTouchUp() override; + void OnWindowScrollTouchDown() override; void OnWindowEnterFullScreen() override; void OnWindowLeaveFullScreen() override; void OnWindowEnterHtmlFullScreen() override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 4df4b49..8935438 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -442,6 +442,16 @@ void NativeWindow::NotifyWindowEnterFullScreen() { OnWindowEnterFullScreen()); } +void NativeWindow::NotifyWindowScrollTouchUp() { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnWindowScrollTouchUp()); +} + +void NativeWindow::NotifyWindowScrollTouchDown() { + FOR_EACH_OBSERVER(NativeWindowObserver, observers_, + OnWindowScrollTouchDown()); +} + void NativeWindow::NotifyWindowLeaveFullScreen() { FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnWindowLeaveFullScreen()); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 0ccf3df..f1dac26 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -205,6 +205,8 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowMove(); void NotifyWindowResize(); void NotifyWindowMoved(); + void NotifyWindowScrollTouchUp(); + void NotifyWindowScrollTouchDown(); void NotifyWindowEnterFullScreen(); void NotifyWindowLeaveFullScreen(); void NotifyWindowEnterHtmlFullScreen(); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index f128f3b..198a78e 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -490,6 +490,25 @@ NativeWindowMac::NativeWindowMac( NSView* view = inspectable_web_contents()->GetView()->GetNativeView(); [view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + BOOL __block down = NO; + [NSEvent addLocalMonitorForEventsMatchingMask:NSScrollWheelMask handler:^NSEvent * _Nullable(NSEvent * event) { + if (![window_ isKeyWindow]) + return event; + + if (!web_contents) + return event; + + if (!down && (([event phase] == NSEventPhaseMayBegin) || ([event phase] == NSEventPhaseBegan))) { + this->NotifyWindowScrollTouchDown(); + down = YES; + } + if (down && (([event phase] == NSEventPhaseEnded) || ([event phase] == NSEventPhaseCancelled))) { + this->NotifyWindowScrollTouchUp(); + down = NO; + } + return event; + }]; + InstallView(); } diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index ce2d41c..b7ba9d7 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -50,6 +50,8 @@ class NativeWindowObserver { virtual void OnWindowResize() {} virtual void OnWindowMove() {} virtual void OnWindowMoved() {} + virtual void OnWindowScrollTouchUp() {} + virtual void OnWindowScrollTouchDown() {} virtual void OnWindowEnterFullScreen() {} virtual void OnWindowLeaveFullScreen() {} virtual void OnWindowEnterHtmlFullScreen() {} -- 2.7.4