From 6cbaf3f7b65c0f22dc4cd46ae860e0f4d143bbb1 Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Wed, 7 Oct 2026 03:46:37 +0200 Subject: [PATCH] refactor(tiles): Ctrl+Tab and Alt+[ / ] cycle tiles through one helper nextSession and prevSession each carried the same grid branch (cycleTile from the active session, a human selection, skip the tab walk). It is now _cycleTileFocus(delta) in tile-grid.js, next to the other focus moves; both call it optionally, so a page or harness without tile-grid.js walks the tabs as before. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/web/public/app.js | 14 +++----------- src/web/public/tile-grid.js | 13 +++++++++++++ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/web/public/app.js b/src/web/public/app.js index 8c083d61..0c8be117 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -9063,12 +9063,8 @@ class CodemanApp { } nextSession() { - // With the tile grid open, Ctrl+Tab and Alt+] cycle through the tiles. - if (this._tileGrid?.open) { - const id = window.CodemanTileGrid.cycleTile(this._tileGrid.ids, this.activeSessionId, 1); - if (id) this.selectSession(id); - return; - } + // With the tile grid open, Ctrl+Tab and Alt+[ / Alt+] cycle through the tiles. + if (this._cycleTileFocus?.(1)) return; if (this.sessionOrder.length <= 1) return; const currentIndex = this.sessionOrder.indexOf(this.activeSessionId); @@ -9077,11 +9073,7 @@ class CodemanApp { } prevSession() { - if (this._tileGrid?.open) { - const id = window.CodemanTileGrid.cycleTile(this._tileGrid.ids, this.activeSessionId, -1); - if (id) this.selectSession(id); - return; - } + if (this._cycleTileFocus?.(-1)) return; if (this.sessionOrder.length <= 1) return; const currentIndex = this.sessionOrder.indexOf(this.activeSessionId); diff --git a/src/web/public/tile-grid.js b/src/web/public/tile-grid.js index 978a2170..13857ec1 100644 --- a/src/web/public/tile-grid.js +++ b/src/web/public/tile-grid.js @@ -608,6 +608,19 @@ Object.assign(CodemanApp.prototype, { if (id) this.selectSession(id); }, + /** + * Ctrl+Tab / Alt+] (delta 1) and Alt+[ (delta -1) while the grid is open: a + * human selection of the next tile in reading order, wrapping. Returns + * whether the grid took the chord (it is open), so the tab walk is skipped. + */ + _cycleTileFocus(delta) { + const grid = this._tileGrid; + if (!grid?.open) return false; + const id = window.CodemanTileGrid.cycleTile(grid.ids, this.activeSessionId, delta); + if (id) this.selectSession(id); + return true; + }, + /** Removes the focused tile (the session keeps running); a neighbour takes focus. */ removeFocusedTile() { const grid = this._tileGrid;