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.
2.1 KiB
Mobile Autocomplete Fix
Date: 2026-03-28
File changed: static/toolbar.js
The Problem
On mobile, typing in the terminal caused glitchy re-typing of characters. For example, typing git sta would suddenly delete and re-insert text, producing garbled input like git stagit sta.
Root Cause
xterm.js captures keyboard input through a hidden <textarea> element (class: .xterm-helper-textarea). Mobile browsers (iOS Safari, Android Chrome/Gboard) treat this like any other text field and activate autocomplete, autocorrect, autocapitalize, and spellcheck.
When the keyboard's autocomplete activates, it:
- Deletes the characters you already typed (sends backspace events)
- Re-inserts the "corrected" or "completed" word
xterm.js interprets this as real input — backspaces erase terminal content, then the replacement text gets typed out. The result is duplicated or garbled text visible on screen.
The Fix
A disableMobileAutocomplete() function finds xterm's hidden textarea and sets four attributes that suppress mobile keyboard text assistance:
ta.setAttribute('autocomplete','off'); // Chrome, general
ta.setAttribute('autocorrect','off'); // Safari
ta.setAttribute('autocapitalize','off'); // iOS (prevents auto-capitalizing first letter)
ta.setAttribute('spellcheck','false'); // All browsers (removes red underlines + suggestions)
All four are needed because different browsers respect different attributes.
Why a MutationObserver
The hidden textarea doesn't exist at page load — xterm.js creates it dynamically when the terminal mounts. The existing MutationObserver (which already handles mobile toolbar resizing) now also calls disableMobileAutocomplete() on every DOM change. A data-acOff guard ensures the attributes are only set once.
Nuclear Option (if still broken)
Some aggressive keyboards (Samsung Keyboard, certain Gboard versions) may ignore these attributes entirely. If that happens, setting inputMode="none" on the textarea would fully disable the soft keyboard — but that requires adding a separate on-screen keyboard or toggle, since users would lose the ability to type normally.