fix(tui): refine floating pane interactions
- commit
- a8648e7e99f2a87329a740bdab32bee5546c2a32
- author
- brice · · 2026-08-14 11:42 UTC
- parent
- 4eba8ac
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
4 files · +28 -3
M packages/agent/modes/interactive_input_routing.go +10 -2
| @@ -281,9 +281,17 @@ func (i *Interactive) handleKey(ctx context.Context, k tui.Key) (done bool) { | |||
| 281 | 281 | residentSession.Scroll(10) | |
| 282 | 282 | case tui.KeyPageDown: | |
| 283 | 283 | residentSession.Scroll(-10) | |
| 284 | - | case tui.KeyUp, tui.KeyMouseWheelUp: | |
| 284 | + | case tui.KeyUp: | |
| 285 | + | if !residentSession.HandleNavigation(k) { | |
| 286 | + | residentSession.Scroll(1) | |
| 287 | + | } | |
| 288 | + | case tui.KeyDown: | |
| 289 | + | if !residentSession.HandleNavigation(k) { | |
| 290 | + | residentSession.Scroll(-1) | |
| 291 | + | } | |
| 292 | + | case tui.KeyMouseWheelUp: | |
| 285 | 293 | residentSession.Scroll(1) | |
| 286 | - | case tui.KeyDown, tui.KeyMouseWheelDown: | |
| 294 | + | case tui.KeyMouseWheelDown: | |
| 287 | 295 | residentSession.Scroll(-1) | |
| 288 | 296 | default: | |
| 289 | 297 | session := residentSession | |
| @@ -281,9 +281,17 @@ func (i *Interactive) handleKey(ctx context.Context, k tui.Key) (done bool) { | |||||
| 281 | residentSession.Scroll(10) | 281 | residentSession.Scroll(10) | ||
| 282 | case tui.KeyPageDown: | 282 | case tui.KeyPageDown: | ||
| 283 | residentSession.Scroll(-10) | 283 | residentSession.Scroll(-10) | ||
| 284 | - | case tui.KeyUp, tui.KeyMouseWheelUp: | 284 | + | case tui.KeyUp: |
| 285 | + | if !residentSession.HandleNavigation(k) { | |||
| 286 | + | residentSession.Scroll(1) | |||
| 287 | + | } | |||
| 288 | + | case tui.KeyDown: | |||
| 289 | + | if !residentSession.HandleNavigation(k) { | |||
| 290 | + | residentSession.Scroll(-1) | |||
| 291 | + | } | |||
| 292 | + | case tui.KeyMouseWheelUp: | |||
| 285 | residentSession.Scroll(1) | 293 | residentSession.Scroll(1) | ||
| 286 | - | case tui.KeyDown, tui.KeyMouseWheelDown: | 294 | + | case tui.KeyMouseWheelDown: |
| 287 | residentSession.Scroll(-1) | 295 | residentSession.Scroll(-1) | ||
| 288 | default: | 296 | default: | ||
| 289 | session := residentSession | 297 | session := residentSession | ||
M packages/agent/modes/subagent_session.go +9 -0
| @@ -297,6 +297,15 @@ func (s *residentChildSession) HandleKey(k tui.Key) (string, bool) { | |||
| 297 | 297 | return prompt, prompt != "" | |
| 298 | 298 | } | |
| 299 | 299 | ||
| 300 | + | func (s *residentChildSession) HandleNavigation(k tui.Key) bool { | |
| 301 | + | if s == nil || s.composer == nil { | |
| 302 | + | return false | |
| 303 | + | } | |
| 304 | + | s.mu.Lock() | |
| 305 | + | defer s.mu.Unlock() | |
| 306 | + | return s.composer.HandleKey(k) | |
| 307 | + | } | |
| 308 | + | ||
| 300 | 309 | func (s *residentChildSession) FinishSubmission(err error) { | |
| 301 | 310 | if s == nil { | |
| 302 | 311 | return | |
| @@ -297,6 +297,15 @@ func (s *residentChildSession) HandleKey(k tui.Key) (string, bool) { | |||||
| 297 | return prompt, prompt != "" | 297 | return prompt, prompt != "" | ||
| 298 | } | 298 | } | ||
| 299 | 299 | ||||
| 300 | + | func (s *residentChildSession) HandleNavigation(k tui.Key) bool { | |||
| 301 | + | if s == nil || s.composer == nil { | |||
| 302 | + | return false | |||
| 303 | + | } | |||
| 304 | + | s.mu.Lock() | |||
| 305 | + | defer s.mu.Unlock() | |||
| 306 | + | return s.composer.HandleKey(k) | |||
| 307 | + | } | |||
| 308 | + | ||||
| 300 | func (s *residentChildSession) FinishSubmission(err error) { | 309 | func (s *residentChildSession) FinishSubmission(err error) { | ||
| 301 | if s == nil { | 310 | if s == nil { | ||
| 302 | return | 311 | return | ||
M packages/agent/modes/subagents_slash.go +4 -0
| @@ -98,11 +98,15 @@ func residentResultStatus(id string, result subagents.ResidentResult) string { | |||
| 98 | 98 | func (i *Interactive) openResidentChildSession(childID string) { | |
| 99 | 99 | session := newResidentChildSession(i.cfg.ResidentManager, childID, i.cfg.Theme) | |
| 100 | 100 | i.mu.Lock() | |
| 101 | + | previous := i.residentChildSession | |
| 101 | 102 | if i.residentSubagentsDialog != nil { | |
| 102 | 103 | i.residentSubagentsDialog.Close() | |
| 103 | 104 | } | |
| 104 | 105 | i.residentChildSession = session | |
| 105 | 106 | i.mu.Unlock() | |
| 107 | + | if previous != nil { | |
| 108 | + | previous.Close() | |
| 109 | + | } | |
| 106 | 110 | i.setResidentChildMouseReporting(true) | |
| 107 | 111 | i.invalidate() | |
| 108 | 112 | if session.BeginLoad() { | |
| @@ -98,11 +98,15 @@ func residentResultStatus(id string, result subagents.ResidentResult) string { | |||||
| 98 | func (i *Interactive) openResidentChildSession(childID string) { | 98 | func (i *Interactive) openResidentChildSession(childID string) { | ||
| 99 | session := newResidentChildSession(i.cfg.ResidentManager, childID, i.cfg.Theme) | 99 | session := newResidentChildSession(i.cfg.ResidentManager, childID, i.cfg.Theme) | ||
| 100 | i.mu.Lock() | 100 | i.mu.Lock() | ||
| 101 | + | previous := i.residentChildSession | |||
| 101 | if i.residentSubagentsDialog != nil { | 102 | if i.residentSubagentsDialog != nil { | ||
| 102 | i.residentSubagentsDialog.Close() | 103 | i.residentSubagentsDialog.Close() | ||
| 103 | } | 104 | } | ||
| 104 | i.residentChildSession = session | 105 | i.residentChildSession = session | ||
| 105 | i.mu.Unlock() | 106 | i.mu.Unlock() | ||
| 107 | + | if previous != nil { | |||
| 108 | + | previous.Close() | |||
| 109 | + | } | |||
| 106 | i.setResidentChildMouseReporting(true) | 110 | i.setResidentChildMouseReporting(true) | ||
| 107 | i.invalidate() | 111 | i.invalidate() | ||
| 108 | if session.BeginLoad() { | 112 | if session.BeginLoad() { | ||
M packages/tui/render.go +5 -1
| @@ -571,9 +571,13 @@ func (r *Renderer) DrawFloating(pane FloatingPaneFrame, cursorRow, cursorCol int | |||
| 571 | 571 | if y < 0 || y >= r.rows { | |
| 572 | 572 | continue | |
| 573 | 573 | } | |
| 574 | + | if pane.Rect.X >= r.cols { | |
| 575 | + | continue | |
| 576 | + | } | |
| 577 | + | width := min(pane.Rect.Width, r.cols-pane.Rect.X) | |
| 574 | 578 | w.WriteString(MoveTo(y+1, pane.Rect.X+1)) | |
| 575 | 579 | w.WriteString("\x1b[0m") | |
| 576 | - | w.WriteString(paintBackgroundRow(truncateToWidth(line, pane.Rect.Width), pane.Rect.Width, r.backgroundStyle)) | |
| 580 | + | w.WriteString(paintBackgroundRow(truncateToWidth(line, width), width, r.backgroundStyle)) | |
| 577 | 581 | } | |
| 578 | 582 | if cursorRow >= 0 && cursorRow < r.rows && cursorCol >= 0 && cursorCol < r.cols { | |
| 579 | 583 | w.WriteString(MoveTo(cursorRow+1, cursorCol+1)) | |
| @@ -571,9 +571,13 @@ func (r *Renderer) DrawFloating(pane FloatingPaneFrame, cursorRow, cursorCol int | |||||
| 571 | if y < 0 || y >= r.rows { | 571 | if y < 0 || y >= r.rows { | ||
| 572 | continue | 572 | continue | ||
| 573 | } | 573 | } | ||
| 574 | + | if pane.Rect.X >= r.cols { | |||
| 575 | + | continue | |||
| 576 | + | } | |||
| 577 | + | width := min(pane.Rect.Width, r.cols-pane.Rect.X) | |||
| 574 | w.WriteString(MoveTo(y+1, pane.Rect.X+1)) | 578 | w.WriteString(MoveTo(y+1, pane.Rect.X+1)) | ||
| 575 | w.WriteString("\x1b[0m") | 579 | w.WriteString("\x1b[0m") | ||
| 576 | - | w.WriteString(paintBackgroundRow(truncateToWidth(line, pane.Rect.Width), pane.Rect.Width, r.backgroundStyle)) | 580 | + | w.WriteString(paintBackgroundRow(truncateToWidth(line, width), width, r.backgroundStyle)) |
| 577 | } | 581 | } | ||
| 578 | if cursorRow >= 0 && cursorRow < r.rows && cursorCol >= 0 && cursorCol < r.cols { | 582 | if cursorRow >= 0 && cursorRow < r.rows && cursorCol >= 0 && cursorCol < r.cols { | ||
| 579 | w.WriteString(MoveTo(cursorRow+1, cursorCol+1)) | 583 | w.WriteString(MoveTo(cursorRow+1, cursorCol+1)) | ||