| // Copyright 2013 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_MAC_H_ |
| #define CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_MAC_H_ |
| |
| #include "chrome/browser/extensions/global_shortcut_listener.h" |
| |
| #include <Carbon/Carbon.h> |
| |
| #include <map> |
| #include <memory> |
| |
| #include "ui/base/accelerators/media_keys_listener.h" |
| |
| namespace extensions { |
| |
| // Mac-specific implementation of the GlobalShortcutListener class that |
| // listens for global shortcuts. Handles basic keyboard intercepting and |
| // forwards its output to the base class for processing. |
| // |
| // This class does two things: |
| // 1. Intercepts media keys. Uses an event tap for intercepting media keys |
| // (PlayPause, NextTrack, PreviousTrack). |
| // 2. Binds keyboard shortcuts (hot keys). Carbon RegisterEventHotKey API for |
| // binding to non-media key global hot keys (eg. Command-Shift-1). |
| class GlobalShortcutListenerMac : public GlobalShortcutListener, |
| public ui::MediaKeysListener::Delegate { |
| public: |
| GlobalShortcutListenerMac(); |
| |
| GlobalShortcutListenerMac(const GlobalShortcutListenerMac&) = delete; |
| GlobalShortcutListenerMac& operator=(const GlobalShortcutListenerMac&) = |
| delete; |
| |
| ~GlobalShortcutListenerMac() override; |
| |
| private: |
| using KeyId = int; |
| using AcceleratorIdMap = std::map<ui::Accelerator, KeyId>; |
| using IdAcceleratorMap = std::map<KeyId, ui::Accelerator>; |
| using IdHotKeyRefMap = std::map<KeyId, EventHotKeyRef>; |
| |
| // Keyboard event callbacks. |
| void OnHotKeyEvent(EventHotKeyID hot_key_id); |
| |
| // GlobalShortcutListener implementation. |
| void StartListening() override; |
| void StopListening() override; |
| bool RegisterAcceleratorImpl(const ui::Accelerator& accelerator) override; |
| void UnregisterAcceleratorImpl(const ui::Accelerator& accelerator) override; |
| |
| // ui::MediaKeysListener::Delegate: |
| void OnMediaKeysAccelerator(const ui::Accelerator& accelerator) override; |
| |
| // Mac-specific functions for registering hot keys with modifiers. |
| bool RegisterHotKey(const ui::Accelerator& accelerator, KeyId hot_key_id); |
| void UnregisterHotKey(const ui::Accelerator& accelerator); |
| |
| // Enable and disable the hot key event handler. |
| void StartWatchingHotKeys(); |
| void StopWatchingHotKeys(); |
| |
| // Whether or not any hot keys are currently registered. |
| bool IsAnyHotKeyRegistered(); |
| |
| // The callback for when a hot key event happens. |
| static OSStatus HotKeyHandler( |
| EventHandlerCallRef next_handler, EventRef event, void* user_data); |
| |
| // Whether this object is listening for global shortcuts. |
| bool is_listening_ = false; |
| |
| // The hotkey identifier for the next global shortcut that is added. |
| KeyId hot_key_id_ = 0; |
| |
| // A map of all hotkeys (media keys and shortcuts) mapping to their |
| // corresponding hotkey IDs. For quickly finding if an accelerator is |
| // registered. |
| AcceleratorIdMap accelerator_ids_; |
| |
| // The inverse map for quickly looking up accelerators by hotkey id. |
| IdAcceleratorMap id_accelerators_; |
| |
| // Keyboard shortcut IDs to hotkeys map for unregistration. |
| IdHotKeyRefMap id_hot_key_refs_; |
| |
| // Event handler for keyboard shortcut hot keys. |
| EventHandlerRef event_handler_ = nullptr; |
| |
| // Media keys listener. |
| std::unique_ptr<ui::MediaKeysListener> media_keys_listener_; |
| }; |
| |
| } // namespace extensions |
| |
| #endif // CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_MAC_H_ |