diff options
author | suzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-25 06:13:43 +0000 |
---|---|---|
committer | suzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-25 06:13:43 +0000 |
commit | f8e55e7f62fbc1156c4bf99b114adb488f78ef6a (patch) | |
tree | 004b768e0103d6bafa6d5d23c53354f20561b0d8 /chrome | |
parent | 8dccd7cbab5135e60aa8f32d4a2ec8bbdd8068f5 (diff) | |
download | chromium_src-f8e55e7f62fbc1156c4bf99b114adb488f78ef6a.zip chromium_src-f8e55e7f62fbc1156c4bf99b114adb488f78ef6a.tar.gz chromium_src-f8e55e7f62fbc1156c4bf99b114adb488f78ef6a.tar.bz2 |
Handle keyboard events correctly in extension popups.
BUG=33221 Keyboard shortcuts doesn't work on extension bubble popups
TEST=Open an extension popup with a text box in it, then try to copy/paste text in the text box with cmd-c/v.
Review URL: http://codereview.chromium.org/654005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39989 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/cocoa/chrome_event_processing_window.mm | 7 | ||||
-rw-r--r-- | chrome/browser/cocoa/info_bubble_window.h | 6 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_host.cc | 17 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_host.h | 7 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_host_mac.h | 4 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_host_mac.mm | 17 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_mac.mm | 65 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 24 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.h | 17 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_view_mac.mm | 34 |
10 files changed, 112 insertions, 86 deletions
diff --git a/chrome/browser/cocoa/chrome_event_processing_window.mm b/chrome/browser/cocoa/chrome_event_processing_window.mm index c4bee5b..7426a94 100644 --- a/chrome/browser/cocoa/chrome_event_processing_window.mm +++ b/chrome/browser/cocoa/chrome_event_processing_window.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -70,6 +70,11 @@ typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int, unichar); if ([r isKindOfClass:[RenderWidgetHostViewCocoa class]]) 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). diff --git a/chrome/browser/cocoa/info_bubble_window.h b/chrome/browser/cocoa/info_bubble_window.h index b0d05c5..837b87f 100644 --- a/chrome/browser/cocoa/info_bubble_window.h +++ b/chrome/browser/cocoa/info_bubble_window.h @@ -1,12 +1,14 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #import <Cocoa/Cocoa.h> +#import "chrome/browser/cocoa/chrome_event_processing_window.h" + // A rounded window with an arrow used for example when you click on the STAR // button or that pops up within our first-run UI. -@interface InfoBubbleWindow : NSWindow { +@interface InfoBubbleWindow : ChromeEventProcessingWindow { @private // Is self in the process of closing. BOOL closing_; diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index e9fb5c4..78d83da 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -570,6 +570,7 @@ void ExtensionHost::TakeFocus(bool reverse) { bool ExtensionHost::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) { if (extension_host_type_ == ViewType::EXTENSION_POPUP && + event.type == NativeWebKeyboardEvent::RawKeyDown && event.windowsKeyCode == base::VKEY_ESCAPE) { DCHECK(is_keyboard_shortcut != NULL); *is_keyboard_shortcut = true; @@ -578,13 +579,17 @@ bool ExtensionHost::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, } void ExtensionHost::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { - if (extension_host_type_ == ViewType::EXTENSION_POPUP && - event.windowsKeyCode == base::VKEY_ESCAPE) { - NotificationService::current()->Notify( - NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, - Source<Profile>(profile_), - Details<ExtensionHost>(this)); + if (extension_host_type_ == ViewType::EXTENSION_POPUP) { + if (event.type == NativeWebKeyboardEvent::RawKeyDown && + event.windowsKeyCode == base::VKEY_ESCAPE) { + NotificationService::current()->Notify( + NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE, + Source<Profile>(profile_), + Details<ExtensionHost>(this)); + return; + } } + UnhandledKeyboardEvent(event); } void ExtensionHost::HandleMouseEvent() { diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h index 2bd7906..c5ea9b2 100644 --- a/chrome/browser/extensions/extension_host.h +++ b/chrome/browser/extensions/extension_host.h @@ -81,6 +81,8 @@ class ExtensionHost : public ExtensionPopupHost::PopupDelegate, } Profile* profile() const { return profile_; } + ViewType::Type extension_host_type() const { return extension_host_type_; } + // Sets the the ViewType of this host (e.g. mole, toolstrip). void SetRenderViewType(ViewType::Type type); @@ -199,6 +201,11 @@ class ExtensionHost : public ExtensionPopupHost::PopupDelegate, return view()->native_view(); } + // Handles keyboard events that were not handled by HandleKeyboardEvent(). + // Platform specific implementation may override this method to handle the + // event in platform specific way. + virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event) {} + // Returns true if we're hosting a background page. // This isn't valid until CreateRenderView is called. bool is_background_page() const { return !view(); } diff --git a/chrome/browser/extensions/extension_host_mac.h b/chrome/browser/extensions/extension_host_mac.h index 0624826..8032fd9 100644 --- a/chrome/browser/extensions/extension_host_mac.h +++ b/chrome/browser/extensions/extension_host_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -21,6 +21,8 @@ class ExtensionHostMac : public ExtensionHost { virtual void ShowCreatedWidgetInternal(RenderWidgetHostView* widget_host_view, const gfx::Rect& initial_pos); private: + virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event); + DISALLOW_COPY_AND_ASSIGN(ExtensionHostMac); }; diff --git a/chrome/browser/extensions/extension_host_mac.mm b/chrome/browser/extensions/extension_host_mac.mm index d541deb..2dfc336 100644 --- a/chrome/browser/extensions/extension_host_mac.mm +++ b/chrome/browser/extensions/extension_host_mac.mm @@ -1,10 +1,12 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/extensions/extension_host_mac.h" +#import "chrome/browser/cocoa/chrome_event_processing_window.h" #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" +#include "chrome/common/native_web_keyboard_event.h" RenderWidgetHostView* ExtensionHostMac::CreateNewWidgetInternal( int route_id, @@ -35,3 +37,16 @@ void ExtensionHostMac::ShowCreatedWidgetInternal( static_cast<RenderWidgetHostViewMac*>(widget_host_view); [widget_view_mac->native_view() release]; } + +void ExtensionHostMac::UnhandledKeyboardEvent( + const NativeWebKeyboardEvent& event) { + if (event.skip_in_browser || event.type == NativeWebKeyboardEvent::Char || + extension_host_type() != ViewType::EXTENSION_POPUP) { + return; + } + + ChromeEventProcessingWindow* event_window = + static_cast<ChromeEventProcessingWindow*>([view()->native_view() window]); + DCHECK([event_window isKindOfClass:[ChromeEventProcessingWindow class]]); + [event_window redispatchKeyEvent:event.os_event]; +} diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm index b413c54..79beb00 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -16,6 +16,7 @@ #include "chrome/browser/plugin_process_host.h" #include "chrome/browser/renderer_host/backing_store_mac.h" #include "chrome/browser/renderer_host/render_process_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_widget_host.h" #include "chrome/browser/spellchecker_platform_engine.h" #include "chrome/common/native_web_keyboard_event.h" @@ -1082,6 +1083,19 @@ bool RenderWidgetHostViewMac::ContainsNativeView( - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { SEL action = [item action]; + // For now, these actions are always enabled for render view, + // this is sub-optimal. + // TODO(suzhe): Plumb the "can*" methods up from WebCore. + if (action == @selector(undo:) || + action == @selector(redo:) || + action == @selector(cut:) || + action == @selector(copy:) || + action == @selector(copyToFindPboard:) || + action == @selector(paste:) || + action == @selector(pasteAsPlainText:)) { + return renderWidgetHostView_->render_widget_host_->IsRenderView(); + } + return editCommand_helper_->IsMenuItemEnabled(action, self); } @@ -1584,4 +1598,53 @@ extern NSString *NSTextInputReplacementRangeAttributeName; } } +- (void)undo:(id)sender { + if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { + static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> + Undo(); + } +} + +- (void)redo:(id)sender { + if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { + static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> + Redo(); + } +} + +- (void)cut:(id)sender { + if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { + static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> + Cut(); + } +} + +- (void)copy:(id)sender { + if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { + static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> + Copy(); + } +} + +- (void)copyToFindPboard:(id)sender { + if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { + static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> + CopyToFindPboard(); + } +} + +- (void)paste:(id)sender { + if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { + static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> + Paste(); + } +} + +- (void)pasteAsPlainText:(id)sender { + if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { + static_cast<RenderViewHost*>(renderWidgetHostView_->render_widget_host_)-> + ForwardEditCommand("PasteAndMatchStyle", ""); + } +} + @end diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 98c41b18..b4aa4a2 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -768,30 +768,6 @@ void TabContents::Stop() { printing_.Stop(); } -void TabContents::Cut() { - render_view_host()->Cut(); -} - -void TabContents::Copy() { - render_view_host()->Copy(); -} - -#if defined(OS_MACOSX) -void TabContents::CopyToFindPboard() { - render_view_host()->CopyToFindPboard(); -} -#endif - -void TabContents::Paste() { - render_view_host()->Paste(); -} - -#if defined(OS_MACOSX) -void TabContents::PasteAndMatchStyle() { - render_view_host()->ForwardEditCommand("PasteAndMatchStyle", ""); -} -#endif - void TabContents::DisassociateFromPopupCount() { render_view_host()->DisassociateFromPopupCount(); } diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 1ee1126..6df01f0 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -327,23 +327,6 @@ class TabContents : public PageNavigator, // Stop any pending navigation. virtual void Stop(); - // TODO(erg): HACK ALERT! This was thrown together for beta and - // needs to be completely removed after we ship it. Right now, the - // cut/copy/paste menu items are always enabled and will send a - // cut/copy/paste command to the currently visible - // TabContents. Post-beta, this needs to be replaced with a unified - // interface for supporting cut/copy/paste, and managing who has - // cut/copy/paste focus. (http://b/1117225) - virtual void Cut(); - virtual void Copy(); -#if defined(OS_MACOSX) - virtual void CopyToFindPboard(); -#endif - virtual void Paste(); -#if defined(OS_MACOSX) - virtual void PasteAndMatchStyle(); -#endif - // Called on a TabContents when it isn't a popup, but a new window. virtual void DisassociateFromPopupCount(); diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm index 5559fe8..8a87923 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.mm +++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -366,43 +366,11 @@ void TabContentsViewMac::Observe(NotificationType type, return NO; } -// In the Windows version, we always have cut/copy/paste enabled. This is sub- -// optimal, but we do it too. TODO(avi): Plumb the "can*" methods up from -// WebCore. - -- (void)cut:(id)sender { - [self tabContents]->Cut(); -} - -- (void)copy:(id)sender { - [self tabContents]->Copy(); -} - -- (void)copyToFindPboard:(id)sender { - [self tabContents]->CopyToFindPboard(); -} - -- (void)paste:(id)sender { - [self tabContents]->Paste(); -} - -- (void)pasteAsPlainText:(id)sender { - [self tabContents]->PasteAndMatchStyle(); -} - - (void)pasteboard:(NSPasteboard*)sender provideDataForType:(NSString*)type { [dragSource_ lazyWriteToPasteboard:sender forType:type]; } -- (void)undo:(id)sender { - [self tabContents]->render_view_host()->Undo(); -} - -- (void)redo:(id)sender { - [self tabContents]->render_view_host()->Redo(); -} - - (void)startDragWithDropData:(const WebDropData&)dropData dragOperationMask:(NSDragOperation)operationMask { dragSource_.reset([[WebDragSource alloc] |