I have been working on custom hotkeys for WebShell. The issue is that web hotkeys are limited by the browser and operating system, so some hotkeys cannot be captured, such as
command t.After some research, I found that
navigator.keyboard.lockcan solve this limitation. Here are some notes and takeaways from using it.
Hotkeys That Cannot Be Intercepted
Taking macOS as an example, the following hotkeys cannot be intercepted in real tests. That is, at the JS layer we cannot capture these keys and therefore cannot prevent the default behavior.
⌘ N Create new window
⌘ T Create new Tab
⌘ W Close Tab
⌘ ⇧ [ Previous Tab
⌘ ⇧ ] Next Tab
This seems unsolvable, but with the lock API, these may become possible to handle.
Lock API
lockcan be called without parameters to lock all keys.lockcan take parameters to lock specific keys, and it does not support locking modifier keys.
navigator.keyboard.lock(["KeyW", "KeyA", "KeyS", "KeyD"]);
Currently only supported in fullscreen mode. In non-fullscreen mode,lockdoes not throw errors but also does not work.
- System keyboard lock is only available when the document is in fullscreen mode, and only from a secure origin.
See https://github.com/WICG/keyboard-lock/blob/gh-pages/explainer.md
- Compatibility:
Chrome/Edge/Opera are supported, Firefox/Safari are not.
See https://caniuse.com/mdn-api_keyboard_lock
Examples
- https://keyboard-lock.glitch.me/
- https://github.com/alanhe421/express-demo/blob/master/test/keyboard-lock/lock.html
In PWA
In PWA, even without fullscreen, navigator.keyboard.lock can still capture keys. But the behavior is not consistent across OSes. So even for PWA, it is recommended to use hotkeys in fullscreen for the best experience.
Final Thoughts
The lock API addresses the pain point of web hotkeys being restricted. Unfortunately, several mainstream browsers still do not fully support it. Looking forward to the day it is widely supported.

