Hotkey Planning in WebShell

· 3 min read

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:

  1. Hotkey combinations need to be semantic for easy user understanding and memorization, not counter-intuitive, while being easy for users to operate

  2. Hotkeys 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:

  1. Action, such as term:clearScreen for clearing screen. The “term” part indicates scope, and “clearScreen” part indicates the function is screen clearing

  2. HotKey, 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

  1. 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:

FunctionMacWindows
Hotkey Help⌘ /Ctrl /
Settings⌘ ,Ctrl ,
Tab Switch⌃ 1-5Ctrl 1-5
New Tab⌥ TAlt T
Close Tab⌥ WAlt W
Search⌘ FCtrl 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.

  1. Actual testing found that P/N keys cannot be locked successfully.
  2. The keyboard.lock API has limited compatibility - currently Chrome is OK, Safari/Firefox don’t support it yet.