diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-12 16:18:07 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-12 16:18:07 +0000 |
commit | c9fe2440f7cf280fc7a2ebd0b91acebb096bc4ab (patch) | |
tree | 42a57f5d33ae3cb4bc951e11a782f24670d88b0e | |
parent | 02fb75abae043fc1d6c14bebedeb6598dd955ef5 (diff) | |
download | chromium_src-c9fe2440f7cf280fc7a2ebd0b91acebb096bc4ab.zip chromium_src-c9fe2440f7cf280fc7a2ebd0b91acebb096bc4ab.tar.gz chromium_src-c9fe2440f7cf280fc7a2ebd0b91acebb096bc4ab.tar.bz2 |
Send key equivalents to renderer first.
Based on a patch by avi@.
See also http://codereview.chromium.org/271054 .
Known issues:
* Breaks if any menu item ever uses a keyboard accelerator that doesn't use cmd as part of the flags.
(* Suppressing keypress() doesn't prevent default action (suppressing keydown() works though. Both Firefox and Safari prevent the default action when either is suppressed). This seems to be broken on linux and windows too, though – it seems to match IE8, but not Firefox or Safari. I guess this is the question for the web council.)
BUG=15090
TEST=Cmd-f now sucks when used on google docs.
Review URL: http://codereview.chromium.org/242069
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28709 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_mac.mm | 35 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_view_mac.mm | 15 |
2 files changed, 47 insertions, 3 deletions
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 e6dc1fa..4a05273 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm @@ -29,6 +29,7 @@ using WebKit::WebMouseWheelEvent; @interface RenderWidgetHostViewCocoa (Private) + (BOOL)shouldAutohideCursorForEvent:(NSEvent*)event; - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r; +- (void)keyEvent:(NSEvent *)theEvent wasKeyEquivalent:(BOOL)equiv; - (void)cancelChildPopups; @end @@ -536,7 +537,41 @@ void RenderWidgetHostViewMac::SetBackground(const SkBitmap& background) { renderWidgetHostView_->render_widget_host_->ForwardMouseEvent(event); } +- (BOOL)performKeyEquivalent:(NSEvent*)theEvent { + // |performKeyEquivalent:| is sent to the whole view tree, not only down the + // responder chain. We only want to handle key equivalents if we're first + // responder. + if ([[self window] firstResponder] != self) + return NO; + + // If we return |NO| from this function, cocoa will send the key event to + // the menu and only if the menu does not process the event to |keyDown:|. We + // want to send the event to a renderer _before_ sending it to the menu, so + // we need to return |YES| for all events that might be swallowed by the menu. + // We do not return |YES| for every keypress because we don't get |keyDown:| + // events for keys that we handle this way. + NSUInteger modifierFlags = [theEvent modifierFlags]; + if ((modifierFlags & NSCommandKeyMask) == 0) { + // Make sure the menu does not contain key equivalents that don't + // contain cmd. + DCHECK(![[NSApp mainMenu] performKeyEquivalent:theEvent]); + return NO; + } + + // Command key combinations are sent via performKeyEquivalent rather than + // keyDown:. We just forward this on and if WebCore doesn't want to handle + // it, we let the TabContentsView figure out how to reinject it. + [self keyEvent:theEvent wasKeyEquivalent:YES]; + return YES; +} + - (void)keyEvent:(NSEvent*)theEvent { + [self keyEvent:theEvent wasKeyEquivalent:NO]; +} + +- (void)keyEvent:(NSEvent *)theEvent wasKeyEquivalent:(BOOL)equiv { + DCHECK([theEvent type] != NSKeyDown || + !equiv == !([theEvent modifierFlags] & NSCommandKeyMask)); // TODO(avi): Possibly kill self? See RenderWidgetHostViewWin::OnKeyEvent and // http://b/issue?id=1192881 . diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm index 03baffc..61195b1 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.mm +++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm @@ -43,7 +43,7 @@ COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery); @interface TabContentsViewCocoa (Private) - (id)initWithTabContentsViewMac:(TabContentsViewMac*)w; -- (void)processKeyboardEvent:(NSEvent*)event; +- (void)processKeyboardEvent:(NativeWebKeyboardEvent*)event; - (void)registerDragTypes; - (void)setCurrentDragOperation:(NSDragOperation)operation; - (void)startDragWithDropData:(const WebDropData&)dropData @@ -202,7 +202,8 @@ void TabContentsViewMac::TakeFocus(bool reverse) { void TabContentsViewMac::HandleKeyboardEvent( const NativeWebKeyboardEvent& event) { - [cocoa_view_.get() processKeyboardEvent:event.os_event]; + [cocoa_view_.get() processKeyboardEvent: + const_cast<NativeWebKeyboardEvent*>(&event)]; } void TabContentsViewMac::ShowContextMenu(const ContextMenuParams& params) { @@ -293,7 +294,15 @@ void TabContentsViewMac::Observe(NotificationType type, return tabContentsView_->tab_contents(); } -- (void)processKeyboardEvent:(NSEvent*)event { +- (void)processKeyboardEvent:(NativeWebKeyboardEvent*)wkEvent { + NSEvent* event = wkEvent->os_event; + + if ([event type] == NSKeyDown && ([event modifierFlags] & NSCommandKeyMask)) { + // We need to dispatch this to the menu. + if ([[NSApp mainMenu] performKeyEquivalent:event]) + return; + } + // If this tab is no longer active, it's window will be |nil|. In that case, // best ignore the event. if (![self window]) |