From 4dabc5c754efa54adb2dc57063c7294b1c2e4654 Mon Sep 17 00:00:00 2001 From: Joe Wreschnig Date: Sat, 9 Mar 2013 15:02:25 +0100 Subject: [PATCH] Mouse improvements. Segment and snap the mouse move and scroll speed for easier matching, and tweak defaults. Add support for simulating the center mouse button. --- Classes/NJOutputController.m | 10 ++- Classes/NJOutputMouseButton.h | 4 + Classes/NJOutputMouseButton.m | 34 ++++++-- Classes/NJOutputMouseMove.m | 32 +++++-- Classes/NJOutputMouseScroll.m | 2 +- Info.plist | 2 +- Resources/English.lproj/MainMenu.xib | 123 ++++++++++++++------------- 7 files changed, 127 insertions(+), 80 deletions(-) diff --git a/Classes/NJOutputController.m b/Classes/NJOutputController.m index bcafe0d..ebedb1b 100644 --- a/Classes/NJOutputController.m +++ b/Classes/NJOutputController.m @@ -59,7 +59,7 @@ if (mouseDirSelect.selectedSegment == -1) mouseDirSelect.selectedSegment = 0; if (!mouseSpeedSlider.floatValue) - mouseSpeedSlider.floatValue = 4; + mouseSpeedSlider.floatValue = 10; } if (row != 4) { @@ -77,7 +77,7 @@ scrollDirSelect.selectedSegment = 0; if (scrollDirSelect.selectedSegment < 2 && !scrollSpeedSlider.floatValue) - scrollSpeedSlider.floatValue = 15.f; + scrollSpeedSlider.floatValue = 15; else if (scrollDirSelect.selectedSegment >= 2 && scrollSpeedSlider.floatValue) scrollSpeedSlider.floatValue = scrollSpeedSlider.minValue; @@ -129,6 +129,8 @@ - (void)sdirChanged:(NSView *)sender { [radioButtons selectCellAtRow:5 column:0]; + if (scrollDirSelect.selectedSegment >= 2) + scrollSpeedSlider.floatValue = 0; [sender.window makeFirstResponder:sender]; [self commit]; } @@ -173,7 +175,7 @@ } case 4: { NJOutputMouseButton *mb = [[NJOutputMouseButton alloc] init]; - mb.button = mouseBtnSelect.selectedSegment == 0 ? kCGMouseButtonLeft : kCGMouseButtonRight; + mb.humanIndexedButton = mouseBtnSelect.selectedSegment; return mb; } case 5: { @@ -240,7 +242,7 @@ } else if ([output isKindOfClass:NJOutputMouseButton.class]) { [radioButtons selectCellAtRow:4 column:0]; - mouseBtnSelect.selectedSegment = [(NJOutputMouseButton *)output button] == kCGMouseButtonLeft ? 0 : 1; + mouseBtnSelect.selectedSegment = [(NJOutputMouseButton *)output humanIndexedButton]; } else if ([output isKindOfClass:NJOutputMouseScroll.class]) { [radioButtons selectCellAtRow:5 column:0]; diff --git a/Classes/NJOutputMouseButton.h b/Classes/NJOutputMouseButton.h index 4d790e5..24d39b0 100644 --- a/Classes/NJOutputMouseButton.h +++ b/Classes/NJOutputMouseButton.h @@ -10,5 +10,9 @@ @interface NJOutputMouseButton : NJOutput @property (nonatomic, assign) CGMouseButton button; + // Indexed as left, right, center. + +@property (nonatomic, assign) int humanIndexedButton; + // Indexed as left, center, right. @end diff --git a/Classes/NJOutputMouseButton.m b/Classes/NJOutputMouseButton.m index bc286bd..c9fe0eb 100644 --- a/Classes/NJOutputMouseButton.m +++ b/Classes/NJOutputMouseButton.m @@ -46,35 +46,57 @@ - (void)trigger { CGFloat height = NSScreen.mainScreen.frame.size.height; NSPoint mouseLoc = NSEvent.mouseLocation; - CGEventType eventType = (_button == kCGMouseButtonLeft) ? kCGEventLeftMouseDown : kCGEventRightMouseDown; + CGEventType eventType = _button == kCGMouseButtonLeft ? kCGEventLeftMouseDown + : _button == kCGMouseButtonRight ? kCGEventRightMouseDown + : kCGEventOtherMouseDown; CGEventRef click = CGEventCreateMouseEvent(NULL, eventType, CGPointMake(mouseLoc.x, height - mouseLoc.y), _button); if (clickCount >= 3 || [upTime compare:[NSDate date]] == NSOrderedAscending - || !CGPointEqualToPoint(NSEvent.mouseLocation, clickPosition)) + || !CGPointEqualToPoint(mouseLoc, clickPosition)) clickCount = 1; else ++clickCount; CGEventSetIntegerValueField(click, kCGMouseEventClickState, clickCount); - CGEventPost(kCGHIDEventTap, click); CFRelease(click); + clickPosition = mouseLoc; } - (void)untrigger { upTime = [NJOutputMouseButton dateWithClickInterval]; - clickPosition = NSEvent.mouseLocation; + NSPoint mouseLoc = NSEvent.mouseLocation; CGFloat height = NSScreen.mainScreen.frame.size.height; - CGEventType eventType = (_button == kCGMouseButtonLeft) ? kCGEventLeftMouseUp : kCGEventRightMouseUp; + CGEventType eventType = _button == kCGMouseButtonLeft ? kCGEventLeftMouseUp + : _button == kCGMouseButtonRight ? kCGEventRightMouseUp + : kCGEventOtherMouseUp; CGEventRef click = CGEventCreateMouseEvent(NULL, eventType, - CGPointMake(clickPosition.x, height - clickPosition.y), + CGPointMake(mouseLoc.x, height - mouseLoc.y), _button); CGEventSetIntegerValueField(click, kCGMouseEventClickState, clickCount); CGEventPost(kCGHIDEventTap, click); CFRelease(click); } +- (int)humanIndexedButton { + switch (_button) { + case kCGMouseButtonLeft: return 0; + case kCGMouseButtonCenter: return 1; + case kCGMouseButtonRight: return 2; + default: return 0; + } +} + +- (void)setHumanIndexedButton:(int)humanIndexedButton { + switch (humanIndexedButton) { + case 0: _button = kCGMouseButtonLeft; break; + case 1: _button = kCGMouseButtonCenter; break; + case 2: _button = kCGMouseButtonRight; break; + default: _button = kCGMouseButtonLeft; + } +} + @end diff --git a/Classes/NJOutputMouseMove.m b/Classes/NJOutputMouseMove.m index 884a3d3..be8b076 100644 --- a/Classes/NJOutputMouseMove.m +++ b/Classes/NJOutputMouseMove.m @@ -28,7 +28,7 @@ output.axis = [serialization[@"axis"] intValue]; output.speed = [serialization[@"speed"] floatValue]; if (!output.speed) - output.speed = 4; + output.speed = 10; return output; } @@ -36,13 +36,15 @@ return YES; } +#define CLAMP(a, l, h) MIN(h, MAX(a, l)) + - (BOOL)update:(NJDeviceController *)jc { if (self.magnitude < 0.05) return NO; // dead zone - CGFloat height = NSScreen.mainScreen.frame.size.height; + CGSize size = NSScreen.mainScreen.frame.size; - float dx = 0.f, dy = 0.f; + CGFloat dx = 0, dy = 0; switch (_axis) { case 0: dx = -self.magnitude * _speed; @@ -58,17 +60,33 @@ break; } NSPoint mouseLoc = jc.mouseLoc; - mouseLoc.x += dx; - mouseLoc.y -= dy; + mouseLoc.x = CLAMP(mouseLoc.x + dx, 0, size.width - 1); + mouseLoc.y = CLAMP(mouseLoc.y - dy, 0, size.height - 1); jc.mouseLoc = mouseLoc; CGEventRef move = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, - CGPointMake(mouseLoc.x, height - mouseLoc.y), + CGPointMake(mouseLoc.x, size.height - mouseLoc.y), 0); - CGEventSetType(move, kCGEventMouseMoved); CGEventSetIntegerValueField(move, kCGMouseEventDeltaX, (int)dx); CGEventSetIntegerValueField(move, kCGMouseEventDeltaY, (int)dy); CGEventPost(kCGHIDEventTap, move); + + if (CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonLeft)) { + CGEventSetType(move, kCGEventLeftMouseDragged); + CGEventSetIntegerValueField(move, kCGMouseEventButtonNumber, kCGMouseButtonLeft); + CGEventPost(kCGHIDEventTap, move); + } + if (CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonRight)) { + CGEventSetType(move, kCGEventRightMouseDragged); + CGEventSetIntegerValueField(move, kCGMouseEventButtonNumber, kCGMouseButtonRight); + CGEventPost(kCGHIDEventTap, move); + } + if (CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonCenter)) { + CGEventSetType(move, kCGEventOtherMouseDragged); + CGEventSetIntegerValueField(move, kCGMouseEventButtonNumber, kCGMouseButtonCenter); + CGEventPost(kCGHIDEventTap, move); + } + CFRelease(move); return YES; } diff --git a/Classes/NJOutputMouseScroll.m b/Classes/NJOutputMouseScroll.m index 812685f..99cec4a 100644 --- a/Classes/NJOutputMouseScroll.m +++ b/Classes/NJOutputMouseScroll.m @@ -24,7 +24,7 @@ withMappings:(NSArray *)mappings { NJOutputMouseScroll *output = [[NJOutputMouseScroll alloc] init]; output.direction = [serialization[@"direction"] intValue]; - output.speed = [serialization[@"direction"] floatValue]; + output.speed = [serialization[@"speed"] floatValue]; return output; } diff --git a/Info.plist b/Info.plist index ad99f4a..b9ce686 100644 --- a/Info.plist +++ b/Info.plist @@ -46,7 +46,7 @@ CFBundleSignature ???? CFBundleVersion - 16 + 63 LSApplicationCategoryType public.app-category.utilities NSHumanReadableCopyright diff --git a/Resources/English.lproj/MainMenu.xib b/Resources/English.lproj/MainMenu.xib index 22b83f7..0c4cdf5 100644 --- a/Resources/English.lproj/MainMenu.xib +++ b/Resources/English.lproj/MainMenu.xib @@ -676,58 +676,6 @@ aW5nLg 285 - - - 265 - {{191, 24}, {130, 12}} - - - - _NS:9 - YES - - -2080374784 - 262144 - - _NS:9 - - 30 - 0.0 - 15 - 0.0 - 0 - 1 - NO - NO - - NO - - - - 265 - {{191, 108}, {176, 12}} - - - - _NS:9 - YES - - -2080374784 - 262144 - - _NS:9 - - 20 - 0.0 - 4 - 0.0 - 0 - 1 - NO - NO - - NO - 265 @@ -747,7 +695,6 @@ aW5nLg 44 ← - YES 0 @@ -791,7 +738,6 @@ aW5nLg 64 ↑ Scroll up continuously - YES 0 @@ -816,6 +762,32 @@ aW5nLg NO + + + 265 + {{191, 24}, {130, 16}} + + + + _NS:9 + YES + + -2080374784 + 262144 + + _NS:9 + + 30 + 0.0 + 15 + 0.0 + 11 + 1 + YES + NO + + NO + 265 @@ -837,22 +809,51 @@ aW5nLg - 87 + 55 Left - YES 0 - 86 - Right + Center 1 0 + + 55 + Right + 0 + 1 NO + + + 265 + {{191, 108}, {176, 16}} + + + + _NS:9 + YES + + 67108864 + 262144 + + _NS:9 + + 20 + 0.0 + 10 + 0.0 + 11 + 1 + YES + NO + + NO + 265 @@ -2846,13 +2847,13 @@ aW5nLg com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin -- 2.30.2