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/mac_util.h" | 8 #import "base/mac/mac_util.h" |
9 #import "base/mac/scoped_nsobject.h" | 9 #import "base/mac/scoped_nsobject.h" |
10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "ui/strings/grit/ui_strings.h" | 25 #include "ui/strings/grit/ui_strings.h" |
26 #include "ui/views/controls/menu/menu_config.h" | 26 #include "ui/views/controls/menu/menu_config.h" |
27 #include "ui/views/controls/menu/menu_controller.h" | 27 #include "ui/views/controls/menu/menu_controller.h" |
28 #include "ui/views/view.h" | 28 #include "ui/views/view.h" |
29 #include "ui/views/widget/widget.h" | 29 #include "ui/views/widget/widget.h" |
30 | 30 |
31 using views::MenuController; | 31 using views::MenuController; |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
| 35 NSString* const kFullKeyboardAccessChangedNotification = |
| 36 @"com.apple.KeyboardUIModeDidChange"; |
| 37 |
35 // Returns true if all four corners of |rect| are contained inside |path|. | 38 // Returns true if all four corners of |rect| are contained inside |path|. |
36 bool IsRectInsidePath(NSRect rect, NSBezierPath* path) { | 39 bool IsRectInsidePath(NSRect rect, NSBezierPath* path) { |
37 return [path containsPoint:rect.origin] && | 40 return [path containsPoint:rect.origin] && |
38 [path containsPoint:NSMakePoint(rect.origin.x + rect.size.width, | 41 [path containsPoint:NSMakePoint(rect.origin.x + rect.size.width, |
39 rect.origin.y)] && | 42 rect.origin.y)] && |
40 [path containsPoint:NSMakePoint(rect.origin.x, | 43 [path containsPoint:NSMakePoint(rect.origin.x, |
41 rect.origin.y + rect.size.height)] && | 44 rect.origin.y + rect.size.height)] && |
42 [path containsPoint:NSMakePoint(rect.origin.x + rect.size.width, | 45 [path containsPoint:NSMakePoint(rect.origin.x + rect.size.width, |
43 rect.origin.y + rect.size.height)]; | 46 rect.origin.y + rect.size.height)]; |
44 } | 47 } |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 // catered for. | 181 // catered for. |
179 // Note: default key bindings in Mac can be read from StandardKeyBinding.dict | 182 // Note: default key bindings in Mac can be read from StandardKeyBinding.dict |
180 // which lives in /System/Library/Frameworks/AppKit.framework/Resources. Do | 183 // which lives in /System/Library/Frameworks/AppKit.framework/Resources. Do |
181 // `plutil -convert xml1 -o StandardKeyBinding.xml StandardKeyBinding.dict` to | 184 // `plutil -convert xml1 -o StandardKeyBinding.xml StandardKeyBinding.dict` to |
182 // get something readable. | 185 // get something readable. |
183 - (void)handleAction:(int)commandId | 186 - (void)handleAction:(int)commandId |
184 keyCode:(ui::KeyboardCode)keyCode | 187 keyCode:(ui::KeyboardCode)keyCode |
185 domCode:(ui::DomCode)domCode | 188 domCode:(ui::DomCode)domCode |
186 eventFlags:(int)eventFlags; | 189 eventFlags:(int)eventFlags; |
187 | 190 |
| 191 // Notification handler invoked when the Full Keyboard Access mode is changed. |
| 192 - (void)onFullKeyboardAccessModeChanged:(NSNotification*)notification; |
| 193 |
188 // Menu action handlers. | 194 // Menu action handlers. |
189 - (void)undo:(id)sender; | 195 - (void)undo:(id)sender; |
190 - (void)redo:(id)sender; | 196 - (void)redo:(id)sender; |
191 - (void)cut:(id)sender; | 197 - (void)cut:(id)sender; |
192 - (void)copy:(id)sender; | 198 - (void)copy:(id)sender; |
193 - (void)paste:(id)sender; | 199 - (void)paste:(id)sender; |
194 - (void)selectAll:(id)sender; | 200 - (void)selectAll:(id)sender; |
195 | 201 |
196 @end | 202 @end |
197 | 203 |
(...skipping 16 matching lines...) Expand all Loading... |
214 | 220 |
215 // Apple's documentation says that NSTrackingActiveAlways is incompatible | 221 // Apple's documentation says that NSTrackingActiveAlways is incompatible |
216 // with NSTrackingCursorUpdate, so use NSTrackingActiveInActiveApp. | 222 // with NSTrackingCursorUpdate, so use NSTrackingActiveInActiveApp. |
217 cursorTrackingArea_.reset([[CrTrackingArea alloc] | 223 cursorTrackingArea_.reset([[CrTrackingArea alloc] |
218 initWithRect:NSZeroRect | 224 initWithRect:NSZeroRect |
219 options:NSTrackingMouseMoved | NSTrackingCursorUpdate | | 225 options:NSTrackingMouseMoved | NSTrackingCursorUpdate | |
220 NSTrackingActiveInActiveApp | NSTrackingInVisibleRect | 226 NSTrackingActiveInActiveApp | NSTrackingInVisibleRect |
221 owner:self | 227 owner:self |
222 userInfo:nil]); | 228 userInfo:nil]); |
223 [self addTrackingArea:cursorTrackingArea_.get()]; | 229 [self addTrackingArea:cursorTrackingArea_.get()]; |
| 230 |
| 231 // Get notified whenever Full Keyboard Access mode is changed. |
| 232 [[NSDistributedNotificationCenter defaultCenter] |
| 233 addObserver:self |
| 234 selector:@selector(onFullKeyboardAccessModeChanged:) |
| 235 name:kFullKeyboardAccessChangedNotification |
| 236 object:nil]; |
| 237 |
| 238 // Initialize the focus manager with the correct keyboard accessibility |
| 239 // setting. |
| 240 [self updateFullKeyboardAccess]; |
224 } | 241 } |
225 return self; | 242 return self; |
226 } | 243 } |
227 | 244 |
228 - (void)clearView { | 245 - (void)clearView { |
229 textInputClient_ = nullptr; | 246 textInputClient_ = nullptr; |
230 hostedView_ = nullptr; | 247 hostedView_ = nullptr; |
| 248 [[NSDistributedNotificationCenter defaultCenter] removeObserver:self]; |
231 [cursorTrackingArea_.get() clearOwner]; | 249 [cursorTrackingArea_.get() clearOwner]; |
232 [self removeTrackingArea:cursorTrackingArea_.get()]; | 250 [self removeTrackingArea:cursorTrackingArea_.get()]; |
233 } | 251 } |
234 | 252 |
235 - (void)processCapturedMouseEvent:(NSEvent*)theEvent { | 253 - (void)processCapturedMouseEvent:(NSEvent*)theEvent { |
236 if (!hostedView_) | 254 if (!hostedView_) |
237 return; | 255 return; |
238 | 256 |
239 NSWindow* source = [theEvent window]; | 257 NSWindow* source = [theEvent window]; |
240 NSWindow* target = [self window]; | 258 NSWindow* target = [self window]; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 | 304 |
287 windowMask_.reset([gfx::CreateNSBezierPathFromSkPath(mask) retain]); | 305 windowMask_.reset([gfx::CreateNSBezierPathFromSkPath(mask) retain]); |
288 | 306 |
289 // Convert to AppKit coordinate system. | 307 // Convert to AppKit coordinate system. |
290 NSAffineTransform* flipTransform = [NSAffineTransform transform]; | 308 NSAffineTransform* flipTransform = [NSAffineTransform transform]; |
291 [flipTransform translateXBy:0.0 yBy:frameRect.size.height]; | 309 [flipTransform translateXBy:0.0 yBy:frameRect.size.height]; |
292 [flipTransform scaleXBy:1.0 yBy:-1.0]; | 310 [flipTransform scaleXBy:1.0 yBy:-1.0]; |
293 [windowMask_ transformUsingAffineTransform:flipTransform]; | 311 [windowMask_ transformUsingAffineTransform:flipTransform]; |
294 } | 312 } |
295 | 313 |
| 314 - (void)updateFullKeyboardAccess { |
| 315 if (!hostedView_) |
| 316 return; |
| 317 |
| 318 views::FocusManager* focusManager = |
| 319 hostedView_->GetWidget()->GetFocusManager(); |
| 320 if (focusManager) |
| 321 focusManager->SetKeyboardAccessible([NSApp isFullKeyboardAccessEnabled]); |
| 322 } |
| 323 |
296 // BridgedContentView private implementation. | 324 // BridgedContentView private implementation. |
297 | 325 |
298 - (void)handleKeyEvent:(NSEvent*)theEvent { | 326 - (void)handleKeyEvent:(NSEvent*)theEvent { |
299 if (!hostedView_) | 327 if (!hostedView_) |
300 return; | 328 return; |
301 | 329 |
302 DCHECK(theEvent); | 330 DCHECK(theEvent); |
303 ui::KeyEvent event(theEvent); | 331 ui::KeyEvent event(theEvent); |
304 if (DispatchEventToMenu(hostedView_->GetWidget(), event.key_code())) | 332 if (DispatchEventToMenu(hostedView_->GetWidget(), event.key_code())) |
305 return; | 333 return; |
(...skipping 15 matching lines...) Expand all Loading... |
321 // performed. | 349 // performed. |
322 if (commandId && textInputClient_ && | 350 if (commandId && textInputClient_ && |
323 textInputClient_->IsEditCommandEnabled(commandId)) | 351 textInputClient_->IsEditCommandEnabled(commandId)) |
324 textInputClient_->SetEditCommandForNextKeyEvent(commandId); | 352 textInputClient_->SetEditCommandForNextKeyEvent(commandId); |
325 | 353 |
326 // Generate a synthetic event with the keycode toolkit-views expects. | 354 // Generate a synthetic event with the keycode toolkit-views expects. |
327 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags); | 355 ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags); |
328 hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(&event); | 356 hostedView_->GetWidget()->GetInputMethod()->DispatchKeyEvent(&event); |
329 } | 357 } |
330 | 358 |
| 359 - (void)onFullKeyboardAccessModeChanged:(NSNotification*)notification { |
| 360 DCHECK([[notification name] |
| 361 isEqualToString:kFullKeyboardAccessChangedNotification]); |
| 362 [self updateFullKeyboardAccess]; |
| 363 } |
| 364 |
331 - (void)undo:(id)sender { | 365 - (void)undo:(id)sender { |
332 // This DCHECK is more strict than a similar check in handleAction:. It can be | 366 // This DCHECK is more strict than a similar check in handleAction:. It can be |
333 // done here because the actors sending these actions should be calling | 367 // done here because the actors sending these actions should be calling |
334 // validateUserInterfaceItem: before enabling UI that allows these messages to | 368 // validateUserInterfaceItem: before enabling UI that allows these messages to |
335 // be sent. Checking it here would be too late to provide correct UI feedback | 369 // be sent. Checking it here would be too late to provide correct UI feedback |
336 // (e.g. there will be no "beep"). | 370 // (e.g. there will be no "beep"). |
337 DCHECK(textInputClient_->IsEditCommandEnabled(IDS_APP_UNDO)); | 371 DCHECK(textInputClient_->IsEditCommandEnabled(IDS_APP_UNDO)); |
338 [self handleAction:IDS_APP_UNDO | 372 [self handleAction:IDS_APP_UNDO |
339 keyCode:ui::VKEY_Z | 373 keyCode:ui::VKEY_Z |
340 domCode:ui::DomCode::US_Z | 374 domCode:ui::DomCode::US_Z |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 } | 986 } |
953 | 987 |
954 return [super accessibilityAttributeValue:attribute]; | 988 return [super accessibilityAttributeValue:attribute]; |
955 } | 989 } |
956 | 990 |
957 - (id)accessibilityHitTest:(NSPoint)point { | 991 - (id)accessibilityHitTest:(NSPoint)point { |
958 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; | 992 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; |
959 } | 993 } |
960 | 994 |
961 @end | 995 @end |
OLD | NEW |