From 1202e9baa206088da0f3a24093bbe0ae93810a9a Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Wed, 7 Oct 2026 03:43:35 +0200 Subject: [PATCH] fix(tiles): "Open group as tiles" keeps the focused session focused With the grid already open, openGroupAsTiles closed it (which sets activeSessionId to null, so re-parking does not snapshot the parked terminal) and only then chose the focus, so the active session was never "in the group" and the group's first session always took focus. The picker's Open chooses before closing. Now both do: the focused session keeps focus when the group holds it, otherwise the group's first session gets it. tile-grid-entry-points covers both cases, with the grid open and closed; the open-grid case failed before this change. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/web/public/tile-grid.js | 4 +++- test/tile-grid-entry-points.test.ts | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/web/public/tile-grid.js b/src/web/public/tile-grid.js index dad1aca4..fd4ac15e 100644 --- a/src/web/public/tile-grid.js +++ b/src/web/public/tile-grid.js @@ -879,13 +879,15 @@ Object.assign(CodemanApp.prototype, { this.showToast?.('This group has no session to show as tiles', 'info'); return false; } + // Before the open grid closes (which drops activeSessionId): the session in + // focus keeps it if the group holds it, as with the picker's Open. + const focus = ids.includes(this.activeSessionId) ? this.activeSessionId : ids[0]; if (this._tilesOwnTerminal()) { this.closeTileGrid({ keepStored: false, reselect: false }); // As selectSession's tile branch: the parked terminal still holds what it // showed before the grid, and re-parking must not snapshot it. this.activeSessionId = null; } - const focus = ids.includes(this.activeSessionId) ? this.activeSessionId : ids[0]; return this.openTileGrid(ids, { focusedId: focus }); }, diff --git a/test/tile-grid-entry-points.test.ts b/test/tile-grid-entry-points.test.ts index 59e08567..fe4b56b4 100644 --- a/test/tile-grid-entry-points.test.ts +++ b/test/tile-grid-entry-points.test.ts @@ -213,6 +213,28 @@ describe('"Open group as tiles"', () => { expect(app._tileGrid.ids).toEqual(['s-c', 's-a']); }); + it('keeps the focused session focused when the group holds it, open grid or not', () => { + for (const gridOpen of [false, true]) { + resetGridHarness(); + const app = makeGridApp(IDS); + withGroups(app); + if (gridOpen) app.openTileGrid(['s-b', 's-a'], { focusedId: 's-a' }); + else app.activeSessionId = 's-a'; + app.openGroupAsTiles('g1'); + expect(app._tileGrid.ids).toEqual(['s-c', 's-a']); + expect(app._tileGrid.focusedId).toBe('s-a'); + expect(app.activeSessionId).toBe('s-a'); + } + }); + + it("focuses the group's first session when it does not hold the focused one", () => { + const app = makeGridApp(IDS); + withGroups(app); + app.openTileGrid(['s-b']); + app.openGroupAsTiles('g1'); + expect(app._tileGrid.focusedId).toBe('s-c'); + }); + it('is not offered where the grid cannot open', () => { const app = makeGridApp(IDS); const actions = withGroups(app);