I want to create a pause menu, but I have this error appearing when the player spam clicks to lock the mouse when locking and unlocking the mouse quickly. Uncaught (in promise) DOMException: The user has exited the lock before this request was completed.
I was wondering if there was a way or a trick to avoid it as 1) it doesn’t lock the mouse 2) make a huge framerate drop each time it happens.
You can store the time when the pointer lock was activated and then whenever you need to toggle it again you check if it was toggled/activated within the last 100 ms or so.
let pointerLockActivatedAt = null;
function inactivatePointerLock() {
const now = performance.now()
if (pointerLockActivatedAt != null && now - pointerLockActivatedAt < 100) {
return
}
// do your thing
}
function activatePointerLock() {
const now = performance.now()
pointerLockActivatedAt = now
}
A requestPointerLock() call immediately after the default unlock gestureMUST fail even when transient activation is available, to prevent malicious sites from acquiring an unescapable locked state through repeated lock attempts. On the other hand, a requestPointerLock() call immediately after a programmatic lock exit (through a exitPointerLock() call) MUST succeed when transient activation is available, to enable applications to move frequently between interaction modes, possibly through a timer or remote network activity.
In other words, if the lock was exited from code then it can be re-entered immediately. If it was exited by the user pressing the default exit key (usually ESC) then immediate re-entry MUST fail.
Similar to suggested above, I capture the pointerLockError event and set a timer. If there’s an error within a second of exiting, I give the player a message telling them to wait a second. When I first encountered this it wasn’t obvious that it was a timing related issue and not something else. Too bad the default DOMException error isn’t more self-explanatory.