1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ash/wm/window_cycle_controller.h" 6 7#include "ash/session/session_state_delegate.h" 8#include "ash/shell.h" 9#include "ash/wm/mru_window_tracker.h" 10#include "ash/wm/window_cycle_list.h" 11#include "base/metrics/histogram.h" 12#include "ui/events/event.h" 13#include "ui/events/event_handler.h" 14 15namespace ash { 16 17namespace { 18 19// Filter to watch for the termination of a keyboard gesture to cycle through 20// multiple windows. 21class WindowCycleEventFilter : public ui::EventHandler { 22 public: 23 WindowCycleEventFilter(); 24 virtual ~WindowCycleEventFilter(); 25 26 // Overridden from ui::EventHandler: 27 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE; 28 29 private: 30 DISALLOW_COPY_AND_ASSIGN(WindowCycleEventFilter); 31}; 32 33WindowCycleEventFilter::WindowCycleEventFilter() { 34 Shell::GetInstance()->AddPreTargetHandler(this); 35} 36 37WindowCycleEventFilter::~WindowCycleEventFilter() { 38 Shell::GetInstance()->RemovePreTargetHandler(this); 39} 40 41void WindowCycleEventFilter::OnKeyEvent(ui::KeyEvent* event) { 42 // Views uses VKEY_MENU for both left and right Alt keys. 43 if (event->key_code() == ui::VKEY_MENU && 44 event->type() == ui::ET_KEY_RELEASED) { 45 Shell::GetInstance()->window_cycle_controller()->StopCycling(); 46 // Warning: |this| will be deleted from here on. 47 } 48} 49 50} // namespace 51 52////////////////////////////////////////////////////////////////////////////// 53// WindowCycleController, public: 54 55WindowCycleController::WindowCycleController() { 56} 57 58WindowCycleController::~WindowCycleController() { 59} 60 61// static 62bool WindowCycleController::CanCycle() { 63 // Don't allow window cycling if the screen is locked or a modal dialog is 64 // open. 65 return !Shell::GetInstance()->session_state_delegate()->IsScreenLocked() && 66 !Shell::GetInstance()->IsSystemModalWindowOpen(); 67} 68 69void WindowCycleController::HandleCycleWindow(Direction direction) { 70 if (!CanCycle()) 71 return; 72 73 if (!IsCycling()) 74 StartCycling(); 75 76 Step(direction); 77} 78 79void WindowCycleController::StartCycling() { 80 window_cycle_list_.reset(new WindowCycleList(ash::Shell::GetInstance()-> 81 mru_window_tracker()->BuildMruWindowList())); 82 event_handler_.reset(new WindowCycleEventFilter()); 83 cycle_start_time_ = base::Time::Now(); 84 Shell::GetInstance()->metrics()->RecordUserMetricsAction(UMA_WINDOW_CYCLE); 85} 86 87////////////////////////////////////////////////////////////////////////////// 88// WindowCycleController, private: 89 90void WindowCycleController::Step(Direction direction) { 91 DCHECK(window_cycle_list_.get()); 92 window_cycle_list_->Step(direction); 93} 94 95void WindowCycleController::StopCycling() { 96 window_cycle_list_.reset(); 97 // Remove our key event filter. 98 event_handler_.reset(); 99 UMA_HISTOGRAM_MEDIUM_TIMES("Ash.WindowCycleController.CycleTime", 100 base::Time::Now() - cycle_start_time_); 101} 102 103} // namespace ash 104