| Index: chrome/browser/ui/cocoa/chrome_event_processing_window.mm
|
| diff --git a/chrome/browser/ui/cocoa/chrome_event_processing_window.mm b/chrome/browser/ui/cocoa/chrome_event_processing_window.mm
|
| index a493d84f39544721d760bf2574103854f17db62c..4dd2c644a574850fc78ae54c78c0da9b3a7c252b 100644
|
| --- a/chrome/browser/ui/cocoa/chrome_event_processing_window.mm
|
| +++ b/chrome/browser/ui/cocoa/chrome_event_processing_window.mm
|
| @@ -6,58 +6,105 @@
|
|
|
| #include "base/logging.h"
|
| #include "chrome/browser/global_keyboard_shortcuts_mac.h"
|
| -#import "chrome/browser/ui/cocoa/browser_command_executor.h"
|
| +#include "chrome/browser/ui/browser_commands.h"
|
| +#include "chrome/browser/ui/browser_finder.h"
|
| #import "chrome/browser/ui/cocoa/browser_window_controller_private.h"
|
| #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
|
| #import "content/public/browser/render_widget_host_view_mac_base.h"
|
|
|
| -typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar);
|
| -
|
| -@interface ChromeEventProcessingWindow ()
|
| -// Duplicate the given key event, but changing the associated window.
|
| -- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event;
|
| -@end
|
| +namespace {
|
|
|
| -@implementation ChromeEventProcessingWindow
|
| +// Type of functions listed in global_keyboard_shortcuts_mac.h.
|
| +typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar);
|
|
|
| -- (BOOL)handleExtraKeyboardShortcut:(NSEvent*)event fromTable:
|
| - (KeyToCommandMapper)commandForKeyboardShortcut {
|
| +// If the event is for a Browser window, and the key combination has an
|
| +// associated command, execute the command.
|
| +bool HandleExtraKeyboardShortcut(
|
| + NSEvent* event,
|
| + NSWindow* window,
|
| + KeyToCommandMapper command_for_keyboard_shortcut) {
|
| // Extract info from |event|.
|
| NSUInteger modifers = [event modifierFlags];
|
| - const bool cmdKey = modifers & NSCommandKeyMask;
|
| - const bool shiftKey = modifers & NSShiftKeyMask;
|
| - const bool cntrlKey = modifers & NSControlKeyMask;
|
| - const bool optKey = modifers & NSAlternateKeyMask;
|
| - const unichar keyCode = [event keyCode];
|
| - const unichar keyChar = KeyCharacterForEvent(event);
|
| -
|
| - int cmdNum = commandForKeyboardShortcut(cmdKey, shiftKey, cntrlKey, optKey,
|
| - keyCode, keyChar);
|
| -
|
| - if (cmdNum != -1) {
|
| - id executor = [self delegate];
|
| - // A bit of sanity.
|
| - DCHECK([executor conformsToProtocol:@protocol(BrowserCommandExecutor)]);
|
| - DCHECK([executor respondsToSelector:@selector(executeCommand:)]);
|
| - [executor executeCommand:cmdNum];
|
| - return YES;
|
| - }
|
| - return NO;
|
| + const bool command = modifers & NSCommandKeyMask;
|
| + const bool shift = modifers & NSShiftKeyMask;
|
| + const bool control = modifers & NSControlKeyMask;
|
| + const bool option = modifers & NSAlternateKeyMask;
|
| + const int key_code = [event keyCode];
|
| + const unichar key_char = KeyCharacterForEvent(event);
|
| +
|
| + int cmd = command_for_keyboard_shortcut(command, shift, control, option,
|
| + key_code, key_char);
|
| +
|
| + if (cmd == -1)
|
| + return false;
|
| +
|
| + // Only handle event if this is a browser window.
|
| + Browser* browser = chrome::FindBrowserWithWindow(window);
|
| + if (!browser)
|
| + return false;
|
| +
|
| + chrome::ExecuteCommand(browser, cmd);
|
| + return true;
|
| }
|
|
|
| -- (BOOL)handleExtraWindowKeyboardShortcut:(NSEvent*)event {
|
| - return [self handleExtraKeyboardShortcut:event
|
| - fromTable:CommandForWindowKeyboardShortcut];
|
| +bool HandleExtraWindowKeyboardShortcut(NSEvent* event, NSWindow* window) {
|
| + return HandleExtraKeyboardShortcut(event, window,
|
| + CommandForWindowKeyboardShortcut);
|
| }
|
|
|
| -- (BOOL)handleDelayedWindowKeyboardShortcut:(NSEvent*)event {
|
| - return [self handleExtraKeyboardShortcut:event
|
| - fromTable:CommandForDelayedWindowKeyboardShortcut];
|
| +bool HandleDelayedWindowKeyboardShortcut(NSEvent* event, NSWindow* window) {
|
| + return HandleExtraKeyboardShortcut(event, window,
|
| + CommandForDelayedWindowKeyboardShortcut);
|
| }
|
|
|
| -- (BOOL)handleExtraBrowserKeyboardShortcut:(NSEvent*)event {
|
| - return [self handleExtraKeyboardShortcut:event
|
| - fromTable:CommandForBrowserKeyboardShortcut];
|
| +bool HandleExtraBrowserKeyboardShortcut(NSEvent* event, NSWindow* window) {
|
| + return HandleExtraKeyboardShortcut(event, window,
|
| + CommandForBrowserKeyboardShortcut);
|
| +}
|
| +
|
| +// Duplicate the given key event, but changing the associated window.
|
| +NSEvent* KeyEventForWindow(NSWindow* window, NSEvent* event) {
|
| + NSEventType event_type = [event type];
|
| +
|
| + // Convert the event's location from the original window's coordinates into
|
| + // our own.
|
| + NSPoint location = [event locationInWindow];
|
| + location = [[event window] convertBaseToScreen:location];
|
| + location = [window convertScreenToBase:location];
|
| +
|
| + // Various things *only* apply to key down/up.
|
| + bool is_a_repeat = false;
|
| + NSString* characters = nil;
|
| + NSString* charactors_ignoring_modifiers = nil;
|
| + if (event_type == NSKeyDown || event_type == NSKeyUp) {
|
| + is_a_repeat = [event isARepeat];
|
| + characters = [event characters];
|
| + charactors_ignoring_modifiers = [event charactersIgnoringModifiers];
|
| + }
|
| +
|
| + // This synthesis may be slightly imperfect: we provide nil for the context,
|
| + // since I (viettrungluu) am sceptical that putting in the original context
|
| + // (if one is given) is valid.
|
| + return [NSEvent keyEventWithType:event_type
|
| + location:location
|
| + modifierFlags:[event modifierFlags]
|
| + timestamp:[event timestamp]
|
| + windowNumber:[window windowNumber]
|
| + context:nil
|
| + characters:characters
|
| + charactersIgnoringModifiers:charactors_ignoring_modifiers
|
| + isARepeat:is_a_repeat
|
| + keyCode:[event keyCode]];
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +@implementation ChromeEventProcessingWindow
|
| +
|
| +- (BOOL)handleExtraKeyboardShortcut:(NSEvent*)event {
|
| + return HandleExtraBrowserKeyboardShortcut(event, self) ||
|
| + HandleExtraWindowKeyboardShortcut(event, self) ||
|
| + HandleDelayedWindowKeyboardShortcut(event, self);
|
| }
|
|
|
| - (BOOL)performKeyEquivalent:(NSEvent*)event {
|
| @@ -86,15 +133,10 @@ typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar);
|
| if ([r conformsToProtocol:@protocol(RenderWidgetHostViewMacBase)])
|
| return [r performKeyEquivalent:event];
|
|
|
| - // If the delegate does not implement the BrowserCommandExecutor protocol,
|
| - // then we don't need to handle browser specific shortcut keys.
|
| - if (![[self delegate] conformsToProtocol:@protocol(BrowserCommandExecutor)])
|
| - return [super performKeyEquivalent:event];
|
| -
|
| // Handle per-window shortcuts like cmd-1, but do not handle browser-level
|
| // shortcuts like cmd-left (else, cmd-left would do history navigation even
|
| // if e.g. the Omnibox has focus).
|
| - if ([self handleExtraWindowKeyboardShortcut:event])
|
| + if (HandleExtraWindowKeyboardShortcut(event, self))
|
| return YES;
|
|
|
| if ([super performKeyEquivalent:event])
|
| @@ -102,7 +144,7 @@ typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar);
|
|
|
| // Handle per-window shortcuts like Esc after giving everybody else a chance
|
| // to handle them
|
| - return [self handleDelayedWindowKeyboardShortcut:event];
|
| + return HandleDelayedWindowKeyboardShortcut(event, self);
|
| }
|
|
|
| - (BOOL)redispatchKeyEvent:(NSEvent*)event {
|
| @@ -122,7 +164,7 @@ typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar);
|
| // rare case, we synthesize a new key event so that its associate window
|
| // (number) is our own.
|
| if ([event window] != self)
|
| - event = [self keyEventForWindow:self fromKeyEvent:event];
|
| + event = KeyEventForWindow(self, event);
|
|
|
| // Redispatch the event.
|
| eventHandled_ = YES;
|
| @@ -143,38 +185,4 @@ typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar);
|
| eventHandled_ = NO;
|
| }
|
|
|
| -- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event {
|
| - NSEventType eventType = [event type];
|
| -
|
| - // Convert the event's location from the original window's coordinates into
|
| - // our own.
|
| - NSPoint eventLoc = [event locationInWindow];
|
| - eventLoc = [[event window] convertBaseToScreen:eventLoc];
|
| - eventLoc = [self convertScreenToBase:eventLoc];
|
| -
|
| - // Various things *only* apply to key down/up.
|
| - BOOL eventIsARepeat = NO;
|
| - NSString* eventCharacters = nil;
|
| - NSString* eventUnmodCharacters = nil;
|
| - if (eventType == NSKeyDown || eventType == NSKeyUp) {
|
| - eventIsARepeat = [event isARepeat];
|
| - eventCharacters = [event characters];
|
| - eventUnmodCharacters = [event charactersIgnoringModifiers];
|
| - }
|
| -
|
| - // This synthesis may be slightly imperfect: we provide nil for the context,
|
| - // since I (viettrungluu) am sceptical that putting in the original context
|
| - // (if one is given) is valid.
|
| - return [NSEvent keyEventWithType:eventType
|
| - location:eventLoc
|
| - modifierFlags:[event modifierFlags]
|
| - timestamp:[event timestamp]
|
| - windowNumber:[window windowNumber]
|
| - context:nil
|
| - characters:eventCharacters
|
| - charactersIgnoringModifiers:eventUnmodCharacters
|
| - isARepeat:eventIsARepeat
|
| - keyCode:[event keyCode]];
|
| -}
|
| -
|
| @end // ChromeEventProcessingWindow
|
|
|