From dd954062b4f51cf18f5e945e479798490ca4e259 Mon Sep 17 00:00:00 2001 From: Ehab Kahwati Date: Sun, 8 Nov 2026 03:08:46 -0700 Subject: [PATCH] fix(ui): keep the wheel over the shell from moving the table scrollMain handled the log and text views, then fell through to the table branch. With the in-panel shell open, the wheel over the pane moved the hidden table's selection, so detaching landed on a different row. It now returns early in shell mode. This is the first acceptance item of Part 1 in #12. Scrollback and passing the wheel to programs in the pod are still open there. Refs #12 Signed-off-by: Ehab Kahwati --- internal/ui/model.go | 6 ++++++ internal/ui/shell_test.go | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/internal/ui/model.go b/internal/ui/model.go index 695ed50..698b190 100644 --- a/internal/ui/model.go +++ b/internal/ui/model.go @@ -1754,6 +1754,12 @@ func (m *Model) scrollMain(delta int) { m.textTop = clamp(m.textTop+delta, 0, maxi(0, len(m.textLines)-(m.layout().midH-2))) return } + if m.mode == modeShell { + // The pane shows the shell, so the table behind it is not what the + // wheel is over. Falling through moved its selection, and detaching + // then landed on a different row. + return + } _, rows := m.tableData() m.rowIdx = clamp(m.rowIdx+delta, 0, maxi(0, len(rows)-1)) m.rowMem[m.curKind().Key] = m.rowIdx diff --git a/internal/ui/shell_test.go b/internal/ui/shell_test.go index c07e772..5bc71bf 100644 --- a/internal/ui/shell_test.go +++ b/internal/ui/shell_test.go @@ -212,6 +212,26 @@ func TestShellSizedToThePanel(t *testing.T) { } } +// The table is hidden behind the shell, so the wheel over the pane must not +// move its selection: detaching would land on a different row. +func TestWheelOverTheShellLeavesTheTableAlone(t *testing.T) { + m, sh := newShellModel(t) + openShell(t, m, sh) + kind := m.curKind().Key + rowBefore, memBefore := m.rowIdx, m.rowMem[kind] + + l := m.layout() + m.handleMouse(wheel(l.leftW+5, l.midY+4, false)) + m.handleMouse(wheel(l.leftW+5, l.midY+4, false)) + + if m.rowIdx != rowBefore || m.rowMem[kind] != memBefore { + t.Errorf("wheel over the shell moved the table: row %d -> %d", rowBefore, m.rowIdx) + } + if m.mode != modeShell { + t.Errorf("mode = %v, want the shell to stay open", m.mode) + } +} + func TestNoShellFallsBackToAToast(t *testing.T) { m := newTestModel(t, mock.New("")) // demo backend has no shell dismissOnboarding(m)