@@ -91,39 +91,80 @@ struct UtilityAreaTerminalView: View {
9191 var body : some View {
9292 UtilityAreaTabView ( model: utilityAreaViewModel. tabViewModel) { tabState in
9393 ZStack {
94- // Keeps the sidebar from changing sizes because TerminalEmulatorView takes a µs to load in
95- HStack { Spacer ( ) }
94+ if let selectedTerminal = getSelectedTerminal ( ) ,
95+ let group = utilityAreaViewModel . terminalGroups . first ( where : { $0 . terminals . contains ( selectedTerminal ) } ) {
9696
97- if let selectedTerminal = getSelectedTerminal ( ) {
9897 GeometryReader { geometry in
9998 let containerHeight = geometry. size. height
99+ let containerWidth = geometry. size. width
100100 let totalFontHeight = fontTotalHeight ( nsFont: font) . rounded ( . up)
101101 let constrainedHeight = containerHeight - containerHeight. truncatingRemainder (
102102 dividingBy: totalFontHeight
103103 )
104- VStack ( spacing: 0 ) {
105- Spacer ( minLength: 0 ) . frame ( minHeight: 0 )
106- TerminalEmulatorView (
107- url: selectedTerminal. url,
108- terminalID: selectedTerminal. id,
109- shellType: selectedTerminal. shell,
110- onTitleChange: { [ weak selectedTerminal] newTitle in
111- guard let id = selectedTerminal? . id else { return }
112- // This can be called whenever, even in a view update so it needs to be dispatched.
113- DispatchQueue . main. async { [ weak utilityAreaViewModel] in
114- utilityAreaViewModel? . updateTerminal ( id, title: newTitle)
104+
105+ if group. terminals. count == 1 {
106+ VStack ( spacing: 0 ) {
107+ TerminalEmulatorView (
108+ url: selectedTerminal. url,
109+ terminalID: selectedTerminal. id,
110+ shellType: selectedTerminal. shell,
111+ onTitleChange: { [ weak selectedTerminal] newTitle in
112+ guard let id = selectedTerminal? . id else { return }
113+ DispatchQueue . main. async { [ weak utilityAreaViewModel] in
114+ utilityAreaViewModel? . updateTerminal ( id, title: newTitle)
115+ }
116+ }
117+ )
118+ . frame ( height: max ( 0 , constrainedHeight - 1 ) )
119+ . id ( selectedTerminal. id)
120+ . padding ( . horizontal, 4 )
121+ }
122+ } else {
123+ VStack {
124+ ScrollView ( . horizontal, showsIndicators: true ) {
125+ HStack ( spacing: 0.5 ) {
126+ Rectangle ( )
127+ . frame ( width: 2 )
128+ . foregroundStyle ( . gray. opacity ( 0.2 ) )
129+ ForEach ( group. terminals, id: \. id) { terminal in
130+ TerminalEmulatorView (
131+ url: terminal. url,
132+ terminalID: terminal. id,
133+ shellType: terminal. shell,
134+ onTitleChange: { [ weak terminal] newTitle in
135+ guard let id = terminal? . id else { return }
136+ DispatchQueue . main. async { [ weak utilityAreaViewModel] in
137+ utilityAreaViewModel? . updateTerminal ( id, title: newTitle)
138+ }
139+ }
140+ )
141+ . frame ( height: max ( 0 , constrainedHeight - 1 ) )
142+ . frame ( minWidth: 200 , maxWidth: . infinity)
143+ . id ( terminal. id)
144+ . padding ( . horizontal, 8 )
145+
146+ Rectangle ( )
147+ . frame ( width: 2 )
148+ . foregroundStyle ( . gray. opacity ( 0.2 ) )
149+ }
115150 }
151+ . frame ( minWidth: containerWidth)
152+ . frame ( maxWidth: . infinity, alignment: . leading)
116153 }
117- )
118- . frame ( height: max ( 0 , constrainedHeight - 1 ) )
119- . id ( selectedTerminal. id)
154+
155+ Rectangle ( )
156+ . frame ( height: 2 )
157+ . foregroundStyle ( . gray. opacity ( 0.2 ) )
158+ }
120159 }
121160 }
161+
122162 } else {
123163 CEContentUnavailableView ( " No Selection " )
124164 }
125165 }
126166 . padding ( . horizontal, 10 )
167+ . padding ( . bottom, 10 )
127168 . paneToolbar {
128169 PaneToolbarSection {
129170 UtilityAreaTerminalPicker (
0 commit comments