Skip to content

Commit

Permalink
Merge pull request artginzburg#62 from gm-vm/improved_tap_detection
Browse files Browse the repository at this point in the history
Improve the detection of taps
  • Loading branch information
artginzburg authored Jun 5, 2023
2 parents 3bfffaf + ce6c6e1 commit 879bdf0
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 7 deletions.
2 changes: 2 additions & 0 deletions MiddleClick.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
75A6B69C0FEE90530071FAC0 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<absolute>"; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = MiddleClick/Info.plist; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* MiddleClick.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MiddleClick.app; sourceTree = BUILT_PRODUCTS_DIR; };
9753175829D5983E0065CAA7 /* PreferenceKeys.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PreferenceKeys.h; path = MiddleClick/PreferenceKeys.h; sourceTree = "<group>"; };
FAD94F9210A88A7800A520EC /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Controller.h; path = MiddleClick/Controller.h; sourceTree = "<group>"; };
FAD94F9310A88A7800A520EC /* Controller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Controller.m; path = MiddleClick/Controller.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -105,6 +106,7 @@
FAD94F9210A88A7800A520EC /* Controller.h */,
FAD94F9310A88A7800A520EC /* Controller.m */,
29B97316FDCFA39411CA2CEA /* main.m */,
9753175829D5983E0065CAA7 /* PreferenceKeys.h */,
);
name = "Other Sources";
sourceTree = "<group>";
Expand Down
14 changes: 9 additions & 5 deletions MiddleClick/Controller.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import "Controller.h"
#import "PreferenceKeys.h"
#include "TrayMenu.h"
#import <Cocoa/Cocoa.h>
#include <CoreFoundation/CoreFoundation.h>
Expand Down Expand Up @@ -66,7 +67,7 @@ - (void)start
threeDown = NO;
wasThreeDown = NO;

fingersQua = [[NSUserDefaults standardUserDefaults] integerForKey:@"fingers"];
fingersQua = [[NSUserDefaults standardUserDefaults] integerForKey:kFingersNum];

NSString* needToClickNullable = [[NSUserDefaults standardUserDefaults] valueForKey:@"needClick"];
needToClick = needToClickNullable ? [[NSUserDefaults standardUserDefaults] boolForKey:@"needClick"] : [self getIsSystemTapToClickDisabled];
Expand Down Expand Up @@ -270,16 +271,19 @@ int touchCallback(int device, Finger* data, int nFingers, double timestamp,
int frame)
{
NSAutoreleasePool* pool = [NSAutoreleasePool new];
fingersQua = [[NSUserDefaults standardUserDefaults] integerForKey:@"fingers"];
fingersQua = [[NSUserDefaults standardUserDefaults] integerForKey:kFingersNum];
float maxDistanceDelta = [[NSUserDefaults standardUserDefaults] floatForKey:kMaxDistanceDelta];
float maxTimeDelta = [[NSUserDefaults standardUserDefaults] integerForKey:kMaxTimeDeltaMs] / 1000.f;

if (needToClick) {
threeDown = nFingers == fingersQua;
} else {
if (nFingers == 0) {
NSTimeInterval elapsedTime = touchStartTime ? -[touchStartTime timeIntervalSinceNow] : 0;
touchStartTime = NULL;
if (middleclickX + middleclickY) {
if (middleclickX + middleclickY && elapsedTime <= maxTimeDelta) {
float delta = ABS(middleclickX - middleclickX2) + ABS(middleclickY - middleclickY2);
if (delta < 0.4f) {
if (delta < maxDistanceDelta) {
// Emulate a middle click

// get the current pointer location
Expand All @@ -304,7 +308,7 @@ int touchCallback(int device, Finger* data, int nFingers, double timestamp,
} else {
if (maybeMiddleClick == YES) {
NSTimeInterval elapsedTime = -[touchStartTime timeIntervalSinceNow];
if (elapsedTime > 0.5f)
if (elapsedTime > maxTimeDelta)
maybeMiddleClick = NO;
}
}
Expand Down
12 changes: 12 additions & 0 deletions MiddleClick/PreferenceKeys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// The number of fingers needed to simulate a middle click.
#define kFingersNum @"fingers"
#define kFingersNumDefault 3

// The maximum distance the cursor can travel between touch and release for a tap to be considered valid.
// The position is normalized and values go from 0 to 1.
#define kMaxDistanceDelta @"maxDistanceDelta"
#define kMaxDistanceDeltaDefault 0.4f

// The maximum interval in milliseconds between touch and release for a tap to be considered valid.
#define kMaxTimeDeltaMs @"maxTimeDelta"
#define kMaxTimeDeltaMsDefault 500
3 changes: 2 additions & 1 deletion MiddleClick/TrayMenu.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import "TrayMenu.h"
#import "PreferenceKeys.h"
#import "Controller.h"
#import <Cocoa/Cocoa.h>

Expand Down Expand Up @@ -74,7 +75,7 @@ - (void)setChecks
bool clickMode = [myController getClickMode];
NSString* clickModeInfo = clickMode ? @"Click" : @"Click or Tap";

int fingersQua = (int)[[NSUserDefaults standardUserDefaults] integerForKey:@"fingers"];
int fingersQua = (int)[[NSUserDefaults standardUserDefaults] integerForKey:kFingersNum];

[infoItem setTitle:[clickModeInfo stringByAppendingFormat: @" with %d Fingers", fingersQua]];
[tapToClickItem setState:clickMode ? NSControlStateValueOff : NSControlStateValueOn];
Expand Down
16 changes: 15 additions & 1 deletion MiddleClick/main.m
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
#import "Controller.h"
#import "PreferenceKeys.h"
#import "TrayMenu.h"

int main(int argc, char* argv[])
{
id keys[] = {
kFingersNum,
kMaxDistanceDelta,
kMaxTimeDeltaMs,
};
id objects[] = {
[NSNumber numberWithInt:kFingersNumDefault],
[NSNumber numberWithFloat:kMaxDistanceDeltaDefault],
[NSNumber numberWithInt:kMaxTimeDeltaMsDefault],
};
NSUInteger count = sizeof(objects) / sizeof(id);
NSDictionary *appDefaults = [NSDictionary
dictionaryWithObject:[NSNumber numberWithInt:3] forKey:@"fingers"];
dictionaryWithObjects:objects
forKeys:keys
count:count];

[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];

Expand Down

0 comments on commit 879bdf0

Please sign in to comment.