Pointer Events in GUI

I’ve noticed some strange behavior regarding pointer events in the BabylonJS GUI.

If you implement a scene with multiple Rectangle controls and assign ‘onPointerDownObservable’ and ‘onPointerUpObservable’ handlers to each control AND you are capturing pointer events in the scene (via onPointerObservable), only the ‘pointerDown’ events will be captured by the control (‘pointerUp’ will not) - though all scene pointer events continue to work.

I have seen some forum topics here addressing this topic. There seems to be two different important observations:

  1. If you set ‘isPointerBlocker’ to true for ALL controls, then the controls’ pointer events will be captured as desired (presumably this prevents the scene from “stealing” the events?).
  2. In the derived/extended GUI class ‘Button’, this problem seems to go away.

And here are some notes on the above:

Regarding (1) above: first of all, the control-based ‘pointerDown’ always works, regardless of the ‘isPointerBlocker’ setting. Second, if the control-based ‘pointerDown’ is intended to work even with ‘isPointerBlocker’ false, then why doesn’t ‘pointerUp’ also work? (Alternatively, if control-based pointer events are not meant to work when ‘isPointerBlocker’ is false, then why does ‘pointerDown’ work?)
This may be important not only for the sake of consistency, but because as it works presently it would seem difficult or impossible to create an environment where you could handle BOTH control-based pointer events and scene-based pointer events.

Regarding (2) above: why does this problem disappear with Button controls? (I haven’t read the source code - perhaps the reason has to do with #1. :slight_smile: )

1 Like

ping @DarraghBurke

1 Like

As far as I know ‘PointerDown’ should be used as an ‘animation’ not an observable together with the ‘PointerUp’ (observable). As far as I know the reason is that, historically, some browsers didn’t return the information for PointerDown. Probably they would all do today, I’m not sure. I wouldn’t however attempt to mix both (animation and observable) on the same ‘PointerDown’ event. And actually, I don’t really see the reason why you’d want to do this?

Alas, I had no idea what you were talking about!

Then I read a little about the “observables” concept, and now I only halfway don’t know what you are talking about. :slight_smile: Some questions:

  1. You mention that ‘PointerDown’ should be used as an animation, not an observable. If so, why is there a ‘onPointerDownObservable’ property?
  2. Aren’t these just simple mouse pointer events? How would one use a pointer event “as an animation”?
  3. How would one “mix” animation and observable?

I’m investigating this right now, but a couple preliminary notes:

  1. Setting isPointerBlocker to true on a control makes the pointer up/down observables work correctly.
  2. Buttons initially start with isPointerBlocker=true since they’re meant to be clicked. This is why they work out of the box.
  3. I am not sure what Mawa is referring to about animations. onPointerDownObservable and onPointerUpObservable is the standard way to add pointer behavior to controls.

I do repro the issue you are describing - if isPointerBlocker is false, you only get the first pointer down event, but no further pointer down or pointer ups. This definitely seems like the wrong behavior. I’ll let you know what I uncover.

2 Likes

I’m referring to this:
button.pointerDownAnimation = () => {
//do something onPointerDown (animateable)
}
VS this:
button.onPointerUpObservable.add(() => {
//do something on PointerUp (observable)
});

Ah, those are only members of the Button class, other GUI controls don’t use them.

Indeed, my apologies. I should may be read the full text first :wink: (speaking about a rectangle :flushed:

1 Like

Hey there @Slimfinger just checking in if your question has been answered :slight_smile:

Oh, sorry - I’ve kind of lost track of this topic. I got my UI working correctly - partially due to the advice from Darragh regarding ‘isPointerBlocker’. I initially didn’t return to this post and mark it solved, etc., because it feels like it’s not exactly solved. True, I can get satisfactory behavior by using the flag provided, but I don’t know if it’s as much a “solution” as a coincidence! LOL

@DarraghBurke - you mentioned above that you were checking into the exact function of ‘isPointerBlocker’. It seems a little confusing to me (even the name is - i.e., what is actually being “blocked”?). Also, if the flag simply allows the control to process pointer events, you’d think that it would only work with the flag set - however, it appears that the behavior is to work consistently when the flag is set, and work only once when it isn’t set (unless the pointer leaves and re-enters the canvas). So, can you explain why this is so (or is it essentially a bug)?

Either way, this topic has basically been solved, but I would immensely appreciate some more clarification! Thanks again, guys :slight_smile:

1 Like

Hey there @Slimfinger ! Apologies for not following up on this earlier. Me and @RaananW are taking care of the GUI for now, so I took a look at isPointerBlocker so I can answer you to the best of my ability. :smiley:

  1. If you set ‘isPointerBlocker’ to true for ALL controls, then the controls’ pointer events will be captured as desired (presumably this prevents the scene from “stealing” the events?).

Your idea of how isPointerBlocker works was right, if this is set on a GUI Control, this _checkPrePointerObservable in the input manager will be set to true, and we will early return from the pointer processing: Babylon.js/scene.inputManager.ts at 2746fca41f6dbe383533c4b27e76ed026e2efc81 · BabylonJS/Babylon.js · GitHub

1 Like

Thanks, Carol, for the response. However, as I mentioned above, this topic has not really been solved, and I do not believe your response to be correct. IMHO, there are problems with the current design, and I created another topic here in “Feature Requests”… IsPointerBlocker Improvement

I do certainly agree that the current design has issues :slight_smile: It’s something we will have to revisit sometime