summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorsuzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-25 06:13:43 +0000
committersuzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-25 06:13:43 +0000
commitf8e55e7f62fbc1156c4bf99b114adb488f78ef6a (patch)
tree004b768e0103d6bafa6d5d23c53354f20561b0d8 /chrome
parent8dccd7cbab5135e60aa8f32d4a2ec8bbdd8068f5 (diff)
downloadchromium_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.mm7
-rw-r--r--chrome/browser/cocoa/info_bubble_window.h6
-rw-r--r--chrome/browser/extensions/extension_host.cc17
-rw-r--r--chrome/browser/extensions/extension_host.h7
-rw-r--r--chrome/browser/extensions/extension_host_mac.h4
-rw-r--r--chrome/browser/extensions/extension_host_mac.mm17
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm65
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc24
-rw-r--r--chrome/browser/tab_contents/tab_contents.h17
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_mac.mm34
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]