test(runtime): align handshake mocks and helpers
- commit
- 38150141df273717c36f21efbc480b9bbf3fc2ff
- author
- brice · · 2026-07-13 21:40 UTC
- parent
- aaad006
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
4 files · +35 -54
M internal/usecase/client/client.go +9 -9
| @@ -366,10 +366,10 @@ type attachResult struct { | |||
| 366 | 366 | // boundedPreWelcome runs one blocking handshake operation. Transport methods | |
| 367 | 367 | // do not accept a context, so cancellation and expiry close this attempt's | |
| 368 | 368 | // transport to interrupt the call, then wait for its goroutine to exit. | |
| 369 | - | func boundedPreWelcome(ctx context.Context, clk ports.Clock, transport ports.Transport, operation func() error) (error, bool) { | |
| 369 | + | func boundedPreWelcome(ctx context.Context, clk ports.Clock, transport ports.Transport, operation func() error) (bool, error) { | |
| 370 | 370 | if err := ctx.Err(); err != nil { | |
| 371 | 371 | _ = transport.Close() | |
| 372 | - | return err, true | |
| 372 | + | return true, err | |
| 373 | 373 | } | |
| 374 | 374 | ||
| 375 | 375 | timer := clk.NewTimer(preWelcomeTimeout) | |
| @@ -384,23 +384,23 @@ func boundedPreWelcome(ctx context.Context, clk ports.Clock, transport ports.Tra | |||
| 384 | 384 | // already returned by the time we observe it here. | |
| 385 | 385 | if ctx.Err() != nil { | |
| 386 | 386 | _ = transport.Close() | |
| 387 | - | return ctx.Err(), true | |
| 387 | + | return true, ctx.Err() | |
| 388 | 388 | } | |
| 389 | 389 | select { | |
| 390 | 390 | case <-timer.C(): | |
| 391 | 391 | _ = transport.Close() | |
| 392 | - | return context.DeadlineExceeded, true | |
| 392 | + | return true, context.DeadlineExceeded | |
| 393 | 393 | default: | |
| 394 | - | return err, false | |
| 394 | + | return false, err | |
| 395 | 395 | } | |
| 396 | 396 | case <-ctx.Done(): | |
| 397 | 397 | _ = transport.Close() | |
| 398 | 398 | <-completed | |
| 399 | - | return ctx.Err(), true | |
| 399 | + | return true, ctx.Err() | |
| 400 | 400 | case <-timer.C(): | |
| 401 | 401 | _ = transport.Close() | |
| 402 | 402 | <-completed | |
| 403 | - | return context.DeadlineExceeded, true | |
| 403 | + | return true, context.DeadlineExceeded | |
| 404 | 404 | } | |
| 405 | 405 | } | |
| 406 | 406 | ||
| @@ -451,7 +451,7 @@ func attachOnce(ctx context.Context, transport ports.Transport, term ports.Termi | |||
| 451 | 451 | TrueColor: trueColor, | |
| 452 | 452 | MaxOutputInFlight: requestedOutputWindow(transport), | |
| 453 | 453 | } | |
| 454 | - | if err, closed := boundedPreWelcome(ctx, clk, transport, func() error { | |
| 454 | + | if closed, err := boundedPreWelcome(ctx, clk, transport, func() error { | |
| 455 | 455 | return transport.Send(ports.Frame{Type: ports.MsgHello, Payload: ports.MarshalHello(hello)}) | |
| 456 | 456 | }); err != nil { | |
| 457 | 457 | return attachResult{transportClosed: closed, err: fmt.Errorf("vev: sending hello: %w", err)} | |
| @@ -460,7 +460,7 @@ func attachOnce(ctx context.Context, transport ports.Transport, term ports.Termi | |||
| 460 | 460 | ||
| 461 | 461 | // 2. Await Welcome or a typed rejection. | |
| 462 | 462 | var reply ports.Frame | |
| 463 | - | err, closed := boundedPreWelcome(ctx, clk, transport, func() error { | |
| 463 | + | closed, err := boundedPreWelcome(ctx, clk, transport, func() error { | |
| 464 | 464 | var recvErr error | |
| 465 | 465 | reply, recvErr = transport.Recv() | |
| 466 | 466 | return recvErr | |
| @@ -366,10 +366,10 @@ type attachResult struct { | |||||
| 366 | // boundedPreWelcome runs one blocking handshake operation. Transport methods | 366 | // boundedPreWelcome runs one blocking handshake operation. Transport methods | ||
| 367 | // do not accept a context, so cancellation and expiry close this attempt's | 367 | // do not accept a context, so cancellation and expiry close this attempt's | ||
| 368 | // transport to interrupt the call, then wait for its goroutine to exit. | 368 | // transport to interrupt the call, then wait for its goroutine to exit. | ||
| 369 | - | func boundedPreWelcome(ctx context.Context, clk ports.Clock, transport ports.Transport, operation func() error) (error, bool) { | 369 | + | func boundedPreWelcome(ctx context.Context, clk ports.Clock, transport ports.Transport, operation func() error) (bool, error) { |
| 370 | if err := ctx.Err(); err != nil { | 370 | if err := ctx.Err(); err != nil { | ||
| 371 | _ = transport.Close() | 371 | _ = transport.Close() | ||
| 372 | - | return err, true | 372 | + | return true, err |
| 373 | } | 373 | } | ||
| 374 | 374 | ||||
| 375 | timer := clk.NewTimer(preWelcomeTimeout) | 375 | timer := clk.NewTimer(preWelcomeTimeout) | ||
| @@ -384,23 +384,23 @@ func boundedPreWelcome(ctx context.Context, clk ports.Clock, transport ports.Tra | |||||
| 384 | // already returned by the time we observe it here. | 384 | // already returned by the time we observe it here. | ||
| 385 | if ctx.Err() != nil { | 385 | if ctx.Err() != nil { | ||
| 386 | _ = transport.Close() | 386 | _ = transport.Close() | ||
| 387 | - | return ctx.Err(), true | 387 | + | return true, ctx.Err() |
| 388 | } | 388 | } | ||
| 389 | select { | 389 | select { | ||
| 390 | case <-timer.C(): | 390 | case <-timer.C(): | ||
| 391 | _ = transport.Close() | 391 | _ = transport.Close() | ||
| 392 | - | return context.DeadlineExceeded, true | 392 | + | return true, context.DeadlineExceeded |
| 393 | default: | 393 | default: | ||
| 394 | - | return err, false | 394 | + | return false, err |
| 395 | } | 395 | } | ||
| 396 | case <-ctx.Done(): | 396 | case <-ctx.Done(): | ||
| 397 | _ = transport.Close() | 397 | _ = transport.Close() | ||
| 398 | <-completed | 398 | <-completed | ||
| 399 | - | return ctx.Err(), true | 399 | + | return true, ctx.Err() |
| 400 | case <-timer.C(): | 400 | case <-timer.C(): | ||
| 401 | _ = transport.Close() | 401 | _ = transport.Close() | ||
| 402 | <-completed | 402 | <-completed | ||
| 403 | - | return context.DeadlineExceeded, true | 403 | + | return true, context.DeadlineExceeded |
| 404 | } | 404 | } | ||
| 405 | } | 405 | } | ||
| 406 | 406 | ||||
| @@ -451,7 +451,7 @@ func attachOnce(ctx context.Context, transport ports.Transport, term ports.Termi | |||||
| 451 | TrueColor: trueColor, | 451 | TrueColor: trueColor, | ||
| 452 | MaxOutputInFlight: requestedOutputWindow(transport), | 452 | MaxOutputInFlight: requestedOutputWindow(transport), | ||
| 453 | } | 453 | } | ||
| 454 | - | if err, closed := boundedPreWelcome(ctx, clk, transport, func() error { | 454 | + | if closed, err := boundedPreWelcome(ctx, clk, transport, func() error { |
| 455 | return transport.Send(ports.Frame{Type: ports.MsgHello, Payload: ports.MarshalHello(hello)}) | 455 | return transport.Send(ports.Frame{Type: ports.MsgHello, Payload: ports.MarshalHello(hello)}) | ||
| 456 | }); err != nil { | 456 | }); err != nil { | ||
| 457 | return attachResult{transportClosed: closed, err: fmt.Errorf("vev: sending hello: %w", err)} | 457 | return attachResult{transportClosed: closed, err: fmt.Errorf("vev: sending hello: %w", err)} | ||
| @@ -460,7 +460,7 @@ func attachOnce(ctx context.Context, transport ports.Transport, term ports.Termi | |||||
| 460 | 460 | ||||
| 461 | // 2. Await Welcome or a typed rejection. | 461 | // 2. Await Welcome or a typed rejection. | ||
| 462 | var reply ports.Frame | 462 | var reply ports.Frame | ||
| 463 | - | err, closed := boundedPreWelcome(ctx, clk, transport, func() error { | 463 | + | closed, err := boundedPreWelcome(ctx, clk, transport, func() error { |
| 464 | var recvErr error | 464 | var recvErr error | ||
| 465 | reply, recvErr = transport.Recv() | 465 | reply, recvErr = transport.Recv() | ||
| 466 | return recvErr | 466 | return recvErr | ||
M internal/usecase/client/client_test.go +23 -38
| @@ -155,41 +155,23 @@ func isType(typ ports.MsgType) any { | |||
| 155 | 155 | return mock.MatchedBy(func(f ports.Frame) bool { return f.Type == typ }) | |
| 156 | 156 | } | |
| 157 | 157 | ||
| 158 | - | // handshakeClock exposes its timer so the pre-Welcome deadline can be tested | |
| 159 | - | // without waiting on wall time. | |
| 160 | - | type handshakeClock struct { | |
| 161 | - | mu sync.Mutex | |
| 162 | - | duration time.Duration | |
| 163 | - | created chan *handshakeTimer | |
| 164 | - | } | |
| 165 | - | ||
| 166 | - | type handshakeTimer struct{ ch chan time.Time } | |
| 167 | - | ||
| 168 | - | func newHandshakeClock() *handshakeClock { | |
| 169 | - | return &handshakeClock{created: make(chan *handshakeTimer, 2)} | |
| 170 | - | } | |
| 171 | - | ||
| 172 | - | func (c *handshakeClock) Now() time.Time { return time.Time{} } | |
| 158 | + | const testPreWelcomeTimeout = 15 * time.Second | |
| 173 | 159 | ||
| 174 | - | func (c *handshakeClock) NewTimer(d time.Duration) ports.Timer { | |
| 175 | - | c.mu.Lock() | |
| 176 | - | c.duration = d | |
| 177 | - | c.mu.Unlock() | |
| 178 | - | t := &handshakeTimer{ch: make(chan time.Time, 1)} | |
| 179 | - | c.created <- t | |
| 180 | - | return t | |
| 181 | - | } | |
| 182 | - | ||
| 183 | - | func (c *handshakeClock) Duration() time.Duration { | |
| 184 | - | c.mu.Lock() | |
| 185 | - | defer c.mu.Unlock() | |
| 186 | - | return c.duration | |
| 160 | + | func newHandshakeClock(t *testing.T, timerCount int) (*portsmocks.MockClock, <-chan chan time.Time) { | |
| 161 | + | t.Helper() | |
| 162 | + | created := make(chan chan time.Time, timerCount) | |
| 163 | + | clk := portsmocks.NewMockClock(t) | |
| 164 | + | clk.EXPECT().NewTimer(testPreWelcomeTimeout).RunAndReturn(func(time.Duration) ports.Timer { | |
| 165 | + | timerC := make(chan time.Time, 1) | |
| 166 | + | timer := portsmocks.NewMockTimer(t) | |
| 167 | + | timer.EXPECT().C().Return((<-chan time.Time)(timerC)).Maybe() | |
| 168 | + | timer.EXPECT().Stop().Return(true).Once() | |
| 169 | + | created <- timerC | |
| 170 | + | return timer | |
| 171 | + | }).Times(timerCount) | |
| 172 | + | return clk, created | |
| 187 | 173 | } | |
| 188 | 174 | ||
| 189 | - | func (t *handshakeTimer) C() <-chan time.Time { return t.ch } | |
| 190 | - | func (t *handshakeTimer) Reset(time.Duration) bool { return false } | |
| 191 | - | func (t *handshakeTimer) Stop() bool { return true } | |
| 192 | - | ||
| 193 | 175 | func TestRunBoundsPreWelcomeOperations(t *testing.T) { | |
| 194 | 176 | tests := []struct { | |
| 195 | 177 | name string | |
| @@ -207,7 +189,11 @@ func TestRunBoundsPreWelcomeOperations(t *testing.T) { | |||
| 207 | 189 | t.Run(tt.name, func(t *testing.T) { | |
| 208 | 190 | ctx, cancel := context.WithCancel(context.Background()) | |
| 209 | 191 | defer cancel() | |
| 210 | - | clk := newHandshakeClock() | |
| 192 | + | timerCount := 1 | |
| 193 | + | if tt.phase == "recv" { | |
| 194 | + | timerCount = 2 | |
| 195 | + | } | |
| 196 | + | clk, createdTimers := newHandshakeClock(t, timerCount) | |
| 211 | 197 | ||
| 212 | 198 | term := portsmocks.NewMockTerminal(t) | |
| 213 | 199 | term.EXPECT().Size().Return(domain.Size{Cols: 80, Rows: 24}, nil).Once() | |
| @@ -243,13 +229,12 @@ func TestRunBoundsPreWelcomeOperations(t *testing.T) { | |||
| 243 | 229 | errCh <- client.Run(ctx, dialer, term, clk, ports.IntentAttach, "main", false, nil, slog.New(slog.DiscardHandler)) | |
| 244 | 230 | }() | |
| 245 | 231 | ||
| 246 | - | var timer *handshakeTimer | |
| 232 | + | var timerC chan time.Time | |
| 247 | 233 | select { | |
| 248 | - | case timer = <-clk.created: | |
| 234 | + | case timerC = <-createdTimers: | |
| 249 | 235 | case <-time.After(time.Second): | |
| 250 | 236 | t.Fatal("pre-Welcome timer was not created") | |
| 251 | 237 | } | |
| 252 | - | require.Equal(t, 15*time.Second, clk.Duration()) | |
| 253 | 238 | select { | |
| 254 | 239 | case <-started: | |
| 255 | 240 | case <-time.After(time.Second): | |
| @@ -257,7 +242,7 @@ func TestRunBoundsPreWelcomeOperations(t *testing.T) { | |||
| 257 | 242 | } | |
| 258 | 243 | if tt.phase == "recv" { | |
| 259 | 244 | select { | |
| 260 | - | case timer = <-clk.created: | |
| 245 | + | case timerC = <-createdTimers: | |
| 261 | 246 | case <-time.After(time.Second): | |
| 262 | 247 | t.Fatal("Welcome timer was not created") | |
| 263 | 248 | } | |
| @@ -266,7 +251,7 @@ func TestRunBoundsPreWelcomeOperations(t *testing.T) { | |||
| 266 | 251 | if tt.end == "cancel" { | |
| 267 | 252 | cancel() | |
| 268 | 253 | } else { | |
| 269 | - | timer.ch <- time.Time{} | |
| 254 | + | timerC <- time.Time{} | |
| 270 | 255 | } | |
| 271 | 256 | ||
| 272 | 257 | select { | |
| @@ -155,41 +155,23 @@ func isType(typ ports.MsgType) any { | |||||
| 155 | return mock.MatchedBy(func(f ports.Frame) bool { return f.Type == typ }) | 155 | return mock.MatchedBy(func(f ports.Frame) bool { return f.Type == typ }) | ||
| 156 | } | 156 | } | ||
| 157 | 157 | ||||
| 158 | - | // handshakeClock exposes its timer so the pre-Welcome deadline can be tested | 158 | + | const testPreWelcomeTimeout = 15 * time.Second |
| 159 | - | // without waiting on wall time. | |||
| 160 | - | type handshakeClock struct { | |||
| 161 | - | mu sync.Mutex | |||
| 162 | - | duration time.Duration | |||
| 163 | - | created chan *handshakeTimer | |||
| 164 | - | } | |||
| 165 | - | ||||
| 166 | - | type handshakeTimer struct{ ch chan time.Time } | |||
| 167 | - | ||||
| 168 | - | func newHandshakeClock() *handshakeClock { | |||
| 169 | - | return &handshakeClock{created: make(chan *handshakeTimer, 2)} | |||
| 170 | - | } | |||
| 171 | - | ||||
| 172 | - | func (c *handshakeClock) Now() time.Time { return time.Time{} } | |||
| 173 | 159 | ||||
| 174 | - | func (c *handshakeClock) NewTimer(d time.Duration) ports.Timer { | 160 | + | func newHandshakeClock(t *testing.T, timerCount int) (*portsmocks.MockClock, <-chan chan time.Time) { |
| 175 | - | c.mu.Lock() | 161 | + | t.Helper() |
| 176 | - | c.duration = d | 162 | + | created := make(chan chan time.Time, timerCount) |
| 177 | - | c.mu.Unlock() | 163 | + | clk := portsmocks.NewMockClock(t) |
| 178 | - | t := &handshakeTimer{ch: make(chan time.Time, 1)} | 164 | + | clk.EXPECT().NewTimer(testPreWelcomeTimeout).RunAndReturn(func(time.Duration) ports.Timer { |
| 179 | - | c.created <- t | 165 | + | timerC := make(chan time.Time, 1) |
| 180 | - | return t | 166 | + | timer := portsmocks.NewMockTimer(t) |
| 181 | - | } | 167 | + | timer.EXPECT().C().Return((<-chan time.Time)(timerC)).Maybe() |
| 182 | - | 168 | + | timer.EXPECT().Stop().Return(true).Once() | |
| 183 | - | func (c *handshakeClock) Duration() time.Duration { | 169 | + | created <- timerC |
| 184 | - | c.mu.Lock() | 170 | + | return timer |
| 185 | - | defer c.mu.Unlock() | 171 | + | }).Times(timerCount) |
| 186 | - | return c.duration | 172 | + | return clk, created |
| 187 | } | 173 | } | ||
| 188 | 174 | ||||
| 189 | - | func (t *handshakeTimer) C() <-chan time.Time { return t.ch } | |||
| 190 | - | func (t *handshakeTimer) Reset(time.Duration) bool { return false } | |||
| 191 | - | func (t *handshakeTimer) Stop() bool { return true } | |||
| 192 | - | ||||
| 193 | func TestRunBoundsPreWelcomeOperations(t *testing.T) { | 175 | func TestRunBoundsPreWelcomeOperations(t *testing.T) { | ||
| 194 | tests := []struct { | 176 | tests := []struct { | ||
| 195 | name string | 177 | name string | ||
| @@ -207,7 +189,11 @@ func TestRunBoundsPreWelcomeOperations(t *testing.T) { | |||||
| 207 | t.Run(tt.name, func(t *testing.T) { | 189 | t.Run(tt.name, func(t *testing.T) { | ||
| 208 | ctx, cancel := context.WithCancel(context.Background()) | 190 | ctx, cancel := context.WithCancel(context.Background()) | ||
| 209 | defer cancel() | 191 | defer cancel() | ||
| 210 | - | clk := newHandshakeClock() | 192 | + | timerCount := 1 |
| 193 | + | if tt.phase == "recv" { | |||
| 194 | + | timerCount = 2 | |||
| 195 | + | } | |||
| 196 | + | clk, createdTimers := newHandshakeClock(t, timerCount) | |||
| 211 | 197 | ||||
| 212 | term := portsmocks.NewMockTerminal(t) | 198 | term := portsmocks.NewMockTerminal(t) | ||
| 213 | term.EXPECT().Size().Return(domain.Size{Cols: 80, Rows: 24}, nil).Once() | 199 | term.EXPECT().Size().Return(domain.Size{Cols: 80, Rows: 24}, nil).Once() | ||
| @@ -243,13 +229,12 @@ func TestRunBoundsPreWelcomeOperations(t *testing.T) { | |||||
| 243 | errCh <- client.Run(ctx, dialer, term, clk, ports.IntentAttach, "main", false, nil, slog.New(slog.DiscardHandler)) | 229 | errCh <- client.Run(ctx, dialer, term, clk, ports.IntentAttach, "main", false, nil, slog.New(slog.DiscardHandler)) | ||
| 244 | }() | 230 | }() | ||
| 245 | 231 | ||||
| 246 | - | var timer *handshakeTimer | 232 | + | var timerC chan time.Time |
| 247 | select { | 233 | select { | ||
| 248 | - | case timer = <-clk.created: | 234 | + | case timerC = <-createdTimers: |
| 249 | case <-time.After(time.Second): | 235 | case <-time.After(time.Second): | ||
| 250 | t.Fatal("pre-Welcome timer was not created") | 236 | t.Fatal("pre-Welcome timer was not created") | ||
| 251 | } | 237 | } | ||
| 252 | - | require.Equal(t, 15*time.Second, clk.Duration()) | |||
| 253 | select { | 238 | select { | ||
| 254 | case <-started: | 239 | case <-started: | ||
| 255 | case <-time.After(time.Second): | 240 | case <-time.After(time.Second): | ||
| @@ -257,7 +242,7 @@ func TestRunBoundsPreWelcomeOperations(t *testing.T) { | |||||
| 257 | } | 242 | } | ||
| 258 | if tt.phase == "recv" { | 243 | if tt.phase == "recv" { | ||
| 259 | select { | 244 | select { | ||
| 260 | - | case timer = <-clk.created: | 245 | + | case timerC = <-createdTimers: |
| 261 | case <-time.After(time.Second): | 246 | case <-time.After(time.Second): | ||
| 262 | t.Fatal("Welcome timer was not created") | 247 | t.Fatal("Welcome timer was not created") | ||
| 263 | } | 248 | } | ||
| @@ -266,7 +251,7 @@ func TestRunBoundsPreWelcomeOperations(t *testing.T) { | |||||
| 266 | if tt.end == "cancel" { | 251 | if tt.end == "cancel" { | ||
| 267 | cancel() | 252 | cancel() | ||
| 268 | } else { | 253 | } else { | ||
| 269 | - | timer.ch <- time.Time{} | 254 | + | timerC <- time.Time{} |
| 270 | } | 255 | } | ||
| 271 | 256 | ||||
| 272 | select { | 257 | select { | ||
M internal/usecase/client/reconnect_toast_test.go +1 -1
| @@ -187,7 +187,7 @@ func newReconnectHandshakeClock(t *testing.T) *portsmocks.MockClock { | |||
| 187 | 187 | timer := portsmocks.NewMockTimer(t) | |
| 188 | 188 | timer.EXPECT().C().Return((<-chan time.Time)(make(chan time.Time))).Maybe() | |
| 189 | 189 | timer.EXPECT().Stop().Return(true).Maybe() | |
| 190 | - | clk.EXPECT().NewTimer(15 * time.Second).Return(timer).Maybe() | |
| 190 | + | clk.EXPECT().NewTimer(preWelcomeTimeout).Return(timer).Maybe() | |
| 191 | 191 | return clk | |
| 192 | 192 | } | |
| 193 | 193 | ||
| @@ -187,7 +187,7 @@ func newReconnectHandshakeClock(t *testing.T) *portsmocks.MockClock { | |||||
| 187 | timer := portsmocks.NewMockTimer(t) | 187 | timer := portsmocks.NewMockTimer(t) | ||
| 188 | timer.EXPECT().C().Return((<-chan time.Time)(make(chan time.Time))).Maybe() | 188 | timer.EXPECT().C().Return((<-chan time.Time)(make(chan time.Time))).Maybe() | ||
| 189 | timer.EXPECT().Stop().Return(true).Maybe() | 189 | timer.EXPECT().Stop().Return(true).Maybe() | ||
| 190 | - | clk.EXPECT().NewTimer(15 * time.Second).Return(timer).Maybe() | 190 | + | clk.EXPECT().NewTimer(preWelcomeTimeout).Return(timer).Maybe() |
| 191 | return clk | 191 | return clk | ||
| 192 | } | 192 | } | ||
| 193 | 193 | ||||
M internal/usecase/daemon/render.go +2 -6
| @@ -32,12 +32,8 @@ func (d *Daemon) paneRenderable(sess *session, tb *tab, p *pane) bool { | |||
| 32 | 32 | ||
| 33 | 33 | // The normal attached render path needs no cross-session picker lookup. | |
| 34 | 34 | // Only inactive or headless tabs can be renderable as a picker preview. | |
| 35 | - | preview := false | |
| 36 | - | if !active || !attached { | |
| 37 | - | preview = d.tabIsPickerPreview(tb) | |
| 38 | - | if !preview { | |
| 39 | - | return false | |
| 40 | - | } | |
| 35 | + | if (!active || !attached) && !d.tabIsPickerPreview(tb) { | |
| 36 | + | return false | |
| 41 | 37 | } | |
| 42 | 38 | tb.mu.Lock() | |
| 43 | 39 | defer tb.mu.Unlock() | |
| @@ -32,12 +32,8 @@ func (d *Daemon) paneRenderable(sess *session, tb *tab, p *pane) bool { | |||||
| 32 | 32 | ||||
| 33 | // The normal attached render path needs no cross-session picker lookup. | 33 | // The normal attached render path needs no cross-session picker lookup. | ||
| 34 | // Only inactive or headless tabs can be renderable as a picker preview. | 34 | // Only inactive or headless tabs can be renderable as a picker preview. | ||
| 35 | - | preview := false | 35 | + | if (!active || !attached) && !d.tabIsPickerPreview(tb) { |
| 36 | - | if !active || !attached { | 36 | + | return false |
| 37 | - | preview = d.tabIsPickerPreview(tb) | |||
| 38 | - | if !preview { | |||
| 39 | - | return false | |||
| 40 | - | } | |||
| 41 | } | 37 | } | ||
| 42 | tb.mu.Lock() | 38 | tb.mu.Lock() | ||
| 43 | defer tb.mu.Unlock() | 39 | defer tb.mu.Unlock() | ||