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

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

Issue 809773006: MacViews: Intercept events for Menus (after AppKit has interpreted keystrokes) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@20141205-MacViews-AcceleratedWidget-PLUS-AddingLayers-fromcl-PLUS-bringup
Patch Set: rollback card unmask Created 6 years 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/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"
12 #include "ui/events/keycodes/dom3/dom_code.h"
13 #import "ui/events/keycodes/keyboard_code_conversion_mac.h"
11 #include "ui/gfx/canvas_paint_mac.h" 14 #include "ui/gfx/canvas_paint_mac.h"
12 #include "ui/gfx/geometry/rect.h" 15 #include "ui/gfx/geometry/rect.h"
13 #include "ui/strings/grit/ui_strings.h" 16 #include "ui/strings/grit/ui_strings.h"
17 #include "ui/views/controls/menu/menu_controller.h"
14 #include "ui/views/view.h" 18 #include "ui/views/view.h"
15 #include "ui/views/widget/widget.h" 19 #include "ui/views/widget/widget.h"
16 20
21 using views::MenuController;
22
17 namespace { 23 namespace {
18 24
19 // 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
20 // 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
21 // origin at the top left of the content area. 27 // origin at the top left of the content area.
22 // 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.
23 gfx::Point MovePointToWindow(const NSPoint& point, 29 gfx::Point MovePointToWindow(const NSPoint& point,
24 NSWindow* source_window, 30 NSWindow* source_window,
25 NSWindow* target_window) { 31 NSWindow* target_window) {
26 NSPoint point_in_screen = source_window 32 NSPoint point_in_screen = source_window
27 ? [source_window convertBaseToScreen:point] 33 ? [source_window convertBaseToScreen:point]
28 : point; 34 : point;
29 35
30 NSPoint point_in_window = [target_window convertScreenToBase:point_in_screen]; 36 NSPoint point_in_window = [target_window convertScreenToBase:point_in_screen];
31 NSRect content_rect = 37 NSRect content_rect =
32 [target_window contentRectForFrameRect:[target_window frame]]; 38 [target_window contentRectForFrameRect:[target_window frame]];
33 return gfx::Point(point_in_window.x, 39 return gfx::Point(point_in_window.x,
34 NSHeight(content_rect) - point_in_window.y); 40 NSHeight(content_rect) - point_in_window.y);
35 } 41 }
36 42
37 } 43 }
38 44
39 @interface BridgedContentView () 45 @interface BridgedContentView ()
40 46
41 // Translates the location of |theEvent| to toolkit-views coordinates and passes 47 // Translates the location of |theEvent| to toolkit-views coordinates and passes
42 // the event to NativeWidgetMac for handling. 48 // the event to NativeWidgetMac for handling.
43 - (void)handleMouseEvent:(NSEvent*)theEvent; 49 - (void)handleMouseEvent:(NSEvent*)theEvent;
44 50
51 // Handles an NSResponder Action Message by mapping it to the keyCode that
52 // toolkit-views expects internally. E.g. moveToBeginningOfLine: would pass
53 // ui::VKEY_HOME even though the Home key on Mac defaults to
54 // moveToBeginningOfDocument:. This approach also allows action messages a user
55 // may have remapped in ~/Library/KeyBindings/DefaultKeyBinding.dict to be
56 // catered for.
57 - (void)handleActionAsKey:(ui::KeyboardCode)keyCode
58 domCode:(ui::DomCode)domCode;
59
45 // Execute a command on the currently focused TextInputClient. 60 // Execute a command on the currently focused TextInputClient.
46 // |commandId| should be a resource ID from ui_strings.grd. 61 // |commandId| should be a resource ID from ui_strings.grd.
47 - (void)doCommandByID:(int)commandId; 62 - (void)doCommandByID:(int)commandId;
48 63
49 @end 64 @end
50 65
51 @implementation BridgedContentView 66 @implementation BridgedContentView
52 67
53 @synthesize hostedView = hostedView_; 68 @synthesize hostedView = hostedView_;
54 @synthesize textInputClient = textInputClient_; 69 @synthesize textInputClient = textInputClient_;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 // BridgedContentView private implementation. 119 // BridgedContentView private implementation.
105 120
106 - (void)handleMouseEvent:(NSEvent*)theEvent { 121 - (void)handleMouseEvent:(NSEvent*)theEvent {
107 if (!hostedView_) 122 if (!hostedView_)
108 return; 123 return;
109 124
110 ui::MouseEvent event(theEvent); 125 ui::MouseEvent event(theEvent);
111 hostedView_->GetWidget()->OnMouseEvent(&event); 126 hostedView_->GetWidget()->OnMouseEvent(&event);
112 } 127 }
113 128
129 - (void)handleActionAsKey:(ui::KeyboardCode)keyCode
130 domCode:(ui::DomCode)domCode {
131 if (!hostedView_)
132 return;
133
134 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode,
135 ui::EventFlagsFromModifiers([NSEvent modifierFlags]));
136
137 MenuController* menuController = MenuController::GetActiveInstance();
138 if (menuController &&
139 menuController->owner() == hostedView_->GetWidget() &&
140 menuController->OnWillDispatchEvent(event) == ui::POST_DISPATCH_NONE)
141 return;
142
143 hostedView_->GetWidget()->OnKeyEvent(&event);
144 }
145
114 - (void)doCommandByID:(int)commandId { 146 - (void)doCommandByID:(int)commandId {
115 if (textInputClient_ && textInputClient_->IsEditingCommandEnabled(commandId)) 147 if (textInputClient_ && textInputClient_->IsEditingCommandEnabled(commandId))
116 textInputClient_->ExecuteEditingCommand(commandId); 148 textInputClient_->ExecuteEditingCommand(commandId);
117 } 149 }
118 150
119 // NSView implementation. 151 // NSView implementation.
120 152
121 - (BOOL)acceptsFirstResponder { 153 - (BOOL)acceptsFirstResponder {
122 return YES; 154 return YES;
123 } 155 }
(...skipping 16 matching lines...) Expand all
140 if (hostedView_->GetWidget()->GetLayer()) 172 if (hostedView_->GetWidget()->GetLayer())
141 return; 173 return;
142 174
143 gfx::CanvasSkiaPaint canvas(dirtyRect, false /* opaque */); 175 gfx::CanvasSkiaPaint canvas(dirtyRect, false /* opaque */);
144 hostedView_->GetWidget()->OnNativeWidgetPaint(&canvas); 176 hostedView_->GetWidget()->OnNativeWidgetPaint(&canvas);
145 } 177 }
146 178
147 // NSResponder implementation. 179 // NSResponder implementation.
148 180
149 - (void)keyDown:(NSEvent*)theEvent { 181 - (void)keyDown:(NSEvent*)theEvent {
150 if (textInputClient_) 182 [self interpretKeyEvents:@[ theEvent ]];
Andre 2014/12/19 06:41:57 How about when BridgedContentView is not first res
tapted 2015/01/28 11:18:06 So this was an excellent point :) it crossed my m
151 [self interpretKeyEvents:@[ theEvent ]];
152 else
153 [super keyDown:theEvent];
154 } 183 }
155 184
156 - (void)mouseDown:(NSEvent*)theEvent { 185 - (void)mouseDown:(NSEvent*)theEvent {
157 [self handleMouseEvent:theEvent]; 186 [self handleMouseEvent:theEvent];
158 } 187 }
159 188
160 - (void)rightMouseDown:(NSEvent*)theEvent { 189 - (void)rightMouseDown:(NSEvent*)theEvent {
161 [self handleMouseEvent:theEvent]; 190 [self handleMouseEvent:theEvent];
162 } 191 }
163 192
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 243
215 - (void)moveLeft:(id)sender { 244 - (void)moveLeft:(id)sender {
216 [self doCommandByID:IDS_MOVE_LEFT]; 245 [self doCommandByID:IDS_MOVE_LEFT];
217 } 246 }
218 247
219 - (void)moveRight:(id)sender { 248 - (void)moveRight:(id)sender {
220 [self doCommandByID:IDS_MOVE_RIGHT]; 249 [self doCommandByID:IDS_MOVE_RIGHT];
221 } 250 }
222 251
223 - (void)insertText:(id)text { 252 - (void)insertText:(id)text {
224 if (textInputClient_) 253 [self insertText:text replacementRange:NSMakeRange(NSNotFound, 0)];
225 textInputClient_->InsertText(base::SysNSStringToUTF16(text)); 254 }
255
256 - (void)moveUp:(id)sender {
257 [self handleActionAsKey:ui::VKEY_UP domCode:ui::DomCode::ARROW_UP];
258 }
259
260 - (void)moveDown:(id)sender {
261 [self handleActionAsKey:ui::VKEY_DOWN domCode:ui::DomCode::ARROW_DOWN];
262 }
263
264 - (void)cancelOperation:(id)sender {
265 [self handleActionAsKey:ui::VKEY_ESCAPE domCode:ui::DomCode::ESCAPE];
226 } 266 }
227 267
228 // Support for Services in context menus. 268 // Support for Services in context menus.
229 // Currently we only support reading and writing plain strings. 269 // Currently we only support reading and writing plain strings.
230 - (id)validRequestorForSendType:(NSString*)sendType 270 - (id)validRequestorForSendType:(NSString*)sendType
231 returnType:(NSString*)returnType { 271 returnType:(NSString*)returnType {
232 BOOL canWrite = [sendType isEqualToString:NSStringPboardType] && 272 BOOL canWrite = [sendType isEqualToString:NSStringPboardType] &&
233 [self selectedRange].length > 0; 273 [self selectedRange].length > 0;
234 BOOL canRead = [returnType isEqualToString:NSStringPboardType]; 274 BOOL canRead = [returnType isEqualToString:NSStringPboardType];
235 // Valid if (sendType, returnType) is either (string, nil), (nil, string), 275 // Valid if (sendType, returnType) is either (string, nil), (nil, string),
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 return [[[NSAttributedString alloc] 321 return [[[NSAttributedString alloc]
282 initWithString:base::SysUTF16ToNSString(substring)] autorelease]; 322 initWithString:base::SysUTF16ToNSString(substring)] autorelease];
283 } 323 }
284 324
285 - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint { 325 - (NSUInteger)characterIndexForPoint:(NSPoint)aPoint {
286 NOTIMPLEMENTED(); 326 NOTIMPLEMENTED();
287 return 0; 327 return 0;
288 } 328 }
289 329
290 - (void)doCommandBySelector:(SEL)selector { 330 - (void)doCommandBySelector:(SEL)selector {
291 if ([self respondsToSelector:selector]) 331 if ([self respondsToSelector:selector]) {
292 [self performSelector:selector withObject:nil]; 332 [self performSelector:selector withObject:nil];
293 else 333 } else {
334 NSLog(@"Unmatched selector: %@\n", NSStringFromSelector(selector));
294 [[self nextResponder] doCommandBySelector:selector]; 335 [[self nextResponder] doCommandBySelector:selector];
336 }
295 } 337 }
296 338
297 - (NSRect)firstRectForCharacterRange:(NSRange)range 339 - (NSRect)firstRectForCharacterRange:(NSRange)range
298 actualRange:(NSRangePointer)actualRange { 340 actualRange:(NSRangePointer)actualRange {
299 NOTIMPLEMENTED(); 341 NOTIMPLEMENTED();
300 return NSZeroRect; 342 return NSZeroRect;
301 } 343 }
302 344
303 - (BOOL)hasMarkedText { 345 - (BOOL)hasMarkedText {
304 return textInputClient_ && textInputClient_->HasCompositionText(); 346 return textInputClient_ && textInputClient_->HasCompositionText();
305 } 347 }
306 348
307 - (void)insertText:(id)text replacementRange:(NSRange)replacementRange { 349 - (void)insertText:(id)text replacementRange:(NSRange)replacementRange {
308 if (!textInputClient_) 350 if (!hostedView_)
309 return; 351 return;
310 352
311 if ([text isKindOfClass:[NSAttributedString class]]) 353 if ([text isKindOfClass:[NSAttributedString class]])
312 text = [text string]; 354 text = [text string];
355
356 MenuController* menuController = MenuController::GetActiveInstance();
357 if (menuController && menuController->owner() == hostedView_->GetWidget()) {
358 DCHECK([text length] > 0);
359 ui::KeyEvent event(ui::ET_KEY_PRESSED,
360 ui::KeyboardCodeFromCharCode([text characterAtIndex:0]),
361 ui::DomCode::NONE,
362 ui::EventFlagsFromModifiers([NSEvent modifierFlags]));
363 if (menuController->OnWillDispatchEvent(event) == ui::POST_DISPATCH_NONE)
364 return;
365 }
366
367 if (!textInputClient_)
368 return;
369
313 textInputClient_->DeleteRange(gfx::Range(replacementRange)); 370 textInputClient_->DeleteRange(gfx::Range(replacementRange));
314 textInputClient_->InsertText(base::SysNSStringToUTF16(text)); 371 textInputClient_->InsertText(base::SysNSStringToUTF16(text));
315 } 372 }
316 373
317 - (NSRange)markedRange { 374 - (NSRange)markedRange {
318 if (!textInputClient_) 375 if (!textInputClient_)
319 return NSMakeRange(NSNotFound, 0); 376 return NSMakeRange(NSNotFound, 0);
320 377
321 gfx::Range range; 378 gfx::Range range;
322 textInputClient_->GetCompositionTextRange(&range); 379 textInputClient_->GetCompositionTextRange(&range);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 } 420 }
364 421
365 return [super accessibilityAttributeValue:attribute]; 422 return [super accessibilityAttributeValue:attribute];
366 } 423 }
367 424
368 - (id)accessibilityHitTest:(NSPoint)point { 425 - (id)accessibilityHitTest:(NSPoint)point {
369 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; 426 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point];
370 } 427 }
371 428
372 @end 429 @end
OLDNEW
« no previous file with comments | « ui/events/keycodes/keyboard_code_conversion_mac.mm ('k') | ui/views/controls/menu/menu_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698