isFocusInvisible on InputText doesn't function as expected

Hello,

When I set ‘isFocusInvisible’ on an InputText control I’d expect it not to be possible to click & focus on that control, but this isn’t the case.

(not sure if this is a bug, or I’m just misunderstanding the expected behavior)

https://playground.babylonjs.com/#Q9VZS9#936

I’m aiming to towards focusing the field on double click, so I’d like to register the first click and wait for the second but not focus straight away.

Thanks,

Jonny

cc @DarraghBurke

isFocusInvisible determines whether or not clicking a control will unfocus the currently focused control. By default, it’s only true for the virtualKeyboard; this is because you don’t want clicking keys on the virtual keyboard to unfocus the input text you’re typing in. It has no bearing on whether or not the control can be focused itself. (This is definitely a bit confusing).

The “click to focus” behavior is implemented in the TextInput class in the _onPointerDown function. The most direct way to get the behavior you’re looking for would be to extend this class and overwrite this function with one of your own, which keeps a flag to determine if you’ve double clicked. On the first click, you can set the flag to true, and set a timer to unset it after some time (say 0.5s). If the flag is already true, you can just focus the control.

You can also open a feature request to have this implemented in the TextInput, though I’m not sure it is a wide enough use case.

Thanks @DarraghBurke @sebavan

That is a better way than I was thinking about.

For anyone stumbling upon this, I just added a ‘isPointerFocusDisabled’ to the InputText class and then implemented my double click (with InputText.focus method) where it’s being used.

See the ‘Custom’ comments below, very minor change.

import { IPointerEvent, PointerInfoBase, Vector2 } from 'babylonjs'
import { Control, InputText } from 'babylonjs-gui'

export class MyInputText extends InputText {

  public isPointerFocusDisabled = false // Custom

  public override _onPointerDown(
    target: Control,
    coordinates: Vector2,
    pointerId: number,
    buttonIndex: number,
    pi: PointerInfoBase,
  ): boolean {
    // if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex, pi)) {
    //   return false
    // }

    if (this.isReadOnly) {
      return true
    }

    this._clickedCoordinate = coordinates.x
    this._isTextHighlightOn = false
    this._highlightedText = ''
    this._cursorIndex = -1
    this._isPointerDown = true
    this._host._capturingControl[pointerId] = this
    this._focusedBy = (pi.event as IPointerEvent).pointerType
    if (this._host.focusedControl === this) {
      // Move cursor
      clearTimeout(this._blinkTimeout)
      this._markAsDirty()
      return true
    }
    if (!this._isEnabled) {
      return false
    }

// Custom
    if (this.isPointerFocusDisabled) { 
      return false
    }

    this._host.focusedControl = this

    return true
  }
}

2 Likes