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 |