Home | History | Annotate | Download | only in wm
      1 // Copyright 2013 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_selector_controller.h"
      6 
      7 #include "ash/session_state_delegate.h"
      8 #include "ash/shell.h"
      9 #include "ash/wm/mru_window_tracker.h"
     10 #include "ash/wm/window_selector.h"
     11 #include "ash/wm/window_util.h"
     12 #include "ui/base/events/event.h"
     13 #include "ui/base/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 WindowSelectorEventFilter : public ui::EventHandler {
     22  public:
     23   WindowSelectorEventFilter();
     24   virtual ~WindowSelectorEventFilter();
     25 
     26   // Overridden from ui::EventHandler:
     27   virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE;
     28 
     29  private:
     30   DISALLOW_COPY_AND_ASSIGN(WindowSelectorEventFilter);
     31 };
     32 
     33 // Watch for all keyboard events by filtering the root window.
     34 WindowSelectorEventFilter::WindowSelectorEventFilter() {
     35   Shell::GetInstance()->AddPreTargetHandler(this);
     36 }
     37 
     38 WindowSelectorEventFilter::~WindowSelectorEventFilter() {
     39   Shell::GetInstance()->RemovePreTargetHandler(this);
     40 }
     41 
     42 void WindowSelectorEventFilter::OnKeyEvent(ui::KeyEvent* event) {
     43   // Views uses VKEY_MENU for both left and right Alt keys.
     44   if (event->key_code() == ui::VKEY_MENU &&
     45       event->type() == ui::ET_KEY_RELEASED) {
     46     Shell::GetInstance()->window_selector_controller()->AltKeyReleased();
     47     // Warning: |this| will be deleted from here on.
     48   }
     49 }
     50 
     51 }  // namespace
     52 
     53 WindowSelectorController::WindowSelectorController() {
     54 }
     55 
     56 WindowSelectorController::~WindowSelectorController() {
     57 }
     58 
     59 // static
     60 bool WindowSelectorController::CanSelect() {
     61   // Don't allow a window overview if the screen is locked or a modal dialog is
     62   // open.
     63   return !Shell::GetInstance()->session_state_delegate()->IsScreenLocked() &&
     64          !Shell::GetInstance()->IsSystemModalWindowOpen();
     65 }
     66 
     67 void WindowSelectorController::ToggleOverview() {
     68   if (window_selector_.get()) {
     69     window_selector_.reset();
     70   } else {
     71     std::vector<aura::Window*> windows = ash::Shell::GetInstance()->
     72         mru_window_tracker()->BuildMruWindowList();
     73     // Don't enter overview mode with no windows.
     74     if (windows.empty())
     75       return;
     76 
     77     // Deactivating the window will hide popup windows like the omnibar or
     78     // open menus.
     79     aura::Window* active_window = wm::GetActiveWindow();
     80     if (active_window)
     81       wm::DeactivateWindow(active_window);
     82     window_selector_.reset(
     83         new WindowSelector(windows, WindowSelector::OVERVIEW, this));
     84   }
     85 }
     86 
     87 void WindowSelectorController::HandleCycleWindow(
     88     WindowSelector::Direction direction) {
     89   if (!CanSelect())
     90     return;
     91 
     92   if (!IsSelecting()) {
     93     event_handler_.reset(new WindowSelectorEventFilter());
     94     std::vector<aura::Window*> windows = ash::Shell::GetInstance()->
     95         mru_window_tracker()->BuildMruWindowList();
     96     window_selector_.reset(
     97         new WindowSelector(windows, WindowSelector::CYCLE, this));
     98     window_selector_->Step(direction);
     99   } else if (window_selector_->mode() == WindowSelector::CYCLE) {
    100     window_selector_->Step(direction);
    101   }
    102 }
    103 
    104 void WindowSelectorController::AltKeyReleased() {
    105   event_handler_.reset();
    106   window_selector_->SelectWindow();
    107 }
    108 
    109 bool WindowSelectorController::IsSelecting() {
    110   return window_selector_.get() != NULL;
    111 }
    112 
    113 void WindowSelectorController::OnWindowSelected(aura::Window* window) {
    114   window_selector_.reset();
    115   wm::ActivateWindow(window);
    116 }
    117 
    118 void WindowSelectorController::OnSelectionCanceled() {
    119   window_selector_.reset();
    120 }
    121 
    122 }  // namespace ash
    123