Skip to content

Commit ede877f

Browse files
committed
fix(desktop): keep terminal close ownership with the window showing the panel
1 parent 8c276f8 commit ede877f

2 files changed

Lines changed: 12 additions & 3 deletions

File tree

apps/desktop/src/main/terminal/index.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -635,11 +635,15 @@ export class TerminalService {
635635

636636
/**
637637
* Whether one renderer may close a tab. The strip that lists shells sits
638-
* outside the terminal panel, so the shell need not be on screen; IPC has
639-
* already checked that the renderer is on the shell's chat.
638+
* outside the terminal panel, so a renderer on the chat may close a shell
639+
* nobody is displaying; while a window does display the panel, only that
640+
* window may close, so a second window on the same chat cannot end a shell
641+
* someone is using.
640642
*/
641643
acceptsUserClose(owner: WebContents, terminalId: string): boolean {
642-
return !owner.isDestroyed() && this.sessions.has(terminalId)
644+
if (owner.isDestroyed() || !this.sessions.has(terminalId)) return false
645+
const shown = this.visibleOwner && !this.visibleOwner.isDestroyed() ? this.visibleOwner : null
646+
return shown === null || shown === owner
643647
}
644648

645649
/** Drops the claim and unsubscribes from the owner's lifecycle. */

apps/desktop/src/main/terminal/registry.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,13 +631,18 @@ describe('TerminalRegistry', () => {
631631
removeListener: vi.fn(),
632632
}
633633
const gone = { ...owner, isDestroyed: () => true }
634+
const other = { ...owner, once: vi.fn(), on: vi.fn(), removeListener: vi.fn() }
634635

635636
// The strip lives outside the panel, so a hidden shell is still closable.
636637
expect(terminals.closeUserTerminal('chat-B', '1', owner as never)).toEqual({
637638
tabs: [],
638639
activeTerminalId: null,
639640
})
640641
expect(terminals.closeUserTerminal('chat-A', first, gone as never).tabs).toHaveLength(2)
642+
// While another window displays the panel, only that window may close.
643+
terminals.setPanelVisible('chat-A', true, other as never)
644+
expect(terminals.closeUserTerminal('chat-A', first, owner as never).tabs).toHaveLength(2)
645+
terminals.setPanelVisible('chat-A', false, other as never)
641646

642647
const closed = terminals.closeUserTerminal('chat-A', first, owner as never)
643648
expect(closed.tabs).toHaveLength(1)

0 commit comments

Comments
 (0)