diff --git a/ui/src/app/app.ts b/ui/src/app/app.ts index 577baa9..b1dec90 100644 --- a/ui/src/app/app.ts +++ b/ui/src/app/app.ts @@ -120,6 +120,13 @@ export class App { } else if (event.ctrlKey && event.key === 'Tab') { event.preventDefault(); this.panels.cycleWorkspace(event.shiftKey ? -1 : 1); + } else if (mod && !event.shiftKey && !event.altKey) { + // ⌘1–⌘8 jump to that tab, ⌘9 to the last (Ctrl+digit elsewhere), like + // Firefox. Matched on event.code so the digit row works on any layout. + const digit = /^(?:Digit|Numpad)([1-9])$/.exec(event.code)?.[1]; + if (!digit) return; + event.preventDefault(); + this.panels.goToWorkspace(digit === '9' ? -1 : Number(digit) - 1); } } diff --git a/ui/src/app/panels.service.ts b/ui/src/app/panels.service.ts index 26e3854..eab0f9f 100644 --- a/ui/src/app/panels.service.ts +++ b/ui/src/app/panels.service.ts @@ -326,6 +326,12 @@ export class PanelsService { this.setActiveWorkspace(next.id); } + /** Jump to a tab by visual position; negative counts from the end (⌘9 = last). */ + goToWorkspace(index: number): void { + const target = this.workspaces().at(index); + if (target) this.setActiveWorkspace(target.id); + } + /** Tab label: "Local" for a local/local pair, else the remote titles. */ workspaceName(workspace: Workspace): string { const remoteTitles = [workspace.left, workspace.right]