OLD | NEW |
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/scoped_nsobject.h" | 8 #import "base/mac/scoped_nsobject.h" |
9 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
10 #include "ui/base/ime/text_input_client.h" | 10 #include "ui/base/ime/text_input_client.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 // Note: default key bindings in Mac can be read from StandardKeyBinding.dict | 60 // Note: default key bindings in Mac can be read from StandardKeyBinding.dict |
61 // which lives in /System/Library/Frameworks/AppKit.framework/Resources. Do | 61 // which lives in /System/Library/Frameworks/AppKit.framework/Resources. Do |
62 // `plutil -convert xml1 -o StandardKeyBinding.xml StandardKeyBinding.dict` to | 62 // `plutil -convert xml1 -o StandardKeyBinding.xml StandardKeyBinding.dict` to |
63 // get something readable. | 63 // get something readable. |
64 - (void)handleAction:(int)commandId | 64 - (void)handleAction:(int)commandId |
65 keyCode:(ui::KeyboardCode)keyCode | 65 keyCode:(ui::KeyboardCode)keyCode |
66 domCode:(ui::DomCode)domCode | 66 domCode:(ui::DomCode)domCode |
67 eventFlags:(int)eventFlags; | 67 eventFlags:(int)eventFlags; |
68 | 68 |
69 // Menu action handlers. | 69 // Menu action handlers. |
| 70 - (void)undo:(id)sender; |
| 71 - (void)redo:(id)sender; |
70 - (void)cut:(id)sender; | 72 - (void)cut:(id)sender; |
71 - (void)copy:(id)sender; | 73 - (void)copy:(id)sender; |
72 - (void)paste:(id)sender; | 74 - (void)paste:(id)sender; |
73 - (void)selectAll:(id)sender; | 75 - (void)selectAll:(id)sender; |
74 | 76 |
75 @end | 77 @end |
76 | 78 |
77 @implementation BridgedContentView | 79 @implementation BridgedContentView |
78 | 80 |
79 @synthesize hostedView = hostedView_; | 81 @synthesize hostedView = hostedView_; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 // performed. | 160 // performed. |
159 if (commandId && textInputClient_ && | 161 if (commandId && textInputClient_ && |
160 textInputClient_->IsEditCommandEnabled(commandId)) | 162 textInputClient_->IsEditCommandEnabled(commandId)) |
161 textInputClient_->SetEditCommandForNextKeyEvent(commandId); | 163 textInputClient_->SetEditCommandForNextKeyEvent(commandId); |
162 | 164 |
163 // Generate a synthetic event with the keycode toolkit-views expects. | 165 // Generate a synthetic event with the keycode toolkit-views expects. |
164 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags); | 166 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags); |
165 hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(event); | 167 hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(event); |
166 } | 168 } |
167 | 169 |
| 170 - (void)undo:(id)sender { |
| 171 // This DCHECK is more strict than a similar check in handleAction:. It can be |
| 172 // done here because the actors sending these actions should be calling |
| 173 // validateUserInterfaceItem: before enabling UI that allows these messages to |
| 174 // be sent. Checking it here would be too late to provide correct UI feedback |
| 175 // (e.g. there will be no "beep"). |
| 176 DCHECK(textInputClient_->IsEditCommandEnabled(IDS_APP_UNDO)); |
| 177 [self handleAction:IDS_APP_UNDO |
| 178 keyCode:ui::VKEY_Z |
| 179 domCode:ui::DomCode::KEY_Z |
| 180 eventFlags:ui::EF_CONTROL_DOWN]; |
| 181 } |
| 182 |
| 183 - (void)redo:(id)sender { |
| 184 DCHECK(textInputClient_->IsEditCommandEnabled(IDS_APP_REDO)); |
| 185 [self handleAction:IDS_APP_REDO |
| 186 keyCode:ui::VKEY_Z |
| 187 domCode:ui::DomCode::KEY_Z |
| 188 eventFlags:ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN]; |
| 189 } |
| 190 |
168 - (void)cut:(id)sender { | 191 - (void)cut:(id)sender { |
169 DCHECK(textInputClient_->IsEditCommandEnabled(IDS_APP_CUT)); | 192 DCHECK(textInputClient_->IsEditCommandEnabled(IDS_APP_CUT)); |
170 [self handleAction:IDS_APP_CUT | 193 [self handleAction:IDS_APP_CUT |
171 keyCode:ui::VKEY_X | 194 keyCode:ui::VKEY_X |
172 domCode:ui::DomCode::KEY_X | 195 domCode:ui::DomCode::KEY_X |
173 eventFlags:ui::EF_CONTROL_DOWN]; | 196 eventFlags:ui::EF_CONTROL_DOWN]; |
174 } | 197 } |
175 | 198 |
176 - (void)copy:(id)sender { | 199 - (void)copy:(id)sender { |
177 DCHECK(textInputClient_->IsEditCommandEnabled(IDS_APP_COPY)); | 200 DCHECK(textInputClient_->IsEditCommandEnabled(IDS_APP_COPY)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 if (menuController && menuController->owner() == hostedView_->GetWidget()) | 259 if (menuController && menuController->owner() == hostedView_->GetWidget()) |
237 return nil; | 260 return nil; |
238 | 261 |
239 return [super inputContext]; | 262 return [super inputContext]; |
240 } | 263 } |
241 | 264 |
242 // NSResponder implementation. | 265 // NSResponder implementation. |
243 | 266 |
244 - (void)keyDown:(NSEvent*)theEvent { | 267 - (void)keyDown:(NSEvent*)theEvent { |
245 // Convert the event into an action message, according to OSX key mappings. | 268 // Convert the event into an action message, according to OSX key mappings. |
| 269 inKeyDown_ = YES; |
246 [self interpretKeyEvents:@[ theEvent ]]; | 270 [self interpretKeyEvents:@[ theEvent ]]; |
| 271 inKeyDown_ = NO; |
247 } | 272 } |
248 | 273 |
249 - (void)mouseDown:(NSEvent*)theEvent { | 274 - (void)mouseDown:(NSEvent*)theEvent { |
250 [self handleMouseEvent:theEvent]; | 275 [self handleMouseEvent:theEvent]; |
251 } | 276 } |
252 | 277 |
253 - (void)rightMouseDown:(NSEvent*)theEvent { | 278 - (void)rightMouseDown:(NSEvent*)theEvent { |
254 [self handleMouseEvent:theEvent]; | 279 [self handleMouseEvent:theEvent]; |
255 } | 280 } |
256 | 281 |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 swallowedAny = true; | 586 swallowedAny = true; |
562 // Ensure the menu remains active. | 587 // Ensure the menu remains active. |
563 menuController = MenuController::GetActiveInstance(); | 588 menuController = MenuController::GetActiveInstance(); |
564 } | 589 } |
565 } | 590 } |
566 | 591 |
567 if (!textInputClient_) | 592 if (!textInputClient_) |
568 return; | 593 return; |
569 | 594 |
570 textInputClient_->DeleteRange(gfx::Range(replacementRange)); | 595 textInputClient_->DeleteRange(gfx::Range(replacementRange)); |
571 textInputClient_->InsertText(base::SysNSStringToUTF16(text)); | 596 |
| 597 // If a single character is inserted by keyDown's call to interpretKeyEvents: |
| 598 // then use InsertChar() to allow editing events to be merged. The second |
| 599 // argument is the key modifier, which interpretKeyEvents: will have already |
| 600 // processed, so don't send it to InsertChar() as well. E.g. Alt+S puts 'ß' in |
| 601 // |text| but sending 'Alt' to InsertChar would filter it out since it thinks |
| 602 // it's a command. Actual commands (e.g. Cmd+S) won't go through insertText:. |
| 603 if (inKeyDown_ && [text length] == 1) |
| 604 textInputClient_->InsertChar([text characterAtIndex:0], 0); |
| 605 else |
| 606 textInputClient_->InsertText(base::SysNSStringToUTF16(text)); |
572 } | 607 } |
573 | 608 |
574 - (NSRange)markedRange { | 609 - (NSRange)markedRange { |
575 if (!textInputClient_) | 610 if (!textInputClient_) |
576 return NSMakeRange(NSNotFound, 0); | 611 return NSMakeRange(NSNotFound, 0); |
577 | 612 |
578 gfx::Range range; | 613 gfx::Range range; |
579 textInputClient_->GetCompositionTextRange(&range); | 614 textInputClient_->GetCompositionTextRange(&range); |
580 return range.ToNSRange(); | 615 return range.ToNSRange(); |
581 } | 616 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 } | 648 } |
614 | 649 |
615 // NSUserInterfaceValidations protocol implementation. | 650 // NSUserInterfaceValidations protocol implementation. |
616 | 651 |
617 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { | 652 - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { |
618 if (!textInputClient_) | 653 if (!textInputClient_) |
619 return NO; | 654 return NO; |
620 | 655 |
621 SEL action = [item action]; | 656 SEL action = [item action]; |
622 | 657 |
| 658 if (action == @selector(undo:)) |
| 659 return textInputClient_->IsEditCommandEnabled(IDS_APP_UNDO); |
| 660 if (action == @selector(redo:)) |
| 661 return textInputClient_->IsEditCommandEnabled(IDS_APP_REDO); |
623 if (action == @selector(cut:)) | 662 if (action == @selector(cut:)) |
624 return textInputClient_->IsEditCommandEnabled(IDS_APP_CUT); | 663 return textInputClient_->IsEditCommandEnabled(IDS_APP_CUT); |
625 if (action == @selector(copy:)) | 664 if (action == @selector(copy:)) |
626 return textInputClient_->IsEditCommandEnabled(IDS_APP_COPY); | 665 return textInputClient_->IsEditCommandEnabled(IDS_APP_COPY); |
627 if (action == @selector(paste:)) | 666 if (action == @selector(paste:)) |
628 return textInputClient_->IsEditCommandEnabled(IDS_APP_PASTE); | 667 return textInputClient_->IsEditCommandEnabled(IDS_APP_PASTE); |
629 if (action == @selector(selectAll:)) | 668 if (action == @selector(selectAll:)) |
630 return textInputClient_->IsEditCommandEnabled(IDS_APP_SELECT_ALL); | 669 return textInputClient_->IsEditCommandEnabled(IDS_APP_SELECT_ALL); |
631 | 670 |
632 return NO; | 671 return NO; |
633 } | 672 } |
634 | 673 |
635 // NSAccessibility informal protocol implementation. | 674 // NSAccessibility informal protocol implementation. |
636 | 675 |
637 - (id)accessibilityAttributeValue:(NSString*)attribute { | 676 - (id)accessibilityAttributeValue:(NSString*)attribute { |
638 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { | 677 if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { |
639 return @[ hostedView_->GetNativeViewAccessible() ]; | 678 return @[ hostedView_->GetNativeViewAccessible() ]; |
640 } | 679 } |
641 | 680 |
642 return [super accessibilityAttributeValue:attribute]; | 681 return [super accessibilityAttributeValue:attribute]; |
643 } | 682 } |
644 | 683 |
645 - (id)accessibilityHitTest:(NSPoint)point { | 684 - (id)accessibilityHitTest:(NSPoint)point { |
646 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; | 685 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; |
647 } | 686 } |
648 | 687 |
649 @end | 688 @end |
OLD | NEW |