Scroll granularity on macOS (DEF-2271)

In my game, I have a list of questions the user can scroll through. The question list is central to gameplay and should have as best of an UX as possible.

As a macOS user, I mostly use the trackpad, which has smooth pixel-level scrolling and inertial scrolling. Most macOS players will be used with this behavior. Unfortunately, Defold only gives me coarse scroll up and scroll down events and no way to detect when user scrolling stops and inertial scrolling begins. Access to the following NSEvent properties would be greatly welcomed:

2 Likes

You should be able to apply inertia to your scrolling by calculating how fast/much scroll events are changing over a time interval and use that to have the visual scrolling continue with a dampening variable (even after the scroll events stop coming in).

For example if someone scrolls 200 pixels worth over 1 second then stops scrolling, you’d continue scrolling the visual elements 1/4 of that distance over the next 0.1 second after scroll events stop, and 1/4 of the last amount over the next 0.1 second and repeating till the scroll distance remaining reaches 0.

I am not trying to add inertia. I am trying to have control (and, for example, cancel) on the one already present in my trackpad.

Do you have the same kind of functionality/APIs on Windows, Linux and HTML5 systems? Personally I’m a bit wary of adding APIs specific to a certain OS to a cross-platform engine such as Defold.

Yes, you do. Different platforms do this differently, but it’s how trackpads and mice are supposed to work in 2016, not just a platform-specific gimmick. Supporting this in games feels like the proper next step. I don’t know the Windows API, but I’ve seen apps on Windows 10 support smooth scrolling. On Linux, I’ve seen GTK 3 apps smoothly scroll, so there must be an API there and on web, you have event.wheelDelta.

Would you mind writing a short specification of what exactly it is you need and how you envision it to be used (additional data in on_input, possible configuration settings in game.project and so on)?

No problem. Maybe not exactly now, as I have to deliver an MVP of the game by tomorrow night, but I’ll try to think up a way to cleanly implement this and do a short write up.

Thanks. I’ll create a ticket once I have more details and then the team will be able to discuss a design and implementation. We’re focusing a bit more on desktop features now, but I cannot promise anything in terms of delivery date for a feature such as this. It feels more like a nice to have feature than a show-stopping feature.

Ok. Here I go:

I’ll discuss the current implementation, then I’ll propose an ideal implementation (but with disregard to backwards compatibility), then discuss the greater issue of maintaining backwards compatibility.

So, currently, when you scroll with the trackpad, the system waits for you to reach a movement threshold with your fingers, then sends a “clumped up” event sequence (pressed = true, then, immediately, released = true).

In the ideal implementation, when the user would scroll, a MOUSE_WHEEL_UP/DOWN event would get sent every time the user moved the fingers just a bit with screen_dx and screen_dy set to the amount of pixels scrolled and value (or another property) would indicate wether the scroll is a genuine user scroll (1) or inertial scrolling generated by the system (0). Conventional mouse wheel events would be differentiated by a value of 2 maybe and would have screen_dy set to a fixed value configurable from game.project.

EDIT: It would also be useful to track entire scroll sequences, so, when possible, pressed would be sent when the user begins the scrolling action, repeated throughout and released when the inertial scrolling finally ended.

EDIT: It’s important to know when the user scrolls and when inertial scrolling scrolls because inertial scrolling should be cancelable (or well, ignorable) in certain scenarios (like when implementing overscrolling bounce-back in a scroll view)

Of course, this would break compatibility with the old behavior of MOUSE_WHEEL_UP/DOWN, which is why I propose to apply the beforementioned behavior to a new MOUSE_SCROLL event and keep MOUSE_WHEEL_UP/DOWN as it is. My only concern with this approach is that it devs (especially devs who don’t use a smooth scrolling trackpad) might not hear about MOUSE_SCROLL and just use MOUSE_WHEEL_UP/DOWN, but I guess that could be solved through documentation.

I’m not sure if this is really the best way to design this, but at least I hope this outlined what kind of information would be necessary to implement a really great scroll view UI component.

Also, I’m sure not all platforms provide all this info (the web doesn’t provide scroll sequence information and inertial scrolling information, as far as I know, for example), but it’s best to offer all the info you have to the developer in a form that allows for progressive enhancement of UX on platforms that do support all the features.

1 Like

Thanks. I’ve created a ticket: DEF-2271

1 Like

Cross referencing similar thread: [Solved] Measure MOUSE_WHEEL_[UP/DOWN]

1 Like