Index: ui/views/cocoa/bridged_content_view.mm |
diff --git a/ui/views/cocoa/bridged_content_view.mm b/ui/views/cocoa/bridged_content_view.mm |
index 8aabac1e8de7b0c320a6c882172715036dc2d133..3ee38a0b2b272b7d7c421e95cbbfb1c654ea3bab 100644 |
--- a/ui/views/cocoa/bridged_content_view.mm |
+++ b/ui/views/cocoa/bridged_content_view.mm |
@@ -14,9 +14,12 @@ |
#include "ui/gfx/canvas_paint_mac.h" |
#include "ui/gfx/geometry/rect.h" |
#include "ui/strings/grit/ui_strings.h" |
+#include "ui/views/controls/menu/menu_controller.h" |
#include "ui/views/view.h" |
#include "ui/views/widget/widget.h" |
+using views::MenuController; |
+ |
namespace { |
// Convert a |point| in |source_window|'s AppKit coordinate system (origin at |
@@ -134,6 +137,15 @@ gfx::Point MovePointToWindow(const NSPoint& point, |
if (!hostedView_) |
return; |
+ // If there's an active MenuController it gets preference, and it will likely |
+ // swallow the event. |
+ MenuController* menuController = MenuController::GetActiveInstance(); |
+ if (menuController && menuController->owner() == hostedView_->GetWidget()) { |
+ if (menuController->OnWillDispatchKeyEvent(0, keyCode) == |
+ ui::POST_DISPATCH_NONE) |
+ return; |
+ } |
+ |
// If there's an active TextInputClient, it ignores the key and processes the |
// logical editing action. |
if (commandId && textInputClient_ && |
@@ -175,6 +187,20 @@ gfx::Point MovePointToWindow(const NSPoint& point, |
hostedView_->GetWidget()->OnNativeWidgetPaint(&canvas); |
} |
+- (NSTextInputContext*)inputContext { |
+ if (!hostedView_) |
+ return [super inputContext]; |
+ |
+ // If a menu is active, and -[NSView interpretKeyEvents:] asks for the |
+ // input context, return nil. This ensures the action message is sent to |
+ // the view, rather than any NSTextInputClient a subview has installed. |
+ MenuController* menuController = MenuController::GetActiveInstance(); |
+ if (menuController && menuController->owner() == hostedView_->GetWidget()) |
+ return nil; |
+ |
+ return [super inputContext]; |
+} |
+ |
// NSResponder implementation. |
- (void)keyDown:(NSEvent*)theEvent { |
@@ -473,11 +499,36 @@ gfx::Point MovePointToWindow(const NSPoint& point, |
} |
- (void)insertText:(id)text replacementRange:(NSRange)replacementRange { |
- if (!textInputClient_) |
+ if (!hostedView_) |
return; |
if ([text isKindOfClass:[NSAttributedString class]]) |
text = [text string]; |
+ |
+ MenuController* menuController = MenuController::GetActiveInstance(); |
+ if (menuController && menuController->owner() == hostedView_->GetWidget()) { |
+ // Handle menu mnemonics (e.g. "sav" jumps to "Save"). Handles both single- |
+ // characters and input from IME. For IME, swallow the entire string unless |
+ // the very first character gives ui::POST_DISPATCH_PERFORM_DEFAULT. |
+ bool swallowedAny = false; |
+ for (NSUInteger i = 0; i < [text length]; ++i) { |
+ if (!menuController || |
+ menuController->OnWillDispatchKeyEvent([text characterAtIndex:i], |
+ ui::VKEY_UNKNOWN) == |
+ ui::POST_DISPATCH_PERFORM_DEFAULT) { |
+ if (swallowedAny) |
+ return; // Swallow remainder. |
+ break; |
+ } |
+ swallowedAny = true; |
+ // Ensure the menu remains active. |
+ menuController = MenuController::GetActiveInstance(); |
+ } |
+ } |
+ |
+ if (!textInputClient_) |
+ return; |
+ |
textInputClient_->DeleteRange(gfx::Range(replacementRange)); |
textInputClient_->InsertText(base::SysNSStringToUTF16(text)); |
} |