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 15 namespace ash { 16 17 namespace { 18 19 // Filter to watch for the termination of a keyboard gesture to cycle through 20 // multiple windows. 21 class 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 WindowCycleEventFilter()33WindowCycleEventFilter::WindowCycleEventFilter() { 34 Shell::GetInstance()->AddPreTargetHandler(this); 35 } 36 ~WindowCycleEventFilter()37WindowCycleEventFilter::~WindowCycleEventFilter() { 38 Shell::GetInstance()->RemovePreTargetHandler(this); 39 } 40 OnKeyEvent(ui::KeyEvent * event)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 WindowCycleController()55WindowCycleController::WindowCycleController() { 56 } 57 ~WindowCycleController()58WindowCycleController::~WindowCycleController() { 59 } 60 61 // static CanCycle()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 HandleCycleWindow(Direction direction)69void WindowCycleController::HandleCycleWindow(Direction direction) { 70 if (!CanCycle()) 71 return; 72 73 if (!IsCycling()) 74 StartCycling(); 75 76 Step(direction); 77 } 78 StartCycling()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 Step(Direction direction)90void WindowCycleController::Step(Direction direction) { 91 DCHECK(window_cycle_list_.get()); 92 window_cycle_list_->Step(direction); 93 } 94 StopCycling()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