Chromium Code Reviews| 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 afbc34cc9e5459268fc63f735ced47e5aedc5e2e..5a8c7532e54f5d188d13a779d702d19e0cafb8ed 100644 |
| --- a/ui/views/cocoa/bridged_content_view.mm |
| +++ b/ui/views/cocoa/bridged_content_view.mm |
| @@ -275,6 +275,11 @@ ui::TextEditCommand GetTextEditCommandForMenuAction(SEL action) { |
| // Passes |event| to the InputMethod for dispatch. |
| - (void)handleKeyEvent:(ui::KeyEvent*)event; |
| +// Allows accelerators to be handled at different points in AppKit key event |
| +// dispatch. Checks for an unhandled event passed in to -keyDown: and passes it |
| +// to the Widget for processing. Returns YES if the Widget handles it. |
| +- (BOOL)handleUnhandledKeyDownAsKeyEvent; |
| + |
| // Handles an NSResponder Action Message by mapping it to a corresponding text |
| // editing command from ui_strings.grd and, when not being sent to a |
| // TextInputClient, the keyCode that toolkit-views expects internally. |
| @@ -455,6 +460,16 @@ ui::TextEditCommand GetTextEditCommandForMenuAction(SEL action) { |
| hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(event); |
| } |
| +- (BOOL)handleUnhandledKeyDownAsKeyEvent { |
| + if (!keyDownEvent_) |
| + return NO; |
| + |
| + ui::KeyEvent event(keyDownEvent_); |
| + [self handleKeyEvent:&event]; |
| + keyDownEvent_ = nil; |
| + return event.handled(); |
| +} |
| + |
| - (void)handleAction:(ui::TextEditCommand)command |
| keyCode:(ui::KeyboardCode)keyCode |
| domCode:(ui::DomCode)domCode |
| @@ -512,6 +527,10 @@ ui::TextEditCommand GetTextEditCommandForMenuAction(SEL action) { |
| } else { |
| textInputClient_->InsertText(base::SysNSStringToUTF16(text)); |
| } |
| + |
| + // If -insertTextInternal: was invoked from -keyDown:, we don't want |
| + // to do -handleUnhandledKeyDownAsKeyEvent. |
| + keyDownEvent_ = nil; |
|
themblsha
2016/11/22 14:33:48
Fixex TextfieldTest.TextInputType_InsertionTest (a
tapted
2016/11/23 02:09:30
Acknowledged. The comment could be more terse, too
themblsha
2016/11/23 15:16:39
Done.
|
| return; |
| } |
| @@ -527,6 +546,10 @@ ui::TextEditCommand GetTextEditCommandForMenuAction(SEL action) { |
| if (isCharacterEvent) { |
| ui::KeyEvent charEvent = GetCharacterEventFromNSEvent(keyDownEvent_); |
| [self handleKeyEvent:&charEvent]; |
| + // Currently it doesn't seem that this code path could be reached from |
| + // -keyDown:. If it does, it needs an additional test case, and to clear the |
| + // keyDownEvent_ to avoid duplicate text processing. |
| + DCHECK(!keyDownEvent_); |
|
themblsha
2016/11/22 14:33:48
This didn't cause any problems with the tests I've
tapted
2016/11/23 02:09:30
It's easy to hit this DCHECK - just focus somethin
themblsha
2016/11/23 15:16:39
Ah. Duplicated "keyDownEvent_ = nil; // Handled."
|
| } |
| } |
| @@ -765,11 +788,27 @@ ui::TextEditCommand GetTextEditCommandForMenuAction(SEL action) { |
| // NSResponder implementation. |
| +- (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 language. In this case, |
| + // that's actually a good thing, though -- see http://crbug.com/26115 .) |
| + return YES; |
| +} |
| + |
| - (void)keyDown:(NSEvent*)theEvent { |
| // Convert the event into an action message, according to OSX key mappings. |
| keyDownEvent_ = theEvent; |
| [self interpretKeyEvents:@[ theEvent ]]; |
| - keyDownEvent_ = nil; |
| + |
| + // If |keyDownEvent_| wasn't cleared during -interpretKeyEvents:, it wasn't |
| + // handled. Give Widget accelerators a chance to handle it. |
| + [self handleUnhandledKeyDownAsKeyEvent]; |
| + DCHECK(!keyDownEvent_); |
| } |
| - (void)keyUp:(NSEvent*)theEvent { |
| @@ -1288,15 +1327,19 @@ ui::TextEditCommand GetTextEditCommandForMenuAction(SEL action) { |
| - (void)doCommandBySelector:(SEL)selector { |
| // Like the renderer, handle insert action messages as a regular key dispatch. |
| // This ensures, e.g., insertTab correctly changes focus between fields. |
| - if (keyDownEvent_ && [NSStringFromSelector(selector) hasPrefix:@"insert"]) { |
| - ui::KeyEvent event(keyDownEvent_); |
| - [self handleKeyEvent:&event]; |
| + if (keyDownEvent_ && [NSStringFromSelector(selector) hasPrefix:@"insert"]) |
| + return; // Handle in -keyDown:. |
| + |
| + if ([self respondsToSelector:selector]) { |
| + [self performSelector:selector withObject:nil]; |
| + keyDownEvent_ = nil; |
| return; |
| } |
| - if ([self respondsToSelector:selector]) |
| - [self performSelector:selector withObject:nil]; |
| - else |
| + // For events that AppKit sends via doCommandBySelector:, first attempt to |
| + // handle as a Widget accelerator. Forward along the responder chain only if |
| + // the Widget doesn't handle it. |
| + if (![self handleUnhandledKeyDownAsKeyEvent]) |
| [[self nextResponder] doCommandBySelector:selector]; |
| } |