Chromium Code Reviews| 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 23 matching lines...) Expand all Loading... | |
| 34 ? [source_window convertBaseToScreen:point] | 34 ? [source_window convertBaseToScreen:point] |
| 35 : point; | 35 : point; |
| 36 | 36 |
| 37 NSPoint point_in_window = [target_window convertScreenToBase:point_in_screen]; | 37 NSPoint point_in_window = [target_window convertScreenToBase:point_in_screen]; |
| 38 NSRect content_rect = | 38 NSRect content_rect = |
| 39 [target_window contentRectForFrameRect:[target_window frame]]; | 39 [target_window contentRectForFrameRect:[target_window frame]]; |
| 40 return gfx::Point(point_in_window.x, | 40 return gfx::Point(point_in_window.x, |
| 41 NSHeight(content_rect) - point_in_window.y); | 41 NSHeight(content_rect) - point_in_window.y); |
| 42 } | 42 } |
| 43 | 43 |
| 44 // Checks if there's an active MenuController during key event dispatch. If | |
| 45 // there is one, it gets preference, and it will likely swallow the event. | |
| 46 bool DispatchEventToMenu(views::Widget* widget, ui::KeyboardCode key_code) { | |
| 47 MenuController* menuController = MenuController::GetActiveInstance(); | |
| 48 if (menuController && menuController->owner() == widget) { | |
| 49 if (menuController->OnWillDispatchKeyEvent(0, key_code) == | |
| 50 ui::POST_DISPATCH_NONE) | |
| 51 return true; | |
| 52 } | |
| 53 return false; | |
| 44 } | 54 } |
| 45 | 55 |
| 56 } // namespace | |
| 57 | |
| 46 @interface BridgedContentView () | 58 @interface BridgedContentView () |
| 47 | 59 |
| 48 // Translates the location of |theEvent| to toolkit-views coordinates and passes | 60 // Translates the location of |theEvent| to toolkit-views coordinates and passes |
| 49 // the event to NativeWidgetMac for handling. | 61 // the event to NativeWidgetMac for handling. |
| 50 - (void)handleMouseEvent:(NSEvent*)theEvent; | 62 - (void)handleMouseEvent:(NSEvent*)theEvent; |
| 51 | 63 |
| 64 // Translates keycodes and modifiers on |theEvent| to ui::KeyEvents and passes | |
| 65 // the event to the InputMethod for dispatch. | |
| 66 - (void)handleKeyEvent:(NSEvent*)theEvent; | |
| 67 | |
| 52 // Handles an NSResponder Action Message by mapping it to a corresponding text | 68 // Handles an NSResponder Action Message by mapping it to a corresponding text |
| 53 // editing command from ui_strings.grd and, when not being sent to a | 69 // editing command from ui_strings.grd and, when not being sent to a |
| 54 // TextInputClient, the keyCode that toolkit-views expects internally. | 70 // TextInputClient, the keyCode that toolkit-views expects internally. |
| 55 // For example, moveToLeftEndOfLine: would pass ui::VKEY_HOME in non-RTL locales | 71 // For example, moveToLeftEndOfLine: would pass ui::VKEY_HOME in non-RTL locales |
| 56 // even though the Home key on Mac defaults to moveToBeginningOfDocument:. | 72 // even though the Home key on Mac defaults to moveToBeginningOfDocument:. |
| 57 // This approach also allows action messages a user | 73 // This approach also allows action messages a user |
| 58 // may have remapped in ~/Library/KeyBindings/DefaultKeyBinding.dict to be | 74 // may have remapped in ~/Library/KeyBindings/DefaultKeyBinding.dict to be |
| 59 // catered for. | 75 // catered for. |
| 60 // Note: default key bindings in Mac can be read from StandardKeyBinding.dict | 76 // Note: default key bindings in Mac can be read from StandardKeyBinding.dict |
| 61 // which lives in /System/Library/Frameworks/AppKit.framework/Resources. Do | 77 // which lives in /System/Library/Frameworks/AppKit.framework/Resources. Do |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 // BridgedContentView private implementation. | 149 // BridgedContentView private implementation. |
| 134 | 150 |
| 135 - (void)handleMouseEvent:(NSEvent*)theEvent { | 151 - (void)handleMouseEvent:(NSEvent*)theEvent { |
| 136 if (!hostedView_) | 152 if (!hostedView_) |
| 137 return; | 153 return; |
| 138 | 154 |
| 139 ui::MouseEvent event(theEvent); | 155 ui::MouseEvent event(theEvent); |
| 140 hostedView_->GetWidget()->OnMouseEvent(&event); | 156 hostedView_->GetWidget()->OnMouseEvent(&event); |
| 141 } | 157 } |
| 142 | 158 |
| 159 - (void)handleKeyEvent:(NSEvent*)theEvent { | |
| 160 if (!hostedView_) | |
| 161 return; | |
| 162 | |
| 163 DCHECK(theEvent); | |
| 164 ui::KeyEvent event(theEvent); | |
| 165 if (DispatchEventToMenu(hostedView_->GetWidget(), event.key_code())) | |
| 166 return; | |
| 167 | |
| 168 hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(event); | |
| 169 } | |
| 170 | |
| 143 - (void)handleAction:(int)commandId | 171 - (void)handleAction:(int)commandId |
| 144 keyCode:(ui::KeyboardCode)keyCode | 172 keyCode:(ui::KeyboardCode)keyCode |
| 145 domCode:(ui::DomCode)domCode | 173 domCode:(ui::DomCode)domCode |
| 146 eventFlags:(int)eventFlags { | 174 eventFlags:(int)eventFlags { |
| 147 if (!hostedView_) | 175 if (!hostedView_) |
| 148 return; | 176 return; |
| 149 | 177 |
| 150 // If there's an active MenuController it gets preference, and it will likely | 178 if (DispatchEventToMenu(hostedView_->GetWidget(), keyCode)) |
| 151 // swallow the event. | 179 return; |
| 152 MenuController* menuController = MenuController::GetActiveInstance(); | |
| 153 if (menuController && menuController->owner() == hostedView_->GetWidget()) { | |
| 154 if (menuController->OnWillDispatchKeyEvent(0, keyCode) == | |
| 155 ui::POST_DISPATCH_NONE) | |
| 156 return; | |
| 157 } | |
| 158 | 180 |
| 159 // If there's an active TextInputClient, schedule the editing command to be | 181 // If there's an active TextInputClient, schedule the editing command to be |
| 160 // performed. | 182 // performed. |
| 161 if (commandId && textInputClient_ && | 183 if (commandId && textInputClient_ && |
| 162 textInputClient_->IsEditCommandEnabled(commandId)) | 184 textInputClient_->IsEditCommandEnabled(commandId)) |
| 163 textInputClient_->SetEditCommandForNextKeyEvent(commandId); | 185 textInputClient_->SetEditCommandForNextKeyEvent(commandId); |
| 164 | 186 |
| 165 // Generate a synthetic event with the keycode toolkit-views expects. | 187 // Generate a synthetic event with the keycode toolkit-views expects. |
| 166 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags); | 188 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags); |
| 167 hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(event); | 189 hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(event); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 return; | 341 return; |
| 320 | 342 |
| 321 ui::MouseWheelEvent event(theEvent); | 343 ui::MouseWheelEvent event(theEvent); |
| 322 hostedView_->GetWidget()->OnMouseEvent(&event); | 344 hostedView_->GetWidget()->OnMouseEvent(&event); |
| 323 } | 345 } |
| 324 | 346 |
| 325 //////////////////////////////////////////////////////////////////////////////// | 347 //////////////////////////////////////////////////////////////////////////////// |
| 326 // NSResponder Action Messages. Keep sorted according NSResponder.h (from the | 348 // NSResponder Action Messages. Keep sorted according NSResponder.h (from the |
| 327 // 10.9 SDK). The list should eventually be complete. Anything not defined will | 349 // 10.9 SDK). The list should eventually be complete. Anything not defined will |
| 328 // beep when interpretKeyEvents: would otherwise call it. | 350 // beep when interpretKeyEvents: would otherwise call it. |
| 329 // TODO(tapted): Make this list complete. | 351 // TODO(tapted): Make this list complete, except for insert* methods which are |
| 352 // dispatched as regular key events in doCommandBySelector:. | |
| 330 | 353 |
| 331 // The insertText action message forwards to the TextInputClient unless a menu | 354 // The insertText action message forwards to the TextInputClient unless a menu |
| 332 // is active. | 355 // is active. Note that NSResponder's interpretKeyEvents: implementation doesn't |
| 356 // direct insertText: through doCommandBySelector:, so this is still needed to | |
| 357 // handle the case when inputContext: is nil. When inputContext: returns non-nil | |
| 358 // text goes directly to insertText:replacementRange:. | |
| 333 - (void)insertText:(id)text { | 359 - (void)insertText:(id)text { |
|
tapted
2015/02/26 00:46:34
Ah, my macviews trybot picked up a regression here
| |
| 334 [self insertText:text replacementRange:NSMakeRange(NSNotFound, 0)]; | 360 [self insertText:text replacementRange:NSMakeRange(NSNotFound, 0)]; |
| 335 } | 361 } |
| 336 | 362 |
| 337 // Selection movement and scrolling. | 363 // Selection movement and scrolling. |
| 338 | 364 |
| 339 - (void)moveRight:(id)sender { | 365 - (void)moveRight:(id)sender { |
| 340 [self handleAction:IDS_MOVE_RIGHT | 366 [self handleAction:IDS_MOVE_RIGHT |
| 341 keyCode:ui::VKEY_RIGHT | 367 keyCode:ui::VKEY_RIGHT |
| 342 domCode:ui::DomCode::ARROW_RIGHT | 368 domCode:ui::DomCode::ARROW_RIGHT |
| 343 eventFlags:0]; | 369 eventFlags:0]; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 eventFlags:ui::EF_SHIFT_DOWN]; | 453 eventFlags:ui::EF_SHIFT_DOWN]; |
| 428 } | 454 } |
| 429 | 455 |
| 430 - (void)moveToRightEndOfLineAndModifySelection:(id)sender { | 456 - (void)moveToRightEndOfLineAndModifySelection:(id)sender { |
| 431 [self handleAction:IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION | 457 [self handleAction:IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION |
| 432 keyCode:ui::VKEY_END | 458 keyCode:ui::VKEY_END |
| 433 domCode:ui::DomCode::END | 459 domCode:ui::DomCode::END |
| 434 eventFlags:ui::EF_SHIFT_DOWN]; | 460 eventFlags:ui::EF_SHIFT_DOWN]; |
| 435 } | 461 } |
| 436 | 462 |
| 437 // Insertions and Indentations. | |
| 438 | |
| 439 - (void)insertNewline:(id)sender { | |
| 440 [self handleAction:0 | |
| 441 keyCode:ui::VKEY_RETURN | |
| 442 domCode:ui::DomCode::ENTER | |
| 443 eventFlags:0]; | |
| 444 } | |
| 445 | |
| 446 // Deletions. | 463 // Deletions. |
| 447 | 464 |
| 448 - (void)deleteForward:(id)sender { | 465 - (void)deleteForward:(id)sender { |
| 449 [self handleAction:IDS_DELETE_FORWARD | 466 [self handleAction:IDS_DELETE_FORWARD |
| 450 keyCode:ui::VKEY_DELETE | 467 keyCode:ui::VKEY_DELETE |
| 451 domCode:ui::DomCode::DEL | 468 domCode:ui::DomCode::DEL |
| 452 eventFlags:0]; | 469 eventFlags:0]; |
| 453 } | 470 } |
| 454 | 471 |
| 455 - (void)deleteBackward:(id)sender { | 472 - (void)deleteBackward:(id)sender { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 return [[[NSAttributedString alloc] | 555 return [[[NSAttributedString alloc] |
| 539 initWithString:base::SysUTF16ToNSString(substring)] autorelease]; | 556 initWithString:base::SysUTF16ToNSString(substring)] autorelease]; |
| 540 } | 557 } |
| 541 | 558 |
| 542 - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { | 559 - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { |
| 543 NOTIMPLEMENTED(); | 560 NOTIMPLEMENTED(); |
| 544 return 0; | 561 return 0; |
| 545 } | 562 } |
| 546 | 563 |
| 547 - (void)doCommandBySelector:(SEL)selector { | 564 - (void)doCommandBySelector:(SEL)selector { |
| 565 // Like the renderer, handle insert action messages as a regular key dispatch. | |
| 566 // This ensures, e.g., insertTab correctly changes focus between fields. | |
| 567 if (inKeyDown_ && [NSStringFromSelector(selector) hasPrefix:@"insert"]) { | |
| 568 [self handleKeyEvent:[NSApp currentEvent]]; | |
| 569 return; | |
| 570 } | |
| 571 | |
| 548 if ([self respondsToSelector:selector]) | 572 if ([self respondsToSelector:selector]) |
| 549 [self performSelector:selector withObject:nil]; | 573 [self performSelector:selector withObject:nil]; |
| 550 else | 574 else |
| 551 [[self nextResponder] doCommandBySelector:selector]; | 575 [[self nextResponder] doCommandBySelector:selector]; |
| 552 } | 576 } |
| 553 | 577 |
| 554 - (NSRect)firstRectForCharacterRange:(NSRange)range | 578 - (NSRect)firstRectForCharacterRange:(NSRange)range |
| 555 actualRange:(NSRangePointer)actualRange { | 579 actualRange:(NSRangePointer)actualRange { |
| 556 NOTIMPLEMENTED(); | 580 NOTIMPLEMENTED(); |
| 557 return NSZeroRect; | 581 return NSZeroRect; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 } | 703 } |
| 680 | 704 |
| 681 return [super accessibilityAttributeValue:attribute]; | 705 return [super accessibilityAttributeValue:attribute]; |
| 682 } | 706 } |
| 683 | 707 |
| 684 - (id)accessibilityHitTest:(NSPoint)point { | 708 - (id)accessibilityHitTest:(NSPoint)point { |
| 685 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; | 709 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; |
| 686 } | 710 } |
| 687 | 711 |
| 688 @end | 712 @end |
| OLD | NEW |