Radobot's picture

Extra mouse buttons aren't registered correctly on windows

Project:The Open Toolkit library
Category:bug report

When I press any of my mouse extra buttons, it always returns MouseButton.Button2 was pressed.
After a bit of debugging I found the issue:
Code which determines which of the extra buttons was pressed is defined like this:

mouse[((wparam.ToUInt32() & 0xFFFF0000) >> 16) != (int)MouseKeys.XButton1 ? MouseButton.Button1 : MouseButton.Button2] = true;

Which takes high-order word of wParam and compares it to defined constant. Which is, technically correct, but it uses incorrect constant. MouseKeys.XButton1 is defined as 0x20 and should be used as a flag for low-order word. Which xbutton was pressed (or released) is stored in high-order word and it's defined as 1 for XButton1 & 2 for XButton2. There are actually two different enums!

This is how the code should look like:

mouse[((wparam.ToUInt32() & 0xFFFF0000) >> 16) == 1 ? MouseButton.Button1 : MouseButton.Button2] = true;

This fix just needs to be applied to
OpenTK/Platform/Windows/WinGLNative.cs : 312
OpenTK/Platform/Windows/WinGLNative.cs : 329
OpenTK/Platform/Windows/WMInput.cs : 113
OpenTK/Platform/Windows/WMInput.cs : 130
and everything works correctly :)

Edit: I didn't check dev builds if this wasn't fixed already. But now I see that 2012-03-15 version still has this bug, it just says Button1 instead of Button2.
Edit2: Actually, the original code is correct, it just compares wparam with wrong constant.


Comment viewing options

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


This page says the extended mouse buttons are in the HIWORD. Are you sure about this? I'm taking a closer look..


Radobot's picture


You are right, I didn't notice the note under the button code list in the msdn documentation on this topic. I just deleted 4 zeros and thought that was the solution since it was so simple to do.
So the correct code, according to msdn documentation should be then:

mouse[((wparam.ToUInt32() & 0xFFFF0000) >> 16) == 1 ? MouseButton.Button1 : MouseButton.Button2] = true;

jeske's picture


The LOWORD contains flags for currently held-down modifiers, including control, shift, the and mouse buttons, while the HIWORD contains which mouse-button was actually pressed in this message. Using the LOWORD like your patch only "happens to work" if no other modifiers are held down, but it is not correct. See this documentation of the message...


For example, wParam values I see on Win7/64 are:

0x00010020 - XButton1 pressed
0x00020040 - XButton2 pressed
0x00020044 - XButton2 pressed while shift held

I have committed what apepars to be a working fix to my github repo here..


jeske's picture


Yes. My patch is a bit more docu-verbose, but effectively the same.

Radobot's picture


I was updating the post while you posted your comment :D. I made practically the same patch, just wrote it differently.

the Fiddler's picture


Version:1.0-2010-10-06» 1.1-dev
Status:open» closed

Somehow missed this, now tracking at https://github.com/opentk/opentk/issues/27

the Fiddler's picture


Thank you for the bug report and investigation, this issue is now fixed with https://github.com/opentk/opentk/commit/b87b9e0a2723915923d1a33e97faf9c5...