Skip to content

Commit 0cac182

Browse files
authored
fix(core): avoid crash when pane area is out of bounds during resize (#34343)
## Current Behavior In some resize/background scenarios, the TUI could crash while rendering output panes, displaying a "Scrollbar area is empty" message. ## Expected Behavior The TUI remains stable during resizes and backgrounding. Output panes no longer crash when a scrollbar would render in an invalid area.
1 parent b69ff4c commit 0cac182

1 file changed

Lines changed: 12 additions & 24 deletions

File tree

packages/nx/src/native/tui/components/terminal_pane.rs

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -419,36 +419,24 @@ impl<'a> StatefulWidget for TerminalPane<'a> {
419419
type State = TerminalPaneState;
420420

421421
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
422+
// Clamp to the buffer to avoid rendering outside bounds
423+
let safe_area = area.intersection(*buf.area());
424+
if safe_area.width == 0 || safe_area.height == 0 {
425+
return;
426+
}
427+
422428
// Add bounds checking to prevent panic when terminal is too narrow
423429
// Safety check: ensure area is at least 5x5 to render anything properly
424-
if area.width < 5 || area.height < 5 {
430+
if safe_area.width < 5 || safe_area.height < 5 {
425431
// Just render a minimal indicator instead of a full pane
426-
let safe_area = Rect {
427-
x: area.x,
428-
y: area.y,
429-
width: area.width.min(buf.area().width.saturating_sub(area.x)),
430-
height: area.height.min(buf.area().height.saturating_sub(area.y)),
431-
};
432-
433-
if safe_area.width > 0 && safe_area.height > 0 {
434-
// Only attempt to render if we have a valid area
435-
let text = "...";
436-
let paragraph = Paragraph::new(text)
437-
.style(Style::default().fg(THEME.secondary_fg))
438-
.alignment(Alignment::Center);
439-
Widget::render(paragraph, safe_area, buf);
440-
}
432+
let text = "...";
433+
let paragraph = Paragraph::new(text)
434+
.style(Style::default().fg(THEME.secondary_fg))
435+
.alignment(Alignment::Center);
436+
Widget::render(paragraph, safe_area, buf);
441437
return;
442438
}
443439

444-
// Ensure the area doesn't extend beyond buffer boundaries
445-
let safe_area = Rect {
446-
x: area.x,
447-
y: area.y,
448-
width: area.width.min(buf.area().width.saturating_sub(area.x)),
449-
height: area.height.min(buf.area().height.saturating_sub(area.y)),
450-
};
451-
452440
let base_style = self.get_base_style(state.task_status);
453441
let border_style = if state.is_focused {
454442
base_style

0 commit comments

Comments
 (0)