From 73291f7c35d564034c560c3e9efe51530f36bcbb Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Thu, 22 Oct 2026 21:30:06 -0700 Subject: [PATCH] Fix reversed hands scroll in Virtualization framework VM windows --- hands/Sources/byre-hands/Input.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hands/Sources/byre-hands/Input.swift b/hands/Sources/byre-hands/Input.swift index 589b5f8..4c20e20 100644 --- a/hands/Sources/byre-hands/Input.swift +++ b/hands/Sources/byre-hands/Input.swift @@ -159,9 +159,15 @@ func drag(_ from: CGPoint, _ to: CGPoint) async throws { } } +// Marks the deltas as inverted from the device, as natural scrolling does: VM windows undo that to recover the device's +// direction and the guest applies its own natural scrolling, so without it a scroll lands reversed there. +let scrollDirectionInverted = CGEventField(rawValue: 137)! + func scroll(_ p: CGPoint, dx: Int32, dy: Int32) { post(CGEvent(mouseEventSource: nil, mouseType: .mouseMoved, mouseCursorPosition: p, mouseButton: .left)) - post(CGEvent(scrollWheelEvent2Source: nil, units: .line, wheelCount: 2, wheel1: dy, wheel2: dx, wheel3: 0)) + let e = CGEvent(scrollWheelEvent2Source: nil, units: .line, wheelCount: 2, wheel1: dy, wheel2: dx, wheel3: 0) + e?.setIntegerValueField(scrollDirectionInverted, value: 1) + post(e) } func type(_ s: String) async throws {