Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Sources/Workspace+Persistence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ extension Workspace {
private func applySessionPanelMetadata(_ snapshot: SessionPanelSnapshot, toPanelId panelId: UUID) {
if let title = snapshot.title?.trimmingCharacters(in: .whitespacesAndNewlines), !title.isEmpty {
panelTitles[panelId] = title
panelsWithLiveTitle.insert(panelId)
}

setPanelCustomTitle(panelId: panelId, title: snapshot.customTitle)
Expand Down
7 changes: 6 additions & 1 deletion Sources/Workspace+SidebarTelemetry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ extension Workspace {
panelTitles[panelId] = trimmed
didMutate = true
}
panelsWithLiveTitle.insert(panelId)

// Update bonsplit tab title only when this panel's title changed.
if didMutate,
Expand Down Expand Up @@ -251,10 +252,13 @@ extension Workspace {

/// Re-derive the workspace title from the focused panel's last known
/// title. Called on pane-focus changes so the sidebar follows the active
/// pane without waiting for it to emit a new OSC title.
/// pane without waiting for it to emit a new OSC title. Only titles that
/// arrived through a real update qualify; creation-time displayTitle
/// seeds must not overwrite the workspace's default title.
func refreshWorkspaceTitleFromFocusedPanel() {
guard customTitle == nil,
let panelId = focusedPanelId,
panelsWithLiveTitle.contains(panelId),
let stored = panelTitles[panelId] else { return }
if title != stored { title = stored }
if processTitle != stored { processTitle = stored }
Expand All @@ -263,6 +267,7 @@ extension Workspace {
func pruneSurfaceMetadata(validSurfaceIds: Set<UUID>) {
panelDirectories = panelDirectories.filter { validSurfaceIds.contains($0.key) }
panelTitles = panelTitles.filter { validSurfaceIds.contains($0.key) }
panelsWithLiveTitle = panelsWithLiveTitle.filter { validSurfaceIds.contains($0) }
panelCustomTitles = panelCustomTitles.filter { validSurfaceIds.contains($0.key) }
pinnedPanelIds = pinnedPanelIds.filter { validSurfaceIds.contains($0) }
manualUnreadPanelIds = manualUnreadPanelIds.filter { validSurfaceIds.contains($0) }
Expand Down
4 changes: 4 additions & 0 deletions Sources/Workspace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ final class Workspace: Identifiable, ObservableObject {
/// Published directory for each panel
@Published var panelDirectories: [UUID: String] = [:]
@Published var panelTitles: [UUID: String] = [:]
/// Panels whose `panelTitles` entry came from a real title update (OSC or
/// session restore), as opposed to the displayTitle placeholder seeded at
/// panel creation. Only these titles may be promoted to the workspace title.
var panelsWithLiveTitle: Set<UUID> = []
@Published var panelCustomTitles: [UUID: String] = [:]
@Published var pinnedPanelIds: Set<UUID> = []
@Published var manualUnreadPanelIds: Set<UUID> = []
Expand Down
Loading