Explains why setting autocomplete/autocorrect/autocapitalize/spellcheck
attributes on xterm.js's hidden helper textarea is needed (and why a
MutationObserver) for mobile keyboards to stop corrupting per-keystroke
input. Still load-bearing alongside the new compose bar — covers chord
and arrow keys typed outside the compose input.
The keydown interceptor was likely conflicting with xterm.js native
Tab handling. Instead, set tabIndex=-1 on toolbar buttons so Tab
can't escape the terminal to browser focus, and auto-refocus terminal
on any click outside the toolbar.
Tab key was being captured by the browser for focus cycling instead of
being sent to the terminal for bash completion. Now intercepted at the
document level and forwarded to the terminal when xterm has focus.
Buttons were sending literal 'n'/'p' instead of Ctrl-A+n/p because
the hex escape decode was failing. Now uses real control characters
in data-k attributes and sends via triggerDataEvent() which hooks
directly into ttyd's websocket transport.
All Ctrl+Shift shortcuts mapped to match kitty defaults:
- Ctrl+Shift+T/W/Left/Right for tab management
- Ctrl+Shift+Enter for splits, ]/[ for pane cycling
- Ctrl+Shift+C/V for copy/paste, H for scrollback pager
- Ctrl+Shift+1-9 for goto tab, F11 for fullscreen
- Dvorak extras and Alt shortcuts preserved alongside
- 200K scrollback, vi-mode copy, copy-on-select
- Ctrl-A S captures pane to ~/logs/, Ctrl-A L toggles live logging
- Status bar shows git branch + working directory
- Pre-built session: code/git/run/logs windows
- Aggressive resize + focus events for multi-device switching
- Toolbar: added Paste (clipboard), Zoom (pane fullscreen), Save (capture)
- All new windows inherit current working directory
- Toolbar split into 2 rows for more buttons without clutter