Fix mobile keybar Ctrl/Shift modifiers not applying to keyboard input

- Apply Ctrl modifier to letters typed via mobile keyboard (e.g., Ctrl+D sends 0x04)
- Apply Shift modifier to uppercase letters typed via mobile keyboard
- Apply modifiers to arrow keys and Tab in keydown handler
- Deactivate modifiers after key is sent

Bump to v0.6.3
This commit is contained in:
GitHub Copilot
2026-01-28 08:36:41 +00:00
parent 0b6288494e
commit 714a5c705c
3 changed files with 44 additions and 16 deletions
File diff suppressed because one or more lines are too long
+38 -10
View File
@@ -497,38 +497,66 @@ class WebTerminal {
textarea.addEventListener("input", () => {
const value = textarea.value;
if (value) {
this.send(["stdin", value]);
let toSend = value;
// Apply Shift modifier (uppercase letters)
if (this.shiftActive && value.length === 1) {
toSend = value.toUpperCase();
}
// Apply Ctrl modifier if active (convert letters to control codes)
if (this.ctrlActive && value.length === 1) {
const code = toSend.toUpperCase().charCodeAt(0);
if (code >= 65 && code <= 90) {
toSend = String.fromCharCode(code - 64); // Ctrl+A = 0x01, Ctrl+D = 0x04, etc.
}
}
this.send(["stdin", toSend]);
textarea.value = "";
this.deactivateModifiers();
}
});
// Handle special navigation keys via keydown (not covered by beforeinput)
textarea.addEventListener("keydown", (e) => {
let seq: string | null = null;
let deactivate = false;
switch (e.key) {
case "Escape":
seq = "\x1b";
deactivate = true;
break;
case "ArrowUp":
seq = "\x1b[A";
break;
case "ArrowDown":
seq = "\x1b[B";
break;
case "ArrowRight":
seq = "\x1b[C";
break;
case "ArrowLeft":
seq = "\x1b[D";
case "ArrowLeft": {
const dir = e.key === "ArrowUp" ? "A" : e.key === "ArrowDown" ? "B" : e.key === "ArrowRight" ? "C" : "D";
if (this.ctrlActive && this.shiftActive) {
seq = `\x1b[1;6${dir}`;
} else if (this.ctrlActive) {
seq = `\x1b[1;5${dir}`;
} else if (this.shiftActive) {
seq = `\x1b[1;2${dir}`;
} else {
seq = `\x1b[${dir}`;
}
deactivate = true;
break;
}
case "Tab":
seq = "\t";
if (this.shiftActive) {
seq = "\x1b[Z"; // Back-tab
} else {
seq = "\t";
}
e.preventDefault();
deactivate = true;
break;
}
if (seq) {
e.preventDefault();
this.send(["stdin", seq]);
if (deactivate) {
this.deactivateModifiers();
}
}
});