| Index: ui/base/test/ui_controls_mac.mm
|
| diff --git a/ui/base/test/ui_controls_mac.mm b/ui/base/test/ui_controls_mac.mm
|
| index b7615b6c2fd78eab1ddbb87a351cf33f47c4efd1..46db392efc6024adaed2c1475dc1eff6fc82dbd7 100644
|
| --- a/ui/base/test/ui_controls_mac.mm
|
| +++ b/ui/base/test/ui_controls_mac.mm
|
| @@ -9,10 +9,14 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/callback.h"
|
| +#import "base/mac/foundation_util.h"
|
| +#import "base/mac/scoped_objc_class_swizzler.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "ui/base/cocoa/cocoa_base_utils.h"
|
| #include "ui/events/keycodes/keyboard_code_conversion_mac.h"
|
| #import "ui/events/test/cocoa_test_event_utils.h"
|
| +#include "ui/gfx/geometry/point.h"
|
| +#import "ui/gfx/mac/coordinate_conversion.h"
|
|
|
| // Implementation details: We use [NSApplication sendEvent:] instead
|
| // of [NSApplication postEvent:atStart:] so that the event gets sent
|
| @@ -52,6 +56,10 @@ namespace {
|
| // when firing keyboard and mouse click events.
|
| NSPoint g_mouse_location = { 0, 0 };
|
|
|
| +// Stores the current pressed mouse buttons. Indexed by
|
| +// ui_controls::MouseButton.
|
| +bool g_mouse_button_down[3] = {false, false, false};
|
| +
|
| bool g_ui_controls_enabled = false;
|
|
|
| // Creates the proper sequence of autoreleased key events for a key down + up.
|
| @@ -173,10 +181,63 @@ NSWindow* WindowAtCurrentMouseLocation() {
|
|
|
| } // namespace
|
|
|
| +// Donates testing implementations of NSEvent methods.
|
| +@interface FakeNSEventTestingDonor : NSObject
|
| +@end
|
| +
|
| +@implementation FakeNSEventTestingDonor
|
| ++ (NSPoint)mouseLocation {
|
| + return g_mouse_location;
|
| +}
|
| +
|
| ++ (NSUInteger)pressedMouseButtons {
|
| + NSUInteger result = 0;
|
| + const int buttons[3] = {
|
| + ui_controls::LEFT, ui_controls::RIGHT, ui_controls::MIDDLE};
|
| + for (size_t i = 0; i < arraysize(buttons); ++i) {
|
| + if (g_mouse_button_down[buttons[i]])
|
| + result |= (1 << i);
|
| + }
|
| + return result;
|
| +}
|
| +@end
|
| +
|
| +namespace {
|
| +
|
| +// Swizzles several Cocoa functions that are used to directly get mouse state,
|
| +// so that they will return the current simulated mouse position and pressed
|
| +// mouse buttons.
|
| +class MockNSEventClassMethods {
|
| + public:
|
| + static void Init() {
|
| + static MockNSEventClassMethods* swizzler = nullptr;
|
| + if (!swizzler) {
|
| + swizzler = new MockNSEventClassMethods();
|
| + }
|
| + }
|
| +
|
| + private:
|
| + MockNSEventClassMethods()
|
| + : mouse_location_swizzler_([NSEvent class],
|
| + [FakeNSEventTestingDonor class],
|
| + @selector(mouseLocation)),
|
| + pressed_mouse_buttons_swizzler_([NSEvent class],
|
| + [FakeNSEventTestingDonor class],
|
| + @selector(pressedMouseButtons)) {}
|
| +
|
| + base::mac::ScopedObjCClassSwizzler mouse_location_swizzler_;
|
| + base::mac::ScopedObjCClassSwizzler pressed_mouse_buttons_swizzler_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MockNSEventClassMethods);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| namespace ui_controls {
|
|
|
| void EnableUIControls() {
|
| g_ui_controls_enabled = true;
|
| + MockNSEventClassMethods::Init();
|
| }
|
|
|
| bool IsUIControlsEnabled() {
|
| @@ -239,9 +300,7 @@ bool SendMouseMove(long x, long y) {
|
| // platforms. E.g. (0,0) is upper-left.
|
| bool SendMouseMoveNotifyWhenDone(long x, long y, const base::Closure& task) {
|
| CHECK(g_ui_controls_enabled);
|
| - CGFloat screenHeight =
|
| - [[[NSScreen screens] firstObject] frame].size.height;
|
| - g_mouse_location = NSMakePoint(x, screenHeight - y); // flip!
|
| + g_mouse_location = gfx::ScreenPointToNSPoint(gfx::Point(x, y)); // flip!
|
|
|
| NSWindow* window = WindowAtCurrentMouseLocation();
|
|
|
| @@ -250,16 +309,25 @@ bool SendMouseMoveNotifyWhenDone(long x, long y, const base::Closure& task) {
|
| pointInWindow = ui::ConvertPointFromScreenToWindow(window, pointInWindow);
|
| NSTimeInterval timestamp = TimeIntervalSinceSystemStartup();
|
|
|
| + NSEventType event_type = NSMouseMoved;
|
| + if (g_mouse_button_down[LEFT]) {
|
| + event_type = NSLeftMouseDragged;
|
| + } else if (g_mouse_button_down[RIGHT]) {
|
| + event_type = NSRightMouseDragged;
|
| + } else if (g_mouse_button_down[MIDDLE]) {
|
| + event_type = NSOtherMouseDragged;
|
| + }
|
| +
|
| NSEvent* event =
|
| - [NSEvent mouseEventWithType:NSMouseMoved
|
| + [NSEvent mouseEventWithType:event_type
|
| location:pointInWindow
|
| modifierFlags:0
|
| timestamp:timestamp
|
| windowNumber:[window windowNumber]
|
| context:nil
|
| eventNumber:0
|
| - clickCount:0
|
| - pressure:0.0];
|
| + clickCount:event_type == NSMouseMoved ? 0 : 1
|
| + pressure:event_type == NSMouseMoved ? 0.0 : 1.0];
|
| [[NSApplication sharedApplication] postEvent:event atStart:NO];
|
|
|
| if (!task.is_null()) {
|
| @@ -284,35 +352,38 @@ bool SendMouseEventsNotifyWhenDone(MouseButton type, int state,
|
| return (SendMouseEventsNotifyWhenDone(type, DOWN, base::Closure()) &&
|
| SendMouseEventsNotifyWhenDone(type, UP, task));
|
| }
|
| - NSEventType etype = NSLeftMouseDown;
|
| + NSEventType event_type = NSLeftMouseDown;
|
| if (type == LEFT) {
|
| if (state == UP) {
|
| - etype = NSLeftMouseUp;
|
| + event_type = NSLeftMouseUp;
|
| } else {
|
| - etype = NSLeftMouseDown;
|
| + event_type = NSLeftMouseDown;
|
| }
|
| } else if (type == MIDDLE) {
|
| if (state == UP) {
|
| - etype = NSOtherMouseUp;
|
| + event_type = NSOtherMouseUp;
|
| } else {
|
| - etype = NSOtherMouseDown;
|
| + event_type = NSOtherMouseDown;
|
| }
|
| } else if (type == RIGHT) {
|
| if (state == UP) {
|
| - etype = NSRightMouseUp;
|
| + event_type = NSRightMouseUp;
|
| } else {
|
| - etype = NSRightMouseDown;
|
| + event_type = NSRightMouseDown;
|
| }
|
| } else {
|
| + NOTREACHED();
|
| return false;
|
| }
|
| + g_mouse_button_down[type] = state == DOWN;
|
| +
|
| NSWindow* window = WindowAtCurrentMouseLocation();
|
| NSPoint pointInWindow = g_mouse_location;
|
| if (window)
|
| pointInWindow = ui::ConvertPointFromScreenToWindow(window, pointInWindow);
|
|
|
| NSEvent* event =
|
| - [NSEvent mouseEventWithType:etype
|
| + [NSEvent mouseEventWithType:event_type
|
| location:pointInWindow
|
| modifierFlags:0
|
| timestamp:TimeIntervalSinceSystemStartup()
|
| @@ -320,7 +391,7 @@ bool SendMouseEventsNotifyWhenDone(MouseButton type, int state,
|
| context:nil
|
| eventNumber:0
|
| clickCount:1
|
| - pressure:(state == DOWN ? 1.0 : 0.0 )];
|
| + pressure:state == DOWN ? 1.0 : 0.0];
|
| [[NSApplication sharedApplication] postEvent:event atStart:NO];
|
|
|
| if (!task.is_null()) {
|
|
|