Index: ash/wm/overview/transparent_activate_window_button.cc |
diff --git a/ash/wm/overview/transparent_activate_window_button.cc b/ash/wm/overview/transparent_activate_window_button.cc |
index 5c6a404f57521155f3e45a4cb4972b12df3c8524..ff0e4842a5a6da89b1f69f295798335ce6b7c866 100644 |
--- a/ash/wm/overview/transparent_activate_window_button.cc |
+++ b/ash/wm/overview/transparent_activate_window_button.cc |
@@ -6,9 +6,11 @@ |
#include <vector> |
+#include "ash/ash_switches.h" |
#include "ash/shell.h" |
#include "ash/shell_window_ids.h" |
#include "ash/wm/overview/transparent_activate_window_button_delegate.h" |
+#include "base/command_line.h" |
#include "ui/events/event.h" |
#include "ui/events/gesture_event_details.h" |
#include "ui/gfx/display.h" |
@@ -22,6 +24,35 @@ namespace ash { |
namespace { |
const char kTransparentButtonName[] = "TransparentButton"; |
+// The default close window distance minimum. |
+const int kDefaultCloseWindowDistanceMinimum = 100; |
+ |
+// The minimum fling velocity which will cause a window to be closed. Unit is |
+// pixels per second. |
+const float kMinimumFlingVelocity = 4000.0f; |
+ |
+// Initializes the event handler transparent window. |
+views::Widget* InitEventHandler(aura::Window* root_window) { |
+ views::Widget* widget = new views::Widget; |
+ views::Widget::InitParams params; |
+ params.type = views::Widget::InitParams::TYPE_POPUP; |
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
+ params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
+ params.accept_events = true; |
+ params.parent = Shell::GetContainer(root_window, |
+ kShellWindowId_OverlayContainer); |
+ widget->set_focus_on_creation(false); |
+ widget->Init(params); |
+ widget->Show(); |
+ |
+ aura::Window* handler = widget->GetNativeWindow(); |
+ handler->parent()->StackChildAtBottom(handler); |
+ |
+ return widget; |
+} |
+ |
+} // namespace |
+ |
// Transparent button that handles events to activate or close windows in |
// overview mode. |
class TransparentButton |
@@ -34,6 +65,10 @@ class TransparentButton |
TransparentActivateWindowButtonDelegate* delegate() { return delegate_; } |
+ void set_close_window_distance_minimum(int distance) { |
+ close_window_distance_minimum_ = distance; |
+ } |
+ |
// views::View: |
virtual void OnGestureEvent(ui::GestureEvent* event) override; |
@@ -47,13 +82,32 @@ class TransparentButton |
private: |
TransparentActivateWindowButtonDelegate* delegate_; |
+ // True if the swipe to close feature is disabled. |
+ const bool swipe_to_close_disabled_; |
+ |
+ // The original X location for a tap down event. |original_x_| is in the local |
+ // coordinate space as |this|. |
+ float original_x_; |
+ |
+ // The velocity of the current fling gesture. A fling is active iff |
+ // |flint_velocity_x_| has a value greater than 0. |
+ float fling_velocity_x_; |
+ |
+ // The minimum distance, in pixels, for which a touch drag should cause a |
+ // window to be closed. |
+ int close_window_distance_minimum_; |
+ |
DISALLOW_COPY_AND_ASSIGN(TransparentButton); |
}; |
TransparentButton::TransparentButton( |
- TransparentActivateWindowButtonDelegate* delegate) |
- : CustomButton(this), |
- delegate_(delegate) { |
+ TransparentActivateWindowButtonDelegate* delegate) |
+ : views::CustomButton(this), |
+ delegate_(delegate), |
+ swipe_to_close_disabled_(CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kAshDisableSwipeToCloseInOverviewMode)), |
+ fling_velocity_x_(0.0f), |
+ close_window_distance_minimum_(kDefaultCloseWindowDistanceMinimum) { |
} |
TransparentButton::~TransparentButton() { |
@@ -74,6 +128,37 @@ void TransparentButton::OnGestureEvent(ui::GestureEvent* event) { |
GetWidget()->ReleaseCapture(); |
} |
+ if (swipe_to_close_disabled_) { |
+ CustomButton::OnGestureEvent(event); |
+ return; |
+ } |
+ |
+ int delta_x = event->x() - original_x_; |
+ |
+ switch (event->type()) { |
+ case ui::ET_GESTURE_TAP_DOWN: |
+ original_x_ = event->x(); |
+ break; |
+ case ui::ET_GESTURE_SCROLL_BEGIN: |
+ case ui::ET_GESTURE_SCROLL_UPDATE: |
+ delegate_->Scroll(delta_x); |
+ break; |
+ case ui::ET_SCROLL_FLING_START: |
+ fling_velocity_x_ = fabs(event->details().velocity_x()); |
+ break; |
+ case ui::ET_GESTURE_END: |
+ if (abs(delta_x) > close_window_distance_minimum_ || |
+ fling_velocity_x_ > kMinimumFlingVelocity) { |
+ delegate_->Close(); |
+ } else { |
+ delegate_->CancelScroll(); |
+ } |
+ original_x_ = 0; |
+ fling_velocity_x_ = 0.0f; |
+ break; |
+ default: |
+ break; |
+ } |
CustomButton::OnGestureEvent(event); |
event->StopPropagation(); |
} |
@@ -83,28 +168,6 @@ void TransparentButton::ButtonPressed(views::Button* sender, |
delegate_->Select(); |
} |
-// Initializes the event handler transparent window. |
-views::Widget* InitEventHandler(aura::Window* root_window) { |
- views::Widget* widget = new views::Widget; |
- views::Widget::InitParams params; |
- params.type = views::Widget::InitParams::TYPE_POPUP; |
- params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
- params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
- params.accept_events = true; |
- params.parent = Shell::GetContainer(root_window, |
- kShellWindowId_OverlayContainer); |
- widget->set_focus_on_creation(false); |
- widget->Init(params); |
- widget->Show(); |
- |
- aura::Window* handler = widget->GetNativeWindow(); |
- handler->parent()->StackChildAtBottom(handler); |
- |
- return widget; |
-} |
- |
-} // namespace |
- |
TransparentActivateWindowButton::TransparentActivateWindowButton( |
aura::Window* root_window, |
TransparentActivateWindowButtonDelegate* delegate) |
@@ -130,6 +193,11 @@ void TransparentActivateWindowButton::SetBounds(const gfx::Rect& bounds) { |
window->SetBoundsInScreen(bounds, display); |
} |
+void TransparentActivateWindowButton::SetCloseWindowDistanceMinimum( |
+ int distance) { |
+ transparent_button_->set_close_window_distance_minimum(distance); |
+} |
+ |
void TransparentActivateWindowButton::SendFocusAlert() const { |
event_handler_widget_->GetContentsView()-> |
NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true); |