Universelle Zurück- / Vorwärts-Maustasten in OSX anstelle von M4 / M5?

1867
Archagon

Ich bin verblüfft über das Verhalten der beiden seitlichen Tasten meiner Logitech MX Master-Maus. Bei allen meinen anderen Mäusen werden die seitlichen Tasten als generische "Taste 4" und "Taste 5" erkannt. (Ich habe dies mit Xcode verifiziert.) OS X scheint diese Befehle im Gegensatz zu Windows als mittlere Klicks zu behandeln. Um also das Vorwärts- / Rückwärtsverhalten zu erhalten, das Sie möglicherweise erwarten, müssen Sie ein Werkzeug wie USB-Overdrive zum Zuordnen verwenden sie zu + [und + ]. Leider funktioniert diese Problemumgehung nicht in jeder App und blinkt beim Auslösen der Menüleiste.

Mittlerweile werden die seitlichen Tasten des Masters überhaupt nicht von meinem Xcode-Mausklick erkannt, aber irgendwie funktionieren sie in praktisch jeder App mit einer Navigationsleiste. Ich habe sie in Finder, Safari, Systemeinstellungen und Xcode getestet. Das Menü blinkt nicht und der Mauszeiger muss sich über dem von der Navigationsleiste gesteuerten Bereich des Fensters befinden, was bedeutet, dass eine Art universelles Zurück / Vorwärts-Ereignis gesendet wird (im Gegensatz zu den üblichen M4 / M5). Ich kann jedoch keine Dokumentation für ein solches Ereignis in OS X finden. Bei den meisten M4 / M5-Fixes werden diese Schaltflächen mit + [und + verknüpft ].

Also, was macht der Master mit diesen seitlichen Knöpfen und wie kann ich dasselbe Verhalten bei all meinen anderen Mäusen wiederholen?

3

1 Antwort auf die Frage

2
Archagon

Ich fügte allen meinen NSWindowVeranstaltungen einen Tipp hinzu . Es stellt sich heraus, dass der Master Swipe-Events simuliert!

NSEvent: type=Swipe loc=(252,60) time=5443.9 flags=0x100 win=0x100b091f0 winNum=2014 ctxt=0x0 phase: 1 axis:0 amount=0.000 velocity= NSEvent: type=Swipe loc=(252,60) time=5443.9 flags=0x100 win=0x100b091f0 winNum=2014 ctxt=0x0 phase: 8 axis:0 amount=0.000 velocity= NSEvent: type=Swipe loc=(252,60) time=5445.7 flags=0x100 win=0x100b091f0 winNum=2014 ctxt=0x0 phase: 1 axis:0 amount=0.000 velocity= NSEvent: type=Swipe loc=(252,60) time=5445.7 flags=0x100 win=0x100b091f0 winNum=2014 ctxt=0x0 phase: 8 axis:0 amount=0.000 velocity= 

OK, das ist ziemlich schlau, denn es bedeutet im Grunde, dass es in jeder Ansicht funktioniert, die den swipeWithEvent:Selektor unterstützt . Ich habe keine Ahnung, warum dies nicht das Standardverhalten für die seitlichen Tasten ist! Jetzt muss ich herausfinden, wie ich diese Funktionalität zu meinen anderen Mäusen hinzufügen kann. Ich glaube nicht, dass USB Overdrive so etwas tun kann, es sei denn, AppleScript kann Gesten simulieren.

UPDATE: Es ist mir gelungen, diese Ereignisse mithilfe der Reverse-Engineering-Gesten-Simulationsfunktionen von Natevw zu replizieren ( https://github.com/calftrail/Touch) . Möglicherweise muss noch etwas repariert werden, aber es funktioniert! Der letzte Schritt wird die Erstellung einer ständig laufenden App sein, die M4- und M5-Ereignisse aufnimmt und diese Gesten ausspuckt.

TLInfoSwipeDirection dir = kTLInfoSwipeLeft;  NSDictionary* swipeInfo1 = [NSDictionary dictionaryWithObjectsAndKeys: @(kTLInfoSubtypeSwipe), kTLInfoKeyGestureSubtype, @(1), kTLInfoKeyGesturePhase, nil];  NSDictionary* swipeInfo2 = [NSDictionary dictionaryWithObjectsAndKeys: @(kTLInfoSubtypeSwipe), kTLInfoKeyGestureSubtype, @(dir), kTLInfoKeySwipeDirection, @(4), kTLInfoKeyGesturePhase, nil];  CGEventRef event1 = tl_CGEventCreateFromGesture((__bridge CFDictionaryRef)(swipeInfo1), (__bridge CFArrayRef)@[]); CGEventRef event2 = tl_CGEventCreateFromGesture((__bridge CFDictionaryRef)(swipeInfo2), (__bridge CFArrayRef)@[]);  CGEventPost(kCGHIDEventTap, event1); CGEventPost(kCGHIDEventTap, event2);  // not sure if necessary under ARC CFRelease(event1); CFRelease(event2); 

UPDATE 2: Hier ist eine grobe Arbeitsskizze eines View Controllers, der M4 und M5 global erfasst und Wischbewegungen ausgibt.

static void SBFFakeSwipe(TLInfoSwipeDirection dir) { NSDictionary* swipeInfo1 = [NSDictionary dictionaryWithObjectsAndKeys: @(kTLInfoSubtypeSwipe), kTLInfoKeyGestureSubtype, @(1), kTLInfoKeyGesturePhase, nil];  NSDictionary* swipeInfo2 = [NSDictionary dictionaryWithObjectsAndKeys: @(kTLInfoSubtypeSwipe), kTLInfoKeyGestureSubtype, @(dir), kTLInfoKeySwipeDirection, @(4), kTLInfoKeyGesturePhase, nil];  CGEventRef event1 = tl_CGEventCreateFromGesture((__bridge CFDictionaryRef)(swipeInfo1), (__bridge CFArrayRef)@[]); CGEventRef event2 = tl_CGEventCreateFromGesture((__bridge CFDictionaryRef)(swipeInfo2), (__bridge CFArrayRef)@[]);  CGEventPost(kCGHIDEventTap, event1); CGEventPost(kCGHIDEventTap, event2);  CFRelease(event1); CFRelease(event2); }  static CGEventRef KeyDownCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { int64_t number = CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber); BOOL down = (CGEventGetType(event) == kCGEventOtherMouseDown);  if (number == 3) { if (down) { SBFFakeSwipe(kTLInfoSwipeLeft); }  return NULL; } else if (number == 4) { if (down) { SBFFakeSwipe(kTLInfoSwipeRight); }  return NULL; } else { return event; } }  @implementation ViewController  -(void) viewDidLoad { [super viewDidLoad];  NSDictionary* options = @{ (__bridge id)kAXTrustedCheckOptionPrompt: @YES }; BOOL accessibilityEnabled = AXIsProcessTrustedWithOptions((CFDictionaryRef)options);  assert(accessibilityEnabled);  CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, CGEventMaskBit(kCGEventOtherMouseUp)|CGEventMaskBit(kCGEventOtherMouseDown), &KeyDownCallback, NULL);  assert(eventTap != NULL);  CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(NULL, eventTap, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes); CFRelease(runLoopSource);  CGEventTapEnable(eventTap, true);  //CFRelease(eventTap); -- needs to be done on dealloc, I think }  @end 

UPDATE 3: Ich habe eine Open-Source-Menüleisten-App veröffentlicht, die das Verhalten des Masters für alle Mäuse von Drittanbietern repliziert. Es heißt SensibleSideButtons . Die technischen Details sind auf der Website beschrieben.