| Index: ui/events/cocoa/events_mac_unittest.mm
|
| diff --git a/ui/events/cocoa/cocoa_event_utils_unittest.mm b/ui/events/cocoa/events_mac_unittest.mm
|
| similarity index 32%
|
| rename from ui/events/cocoa/cocoa_event_utils_unittest.mm
|
| rename to ui/events/cocoa/events_mac_unittest.mm
|
| index 4e24fd2c775ba9b9b2fbaf608b4e68fca90f3ab0..9b930845705bd3de3417bc30c4d339b54a2d5c62 100644
|
| --- a/ui/events/cocoa/cocoa_event_utils_unittest.mm
|
| +++ b/ui/events/cocoa/events_mac_unittest.mm
|
| @@ -2,25 +2,127 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "ui/events/cocoa/cocoa_event_utils.h"
|
| +#include "ui/events/event_utils.h"
|
|
|
| -#import <objc/objc-class.h>
|
| +#import <Cocoa/Cocoa.h>
|
|
|
| +#include "base/mac/scoped_cftyperef.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| -#include "testing/platform_test.h"
|
| #include "ui/events/event_constants.h"
|
| -#include "ui/events/event_utils.h"
|
| #import "ui/events/test/cocoa_test_event_utils.h"
|
| +#include "ui/gfx/point.h"
|
| #import "ui/gfx/test/ui_cocoa_test_helper.h"
|
|
|
| +namespace {
|
| +
|
| +NSWindow* g_test_window = nil;
|
| +
|
| +} // namespace
|
| +
|
| +// Mac APIs for creating test events are frustrating. Quartz APIs have, e.g.,
|
| +// CGEventCreateMouseEvent() which can't set a window or modifier flags.
|
| +// Cocoa APIs have +[NSEvent mouseEventWithType:..] which can't set
|
| +// buttonNumber or scroll deltas. To work around this, these tests use some
|
| +// Objective C magic to donate member functions to NSEvent temporarily.
|
| +@interface MiddleMouseButtonNumberDonor : NSObject
|
| +@end
|
| +
|
| +@interface TestWindowDonor : NSObject
|
| +@end
|
| +
|
| +@implementation MiddleMouseButtonNumberDonor
|
| +- (NSUInteger)buttonNumber { return 2; }
|
| +@end
|
| +
|
| +@implementation TestWindowDonor
|
| +- (NSWindow*)window { return g_test_window; }
|
| +@end
|
| +
|
| namespace ui {
|
|
|
| namespace {
|
|
|
| -class CocoaEventUtilsTest : public CocoaTest {
|
| +class EventsMacTest : public CocoaTest {
|
| + public:
|
| + EventsMacTest() {}
|
| +
|
| + gfx::Point Flip(gfx::Point window_location) {
|
| + window_location.set_y(
|
| + NSHeight([test_window() frame]) - window_location.y());
|
| + return window_location;
|
| + }
|
| +
|
| + void SwizzleMiddleMouseButton() {
|
| + DCHECK(!swizzler_);
|
| + swizzler_.reset(new ScopedClassSwizzler(
|
| + [NSEvent class],
|
| + [MiddleMouseButtonNumberDonor class],
|
| + @selector(buttonNumber)));
|
| + }
|
| +
|
| + void SwizzleTestWindow() {
|
| + DCHECK(!g_test_window);
|
| + DCHECK(!swizzler_);
|
| + g_test_window = test_window();
|
| + swizzler_.reset(new ScopedClassSwizzler(
|
| + [NSEvent class],
|
| + [TestWindowDonor class],
|
| + @selector(window)));
|
| + }
|
| +
|
| + void ClearSwizzle() {
|
| + swizzler_.reset();
|
| + g_test_window = nil;
|
| + }
|
| +
|
| + NSEvent* TestMouseEvent(NSEventType type,
|
| + const gfx::Point &window_location,
|
| + NSInteger modifier_flags) {
|
| + NSPoint point = NSPointFromCGPoint(Flip(window_location).ToCGPoint());
|
| + return [NSEvent mouseEventWithType:type
|
| + location:point
|
| + modifierFlags:modifier_flags
|
| + timestamp:0
|
| + windowNumber:[test_window() windowNumber]
|
| + context:nil
|
| + eventNumber:0
|
| + clickCount:0
|
| + pressure:1.0];
|
| + }
|
| +
|
| + NSEvent* TestScrollEvent(const gfx::Point& window_location,
|
| + int32_t delta_x,
|
| + int32_t delta_y) {
|
| + SwizzleTestWindow();
|
| + base::ScopedCFTypeRef<CGEventRef> scroll(
|
| + CGEventCreateScrollWheelEvent(NULL,
|
| + kCGScrollEventUnitLine,
|
| + 2,
|
| + delta_y,
|
| + delta_x));
|
| + // CGEvents are always in global display coordinates. These are like screen
|
| + // coordinates, but flipped. But first the point needs to be converted out
|
| + // of window coordinates (which also requires flipping).
|
| + NSPoint window_point =
|
| + NSPointFromCGPoint(Flip(window_location).ToCGPoint());
|
| + NSPoint screen_point = [test_window() convertBaseToScreen:window_point];
|
| + CGFloat primary_screen_height =
|
| + NSHeight([[[NSScreen screens] objectAtIndex:0] frame]);
|
| + screen_point.y = primary_screen_height - screen_point.y;
|
| + CGEventSetLocation(scroll, NSPointToCGPoint(screen_point));
|
| + return [NSEvent eventWithCGEvent:scroll];
|
| + }
|
| +
|
| + private:
|
| + scoped_ptr<ScopedClassSwizzler> swizzler_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(EventsMacTest);
|
| };
|
|
|
| -TEST_F(CocoaEventUtilsTest, EventFlagsFromNative) {
|
| +} // namespace
|
| +
|
| +TEST_F(EventsMacTest, EventFlagsFromNative) {
|
| // Left click.
|
| NSEvent* left = cocoa_test_event_utils::MouseEventWithType(NSLeftMouseUp, 0);
|
| EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, EventFlagsFromNative(left));
|
| @@ -74,6 +176,68 @@ TEST_F(CocoaEventUtilsTest, EventFlagsFromNative) {
|
| EventFlagsFromNative(cmdalt));
|
| }
|
|
|
| -} // namespace
|
| +// Tests mouse button presses and mouse wheel events.
|
| +TEST_F(EventsMacTest, ButtonEvents) {
|
| + gfx::Point location(5, 10);
|
| + gfx::Vector2d offset;
|
| +
|
| + NSEvent* event = TestMouseEvent(NSLeftMouseDown, location, 0);
|
| + EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromNative(event));
|
| + EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, ui::EventFlagsFromNative(event));
|
| + EXPECT_EQ(location, ui::EventLocationFromNative(event));
|
| +
|
| + SwizzleMiddleMouseButton();
|
| + event = TestMouseEvent(NSOtherMouseDown, location, NSShiftKeyMask);
|
| + EXPECT_EQ(ui::ET_MOUSE_PRESSED, ui::EventTypeFromNative(event));
|
| + EXPECT_EQ(ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_SHIFT_DOWN,
|
| + ui::EventFlagsFromNative(event));
|
| + EXPECT_EQ(location, ui::EventLocationFromNative(event));
|
| + ClearSwizzle();
|
| +
|
| + event = TestMouseEvent(NSRightMouseUp, location, 0);
|
| + EXPECT_EQ(ui::ET_MOUSE_RELEASED, ui::EventTypeFromNative(event));
|
| + EXPECT_EQ(ui::EF_RIGHT_MOUSE_BUTTON, ui::EventFlagsFromNative(event));
|
| + EXPECT_EQ(location, ui::EventLocationFromNative(event));
|
| +
|
| + // Scroll up.
|
| + event = TestScrollEvent(location, 0, 1);
|
| + EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event));
|
| + EXPECT_EQ(0, ui::EventFlagsFromNative(event));
|
| + EXPECT_EQ(location.ToString(), ui::EventLocationFromNative(event).ToString());
|
| + offset = ui::GetMouseWheelOffset(event);
|
| + EXPECT_GT(offset.y(), 0);
|
| + EXPECT_EQ(0, offset.x());
|
| + ClearSwizzle();
|
| +
|
| + // Scroll down.
|
| + event = TestScrollEvent(location, 0, -1);
|
| + EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event));
|
| + EXPECT_EQ(0, ui::EventFlagsFromNative(event));
|
| + EXPECT_EQ(location, ui::EventLocationFromNative(event));
|
| + offset = ui::GetMouseWheelOffset(event);
|
| + EXPECT_LT(offset.y(), 0);
|
| + EXPECT_EQ(0, offset.x());
|
| + ClearSwizzle();
|
| +
|
| + // Scroll left.
|
| + event = TestScrollEvent(location, 1, 0);
|
| + EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event));
|
| + EXPECT_EQ(0, ui::EventFlagsFromNative(event));
|
| + EXPECT_EQ(location, ui::EventLocationFromNative(event));
|
| + offset = ui::GetMouseWheelOffset(event);
|
| + EXPECT_EQ(0, offset.y());
|
| + EXPECT_GT(offset.x(), 0);
|
| + ClearSwizzle();
|
| +
|
| + // Scroll right.
|
| + event = TestScrollEvent(location, -1, 0);
|
| + EXPECT_EQ(ui::ET_MOUSEWHEEL, ui::EventTypeFromNative(event));
|
| + EXPECT_EQ(0, ui::EventFlagsFromNative(event));
|
| + EXPECT_EQ(location, ui::EventLocationFromNative(event));
|
| + offset = ui::GetMouseWheelOffset(event);
|
| + EXPECT_EQ(0, offset.y());
|
| + EXPECT_LT(offset.x(), 0);
|
| + ClearSwizzle();
|
| +}
|
|
|
| } // namespace ui
|
|
|