| 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 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "base/mac/scoped_cftyperef.h" | 10 #include "base/mac/scoped_cftyperef.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 EventsMacTest() {} | 30 EventsMacTest() {} |
| 31 | 31 |
| 32 gfx::Point Flip(gfx::Point window_location) { | 32 gfx::Point Flip(gfx::Point window_location) { |
| 33 NSRect window_frame = [test_window() frame]; | 33 NSRect window_frame = [test_window() frame]; |
| 34 CGFloat content_height = | 34 CGFloat content_height = |
| 35 NSHeight([test_window() contentRectForFrameRect:window_frame]); | 35 NSHeight([test_window() contentRectForFrameRect:window_frame]); |
| 36 window_location.set_y(content_height - window_location.y()); | 36 window_location.set_y(content_height - window_location.y()); |
| 37 return window_location; | 37 return window_location; |
| 38 } | 38 } |
| 39 | 39 |
| 40 // TODO(tapted): Move this to cocoa_test_event_utils. It's not a drop-in |
| 41 // replacement because -[NSApp sendEvent:] may route events generated this way |
| 42 // differently. |
| 40 NSEvent* TestMouseEvent(CGEventType type, | 43 NSEvent* TestMouseEvent(CGEventType type, |
| 41 const gfx::Point& window_location, | 44 const gfx::Point& window_location, |
| 42 CGEventFlags event_flags) { | 45 CGEventFlags event_flags) { |
| 43 // CGEventCreateMouseEvent() ignores the CGMouseButton parameter unless | 46 // CGEventCreateMouseEvent() ignores the CGMouseButton parameter unless |
| 44 // |type| is one of kCGEventOtherMouse{Up,Down,Dragged}. It can be an | 47 // |type| is one of kCGEventOtherMouse{Up,Down,Dragged}. It can be an |
| 45 // integer up to 31. However, constants are only supplied up to 2. For now, | 48 // integer up to 31. However, constants are only supplied up to 2. For now, |
| 46 // just assume "other" means the third/center mouse button, and rely on | 49 // just assume "other" means the third/center mouse button, and rely on |
| 47 // Quartz ignoring it when the type is not "other". | 50 // Quartz ignoring it when the type is not "other". |
| 48 CGMouseButton other_button = kCGMouseButtonCenter; | 51 CGMouseButton other_button = kCGMouseButtonCenter; |
| 49 base::ScopedCFTypeRef<CGEventRef> mouse(CGEventCreateMouseEvent( | 52 CGPoint screen_point = cocoa_test_event_utils::ScreenPointFromWindow( |
| 50 nullptr, type, TestWindowPointToScreen(window_location), other_button)); | 53 Flip(window_location).ToCGPoint(), test_window()); |
| 54 base::ScopedCFTypeRef<CGEventRef> mouse( |
| 55 CGEventCreateMouseEvent(nullptr, type, screen_point, other_button)); |
| 51 CGEventSetFlags(mouse, event_flags); | 56 CGEventSetFlags(mouse, event_flags); |
| 52 return EventWithTestWindow(mouse); | 57 return cocoa_test_event_utils::AttachWindowToCGEvent(mouse, test_window()); |
| 53 } | 58 } |
| 54 | 59 |
| 60 // Creates a scroll event from a "real" mouse wheel (i.e. not a trackpad). |
| 55 NSEvent* TestScrollEvent(const gfx::Point& window_location, | 61 NSEvent* TestScrollEvent(const gfx::Point& window_location, |
| 56 int32_t delta_x, | 62 int32_t delta_x, |
| 57 int32_t delta_y) { | 63 int32_t delta_y) { |
| 58 base::ScopedCFTypeRef<CGEventRef> scroll(CGEventCreateScrollWheelEvent( | 64 return cocoa_test_event_utils::TestScrollEvent( |
| 59 nullptr, kCGScrollEventUnitLine, 2, delta_y, delta_x)); | 65 Flip(window_location).ToCGPoint(), test_window(), delta_x, delta_y); |
| 60 CGEventSetLocation(scroll, TestWindowPointToScreen(window_location)); | |
| 61 return EventWithTestWindow(scroll); | |
| 62 } | 66 } |
| 63 | 67 |
| 64 private: | 68 private: |
| 65 CGPoint TestWindowPointToScreen(const gfx::Point& window_location) { | |
| 66 // CGEvents are always in global display coordinates. These are like screen | |
| 67 // coordinates, but flipped. But first the point needs to be converted out | |
| 68 // of window coordinates (which also requires flipping). | |
| 69 NSPoint window_point = | |
| 70 NSPointFromCGPoint(Flip(window_location).ToCGPoint()); | |
| 71 NSRect window_rect = NSMakeRect(window_point.x, window_point.y, 0, 0); | |
| 72 NSPoint screen_point = | |
| 73 [test_window() convertRectToScreen:window_rect].origin; | |
| 74 CGFloat primary_screen_height = | |
| 75 NSHeight([[[NSScreen screens] firstObject] frame]); | |
| 76 screen_point.y = primary_screen_height - screen_point.y; | |
| 77 return NSPointToCGPoint(screen_point); | |
| 78 } | |
| 79 | |
| 80 NSEvent* EventWithTestWindow(CGEventRef event) { | |
| 81 // These CGEventFields were made public in the 10.7 SDK, but don't help to | |
| 82 // populate the -[NSEvent window] pointer when creating an event with | |
| 83 // +[NSEvent eventWithCGEvent:]. Set that separately, using reflection. | |
| 84 CGEventSetIntegerValueField(event, kCGMouseEventWindowUnderMousePointer, | |
| 85 [test_window() windowNumber]); | |
| 86 CGEventSetIntegerValueField( | |
| 87 event, kCGMouseEventWindowUnderMousePointerThatCanHandleThisEvent, | |
| 88 [test_window() windowNumber]); | |
| 89 NSEvent* ns_event = [NSEvent eventWithCGEvent:event]; | |
| 90 EXPECT_EQ(nil, [ns_event window]); // Verify assumptions. | |
| 91 [ns_event setValue:test_window() forKey:@"_window"]; | |
| 92 EXPECT_EQ(test_window(), [ns_event window]); | |
| 93 return ns_event; | |
| 94 } | |
| 95 | |
| 96 DISALLOW_COPY_AND_ASSIGN(EventsMacTest); | 69 DISALLOW_COPY_AND_ASSIGN(EventsMacTest); |
| 97 }; | 70 }; |
| 98 | 71 |
| 99 } // namespace | 72 } // namespace |
| 100 | 73 |
| 101 TEST_F(EventsMacTest, EventFlagsFromNative) { | 74 TEST_F(EventsMacTest, EventFlagsFromNative) { |
| 102 // Left click. | 75 // Left click. |
| 103 NSEvent* left = cocoa_test_event_utils::MouseEventWithType(NSLeftMouseUp, 0); | 76 NSEvent* left = cocoa_test_event_utils::MouseEventWithType(NSLeftMouseUp, 0); |
| 104 EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, EventFlagsFromNative(left)); | 77 EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, EventFlagsFromNative(left)); |
| 105 | 78 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 event = cocoa_test_event_utils::MouseEventWithType(NSMouseMoved, 0); | 255 event = cocoa_test_event_utils::MouseEventWithType(NSMouseMoved, 0); |
| 283 EXPECT_EQ(ui::ET_MOUSE_MOVED, ui::EventTypeFromNative(event)); | 256 EXPECT_EQ(ui::ET_MOUSE_MOVED, ui::EventTypeFromNative(event)); |
| 284 | 257 |
| 285 event = cocoa_test_event_utils::EnterEvent(); | 258 event = cocoa_test_event_utils::EnterEvent(); |
| 286 EXPECT_EQ(ui::ET_MOUSE_ENTERED, ui::EventTypeFromNative(event)); | 259 EXPECT_EQ(ui::ET_MOUSE_ENTERED, ui::EventTypeFromNative(event)); |
| 287 event = cocoa_test_event_utils::ExitEvent(); | 260 event = cocoa_test_event_utils::ExitEvent(); |
| 288 EXPECT_EQ(ui::ET_MOUSE_EXITED, ui::EventTypeFromNative(event)); | 261 EXPECT_EQ(ui::ET_MOUSE_EXITED, ui::EventTypeFromNative(event)); |
| 289 } | 262 } |
| 290 | 263 |
| 291 } // namespace ui | 264 } // namespace ui |
| OLD | NEW |