1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/accelerators/accelerator_delegate.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/accelerators/accelerator_controller.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/shell.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/wm/window_state.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/base/accelerators/accelerator.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/events/event.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/wm/core/window_util.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace ash {
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {}  // namespace
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AcceleratorDelegate::AcceleratorDelegate() {
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AcceleratorDelegate::~AcceleratorDelegate() {
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool AcceleratorDelegate::ProcessAccelerator(const ui::KeyEvent& key_event,
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                             const ui::Accelerator& accelerator,
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                             KeyType key_type) {
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Special hardware keys like brightness and volume are handled in
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // special way. However, some windows can override this behavior
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // (e.g. Chrome v1 apps by default and Chrome v2 apps with
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // permission) by setting a window property.
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (key_type == KEY_TYPE_SYSTEM && !CanConsumeSystemKeys(key_event)) {
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // System keys are always consumed regardless of whether they trigger an
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // accelerator to prevent windows from seeing unexpected key up events.
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    Shell::GetInstance()->accelerator_controller()->Process(accelerator);
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return true;
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!ShouldProcessAcceleratorNow(key_event, accelerator))
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return false;
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return Shell::GetInstance()->accelerator_controller()->Process(accelerator);
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Uses the top level window so if the target is a web contents window the
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// containing parent window will be checked for the property.
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool AcceleratorDelegate::CanConsumeSystemKeys(const ui::KeyEvent& event) {
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* target = static_cast<aura::Window*>(event.target());
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(target);
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* top_level = ::wm::GetToplevelWindow(target);
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return top_level && wm::GetWindowState(top_level)->can_consume_system_keys();
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Returns true if the |accelerator| should be processed now, inside Ash's env
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// event filter.
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool AcceleratorDelegate::ShouldProcessAcceleratorNow(
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ui::KeyEvent& event,
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ui::Accelerator& accelerator) {
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* target = static_cast<aura::Window*>(event.target());
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(target);
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (std::find(root_windows.begin(), root_windows.end(), target) !=
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      root_windows.end())
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  aura::Window* top_level = ::wm::GetToplevelWindow(target);
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Shell* shell = Shell::GetInstance();
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Reserved accelerators (such as Power button) always have a prority.
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (shell->accelerator_controller()->IsReserved(accelerator))
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return true;
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A full screen window has a right to handle all key events including the
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // reserved ones.
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (top_level && wm::GetWindowState(top_level)->IsFullscreen()) {
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // On ChromeOS, fullscreen windows are either browser or apps, which
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // send key events to a web content first, then will process keys
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // if the web content didn't consume them.
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Handle preferred accelerators (such as ALT-TAB) before sending
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // to the target.
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (shell->accelerator_controller()->IsPreferred(accelerator))
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return shell->GetAppListTargetVisibility();
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace ash
87