GUI elements miss mouse up event when mouse leaves window and stay active

Hey there,

In some (but not all) circumstances, GUI elements get confused when they are active (mouse down) in the middle of a drag and the mouse leaves the window. They seem to lose track of a mouse up button, never receive it, and thus the GUI element stays active.

To reproduce:

  1. Choose a documentation pages (e.g., Procedural Textures | Babylon.js Documentation )
  2. Click on the demo on in the right column, but DO NOT choose the full window option.
  3. In the demo subwindow, drag one of the sliders to the right so that the pointer leaves the subwindow.
  4. Release the mouse outside of the subwindow.
  5. Now move the mouse back into the subwindow. Notice that the slider is still tracking the mouse.
  6. You’re now stuck. There seems to be no way of getting out of this state.

I have seen this behavior happen with GUI controls and gizmos. It doesn’t appear to happen when the demo is full-window and the mouse falls outside the browser window.

It might be that they do not handle lost focus events ? @Deltakosh would know for sure as I wonder if it is intentional, he ll be back on Monday so we could check with him then.

I’m adding @RaananW as I feel this could be fixed by the host by calling blur on the canvas when the mouse is down or up outside

Canvas is listening to blur and focus: Babylon.js/engine.ts at master · BabylonJS/Babylon.js (github.com)

Unless I misunderstood - this is called in an iframe, I have no control over anything that happens inside of it and can’t fire any events on it.
it’s an interesting issue. Keep me assigned, I hope to find a creative solution soon.

@RaananW
FYI, the bug isn’t present on Firefox

yeah, firefox has a different security policy regarding iframes and mouse events for some reason.

An interesting thing i just found is that if after your step 5 you go back to the parent window and click on the screen, the mouseup event is triggered in the iframe. Still checking, thanks for reporting this!

Thanks mate!

Just wanted to update here - the fix was actually on the playground’s side (not the playground website, the actual playground). noPreventDefault should be set to true when attaching control, otherwise it will act wrong. As we don’t have direct access to the information from the iframe, it is not possible to do that programmatically from the doc page. There is a very complex way to override the behavior on the doc level, but this will probably have perf implications which I would rather not introduce.

TL;dr - The issue was attachControl without noPreventDefault. if you find more playgrounds like that please let me know and I will fix it.

Thanks!

I had a project where the fix for when we had scenes inside an iframe and the user did interactions like that was to on the document level that has the iframe do something like this:

let release = ()=>{
  document.getElementById('iframe-scene').scene.activeCamera.detachControl()
  document.getElementById('iframe-scene').scene.activeCamera.attachControl()
}
window.addEventListener('mouseout', ()=>{    
release()
})
document.getElementById('iframe-scene').addEventListener('mouseout', ()=>{    
release()
})

This “works” but the relese function prolly needs to be refined thats just for the camera controls, you might need to do a canvas click to or something to release the GUI element.

Update
I wrote this before I saw Raanan posted his solution. I guess this was fixed, ignore my comment XD.

2 Likes