휠 반전 대체 이벤트를 줄 단위로 바꿔 원래 스크롤 속도 유지

픽셀 단위 대체 이벤트는 앱이 트랙패드처럼 처리해 한 칸당 이동 거리가 줄었다.
줄 단위로 만들고 원래 픽셀·소수점 이동량을 반전해 그대로 넣는다. 픽셀 이동량이
0인 휠 이벤트가 반전 없이 지나가던 문제도 고친다.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
jsahn
2026-09-28 16:56:58 +09:00
co-authored by Claude Opus 5.5
parent 70a1c17e03
commit 606b617d19
+14 -5
View File
@@ -170,14 +170,23 @@ let scrollCallback: CGEventTapCallBack = { proxy, type, event, _ in
log("Scroll events: \(kind)")
lastScrollKind = kind
}
let lineY = event.getIntegerValueField(.scrollWheelEventDeltaAxis1)
let pointY = event.getIntegerValueField(.scrollWheelEventPointDeltaAxis1)
guard isWheel, pointY != 0 else { return Unmanaged.passUnretained(event) }
// Apps read the hardware data attached to the original event, so editing its delta
// fields has no visible effect. Post a fresh event with the vertical delta flipped.
let fixedY = event.getDoubleValueField(.scrollWheelEventFixedPtDeltaAxis1)
guard isWheel, lineY != 0 || pointY != 0 || fixedY != 0 else { return Unmanaged.passUnretained(event) }
let lineX = event.getIntegerValueField(.scrollWheelEventDeltaAxis2)
let pointX = event.getIntegerValueField(.scrollWheelEventPointDeltaAxis2)
guard let replacement = CGEvent(scrollWheelEvent2Source: nil, units: .pixel, wheelCount: 2,
wheel1: Int32(clamping: -pointY), wheel2: Int32(clamping: pointX), wheel3: 0)
let fixedX = event.getDoubleValueField(.scrollWheelEventFixedPtDeltaAxis2)
// Apps read the hardware data attached to the original event, so editing its delta
// fields has no visible effect. Post a fresh line-based event (like a real wheel, so
// apps keep their per-line scroll distance) carrying the original deltas, Y flipped.
guard let replacement = CGEvent(scrollWheelEvent2Source: nil, units: .line, wheelCount: 2,
wheel1: Int32(clamping: -lineY), wheel2: Int32(clamping: lineX), wheel3: 0)
else { return Unmanaged.passUnretained(event) }
replacement.setIntegerValueField(.scrollWheelEventPointDeltaAxis1, value: -pointY)
replacement.setIntegerValueField(.scrollWheelEventPointDeltaAxis2, value: pointX)
replacement.setDoubleValueField(.scrollWheelEventFixedPtDeltaAxis1, value: -fixedY)
replacement.setDoubleValueField(.scrollWheelEventFixedPtDeltaAxis2, value: fixedX)
replacement.location = event.location
replacement.flags = event.flags
replacement.setIntegerValueField(.eventSourceUserData, value: invertedScrollMarker)