-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.m
executable file
·129 lines (85 loc) · 3.52 KB
/
main.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#import <ApplicationServices/ApplicationServices.h>
#import <Foundation/NSObjCRuntime.h>
#import <Cocoa/Cocoa.h>
#import <libproc.h>
#define RequiredEvent 29
#define RequiredProcName "Google Chrome"
bool needIgnoreNextLeftMouseUp = false;
CGEventRef myCGEventCallback(CGEventTapProxy proxy,
CGEventType type,
CGEventRef eventRef,
void *refcon)
{
@autoreleasepool {
if(needIgnoreNextLeftMouseUp &&
(type == kCGEventLeftMouseUp || type == kCGEventLeftMouseDown)){
return (NULL);
}
if ((type != RequiredEvent)){
return eventRef;
}
NSEvent *event = [NSEvent eventWithCGEvent:eventRef];
if(needIgnoreNextLeftMouseUp && event.stage != 0){
return (NULL);
}
if(needIgnoreNextLeftMouseUp){
needIgnoreNextLeftMouseUp = false;
return (NULL);
}
char ProcName[PROC_PIDPATHINFO_MAXSIZE];
if (!proc_name((pid_t)CGEventGetIntegerValueField(eventRef, kCGEventTargetUnixProcessID), ProcName, sizeof(ProcName))){
return eventRef;
}
NSString *Target = [NSString stringWithUTF8String: ProcName];
if (![Target isEqualToString: @RequiredProcName]){
return eventRef;
}
if (event.type == NSEventTypePressure && event.stage == 2){
if(event.pressure > 0.000){
return (NULL);
}
//NSLog(@"Deep click");
CGEventSourceRef src = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGPoint mouse_pos = CGEventGetLocation(eventRef);
CGEventRef click_down = CGEventCreateMouseEvent(
src, kCGEventLeftMouseDown,
mouse_pos,
kCGMouseButtonLeft
);
CGEventRef click_up = CGEventCreateMouseEvent(
src, kCGEventLeftMouseUp,
mouse_pos,
kCGMouseButtonLeft
);
CGEventSetFlags(click_down, kCGEventFlagMaskCommand);
CGEventSetFlags(click_up, kCGEventFlagMaskCommand);
CGEventPost(kCGHIDEventTap, click_down);
needIgnoreNextLeftMouseUp = true;
CFRelease(src);
CFRelease(click_down);
return click_up;
}
return eventRef;
}
}
int main(void)
{
CFMachPortRef eventTap;
CGEventMask eventMask;
CFRunLoopSourceRef runLoopSource;
eventMask = ((1 << RequiredEvent) | (1 << kCGEventLeftMouseUp) | (1 << kCGEventLeftMouseDown));
eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
eventMask, myCGEventCallback, NULL);
if (!eventTap) {
fprintf(stderr, "failed to create event tap\n");
exit(1);
}
runLoopSource = CFMachPortCreateRunLoopSource(
kCFAllocatorDefault, eventTap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);
NSLog(@"Start handling deep clicks in " RequiredProcName);
CFRunLoopRun();
exit(0);
}