Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OS/Browser Specific Mouse Wheel Events #11

Open
Omustardo opened this issue Jan 23, 2017 · 9 comments
Open

OS/Browser Specific Mouse Wheel Events #11

Omustardo opened this issue Jan 23, 2017 · 9 comments

Comments

@Omustardo
Copy link

Omustardo commented Jan 23, 2017

In comparison to the high level discussion of handling mouse wheel events in #10 this issue is to look into specific instances of wheel event behavior.

The basic issue is that mouse "wheel" events provide extremely different delta values on different systems. At minimum browser, OS, and hardware are likely to play a role. For example, on Chrome+Win10, each step of a mouse scroll wheel results in a wheel event with delta value 120. On Firefox+Win10 the delta is 3.

The values goxjs/glfw is getting can be found manually for your system in the web console of:
https://dmitri.shuralyov.com/projects/touch/scroll.html
To see the base values that the system is sending to the browser, use gopherjs serve and navigate to:
http://localhost:8080/github.com/goxjs/glfw/test/events/

A list of some values can be found here:
http://stackoverflow.com/q/5527601/3184079

@Omustardo
Copy link
Author

Omustardo commented Jan 23, 2017

Specific instances I've tested personally by modifying glfw/browser.go to print the actual wheel event:

document.AddEventListener("wheel", false, func(event dom.Event) {
	we := event.(*dom.WheelEvent)
	log.Printf("Wheel Event: %#v", we)

and then running the event listener locally:
http://localhost:8080/github.com/goxjs/glfw/tests/events/
This results in a mapping from deltaY value per mouse step : environment

  • Windows 10 Laptop with cheap old mouse
    125 : Chrome Version 55.0.2883.87 m (64-bit)
    3 : Firefox 50.1.0

  • Windows 10 Desktop with Logitech G502
    100 : Chrome Version 55.0.2883.87 m (64-bit)
    3 : Firefox 50.1.0

@Omustardo
Copy link
Author

Omustardo commented Jan 25, 2017

I realized this can be tested more easily with a bit of javascript. Open up a web console in any browser (tested on chrome + firefox), and enter the following:

document.addEventListener('wheel', function(event){console.log(event)});

Then any scrolling will result in a log message displaying the full event object. Its fields are fully described here:
https://developer.mozilla.org/en-US/docs/Web/Events/wheel

Note that on Firefox, you need to click where it says "wheel" in the log message to view the full object rather than just the few fields it logs.

Looking at the actual events gives more info than the previous post since the WheelEvent struct in Go only deals with the deltaX, deltaY, deltaZ, and deltaMode fields of the javascript object. This may or may not be useful. I tested by scrolling up a single step and recording values:

  • Win10 Laptop

    • Chrome
      • wheelDelta: 150
      • wheelDeltaY: 150
      • deltaY: -125
      • deltaMode: 0
    • Firefox
      • deltaMode: 1
      • deltaY: -3
  • Win10 Desktop

    • Chrome
      • wheelDelta: 120
      • wheelDeltaY: 120
      • deltaY: -100
      • deltaMode: 0
    • Firefox
      • deltaMode: 1
      • deltaY: -3

Except for the laptop + chrome results these results match http://stackoverflow.com/a/24595588/3184079
In all of the reading I've done about solutions for this issue, I've never seen anyone mention chrome providing wheelDeltas of anything other than 120.
This is a problem as most of the existing javascript solutions simply divide deltas by 120 or by 40 to normalize them. Evidently that doesn't actually work and we'll need to find something else. (or hopefully I am doing something wrong and an existing solution works)

@dmitshur
Copy link
Member

dmitshur commented Jan 27, 2017

@Omustardo, this issue has a lot of information but it's not specific to the problem you reported in #10. You originally said:

When run on desktop, the scroll wheel has a delta of 1 per tick in my experience. When run in the browser I experience a delta of 10 per tick.

That's what I wanted more details about, so that I can figure out what it would take to be able to reproduce it and resolve it.

Here's what information I'm looking for:

  • What did you do?

    (This should be code that uses goxjs/glfw API. I'm guessing you tried to print values of scroll delta when using GLFW on desktop, and in browser.)

  • What did you expect to see?

  • What did you see instead?

  • What operating system, processor architecture are you using (go env), and what browser version are you using?

@Omustardo
Copy link
Author

Omustardo commented Jan 27, 2017

What did you do?

  • On desktop I ran github.com\goxjs\glfw\tests\events\main.go to print the scroll delta. This printed +1 or -1 for single mouse scrollwheel steps.
  • I tried the same thing in Chrome and got +10, -10. This is due to goxjs/glfw receiving a delta of 100 in pixel mode, and dividing by 10:
    https://github.com/goxjs/glfw/blob/master/browser.go#L240
    Because this debug printing doesn't show what deltaMode is in use, and for ease of use, I decided to do all further browser testing directly with javascript by adding a listener to print the event in the web console: document.addEventListener('wheel', function(event){console.log('DeltaMode:'+event.deltaMode+" DeltaX:"+event.deltaX+" DeltaY:"+event.deltaY)});
    This results in DeltaMode:0 DeltaX:0 DeltaY:100 being logged.
    It's worth noting that the WheelEvent struct we depend on only looks at deltaX, deltaY, deltaZ, and deltaMode.
    https://github.com/dominikh/go-js-dom/blob/master/events.go#L317
    The wheel event object has more fields which are likely to be relevant. In particular, wheelDeltaY, which seems to have deltas in multiples of 120.

What did you expect to see?

Ideally the browser scroll events would have deltas with absolute value 1 per scroll wheel step.

What did you see instead?

Deltas of 10.

What operating system, processor architecture are you using (go env), and what browser version are you using?

Windows 10
Chrome Version 55.0.2883.87 m (64-bit)
GOARCH=amd64
Logitech G502 mouse

@dmitshur
Copy link
Member

Perfect, that's what I needed. Thanks.

I see one inconsistency... You said:

I tried the same thing in Chrome and got +10, -10.

What did you see instead?

Deltas of 100.

Did you mean 10?

@Omustardo
Copy link
Author

Yes, correct. Fixed the post.

@Omustardo
Copy link
Author

I think I found a situation which is not possible to reconcile between the browser and desktop, unless I'm missing an information source.

Environment:
Windows 10
Chrome Version 55.0.2883.87 m (64-bit)
GOARCH=amd64
Logitech G502 mouse

Steps to reproduce:

  • Open the OS mouse settings. The default ones are:
    Roll the mouse to scroll: multiple lines at a time
    Choose how many lines to scroll each time: 3
  • See what GLFW values these result in:
  1. Browser: Open a browser window, paste document.addEventListener('wheel', function(event){console.log('DeltaMode:'+event.deltaMode+" DeltaY:"+event.deltaY)}); into the web console, and scroll
    This results in: DeltaMode:0 DeltaY:-100
  2. Desktop: Run the test utility github.com\goxjs\glfw\tests\events\main.go and see that scrolling has a deltaY of 1.0
  • Now change the OS mouse settings so it scrolls 1 line each time, and then see what values this results in:
  1. Browser: DeltaMode:0 DeltaY:-33.33333206176758
  2. Desktop: deltaY of 1.0

That's bad as is - that the browser supplied GLFW values depend on OS settings, and desktop GLFW isn't affected at all.
The real irreconcilable issue is if you spin the mouse wheel quickly. It can result in mouse events being caught in the same event, so where one mouse step is:
DeltaMode:0 DeltaY:-33.33333206176758
you can get events like:
DeltaMode:0 DeltaY:66.66666412353516

There's no way to tell this grouped event apart from a single event where the OS setting is to scroll 2 lines per step.

This is related to to https://bugs.chromium.org/p/chromium/issues/detail?id=227454#c23
which states that Chrome and IE only ever use DOM_DELTA_PIXEL for deltaMode in wheel events. Chrome is converting from line scrolling to pixel scrolling under the hood. In this case it seems to be using a value of 33.333 pixels per line. I tested the exact same procedure on my laptop and it uses 41.666 pixels per line. I suppose the exact pixel to line conversion is irrelevant, as the desktop behavior in this case only shows 1.0, or 2.0 for the two grouped events.

@dmitshur
Copy link
Member

dmitshur commented Feb 8, 2017

I forgot to post an update here earlier. I investigated this issue a little a few days ago.

I think I found a situation which is not possible to reconcile between the browser and desktop, unless I'm missing an information source.

I came to the same conclusion. I found there was not enough raw information to be able to differentiate all the different situations. Even if I looked at some of the additional/optional/deprecated fields like wheelDelta, which seemed to offer some way of telling different scenarios apart, it still wasn't enough.

Unfortunately, I forgot the exact details (I can get it back if I try it again), but that was my conclusion too.

I've asked in #10 (comment), but how critical is fixing this bug for you? What timeline are you on? Thanks!

@Omustardo
Copy link
Author

how critical is fixing this bug for you? What timeline are you on?

I'd much prefer to wait and do it right than to get a hack in quickly. I have essentially no time constraints. My only plans for are for a basic game engine (gome), which I've been working on in my spare time.

I can just add a simple fix that should work well enough in most cases.
I'll either normalize all values to have absolute delta 1.0, or send them through a log function to keep them relatively similar. That should work for all mice by default, and if people developing on the engine are motivated, they can add support for a delta multiplier which would allow for better trackpad handling.

samhocevar pushed a commit to samhocevar-forks/goxjs-glfw that referenced this issue Aug 16, 2022
Add a simple static analysis workflow
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants