Reset key states on window blur in CanvasInteractions

Adds a window blur event listener to reset key states and interaction modes when the window loses focus. This prevents stuck key states and finalizes any in-progress cloning drags, improving interaction reliability.
This commit is contained in:
Dariusz L
2025-07-23 17:05:19 +02:00
parent bccb9da641
commit 4e1be7c1a3
2 changed files with 42 additions and 0 deletions

View File

@@ -31,6 +31,8 @@ export class CanvasInteractions {
this.canvas.canvas.addEventListener('wheel', this.handleWheel.bind(this), { passive: false });
this.canvas.canvas.addEventListener('keydown', this.handleKeyDown.bind(this));
this.canvas.canvas.addEventListener('keyup', this.handleKeyUp.bind(this));
// Add a blur event listener to the window to reset key states
window.addEventListener('blur', this.handleBlur.bind(this));
document.addEventListener('paste', this.handlePasteEvent.bind(this));
this.canvas.canvas.addEventListener('mouseenter', (e) => {
this.canvas.isMouseOver = true;
@@ -373,6 +375,23 @@ export class CanvasInteractions {
this.interaction.keyMovementInProgress = false;
}
}
handleBlur() {
log.debug('Window lost focus, resetting key states.');
this.interaction.isCtrlPressed = false;
this.interaction.isAltPressed = false;
this.interaction.keyMovementInProgress = false;
// Also reset any interaction that relies on a key being held down
if (this.interaction.mode === 'dragging' && this.interaction.hasClonedInDrag) {
// If we were in the middle of a cloning drag, finalize it
this.canvas.saveState();
this.canvas.canvasState.saveStateToDB();
}
// Reset interaction mode if it's something that can get "stuck"
if (this.interaction.mode !== 'none' && this.interaction.mode !== 'drawingMask') {
this.resetInteractionState();
this.canvas.render();
}
}
updateCursor(worldCoords) {
const transformTarget = this.canvas.canvasLayers.getHandleAtPosition(worldCoords.x, worldCoords.y);
if (transformTarget) {

View File

@@ -59,6 +59,9 @@ export class CanvasInteractions {
this.canvas.canvas.addEventListener('keydown', this.handleKeyDown.bind(this) as EventListener);
this.canvas.canvas.addEventListener('keyup', this.handleKeyUp.bind(this) as EventListener);
// Add a blur event listener to the window to reset key states
window.addEventListener('blur', this.handleBlur.bind(this));
document.addEventListener('paste', this.handlePasteEvent.bind(this));
this.canvas.canvas.addEventListener('mouseenter', (e: MouseEvent) => {
@@ -426,6 +429,26 @@ export class CanvasInteractions {
}
}
handleBlur(): void {
log.debug('Window lost focus, resetting key states.');
this.interaction.isCtrlPressed = false;
this.interaction.isAltPressed = false;
this.interaction.keyMovementInProgress = false;
// Also reset any interaction that relies on a key being held down
if (this.interaction.mode === 'dragging' && this.interaction.hasClonedInDrag) {
// If we were in the middle of a cloning drag, finalize it
this.canvas.saveState();
this.canvas.canvasState.saveStateToDB();
}
// Reset interaction mode if it's something that can get "stuck"
if (this.interaction.mode !== 'none' && this.interaction.mode !== 'drawingMask') {
this.resetInteractionState();
this.canvas.render();
}
}
updateCursor(worldCoords: Point): void {
const transformTarget = this.canvas.canvasLayers.getHandleAtPosition(worldCoords.x, worldCoords.y);