fix(tui): correct btw cursor offset
Only count the dialog frame padding row when padDialogFrame actually inserts it, so the btw editor cursor stays on the input row after a turn. Co-authored-by: mi-skam <40042054+mi-skam@users.noreply.github.com>
- commit
- c56e04afd51f6351f86851f7ac9d46fe7020702a
- author
- patriceckhart · · 2026-06-22 05:47 UTC
- parent
- ab3d4c5
- signature
- unsigned
1 file · +6 -4
M packages/agent/modes/btw_dialog.go +6 -4
| @@ -378,12 +378,14 @@ func (d *btwDialog) CursorPos(width int) (row, col int) { | |||
| 378 | 378 | } | |
| 379 | 379 | // Reproduce render's structure to find where the editor sits. | |
| 380 | 380 | // Note: the parent (interactive.go) wraps every dialog with | |
| 381 | - | // padDialogFrame, which injects a blank row right after the | |
| 382 | - | // frame header. We have to count that injected row here too; | |
| 383 | - | // otherwise the reported cursor lands one row above the editor. | |
| 381 | + | // padDialogFrame. It only injects a blank row after the frame | |
| 382 | + | // header when Render did not already put one there. With existing | |
| 383 | + | // turns or a loading spinner, Render's first body row is already | |
| 384 | + | // blank, so counting an extra pad row would place the cursor one | |
| 385 | + | // row too low. | |
| 384 | 386 | editorOffset := 1 // header | |
| 385 | - | editorOffset++ // padDialogFrame's post-header blank | |
| 386 | 387 | if len(d.turns) == 0 && !d.loading { | |
| 388 | + | editorOffset++ // padDialogFrame's post-header blank | |
| 387 | 389 | editorOffset++ // muted "ask anything..." line | |
| 388 | 390 | } | |
| 389 | 391 | for _, t := range d.turns { | |
| @@ -378,12 +378,14 @@ func (d *btwDialog) CursorPos(width int) (row, col int) { | |||||
| 378 | } | 378 | } | ||
| 379 | // Reproduce render's structure to find where the editor sits. | 379 | // Reproduce render's structure to find where the editor sits. | ||
| 380 | // Note: the parent (interactive.go) wraps every dialog with | 380 | // Note: the parent (interactive.go) wraps every dialog with | ||
| 381 | - | // padDialogFrame, which injects a blank row right after the | 381 | + | // padDialogFrame. It only injects a blank row after the frame |
| 382 | - | // frame header. We have to count that injected row here too; | 382 | + | // header when Render did not already put one there. With existing |
| 383 | - | // otherwise the reported cursor lands one row above the editor. | 383 | + | // turns or a loading spinner, Render's first body row is already |
| 384 | + | // blank, so counting an extra pad row would place the cursor one | |||
| 385 | + | // row too low. | |||
| 384 | editorOffset := 1 // header | 386 | editorOffset := 1 // header | ||
| 385 | - | editorOffset++ // padDialogFrame's post-header blank | |||
| 386 | if len(d.turns) == 0 && !d.loading { | 387 | if len(d.turns) == 0 && !d.loading { | ||
| 388 | + | editorOffset++ // padDialogFrame's post-header blank | |||
| 387 | editorOffset++ // muted "ask anything..." line | 389 | editorOffset++ // muted "ask anything..." line | ||
| 388 | } | 390 | } | ||
| 389 | for _, t := range d.turns { | 391 | for _, t := range d.turns { | ||