JTalton's picture

Mouse wheel does not seem to work

Project:The Open Toolkit library
Version:1.0-beta-2
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:closed
Description

While events are fired when the mouse wheel changes, the wheel value is always 0 and the wheel delta is always 0 for both the MouseDevice and the MouseWheelEventArgs.
I could just be missing something here.

Windows Vista using Game Window


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

#1

I cannot reproduce this, the absolute and relative (delta) values are set correctly here for both MouseWheelEventArgs and MouseDevice (Windows Vista / GameWindow).

Can you please provide a simple test case that reproduces the issue?

JTalton's picture

#2

Running on Vista 32-bit. e.Delta and e.Value are always 0 for me. Let me know what I can do to help narrow down the problem.

class Program : GameWindow
{
    static void Main(string[] args)
    {
        new Program().Run();
    }
 
    public Program()
    {
        Mouse.WheelChanged += new EventHandler<OpenTK.Input.MouseWheelEventArgs>(Mouse_WheelChanged);
    }
 
    void Mouse_WheelChanged(object sender, OpenTK.Input.MouseWheelEventArgs e)
    {
        Debug.WriteLine(e.Delta.ToString() + " " + e.Value.ToString());
    }
}
the Fiddler's picture

#3

Thanks for the test case.

Unfortunately, this seems to work fine on my test system (Vista 32bit, using OpenTK 1.0 beta-1). I tested this with an Microsoft optical USB mouse and a Synaptics touchpad and both return the correct values for Delta and Value.

Who is the manufacturer of your mouse? Is it a normal wheel mouse? USB or PS/2?

Moreover, does it use built-in windows drivers or drivers downloaded by the manufacturer's site? If it is the latter, could the drivers be remapping wheel events into something else entirely? (e.g. keyboard down/up keys) Check whether there is an option to modify the drivers' behavior.

I used to have a PS/2 Trust mouse which generated key instead of wheel events by default , probably for compatibility reasons.

the Fiddler's picture

#4

WinGLNative.cs:316 contains the wheel calculation:

                case WindowMessage.MOUSEWHEEL:
                    // This is due to inconsistent behavior of the WParam value on 64bit arch, where
                    // wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
                    mouse.Wheel += (int)((long)wParam << 32 >> 48) / 120;
                    break;

This assumes (maybe incorrectly) that wparam arrives in multiples of 120. This holds for every mouse and touchpad I've laid my hands on, but I don't know if this is universal or just a coincidence.

Can you please add a Debug.WriteLine(wParam.ToString()) statement to the above code and post its output? Maybe this could give us some ideas.

AdrianPi's picture

#5

I have a question regarding this, don't know if it is the best place to post about it but here it goes:

I've been using MouseWheel event on the GLControl to zoom in/out a model, and noticed that deltas are given by 120 for each mouse wheel tick.
Where does this 120 comes from? Is there any field on some environment object that I could ask for "mouse wheel resolution" somewhere in .NET?
What I did works fine but I would like to get rid of that hardcoded "120":

AdrianPi's picture

#6

It seems there is no such a thing:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?Fe...

The beast is hardcoded in winuser.h:

/* Value for rolling one detent */
#define WHEEL_DELTA                     120
JTalton's picture

#7

I am using a wireless Microsoft mouse and keyboard.

In my case
wParam == 1835008
((long)wParam << 32 >> 48) == 28

the Fiddler's picture

#8

Status:open» confirmed

Looks like we've found our bug. It seems that the behavior of WM_MOUSEWHEEL was changed with the introduction of Vista. MSDN now states:

Quote:

The delta was set to 120 to allow Microsoft or other vendors to build finer-resolution wheels in the future, including perhaps a freely-rotating wheel with no notches. The expectation is that such a device would send more messages per rotation, but with a smaller value in each message. To support this possibility, you should either add the incoming delta values until WHEEL_DELTA is reached (so for a delta-rotation you get the same response), or scroll partial lines in response to the more frequent messages. You could also choose your scroll granularity and accumulate deltas until it is reached.

This blob wasn't in MSDN originally and it seems this change has caused several games to break. Potential solutions (source):

  1. Add up the deltas and wait until you get 120; keep the leftover for next time
  2. Use the deltas raw, without /120
  3. Use floats instead of int math
  4. suggest that the user change the mouse wheel speed in the control panel - increasing the speed may break the '120' barrier for slow wheel scrolls

Solution #2 would introduce incompatibilities with other platforms (leaky abstraction). Solution #4 can be discarded outright. This leaves #1 and #3.

#1 would likely make the user experience on such mice worse. #3 would require existing programs to change for the wheel to work correctly. My gut instinct is to deprecate the current properties in favor of two new ones: DeltaPrecise and ValuePrecise (or "*Fractional" instead of "*Precise").

Thoughts?

JTalton's picture

#9

Those sound good to me.

the Fiddler's picture

#10

Version:0.9.9-3» 0.9.x-dev
Status:confirmed» fixed

Fix committed to r2521. Fractional movements are now accumulated correctly and can be accessed via MouseDevice.WheelPrecise or MouseWheelEventArgs.ValuePrecise/DeltaPrecise.