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" |
11 #import "ui/events/cocoa/cocoa_event_utils.h" | 11 #import "ui/events/cocoa/cocoa_event_utils.h" |
12 #include "ui/events/keycodes/dom3/dom_code.h" | 12 #include "ui/events/keycodes/dom3/dom_code.h" |
13 #import "ui/events/keycodes/keyboard_code_conversion_mac.h" | 13 #import "ui/events/keycodes/keyboard_code_conversion_mac.h" |
14 #include "ui/gfx/canvas_paint_mac.h" | 14 #include "ui/gfx/canvas_paint_mac.h" |
15 #include "ui/gfx/geometry/rect.h" | 15 #include "ui/gfx/geometry/rect.h" |
16 #include "ui/strings/grit/ui_strings.h" | 16 #include "ui/strings/grit/ui_strings.h" |
| 17 #include "ui/views/controls/menu/menu_controller.h" |
17 #include "ui/views/view.h" | 18 #include "ui/views/view.h" |
18 #include "ui/views/widget/widget.h" | 19 #include "ui/views/widget/widget.h" |
19 | 20 |
| 21 using views::MenuController; |
| 22 |
20 namespace { | 23 namespace { |
21 | 24 |
22 // Convert a |point| in |source_window|'s AppKit coordinate system (origin at | 25 // Convert a |point| in |source_window|'s AppKit coordinate system (origin at |
23 // the bottom left of the window) to |target_window|'s content rect, with the | 26 // the bottom left of the window) to |target_window|'s content rect, with the |
24 // origin at the top left of the content area. | 27 // origin at the top left of the content area. |
25 // If |source_window| is nil, |point| will be treated as screen coordinates. | 28 // If |source_window| is nil, |point| will be treated as screen coordinates. |
26 gfx::Point MovePointToWindow(const NSPoint& point, | 29 gfx::Point MovePointToWindow(const NSPoint& point, |
27 NSWindow* source_window, | 30 NSWindow* source_window, |
28 NSWindow* target_window) { | 31 NSWindow* target_window) { |
29 NSPoint point_in_screen = source_window | 32 NSPoint point_in_screen = source_window |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 hostedView_->GetWidget()->OnMouseEvent(&event); | 130 hostedView_->GetWidget()->OnMouseEvent(&event); |
128 } | 131 } |
129 | 132 |
130 - (void)handleAction:(int)commandId | 133 - (void)handleAction:(int)commandId |
131 keyCode:(ui::KeyboardCode)keyCode | 134 keyCode:(ui::KeyboardCode)keyCode |
132 domCode:(ui::DomCode)domCode | 135 domCode:(ui::DomCode)domCode |
133 eventFlags:(int)eventFlags { | 136 eventFlags:(int)eventFlags { |
134 if (!hostedView_) | 137 if (!hostedView_) |
135 return; | 138 return; |
136 | 139 |
| 140 // If there's an active MenuController it gets preference, and it will likely |
| 141 // swallow the event. |
| 142 MenuController* menuController = MenuController::GetActiveInstance(); |
| 143 if (menuController && menuController->owner() == hostedView_->GetWidget()) { |
| 144 if (menuController->OnWillDispatchKeyEvent(0, keyCode) == |
| 145 ui::POST_DISPATCH_NONE) |
| 146 return; |
| 147 } |
| 148 |
137 // If there's an active TextInputClient, it ignores the key and processes the | 149 // If there's an active TextInputClient, it ignores the key and processes the |
138 // logical editing action. | 150 // logical editing action. |
139 if (commandId && textInputClient_ && | 151 if (commandId && textInputClient_ && |
140 textInputClient_->IsEditingCommandEnabled(commandId)) { | 152 textInputClient_->IsEditingCommandEnabled(commandId)) { |
141 textInputClient_->ExecuteEditingCommand(commandId); | 153 textInputClient_->ExecuteEditingCommand(commandId); |
142 return; | 154 return; |
143 } | 155 } |
144 | 156 |
145 // Otherwise, process the action as a regular key event. | 157 // Otherwise, process the action as a regular key event. |
146 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags); | 158 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags); |
(...skipping 21 matching lines...) Expand all Loading... |
168 return; | 180 return; |
169 | 181 |
170 // If there's a layer, painting occurs in BridgedNativeWidget::OnPaintLayer(). | 182 // If there's a layer, painting occurs in BridgedNativeWidget::OnPaintLayer(). |
171 if (hostedView_->GetWidget()->GetLayer()) | 183 if (hostedView_->GetWidget()->GetLayer()) |
172 return; | 184 return; |
173 | 185 |
174 gfx::CanvasSkiaPaint canvas(dirtyRect, false /* opaque */); | 186 gfx::CanvasSkiaPaint canvas(dirtyRect, false /* opaque */); |
175 hostedView_->GetWidget()->OnNativeWidgetPaint(&canvas); | 187 hostedView_->GetWidget()->OnNativeWidgetPaint(&canvas); |
176 } | 188 } |
177 | 189 |
| 190 - (NSTextInputContext*)inputContext { |
| 191 if (!hostedView_) |
| 192 return [super inputContext]; |
| 193 |
| 194 // If a menu is active, and -[NSView interpretKeyEvents:] asks for the |
| 195 // input context, return nil. This ensures the action message is sent to |
| 196 // the view, rather than any NSTextInputClient a subview has installed. |
| 197 MenuController* menuController = MenuController::GetActiveInstance(); |
| 198 if (menuController && menuController->owner() == hostedView_->GetWidget()) |
| 199 return nil; |
| 200 |
| 201 return [super inputContext]; |
| 202 } |
| 203 |
178 // NSResponder implementation. | 204 // NSResponder implementation. |
179 | 205 |
180 - (void)keyDown:(NSEvent*)theEvent { | 206 - (void)keyDown:(NSEvent*)theEvent { |
181 // Convert the event into an action message, according to OSX key mappings. | 207 // Convert the event into an action message, according to OSX key mappings. |
182 [self interpretKeyEvents:@[ theEvent ]]; | 208 [self interpretKeyEvents:@[ theEvent ]]; |
183 } | 209 } |
184 | 210 |
185 - (void)mouseDown:(NSEvent*)theEvent { | 211 - (void)mouseDown:(NSEvent*)theEvent { |
186 [self handleMouseEvent:theEvent]; | 212 [self handleMouseEvent:theEvent]; |
187 } | 213 } |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 actualRange:(NSRangePointer)actualRange { | 492 actualRange:(NSRangePointer)actualRange { |
467 NOTIMPLEMENTED(); | 493 NOTIMPLEMENTED(); |
468 return NSZeroRect; | 494 return NSZeroRect; |
469 } | 495 } |
470 | 496 |
471 - (BOOL)hasMarkedText { | 497 - (BOOL)hasMarkedText { |
472 return textInputClient_ && textInputClient_->HasCompositionText(); | 498 return textInputClient_ && textInputClient_->HasCompositionText(); |
473 } | 499 } |
474 | 500 |
475 - (void)insertText:(id)text replacementRange:(NSRange)replacementRange { | 501 - (void)insertText:(id)text replacementRange:(NSRange)replacementRange { |
476 if (!textInputClient_) | 502 if (!hostedView_) |
477 return; | 503 return; |
478 | 504 |
479 if ([text isKindOfClass:[NSAttributedString class]]) | 505 if ([text isKindOfClass:[NSAttributedString class]]) |
480 text = [text string]; | 506 text = [text string]; |
| 507 |
| 508 MenuController* menuController = MenuController::GetActiveInstance(); |
| 509 if (menuController && menuController->owner() == hostedView_->GetWidget()) { |
| 510 // Handle menu mnemonics (e.g. "sav" jumps to "Save"). Handles both single- |
| 511 // characters and input from IME. For IME, swallow the entire string unless |
| 512 // the very first character gives ui::POST_DISPATCH_PERFORM_DEFAULT. |
| 513 bool swallowedAny = false; |
| 514 for (NSUInteger i = 0; i < [text length]; ++i) { |
| 515 if (!menuController || |
| 516 menuController->OnWillDispatchKeyEvent([text characterAtIndex:i], |
| 517 ui::VKEY_UNKNOWN) == |
| 518 ui::POST_DISPATCH_PERFORM_DEFAULT) { |
| 519 if (swallowedAny) |
| 520 return; // Swallow remainder. |
| 521 break; |
| 522 } |
| 523 swallowedAny = true; |
| 524 // Ensure the menu remains active. |
| 525 menuController = MenuController::GetActiveInstance(); |
| 526 } |
| 527 } |
| 528 |
| 529 if (!textInputClient_) |
| 530 return; |
| 531 |
481 textInputClient_->DeleteRange(gfx::Range(replacementRange)); | 532 textInputClient_->DeleteRange(gfx::Range(replacementRange)); |
482 textInputClient_->InsertText(base::SysNSStringToUTF16(text)); | 533 textInputClient_->InsertText(base::SysNSStringToUTF16(text)); |
483 } | 534 } |
484 | 535 |
485 - (NSRange)markedRange { | 536 - (NSRange)markedRange { |
486 if (!textInputClient_) | 537 if (!textInputClient_) |
487 return NSMakeRange(NSNotFound, 0); | 538 return NSMakeRange(NSNotFound, 0); |
488 | 539 |
489 gfx::Range range; | 540 gfx::Range range; |
490 textInputClient_->GetCompositionTextRange(&range); | 541 textInputClient_->GetCompositionTextRange(&range); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 } | 582 } |
532 | 583 |
533 return [super accessibilityAttributeValue:attribute]; | 584 return [super accessibilityAttributeValue:attribute]; |
534 } | 585 } |
535 | 586 |
536 - (id)accessibilityHitTest:(NSPoint)point { | 587 - (id)accessibilityHitTest:(NSPoint)point { |
537 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; | 588 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; |
538 } | 589 } |
539 | 590 |
540 @end | 591 @end |
OLD | NEW |