diff --git a/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs b/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs index 001634f0..d187f1aa 100644 --- a/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs +++ b/Source/OpenTK/Platform/MacOS/CocoaNativeWindow.cs @@ -540,7 +540,10 @@ namespace OpenTK.Platform.MacOS // Only raise wheel events when the user has actually scrolled if (dx != 0 || dy != 0) { - OnMouseWheel(dx, dy); + // Note: OpenTK follows the win32 convention, where + // (+h, +v) = (right, up). MacOS reports (+h, +v) = (left, up) + // so we need to flip the horizontal scroll direction. + OnMouseWheel(-dx, dy); } } break; diff --git a/Source/OpenTK/Platform/MacOS/HIDInput.cs b/Source/OpenTK/Platform/MacOS/HIDInput.cs index 2483fde5..8f303040 100755 --- a/Source/OpenTK/Platform/MacOS/HIDInput.cs +++ b/Source/OpenTK/Platform/MacOS/HIDInput.cs @@ -180,9 +180,14 @@ namespace OpenTK.Platform.MacOS break; case CGEventType.ScrollWheel: - CursorState.SetScrollRelative( - (float)CG.EventGetDoubleValueField(@event, CGEventField.ScrollWheelEventPointDeltaAxis2) * MacOSFactory.ScrollFactor, - (float)CG.EventGetDoubleValueField(@event, CGEventField.ScrollWheelEventPointDeltaAxis1) * MacOSFactory.ScrollFactor); + { + // Note: OpenTK follows the win32 convention, where + // (+h, +v) = (right, up). MacOS reports (+h, +v) = (left, up) + // so we need to flip the horizontal scroll direction. + double h = CG.EventGetDoubleValueField(@event, CGEventField.ScrollWheelEventPointDeltaAxis2) * MacOSFactory.ScrollFactor; + double v = CG.EventGetDoubleValueField(@event, CGEventField.ScrollWheelEventPointDeltaAxis1) * MacOSFactory.ScrollFactor; + CursorState.SetScrollRelative((float)(-h), (float)v); + } break; case CGEventType.LeftMouseDown: @@ -190,6 +195,7 @@ namespace OpenTK.Platform.MacOS case CGEventType.OtherMouseDown: { int n = CG.EventGetIntegerValueField(@event, CGEventField.MouseEventButtonNumber); + n = n == 1 ? 2 : n == 2 ? 1 : n; // flip middle and right button numbers to match OpenTK MouseButton b = MouseButton.Left + n; CursorState[b] = true; } @@ -200,6 +206,7 @@ namespace OpenTK.Platform.MacOS case CGEventType.OtherMouseUp: { int n = CG.EventGetIntegerValueField(@event, CGEventField.MouseEventButtonNumber); + n = n == 1 ? 2 : n == 2 ? 1 : n; // flip middle and right button numbers to match OpenTK MouseButton b = MouseButton.Left + n; CursorState[b] = false; } @@ -406,6 +413,11 @@ namespace OpenTK.Platform.MacOS mouse.State.Y += v_int; break; + case HIDUsageGD.Z: + // Horizontal scrolling for apple mouse (old-style with trackball) + mouse.State.SetScrollRelative(v_int, 0); + break; + case HIDUsageGD.Wheel: mouse.State.SetScrollRelative(0, v_int); break; diff --git a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs index 9c79119b..43e7bd75 100644 --- a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs +++ b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs @@ -37,6 +37,9 @@ namespace OpenTK.Platform.MacOS class MacOSFactory : PlatformFactoryBase { + // Todo: we can query the exact amount via + // CGEventSourceGetPixelsPerLine. This is + // approximately 0.1f internal const float ScrollFactor = 0.1f; internal static bool ExclusiveFullscreen = false; diff --git a/Source/OpenTK/Platform/X11/XI2MouseKeyboard.cs b/Source/OpenTK/Platform/X11/XI2MouseKeyboard.cs index 1ef31796..0df840ce 100644 --- a/Source/OpenTK/Platform/X11/XI2MouseKeyboard.cs +++ b/Source/OpenTK/Platform/X11/XI2MouseKeyboard.cs @@ -544,7 +544,11 @@ namespace OpenTK.Platform.X11 d.State.X += (int)Math.Round(x); d.State.Y += (int)Math.Round(y); - d.State.SetScrollRelative((float)h, (float)v); + + // Note: OpenTK follows the windows scrolling convention where + // (+h, +v) = (right, up). XI2 uses (+h, +v) = (right, down) + // instead, so we need to flip the vertical offset. + d.State.SetScrollRelative((float)h, (float)(-v)); } unsafe static double ReadRawValue(ref XIRawEvent raw, int bit)