Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: ui/views/cocoa/bridged_content_view.mm

Issue 2505943002: MacViews: Fix accelerator handling while Omnibox is in focus. (Closed)
Patch Set: Fixed TextfieldTest.*, disable ViewTest.ActivateAcceleratorOnMac on non-MacViews. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ui/views/cocoa/bridged_content_view.h" 5 #import "ui/views/cocoa/bridged_content_view.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #import "base/mac/mac_util.h" 8 #import "base/mac/mac_util.h"
9 #import "base/mac/scoped_nsobject.h" 9 #import "base/mac/scoped_nsobject.h"
10 #import "base/mac/sdk_forward_declarations.h" 10 #import "base/mac/sdk_forward_declarations.h"
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 268
269 @interface BridgedContentView () 269 @interface BridgedContentView ()
270 270
271 // Returns the active menu controller corresponding to |hostedView_|, 271 // Returns the active menu controller corresponding to |hostedView_|,
272 // nil otherwise. 272 // nil otherwise.
273 - (MenuController*)activeMenuController; 273 - (MenuController*)activeMenuController;
274 274
275 // Passes |event| to the InputMethod for dispatch. 275 // Passes |event| to the InputMethod for dispatch.
276 - (void)handleKeyEvent:(ui::KeyEvent*)event; 276 - (void)handleKeyEvent:(ui::KeyEvent*)event;
277 277
278 // Allows accelerators to be handled at different points in AppKit key event
279 // dispatch. Checks for an unhandled event passed in to -keyDown: and passes it
280 // to the Widget for processing. Returns YES if the Widget handles it.
281 - (BOOL)handleUnhandledKeyDownAsKeyEvent;
282
278 // Handles an NSResponder Action Message by mapping it to a corresponding text 283 // Handles an NSResponder Action Message by mapping it to a corresponding text
279 // editing command from ui_strings.grd and, when not being sent to a 284 // editing command from ui_strings.grd and, when not being sent to a
280 // TextInputClient, the keyCode that toolkit-views expects internally. 285 // TextInputClient, the keyCode that toolkit-views expects internally.
281 // For example, moveToLeftEndOfLine: would pass ui::VKEY_HOME in non-RTL locales 286 // For example, moveToLeftEndOfLine: would pass ui::VKEY_HOME in non-RTL locales
282 // even though the Home key on Mac defaults to moveToBeginningOfDocument:. 287 // even though the Home key on Mac defaults to moveToBeginningOfDocument:.
283 // This approach also allows action messages a user 288 // This approach also allows action messages a user
284 // may have remapped in ~/Library/KeyBindings/DefaultKeyBinding.dict to be 289 // may have remapped in ~/Library/KeyBindings/DefaultKeyBinding.dict to be
285 // catered for. 290 // catered for.
286 // Note: default key bindings in Mac can be read from StandardKeyBinding.dict 291 // Note: default key bindings in Mac can be read from StandardKeyBinding.dict
287 // which lives in /System/Library/Frameworks/AppKit.framework/Resources. Do 292 // which lives in /System/Library/Frameworks/AppKit.framework/Resources. Do
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 if (!hostedView_) 453 if (!hostedView_)
449 return; 454 return;
450 455
451 DCHECK(event); 456 DCHECK(event);
452 if (DispatchEventToMenu([self activeMenuController], event)) 457 if (DispatchEventToMenu([self activeMenuController], event))
453 return; 458 return;
454 459
455 hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(event); 460 hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(event);
456 } 461 }
457 462
463 - (BOOL)handleUnhandledKeyDownAsKeyEvent {
464 if (!keyDownEvent_)
465 return NO;
466
467 ui::KeyEvent event(keyDownEvent_);
468 [self handleKeyEvent:&event];
469 keyDownEvent_ = nil;
470 return event.handled();
471 }
472
458 - (void)handleAction:(ui::TextEditCommand)command 473 - (void)handleAction:(ui::TextEditCommand)command
459 keyCode:(ui::KeyboardCode)keyCode 474 keyCode:(ui::KeyboardCode)keyCode
460 domCode:(ui::DomCode)domCode 475 domCode:(ui::DomCode)domCode
461 eventFlags:(int)eventFlags { 476 eventFlags:(int)eventFlags {
462 if (!hostedView_) 477 if (!hostedView_)
463 return; 478 return;
464 479
465 // Generate a synthetic event with the keycode toolkit-views expects. 480 // Generate a synthetic event with the keycode toolkit-views expects.
466 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags); 481 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags);
467 482
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 // ui::KeyEvent since for text inserted using an IME, [keyDownEvent_ 520 // ui::KeyEvent since for text inserted using an IME, [keyDownEvent_
506 // characters] might not be the same as |text|. This is because 521 // characters] might not be the same as |text|. This is because
507 // |keyDownEvent_| will correspond to the event that caused the composition 522 // |keyDownEvent_| will correspond to the event that caused the composition
508 // text to be confirmed, say, Return key press. 523 // text to be confirmed, say, Return key press.
509 if (isCharacterEvent) { 524 if (isCharacterEvent) {
510 textInputClient_->InsertChar(ui::KeyEvent([text characterAtIndex:0], 525 textInputClient_->InsertChar(ui::KeyEvent([text characterAtIndex:0],
511 ui::VKEY_UNKNOWN, ui::EF_NONE)); 526 ui::VKEY_UNKNOWN, ui::EF_NONE));
512 } else { 527 } else {
513 textInputClient_->InsertText(base::SysNSStringToUTF16(text)); 528 textInputClient_->InsertText(base::SysNSStringToUTF16(text));
514 } 529 }
530
531 // If -insertTextInternal: was invoked from -keyDown:, we don't want
532 // to do -handleUnhandledKeyDownAsKeyEvent.
533 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.
515 return; 534 return;
516 } 535 }
517 536
518 // Only handle the case where no. of characters is 1. Cases not handled (not 537 // Only handle the case where no. of characters is 1. Cases not handled (not
519 // an exhaustive list): 538 // an exhaustive list):
520 // - |text| contains a unicode surrogate pair, i.e. a single grapheme which 539 // - |text| contains a unicode surrogate pair, i.e. a single grapheme which
521 // requires two 16 bit characters. Currently Views menu only supports 540 // requires two 16 bit characters. Currently Views menu only supports
522 // mnemonics using a single 16 bit character, so it is ok to ignore this 541 // mnemonics using a single 16 bit character, so it is ok to ignore this
523 // case. 542 // case.
524 // - Programmatically created events. 543 // - Programmatically created events.
525 // - Input from IME. But this case should not occur since inputContext is 544 // - Input from IME. But this case should not occur since inputContext is
526 // nil. 545 // nil.
527 if (isCharacterEvent) { 546 if (isCharacterEvent) {
528 ui::KeyEvent charEvent = GetCharacterEventFromNSEvent(keyDownEvent_); 547 ui::KeyEvent charEvent = GetCharacterEventFromNSEvent(keyDownEvent_);
529 [self handleKeyEvent:&charEvent]; 548 [self handleKeyEvent:&charEvent];
549 // Currently it doesn't seem that this code path could be reached from
550 // -keyDown:. If it does, it needs an additional test case, and to clear the
551 // keyDownEvent_ to avoid duplicate text processing.
552 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."
530 } 553 }
531 } 554 }
532 555
533 - (views::DragDropClientMac*)dragDropClient { 556 - (views::DragDropClientMac*)dragDropClient {
534 views::BridgedNativeWidget* bridge = 557 views::BridgedNativeWidget* bridge =
535 views::NativeWidgetMac::GetBridgeForNativeWindow([self window]); 558 views::NativeWidgetMac::GetBridgeForNativeWindow([self window]);
536 return bridge ? bridge->drag_drop_client() : nullptr; 559 return bridge ? bridge->drag_drop_client() : nullptr;
537 } 560 }
538 561
539 - (void)undo:(id)sender { 562 - (void)undo:(id)sender {
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 case ui::TEXT_INPUT_TYPE_NONE: 781 case ui::TEXT_INPUT_TYPE_NONE:
759 case ui::TEXT_INPUT_TYPE_PASSWORD: 782 case ui::TEXT_INPUT_TYPE_PASSWORD:
760 return nil; 783 return nil;
761 default: 784 default:
762 return [super inputContext]; 785 return [super inputContext];
763 } 786 }
764 } 787 }
765 788
766 // NSResponder implementation. 789 // NSResponder implementation.
767 790
791 - (BOOL)_wantsKeyDownForEvent:(NSEvent*)event {
792 // This is a SPI that AppKit apparently calls after |performKeyEquivalent:|
793 // returned NO. If this function returns |YES|, Cocoa sends the event to
794 // |keyDown:| instead of doing other things with it. Ctrl-tab will be sent
795 // to us instead of doing key view loop control, ctrl-left/right get handled
796 // correctly, etc.
797 // (However, there are still some keys that Cocoa swallows, e.g. the key
798 // equivalent that Cocoa uses for toggling the input language. In this case,
799 // that's actually a good thing, though -- see http://crbug.com/26115 .)
800 return YES;
801 }
802
768 - (void)keyDown:(NSEvent*)theEvent { 803 - (void)keyDown:(NSEvent*)theEvent {
769 // Convert the event into an action message, according to OSX key mappings. 804 // Convert the event into an action message, according to OSX key mappings.
770 keyDownEvent_ = theEvent; 805 keyDownEvent_ = theEvent;
771 [self interpretKeyEvents:@[ theEvent ]]; 806 [self interpretKeyEvents:@[ theEvent ]];
772 keyDownEvent_ = nil; 807
808 // If |keyDownEvent_| wasn't cleared during -interpretKeyEvents:, it wasn't
809 // handled. Give Widget accelerators a chance to handle it.
810 [self handleUnhandledKeyDownAsKeyEvent];
811 DCHECK(!keyDownEvent_);
773 } 812 }
774 813
775 - (void)keyUp:(NSEvent*)theEvent { 814 - (void)keyUp:(NSEvent*)theEvent {
776 ui::KeyEvent event(theEvent); 815 ui::KeyEvent event(theEvent);
777 [self handleKeyEvent:&event]; 816 [self handleKeyEvent:&event];
778 } 817 }
779 818
780 - (void)scrollWheel:(NSEvent*)theEvent { 819 - (void)scrollWheel:(NSEvent*)theEvent {
781 if (!hostedView_) 820 if (!hostedView_)
782 return; 821 return;
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 } 1320 }
1282 1321
1283 - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { 1322 - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint {
1284 NOTIMPLEMENTED(); 1323 NOTIMPLEMENTED();
1285 return 0; 1324 return 0;
1286 } 1325 }
1287 1326
1288 - (void)doCommandBySelector:(SEL)selector { 1327 - (void)doCommandBySelector:(SEL)selector {
1289 // Like the renderer, handle insert action messages as a regular key dispatch. 1328 // Like the renderer, handle insert action messages as a regular key dispatch.
1290 // This ensures, e.g., insertTab correctly changes focus between fields. 1329 // This ensures, e.g., insertTab correctly changes focus between fields.
1291 if (keyDownEvent_ && [NSStringFromSelector(selector) hasPrefix:@"insert"]) { 1330 if (keyDownEvent_ && [NSStringFromSelector(selector) hasPrefix:@"insert"])
1292 ui::KeyEvent event(keyDownEvent_); 1331 return; // Handle in -keyDown:.
1293 [self handleKeyEvent:&event]; 1332
1333 if ([self respondsToSelector:selector]) {
1334 [self performSelector:selector withObject:nil];
1335 keyDownEvent_ = nil;
1294 return; 1336 return;
1295 } 1337 }
1296 1338
1297 if ([self respondsToSelector:selector]) 1339 // For events that AppKit sends via doCommandBySelector:, first attempt to
1298 [self performSelector:selector withObject:nil]; 1340 // handle as a Widget accelerator. Forward along the responder chain only if
1299 else 1341 // the Widget doesn't handle it.
1342 if (![self handleUnhandledKeyDownAsKeyEvent])
1300 [[self nextResponder] doCommandBySelector:selector]; 1343 [[self nextResponder] doCommandBySelector:selector];
1301 } 1344 }
1302 1345
1303 - (NSRect)firstRectForCharacterRange:(NSRange)range 1346 - (NSRect)firstRectForCharacterRange:(NSRange)range
1304 actualRange:(NSRangePointer)actualNSRange { 1347 actualRange:(NSRangePointer)actualNSRange {
1305 gfx::Range actualRange; 1348 gfx::Range actualRange;
1306 gfx::Rect rect = GetFirstRectForRangeHelper(textInputClient_, 1349 gfx::Rect rect = GetFirstRectForRangeHelper(textInputClient_,
1307 gfx::Range(range), &actualRange); 1350 gfx::Range(range), &actualRange);
1308 if (actualNSRange) 1351 if (actualNSRange)
1309 *actualNSRange = actualRange.ToNSRange(); 1352 *actualNSRange = actualRange.ToNSRange();
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1432 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; 1475 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point];
1433 } 1476 }
1434 1477
1435 - (id)accessibilityFocusedUIElement { 1478 - (id)accessibilityFocusedUIElement {
1436 if (!hostedView_) 1479 if (!hostedView_)
1437 return nil; 1480 return nil;
1438 return [hostedView_->GetNativeViewAccessible() accessibilityFocusedUIElement]; 1481 return [hostedView_->GetNativeViewAccessible() accessibilityFocusedUIElement];
1439 } 1482 }
1440 1483
1441 @end 1484 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698