1

If I want consistent scrolling behavior across platforms and different wheel resolutions, I need a way to make wheel input independent of the device’s physical precision.

Different mice seem to have different physical resolutions. Some wheels have 16 notches per revolution, others have 24, and electromagnetic wheels may not even have discrete notches.

Is there any standard or common practice for converting the physical wheel rotation angle into the reported scroll value?

AI told me that on Windows, WHEEL_DELTA = 120 is defined as the unit step, but it does not guarantee that different mice with different resolutions will report the same delta for the same physical rotation (I’m using RAWINPUT to read raw mouse data).
And there doesn’t seem to be any reference value like this at all on Linux.

1 Answer 1

3

After reading the answers I received during the staging phase, I realized I had fallen into a misconception.


case WM_INPUT:
{
    UINT dwSize = sizeof(RAWINPUT);
    static BYTE lpb[sizeof(RAWINPUT)];
    
    GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
    
    RAWINPUT* raw = (RAWINPUT*)lpb;
    
    if (raw->header.dwType == RIM_TYPEMOUSE)
    {
        RAWMOUSE& mouse = raw->data.mouse;
        
        if ((mouse.usButtonFlags & RI_MOUSE_WHEEL) || (mouse.usButtonFlags & RI_MOUSE_HWHEEL))
        {
            short wheelDelta = (short)mouse.usButtonData;
            float scrollDelta = (float)wheelDelta / WHEEL_DELTA;
            
            if (mouse.usButtonFlags & RI_MOUSE_HWHEEL) // Horizontal
            {
                unsigned long scrollChars = 1; // 1 is the default
                SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0);
                scrollDelta *= scrollChars;
                ...
            }
            else // Vertical
            {
                unsigned long scrollLines = 3; // 3 is the default
                SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0);
                if (scrollLines != WHEEL_PAGESCROLL)
                    scrollDelta *= scrollLines;
                ...
            }
        }
        ...
    }
    
    return 0;
}

This is the sample provided in the
RAWMOUSE structure documentation
for handling raw mouse input.

I had been trying to figure out how to ensure that the same physical rotation of the mouse wheel would always produce the same wheelDelta, so that the scrolling behavior in my application would be consistent. Now I realize that this may depend on the user’s own settings. For example, if the user configures a higher wheel sensitivity in the mouse driver software, the wheelDelta received in WM_INPUT will also be larger.

Rather than forcing a perfectly uniform scrolling behavior across all devices, it makes more sense to respect the user’s configuration and allow them to adjust the wheel sensitivity according to their own needs.

Sign up to request clarification or add additional context in comments.

1 Comment

My program fell into the same trap. Instead of using user preference double-click timing, we used our own timing. That turned into an accessibility issue for people that needed a much greater double-click timing window than what we had hard-coded. Then we made the timing a user preference. Then users complained that we should just be using the operating system user settings. Then we used that instead. Then we had other users complain that we had removed our application setting. Now we have both. Doubling our testing burden.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.