Merge PR #129: macOS Option/physical-key session shortcuts + terminal-ui ESC-leak fix

Make Option/Alt session shortcuts work on macOS (physical key codes)
This commit is contained in:
Ark0N
2026-06-14 22:43:08 +02:00
committed by GitHub
5 changed files with 72 additions and 10 deletions
+23 -6
View File
@@ -770,14 +770,31 @@ class CodemanApp {
if (this.attachmentHistoryDrawerOpen) this.closeAttachmentHistory();
}
// Alt+1-9: switch to Codeman session by index
if (e.altKey && !e.ctrlKey && !e.shiftKey && e.key >= '1' && e.key <= '9') {
const idx = parseInt(e.key) - 1;
if (idx < this.sessionOrder.length) {
// Option/Alt session navigation uses physical key CODES, not e.key, so macOS
// keyboard layouts that emit special characters under Option (Option+1 -> ¡,
// Option+[ -> "“") still switch sessions. e.code is the physical key regardless
// of layout. Option+1-9 = switch by index; Option+[ / Option+] = prev / next.
if (e.altKey && !e.ctrlKey && !e.shiftKey) {
const code = e.code || '';
const digitMatch = code.match(/^Digit([1-9])$/);
if (digitMatch) {
const idx = parseInt(digitMatch[1], 10) - 1;
if (idx < this.sessionOrder.length) {
e.preventDefault();
this.selectSession(this.sessionOrder[idx]);
}
return;
}
if (e.code === 'BracketLeft') {
e.preventDefault();
this.selectSession(this.sessionOrder[idx]);
this.prevSession();
return;
}
if (e.code === 'BracketRight') {
e.preventDefault();
this.nextSession();
return;
}
return;
}
// Match against shortcut table
+2 -1
View File
@@ -508,7 +508,8 @@
<div class="shortcuts-grid">
<div><kbd>Ctrl</kbd>+<kbd>W</kbd></div><div>Close Session</div>
<div><kbd>Ctrl</kbd>+<kbd>Tab</kbd></div><div>Next Session</div>
<div><kbd>Alt</kbd>+<kbd>1-9</kbd></div><div>Switch to Tab N</div>
<div><kbd>Alt/Option</kbd>+<kbd>[</kbd> / <kbd>Alt/Option</kbd>+<kbd>]</kbd></div><div>Previous / Next Session</div>
<div><kbd>Alt/Option</kbd>+<kbd>1-9</kbd></div><div>Switch to Tab N</div>
<div><kbd>Ctrl</kbd>+<kbd>L</kbd></div><div>Clear Terminal</div>
<div><kbd>Ctrl</kbd>+<kbd>+</kbd></div><div>Increase Font</div>
<div><kbd>Ctrl</kbd>+<kbd>-</kbd></div><div>Decrease Font</div>
+8 -2
View File
@@ -114,8 +114,14 @@ Object.assign(CodemanApp.prototype, {
this.terminal.attachCustomKeyEventHandler((ev) => {
if (ev.isComposing || ev.keyCode === 229) return false;
// Let Alt+digit pass through to browser (tab switching)
if (ev.altKey && ev.key >= '0' && ev.key <= '9') return false;
// Let the app's Alt/Option session-nav shortcuts reach the document keydown handler
// (app.js switches tabs by PHYSICAL e.code) instead of xterm injecting ESC<char> into
// the PTY. Mirror app.js's gate exactly — same physical codes + modifier guard — so
// macOS Option layouts (Option+1 -> "¡", Option+[ -> "“") are suppressed here too and
// don't leak an escape sequence into the focused terminal on every tab switch.
if (ev.altKey && !ev.ctrlKey && !ev.shiftKey && /^(Digit[1-9]|BracketLeft|BracketRight)$/.test(ev.code || '')) {
return false;
}
// Ctrl+V / Cmd+V: intercept before xterm sends ^V to PTY.
// Route through our paste trap which handles both images and text.