Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1353)

Side by Side Diff: chrome/browser/ui/cocoa/chrome_event_processing_window.mm

Issue 1250533003: [Mac] Remove BrowserCommandExecutor protocol. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Don't take a window for handleExtraKeyboardShortcut. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" 5 #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "chrome/browser/global_keyboard_shortcuts_mac.h" 8 #include "chrome/browser/global_keyboard_shortcuts_mac.h"
9 #import "chrome/browser/ui/cocoa/browser_command_executor.h" 9 #include "chrome/browser/ui/browser_commands.h"
10 #include "chrome/browser/ui/browser_finder.h"
10 #import "chrome/browser/ui/cocoa/browser_window_controller_private.h" 11 #import "chrome/browser/ui/cocoa/browser_window_controller_private.h"
11 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" 12 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
12 #import "content/public/browser/render_widget_host_view_mac_base.h" 13 #import "content/public/browser/render_widget_host_view_mac_base.h"
13 14
15 namespace {
16
17 // Type of functions listed in global_keyboard_shortcuts_mac.h.
14 typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar); 18 typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar);
15 19
16 @interface ChromeEventProcessingWindow () 20 // If the event is for a Browser window, and the key combination has an
21 // associated command, execute the command.
22 bool HandleExtraKeyboardShortcut(
23 NSEvent* event,
24 NSWindow* window,
25 KeyToCommandMapper command_for_keyboard_shortcut) {
26 // Extract info from |event|.
27 NSUInteger modifers = [event modifierFlags];
28 const bool command = modifers & NSCommandKeyMask;
29 const bool shift = modifers & NSShiftKeyMask;
30 const bool control = modifers & NSControlKeyMask;
31 const bool option = modifers & NSAlternateKeyMask;
32 const int key_code = [event keyCode];
33 const unichar key_char = KeyCharacterForEvent(event);
34
35 int cmd = command_for_keyboard_shortcut(command, shift, control, option,
36 key_code, key_char);
37
38 if (cmd == -1)
39 return false;
40
41 // Only handle event if this is a browser window.
42 Browser* browser = chrome::FindBrowserWithWindow(event.window);
tapted 2015/07/28 06:57:10 event.window -> window
jackhou1 2015/07/29 00:33:53 Oops. Done.
43 if (!browser)
44 return false;
45
46 chrome::ExecuteCommand(browser, cmd);
47 return true;
48 }
49
50 bool HandleExtraWindowKeyboardShortcut(NSEvent* event, NSWindow* window) {
51 return HandleExtraKeyboardShortcut(event, window,
52 CommandForWindowKeyboardShortcut);
53 }
54
55 bool HandleDelayedWindowKeyboardShortcut(NSEvent* event, NSWindow* window) {
56 return HandleExtraKeyboardShortcut(event, window,
57 CommandForDelayedWindowKeyboardShortcut);
58 }
59
60 bool HandleExtraBrowserKeyboardShortcut(NSEvent* event, NSWindow* window) {
61 return HandleExtraKeyboardShortcut(event, window,
62 CommandForBrowserKeyboardShortcut);
63 }
64
17 // Duplicate the given key event, but changing the associated window. 65 // Duplicate the given key event, but changing the associated window.
18 - (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event; 66 NSEvent* KeyEventForWindow(NSWindow* window, NSEvent* event) {
19 @end 67 NSEventType event_type = [event type];
68
69 // Convert the event's location from the original window's coordinates into
70 // our own.
71 NSPoint location = [event locationInWindow];
72 location = [[event window] convertBaseToScreen:location];
73 location = [window convertScreenToBase:location];
74
75 // Various things *only* apply to key down/up.
76 bool is_a_repeat = false;
77 NSString* characters = nil;
78 NSString* charactors_ignoring_modifiers = nil;
79 if (event_type == NSKeyDown || event_type == NSKeyUp) {
80 is_a_repeat = [event isARepeat];
81 characters = [event characters];
82 charactors_ignoring_modifiers = [event charactersIgnoringModifiers];
83 }
84
85 // This synthesis may be slightly imperfect: we provide nil for the context,
86 // since I (viettrungluu) am sceptical that putting in the original context
87 // (if one is given) is valid.
88 return [NSEvent keyEventWithType:event_type
89 location:location
90 modifierFlags:[event modifierFlags]
91 timestamp:[event timestamp]
92 windowNumber:[window windowNumber]
93 context:nil
94 characters:characters
95 charactersIgnoringModifiers:charactors_ignoring_modifiers
96 isARepeat:is_a_repeat
97 keyCode:[event keyCode]];
98 }
99
100 } // namespace
20 101
21 @implementation ChromeEventProcessingWindow 102 @implementation ChromeEventProcessingWindow
22 103
23 - (BOOL)handleExtraKeyboardShortcut:(NSEvent*)event fromTable: 104 - (BOOL)handleExtraKeyboardShortcut:(NSEvent*)event {
24 (KeyToCommandMapper)commandForKeyboardShortcut { 105 return HandleExtraBrowserKeyboardShortcut(event, self) ||
25 // Extract info from |event|. 106 HandleExtraWindowKeyboardShortcut(event, self) ||
26 NSUInteger modifers = [event modifierFlags]; 107 HandleDelayedWindowKeyboardShortcut(event, self);
27 const bool cmdKey = modifers & NSCommandKeyMask;
28 const bool shiftKey = modifers & NSShiftKeyMask;
29 const bool cntrlKey = modifers & NSControlKeyMask;
30 const bool optKey = modifers & NSAlternateKeyMask;
31 const unichar keyCode = [event keyCode];
32 const unichar keyChar = KeyCharacterForEvent(event);
33
34 int cmdNum = commandForKeyboardShortcut(cmdKey, shiftKey, cntrlKey, optKey,
35 keyCode, keyChar);
36
37 if (cmdNum != -1) {
38 id executor = [self delegate];
39 // A bit of sanity.
40 DCHECK([executor conformsToProtocol:@protocol(BrowserCommandExecutor)]);
41 DCHECK([executor respondsToSelector:@selector(executeCommand:)]);
42 [executor executeCommand:cmdNum];
43 return YES;
44 }
45 return NO;
46 }
47
48 - (BOOL)handleExtraWindowKeyboardShortcut:(NSEvent*)event {
49 return [self handleExtraKeyboardShortcut:event
50 fromTable:CommandForWindowKeyboardShortcut];
51 }
52
53 - (BOOL)handleDelayedWindowKeyboardShortcut:(NSEvent*)event {
54 return [self handleExtraKeyboardShortcut:event
55 fromTable:CommandForDelayedWindowKeyboardShortcut];
56 }
57
58 - (BOOL)handleExtraBrowserKeyboardShortcut:(NSEvent*)event {
59 return [self handleExtraKeyboardShortcut:event
60 fromTable:CommandForBrowserKeyboardShortcut];
61 } 108 }
62 109
63 - (BOOL)performKeyEquivalent:(NSEvent*)event { 110 - (BOOL)performKeyEquivalent:(NSEvent*)event {
64 // Some extension commands have higher priority than web content, and some 111 // Some extension commands have higher priority than web content, and some
65 // have lower priority. Regardless of whether the event is being 112 // have lower priority. Regardless of whether the event is being
66 // redispatched, let the extension system try to handle the event. 113 // redispatched, let the extension system try to handle the event.
67 NSWindow* window = event.window; 114 NSWindow* window = event.window;
68 if (window) { 115 if (window) {
69 BrowserWindowController* controller = [window windowController]; 116 BrowserWindowController* controller = [window windowController];
70 if ([controller respondsToSelector:@selector(handledByExtensionCommand: 117 if ([controller respondsToSelector:@selector(handledByExtensionCommand:
71 priority:)]) { 118 priority:)]) {
72 ui::AcceleratorManager::HandlerPriority priority = 119 ui::AcceleratorManager::HandlerPriority priority =
73 redispatchingEvent_ ? ui::AcceleratorManager::kNormalPriority 120 redispatchingEvent_ ? ui::AcceleratorManager::kNormalPriority
74 : ui::AcceleratorManager::kHighPriority; 121 : ui::AcceleratorManager::kHighPriority;
75 if ([controller handledByExtensionCommand:event priority:priority]) 122 if ([controller handledByExtensionCommand:event priority:priority])
76 return YES; 123 return YES;
77 } 124 }
78 } 125 }
79 126
80 if (redispatchingEvent_) 127 if (redispatchingEvent_)
81 return NO; 128 return NO;
82 129
83 // Give the web site a chance to handle the event. If it doesn't want to 130 // Give the web site a chance to handle the event. If it doesn't want to
84 // handle it, it will call us back with one of the |handle*| methods above. 131 // handle it, it will call us back with one of the |handle*| methods above.
85 NSResponder* r = [self firstResponder]; 132 NSResponder* r = [self firstResponder];
86 if ([r conformsToProtocol:@protocol(RenderWidgetHostViewMacBase)]) 133 if ([r conformsToProtocol:@protocol(RenderWidgetHostViewMacBase)])
87 return [r performKeyEquivalent:event]; 134 return [r performKeyEquivalent:event];
88 135
89 // If the delegate does not implement the BrowserCommandExecutor protocol,
90 // then we don't need to handle browser specific shortcut keys.
91 if (![[self delegate] conformsToProtocol:@protocol(BrowserCommandExecutor)])
92 return [super performKeyEquivalent:event];
93
94 // Handle per-window shortcuts like cmd-1, but do not handle browser-level 136 // Handle per-window shortcuts like cmd-1, but do not handle browser-level
95 // shortcuts like cmd-left (else, cmd-left would do history navigation even 137 // shortcuts like cmd-left (else, cmd-left would do history navigation even
96 // if e.g. the Omnibox has focus). 138 // if e.g. the Omnibox has focus).
97 if ([self handleExtraWindowKeyboardShortcut:event]) 139 if (HandleExtraWindowKeyboardShortcut(event, self))
98 return YES; 140 return YES;
99 141
100 if ([super performKeyEquivalent:event]) 142 if ([super performKeyEquivalent:event])
101 return YES; 143 return YES;
102 144
103 // Handle per-window shortcuts like Esc after giving everybody else a chance 145 // Handle per-window shortcuts like Esc after giving everybody else a chance
104 // to handle them 146 // to handle them
105 return [self handleDelayedWindowKeyboardShortcut:event]; 147 return HandleDelayedWindowKeyboardShortcut(event, self);
106 } 148 }
107 149
108 - (BOOL)redispatchKeyEvent:(NSEvent*)event { 150 - (BOOL)redispatchKeyEvent:(NSEvent*)event {
109 DCHECK(event); 151 DCHECK(event);
110 NSEventType eventType = [event type]; 152 NSEventType eventType = [event type];
111 if (eventType != NSKeyDown && 153 if (eventType != NSKeyDown &&
112 eventType != NSKeyUp && 154 eventType != NSKeyUp &&
113 eventType != NSFlagsChanged) { 155 eventType != NSFlagsChanged) {
114 NOTREACHED(); 156 NOTREACHED();
115 return YES; // Pretend it's been handled in an effort to limit damage. 157 return YES; // Pretend it's been handled in an effort to limit damage.
116 } 158 }
117 159
118 // Ordinarily, the event's window should be this window. However, when 160 // Ordinarily, the event's window should be this window. However, when
119 // switching between normal and fullscreen mode, we switch out the window, and 161 // switching between normal and fullscreen mode, we switch out the window, and
120 // the event's window might be the previous window (or even an earlier one if 162 // the event's window might be the previous window (or even an earlier one if
121 // the renderer is running slowly and several mode switches occur). In this 163 // the renderer is running slowly and several mode switches occur). In this
122 // rare case, we synthesize a new key event so that its associate window 164 // rare case, we synthesize a new key event so that its associate window
123 // (number) is our own. 165 // (number) is our own.
124 if ([event window] != self) 166 if ([event window] != self)
125 event = [self keyEventForWindow:self fromKeyEvent:event]; 167 event = KeyEventForWindow(self, event);
126 168
127 // Redispatch the event. 169 // Redispatch the event.
128 eventHandled_ = YES; 170 eventHandled_ = YES;
129 redispatchingEvent_ = YES; 171 redispatchingEvent_ = YES;
130 [NSApp sendEvent:event]; 172 [NSApp sendEvent:event];
131 redispatchingEvent_ = NO; 173 redispatchingEvent_ = NO;
132 174
133 // If the event was not handled by [NSApp sendEvent:], the sendEvent: 175 // If the event was not handled by [NSApp sendEvent:], the sendEvent:
134 // method below will be called, and because |redispatchingEvent_| is YES, 176 // method below will be called, and because |redispatchingEvent_| is YES,
135 // |eventHandled_| will be set to NO. 177 // |eventHandled_| will be set to NO.
136 return eventHandled_; 178 return eventHandled_;
137 } 179 }
138 180
139 - (void)sendEvent:(NSEvent*)event { 181 - (void)sendEvent:(NSEvent*)event {
140 if (!redispatchingEvent_) 182 if (!redispatchingEvent_)
141 [super sendEvent:event]; 183 [super sendEvent:event];
142 else 184 else
143 eventHandled_ = NO; 185 eventHandled_ = NO;
144 } 186 }
145 187
146 - (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event {
147 NSEventType eventType = [event type];
148
149 // Convert the event's location from the original window's coordinates into
150 // our own.
151 NSPoint eventLoc = [event locationInWindow];
152 eventLoc = [[event window] convertBaseToScreen:eventLoc];
153 eventLoc = [self convertScreenToBase:eventLoc];
154
155 // Various things *only* apply to key down/up.
156 BOOL eventIsARepeat = NO;
157 NSString* eventCharacters = nil;
158 NSString* eventUnmodCharacters = nil;
159 if (eventType == NSKeyDown || eventType == NSKeyUp) {
160 eventIsARepeat = [event isARepeat];
161 eventCharacters = [event characters];
162 eventUnmodCharacters = [event charactersIgnoringModifiers];
163 }
164
165 // This synthesis may be slightly imperfect: we provide nil for the context,
166 // since I (viettrungluu) am sceptical that putting in the original context
167 // (if one is given) is valid.
168 return [NSEvent keyEventWithType:eventType
169 location:eventLoc
170 modifierFlags:[event modifierFlags]
171 timestamp:[event timestamp]
172 windowNumber:[window windowNumber]
173 context:nil
174 characters:eventCharacters
175 charactersIgnoringModifiers:eventUnmodCharacters
176 isARepeat:eventIsARepeat
177 keyCode:[event keyCode]];
178 }
179
180 @end // ChromeEventProcessingWindow 188 @end // ChromeEventProcessingWindow
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698