| 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 <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
| 6 | 6 |
| 7 #import "base/mac/scoped_nsobject.h" |
| 7 #import "base/mac/scoped_objc_class_swizzler.h" | 8 #import "base/mac/scoped_objc_class_swizzler.h" |
| 8 #include "base/memory/singleton.h" | 9 #include "base/memory/singleton.h" |
| 9 #include "ui/events/event_processor.h" | 10 #include "ui/events/event_processor.h" |
| 10 #include "ui/events/event_target.h" | 11 #include "ui/events/event_target.h" |
| 11 #include "ui/events/event_target_iterator.h" | 12 #include "ui/events/event_target_iterator.h" |
| 12 #include "ui/events/event_targeter.h" | 13 #include "ui/events/event_targeter.h" |
| 13 #import "ui/events/test/cocoa_test_event_utils.h" | 14 #import "ui/events/test/cocoa_test_event_utils.h" |
| 14 #include "ui/events/test/event_generator.h" | 15 #include "ui/events/test/event_generator.h" |
| 15 #include "ui/gfx/mac/coordinate_conversion.h" | 16 #include "ui/gfx/mac/coordinate_conversion.h" |
| 16 | 17 |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 | 284 |
| 284 private: | 285 private: |
| 285 friend struct DefaultSingletonTraits<EventGeneratorDelegateMac>; | 286 friend struct DefaultSingletonTraits<EventGeneratorDelegateMac>; |
| 286 | 287 |
| 287 EventGeneratorDelegateMac(); | 288 EventGeneratorDelegateMac(); |
| 288 ~EventGeneratorDelegateMac() override; | 289 ~EventGeneratorDelegateMac() override; |
| 289 | 290 |
| 290 ui::test::EventGenerator* owner_; | 291 ui::test::EventGenerator* owner_; |
| 291 NSWindow* window_; | 292 NSWindow* window_; |
| 292 scoped_ptr<base::mac::ScopedObjCClassSwizzler> swizzle_pressed_; | 293 scoped_ptr<base::mac::ScopedObjCClassSwizzler> swizzle_pressed_; |
| 294 base::scoped_nsobject<NSMenu> fake_menu_; |
| 293 | 295 |
| 294 DISALLOW_COPY_AND_ASSIGN(EventGeneratorDelegateMac); | 296 DISALLOW_COPY_AND_ASSIGN(EventGeneratorDelegateMac); |
| 295 }; | 297 }; |
| 296 | 298 |
| 297 EventGeneratorDelegateMac::EventGeneratorDelegateMac() | 299 EventGeneratorDelegateMac::EventGeneratorDelegateMac() |
| 298 : owner_(NULL), | 300 : owner_(NULL), |
| 299 window_(NULL) { | 301 window_(NULL) { |
| 300 DCHECK(!ui::test::EventGenerator::default_delegate); | 302 DCHECK(!ui::test::EventGenerator::default_delegate); |
| 301 ui::test::EventGenerator::default_delegate = this; | 303 ui::test::EventGenerator::default_delegate = this; |
| 304 // Install a fake "edit" menu. This is normally provided by Chrome's |
| 305 // MainMenu.xib, but src/ui shouldn't depend on that. |
| 306 fake_menu_.reset([[NSMenu alloc] initWithTitle:@"Edit"]); |
| 307 struct { |
| 308 NSString* title; |
| 309 SEL action; |
| 310 NSString* key_equivalent; |
| 311 } fake_menu_item[] = { |
| 312 { @"Undo", @selector(undo:), @"z" }, |
| 313 { @"Redo", @selector(redo:), @"Z" }, |
| 314 { @"Copy", @selector(copy:), @"c" }, |
| 315 { @"Cut", @selector(cut:), @"x" }, |
| 316 { @"Paste", @selector(paste:), @"v" }, |
| 317 { @"Select All", @selector(selectAll:), @"a" }, |
| 318 }; |
| 319 for (size_t i = 0; i < arraysize(fake_menu_item); ++i) { |
| 320 [fake_menu_ insertItemWithTitle:fake_menu_item[i].title |
| 321 action:fake_menu_item[i].action |
| 322 keyEquivalent:fake_menu_item[i].key_equivalent |
| 323 atIndex:i]; |
| 324 } |
| 302 } | 325 } |
| 303 | 326 |
| 304 EventGeneratorDelegateMac::~EventGeneratorDelegateMac() { | 327 EventGeneratorDelegateMac::~EventGeneratorDelegateMac() { |
| 305 DCHECK_EQ(this, ui::test::EventGenerator::default_delegate); | 328 DCHECK_EQ(this, ui::test::EventGenerator::default_delegate); |
| 306 ui::test::EventGenerator::default_delegate = NULL; | 329 ui::test::EventGenerator::default_delegate = NULL; |
| 307 } | 330 } |
| 308 | 331 |
| 309 scoped_ptr<ui::EventTargetIterator> | 332 scoped_ptr<ui::EventTargetIterator> |
| 310 EventGeneratorDelegateMac::GetChildIterator() const { | 333 EventGeneratorDelegateMac::GetChildIterator() const { |
| 311 // Return NULL to dispatch all events to the result of GetRootTarget(). | 334 // Return NULL to dispatch all events to the result of GetRootTarget(). |
| (...skipping 11 matching lines...) Expand all Loading... |
| 323 [NSApp sendEvent:ns_event]; | 346 [NSApp sendEvent:ns_event]; |
| 324 else | 347 else |
| 325 EmulateSendEvent(window_, ns_event); | 348 EmulateSendEvent(window_, ns_event); |
| 326 } | 349 } |
| 327 | 350 |
| 328 void EventGeneratorDelegateMac::OnKeyEvent(ui::KeyEvent* event) { | 351 void EventGeneratorDelegateMac::OnKeyEvent(ui::KeyEvent* event) { |
| 329 NSUInteger modifiers = EventFlagsToModifiers(event->flags()); | 352 NSUInteger modifiers = EventFlagsToModifiers(event->flags()); |
| 330 NSEvent* ns_event = cocoa_test_event_utils::SynthesizeKeyEvent( | 353 NSEvent* ns_event = cocoa_test_event_utils::SynthesizeKeyEvent( |
| 331 window_, event->type() == ui::ET_KEY_PRESSED, event->key_code(), | 354 window_, event->type() == ui::ET_KEY_PRESSED, event->key_code(), |
| 332 modifiers); | 355 modifiers); |
| 333 if (owner_->targeting_application()) | 356 if (owner_->targeting_application()) { |
| 334 [NSApp sendEvent:ns_event]; | 357 [NSApp sendEvent:ns_event]; |
| 335 else | 358 return; |
| 336 EmulateSendEvent(window_, ns_event); | 359 } |
| 360 |
| 361 if ([fake_menu_ performKeyEquivalent:ns_event]) |
| 362 return; |
| 363 |
| 364 EmulateSendEvent(window_, ns_event); |
| 337 } | 365 } |
| 338 | 366 |
| 339 void EventGeneratorDelegateMac::SetContext(ui::test::EventGenerator* owner, | 367 void EventGeneratorDelegateMac::SetContext(ui::test::EventGenerator* owner, |
| 340 gfx::NativeWindow root_window, | 368 gfx::NativeWindow root_window, |
| 341 gfx::NativeWindow window) { | 369 gfx::NativeWindow window) { |
| 342 swizzle_pressed_.reset(); | 370 swizzle_pressed_.reset(); |
| 343 owner_ = owner; | 371 owner_ = owner; |
| 344 window_ = window; | 372 window_ = window; |
| 373 |
| 374 // Normally, edit menu items have a `nil` target. This results in -[NSMenu |
| 375 // performKeyEquivalent:] relying on -[NSApplication targetForAction:to:from:] |
| 376 // to find a target starting at the first responder of the key window. Since |
| 377 // non-interactive tests have no key window, that won't work. So set (or |
| 378 // clear) the target explicitly on all menu items. |
| 379 [[fake_menu_ itemArray] makeObjectsPerformSelector:@selector(setTarget:) |
| 380 withObject:[window firstResponder]]; |
| 381 |
| 345 if (owner_) { | 382 if (owner_) { |
| 346 swizzle_pressed_.reset(new base::mac::ScopedObjCClassSwizzler( | 383 swizzle_pressed_.reset(new base::mac::ScopedObjCClassSwizzler( |
| 347 [NSEvent class], | 384 [NSEvent class], |
| 348 [NSEventDonor class], | 385 [NSEventDonor class], |
| 349 @selector(pressedMouseButtons))); | 386 @selector(pressedMouseButtons))); |
| 350 } | 387 } |
| 351 } | 388 } |
| 352 | 389 |
| 353 gfx::Point EventGeneratorDelegateMac::CenterOfTarget( | 390 gfx::Point EventGeneratorDelegateMac::CenterOfTarget( |
| 354 const ui::EventTarget* target) const { | 391 const ui::EventTarget* target) const { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 366 | 403 |
| 367 namespace views { | 404 namespace views { |
| 368 namespace test { | 405 namespace test { |
| 369 | 406 |
| 370 void InitializeMacEventGeneratorDelegate() { | 407 void InitializeMacEventGeneratorDelegate() { |
| 371 EventGeneratorDelegateMac::GetInstance(); | 408 EventGeneratorDelegateMac::GetInstance(); |
| 372 } | 409 } |
| 373 | 410 |
| 374 } // namespace test | 411 } // namespace test |
| 375 } // namespace views | 412 } // namespace views |
| OLD | NEW |