1// Copyright (c) 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#ifndef CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_H_
6#define CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_H_
7
8#include <map>
9
10#include "base/basictypes.h"
11#include "ui/events/keycodes/keyboard_codes.h"
12
13namespace ui {
14class Accelerator;
15}
16
17namespace extensions {
18
19// Platform-neutral implementation of a class that keeps track of observers and
20// monitors keystrokes. It relays messages to the appropriate observer when a
21// global shortcut has been struck by the user.
22class GlobalShortcutListener {
23 public:
24  class Observer {
25   public:
26    // Called when your global shortcut (|accelerator|) is struck.
27    virtual void OnKeyPressed(const ui::Accelerator& accelerator) = 0;
28  };
29
30  virtual ~GlobalShortcutListener();
31
32  static GlobalShortcutListener* GetInstance();
33
34  // Register an observer for when a certain |accelerator| is struck. Returns
35  // true if register successfully, or false if 1) the specificied |accelerator|
36  // has been registered by another caller or other native applications, or
37  // 2) shortcut handling is suspended.
38  //
39  // Note that we do not support recognizing that an accelerator has been
40  // registered by another application on all platforms. This is a per-platform
41  // consideration.
42  bool RegisterAccelerator(const ui::Accelerator& accelerator,
43                           Observer* observer);
44
45  // Stop listening for the given |accelerator|, does nothing if shortcut
46  // handling is suspended.
47  void UnregisterAccelerator(const ui::Accelerator& accelerator,
48                             Observer* observer);
49
50  // Stop listening for all accelerators of the given |observer|, does nothing
51  // if shortcut handling is suspended.
52  void UnregisterAccelerators(Observer* observer);
53
54  // Suspend/Resume global shortcut handling. Note that when suspending,
55  // RegisterAccelerator/UnregisterAccelerator/UnregisterAccelerators are not
56  // allowed to be called until shortcut handling has been resumed.
57  void SetShortcutHandlingSuspended(bool suspended);
58
59  // Returns whether shortcut handling is currently suspended.
60  bool IsShortcutHandlingSuspended() const;
61
62 protected:
63  GlobalShortcutListener();
64
65  // Called by platform specific implementations of this class whenever a key
66  // is struck. Only called for keys that have an observer registered.
67  void NotifyKeyPressed(const ui::Accelerator& accelerator);
68
69 private:
70  // The following methods are implemented by platform-specific implementations
71  // of this class.
72  //
73  // Start/StopListening are called when transitioning between zero and nonzero
74  // registered accelerators. StartListening will be called after
75  // RegisterAcceleratorImpl and StopListening will be called after
76  // UnregisterAcceleratorImpl.
77  //
78  // For RegisterAcceleratorImpl, implementations return false if registration
79  // did not complete successfully.
80  virtual void StartListening() = 0;
81  virtual void StopListening() = 0;
82  virtual bool RegisterAcceleratorImpl(const ui::Accelerator& accelerator) = 0;
83  virtual void UnregisterAcceleratorImpl(
84      const ui::Accelerator& accelerator) = 0;
85
86  // The map of accelerators that have been successfully registered as global
87  // shortcuts and their observer.
88  typedef std::map<ui::Accelerator, Observer*> AcceleratorMap;
89  AcceleratorMap accelerator_map_;
90
91  // Keeps track of whether shortcut handling is currently suspended.
92  bool shortcut_handling_suspended_;
93
94  DISALLOW_COPY_AND_ASSIGN(GlobalShortcutListener);
95};
96
97}  // namespace extensions
98
99#endif  // CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_H_
100