1 // Copyright 2015 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.
5 #import "chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.h"
7 #include "base/logging.h"
8 #include "chrome/browser/global_keyboard_shortcuts_mac.h"
9 #include "chrome/browser/ui/browser_commands.h"
10 #include "chrome/browser/ui/browser_finder.h"
11 #import "chrome/browser/ui/cocoa/browser_window_controller_private.h"
12 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
16 // Type of functions listed in global_keyboard_shortcuts_mac.h.
17 typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar);
19 // If the event is for a Browser window, and the key combination has an
20 // associated command, execute the command.
21 bool HandleExtraKeyboardShortcut(
24 KeyToCommandMapper command_for_keyboard_shortcut) {
25 // Extract info from |event|.
26 NSUInteger modifers = [event modifierFlags];
27 const bool command = modifers & NSCommandKeyMask;
28 const bool shift = modifers & NSShiftKeyMask;
29 const bool control = modifers & NSControlKeyMask;
30 const bool option = modifers & NSAlternateKeyMask;
31 const int key_code = [event keyCode];
32 const unichar key_char = KeyCharacterForEvent(event);
34 int cmd = command_for_keyboard_shortcut(command, shift, control, option,
40 // Only handle event if this is a browser window.
41 Browser* browser = chrome::FindBrowserWithWindow(window);
45 chrome::ExecuteCommand(browser, cmd);
49 bool HandleExtraWindowKeyboardShortcut(NSEvent* event, NSWindow* window) {
50 return HandleExtraKeyboardShortcut(event, window,
51 CommandForWindowKeyboardShortcut);
54 bool HandleDelayedWindowKeyboardShortcut(NSEvent* event, NSWindow* window) {
55 return HandleExtraKeyboardShortcut(event, window,
56 CommandForDelayedWindowKeyboardShortcut);
59 bool HandleExtraBrowserKeyboardShortcut(NSEvent* event, NSWindow* window) {
60 return HandleExtraKeyboardShortcut(event, window,
61 CommandForBrowserKeyboardShortcut);
66 @implementation ChromeCommandDispatcherDelegate
68 - (BOOL)handleExtraKeyboardShortcut:(NSEvent*)event window:(NSWindow*)window {
69 return HandleExtraBrowserKeyboardShortcut(event, window) ||
70 HandleExtraWindowKeyboardShortcut(event, window) ||
71 HandleDelayedWindowKeyboardShortcut(event, window);
74 - (BOOL)eventHandledByExtensionCommand:(NSEvent*)event
75 isRedispatch:(BOOL)isRedispatch {
76 // Some extension commands have higher priority than web content, and some
77 // have lower priority. Regardless of whether the event is being redispatched,
78 // let the extension system try to handle the event. In case this is a
79 // redispatched event, [event window] gives the correct window.
81 BrowserWindowController* controller = [[event window] windowController];
82 // |controller| is only set in Cocoa. In toolkit-views extension commands
83 // are handled by BrowserView.
84 if ([controller respondsToSelector:@selector(handledByExtensionCommand:
86 ui::AcceleratorManager::HandlerPriority priority =
87 isRedispatch ? ui::AcceleratorManager::kNormalPriority
88 : ui::AcceleratorManager::kHighPriority;
89 if ([controller handledByExtensionCommand:event priority:priority])
96 - (BOOL)prePerformKeyEquivalent:(NSEvent*)event window:(NSWindow*)window {
97 // Handle per-window shortcuts like cmd-1, but do not handle browser-level
98 // shortcuts like cmd-left (else, cmd-left would do history navigation even
99 // if e.g. the Omnibox has focus).
100 return HandleExtraWindowKeyboardShortcut(event, window);
103 - (BOOL)postPerformKeyEquivalent:(NSEvent*)event window:(NSWindow*)window {
104 // Handle per-window shortcuts like Esc after giving everybody else a chance
106 return HandleDelayedWindowKeyboardShortcut(event, window);
109 @end // ChromeCommandDispatchDelegate