OrbitControls: Ensure pointerdown is registered when another element was focused first
Possibly related to #26735, not sure if it's the same issue.
Description
I've identified a bug in OrbitControls that is easily reproducible in latest Safari (17). Well, I think it's actually a browser bug, but OrbitControls is affected by it.
If you first focus another element and then subsequently click+drag the canvas to rotate/pan the scene, it doesn't work. In Safari it seems no pointerdown event is fired on the first canvas click. Clicking a second time, however, does fire an event:
https://github.com/mrdoob/three.js/assets/1034878/5215a130-caa0-46d4-b434-d6d26de020b0
Quite strange. Even stranger, a mousedown event does get fired on the first canvas click. Just no pointerdown.
I did find a way to fix it though, which is what I'm proposing in this PR. It seems the first pointermove event on canvas click does include the "down" button info, so we can use that to ad-hoc register a quick pointerdown:
https://github.com/mrdoob/three.js/assets/1034878/ed5406eb-6dfd-45b2-ab00-53354908b510
Now I know this should probably be fixed in the browser itself, but I hope you'll consider this fix in OrbitControls. It's quite an annoyance for me, because the apps I'm building use my custom HTML controls and not Three.js' GUI controls (which don't seem to induce this bug for some reason...), so I'm seeing this bug very frequently on Safari.
I've included an example page in the PR that you can use to test my fix out locally. If you approve I'll delete it before merge.
And here are a couple of codepens to demonstrate the bug:
- https://codepen.io/lukehorvat/pen/vYwXbvE (Canvas, no Three.js)
- https://codepen.io/lukehorvat/pen/LYoRqgo (Three.js + OrbitControls)
Three.js' GUI controls (which don't seem to induce this bug for some reason...)
Actually, I noticed the Safari issue in the example links in https://github.com/mrdoob/three.js/issues/28692#issuecomment-2176807531. Those examples do use the three.js GUI.
Actually, I noticed the Safari issue in the example links in #28692 (comment). Those examples do use the three.js GUI.
Oh, good catch. So it seems this is a problem specifically for <select> elements in Safari.
Out of curiosity I just had a look at FlyControls and it seems its dragToLook is similarly affected. In fact the problem is worse because, unlike OrbitControls, it won't even respond to canvas clicks after the first one. It becomes permanently immune to clicks once the <select> has been interacted with.
https://github.com/mrdoob/three.js/assets/1034878/cf621e6b-20cc-4cf1-802f-2adeec3c5999
If this PR is approved then I could follow up with a similar fix for FlyControls in another PR if you like? And maybe have a look at the other controls as well.
Since all controls and even normal websites are affected, it is not appropriate to add a patch for every UI related component to accommodate this browser bug.
@lukehorvat Would you be willing to report this issue to the Webkit bug tracker: https://bugs.webkit.org/?
We can revisit the implementation when it turns out that Webkit behaves spec conform (which I doubt, tbh).