diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-02 01:25:41 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-02 01:25:41 +0000 |
commit | 97df4b330f4a2b1a34adb1eb8e5f5e7f60d716ff (patch) | |
tree | 46cd48cb3b533fb88bb6e6975427e7741578cb5c /chrome | |
parent | 7a0f5a3abf37e21eb15f4fe4058e917426e2e105 (diff) | |
download | chromium_src-97df4b330f4a2b1a34adb1eb8e5f5e7f60d716ff.zip chromium_src-97df4b330f4a2b1a34adb1eb8e5f5e7f60d716ff.tar.gz chromium_src-97df4b330f4a2b1a34adb1eb8e5f5e7f60d716ff.tar.bz2 |
Don't send tab switching/killing/creating keyboard accelerators to pages. This avoids tabs maliciously preventing closing using ctrl+f4/ctrl+w/alt+f4, and also hung/slow renderers from making tab cycling sluggish.
BUG=5496
TEST=added ui test
Review URL: http://codereview.chromium.org/224023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27814 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
25 files changed, 198 insertions, 30 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index ae1b5538..13288c9 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -2108,6 +2108,28 @@ void Browser::ShowPageInfo(Profile* profile, window()->ShowPageInfo(profile, url, ssl, show_history); } +bool Browser::IsReservedAccelerator(const NativeWebKeyboardEvent& event) { + // Other platforms don't send close-app keyboard shortcuts to apps first. +#if defined(OS_WIN) + if ((event.modifiers & NativeWebKeyboardEvent::AltKey) && + event.windowsKeyCode == VK_F4) { + return true; + } +#endif + + int command_id = window()->GetCommandId(event); + return command_id == IDC_CLOSE_TAB || + command_id == IDC_CLOSE_POPUPS || + command_id == IDC_CLOSE_WINDOW || + command_id == IDC_NEW_INCOGNITO_WINDOW || + command_id == IDC_NEW_TAB || + command_id == IDC_NEW_WINDOW || + command_id == IDC_RESTORE_TAB || + command_id == IDC_SELECT_NEXT_TAB || + command_id == IDC_SELECT_PREVIOUS_TAB || + command_id == IDC_TASK_MANAGER; +} + void Browser::ShowRepostFormWarningDialog(TabContents *tab_contents) { window()->ShowRepostFormWarningDialog(tab_contents); } diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index be4e1c2..b83eeea 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -539,6 +539,7 @@ class Browser : public TabStripModelDelegate, const GURL& url, const NavigationEntry::SSLStatus& ssl, bool show_history); + virtual bool IsReservedAccelerator(const NativeWebKeyboardEvent& event); virtual void ShowRepostFormWarningDialog(TabContents* tab_contents); // Overridden from SelectFileDialog::Listener: diff --git a/chrome/browser/browser_focus_uitest.cc b/chrome/browser/browser_focus_uitest.cc index 89abf91..e5f014a 100644 --- a/chrome/browser/browser_focus_uitest.cc +++ b/chrome/browser/browser_focus_uitest.cc @@ -15,8 +15,13 @@ #include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/browser/view_ids.h" #include "chrome/common/chrome_paths.h" +#include "chrome/test/automation/browser_proxy.h" +#include "chrome/test/automation/tab_proxy.h" +#include "chrome/test/automation/window_proxy.h" #include "chrome/test/in_process_browser_test.h" +#include "chrome/test/ui/ui_test.h" #include "chrome/test/ui_test_utils.h" +#include "views/event.h" #include "views/focus/focus_manager.h" #include "views/view.h" #include "views/window/window.h" @@ -737,3 +742,38 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReloadCrashedTab) { browser()->ShowDownloadsTab(); CheckViewHasFocus(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW); } + +#if !defined(OS_MACOSX) // see BrowserWindowCocoa::GetCommandId +// Tests that tab related keyboard accelerators are reserved by the app. + +class BrowserInteractiveTest : public UITest { +}; + +TEST_F(BrowserInteractiveTest, ReserveKeyboardAccelerators) { + const std::string kBadPage = + "<html><script>" + "document.onkeydown = function() {" + " event.preventDefault();" + " return false;" + "}" + "</script></html>"; + scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); + browser->AppendTab(GURL("data:text/html," + kBadPage)); + int tab_count = 0; + ASSERT_TRUE(browser->GetTabCount(&tab_count)); + ASSERT_EQ(tab_count, 2); + + int active_tab = 0; + ASSERT_TRUE(browser->GetActiveTabIndex(&active_tab)); + ASSERT_EQ(active_tab, 1); + + scoped_refptr<WindowProxy> window(browser->GetWindow()); + ASSERT_TRUE(window->SimulateOSKeyPress( + base::VKEY_TAB, views::Event::EF_CONTROL_DOWN)); + ASSERT_TRUE(browser->WaitForTabToBecomeActive(0, action_max_timeout_ms())); + + ASSERT_TRUE(window->SimulateOSKeyPress( + base::VKEY_F4, views::Event::EF_CONTROL_DOWN)); + ASSERT_TRUE(browser->WaitForTabCountToBecome(1, action_max_timeout_ms())); +} +#endif diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h index 5de0857..b26b447 100644 --- a/chrome/browser/browser_window.h +++ b/chrome/browser/browser_window.h @@ -21,6 +21,7 @@ class TabContents; class TabContentsContainer; class TemplateURL; class ToolbarView; +struct NativeWebKeyboardEvent; namespace gfx { class Rect; @@ -255,6 +256,10 @@ class BrowserWindow { // Shows the app menu (for accessibility). virtual void ShowAppMenu() = 0; + // Returns the id of the keyboard accelerator associated with the given + // keyboard event if one exists, otherwise -1. + virtual int GetCommandId(const NativeWebKeyboardEvent& event) = 0; + // Construct a BrowserWindow implementation for the specified |browser|. static BrowserWindow* CreateBrowserWindow(Browser* browser); diff --git a/chrome/browser/chromeos/main_menu.h b/chrome/browser/chromeos/main_menu.h index 85bf5689..e1f7a5f 100644 --- a/chrome/browser/chromeos/main_menu.h +++ b/chrome/browser/chromeos/main_menu.h @@ -132,6 +132,9 @@ class MainMenu : public RenderViewHostDelegate, virtual void UpdateDragCursor(WebKit::WebDragOperation operation) {} virtual void GotFocus() {} virtual void TakeFocus(bool reverse) {} + virtual bool IsReservedAccelerator(const NativeWebKeyboardEvent& event) { + return false; + } virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {} virtual void HandleMouseEvent() {} virtual void HandleMouseLeave() {} diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h index 922e4f3..73e3bff 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.h +++ b/chrome/browser/cocoa/browser_window_cocoa.h @@ -88,6 +88,7 @@ class BrowserWindowCocoa : public BrowserWindow, bool show_history); virtual void ShowPageMenu(); virtual void ShowAppMenu(); + virtual int GetCommandId(const NativeWebKeyboardEvent& event); // Overridden from NotificationObserver virtual void Observe(NotificationType type, diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index a83e091..3afae7e 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -320,6 +320,12 @@ void BrowserWindowCocoa::ShowAppMenu() { // No-op. Mac doesn't support showing the menus via alt keys. } +int BrowserWindowCocoa::GetCommandId(const NativeWebKeyboardEvent& event) { + // TODO(port): return the command id if this is a keyboard accelerator. + // CommandForKeyboardShortcut() doesn't have the full list. + return -1; +} + void BrowserWindowCocoa::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index 84852e2..0f3f6d8 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -415,6 +415,10 @@ void ExtensionHost::GotFocus() { void ExtensionHost::TakeFocus(bool reverse) { } +bool ExtensionHost::IsReservedAccelerator(const NativeWebKeyboardEvent& event) { + return false; +} + void ExtensionHost::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { } diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h index 7f3ad2cf..70690ef 100644 --- a/chrome/browser/extensions/extension_host.h +++ b/chrome/browser/extensions/extension_host.h @@ -128,6 +128,7 @@ class ExtensionHost : public RenderViewHostDelegate, virtual void UpdateDragCursor(WebKit::WebDragOperation operation); virtual void GotFocus(); virtual void TakeFocus(bool reverse); + virtual bool IsReservedAccelerator(const NativeWebKeyboardEvent& event); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); virtual void HandleMouseEvent(); virtual void HandleMouseLeave(); diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 1fff4f4..d9a43ca 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -198,6 +198,10 @@ const struct AcceleratorMapping { { GDK_Page_Up, IDC_MOVE_TAB_PREVIOUS, GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) }, { GDK_Page_Up, IDC_SELECT_PREVIOUS_TAB, GDK_CONTROL_MASK }, + { GDK_t, IDC_NEW_TAB, GDK_CONTROL_MASK }, + { GDK_n, IDC_NEW_WINDOW, GDK_CONTROL_MASK }, + { GDK_n, IDC_NEW_INCOGNITO_WINDOW, + GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) }, { GDK_w, IDC_CLOSE_TAB, GDK_CONTROL_MASK }, { GDK_t, IDC_RESTORE_TAB, GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) }, @@ -361,18 +365,15 @@ int GetCommandId(guint accel_key, GdkModifierType modifier) { kAcceleratorMap[i].modifier_type == modifier) return kAcceleratorMap[i].command_id; } - NOTREACHED(); - return 0; + + return -1; } -// An event handler for key press events. We need to special case key -// combinations that are not valid gtk accelerators. This function returns -// TRUE if it can handle the key press. -gboolean HandleCustomAccelerator(guint keyval, GdkModifierType modifier, - Browser* browser) { +int GetCustomCommandId(guint keyval, GdkModifierType modifier) { // Filter modifier to only include accelerator modifiers. modifier = static_cast<GdkModifierType>( modifier & gtk_accelerator_get_default_mod_mask()); + switch (keyval) { // Gtk doesn't allow GDK_Tab or GDK_ISO_Left_Tab to be an accelerator (see // gtk_accelerator_valid), so we need to handle these accelerators @@ -384,18 +385,29 @@ gboolean HandleCustomAccelerator(guint keyval, GdkModifierType modifier, case GDK_ISO_Left_Tab: case GDK_KP_Tab: if (GDK_CONTROL_MASK == modifier) { - browser->ExecuteCommand(IDC_SELECT_NEXT_TAB); - return TRUE; + return IDC_SELECT_NEXT_TAB; } else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) { - browser->ExecuteCommand(IDC_SELECT_PREVIOUS_TAB); - return TRUE; + return IDC_SELECT_PREVIOUS_TAB; } break; default: break; } - return FALSE; + return -1; +} + +// An event handler for key press events. We need to special case key +// combinations that are not valid gtk accelerators. This function returns +// TRUE if it can handle the key press. +gboolean HandleCustomAccelerator(guint keyval, GdkModifierType modifier, + Browser* browser) { + int command = GetCustomCommandId(keyval, modifier); + if (command == -1) + return FALSE; + + browser->ExecuteCommand(command); + return TRUE; } // Handle accelerators that we don't want the native widget to be able to @@ -1153,6 +1165,18 @@ void BrowserWindowGtk::ShowPageMenu() { void BrowserWindowGtk::ShowAppMenu() { } +int BrowserWindowGtk::GetCommandId(const NativeWebKeyboardEvent& event) { + if (!event.os_event) + return -1; + + guint keyval = event.os_event->keyval; + GdkModifierType modifier = GdkModifierType(event.os_event->state); + int command = ::GetCommandId(keyval, modifier); + if (command == -1) + command = GetCustomCommandId(keyval, modifier); + return command; +} + void BrowserWindowGtk::ConfirmBrowserCloseWithPendingDownloads() { new DownloadInProgressDialogGtk(browser()); } @@ -1881,7 +1905,8 @@ gboolean BrowserWindowGtk::OnGtkAccelerator(GtkAccelGroup* accel_group, guint keyval, GdkModifierType modifier, BrowserWindowGtk* browser_window) { - int command_id = GetCommandId(keyval, modifier); + int command_id = ::GetCommandId(keyval, modifier); + DCHECK(command_id != -1); browser_window->ExecuteBrowserCommand(command_id); return TRUE; diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index d109821..549a84a 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -121,6 +121,7 @@ class BrowserWindowGtk : public BrowserWindow, bool show_history); virtual void ShowPageMenu(); virtual void ShowAppMenu(); + virtual int GetCommandId(const NativeWebKeyboardEvent& event); // Overridden from NotificationObserver: virtual void Observe(NotificationType type, diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 2b66289..c0cb864 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -1425,19 +1425,18 @@ void RenderViewHost::OnUserMetricsRecordAction(const std::wstring& action) { UserMetrics::RecordComputedAction(action.c_str(), process()->profile()); } +bool RenderViewHost::ShouldSendToRenderer(const NativeWebKeyboardEvent& event) { + RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); + if (!view) + return true; + return !view->IsReservedAccelerator(event); +} + void RenderViewHost::UnhandledKeyboardEvent( const NativeWebKeyboardEvent& event) { RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); - if (view) { - // TODO(brettw) why do we have to filter these types of events here. Can't - // the renderer just send us the ones we care abount, or maybe the view - // should be able to decide which ones it wants or not? - if ((event.type == WebInputEvent::RawKeyDown) || - (event.type == WebInputEvent::KeyDown) || - (event.type == WebInputEvent::Char)) { - view->HandleKeyboardEvent(event); - } - } + if (view) + view->HandleKeyboardEvent(event); } void RenderViewHost::OnUserGesture() { diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 328a566..72ee9eb 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -436,6 +436,7 @@ class RenderViewHost : public RenderWidgetHost, protected: // RenderWidgetHost protected overrides. + virtual bool ShouldSendToRenderer(const NativeWebKeyboardEvent& event); virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event); virtual void OnUserGesture(); virtual void NotifyRendererUnresponsive(); diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index 9c121a1..d31d94c 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -125,6 +125,10 @@ class RenderViewHostDelegate { // true, it means the focus was retrieved by doing a Shift-Tab. virtual void TakeFocus(bool reverse) = 0; + // Returns whether the event is a reserved keyboard shortcut that should not + // be sent to the renderer. + virtual bool IsReservedAccelerator(const NativeWebKeyboardEvent& event) = 0; + // Callback to inform the browser that the renderer did not process the // specified events. This gives an opportunity to the browser to process the // event (used for keyboard shortcuts). diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index d9971ec..01ee015 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -400,6 +400,13 @@ void RenderWidgetHost::ForwardKeyboardEvent( if (!process_->HasConnection()) return; + // Tab switching/closing accelerators aren't sent to the renderer to avoid a + // hung/malicious renderer from interfering. + if (!ShouldSendToRenderer(key_event)) { + UnhandledKeyboardEvent(key_event); + return; + } + // Put all WebKeyboardEvent objects in a queue since we can't trust the // renderer and we need to give something to the UnhandledInputEvent // handler. @@ -754,7 +761,7 @@ void RenderWidgetHost::OnMsgInputEventAck(const IPC::Message& message) { if (!message.ReadBool(&iter, &processed)) process()->ReceivedBadMessage(message.type()); - KeyQueue::value_type front_item = key_queue_.front(); + NativeWebKeyboardEvent front_item = key_queue_.front(); key_queue_.pop(); if (!processed) { diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h index a80d1fd..2438e16 100644 --- a/chrome/browser/renderer_host/render_widget_host.h +++ b/chrome/browser/renderer_host/render_widget_host.h @@ -357,6 +357,12 @@ class RenderWidgetHost : public IPC::Channel::Listener, // This is used for various IPC messages, including plugins. gfx::NativeViewId GetNativeViewId(); + // Called when an InputEvent is received to check if the event should be sent + // to the renderer or not. + virtual bool ShouldSendToRenderer(const NativeWebKeyboardEvent& event) { + return true; + } + // Called when we an InputEvent was not processed by the renderer. This is // overridden by RenderView to send upwards to its delegate. virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event) {} diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc index 0440820..d382aff 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -519,6 +519,9 @@ void RenderWidgetHostViewGtk::Destroy() { // See http://www.crbug.com/11847 for details. gtk_widget_destroy(view_.get()); + // The RenderWidgetHost's destruction led here, so don't call it. + host_ = NULL; + MessageLoop::current()->DeleteSoon(FROM_HERE, this); } @@ -643,6 +646,9 @@ void RenderWidgetHostViewGtk::DestroyPluginContainer( void RenderWidgetHostViewGtk::ForwardKeyboardEvent( const NativeWebKeyboardEvent& event) { + if (!host_) + return; + EditCommands edit_commands; if (key_bindings_handler_->Match(event, &edit_commands)) { host_->ForwardEditCommandsForNextKeyEvent(edit_commands); diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.h b/chrome/browser/renderer_host/render_widget_host_view_gtk.h index 2f7e6b3..933629e 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.h +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.h @@ -90,7 +90,7 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView { void ShowCurrentCursor(); // The model object. - RenderWidgetHost* const host_; + RenderWidgetHost* host_; // The native UI widget. OwnedWidgetGtk view_; diff --git a/chrome/browser/tab_contents/interstitial_page.cc b/chrome/browser/tab_contents/interstitial_page.cc index 4191d4d..935dc1c 100644 --- a/chrome/browser/tab_contents/interstitial_page.cc +++ b/chrome/browser/tab_contents/interstitial_page.cc @@ -93,6 +93,7 @@ class InterstitialPage::InterstitialPageRVHViewDelegate virtual void UpdateDragCursor(WebDragOperation operation); virtual void GotFocus(); virtual void TakeFocus(bool reverse); + virtual bool IsReservedAccelerator(const NativeWebKeyboardEvent& event); virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); virtual void HandleMouseEvent(); virtual void HandleMouseLeave(); @@ -575,6 +576,11 @@ void InterstitialPage::InterstitialPageRVHViewDelegate::TakeFocus( interstitial_page_->tab()->GetViewDelegate()->TakeFocus(reverse); } +bool InterstitialPage::InterstitialPageRVHViewDelegate::IsReservedAccelerator( + const NativeWebKeyboardEvent& event) { + return false; +} + void InterstitialPage::InterstitialPageRVHViewDelegate::HandleKeyboardEvent( const NativeWebKeyboardEvent& event) { if (interstitial_page_->tab() && interstitial_page_->tab()->GetViewDelegate()) diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h index 156bb18..c61a4d7 100644 --- a/chrome/browser/tab_contents/tab_contents_delegate.h +++ b/chrome/browser/tab_contents/tab_contents_delegate.h @@ -214,6 +214,12 @@ class TabContentsDelegate { bool show_history) { } + // Returns whether the event is a reserved keyboard shortcut that should not + // be sent to the renderer. + virtual bool IsReservedAccelerator(const NativeWebKeyboardEvent& event) { + return false; + } + // Allows delegates to handle unhandled keyboard messages coming back from // the renderer. // Returns true if the keyboard message was handled. diff --git a/chrome/browser/tab_contents/tab_contents_view.cc b/chrome/browser/tab_contents/tab_contents_view.cc index 7a45e04..99a052a 100644 --- a/chrome/browser/tab_contents/tab_contents_view.cc +++ b/chrome/browser/tab_contents/tab_contents_view.cc @@ -56,6 +56,12 @@ void TabContentsView::ShowCreatedWidget(int route_id, ShowCreatedWidgetInternal(widget_host_view, initial_pos); } +bool TabContentsView::IsReservedAccelerator( + const NativeWebKeyboardEvent& event) { + return tab_contents()->delegate() && + tab_contents()->delegate()->IsReservedAccelerator(event); +} + RenderWidgetHostView* TabContentsView::CreateNewWidgetInternal( int route_id, bool activatable) { return delegate_view_helper_.CreateNewWidget(route_id, activatable, diff --git a/chrome/browser/tab_contents/tab_contents_view.h b/chrome/browser/tab_contents/tab_contents_view.h index ca42276..978b086 100644 --- a/chrome/browser/tab_contents/tab_contents_view.h +++ b/chrome/browser/tab_contents/tab_contents_view.h @@ -20,11 +20,6 @@ class RenderViewHost; class RenderWidgetHost; class RenderWidgetHostView; class TabContents; -class WebKeyboardEvent; - -namespace base { -class WaitableEvent; -} // The TabContentsView is an interface that is implemented by the platform- // dependent web contents views. The TabContents uses this interface to talk to @@ -181,6 +176,7 @@ class TabContentsView : public RenderViewHostDelegate::View { bool user_gesture, const GURL& creator_url); virtual void ShowCreatedWidget(int route_id, const gfx::Rect& initial_pos); + virtual bool IsReservedAccelerator(const NativeWebKeyboardEvent& event); // The TabContents whose contents we display. TabContents* tab_contents_; diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 50fd3bd..a9fea14 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -12,6 +12,7 @@ #include "base/command_line.h" #include "base/keyboard_codes.h" #include "base/time.h" +#include "base/win_util.h" #include "build/build_config.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/app_modal_dialog_queue.h" @@ -48,6 +49,7 @@ #include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/browser/window_sizer.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/native_web_keyboard_event.h" #include "chrome/common/native_window_notification_source.h" #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" @@ -1127,6 +1129,24 @@ void BrowserView::ShowAppMenu() { toolbar_->app_menu()->Activate(); } +int BrowserView::GetCommandId(const NativeWebKeyboardEvent& event) { + views::Accelerator accelerator( + win_util::WinToKeyboardCode(event.windowsKeyCode), + (event.modifiers & NativeWebKeyboardEvent::ShiftKey) == + NativeWebKeyboardEvent::ShiftKey, + (event.modifiers & NativeWebKeyboardEvent::ControlKey) == + NativeWebKeyboardEvent::ControlKey, + (event.modifiers & NativeWebKeyboardEvent::AltKey) == + NativeWebKeyboardEvent::AltKey); + + std::map<views::Accelerator, int>::const_iterator iter = + accelerator_table_.find(accelerator); + if (iter == accelerator_table_.end()) + return -1; + + return iter->second; +} + /////////////////////////////////////////////////////////////////////////////// // BrowserView, BrowserWindowTesting implementation: diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index f910e29..f4f2c2e 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -261,6 +261,7 @@ class BrowserView : public BrowserWindow, bool show_history); virtual void ShowAppMenu(); virtual void ShowPageMenu(); + virtual int GetCommandId(const NativeWebKeyboardEvent& event); // Overridden from BrowserWindowTesting: virtual BookmarkBarView* GetBookmarkBarView() const; diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h index 636e951..0859089 100644 --- a/chrome/test/test_browser_window.h +++ b/chrome/test/test_browser_window.h @@ -53,6 +53,7 @@ class TestBrowserWindow : public BrowserWindow { virtual void FocusToolbar() {} virtual void ShowPageMenu() {} virtual void ShowAppMenu() {} + virtual int GetCommandId(const NativeWebKeyboardEvent& event) { return -1; } virtual bool IsBookmarkBarVisible() const { return false; } virtual gfx::Rect GetRootWindowResizerRect() const { return gfx::Rect(); } virtual void ConfirmAddSearchProvider(const TemplateURL* template_url, |