1

The docs are really stingy regarding this but from the info I gathered online, the wheelCount should be 1 for Y-only, 2 for Y-X, 3 for Y-X-Z.

To my understanding setting wheelCount = 2 inside CGEventCreateScrollWheelEvent should scroll both x and y by 10 pixels but the next chunk of code scrolls, in some apps (Chrome, Safari) only 10 pixels up while in other apps (Preview, Firefox) scrolls both axis:

    CGEventRef scroll = CGEventCreateScrollWheelEvent(NULL,
                                                  kCGScrollEventUnitPixel,
                                                  (uint32_t)2,(int32_t)10,
                                                  (int32_t)10);
    CGEventPost(kCGHIDEventTap, scroll);

    // Verify deltas

    int64_t deltaAxis1 = CGEventGetIntegerValueField(scroll, kCGScrollWheelEventPointDeltaAxis1);
    int64_t deltaAxis2 = CGEventGetIntegerValueField(scroll, kCGScrollWheelEventPointDeltaAxis2);

    NSLog(@"kCGScrollWheelEventPointDeltaAxis1: %lld",deltaAxis1); //kCGScrollWheelEventPointDeltaAxis1: 10
    NSLog(@"kCGScrollWheelEventPointDeltaAxis2: %lld",deltaAxis2); //kCGScrollWheelEventPointDeltaAxis2: 10

    CFRelease(scroll);

Link to docs

Update: After some digging, it seems that some apps don't know how to interpret multi wheel scrolling and scrolls only x or y.

This can be easily reproduced using the above code or a Macbook trackpad:

Open a zoomed in picture in Preview and in Safari. Swiping 2 fingers on a trackpad diagonally while in Preview will create a nice smooth x&y scroll. Doing the same inside Safari or Chrome will result only X or Y being scrolled and will feel broken in general.

I've found a Chrome bug related to this that was closed with "Won't fix". Can't understand why.

Any better explanation on why this is happening would be great.

Thanks

Segev
  • 19,035
  • 12
  • 80
  • 152
  • Just for the protocol: 1. Did you try to cast the deltas to `uint32_t`? 2. Did you read out the properties from the just created event? – Amin Negm-Awad Jun 25 '17 at 17:12
  • I did. I'll edit the question to clarify this. – Segev Jun 25 '17 at 17:24
  • How did you test this, using Xcodes editor? Try a Finder window. – Willeke Jun 25 '17 at 21:18
  • Finder window, a large zoomed in image in Chrome \ Safari \ Firefox \ Preview. All with the same result. – Segev Jun 25 '17 at 21:19
  • Weird, it works for me. Except Xcode. What happens when you do deltaAxis2 = 100 or deltaAxis1 = 0? – Willeke Jun 25 '17 at 23:31
  • I've updated the question with more info. – Segev Jun 26 '17 at 12:28
  • 1
    I think is has something to do with [usesPredominantAxisScrolling](https://developer.apple.com/documentation/appkit/nsscrollview/1403489-usespredominantaxisscrolling). In a test app with a WebView, `usesPredominantAxisScrolling` of the scroll view is YES. Setting it to NO fixes the problem. – Willeke Jun 27 '17 at 16:04
  • Great find! The description explains just that. – Segev Jun 27 '17 at 16:32
  • @Willeke Please add your last comment as an answer so I can accept it. It seems that that's exactly what differentiate apps that can scroll diagonally and apps that can't. – Segev Jul 10 '17 at 05:06

1 Answers1

1

usesPredominantAxisScrolling describes the phenomenon:

Some content is scrollable in both the horizontal and vertical axes, but is predominantly scrolled one axis at a time. Other content (such as a drawing canvas) should scroll freely in both axes.

Traditionally this is not an issue with scroll wheels since they can only scroll in one direction at a time. With scroll balls and touch surfaces, it becomes more difficult to determine the user's intention.

This property helps a scroll view determine the user's intention by specifying if there is a predominant scrolling axis for content.

In a test app with a WebView, usesPredominantAxisScrolling of the scroll view is YES. Setting it to NO fixes the problem.

Community
  • 1
  • 1
Willeke
  • 14,578
  • 4
  • 19
  • 47