[GH-ISSUE #944] Changing selection on a cleared table can make the app unresponsive. #693

Closed
opened 2026-03-04 01:07:04 +03:00 by kerem · 2 comments
Owner

Originally created by @stijnveenman on GitHub (Feb 5, 2024).
Original GitHub issue: https://github.com/rivo/tview/issues/944

If we take the following example

package main

import (
	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"
)

func main() {
	app := tview.NewApplication()
	table := tview.NewTable().
		SetBorders(true)

	table.SetCell(0, 0, tview.NewTableCell("test").SetSelectable(false))
	table.SetCell(1, 0, tview.NewTableCell("test").SetSelectable(true))
	table.SetCell(2, 0, tview.NewTableCell("test").SetSelectable(true))

	table.SetSelectable(true, false)

	table.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
		if event.Rune() == 'a' {
			table.SetCell(table.GetRowCount(), 0, tview.NewTableCell("test"))
		}
		if event.Rune() == 'c' {
			table.Clear()
			table.SetCell(0, 0, tview.NewTableCell("test").SetSelectable(false))
		}
		return event
	})

	if err := app.SetRoot(table, true).SetFocus(table).Run(); err != nil {
		panic(err)
	}
}

We have row 0; which is not selectable (think of a header in a table)
And a few selectable rows. We can add rows by pressing a, and clear with c.

Expected

If we add a few rows this works fine, but if we click c we clear the table and create the (unselectable) header again. Then, we press j to move to a different row, causing the selection to "change".

After this, the app becomes unresponsive. Adding a new row with a does nothing.
Even ctr+c does not close the app anymore, and CPU jumps up to 100%.

Side note: if i clear the table with row 2 (3th row) selected, and do not select a different row. And add a few rows again, i can see that row 2 is still selected. And the app stays responsive. It only happens when changing a row.

Originally created by @stijnveenman on GitHub (Feb 5, 2024). Original GitHub issue: https://github.com/rivo/tview/issues/944 If we take the following example ```go package main import ( "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) func main() { app := tview.NewApplication() table := tview.NewTable(). SetBorders(true) table.SetCell(0, 0, tview.NewTableCell("test").SetSelectable(false)) table.SetCell(1, 0, tview.NewTableCell("test").SetSelectable(true)) table.SetCell(2, 0, tview.NewTableCell("test").SetSelectable(true)) table.SetSelectable(true, false) table.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if event.Rune() == 'a' { table.SetCell(table.GetRowCount(), 0, tview.NewTableCell("test")) } if event.Rune() == 'c' { table.Clear() table.SetCell(0, 0, tview.NewTableCell("test").SetSelectable(false)) } return event }) if err := app.SetRoot(table, true).SetFocus(table).Run(); err != nil { panic(err) } } ``` We have row 0; which is not selectable (think of a header in a table) And a few selectable rows. We can add rows by pressing `a`, and clear with `c`. ## Expected If we add a few rows this works fine, but if we click `c` we clear the table and create the (unselectable) header again. Then, we press `j` to move to a different row, causing the selection to "change". After this, the app becomes unresponsive. Adding a new row with `a` does nothing. Even `ctr+c` does not close the app anymore, and CPU jumps up to 100%. Side note: if i clear the table with row 2 (3th row) selected, and do **not** select a different row. And add a few rows again, i can see that row 2 is still selected. And the app stays responsive. It only happens when changing a row.
kerem closed this issue 2026-03-04 01:07:04 +03:00
Author
Owner

@F1bonacc1 commented on GitHub (Feb 5, 2024):

I attached a goroutine profiler. It looks like the table is stuck in this loop:
github.com/rivo/tview@861aa94d61/table.go (L1373)

#	0x65ae14	github.com/rivo/tview.(*Table).InputHandler.func1.2+0x54			github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/table.go:1375
#	0x65aca3	github.com/rivo/tview.(*Table).InputHandler.func1.5+0xa3			github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/table.go:1440
#	0x65a5a4	github.com/rivo/tview.(*Table).InputHandler.func1+0x4e4				github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/table.go:1598
#	0x65a08f	github.com/rivo/tview.(*Table).InputHandler.(*Box).WrapInputHandler.func2+0x4f	github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/box.go:167
#	0x63bb16	github.com/rivo/tview.(*Grid).InputHandler.func1+0x1b6				github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/grid.go:277
#	0x63b92f	github.com/rivo/tview.(*Grid).InputHandler.(*Box).WrapInputHandler.func2+0x4f	github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/box.go:167
#	0x650801	github.com/rivo/tview.(*Pages).InputHandler.func1+0xa1				github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/pages.go:311
#	0x65072f	github.com/rivo/tview.(*Pages).InputHandler.(*Box).WrapInputHandler.func2+0x4f	github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/box.go:167
#	0x627737	github.com/rivo/tview.(*Application).Run+0x557	
<!-- gh-comment-id:1928503134 --> @F1bonacc1 commented on GitHub (Feb 5, 2024): I attached a goroutine profiler. It looks like the table is stuck in this loop: https://github.com/rivo/tview/blob/861aa94d61c899b32a1304d61b840d0178ece408/table.go#L1373 ``` # 0x65ae14 github.com/rivo/tview.(*Table).InputHandler.func1.2+0x54 github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/table.go:1375 # 0x65aca3 github.com/rivo/tview.(*Table).InputHandler.func1.5+0xa3 github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/table.go:1440 # 0x65a5a4 github.com/rivo/tview.(*Table).InputHandler.func1+0x4e4 github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/table.go:1598 # 0x65a08f github.com/rivo/tview.(*Table).InputHandler.(*Box).WrapInputHandler.func2+0x4f github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/box.go:167 # 0x63bb16 github.com/rivo/tview.(*Grid).InputHandler.func1+0x1b6 github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/grid.go:277 # 0x63b92f github.com/rivo/tview.(*Grid).InputHandler.(*Box).WrapInputHandler.func2+0x4f github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/box.go:167 # 0x650801 github.com/rivo/tview.(*Pages).InputHandler.func1+0xa1 github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/pages.go:311 # 0x65072f github.com/rivo/tview.(*Pages).InputHandler.(*Box).WrapInputHandler.func2+0x4f github.com/rivo/tview@v0.0.0-20240101144852-b3bd1aa5e9f2/box.go:167 # 0x627737 github.com/rivo/tview.(*Application).Run+0x557 ```
Author
Owner

@rivo commented on GitHub (Mar 7, 2024):

Thank you. This should be fixed with the latest commit.

<!-- gh-comment-id:1983908946 --> @rivo commented on GitHub (Mar 7, 2024): Thank you. This should be fixed with the latest commit.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/tview#693
No description provided.