Also store the mouse location and don't double-click if it moved.
[enjoyable.git] / Classes / NJOutputMouseButton.m
1 //
2 // NJOutputMouseButton.m
3 // Enjoy
4 //
5 // Created by Yifeng Huang on 7/27/12.
6 //
7
8 #import "NJOutputMouseButton.h"
9
10 @implementation NJOutputMouseButton {
11 NSDate *upTime;
12 int clickCount;
13 NSPoint clickPosition;
14 }
15
16 + (NSTimeInterval)doubleClickInterval {
17 static NSTimeInterval s_doubleClickThreshold;
18 if (!s_doubleClickThreshold) {
19 s_doubleClickThreshold = [[NSUserDefaults.standardUserDefaults
20 objectForKey:@"com.apple.mouse.doubleClickThreshold"] floatValue];
21 if (s_doubleClickThreshold <= 0)
22 s_doubleClickThreshold = 1.0;
23 }
24 return s_doubleClickThreshold;
25 }
26
27 + (NSDate *)dateWithClickInterval {
28 return [[NSDate alloc] initWithTimeIntervalSinceNow:self.doubleClickInterval];
29 }
30
31 + (NSString *)serializationCode {
32 return @"mouse button";
33 }
34
35 - (NSDictionary *)serialize {
36 return @{ @"type": self.class.serializationCode, @"button": @(_button) };
37 }
38
39 + (NJOutput *)outputDeserialize:(NSDictionary *)serialization
40 withMappings:(NSArray *)mappings {
41 NJOutputMouseButton *output = [[NJOutputMouseButton alloc] init];
42 output.button = [serialization[@"button"] intValue];
43 return output;
44 }
45
46 - (void)trigger {
47 CGFloat height = NSScreen.mainScreen.frame.size.height;
48 NSPoint mouseLoc = NSEvent.mouseLocation;
49 CGEventType eventType = (_button == kCGMouseButtonLeft) ? kCGEventLeftMouseDown : kCGEventRightMouseDown;
50 CGEventRef click = CGEventCreateMouseEvent(NULL,
51 eventType,
52 CGPointMake(mouseLoc.x, height - mouseLoc.y),
53 _button);
54
55 if (clickCount >= 3 || [upTime compare:[NSDate date]] == NSOrderedAscending
56 || !CGPointEqualToPoint(NSEvent.mouseLocation, clickPosition))
57 clickCount = 1;
58 else
59 ++clickCount;
60 CGEventSetIntegerValueField(click, kCGMouseEventClickState, clickCount);
61
62 CGEventPost(kCGHIDEventTap, click);
63 CFRelease(click);
64 }
65
66 - (void)untrigger {
67 upTime = [NJOutputMouseButton dateWithClickInterval];
68 clickPosition = NSEvent.mouseLocation;
69 CGFloat height = NSScreen.mainScreen.frame.size.height;
70 CGEventType eventType = (_button == kCGMouseButtonLeft) ? kCGEventLeftMouseUp : kCGEventRightMouseUp;
71 CGEventRef click = CGEventCreateMouseEvent(NULL,
72 eventType,
73 CGPointMake(clickPosition.x, height - clickPosition.y),
74 _button);
75 CGEventSetIntegerValueField(click, kCGMouseEventClickState, clickCount);
76 CGEventPost(kCGHIDEventTap, click);
77 CFRelease(click);
78 }
79
80 @end