• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()33 WindowCycleEventFilter::WindowCycleEventFilter() {
34   Shell::GetInstance()->AddPreTargetHandler(this);
35 }
36 
~WindowCycleEventFilter()37 WindowCycleEventFilter::~WindowCycleEventFilter() {
38   Shell::GetInstance()->RemovePreTargetHandler(this);
39 }
40 
OnKeyEvent(ui::KeyEvent * event)41 void 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()55 WindowCycleController::WindowCycleController() {
56 }
57 
~WindowCycleController()58 WindowCycleController::~WindowCycleController() {
59 }
60 
61 // static
CanCycle()62 bool 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)69 void WindowCycleController::HandleCycleWindow(Direction direction) {
70   if (!CanCycle())
71     return;
72 
73   if (!IsCycling())
74     StartCycling();
75 
76   Step(direction);
77 }
78 
StartCycling()79 void 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)90 void WindowCycleController::Step(Direction direction) {
91   DCHECK(window_cycle_list_.get());
92   window_cycle_list_->Step(direction);
93 }
94 
StopCycling()95 void 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