diff --git a/src/components/Viewport.vue b/src/components/Viewport.vue index 13320ac5a..bda3bc1e4 100644 --- a/src/components/Viewport.vue +++ b/src/components/Viewport.vue @@ -329,11 +329,31 @@ function cleanupMouseHandlers() { function setupKeyboardHandlers() { window.addEventListener('keydown', onKeyDown) window.addEventListener('keyup', onKeyUp) + window.addEventListener('blur', onWindowBlur) } function cleanupKeyboardHandlers() { window.removeEventListener('keydown', onKeyDown) window.removeEventListener('keyup', onKeyUp) + window.removeEventListener('blur', onWindowBlur) +} + +function onWindowBlur() { + // Reset all modifier states when window loses focus + // This prevents "stuck" modifiers when user alt-tabs or switches tabs + const needsUpdate = + isCtrlPressed || isShiftPressed || isAltPressed || isSpacePressed || isMiddleMouseDown + + isCtrlPressed = false + isShiftPressed = false + isAltPressed = false + isSpacePressed = false + isMiddleMouseDown = false + controls.enabled = false + + if (needsUpdate) { + updateGizmoVisibility() + } } function onKeyDown(event: KeyboardEvent) {