Home | History | Annotate | Download | only in extensions
      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_MAC_H_
      6 #define CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_MAC_H_
      7 
      8 #include "chrome/browser/extensions/global_shortcut_listener.h"
      9 
     10 #include <Carbon/Carbon.h>
     11 #include <CoreFoundation/CoreFoundation.h>
     12 
     13 #include <map>
     14 
     15 #include "base/mac/scoped_nsobject.h"
     16 
     17 namespace extensions {
     18 
     19 // Mac-specific implementation of the GlobalShortcutListener class that
     20 // listens for global shortcuts. Handles basic keyboard intercepting and
     21 // forwards its output to the base class for processing.
     22 //
     23 // This class does two things:
     24 // 1. Intercepts media keys. Uses an event tap for intercepting media keys
     25 // (PlayPause, NextTrack, PreviousTrack).
     26 // 2. Binds keyboard shortcuts (hot keys). Carbon RegisterEventHotKey API for
     27 // binding to non-media key global hot keys (eg. Command-Shift-1).
     28 class GlobalShortcutListenerMac : public GlobalShortcutListener {
     29  public:
     30   GlobalShortcutListenerMac();
     31   virtual ~GlobalShortcutListenerMac();
     32 
     33  private:
     34   typedef int KeyId;
     35   typedef std::map<ui::Accelerator, KeyId> AcceleratorIdMap;
     36   typedef std::map<KeyId, ui::Accelerator> IdAcceleratorMap;
     37   typedef std::map<KeyId, EventHotKeyRef> IdHotKeyRefMap;
     38 
     39   // Keyboard event callbacks.
     40   void OnHotKeyEvent(EventHotKeyID hot_key_id);
     41   bool OnMediaKeyEvent(int key_code);
     42 
     43   // GlobalShortcutListener implementation.
     44   virtual void StartListening() OVERRIDE;
     45   virtual void StopListening() OVERRIDE;
     46   virtual bool RegisterAcceleratorImpl(
     47       const ui::Accelerator& accelerator) OVERRIDE;
     48   virtual void UnregisterAcceleratorImpl(
     49       const ui::Accelerator& accelerator) OVERRIDE;
     50 
     51   // Mac-specific functions for registering hot keys with modifiers.
     52   bool RegisterHotKey(const ui::Accelerator& accelerator, KeyId hot_key_id);
     53   void UnregisterHotKey(const ui::Accelerator& accelerator);
     54 
     55   // Enable and disable the media key event tap.
     56   void StartWatchingMediaKeys();
     57   void StopWatchingMediaKeys();
     58 
     59   // Enable and disable the hot key event handler.
     60   void StartWatchingHotKeys();
     61   void StopWatchingHotKeys();
     62 
     63   // Whether or not any media keys are currently registered.
     64   bool IsAnyMediaKeyRegistered();
     65 
     66   // Whether or not any hot keys are currently registered.
     67   bool IsAnyHotKeyRegistered();
     68 
     69   // The callback for when an event tap happens.
     70   static CGEventRef EventTapCallback(
     71       CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* refcon);
     72 
     73   // The callback for when a hot key event happens.
     74   static OSStatus HotKeyHandler(
     75       EventHandlerCallRef next_handler, EventRef event, void* user_data);
     76 
     77   // Whether this object is listening for global shortcuts.
     78   bool is_listening_;
     79 
     80   // The hotkey identifier for the next global shortcut that is added.
     81   KeyId hot_key_id_;
     82 
     83   // A map of all hotkeys (media keys and shortcuts) mapping to their
     84   // corresponding hotkey IDs. For quickly finding if an accelerator is
     85   // registered.
     86   AcceleratorIdMap accelerator_ids_;
     87 
     88   // The inverse map for quickly looking up accelerators by hotkey id.
     89   IdAcceleratorMap id_accelerators_;
     90 
     91   // Keyboard shortcut IDs to hotkeys map for unregistration.
     92   IdHotKeyRefMap id_hot_key_refs_;
     93 
     94   // Event tap for intercepting mac media keys.
     95   CFMachPortRef event_tap_;
     96   CFRunLoopSourceRef event_tap_source_;
     97 
     98   // Event handler for keyboard shortcut hot keys.
     99   EventHandlerRef event_handler_;
    100 
    101   DISALLOW_COPY_AND_ASSIGN(GlobalShortcutListenerMac);
    102 };
    103 
    104 }  // namespace extensions
    105 
    106 #endif  // CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_MAC_H_
    107