Chromium Code Reviews| 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" |
| 11 #include "base/mac/sdk_forward_declarations.h" | 11 #include "base/mac/sdk_forward_declarations.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 14 #import "ui/events/cocoa/cocoa_event_utils.h" | |
| 14 #include "ui/events/event_constants.h" | 15 #include "ui/events/event_constants.h" |
| 15 #include "ui/events/event_utils.h" | 16 #include "ui/events/event_utils.h" |
| 16 #import "ui/events/test/cocoa_test_event_utils.h" | 17 #import "ui/events/test/cocoa_test_event_utils.h" |
| 17 #include "ui/gfx/geometry/point.h" | 18 #include "ui/gfx/geometry/point.h" |
| 18 #import "ui/gfx/test/ui_cocoa_test_helper.h" | 19 #import "ui/gfx/test/ui_cocoa_test_helper.h" |
| 19 | 20 |
| 20 namespace ui { | 21 namespace ui { |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 54 base::ScopedCFTypeRef<CGEventRef> mouse( | 55 base::ScopedCFTypeRef<CGEventRef> mouse( |
| 55 CGEventCreateMouseEvent(nullptr, type, screen_point, other_button)); | 56 CGEventCreateMouseEvent(nullptr, type, screen_point, other_button)); |
| 56 CGEventSetFlags(mouse, event_flags); | 57 CGEventSetFlags(mouse, event_flags); |
| 57 return cocoa_test_event_utils::AttachWindowToCGEvent(mouse, test_window()); | 58 return cocoa_test_event_utils::AttachWindowToCGEvent(mouse, test_window()); |
| 58 } | 59 } |
| 59 | 60 |
| 60 // Creates a scroll event from a "real" mouse wheel (i.e. not a trackpad). | 61 // Creates a scroll event from a "real" mouse wheel (i.e. not a trackpad). |
| 61 NSEvent* TestScrollEvent(const gfx::Point& window_location, | 62 NSEvent* TestScrollEvent(const gfx::Point& window_location, |
| 62 int32_t delta_x, | 63 int32_t delta_x, |
| 63 int32_t delta_y) { | 64 int32_t delta_y) { |
| 65 bool precise = false; | |
| 64 return cocoa_test_event_utils::TestScrollEvent( | 66 return cocoa_test_event_utils::TestScrollEvent( |
| 65 Flip(window_location).ToCGPoint(), test_window(), delta_x, delta_y); | 67 Flip(window_location).ToCGPoint(), test_window(), delta_x, delta_y, |
| 68 precise, NSEventPhaseNone, NSEventPhaseNone); | |
| 66 } | 69 } |
| 67 | 70 |
| 71 // Creates the sequence of events generated by a trackpad scroll. | |
| 72 // |initial_rest| indicates whether there is a pause before scrolling starts. | |
| 73 // |delta_y| is the portion to scroll without momentum (fingers on the | |
| 74 // trackpad). |momentum_delta_y| is the momentum portion. A zero delta skips | |
| 75 // that phase (if both are zero, the |initial_rest| is cancelled). | |
| 76 void TrackpadScrollSequence(bool initial_rest, | |
| 77 int32_t delta_y, | |
| 78 int32_t momentum_delta_y, | |
| 79 std::vector<NSEvent*>* events); | |
|
sky
2016/09/23 17:47:08
Is there an equivalent to std::unique_ptr you can
tapted
2016/09/26 11:12:20
Done (made this more idiomatic).
scoped_nsobject
| |
| 80 | |
| 81 protected: | |
| 82 const gfx::Point default_location_ = gfx::Point(10, 20); | |
| 83 | |
| 68 private: | 84 private: |
| 69 DISALLOW_COPY_AND_ASSIGN(EventsMacTest); | 85 DISALLOW_COPY_AND_ASSIGN(EventsMacTest); |
| 70 }; | 86 }; |
| 71 | 87 |
| 88 // Trackpad scroll sequences below determined empirically on OSX 10.11 (linking | |
| 89 // to 10.10 SDK), and dumping out with NSLog in -[NSView scrollWheel:]. First | |
| 90 // created using a Magic Trackpad 2 on a MacPro. See the Trackpad* test cases | |
| 91 // below for example event streams. | |
| 92 void EventsMacTest::TrackpadScrollSequence(bool initial_rest, | |
| 93 int32_t delta_y, | |
| 94 int32_t momentum_delta_y, | |
| 95 std::vector<NSEvent*>* events) { | |
| 96 int32_t delta_x = 0; // Just test vertical scrolling for now. | |
| 97 | |
| 98 // Resting part. | |
| 99 if (initial_rest) { | |
| 100 // MayBegin always has a zero delta. | |
| 101 events->push_back(cocoa_test_event_utils::TestScrollEvent( | |
| 102 Flip(default_location_).ToCGPoint(), test_window(), delta_x, 0, true, | |
| 103 NSEventPhaseMayBegin, NSEventPhaseNone)); | |
| 104 if (delta_y == 0) { | |
| 105 // Rest and release: event gets cancelled. | |
| 106 DCHECK_EQ(0, momentum_delta_y); // Pretty sure this is impossible. | |
| 107 events->push_back(cocoa_test_event_utils::TestScrollEvent( | |
| 108 Flip(default_location_).ToCGPoint(), test_window(), delta_x, 0, true, | |
| 109 NSEventPhaseCancelled, NSEventPhaseNone)); | |
| 110 return; | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 // With or without a rest, a begin is sent. It can have a non-zero | |
| 115 // deviceDeltaY but regular deltaY is always 0. | |
| 116 events->push_back(cocoa_test_event_utils::TestScrollEvent( | |
| 117 Flip(default_location_).ToCGPoint(), test_window(), delta_x, 0, true, | |
| 118 NSEventPhaseBegan, NSEventPhaseNone)); | |
| 119 | |
| 120 events->push_back(cocoa_test_event_utils::TestScrollEvent( | |
| 121 Flip(default_location_).ToCGPoint(), test_window(), delta_x, delta_y, | |
| 122 true, NSEventPhaseChanged, NSEventPhaseNone)); | |
| 123 | |
| 124 // With or without momentum, an end is sent for the non-momentum part. | |
| 125 events->push_back(cocoa_test_event_utils::TestScrollEvent( | |
| 126 Flip(default_location_).ToCGPoint(), test_window(), delta_x, 0, true, | |
| 127 NSEventPhaseEnded, NSEventPhaseNone)); | |
| 128 | |
| 129 if (momentum_delta_y == 0) | |
| 130 return; | |
| 131 | |
| 132 // Flick part. Basically the same, but with phase and momentumPhase swapped. | |
| 133 events->push_back(cocoa_test_event_utils::TestScrollEvent( | |
| 134 Flip(default_location_).ToCGPoint(), test_window(), delta_x, 0, true, | |
| 135 NSEventPhaseNone, NSEventPhaseBegan)); | |
| 136 | |
| 137 events->push_back(cocoa_test_event_utils::TestScrollEvent( | |
| 138 Flip(default_location_).ToCGPoint(), test_window(), delta_x, | |
| 139 momentum_delta_y, true, NSEventPhaseNone, NSEventPhaseChanged)); | |
| 140 | |
| 141 events->push_back(cocoa_test_event_utils::TestScrollEvent( | |
| 142 Flip(default_location_).ToCGPoint(), test_window(), delta_x, 0, true, | |
| 143 NSEventPhaseNone, NSEventPhaseEnded)); | |
| 144 } | |
| 145 | |
| 72 } // namespace | 146 } // namespace |
| 73 | 147 |
| 74 TEST_F(EventsMacTest, EventFlagsFromNative) { | 148 TEST_F(EventsMacTest, EventFlagsFromNative) { |
| 75 // Left click. | 149 // Left click. |
| 76 NSEvent* left = cocoa_test_event_utils::MouseEventWithType(NSLeftMouseUp, 0); | 150 NSEvent* left = cocoa_test_event_utils::MouseEventWithType(NSLeftMouseUp, 0); |
| 77 EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, EventFlagsFromNative(left)); | 151 EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, EventFlagsFromNative(left)); |
| 78 | 152 |
| 79 // Right click. | 153 // Right click. |
| 80 NSEvent* right = cocoa_test_event_utils::MouseEventWithType(NSRightMouseUp, | 154 NSEvent* right = cocoa_test_event_utils::MouseEventWithType(NSRightMouseUp, |
| 81 0); | 155 0); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 ui::EventFlagsFromNative(event)); | 222 ui::EventFlagsFromNative(event)); |
| 149 EXPECT_EQ(location, ui::EventLocationFromNative(event)); | 223 EXPECT_EQ(location, ui::EventLocationFromNative(event)); |
| 150 | 224 |
| 151 event = TestMouseEvent(kCGEventRightMouseUp, location, kNoEventFlags); | 225 event = TestMouseEvent(kCGEventRightMouseUp, location, kNoEventFlags); |
| 152 EXPECT_EQ(ui::ET_MOUSE_RELEASED, ui::EventTypeFromNative(event)); | 226 EXPECT_EQ(ui::ET_MOUSE_RELEASED, ui::EventTypeFromNative(event)); |
| 153 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, ui::EventFlagsFromNative(event)); | 227 EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, ui::EventFlagsFromNative(event)); |
| 154 EXPECT_EQ(location, ui::EventLocationFromNative(event)); | 228 EXPECT_EQ(location, ui::EventLocationFromNative(event)); |
| 155 | 229 |
| 156 // Scroll up. | 230 // Scroll up. |
| 157 event = TestScrollEvent(location, 0, 1); | 231 event = TestScrollEvent(location, 0, 1); |
| 158 EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event)); | 232 EXPECT_EQ(ui::ET_SCROLL, ui::EventTypeFromNative(event)); |
| 159 EXPECT_EQ(0, ui::EventFlagsFromNative(event)); | 233 EXPECT_EQ(0, ui::EventFlagsFromNative(event)); |
| 160 EXPECT_EQ(location.ToString(), ui::EventLocationFromNative(event).ToString()); | 234 EXPECT_EQ(location.ToString(), ui::EventLocationFromNative(event).ToString()); |
| 161 offset = ui::GetMouseWheelOffset(event); | 235 offset = ui::GetMouseWheelOffset(event); |
| 162 EXPECT_GT(offset.y(), 0); | 236 EXPECT_GT(offset.y(), 0); |
| 163 EXPECT_EQ(0, offset.x()); | 237 EXPECT_EQ(0, offset.x()); |
| 164 | 238 |
| 165 // Scroll down. | 239 // Scroll down. |
| 166 event = TestScrollEvent(location, 0, -1); | 240 event = TestScrollEvent(location, 0, -1); |
| 167 EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event)); | 241 EXPECT_EQ(ui::ET_SCROLL, ui::EventTypeFromNative(event)); |
| 168 EXPECT_EQ(0, ui::EventFlagsFromNative(event)); | 242 EXPECT_EQ(0, ui::EventFlagsFromNative(event)); |
| 169 EXPECT_EQ(location, ui::EventLocationFromNative(event)); | 243 EXPECT_EQ(location, ui::EventLocationFromNative(event)); |
| 170 offset = ui::GetMouseWheelOffset(event); | 244 offset = ui::GetMouseWheelOffset(event); |
| 171 EXPECT_LT(offset.y(), 0); | 245 EXPECT_LT(offset.y(), 0); |
| 172 EXPECT_EQ(0, offset.x()); | 246 EXPECT_EQ(0, offset.x()); |
| 173 | 247 |
| 174 // Scroll left. | 248 // Scroll left. |
| 175 event = TestScrollEvent(location, 1, 0); | 249 event = TestScrollEvent(location, 1, 0); |
| 176 EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event)); | 250 EXPECT_EQ(ui::ET_SCROLL, ui::EventTypeFromNative(event)); |
| 177 EXPECT_EQ(0, ui::EventFlagsFromNative(event)); | 251 EXPECT_EQ(0, ui::EventFlagsFromNative(event)); |
| 178 EXPECT_EQ(location, ui::EventLocationFromNative(event)); | 252 EXPECT_EQ(location, ui::EventLocationFromNative(event)); |
| 179 offset = ui::GetMouseWheelOffset(event); | 253 offset = ui::GetMouseWheelOffset(event); |
| 180 EXPECT_EQ(0, offset.y()); | 254 EXPECT_EQ(0, offset.y()); |
| 181 EXPECT_GT(offset.x(), 0); | 255 EXPECT_GT(offset.x(), 0); |
| 182 | 256 |
| 183 // Scroll right. | 257 // Scroll right. |
| 184 event = TestScrollEvent(location, -1, 0); | 258 event = TestScrollEvent(location, -1, 0); |
| 185 EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event)); | 259 EXPECT_EQ(ui::ET_SCROLL, ui::EventTypeFromNative(event)); |
| 186 EXPECT_EQ(0, ui::EventFlagsFromNative(event)); | 260 EXPECT_EQ(0, ui::EventFlagsFromNative(event)); |
| 187 EXPECT_EQ(location, ui::EventLocationFromNative(event)); | 261 EXPECT_EQ(location, ui::EventLocationFromNative(event)); |
| 188 offset = ui::GetMouseWheelOffset(event); | 262 offset = ui::GetMouseWheelOffset(event); |
| 189 EXPECT_EQ(0, offset.y()); | 263 EXPECT_EQ(0, offset.y()); |
| 190 EXPECT_LT(offset.x(), 0); | 264 EXPECT_LT(offset.x(), 0); |
| 191 } | 265 } |
| 192 | 266 |
| 193 // Test correct location when the window has a native titlebar. | 267 // Test correct location when the window has a native titlebar. |
| 194 TEST_F(EventsMacTest, NativeTitlebarEventLocation) { | 268 TEST_F(EventsMacTest, NativeTitlebarEventLocation) { |
| 195 gfx::Point location(5, 10); | 269 gfx::Point location(5, 10); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 | 328 |
| 255 event = cocoa_test_event_utils::MouseEventWithType(NSMouseMoved, 0); | 329 event = cocoa_test_event_utils::MouseEventWithType(NSMouseMoved, 0); |
| 256 EXPECT_EQ(ui::ET_MOUSE_MOVED, ui::EventTypeFromNative(event)); | 330 EXPECT_EQ(ui::ET_MOUSE_MOVED, ui::EventTypeFromNative(event)); |
| 257 | 331 |
| 258 event = cocoa_test_event_utils::EnterEvent(); | 332 event = cocoa_test_event_utils::EnterEvent(); |
| 259 EXPECT_EQ(ui::ET_MOUSE_ENTERED, ui::EventTypeFromNative(event)); | 333 EXPECT_EQ(ui::ET_MOUSE_ENTERED, ui::EventTypeFromNative(event)); |
| 260 event = cocoa_test_event_utils::ExitEvent(); | 334 event = cocoa_test_event_utils::ExitEvent(); |
| 261 EXPECT_EQ(ui::ET_MOUSE_EXITED, ui::EventTypeFromNative(event)); | 335 EXPECT_EQ(ui::ET_MOUSE_EXITED, ui::EventTypeFromNative(event)); |
| 262 } | 336 } |
| 263 | 337 |
| 338 // Verify that a mouse wheel scroll event is correctly lacking phase data. | |
| 339 TEST_F(EventsMacTest, MouseWheelScroll) { | |
| 340 int32_t wheel_delta_y = 2; | |
| 341 | |
| 342 NSEvent* ns_wheel = TestScrollEvent(default_location_, 0, wheel_delta_y); | |
| 343 EXPECT_FALSE([ns_wheel hasPreciseScrollingDeltas]); | |
| 344 ui::ScrollEvent wheel(ns_wheel); | |
| 345 EXPECT_EQ(ui::ET_SCROLL, wheel.type()); | |
| 346 | |
| 347 // Currently wheel events still say two for finger count, but this may change. | |
| 348 EXPECT_EQ(2, wheel.finger_count()); | |
| 349 | |
| 350 // Note the phase is "end" for wheel events, not "none". There is always an | |
| 351 // "end" when no more events are expected. | |
| 352 EXPECT_EQ(ui::EM_PHASE_END, wheel.momentum_phase()); | |
| 353 EXPECT_EQ(default_location_, wheel.location()); | |
| 354 | |
| 355 float pixel_delta_y = wheel_delta_y * ui::kScrollbarPixelsPerCocoaTick; | |
| 356 EXPECT_EQ(pixel_delta_y, wheel.y_offset_ordinal()); | |
| 357 EXPECT_EQ(0, wheel.x_offset_ordinal()); | |
| 358 } | |
| 359 | |
| 360 // Test the event flow for a trackpad "rest" that doesn't result in scrolling | |
| 361 // nor momentum. Also check the boring stuff like type, finger count and | |
| 362 // location, which isn't phase-specific. | |
| 363 // Sequence: | |
| 364 // (1) NSEvent: type=ScrollWheel loc=(780,41) time=14909.3 flags=0x100 win=<set> | |
| 365 // {deviceD,d}elta{X,Y,Z}=0 count:0 phase=MayBegin momentumPhase=None | |
| 366 // (2) NSEvent: type=ScrollWheel loc=(780,41) time=14912.9 flags=0x100 win=<set> | |
| 367 // {deviceD,d}elta{X,Y,Z}=0 count:0 phase=Cancelled momentumPhase=None. | |
| 368 TEST_F(EventsMacTest, TrackpadRestRelease) { | |
| 369 std::vector<NSEvent*> ns_events; | |
| 370 TrackpadScrollSequence(true, 0, 0, &ns_events); | |
| 371 ASSERT_EQ(2u, ns_events.size()); | |
| 372 EXPECT_TRUE([ns_events[0] hasPreciseScrollingDeltas]); | |
| 373 | |
| 374 ui::ScrollEvent rest(ns_events[0]); | |
| 375 EXPECT_EQ(ui::ET_SCROLL, rest.type()); | |
| 376 EXPECT_EQ(2, rest.finger_count()); | |
| 377 EXPECT_EQ(ui::EM_PHASE_MAY_BEGIN, rest.momentum_phase()); | |
| 378 EXPECT_EQ(0, rest.y_offset_ordinal()); | |
| 379 EXPECT_EQ(default_location_, rest.location()); | |
| 380 | |
| 381 ui::ScrollEvent cancel(ns_events[1]); | |
| 382 EXPECT_EQ(ui::ET_SCROLL, cancel.type()); | |
| 383 EXPECT_EQ(2, cancel.finger_count()); | |
| 384 EXPECT_EQ(ui::EM_PHASE_END, cancel.momentum_phase()); | |
| 385 EXPECT_EQ(0, cancel.y_offset_ordinal()); | |
| 386 EXPECT_EQ(default_location_, cancel.location()); | |
| 387 } | |
| 388 | |
| 389 // Test the event flow for touching the trackpad while "in motion" already, then | |
| 390 // pausing so that a flick is not generated. deltaX and deltaZ are always zero. | |
| 391 // Note, deviceDeltaX may take on an integer value even though deltaX is zero. | |
| 392 // Sequence: | |
| 393 // (1) NSEvent: type=ScrollWheel loc=(780,41) time=15263.2 flags=0x100 win=<set> | |
| 394 // deltaY=0.000000 deviceDeltaY=1.000000 phase=Began momentumPhase=None | |
| 395 // (n) NSEvent: type=ScrollWheel loc=(780,41) time=15263.2 flags=0x100 win=<set> | |
| 396 // deltaY=0.400024 deviceDeltaY=3.000000 phase=Changed momentumPhase=None | |
| 397 // (3) NSEvent: type=ScrollWheel loc=(780,41) time=15264.2 flags=0x100 win=<set> | |
| 398 // deltaY=0.000000 deviceDeltaY=0.000000 phase=Ended momentumPhase=None. | |
| 399 TEST_F(EventsMacTest, TrackpadScrollThenRest) { | |
| 400 int32_t delta_y = 21; | |
| 401 | |
| 402 std::vector<NSEvent*> ns_events; | |
| 403 TrackpadScrollSequence(false, delta_y, 0, &ns_events); | |
| 404 ASSERT_EQ(3u, ns_events.size()); | |
| 405 | |
| 406 ui::ScrollEvent begin(ns_events[0]); | |
| 407 EXPECT_EQ(ui::EM_PHASE_MAY_BEGIN, begin.momentum_phase()); | |
| 408 EXPECT_EQ(0, begin.y_offset_ordinal()); | |
| 409 | |
| 410 ui::ScrollEvent update(ns_events[1]); | |
| 411 // There's no momentum yet, so phase is none. | |
| 412 EXPECT_EQ(ui::EM_PHASE_NONE, update.momentum_phase()); | |
| 413 // Note: No pixel conversion for "precise" deltas. | |
| 414 EXPECT_EQ(delta_y, update.y_offset_ordinal()); | |
| 415 | |
| 416 ui::ScrollEvent end(ns_events[2]); | |
| 417 EXPECT_EQ(ui::EM_PHASE_END, end.momentum_phase()); | |
| 418 EXPECT_EQ(0, end.y_offset_ordinal()); | |
| 419 } | |
| 420 | |
| 421 // Same as the above, but with an initial rest, which is not cancelled. This | |
| 422 // results in multiple MAY_BEGIN phases. | |
| 423 TEST_F(EventsMacTest, TrackpadRestThenScrollThenRest) { | |
| 424 int32_t delta_y = 21; | |
| 425 | |
| 426 std::vector<NSEvent*> ns_events; | |
| 427 TrackpadScrollSequence(true, delta_y, 0, &ns_events); | |
| 428 ASSERT_EQ(4u, ns_events.size()); | |
| 429 | |
| 430 ui::ScrollEvent rest(ns_events[0]); | |
| 431 EXPECT_EQ(ui::EM_PHASE_MAY_BEGIN, rest.momentum_phase()); | |
| 432 EXPECT_EQ(0, rest.y_offset_ordinal()); | |
| 433 | |
| 434 ui::ScrollEvent begin(ns_events[1]); | |
| 435 EXPECT_EQ(ui::EM_PHASE_MAY_BEGIN, begin.momentum_phase()); | |
| 436 EXPECT_EQ(0, begin.y_offset_ordinal()); | |
| 437 | |
| 438 ui::ScrollEvent update(ns_events[2]); | |
| 439 EXPECT_EQ(ui::EM_PHASE_NONE, update.momentum_phase()); | |
| 440 EXPECT_EQ(delta_y, update.y_offset_ordinal()); | |
| 441 | |
| 442 ui::ScrollEvent end(ns_events[3]); | |
| 443 EXPECT_EQ(ui::EM_PHASE_END, end.momentum_phase()); | |
| 444 EXPECT_EQ(0, end.y_offset_ordinal()); | |
| 445 } | |
| 446 | |
| 447 // Test the event flows that lead to momentum, with and without an initial rest. | |
| 448 // Example sequence (no initial rest): | |
| 449 // (1) NSEvent: type=ScrollWheel loc=(780,41) time=15187.5 flags=0x100 win=<set> | |
| 450 // deltaY=0.000000 deviceDeltaY=1.000000 phase=Began momentumPhase=None | |
| 451 // (n) NSEvent: type=ScrollWheel loc=(780,41) time=15187.5 flags=0x100 win=<set> | |
| 452 // deltaY=0.500031 deviceDeltaY=4.000000 phase=Changed momentumPhase=None | |
| 453 // (3) NSEvent: type=ScrollWheel loc=(780,41) time=15187.6 flags=0x100 win=<set> | |
| 454 // deltaY=0.000000 deviceDeltaY=0.000000 phase=Ended momentumPhase=None | |
| 455 // (4) NSEvent: type=ScrollWheel loc=(780,41) time=15187.6 flags=0x100 win=<set> | |
| 456 // deltaY=0.900055 deviceDeltaY=3.000000 phase=None momentumPhase=Began | |
| 457 // (n) NSEvent: type=ScrollWheel loc=(780,41) time=15187.6 flags=0x100 win=<set> | |
| 458 // deltaY=0.300018 deviceDeltaY=3.000000 phase=None momentumPhase=Changed | |
| 459 // (6) NSEvent: type=ScrollWheel loc=(780,41) time=15188.0 flags=0x100 win=<set> | |
| 460 // deltaY=0.000000 deviceDeltaY=0.000000 phase=None momentumPhase=Ended. | |
| 461 TEST_F(EventsMacTest, TrackpadScrollThenFlick) { | |
| 462 int32_t delta_y = 21; | |
| 463 int32_t momentum_delta_y = 33; | |
| 464 | |
| 465 std::vector<NSEvent*> ns_events; | |
| 466 TrackpadScrollSequence(false, delta_y, momentum_delta_y, &ns_events); | |
| 467 ASSERT_EQ(6u, ns_events.size()); | |
| 468 | |
| 469 // Non-momentum part. | |
| 470 { | |
| 471 ui::ScrollEvent begin(ns_events[0]); | |
| 472 EXPECT_EQ(ui::EM_PHASE_MAY_BEGIN, begin.momentum_phase()); | |
| 473 EXPECT_EQ(0, begin.y_offset_ordinal()); | |
| 474 | |
| 475 ui::ScrollEvent update(ns_events[1]); | |
| 476 EXPECT_EQ(ui::EM_PHASE_NONE, update.momentum_phase()); | |
| 477 EXPECT_EQ(delta_y, update.y_offset_ordinal()); | |
| 478 | |
| 479 ui::ScrollEvent end(ns_events[2]); | |
| 480 // Even though the event stream continues, AppKit doesn't provide a way to | |
| 481 // know this without peeking at future events. So this "end" mid-stream is | |
| 482 // unavoidable. | |
| 483 EXPECT_EQ(ui::EM_PHASE_END, end.momentum_phase()); | |
| 484 EXPECT_EQ(0, end.y_offset_ordinal()); | |
| 485 } | |
| 486 // Momentum part. | |
| 487 { | |
| 488 ui::ScrollEvent begin(ns_events[3]); | |
| 489 // Since a momentum "begin" is really a continuation of the stream, it's | |
| 490 // currently treated as an update, but the offsets should always be zero. | |
| 491 EXPECT_EQ(ui::EM_PHASE_INERTIAL_UPDATE, begin.momentum_phase()); | |
| 492 EXPECT_EQ(0, begin.y_offset_ordinal()); | |
| 493 | |
| 494 ui::ScrollEvent update(ns_events[4]); | |
| 495 EXPECT_EQ(ui::EM_PHASE_INERTIAL_UPDATE, update.momentum_phase()); | |
| 496 EXPECT_EQ(momentum_delta_y, update.y_offset_ordinal()); | |
| 497 | |
| 498 ui::ScrollEvent end(ns_events[5]); | |
| 499 EXPECT_EQ(ui::EM_PHASE_END, end.momentum_phase()); | |
| 500 EXPECT_EQ(0, end.y_offset_ordinal()); | |
| 501 } | |
| 502 } | |
| 503 | |
| 264 } // namespace ui | 504 } // namespace ui |
| OLD | NEW |