From 89a7a14111ebf02a6611a9763786a4286bcc40e8 Mon Sep 17 00:00:00 2001 From: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Date: Fri, 18 Sep 2026 18:21:16 -0700 Subject: [PATCH 1/2] Quiet cloud terminal creation tabs --- .../Workspace+CloudManualMirror.swift | 24 ++++++++++++------- .../Workspace+CloudTerminalReservation.swift | 7 +++--- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Sources/Surfaces/Workspace+CloudManualMirror.swift b/Sources/Surfaces/Workspace+CloudManualMirror.swift index 6ee8a773065b..3d0bb1f29e65 100644 --- a/Sources/Surfaces/Workspace+CloudManualMirror.swift +++ b/Sources/Surfaces/Workspace+CloudManualMirror.swift @@ -15,6 +15,10 @@ import GhosttyKit /// (`Workspace+CloudTerminalReservation`). @MainActor extension Workspace { + private static var cloudManualMirrorTabTitle: String { + String(localized: "panel.cloudTerminal.title", defaultValue: "terminal") + } + /// Inserts a manual-mirror terminal in `destination` and returns its native surface. /// /// - Parameters: @@ -113,13 +117,13 @@ extension Workspace { isLoading: Bool ) throws -> UUID { panels[panel.id] = panel - panelTitles[panel.id] = panel.displayTitle + panelTitles[panel.id] = Self.cloudManualMirrorTabTitle guard let tab = bonsplitController.createTab( - title: panel.displayTitle, + title: Self.cloudManualMirrorTabTitle, icon: panel.displayIcon, kind: SurfaceKind.terminal.rawValue, isDirty: panel.isDirty, - isLoading: isLoading, + isLoading: false, isPinned: false, inPane: pane ) else { @@ -148,13 +152,13 @@ extension Workspace { let previousPane = bonsplitController.focusedPaneId let previousTab = previousPane.flatMap { bonsplitController.selectedTab(inPane: $0)?.id } panels[panel.id] = panel - panelTitles[panel.id] = panel.displayTitle + panelTitles[panel.id] = Self.cloudManualMirrorTabTitle let tab = Bonsplit.Tab( - title: panel.displayTitle, + title: Self.cloudManualMirrorTabTitle, icon: panel.displayIcon, kind: SurfaceKind.terminal.rawValue, isDirty: panel.isDirty, - isLoading: isLoading, + isLoading: false, isPinned: false ) bindSurface(tab.id, toPanelId: panel.id) @@ -186,10 +190,12 @@ extension Workspace { return panel.id } - /// Flags or clears the tab-strip spinner of a pane whose terminal is still arriving. + /// Cloud terminal creation stays quiet in the tab strip while the remote pane arrives. + /// Keep this seam for callers that bracket creation/retry state without exposing a + /// transient loading indicator to the user. func setCloudManualMirrorTabLoading(panelID: UUID, _ isLoading: Bool) { - guard let tabID = surfaceIdFromPanelId(panelID) else { return } - bonsplitController.updateTab(tabID, isLoading: isLoading) + _ = panelID + _ = isLoading } /// The live workspace with `id` in any window, or nil once it was retired. diff --git a/Sources/Surfaces/Workspace+CloudTerminalReservation.swift b/Sources/Surfaces/Workspace+CloudTerminalReservation.swift index c4591d7c4838..ea3786b93565 100644 --- a/Sources/Surfaces/Workspace+CloudTerminalReservation.swift +++ b/Sources/Surfaces/Workspace+CloudTerminalReservation.swift @@ -69,7 +69,8 @@ extension Workspace { attachment: attachment ) clearCloudMaterializationFailure(surfaceID: reservation.panelID) - // The tab-strip spinner clears on real attachment, not on adoption. + // The tab strip stays quiet throughout optimistic creation; attachment only + // wires the remote session into the already-visible terminal pane. let panelID = reservation.panelID attachment.onStateChange = { [weak self, weak attachment] state in guard state == .attached || state == .ended else { return } @@ -100,7 +101,6 @@ extension Workspace { /// explain inside it, with Reconnect wired to the same request's retry. func failReservedCloudTerminalPane(_ reservation: CloudTerminalPaneReservation, error: Error) { guard cloudPendingCreations[reservation.panelID] === reservation else { return } - setCloudManualMirrorTabLoading(panelID: reservation.panelID, false) let failure = CloudPaneCreationFailure(machine: reservation.machine, error: error, context: CloudOperationContext.current) setCloudMaterializationFailure( surfaceID: reservation.panelID, @@ -113,7 +113,8 @@ extension Workspace { func restartReservedCloudTerminalPane(_ reservation: CloudTerminalPaneReservation) { guard cloudPendingCreations[reservation.panelID] === reservation else { return } clearCloudMaterializationFailure(surfaceID: reservation.panelID) - setCloudManualMirrorTabLoading(panelID: reservation.panelID, true) + // Keep the reserved tab visually stable while retrying. The pane itself + // reports any failure through its reconnect affordance. } /// Reconnect pressed on a reserved pane's failure card replays the request. From 6ed6b68f159e4da01f0b511a117d3ba4c585c897 Mon Sep 17 00:00:00 2001 From: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Date: Fri, 18 Sep 2026 21:38:24 -0700 Subject: [PATCH 2/2] Reuse localized cloud terminal title and remove obsolete loading callback --- Sources/Surfaces/Workspace+CloudManualMirror.swift | 10 +--------- .../Surfaces/Workspace+CloudTerminalReservation.swift | 9 --------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/Sources/Surfaces/Workspace+CloudManualMirror.swift b/Sources/Surfaces/Workspace+CloudManualMirror.swift index 3d0bb1f29e65..84999ee89b1e 100644 --- a/Sources/Surfaces/Workspace+CloudManualMirror.swift +++ b/Sources/Surfaces/Workspace+CloudManualMirror.swift @@ -16,7 +16,7 @@ import GhosttyKit @MainActor extension Workspace { private static var cloudManualMirrorTabTitle: String { - String(localized: "panel.cloudTerminal.title", defaultValue: "terminal") + String(localized: "cloudTree.terminal.untitled", defaultValue: "terminal") } /// Inserts a manual-mirror terminal in `destination` and returns its native surface. @@ -190,14 +190,6 @@ extension Workspace { return panel.id } - /// Cloud terminal creation stays quiet in the tab strip while the remote pane arrives. - /// Keep this seam for callers that bracket creation/retry state without exposing a - /// transient loading indicator to the user. - func setCloudManualMirrorTabLoading(panelID: UUID, _ isLoading: Bool) { - _ = panelID - _ = isLoading - } - /// The live workspace with `id` in any window, or nil once it was retired. static func liveWorkspace(id: UUID) -> Workspace? { AppDelegate.shared?.tabManagerFor(tabId: id)?.tabs.first { $0.id == id } diff --git a/Sources/Surfaces/Workspace+CloudTerminalReservation.swift b/Sources/Surfaces/Workspace+CloudTerminalReservation.swift index ea3786b93565..f05097e31095 100644 --- a/Sources/Surfaces/Workspace+CloudTerminalReservation.swift +++ b/Sources/Surfaces/Workspace+CloudTerminalReservation.swift @@ -69,15 +69,6 @@ extension Workspace { attachment: attachment ) clearCloudMaterializationFailure(surfaceID: reservation.panelID) - // The tab strip stays quiet throughout optimistic creation; attachment only - // wires the remote session into the already-visible terminal pane. - let panelID = reservation.panelID - attachment.onStateChange = { [weak self, weak attachment] state in - guard state == .attached || state == .ended else { return } - attachment?.onStateChange = nil - self?.setCloudManualMirrorTabLoading(panelID: panelID, false) - } - if attachment.state == .attached { attachment.onStateChange?(.attached) } panel.surface.flushPendingManualSizeReportIfAttached() return (id, panel.id, panel.surface) }