overview_gesture_handler.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Copyright 2013 The Chromium Authors. All rights reserved. 227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Use of this source code is governed by a BSD-style license that can be 327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// found in the LICENSE file. 427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ash/wm/gestures/overview_gesture_handler.h" 627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ash/metrics/user_metrics_recorder.h" 827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ash/shell.h" 927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ash/wm/coordinate_conversion.h" 1027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ash/wm/overview/window_selector_controller.h" 1127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ui/aura/window.h" 1227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ui/events/event.h" 1327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ui/events/event_constants.h" 1427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ui/gfx/rect.h" 1527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "ui/gfx/screen.h" 1627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 1727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshinamespace ash { 1827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshinamespace { 1927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 2027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// The number of pixels from the top of the screen (a virtual bezel) to allow 2127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// the overview swipe down gesture to begin within. Note this does not actually 2227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// prevent handling of the touches so a fullscreen page which consumes these can 2327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// prevent entering overview with a swipe down. 2427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiconst int kTopBezelExtraPixels = 5; 2527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 2627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// The threshold before engaging overview on a three finger swipe on the 2727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// touchpad. 2827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiconst float kSwipeThresholdPixels = 300; 2927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 303473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi} // namespace; 3127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 3227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiOverviewGestureHandler::OverviewGestureHandler() 3327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi : in_top_bezel_gesture_(false), 3427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi scroll_x_(0), 3527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi scroll_y_(0) { 3627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi} 3727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 3827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiOverviewGestureHandler::~OverviewGestureHandler() { 3927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi} 4027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 4127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool OverviewGestureHandler::ProcessScrollEvent(const ui::ScrollEvent& event) { 4227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (event.type() == ui::ET_SCROLL_FLING_START || 4327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi event.type() == ui::ET_SCROLL_FLING_CANCEL || 4427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi event.finger_count() != 3) { 4527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi scroll_x_ = scroll_y_ = 0; 4627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return false; 4727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 482272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi 492272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi scroll_x_ += event.x_offset(); 50e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi scroll_y_ += event.y_offset(); 51e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi 5227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi // Horizontal swiping is ignored. 5327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (std::fabs(scroll_x_) >= std::fabs(scroll_y_)) { 5427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi scroll_x_ = scroll_y_ = 0; 553473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi return false; 5627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 5727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 5827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi // Only allow swipe up to enter overview, down to exit. Ignore extra swiping 5927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi // in the wrong direction. 6027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi Shell* shell = Shell::GetInstance(); 6127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (shell->window_selector_controller()->IsSelecting()) { 6227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (scroll_y_ < 0) 6327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi scroll_x_ = scroll_y_ = 0; 6427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (scroll_y_ < kSwipeThresholdPixels) 6527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return false; 6627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } else { 6727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (scroll_y_ > 0) 6827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi scroll_x_ = scroll_y_ = 0; 6927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (scroll_y_ > -kSwipeThresholdPixels) 7027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return false; 7127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 7227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 73e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi // Reset scroll amount on toggling. 7427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi scroll_x_ = scroll_y_ = 0; 7527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi shell->metrics()->RecordUserMetricsAction(UMA_TOUCHPAD_GESTURE_OVERVIEW); 7627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi shell->window_selector_controller()->ToggleOverview(); 7727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return true; 7827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi} 7927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 8027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool OverviewGestureHandler::ProcessGestureEvent( 8127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi const ui::GestureEvent& event) { 8227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi // Detect at the beginning of any gesture whether it begins on the top bezel. 8327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (event.type() == ui::ET_GESTURE_BEGIN && 8427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi event.details().touch_points() == 1) { 852272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi gfx::Point point_in_screen(event.location()); 862272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi aura::Window* target = static_cast<aura::Window*>(event.target()); 872272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi wm::ConvertPointToScreen(target, &point_in_screen); 882272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi in_top_bezel_gesture_ = !Shell::GetScreen()->GetDisplayNearestPoint( 89e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi point_in_screen).bounds().y() + kTopBezelExtraPixels > 9027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi point_in_screen.y(); 91e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi return false; 9227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 9327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 9427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi if (!in_top_bezel_gesture_ || 9527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi event.type() != ui::ET_GESTURE_MULTIFINGER_SWIPE || 9627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi !event.details().swipe_down() || 9727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi event.details().touch_points() != 3) { 9827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return false; 9927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi } 10027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 1013473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi Shell* shell = Shell::GetInstance(); 1023473846f64f5b28e1cbeb70ef5867073fc93159eTakeshi Aimi shell->metrics()->RecordUserMetricsAction(UMA_GESTURE_OVERVIEW); 10327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi shell->window_selector_controller()->ToggleOverview(); 10427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi return true; 10527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi} 10627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi 10727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi} // namespace ash 10827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi