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 3 // found in the LICENSE file. 4 5 #import <Cocoa/Cocoa.h> 6 7 #include "ui/events/test/cocoa_test_event_utils.h" 8 9 ScopedClassSwizzler::ScopedClassSwizzler(Class target, Class source, 10 SEL selector) { 11 old_selector_impl_ = class_getInstanceMethod(target, selector); 12 new_selector_impl_ = class_getInstanceMethod(source, selector); 13 method_exchangeImplementations(old_selector_impl_, new_selector_impl_); 14 } 15 16 ScopedClassSwizzler::~ScopedClassSwizzler() { 17 method_exchangeImplementations(old_selector_impl_, new_selector_impl_); 18 } 19 20 namespace cocoa_test_event_utils { 21 22 NSEvent* MouseEventAtPoint(NSPoint point, NSEventType type, 23 NSUInteger modifiers) { 24 if (type == NSOtherMouseUp) { 25 // To synthesize middle clicks we need to create a CGEvent with the 26 // "center" button flags so that our resulting NSEvent will have the 27 // appropriate buttonNumber field. NSEvent provides no way to create a 28 // mouse event with a buttonNumber directly. 29 CGPoint location = { point.x, point.y }; 30 CGEventRef cg_event = CGEventCreateMouseEvent(NULL, kCGEventOtherMouseUp, 31 location, 32 kCGMouseButtonCenter); 33 // Also specify the modifiers for the middle click case. This makes this 34 // test resilient to external modifiers being pressed. 35 CGEventSetFlags(cg_event, modifiers); 36 NSEvent* event = [NSEvent eventWithCGEvent:cg_event]; 37 CFRelease(cg_event); 38 return event; 39 } 40 return [NSEvent mouseEventWithType:type 41 location:point 42 modifierFlags:modifiers 43 timestamp:0 44 windowNumber:0 45 context:nil 46 eventNumber:0 47 clickCount:1 48 pressure:1.0]; 49 } 50 51 NSEvent* MouseEventWithType(NSEventType type, NSUInteger modifiers) { 52 return MouseEventAtPoint(NSZeroPoint, type, modifiers); 53 } 54 55 static NSEvent* MouseEventAtPointInWindow(NSPoint point, 56 NSEventType type, 57 NSWindow* window, 58 NSUInteger clickCount) { 59 return [NSEvent mouseEventWithType:type 60 location:point 61 modifierFlags:0 62 timestamp:0 63 windowNumber:[window windowNumber] 64 context:nil 65 eventNumber:0 66 clickCount:clickCount 67 pressure:1.0]; 68 } 69 70 NSEvent* RightMouseDownAtPointInWindow(NSPoint point, NSWindow* window) { 71 return MouseEventAtPointInWindow(point, NSRightMouseDown, window, 1); 72 } 73 74 NSEvent* RightMouseDownAtPoint(NSPoint point) { 75 return RightMouseDownAtPointInWindow(point, nil); 76 } 77 78 NSEvent* LeftMouseDownAtPointInWindow(NSPoint point, NSWindow* window) { 79 return MouseEventAtPointInWindow(point, NSLeftMouseDown, window, 1); 80 } 81 82 NSEvent* LeftMouseDownAtPoint(NSPoint point) { 83 return LeftMouseDownAtPointInWindow(point, nil); 84 } 85 86 std::pair<NSEvent*,NSEvent*> MouseClickInView(NSView* view, 87 NSUInteger clickCount) { 88 const NSRect bounds = [view convertRect:[view bounds] toView:nil]; 89 const NSPoint mid_point = NSMakePoint(NSMidX(bounds), NSMidY(bounds)); 90 NSEvent* down = MouseEventAtPointInWindow(mid_point, NSLeftMouseDown, 91 [view window], clickCount); 92 NSEvent* up = MouseEventAtPointInWindow(mid_point, NSLeftMouseUp, 93 [view window], clickCount); 94 return std::make_pair(down, up); 95 } 96 97 NSEvent* KeyEventWithCharacter(unichar c) { 98 return KeyEventWithKeyCode(0, c, NSKeyDown, 0); 99 } 100 101 NSEvent* KeyEventWithType(NSEventType event_type, NSUInteger modifiers) { 102 return KeyEventWithKeyCode(0x78, 'x', event_type, modifiers); 103 } 104 105 NSEvent* KeyEventWithKeyCode(unsigned short key_code, 106 unichar c, 107 NSEventType event_type, 108 NSUInteger modifiers) { 109 NSString* chars = [NSString stringWithCharacters:&c length:1]; 110 return [NSEvent keyEventWithType:event_type 111 location:NSZeroPoint 112 modifierFlags:modifiers 113 timestamp:0 114 windowNumber:0 115 context:nil 116 characters:chars 117 charactersIgnoringModifiers:chars 118 isARepeat:NO 119 keyCode:key_code]; 120 } 121 122 NSEvent* EnterExitEventWithType(NSEventType event_type) { 123 return [NSEvent enterExitEventWithType:event_type 124 location:NSZeroPoint 125 modifierFlags:0 126 timestamp:0 127 windowNumber:0 128 context:nil 129 eventNumber:0 130 trackingNumber:0 131 userData:NULL]; 132 } 133 134 NSEvent* OtherEventWithType(NSEventType event_type) { 135 return [NSEvent otherEventWithType:event_type 136 location:NSZeroPoint 137 modifierFlags:0 138 timestamp:0 139 windowNumber:0 140 context:nil 141 subtype:0 142 data1:0 143 data2:0]; 144 } 145 146 } // namespace cocoa_test_event_utils 147