diff --git a/dist/what's new.md b/dist/what's new.md index d1cf45c546a..1e07a93ea11 100644 --- a/dist/what's new.md +++ b/dist/what's new.md @@ -236,6 +236,7 @@ - Added `ScrollViewer.freezeControls` property to speed up rendering ([Popov72](https://github.com/Popov72)) - Added `ImageScrollBar.num90RotationInVerticalMode` property to let the user rotate the pictures when in vertical mode ([Popov72](https://github.com/Popov72)) - Modified isPointerBlocker to block mouse wheel scroll events. ScrollViewer mouse scroll no longer dependent on scene. ([lockphase](https://github.com/lockphase/)) +- Added `_onCanvasBlur` event for controls to detect when the canvas loses focus. Fixes bug where sliders and color pickers would become stuck when canvas lost focus. ([DarraghBurkeMS](https://github.com/DarraghBurkeMS)) ### Particles diff --git a/gui/src/2D/advancedDynamicTexture.ts b/gui/src/2D/advancedDynamicTexture.ts index 808cec585e9..789c64a841b 100644 --- a/gui/src/2D/advancedDynamicTexture.ts +++ b/gui/src/2D/advancedDynamicTexture.ts @@ -56,6 +56,7 @@ export class AdvancedDynamicTexture extends DynamicTexture { private _pointerMoveObserver: Nullable>; private _pointerObserver: Nullable>; private _canvasPointerOutObserver: Nullable>; + private _canvasBlurObserver: Nullable>; private _background: string; /** @hidden */ public _rootContainer = new Container("root"); @@ -480,6 +481,9 @@ export class AdvancedDynamicTexture extends DynamicTexture { if (this._canvasPointerOutObserver) { scene.getEngine().onCanvasPointerOutObservable.remove(this._canvasPointerOutObserver); } + if (this._canvasBlurObserver) { + scene.getEngine().onCanvasBlurObservable.remove(this._canvasBlurObserver); + } if (this._layerToDispose) { this._layerToDispose.texture = null; this._layerToDispose.dispose(); @@ -741,6 +745,7 @@ export class AdvancedDynamicTexture extends DynamicTexture { } }); this._attachToOnPointerOut(scene); + this._attachToOnBlur(scene); } /** @hidden */ private onClipboardCopy = (rawEvt: Event) => { @@ -838,6 +843,7 @@ export class AdvancedDynamicTexture extends DynamicTexture { }); mesh.enablePointerMoveEvents = supportPointerMove; this._attachToOnPointerOut(scene); + this._attachToOnBlur(scene); } /** * Move the focus to a specific control @@ -876,6 +882,14 @@ export class AdvancedDynamicTexture extends DynamicTexture { } }); } + private _attachToOnBlur(scene: Scene): void { + this._canvasBlurObserver = scene.getEngine().onCanvasBlurObservable.add((pointerEvent) => { + Object.entries(this._lastControlDown).forEach(([key, value]) => { + value._onCanvasBlur(); + }); + this._lastControlDown = {}; + }); + } // Statics /** * Creates a new AdvancedDynamicTexture in projected mode (ie. attached to a mesh) diff --git a/gui/src/2D/controls/colorpicker.ts b/gui/src/2D/controls/colorpicker.ts index 29acd1ea03a..c6e1fdbc760 100644 --- a/gui/src/2D/controls/colorpicker.ts +++ b/gui/src/2D/controls/colorpicker.ts @@ -434,6 +434,11 @@ export class ColorPicker extends Control { super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick); } + public _onCanvasBlur() { + this._forcePointerUp(); + super._onCanvasBlur(); + } + /** * This function expands the color picker by creating a color picker dialog with manual * color value input and the ability to save colors into an array to be used later in diff --git a/gui/src/2D/controls/control.ts b/gui/src/2D/controls/control.ts index 51d0c9d433c..15cafac35e1 100644 --- a/gui/src/2D/controls/control.ts +++ b/gui/src/2D/controls/control.ts @@ -1853,6 +1853,9 @@ export class Control { if (canNotify && this.parent != null) { this.parent._onWheelScroll(deltaX, deltaY); } } + /** @hidden */ + public _onCanvasBlur(): void {} + /** @hidden */ public _processObservables(type: number, x: number, y: number, pointerId: number, buttonIndex: number, deltaX?: number, deltaY?: number): boolean { if (!this._isEnabled) { diff --git a/gui/src/2D/controls/sliders/baseSlider.ts b/gui/src/2D/controls/sliders/baseSlider.ts index 0e370a07bf5..a8779069826 100644 --- a/gui/src/2D/controls/sliders/baseSlider.ts +++ b/gui/src/2D/controls/sliders/baseSlider.ts @@ -326,4 +326,10 @@ export class BaseSlider extends Control { delete this._host._capturingControl[pointerId]; super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick); } + + public _onCanvasBlur(): void { + this._forcePointerUp(); + super._onCanvasBlur(); + } + }