Skip to content

Commit

Permalink
Merge branch 'main' into improved_tap_detection
Browse files Browse the repository at this point in the history
  • Loading branch information
artginzburg authored Jun 5, 2023
2 parents d53bb3b + 3bfffaf commit ce6c6e1
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 46 deletions.
85 changes: 42 additions & 43 deletions MiddleClick/Controller.m
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ - (void)start
NSString* needToClickNullable = [[NSUserDefaults standardUserDefaults] valueForKey:@"needClick"];
needToClick = needToClickNullable ? [[NSUserDefaults standardUserDefaults] boolForKey:@"needClick"] : [self getIsSystemTapToClickDisabled];

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSAutoreleasePool* pool = [NSAutoreleasePool new];
[NSApplication sharedApplication];

registerTouchCallback();
Expand Down Expand Up @@ -114,7 +114,7 @@ - (void)start
[self registerMouseCallback:pool];
}

static void stopUnstableListeners()
static void stopUnstableListeners(void)
{
NSLog(@"Stopping unstable listeners...");

Expand All @@ -126,15 +126,15 @@ - (void)startUnstableListeners
{
NSLog(@"Starting unstable listeners...");

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSAutoreleasePool* pool = [NSAutoreleasePool new];

registerTouchCallback();
[self registerMouseCallback:pool];
}

static void registerTouchCallback()
static void registerTouchCallback(void)
{
// Get list of all multi touch devices
/// Get list of all multi touch devices
NSMutableArray* deviceList = (NSMutableArray*)MTDeviceCreateList(); // grab our device list
currentDeviceList = deviceList;

Expand All @@ -144,9 +144,9 @@ static void registerTouchCallback()
registerMTDeviceCallback((MTDeviceRef)[deviceList objectAtIndex:i], touchCallback);
}
}
static void unregisterTouchCallback()
static void unregisterTouchCallback(void)
{
// Get list of all multi touch devices
/// Get list of all multi touch devices
NSMutableArray* deviceList = currentDeviceList; // grab our device list

// Iterate and unregister callbacks for multitouch devices.
Expand All @@ -158,12 +158,12 @@ static void unregisterTouchCallback()

- (void)registerMouseCallback:(NSAutoreleasePool*)pool
{
// we only want to see left mouse down and left mouse up, because we only want
// to change that one
/// we only want to see left mouse down and left mouse up, because we only want
/// to change that one
CGEventMask eventMask = (CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseUp));

// create eventTap which listens for core grpahic events with the filter
// sepcified above (so left mouse down and up again)
/// create eventTap which listens for core grpahic events with the filter
/// specified above (so left mouse down and up again)
CFMachPortRef eventTap = CGEventTapCreate(
kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault,
eventMask, mouseCallback, NULL);
Expand All @@ -187,7 +187,7 @@ - (void)registerMouseCallback:(NSAutoreleasePool*)pool
[self scheduleRestart:5];
}
}
static void unregisterMouseCallback()
static void unregisterMouseCallback(void)
{
// Remove from the current run loop.
if (currentRunLoopSource) {
Expand All @@ -213,8 +213,8 @@ - (void)scheduleRestart:(NSTimeInterval)delay
}];
}

// Callback for system wake up. This restarts the app to initialize callbacks.
// Can be tested by entering `pmset sleepnow` in the Terminal
/// Callback for system wake up. This restarts the app to initialize callbacks.
/// Can be tested by entering `pmset sleepnow` in the Terminal
- (void)receiveWakeNote:(NSNotification*)note
{
NSLog(@"System woke up, restarting...");
Expand All @@ -237,12 +237,12 @@ - (void)resetClickMode
needToClick = [self getIsSystemTapToClickDisabled];
}

// listening to mouse clicks to replace them with middle clicks if there are 3
// fingers down at the time of clicking this is done by replacing the left click
// down with a other click down and setting the button number to middle click
// when 3 fingers are down when clicking, and by replacing left click up with
// other click up and setting three button number to middle click when 3 fingers
// were down when the last click went down.
/// listening to mouse clicks to replace them with middle clicks if there are 3
/// fingers down at the time of clicking this is done by replacing the left click
/// down with a other click down and setting the button number to middle click
/// when 3 fingers are down when clicking, and by replacing left click up with
/// other click up and setting three button number to middle click when 3 fingers
/// were down when the last click went down.
CGEventRef mouseCallback(CGEventTapProxy proxy, CGEventType type,
CGEventRef event, void* refcon)
{
Expand All @@ -265,28 +265,18 @@ CGEventRef mouseCallback(CGEventTapProxy proxy, CGEventType type,
return event;
}

// mulittouch callback, see what is touched. If 3 are on the mouse set
// threedowns, else unset threedowns.
/// Mulittouch callback, see what is touched. If 3 are on the mouse set
/// threedowns, else unset threedowns.
int touchCallback(int device, Finger* data, int nFingers, double timestamp,
int frame)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSAutoreleasePool* pool = [NSAutoreleasePool new];
fingersQua = [[NSUserDefaults standardUserDefaults] integerForKey:kFingersNum];
float maxDistanceDelta = [[NSUserDefaults standardUserDefaults] floatForKey:kMaxDistanceDelta];
float maxTimeDelta = [[NSUserDefaults standardUserDefaults] integerForKey:kMaxTimeDeltaMs] / 1000.f;

if (needToClick) {
if (nFingers == fingersQua) {
if (!threeDown) {
threeDown = YES;
}
}

if (nFingers != fingersQua) {
if (threeDown) {
threeDown = NO;
}
}
threeDown = nFingers == fingersQua;
} else {
if (nFingers == 0) {
NSTimeInterval elapsedTime = touchStartTime ? -[touchStartTime timeIntervalSinceNow] : 0;
Expand All @@ -299,17 +289,16 @@ int touchCallback(int device, Finger* data, int nFingers, double timestamp,
// get the current pointer location
CGEventRef ourEvent = CGEventCreate(NULL);
CGPoint ourLoc = CGEventGetLocation(ourEvent);
CFRelease(ourEvent);

CGEventPost(kCGHIDEventTap,
CGEventCreateMouseEvent(NULL, kCGEventOtherMouseDown,
ourLoc, kCGMouseButtonCenter));
CGEventPost(kCGHIDEventTap,
CGEventCreateMouseEvent(NULL, kCGEventOtherMouseUp,
ourLoc, kCGMouseButtonCenter));
CGMouseButton buttonType = kCGMouseButtonCenter;

postMouseEvent(kCGEventOtherMouseDown, buttonType, ourLoc);
postMouseEvent(kCGEventOtherMouseUp, buttonType, ourLoc);
}
}
} else if (nFingers > 0 && touchStartTime == NULL) {
NSDate* now = [[NSDate alloc] init];
NSDate* now = [NSDate new];
touchStartTime = [now retain];
[now release];

Expand Down Expand Up @@ -400,6 +389,12 @@ static void unregisterMTDeviceCallback(MTDeviceRef device, MTContactCallbackFunc
MTDeviceRelease(device);
}

static void postMouseEvent(CGEventType eventType, CGMouseButton buttonType, CGPoint ourLoc) {
CGEventRef mouseEvent = CGEventCreateMouseEvent(NULL, eventType, ourLoc, buttonType);
CGEventPost(kCGHIDEventTap, mouseEvent);
CFRelease(mouseEvent);
}

- (BOOL)getIsSystemTapToClickDisabled {
NSString* isSystemTapToClickEnabled = [self runCommand:(@"defaults read com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking")];
return [isSystemTapToClickEnabled isEqualToString:@"0\n"];
Expand All @@ -408,15 +403,19 @@ - (BOOL)getIsSystemTapToClickDisabled {
- (NSString *)runCommand:(NSString *)commandToRun {
NSPipe* pipe = [NSPipe pipe];

NSTask* task = [[NSTask alloc] init];
NSTask* task = [NSTask new];
[task setLaunchPath: @"/bin/sh"];
[task setArguments:@[@"-c", [NSString stringWithFormat:@"%@", commandToRun]]];
[task setStandardOutput:pipe];

NSFileHandle* file = [pipe fileHandleForReading];
[task launch];

return [[NSString alloc] initWithData:[file readDataToEndOfFile] encoding:NSUTF8StringEncoding];
NSString *output = [[NSString alloc] initWithData:[file readDataToEndOfFile] encoding:NSUTF8StringEncoding];

[task release];

return [output autorelease];
}

@end
8 changes: 6 additions & 2 deletions MiddleClick/TrayMenu.m
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ - (NSMenu*)createMenu
[self createMenuAccessibilityPermissionItems:menu];

// Add About
menuItem = [menu addItemWithTitle:@"About MiddleClick..."
menuItem = [menu addItemWithTitle:[NSString stringWithFormat:@"About %@...", getAppName()]
action:@selector(openWebsite:)
keyEquivalent:@""];
[menuItem setTarget:self];
Expand Down Expand Up @@ -162,7 +162,7 @@ - (void)applicationDidFinishLaunching:(NSNotification*)notification
statusItemWithLength:24] retain];
_statusItem.behavior = NSStatusItemBehaviorRemovalAllowed;
_statusItem.menu = menu;
_statusItem.button.toolTip = @"MiddleClick";
_statusItem.button.toolTip = getAppName();
_statusItem.button.image = icon;

[self initAccessibilityPermissionStatus:menu];
Expand All @@ -177,4 +177,8 @@ - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender
return 1;
}

NSString* getAppName(void) {
return [[NSProcessInfo processInfo] processName];
}

@end
6 changes: 5 additions & 1 deletion MiddleClick/main.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ int main(int argc, char* argv[])

NSApplication* app = [NSApplication sharedApplication];

Controller* con = [[Controller alloc] init];
Controller* con = [Controller new];
[con start];

// add Menu Bar item
Expand All @@ -33,5 +33,9 @@ int main(int argc, char* argv[])

[app run];

// Suppress memory leak warnings in "Product" > "Analyze". It sounds pointless releasing objects right before the app closes and releases absolutely everything — but I'm OK with it as long as no warnings occur.
[con release];
[menu release];

return EXIT_SUCCESS;
}
7 changes: 7 additions & 0 deletions codemods/allocInitToNew.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

# Replaces all occurrences of `[[Class alloc] init]` with `[Class new]` in a file, `Class` being an arbitrary class name.

# Change `-i ''` to `-i.bak` after `sed` to make backup files.

sed -i '' -E 's/\[\[([A-Za-z_]+) +alloc\] +init\]/[\1 new]/g' ./MiddleClick/*.m

0 comments on commit ce6c6e1

Please sign in to comment.