Hotkey Planning in WebShell
The WebShell I’m working on recently needs to support hotkeys. Here’s a summary of the overall approach.
Hotkey Philosophy
First, clarify the design principles:
Hotkey combinations need to be semantic
for easy user understanding and memorization
, not counter-intuitive, while being easy for users to operateHotkeys should avoid commonly used hotkeys, such as browser hotkeys. Even if they can be intercepted and overridden, this should be considered carefully
Hotkey Conflicts
Web pages are limited by system/browser/browser plugin hotkey conflicts. Since this is a web terminal, terminals themselves have some hotkeys/keys, so we need to consider hotkeys from several aspects.
Terminal Native Hotkeys
⌥ ⬅️ Move cursor left to the beginning of the previous word, no corresponding support on Windows
⌥ ➡️ Move cursor left to the beginning of the next word, no corresponding support on Windows
⌘ ⬅️ Move cursor to beginning of line, Home on Windows
⌘ ➡️ Move cursor to end of line, End on Windows
Control C Cancel
Browser-Level Hotkeys
Browsers already have some hotkeys, and some can be intercepted while others cannot.
After actual testing on Mac Chrome, here are the results:
Interceptable Hotkeys
⌘ F
⌘ L
⌘ P
⌘ ,
⌘ S
ESC
Non-interceptable Hotkeys
⌘ N
Create new window⌘ T
Create new Tab⌘ W
Close Tab⌘ ⇧ [
Left Tab⌘ ⇧ [
Right Tab
System Hotkeys
⌘ Tab
App switching
Final Solution
Based on the above situation, the following solution is designed:
Extract the following concepts:
Action, such as
term:clearScreen
for clearing screen. The “term” part indicates scope, and “clearScreen” part indicates the function is screen clearingHotKey, such as
command+k
for a specific hotkey
Actions can bind multiple hotkeys, and the same hotkey combination can also be bound to multiple Actions.
Processing Logic
Globally capture and listen to all hotkeys under N Actions
- When a hotkey is triggered, determine whether it’s an event from the target Scope based on the element that triggered the event and the Action bound during binding. If not, ignore the event. If yes, trigger the corresponding action behavior and mark the event as caught. This facilitates subsequent bubbling event processing.
Hotkey Planning
Here are some examples for reference:
Function | Mac | Windows |
---|---|---|
Hotkey Help | ⌘ / | Ctrl / |
Settings | ⌘ , | Ctrl , |
Tab Switch | ⌃ 1-5 | Ctrl 1-5 |
New Tab | ⌥ T | Alt T |
Close Tab | ⌥ W | Alt W |
Search | ⌘ F | Ctrl F |
Increase Font | ⌘ ⇧ + | Ctrl + |
Decrease Font | ⌘ ⇧ - | Ctrl - |
AI Command | ⌃ ` | Ctrl ` |
Command Palette | ⌘⇧P |
Extensions
Apple Platform Detection
Different platforms have different hotkey bindings, so platform detection is needed.
/Mac|iPod|iPhone|iPad/.test(navigator.platform)
Mod Key
In hotkey planning, the ⌘
key on Mac corresponds to the ⌃
key on Windows, not the Windows key. This needs attention.
Windows Ctrl Left/Right
Hyper has disabled this support, but my personal testing shows it works.
Full Hotkey Support
As mentioned above, many hotkeys on web pages cannot be captured and processed because they are directly supported by browsers. However, this pain point can be solved by using keyboard.lock
to lock certain keys while the webpage is in PWA/fullscreen mode.
- Actual testing found that P/N keys cannot be locked successfully.
- The keyboard.lock API has limited compatibility - currently Chrome is OK, Safari/Firefox don’t support it yet.