summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chrome_browser_application_mac.mm17
-rw-r--r--chrome/browser/cocoa/chrome_event_processing_window.h4
-rw-r--r--chrome/browser/cocoa/chrome_event_processing_window.mm30
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm50
4 files changed, 52 insertions, 49 deletions
diff --git a/chrome/browser/chrome_browser_application_mac.mm b/chrome/browser/chrome_browser_application_mac.mm
index 57c6fab..48bef43 100644
--- a/chrome/browser/chrome_browser_application_mac.mm
+++ b/chrome/browser/chrome_browser_application_mac.mm
@@ -9,7 +9,6 @@
#import "base/scoped_nsobject.h"
#import "base/sys_string_conversions.h"
#import "chrome/app/breakpad_mac.h"
-#import "chrome/browser/cocoa/chrome_event_processing_window.h"
#import "chrome/browser/cocoa/objc_method_swizzle.h"
// The implementation of NSExceptions break various assumptions in the
@@ -243,22 +242,6 @@ BOOL SwizzleNSExceptionInit() {
return [super sendAction:anAction to:aTarget from:sender];
}
-- (void)sendEvent:(NSEvent*)event {
- chrome_application_mac::ScopedSendingEvent scoper(self);
- // The superclass's |sendEvent:| sends keyboard events to the menu and the key
- // view loop before dispatching them to |keyDown:|. Since we want to send keys
- // to the renderer before sending them to the menu, and we never want them to
- // the kev view loop when the web is focussed, we change this behavior.
- if ([[self keyWindow]
- isKindOfClass:[ChromeEventProcessingWindow class]]) {
- if ([static_cast<ChromeEventProcessingWindow*>([self keyWindow])
- shortcircuitEvent:event])
- return;
- }
-
- [super sendEvent:event];
-}
-
// NSExceptions which are caught by the event loop are logged here.
// NSException uses setjmp/longjmp, which can be very bad for C++, so
// we attempt to track and report them.
diff --git a/chrome/browser/cocoa/chrome_event_processing_window.h b/chrome/browser/cocoa/chrome_event_processing_window.h
index 4f13c27..78cc747 100644
--- a/chrome/browser/cocoa/chrome_event_processing_window.h
+++ b/chrome/browser/cocoa/chrome_event_processing_window.h
@@ -18,10 +18,6 @@
BOOL eventHandled_;
}
-// Returns |YES| if |event| has been shortcircuited and should not be processed
-// further.
-- (BOOL)shortcircuitEvent:(NSEvent*)event;
-
// Sends an event to |NSApp sendEvent:|, but also makes sure that it's not
// short-circuited to the RWHV. This is used to send keyboard events to the menu
// and the cmd-` handler if a keyboard event comes back unhandled from the
diff --git a/chrome/browser/cocoa/chrome_event_processing_window.mm b/chrome/browser/cocoa/chrome_event_processing_window.mm
index e70113a..99ed6af 100644
--- a/chrome/browser/cocoa/chrome_event_processing_window.mm
+++ b/chrome/browser/cocoa/chrome_event_processing_window.mm
@@ -49,37 +49,19 @@ typedef int (*KeyToCommandMapper)(bool, bool, bool, bool, int);
fromTable:CommandForBrowserKeyboardShortcut];
}
-- (BOOL)shortcircuitEvent:(NSEvent*)event {
- if (!redispatchingEvent_ &&
- ([event type] == NSKeyDown || [event type] == NSKeyUp)) {
- if ([[self firstResponder]
- isKindOfClass:[RenderWidgetHostViewCocoa class]]) {
- // No other mac browser sends keyup() for keyboard equivalents, so let's
- // suppress this.
- if (([event modifierFlags] & NSCommandKeyMask) && [event type] == NSKeyUp)
- return YES;
-
- RenderWidgetHostViewCocoa* rwhv = static_cast<RenderWidgetHostViewCocoa*>(
- [self firstResponder]);
- [rwhv keyEvent:event];
- return YES;
- }
- }
- return NO;
-}
-
- (BOOL)performKeyEquivalent:(NSEvent*)event {
if (redispatchingEvent_)
return NO;
- // |shortcircuitEvent:| should handle all events directed to the RWHV.
- DCHECK(![[self firstResponder]
- isKindOfClass:[RenderWidgetHostViewCocoa class]]);
+ // Give the web site a chance to handle the event. If it doesn't want to
+ // handle it, it will call us back with one of the |handle*| methods above.
+ NSResponder* r = [self firstResponder];
+ if ([r isKindOfClass:[RenderWidgetHostViewCocoa class]])
+ return [r 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). If the web has focus, don't do this here,
- // since the web needs to get a chance at swallowing the event first.
+ // if e.g. the Omnibox has focus).
if ([self handleExtraWindowKeyboardShortcut:event])
return YES;
return [super performKeyEquivalent: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 69a5620..2824592 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
@@ -557,16 +558,57 @@ void RenderWidgetHostViewMac::SetBackground(const SkBitmap& background) {
if (ignoreKeyEvents_)
return NO;
- // We have some magic in |CrApplication sendEvent:| that always sends key
- // events to |keyEvent:| so that cocoa doesn't have a chance to intercept it.
- DCHECK([[self window] firstResponder] != self);
- return NO;
+ // |performKeyEquivalent:| is sent to all views of a window, not only down the
+ // responder chain (cf. "Handling Key Equivalents" in
+ // http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/EventOverview/HandlingKeyEvents/HandlingKeyEvents.html
+ // ). 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;
+}
+
+- (BOOL)_wantsKeyDownForEvent:(NSEvent*)event {
+ // This is a SPI that AppKit apparently calls after |performKeyEquivalent:|
+ // returned NO. If this function returns |YES|, Cocoa sends the event to
+ // |keyDown:| instead of doing other things with it. Ctrl-tab will be sent
+ // to us instead of doing key view loop control, ctrl-left/right get handled
+ // correctly, etc.
+ // (However, there are still some keys that Cocoa swallows, e.g. the key
+ // equivalent that Cocoa uses for toggling the input langauge. In this case,
+ // that's actually a good thing, though -- see http://crbug.com/26115 .)
+ return YES;
}
- (void)keyEvent:(NSEvent*)theEvent {
+ [self keyEvent:theEvent wasKeyEquivalent:NO];
+}
+
+- (void)keyEvent:(NSEvent *)theEvent wasKeyEquivalent:(BOOL)equiv {
if (ignoreKeyEvents_)
return;
+ DCHECK([theEvent type] != NSKeyDown ||
+ !equiv == !([theEvent modifierFlags] & NSCommandKeyMask));
+
scoped_nsobject<RenderWidgetHostViewCocoa> keepSelfAlive([self retain]);
// Don't cancel child popups; the key events are probably what's triggering