From 17c7dd3a8ac7c1af095f1971ba017e9815487590 Mon Sep 17 00:00:00 2001 From: Bruno Bornsztein Date: Wed, 11 Feb 2026 13:22:39 -0600 Subject: [PATCH] Enable scrolling in task detail view with j/k keys and mouse wheel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, the task detail pane viewport was only scrollable with PgUp/PgDn keys. Users naturally expected to use j/k keys (vim-style) and mouse wheel for scrolling, but these were not working. Changes: - Removed j/k key blocking in detail view to enable vim-style scrolling - Added mouse event routing to detail view for mouse wheel scrolling - Updated help text to show "j/k/wheel" as scroll options The viewport component already supported these inputs, but they were being blocked at the app routing level. Mouse events are now passed to the detail view while preserving tmux's native pane-clicking functionality (which operates at the tmux level, not the app level). Navigation keys remain unchanged: - Arrow keys (↑/↓) navigate between tasks - j/k scroll within the current task's content - Mouse clicks on tmux panes still switch between panes Co-Authored-By: Claude Sonnet 4.5 --- internal/ui/app.go | 9 +++++---- internal/ui/detail.go | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/ui/app.go b/internal/ui/app.go index 906d556..3e67283 100644 --- a/internal/ui/app.go +++ b/internal/ui/app.go @@ -738,6 +738,10 @@ func (m *AppModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, m.loadTask(task.ID) } } + // Pass mouse events to detail view for scrolling + if m.currentView == ViewDetail { + return m.updateDetail(msg) + } case tasksLoadedMsg: m.loading = false @@ -2406,10 +2410,7 @@ func (m *AppModel) updateDetail(msg tea.Msg) (tea.Model, tea.Cmd) { } // Arrow key navigation to prev/next task in the same column - // Skip j/k in detail view - only use arrow keys (j/k reserved for other uses) - if keyMsg.String() == "j" || keyMsg.String() == "k" { - return m, nil - } + // j/k keys are passed through to the viewport for scrolling if key.Matches(keyMsg, m.keys.Up) { // Ignore if no previous task exists if !m.kanban.HasPrevTask() { diff --git a/internal/ui/detail.go b/internal/ui/detail.go index 23e12a6..6129a6c 100644 --- a/internal/ui/detail.go +++ b/internal/ui/detail.go @@ -2615,7 +2615,7 @@ func (m *DetailModel) renderHelp() string { // Show scroll hint when content is scrollable if m.viewport.TotalLineCount() > m.viewport.VisibleLineCount() { - keys = append(keys, helpKey{"PgUp/Dn", "scroll", false}) + keys = append(keys, helpKey{"j/k/wheel", "scroll", false}) } // Only show execute/retry when Claude is not running