@@ -47,7 +47,6 @@ const TerminalPage: FC = () => {
47
47
const workspaceName = params . workspace ;
48
48
const xtermRef = useRef < HTMLDivElement > ( null ) ;
49
49
const [ terminal , setTerminal ] = useState < XTerm . Terminal | null > ( null ) ;
50
- const [ fitAddon , setFitAddon ] = useState < FitAddon | null > ( null ) ;
51
50
const [ searchParams ] = useSearchParams ( ) ;
52
51
// The reconnection token is a unique token that identifies
53
52
// a terminal session. It's generated by the client to reduce
@@ -173,7 +172,6 @@ const TerminalPage: FC = () => {
173
172
terminal . loadAddon ( new CanvasAddon ( ) ) ;
174
173
}
175
174
const fitAddon = new FitAddon ( ) ;
176
- setFitAddon ( fitAddon ) ;
177
175
terminal . loadAddon ( fitAddon ) ;
178
176
terminal . loadAddon ( new Unicode11Addon ( ) ) ;
179
177
terminal . unicode . activeVersion = "11" ;
@@ -190,6 +188,16 @@ const TerminalPage: FC = () => {
190
188
} ,
191
189
} ) ;
192
190
} ) ;
191
+
192
+ terminal . open ( xtermRef . current ) ;
193
+
194
+ // We have to fit twice here. It's unknown why, but the first fit will
195
+ // overflow slightly in some scenarios. Applying a second fit resolves this.
196
+ fitAddon . fit ( ) ;
197
+ fitAddon . fit ( ) ;
198
+
199
+ // The initial size will be sent on connection. For future resizes, add a
200
+ // listener to update the backend (this triggers on fit()).
193
201
terminal . onResize ( ( event ) => {
194
202
sendEvent ( {
195
203
type : "WRITE" ,
@@ -199,13 +207,14 @@ const TerminalPage: FC = () => {
199
207
} ,
200
208
} ) ;
201
209
} ) ;
202
- setTerminal ( terminal ) ;
203
- terminal . open ( xtermRef . current ) ;
204
- const listener = ( ) => {
205
- // This will trigger a resize event on the terminal.
206
- fitAddon . fit ( ) ;
207
- } ;
210
+
211
+ // Run a fit every time the window size changes.
212
+ const listener = ( ) => fitAddon . fit ( ) ;
208
213
window . addEventListener ( "resize" , listener ) ;
214
+
215
+ // Terminal is now ready.
216
+ setTerminal ( terminal ) ;
217
+
209
218
return ( ) => {
210
219
window . removeEventListener ( "resize" , listener ) ;
211
220
terminal . dispose ( ) ;
@@ -232,16 +241,10 @@ const TerminalPage: FC = () => {
232
241
233
242
// Apply terminal options based on connection state.
234
243
useEffect ( ( ) => {
235
- if ( ! terminal || ! fitAddon ) {
244
+ if ( ! terminal ) {
236
245
return ;
237
246
}
238
247
239
- // We have to fit twice here. It's unknown why, but
240
- // the first fit will overflow slightly in some
241
- // scenarios. Applying a second fit resolves this.
242
- fitAddon . fit ( ) ;
243
- fitAddon . fit ( ) ;
244
-
245
248
if ( ! isConnected ) {
246
249
// Disable user input when not connected.
247
250
terminal . options = {
@@ -278,7 +281,10 @@ const TerminalPage: FC = () => {
278
281
windowsMode : workspaceAgent ?. operating_system === "windows" ,
279
282
} ;
280
283
281
- // Update the terminal size post-fit.
284
+ // Send the initial terminal size.
285
+ // Ideally this would happen together with the connection via the query
286
+ // parameters on the web socket URL to avoid the extra trip and possible
287
+ // weirdness of starting at a different size and immediately resizing.
282
288
sendEvent ( {
283
289
type : "WRITE" ,
284
290
request : {
@@ -292,7 +298,6 @@ const TerminalPage: FC = () => {
292
298
websocketError ,
293
299
workspaceAgent ,
294
300
terminal ,
295
- fitAddon ,
296
301
isConnected ,
297
302
sendEvent ,
298
303
] ) ;
0 commit comments