We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2293 - Precise scrolling events
Summary: Precise scrolling events
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: events (show other bugs)
Version: 2.0.1
Hardware: All Linux
: P2 enhancement
Assignee: Martijn Courteaux
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-12-10 21:22 UTC by r.kreis
Modified: 2017-08-15 04:28 UTC (History)
2 users (show)

See Also:


Attachments
The changeset for precise scrolling events. (19.58 KB, patch)
2016-06-01 14:26 UTC, Martijn Courteaux
Details | Diff
Fixed patch (cleaner). (18.87 KB, patch)
2016-06-01 15:40 UTC, Martijn Courteaux
Details | Diff
Working patch this time. (18.37 KB, patch)
2016-08-17 23:14 UTC, Martijn Courteaux
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description r.kreis 2013-12-10 21:22:32 UTC
SDL2 reports scrolling events as the number of "clicks" in each direction.  While this mirrors the way most mouse wheels work, many important input devices (some mice, all touchpads, trackpoints and touchscreens) report more precise data.  Although this is available on at least X11 (xinput2), Cocoa and Windows, SDL2 does not make use of it.

Adding precise scrolling support will require API changes.  Redefining SDL_MouseWheelEvent.{x,y} to be pixels (which would be useful for "actual" scrolling) or some other unit (windows uses 120th of a "click") might break existing applications.  One solution would be adding another function to set the resolution of wheel events and keeping the current behaviour (which really should be documented) until it's called.  Another way would be adding a new event with precise data.  This would enable keeping intentional "clicks" (which could lead to an action, like cycling through items/weapons in FPS games) and continuous movement (as used for smooth scrolling or zooming) apart.

I wrote a proof of concept based for SDL2 and X11/xinput2, but it's quite flawed because xinput2 is very awkward regarding wheel events (or anything, really).  It could still evolve into a proper implementation, and I'd happily share it.  As far as I can see, those events are more easily available from Cocoa and Windows, where the implementation should be almost trivial.
Comment 1 BurnSpamAddress 2013-12-18 23:09:15 UTC
IIRC, Cocoa reports movements in floating-point numbers, so this is trivial to support there.

On Windows, regular wheel events come in multiples of 120, while high-res events come in fractions of 120. Supporting high-res events would entail removing the integer division by 120.

There are two possible approaches: either add a new field to SDL_MouseWheelEvent that reports wheel events in fixed-point numbers (similar to joystick axes), or add a new method to add a scaling factor to normal events (essentially turning normal wheel values from integers to fixed-point), as suggested here: http://lists.libsdl.org/pipermail/sdl-libsdl.org/2013-December/092346.html

The second approach is a little more involved for the users, since they'd have to manually handle fixed-point scaling with all related issues (cumulative errors, etc).
Comment 2 Martijn Courteaux 2016-06-01 14:26:57 UTC
Created attachment 2475 [details]
The changeset for precise scrolling events.

OS X code is tested and works. Can't speak for others.
Comment 3 Martijn Courteaux 2016-06-01 14:35:40 UTC
I implemented precise scrolling events. I have been through all the folders in /src/video/[platform] to implement where possible. This works on OS X, but I can't speak for others. Build farm will figure that out, I guess. I think this patch should introduce precise scrolling on OS X, Wayland, Mir, Windows, Android, Nacl, Windows RT.

The way I provide precise scrolling events is by adding two float fields to the SDL_MouseWheelScrollEvent datastructure, called "preciseX" and "preciseY". The old integer fields "x" and "y" are still present. The idea is that every platform specific code normalises the scroll amounts and forwards them to the SDL_SendMouseWheel function. It is this function that will now accumulate these (using a static variable, as I have seen how it was implemented in the Windows specific code) and once we hit a unit size, set the traditional integer "x" and "y" fields.

I believe this is pretty solid way of doing it, although I'm not the expert here.

There is also a fix in the patch for a typo recently introduced, that might need to be taken away by the time anybody merges this in. There is also a file in Nacl which I have stripped a horrible amount of trailing whitespaces. (Leave that part out if you want).
Comment 4 Martijn Courteaux 2016-06-01 15:40:14 UTC
Created attachment 2476 [details]
Fixed patch (cleaner).

New version of the patch. Removes the typo I introduced (the typo I thought someone else introduced).
Comment 5 Martijn Courteaux 2016-06-01 16:12:29 UTC
Note that this doesn't fix it for X11. I'm a X11 noob, but I think that SDL doesn't use xinput2, since @r.kreis said that.
Comment 6 Martijn Courteaux 2016-08-17 23:14:49 UTC
Created attachment 2552 [details]
Working patch this time.

I tried reapplying my own patch to a fresh checkout, and it seemed to contain a bug. Here is the working patch.
Comment 7 Sam Lantinga 2017-08-15 04:28:57 UTC
Patch added, thanks!
https://hg.libsdl.org/SDL/rev/68a80d7afec3

I left out the public event interface change for now and we can add the precise motion fields to the event for SDL 2.1.