···401401 let previousTabID = focusedTabID
402402 focusedTabID = tabID
403403404404+ // Sync the tab selection on the owning worktree so that exiting canvas
405405+ // (via toggleCanvas → selectWorktree) will focus the correct tab.
406406+ if let ownerState = states.first(where: { $0.surfaceView(for: tabID) != nil }) {
407407+ ownerState.tabManager.selectTab(tabID)
408408+ terminalManager.canvasFocusedWorktreeID = ownerState.worktreeID
409409+ }
410410+404411 // Unfocus all surfaces in the previous card's split tree
405412 if let previousTabID, previousTabID != tabID,
406413 let previousState = states.first(where: { $0.surfaceView(for: previousTabID) != nil })
···430437431438 private func activateCanvas() {
432439 cleanStaleLayouts()
433433- for state in terminalManager.activeWorktreeStates {
440440+441441+ let activeStates = terminalManager.activeWorktreeStates
442442+443443+ // Auto-focus the card that was active before entering canvas.
444444+ if let selectedID = terminalManager.selectedWorktreeID,
445445+ let state = activeStates.first(where: { $0.worktreeID == selectedID }),
446446+ let tabID = state.tabManager.selectedTabId,
447447+ let surface = state.surfaceView(for: tabID)
448448+ {
449449+ focusCard(tabID, surfaceView: surface, states: activeStates)
450450+ }
451451+452452+ for state in activeStates {
434453 state.setAllSurfacesOccluded()
435454 }
436455 // Un-occlude all surfaces visible on canvas (including split panes)
437437- for state in terminalManager.activeWorktreeStates {
456456+ for state in activeStates {
438457 for tab in state.tabManager.tabs {
439458 for surface in state.splitTree(for: tab.id).leaves() {
440459 surface.setOcclusion(true)
···8383 var automaticallyArchiveMergedWorktrees = false
8484 var moveNotifiedWorktreeToTop = true
8585 var lastFocusedWorktreeID: Worktree.ID?
8686+ var preCanvasWorktreeID: Worktree.ID?
8687 var shouldRestoreLastFocusedWorktree = false
8788 var shouldSelectFirstAfterReload = false
8889 var isRefreshingWorktrees = false
···134135 case repositoriesLoaded([Repository], failures: [LoadFailure], roots: [URL], animated: Bool)
135136 case selectArchivedWorktrees
136137 case selectCanvas
138138+ case toggleCanvas
137139 case setSidebarSelectedWorktreeIDs(Set<Worktree.ID>)
138140 case openRepositories([URL])
139141 case openRepositoriesFinished(
···292294 case worktreeCreated(Worktree)
293295 }
294296297297+ @Dependency(TerminalClient.self) private var terminalClient
295298 @Dependency(AnalyticsClient.self) private var analyticsClient
296299 @Dependency(GitClientDependency.self) private var gitClient
297300 @Dependency(GithubCLIClient.self) private var githubCLI
···546549 return .send(.delegate(.selectedWorktreeChanged(nil)))
547550548551 case .selectCanvas:
552552+ // Remember the current worktree so toggleCanvas can restore it.
553553+ state.preCanvasWorktreeID = state.selectedWorktreeID
549554 state.selection = .canvas
550555 state.sidebarSelectedWorktreeIDs = []
551556 return .none
557557+558558+ case .toggleCanvas:
559559+ if state.isShowingCanvas {
560560+ // Exit canvas: prefer the card focused in canvas, then the worktree
561561+ // we came from, then the first available worktree.
562562+ let targetID =
563563+ terminalClient.canvasFocusedWorktreeID()
564564+ ?? state.preCanvasWorktreeID
565565+ ?? state.lastFocusedWorktreeID
566566+ ?? state.orderedWorktreeRows().first?.id
567567+ guard let targetID else { return .none }
568568+ return .send(.selectWorktree(targetID, focusTerminal: true))
569569+ } else {
570570+ // Enter canvas if there are any open worktrees.
571571+ guard !state.orderedWorktreeRows().isEmpty else { return .none }
572572+ return .send(.selectCanvas)
573573+ }
552574553575 case .setSidebarSelectedWorktreeIDs(let worktreeIDs):
554576 let validWorktreeIDs = Set(state.orderedWorktreeRows().map(\.id))
···1313 private var eventContinuation: AsyncStream<TerminalClient.Event>.Continuation?
1414 private var pendingEvents: [TerminalClient.Event] = []
1515 var selectedWorktreeID: Worktree.ID?
1616+ /// The worktree+tab focused in Canvas, updated by CanvasView on card tap.
1717+ /// Used by toggleCanvas to know which worktree to return to.
1818+ var canvasFocusedWorktreeID: Worktree.ID?
16191720 init(runtime: GhosttyRuntime) {
1821 self.runtime = runtime