diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-18 08:56:18 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-18 08:56:18 +0000 |
commit | 1ade7b6573cd86b9969740d7cc0376a6be23f385 (patch) | |
tree | 803722693e07073c11e30b7e31a56bd6c6a0d820 /chrome | |
parent | 82bf749a2af4de1a5e1dcafd3f211993582bf24b (diff) | |
download | chromium_src-1ade7b6573cd86b9969740d7cc0376a6be23f385.zip chromium_src-1ade7b6573cd86b9969740d7cc0376a6be23f385.tar.gz chromium_src-1ade7b6573cd86b9969740d7cc0376a6be23f385.tar.bz2 |
Add a keyboard shortcut on Escape that emits the IDC_STOP command.
BUG=20916
TEST=Load something big (http://cnn.com/) and hit escape. Page load will stop.
Review URL: http://codereview.chromium.org/491023
Patch from Jochen Eisinger.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34942 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
7 files changed, 81 insertions, 7 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm index 9fab62f..3a38f58 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm @@ -600,8 +600,7 @@ bool AutocompleteEditViewMac::OnDoCommandBySelector(SEL cmd) { } if (cmd == @selector(cancelOperation:)) { - model_->OnEscapeKeyPressed(); - return true; + return model_->OnEscapeKeyPressed(); } if (cmd == @selector(insertTab:)) { diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index 3849510..b01a844 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -486,6 +486,9 @@ bool BrowserWindowCocoa::HandleKeyboardEventInternal(NSEvent* event) { if ([event_window handleExtraWindowKeyboardShortcut:event]) return true; + + if ([event_window handleDelayedWindowKeyboardShortcut:event]) + return true; } return [event_window redispatchEvent:event]; diff --git a/chrome/browser/cocoa/chrome_event_processing_window.h b/chrome/browser/cocoa/chrome_event_processing_window.h index 78cc747..0d9cfbb 100644 --- a/chrome/browser/cocoa/chrome_event_processing_window.h +++ b/chrome/browser/cocoa/chrome_event_processing_window.h @@ -31,6 +31,10 @@ // window controller's |executeCommand:| and returns |YES|. - (BOOL)handleExtraWindowKeyboardShortcut:(NSEvent*)event; +// Checks if |event| is a delayed window keyboard shortcut. If so, dispatches +// it to the window controller's |executeCommand:| and returns |YES|. +- (BOOL)handleDelayedWindowKeyboardShortcut:(NSEvent*)event; + // Checks if |event| is a browser keyboard shortcut. If so, dispatches it to the // window controller's |executeCommand:| and returns |YES|. - (BOOL)handleExtraBrowserKeyboardShortcut:(NSEvent*)event; diff --git a/chrome/browser/cocoa/chrome_event_processing_window.mm b/chrome/browser/cocoa/chrome_event_processing_window.mm index da23e7e..b5c43e0 100644 --- a/chrome/browser/cocoa/chrome_event_processing_window.mm +++ b/chrome/browser/cocoa/chrome_event_processing_window.mm @@ -44,6 +44,11 @@ typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int); fromTable:CommandForWindowKeyboardShortcut]; } +- (BOOL)handleDelayedWindowKeyboardShortcut:(NSEvent*)event { + return [self handleExtraKeyboardShortcut:event + fromTable:CommandForDelayedWindowKeyboardShortcut]; +} + - (BOOL)handleExtraBrowserKeyboardShortcut:(NSEvent*)event { return [self handleExtraKeyboardShortcut:event fromTable:CommandForBrowserKeyboardShortcut]; @@ -64,7 +69,13 @@ typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int); // if e.g. the Omnibox has focus). if ([self handleExtraWindowKeyboardShortcut:event]) return YES; - return [super performKeyEquivalent:event]; + + if ([super performKeyEquivalent:event]) + return YES; + + // Handle per-window shortcuts like Esc after giving everybody else a chance + // to handle them + return [self handleDelayedWindowKeyboardShortcut:event]; } - (BOOL)redispatchEvent:(NSEvent*)event { diff --git a/chrome/browser/global_keyboard_shortcuts_mac.h b/chrome/browser/global_keyboard_shortcuts_mac.h index 13a4587..d72c8aa 100644 --- a/chrome/browser/global_keyboard_shortcuts_mac.h +++ b/chrome/browser/global_keyboard_shortcuts_mac.h @@ -20,10 +20,13 @@ struct KeyboardShortcutData { // returns: Command number (as passed to Browser::ExecuteCommand) or -1 if there // was no match. // -// |performKeyEquivalent:| bubbles events up from the window to the views. -// If we let it bubble up to the Omnibox, then the Omnibox handles -// cmd-left/right just fine, but it swallows cmd-1 and doesn't give us a chance -// to intercept this. Hence, we need two types of keyboard shortcuts. +// |performKeyEquivalent:| bubbles events up from the window to the views. If +// we let it bubble up to the Omnibox, then the Omnibox handles cmd-left/right +// just fine, but it swallows cmd-1 and doesn't give us a chance to intercept +// this. Hence, we need three types of keyboard shortcuts: shortcuts that are +// intercepted before the Omnibox handles events, shortcuts that are +// intercepted after the Omnibox had a chance but did not handle them, and +// shortcuts that are only handled when tab contents is focused. // // This means cmd-left doesn't work if you hit cmd-l tab, which focusses // something that's neither omnibox nor tab contents. This behavior is @@ -38,6 +41,13 @@ int CommandForWindowKeyboardShortcut( bool command_key, bool shift_key, bool cntrl_key, bool opt_key, int vkey_code); +// This returns shortcuts that should work no matter what component of the +// browser is focused. They are executed by the window, after any view has the +// opportunity to override the shortcut +int CommandForDelayedWindowKeyboardShortcut( + bool command_key, bool shift_key, bool cntrl_key, bool opt_key, + int vkey_code); + // This returns shortcuts that should work only if the tab contents have focus // (e.g. cmd-left, which shouldn't do history navigation if e.g. the omnibox has // focus). @@ -48,6 +58,8 @@ int CommandForBrowserKeyboardShortcut( // For testing purposes. const KeyboardShortcutData* GetWindowKeyboardShortcutTable(size_t* num_entries); const KeyboardShortcutData* + GetDelayedWindowKeyboardShortcutTable(size_t* num_entries); +const KeyboardShortcutData* GetBrowserKeyboardShortcutTable(size_t* num_entries); #endif // #ifndef CHROME_BROWSER_GLOBAL_KEYBOARD_SHORTCUTS_MAC_H_ diff --git a/chrome/browser/global_keyboard_shortcuts_mac.mm b/chrome/browser/global_keyboard_shortcuts_mac.mm index 1d97f99..4872a40 100644 --- a/chrome/browser/global_keyboard_shortcuts_mac.mm +++ b/chrome/browser/global_keyboard_shortcuts_mac.mm @@ -9,6 +9,14 @@ #include "base/basictypes.h" #include "chrome/app/chrome_dll_resource.h" +// Basically, there are two kinds of keyboard shortcuts: Ones that should work +// only if the tab contents is focused (BrowserKeyboardShortcut), and ones that +// should work in all other cases (WindowKeyboardShortcut). In the latter case, +// we differentiate between shortcuts that are checked before any other view +// gets the chance to handle them (WindowKeyboardShortcut) or after all views +// had a chance but did not handle the keypress event +// (DelayedWindowKeyboardShortcut) + const KeyboardShortcutData* GetWindowKeyboardShortcutTable (size_t* num_entries) { static const KeyboardShortcutData keyboard_shortcuts[] = { @@ -35,6 +43,17 @@ const KeyboardShortcutData* GetWindowKeyboardShortcutTable return keyboard_shortcuts; } +const KeyboardShortcutData* GetDelayedWindowKeyboardShortcutTable + (size_t* num_entries) { + static const KeyboardShortcutData keyboard_shortcuts[] = { + {false, false, false, false, kVK_Escape, IDC_STOP}, + }; + + *num_entries = arraysize(keyboard_shortcuts); + + return keyboard_shortcuts; +} + const KeyboardShortcutData* GetBrowserKeyboardShortcutTable (size_t* num_entries) { static const KeyboardShortcutData keyboard_shortcuts[] = { @@ -82,6 +101,14 @@ int CommandForWindowKeyboardShortcut( cntrl_key, opt_key, vkey_code); } +int CommandForDelayedWindowKeyboardShortcut( + bool command_key, bool shift_key, bool cntrl_key, bool opt_key, + int vkey_code) { + return CommandForKeyboardShortcut(GetDelayedWindowKeyboardShortcutTable, + command_key, shift_key, + cntrl_key, opt_key, vkey_code); +} + int CommandForBrowserKeyboardShortcut( bool command_key, bool shift_key, bool cntrl_key, bool opt_key, int vkey_code) { diff --git a/chrome/browser/global_keyboard_shortcuts_mac_unittest.cc b/chrome/browser/global_keyboard_shortcuts_mac_unittest.cc index 39199bb..f2a88ac 100644 --- a/chrome/browser/global_keyboard_shortcuts_mac_unittest.cc +++ b/chrome/browser/global_keyboard_shortcuts_mac_unittest.cc @@ -34,6 +34,24 @@ TEST(GlobalKeyboardShortcuts, ShortcutsToWindowCommand) { false, false, false, false, kVK_Delete)); } +TEST(GlobalKeyboardShortcuts, ShortcutsToDelayedWindowCommand) { + // Test that an invalid shortcut translates into an invalid command id. + ASSERT_EQ(-1, + CommandForDelayedWindowKeyboardShortcut(false, false, false, false, 0)); + + // Check that all known keyboard shortcuts return valid results. + size_t num_shortcuts = 0; + const KeyboardShortcutData *it = + GetDelayedWindowKeyboardShortcutTable(&num_shortcuts); + ASSERT_GT(num_shortcuts, 0U); + for (size_t i = 0; i < num_shortcuts; ++i, ++it) { + int cmd_num = CommandForDelayedWindowKeyboardShortcut( + it->command_key, it->shift_key, it->cntrl_key, it->opt_key, + it->vkey_code); + ASSERT_EQ(cmd_num, it->chrome_command); + } +} + TEST(GlobalKeyboardShortcuts, ShortcutsToBrowserCommand) { // Test that an invalid shortcut translates into an invalid command id. ASSERT_EQ( |