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

Side by Side Diff: ui/events/cocoa/events_mac_unittest.mm

Issue 251493002: MacViews: Implement basic NSEvent -> ui::Event conversion for Mac (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address comments Created 6 years, 7 months 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 | Annotate | Revision Log
« no previous file with comments | « ui/events/cocoa/events_mac.mm ('k') | ui/events/event.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "ui/events/cocoa/cocoa_event_utils.h" 5 #include "ui/events/event_utils.h"
6 6
7 #import <objc/objc-class.h> 7 #import <Cocoa/Cocoa.h>
8 8
9 #include "base/mac/scoped_cftyperef.h"
10 #include "base/memory/scoped_ptr.h"
9 #include "testing/gtest/include/gtest/gtest.h" 11 #include "testing/gtest/include/gtest/gtest.h"
10 #include "testing/platform_test.h"
11 #include "ui/events/event_constants.h" 12 #include "ui/events/event_constants.h"
12 #include "ui/events/event_utils.h"
13 #import "ui/events/test/cocoa_test_event_utils.h" 13 #import "ui/events/test/cocoa_test_event_utils.h"
14 #include "ui/gfx/point.h"
14 #import "ui/gfx/test/ui_cocoa_test_helper.h" 15 #import "ui/gfx/test/ui_cocoa_test_helper.h"
15 16
17 namespace {
18
19 NSWindow* g_test_window = nil;
20
21 } // namespace
22
23 // Mac APIs for creating test events are frustrating. Quartz APIs have, e.g.,
24 // CGEventCreateMouseEvent() which can't set a window or modifier flags.
25 // Cocoa APIs have +[NSEvent mouseEventWithType:..] which can't set
26 // buttonNumber or scroll deltas. To work around this, these tests use some
27 // Objective C magic to donate member functions to NSEvent temporarily.
28 @interface MiddleMouseButtonNumberDonor : NSObject
29 @end
30
31 @interface TestWindowDonor : NSObject
32 @end
33
34 @implementation MiddleMouseButtonNumberDonor
35 - (NSUInteger)buttonNumber { return 2; }
36 @end
37
38 @implementation TestWindowDonor
39 - (NSWindow*)window { return g_test_window; }
40 @end
41
16 namespace ui { 42 namespace ui {
17 43
18 namespace { 44 namespace {
19 45
20 class CocoaEventUtilsTest : public CocoaTest { 46 class EventsMacTest : public CocoaTest {
47 public:
48 EventsMacTest() {}
49
50 gfx::Point Flip(gfx::Point window_location) {
51 window_location.set_y(
52 NSHeight([test_window() frame]) - window_location.y());
53 return window_location;
54 }
55
56 void SwizzleMiddleMouseButton() {
57 DCHECK(!swizzler_);
58 swizzler_.reset(new ScopedClassSwizzler(
59 [NSEvent class],
60 [MiddleMouseButtonNumberDonor class],
61 @selector(buttonNumber)));
62 }
63
64 void SwizzleTestWindow() {
65 DCHECK(!g_test_window);
66 DCHECK(!swizzler_);
67 g_test_window = test_window();
68 swizzler_.reset(new ScopedClassSwizzler(
69 [NSEvent class],
70 [TestWindowDonor class],
71 @selector(window)));
72 }
73
74 void ClearSwizzle() {
75 swizzler_.reset();
76 g_test_window = nil;
77 }
78
79 NSEvent* TestMouseEvent(NSEventType type,
80 const gfx::Point &window_location,
81 NSInteger modifier_flags) {
82 NSPoint point = NSPointFromCGPoint(Flip(window_location).ToCGPoint());
83 return [NSEvent mouseEventWithType:type
84 location:point
85 modifierFlags:modifier_flags
86 timestamp:0
87 windowNumber:[test_window() windowNumber]
88 context:nil
89 eventNumber:0
90 clickCount:0
91 pressure:1.0];
92 }
93
94 NSEvent* TestScrollEvent(const gfx::Point& window_location,
95 int32_t delta_x,
96 int32_t delta_y) {
97 SwizzleTestWindow();
98 base::ScopedCFTypeRef<CGEventRef> scroll(
99 CGEventCreateScrollWheelEvent(NULL,
100 kCGScrollEventUnitLine,
101 2,
102 delta_y,
103 delta_x));
104 // CGEvents are always in global display coordinates. These are like screen
105 // coordinates, but flipped. But first the point needs to be converted out
106 // of window coordinates (which also requires flipping).
107 NSPoint window_point =
108 NSPointFromCGPoint(Flip(window_location).ToCGPoint());
109 NSPoint screen_point = [test_window() convertBaseToScreen:window_point];
110 CGFloat primary_screen_height =
111 NSHeight([[[NSScreen screens] objectAtIndex:0] frame]);
112 screen_point.y = primary_screen_height - screen_point.y;
113 CGEventSetLocation(scroll, NSPointToCGPoint(screen_point));
114 return [NSEvent eventWithCGEvent:scroll];
115 }
116
117 private:
118 scoped_ptr<ScopedClassSwizzler> swizzler_;
119
120 DISALLOW_COPY_AND_ASSIGN(EventsMacTest);
21 }; 121 };
22 122
23 TEST_F(CocoaEventUtilsTest, EventFlagsFromNative) { 123 } // namespace
124
125 TEST_F(EventsMacTest, EventFlagsFromNative) {
24 // Left click. 126 // Left click.
25 NSEvent* left = cocoa_test_event_utils::MouseEventWithType(NSLeftMouseUp, 0); 127 NSEvent* left = cocoa_test_event_utils::MouseEventWithType(NSLeftMouseUp, 0);
26 EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, EventFlagsFromNative(left)); 128 EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, EventFlagsFromNative(left));
27 129
28 // Right click. 130 // Right click.
29 NSEvent* right = cocoa_test_event_utils::MouseEventWithType(NSRightMouseUp, 131 NSEvent* right = cocoa_test_event_utils::MouseEventWithType(NSRightMouseUp,
30 0); 132 0);
31 EXPECT_EQ(EF_RIGHT_MOUSE_BUTTON, EventFlagsFromNative(right)); 133 EXPECT_EQ(EF_RIGHT_MOUSE_BUTTON, EventFlagsFromNative(right));
32 134
33 // Middle click. 135 // Middle click.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 EXPECT_EQ(EF_LEFT_MOUSE_BUTTON | EF_SHIFT_DOWN | EF_CONTROL_DOWN, 169 EXPECT_EQ(EF_LEFT_MOUSE_BUTTON | EF_SHIFT_DOWN | EF_CONTROL_DOWN,
68 EventFlagsFromNative(shiftctrl)); 170 EventFlagsFromNative(shiftctrl));
69 171
70 // Cmd + Alt + Right 172 // Cmd + Alt + Right
71 NSEvent* cmdalt = cocoa_test_event_utils::MouseEventWithType( 173 NSEvent* cmdalt = cocoa_test_event_utils::MouseEventWithType(
72 NSLeftMouseUp, NSCommandKeyMask | NSAlternateKeyMask); 174 NSLeftMouseUp, NSCommandKeyMask | NSAlternateKeyMask);
73 EXPECT_EQ(EF_LEFT_MOUSE_BUTTON | EF_COMMAND_DOWN | EF_ALT_DOWN, 175 EXPECT_EQ(EF_LEFT_MOUSE_BUTTON | EF_COMMAND_DOWN | EF_ALT_DOWN,
74 EventFlagsFromNative(cmdalt)); 176 EventFlagsFromNative(cmdalt));
75 } 177 }
76 178
77 } // namespace 179 // Tests mouse button presses and mouse wheel events.
180 TEST_F(EventsMacTest, ButtonEvents) {
181 gfx::Point location(5, 10);
182 gfx::Vector2d offset;
183
184 NSEvent* event = TestMouseEvent(NSLeftMouseDown, location, 0);
185 EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromNative(event));
186 EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, ui::EventFlagsFromNative(event));
187 EXPECT_EQ(location, ui::EventLocationFromNative(event));
188
189 SwizzleMiddleMouseButton();
190 event = TestMouseEvent(NSOtherMouseDown, location, NSShiftKeyMask);
191 EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromNative(event));
192 EXPECT_EQ(ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_SHIFT_DOWN,
193 ui::EventFlagsFromNative(event));
194 EXPECT_EQ(location, ui::EventLocationFromNative(event));
195 ClearSwizzle();
196
197 event = TestMouseEvent(NSRightMouseUp, location, 0);
198 EXPECT_EQ(ui::ET_MOUSE_RELEASED, ui::EventTypeFromNative(event));
199 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, ui::EventFlagsFromNative(event));
200 EXPECT_EQ(location, ui::EventLocationFromNative(event));
201
202 // Scroll up.
203 event = TestScrollEvent(location, 0, 1);
204 EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event));
205 EXPECT_EQ(0, ui::EventFlagsFromNative(event));
206 EXPECT_EQ(location.ToString(), ui::EventLocationFromNative(event).ToString());
207 offset = ui::GetMouseWheelOffset(event);
208 EXPECT_GT(offset.y(), 0);
209 EXPECT_EQ(0, offset.x());
210 ClearSwizzle();
211
212 // Scroll down.
213 event = TestScrollEvent(location, 0, -1);
214 EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event));
215 EXPECT_EQ(0, ui::EventFlagsFromNative(event));
216 EXPECT_EQ(location, ui::EventLocationFromNative(event));
217 offset = ui::GetMouseWheelOffset(event);
218 EXPECT_LT(offset.y(), 0);
219 EXPECT_EQ(0, offset.x());
220 ClearSwizzle();
221
222 // Scroll left.
223 event = TestScrollEvent(location, 1, 0);
224 EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event));
225 EXPECT_EQ(0, ui::EventFlagsFromNative(event));
226 EXPECT_EQ(location, ui::EventLocationFromNative(event));
227 offset = ui::GetMouseWheelOffset(event);
228 EXPECT_EQ(0, offset.y());
229 EXPECT_GT(offset.x(), 0);
230 ClearSwizzle();
231
232 // Scroll right.
233 event = TestScrollEvent(location, -1, 0);
234 EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event));
235 EXPECT_EQ(0, ui::EventFlagsFromNative(event));
236 EXPECT_EQ(location, ui::EventLocationFromNative(event));
237 offset = ui::GetMouseWheelOffset(event);
238 EXPECT_EQ(0, offset.y());
239 EXPECT_LT(offset.x(), 0);
240 ClearSwizzle();
241 }
78 242
79 } // namespace ui 243 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/cocoa/events_mac.mm ('k') | ui/events/event.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698