From 9e2a332712c546e1599c19d3cab59d1b5515ef8b Mon Sep 17 00:00:00 2001 From: Jiahao Lu Date: Fri, 18 Feb 2022 18:39:26 +0800 Subject: [PATCH 1/2] Fix scrolling in WebKit --- CoreGraphicsSPI.h | 9 +++++ IOKitSPI.h | 46 ++++++++++++++++++++++++ MouseTap.m | 10 ++++++ ScrollReverser.xcodeproj/project.pbxproj | 4 +++ Scroll_Inverter_Prefix.pch | 2 ++ 5 files changed, 71 insertions(+) create mode 100644 CoreGraphicsSPI.h create mode 100644 IOKitSPI.h diff --git a/CoreGraphicsSPI.h b/CoreGraphicsSPI.h new file mode 100644 index 0000000..d6832b8 --- /dev/null +++ b/CoreGraphicsSPI.h @@ -0,0 +1,9 @@ +// This file is part of Scroll Reverser +// Licensed under Apache License v2.0 + +#ifndef CoreGraphicsSPI_h +#define CoreGraphicsSPI_h + +IOHIDEventRef CGEventCopyIOHIDEvent(CGEventRef); + +#endif /* CoreGraphicsSPI_h */ diff --git a/IOKitSPI.h b/IOKitSPI.h new file mode 100644 index 0000000..24aedaf --- /dev/null +++ b/IOKitSPI.h @@ -0,0 +1,46 @@ +// This file is part of Scroll Reverser +// Licensed under Apache License v2.0 + +#ifndef IOKitSPI_h +#define IOKitSPI_h + +typedef struct __IOHIDEvent * IOHIDEventRef; + +enum { + kIOHIDEventTypeNULL, + kIOHIDEventTypeVendorDefined, + kIOHIDEventTypeKeyboard = 3, + kIOHIDEventTypeRotation = 5, + kIOHIDEventTypeScroll = 6, + kIOHIDEventTypeZoom = 8, + kIOHIDEventTypeDigitizer = 11, + kIOHIDEventTypeNavigationSwipe = 16, + kIOHIDEventTypeForce = 32, +}; +typedef uint32_t IOHIDEventType; + +typedef uint32_t IOHIDEventField; +typedef uint64_t IOHIDEventSenderID; + + +enum { + kIOHIDEventScrollMomentumInterrupted = (1 << 4), +}; +typedef uint8_t IOHIDEventScrollMomentumBits; + +#ifdef __LP64__ +typedef double IOHIDFloat; +#else +typedef float IOHIDFloat; +#endif + +#define IOHIDEventFieldBase(type) (type << 16) + +#define kIOHIDEventFieldScrollBase IOHIDEventFieldBase(kIOHIDEventTypeScroll) +static const IOHIDEventField kIOHIDEventFieldScrollX = (kIOHIDEventFieldScrollBase | 0); +static const IOHIDEventField kIOHIDEventFieldScrollY = (kIOHIDEventFieldScrollBase | 1); + +IOHIDFloat IOHIDEventGetFloatValue(IOHIDEventRef, IOHIDEventField); +void IOHIDEventSetFloatValue(IOHIDEventRef, IOHIDEventField, IOHIDFloat); + +#endif /* IOKitSPI_h */ diff --git a/MouseTap.m b/MouseTap.m index ca74f7d..8586180 100644 --- a/MouseTap.m +++ b/MouseTap.m @@ -78,6 +78,8 @@ static CGEventRef _callback(CGEventTapProxy proxy, } else if (type==(CGEventType)NSEventTypeScrollWheel) { + IOHIDEventRef const ioHidEventRef=CGEventCopyIOHIDEvent(eventRef); + // is inverted from device? (1=natural scrolling, 0=classic scrolling) const BOOL invertedFromDevice=!![event isDirectionInvertedFromDevice]; [tap->logger logBool:invertedFromDevice forKey:@"ifd"]; @@ -93,12 +95,16 @@ static CGEventRef _callback(CGEventTapProxy proxy, const int64_t point_axis2=CGEventGetIntegerValueField(eventRef, kCGScrollWheelEventPointDeltaAxis2); const double fixedpt_axis1=CGEventGetDoubleValueField(eventRef, kCGScrollWheelEventFixedPtDeltaAxis1); const double fixedpt_axis2=CGEventGetDoubleValueField(eventRef, kCGScrollWheelEventFixedPtDeltaAxis2); + const IOHIDFloat iohid_axis1=IOHIDEventGetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollY); + const IOHIDFloat iohid_axis2=IOHIDEventGetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollX); [tap->logger logSignedInteger:axis1 forKey:@"y"]; [tap->logger logSignedInteger:axis2 forKey:@"x"]; [tap->logger logSignedInteger:point_axis1 forKey:@"y_pt"]; [tap->logger logSignedInteger:point_axis2 forKey:@"x_pt"]; [tap->logger logDouble:fixedpt_axis1 forKey:@"y_fp"]; [tap->logger logDouble:fixedpt_axis2 forKey:@"x_fp"]; + [tap->logger logDouble:iohid_axis1 forKey:@"y_iohid"]; + [tap->logger logDouble:iohid_axis2 forKey:@"x_iohid"]; // get source pid const uint64_t pid=CGEventGetIntegerValueField(eventRef, kCGEventSourceUnixProcessID); @@ -197,12 +203,16 @@ This is because setting DeltaAxis causes macos to internally modify PointDeltaAx if (!discreteAdjust&&vmul!=1) { // vertical - only set these if not doing discrete adjust CGEventSetDoubleValueField(eventRef, kCGScrollWheelEventFixedPtDeltaAxis1, fixedpt_axis1*vmul); CGEventSetIntegerValueField(eventRef, kCGScrollWheelEventPointDeltaAxis1, point_axis1*vmul); + IOHIDEventSetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollY, iohid_axis1*vmul); } if (hmul!=1) { // horizontal CGEventSetIntegerValueField(eventRef, kCGScrollWheelEventDeltaAxis2, axis2*hmul); CGEventSetDoubleValueField(eventRef, kCGScrollWheelEventFixedPtDeltaAxis2, fixedpt_axis2*hmul); CGEventSetIntegerValueField(eventRef, kCGScrollWheelEventPointDeltaAxis2, point_axis2*hmul); + IOHIDEventSetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollX, iohid_axis2*vmul); } + + CFRelease(ioHidEventRef); } else { diff --git a/ScrollReverser.xcodeproj/project.pbxproj b/ScrollReverser.xcodeproj/project.pbxproj index a200ba8..f308ca5 100644 --- a/ScrollReverser.xcodeproj/project.pbxproj +++ b/ScrollReverser.xcodeproj/project.pbxproj @@ -169,6 +169,8 @@ 88AC80572405185D00063181 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = resources/es.lproj/Localizable.strings; sourceTree = ""; }; 8D1107310486CEB800E47090 /* ScrollReverser-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ScrollReverser-Info.plist"; sourceTree = ""; }; 8D1107320486CEB800E47090 /* Scroll Reverser (Dev).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Scroll Reverser (Dev).app"; sourceTree = BUILT_PRODUCTS_DIR; }; + B7CF5D6627BFAB8400E09485 /* IOKitSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IOKitSPI.h; sourceTree = ""; }; + B7CF5D6727BFACD800E09485 /* CoreGraphicsSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreGraphicsSPI.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -302,6 +304,8 @@ isa = PBXGroup; children = ( 256AC3F00F4B6AF500CF3369 /* Scroll_Inverter_Prefix.pch */, + B7CF5D6627BFAB8400E09485 /* IOKitSPI.h */, + B7CF5D6727BFACD800E09485 /* CoreGraphicsSPI.h */, 29B97316FDCFA39411CA2CEA /* main.m */, ); name = "Other Sources"; diff --git a/Scroll_Inverter_Prefix.pch b/Scroll_Inverter_Prefix.pch index c80bfb5..42aec2b 100644 --- a/Scroll_Inverter_Prefix.pch +++ b/Scroll_Inverter_Prefix.pch @@ -4,6 +4,8 @@ #ifdef __OBJC__ #import + #import "IOKitSPI.h" + #import "CoreGraphicsSPI.h" #if !defined(DEBUG) #define NSLog(...) From 17afc2ff520998ac7d77048abc6a403ecff07bd2 Mon Sep 17 00:00:00 2001 From: Jiahao Lu Date: Fri, 18 Feb 2022 20:38:21 +0800 Subject: [PATCH 2/2] Check if ioHidEventRef is nil ioHidEventRef might be nil if CGEvent is created directly by CGEventCreateXXX. --- MouseTap.m | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/MouseTap.m b/MouseTap.m index 8586180..2a54239 100644 --- a/MouseTap.m +++ b/MouseTap.m @@ -95,8 +95,12 @@ static CGEventRef _callback(CGEventTapProxy proxy, const int64_t point_axis2=CGEventGetIntegerValueField(eventRef, kCGScrollWheelEventPointDeltaAxis2); const double fixedpt_axis1=CGEventGetDoubleValueField(eventRef, kCGScrollWheelEventFixedPtDeltaAxis1); const double fixedpt_axis2=CGEventGetDoubleValueField(eventRef, kCGScrollWheelEventFixedPtDeltaAxis2); - const IOHIDFloat iohid_axis1=IOHIDEventGetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollY); - const IOHIDFloat iohid_axis2=IOHIDEventGetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollX); + IOHIDFloat iohid_axis1=0; + IOHIDFloat iohid_axis2=0; + if (ioHidEventRef) { + iohid_axis1=IOHIDEventGetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollY); + iohid_axis2=IOHIDEventGetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollX); + } [tap->logger logSignedInteger:axis1 forKey:@"y"]; [tap->logger logSignedInteger:axis2 forKey:@"x"]; [tap->logger logSignedInteger:point_axis1 forKey:@"y_pt"]; @@ -203,16 +207,22 @@ This is because setting DeltaAxis causes macos to internally modify PointDeltaAx if (!discreteAdjust&&vmul!=1) { // vertical - only set these if not doing discrete adjust CGEventSetDoubleValueField(eventRef, kCGScrollWheelEventFixedPtDeltaAxis1, fixedpt_axis1*vmul); CGEventSetIntegerValueField(eventRef, kCGScrollWheelEventPointDeltaAxis1, point_axis1*vmul); - IOHIDEventSetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollY, iohid_axis1*vmul); + if (ioHidEventRef) { + IOHIDEventSetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollY, iohid_axis1*vmul); + } } if (hmul!=1) { // horizontal CGEventSetIntegerValueField(eventRef, kCGScrollWheelEventDeltaAxis2, axis2*hmul); CGEventSetDoubleValueField(eventRef, kCGScrollWheelEventFixedPtDeltaAxis2, fixedpt_axis2*hmul); CGEventSetIntegerValueField(eventRef, kCGScrollWheelEventPointDeltaAxis2, point_axis2*hmul); - IOHIDEventSetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollX, iohid_axis2*vmul); + if (ioHidEventRef) { + IOHIDEventSetFloatValue(ioHidEventRef, kIOHIDEventFieldScrollX, iohid_axis2*vmul); + } } - CFRelease(ioHidEventRef); + if (ioHidEventRef) { + CFRelease(ioHidEventRef); + } } else {