[GH-ISSUE #134] Bug: Suspend() doesn't work from goroutine #105

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

Originally created by @kvj on GitHub (Jun 20, 2018).
Original GitHub issue: https://github.com/rivo/tview/issues/134

I'm trying to get user input using fmt.Scanf() by temporarily suspending tview/tcell application and later resuming it. If Suspend() is called from same thread with Run()/KeyboardInterceptor() - everything works, I can get user input, but application hangs (Run() finishes) when goroutine is used. Following sample code demonstrates the issue:

package main

import (
	"fmt"
	"log"
	"os"

	"github.com/gdamore/tcell"
	"github.com/rivo/tview"
)

func doInput(app *tview.Application) {
	app.Suspend(func() {
		fmt.Printf("Input something: ")
		var code string
		if _, err := fmt.Scan(&code); err != nil {
			log.Fatalf("Unable to read authorization code %v", err)
		}
		fmt.Printf("\r\nInput: %s\r\n", code)
	})
}

func main() {
	os.Setenv("TERM", "xterm-256color")
	box := tview.NewBox().SetBorder(true).SetTitle("Hello, world!")
	app := tview.NewApplication()
	pages := tview.NewPages()
	pages.AddPage("grid", box, true, true)
	app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
		switch event.Key() {
		case tcell.KeyCtrlR:
			doInput(app)
		default:
			return event
		}
		return event
	})
	if err := app.SetRoot(pages, true).Run(); err != nil {
		panic(err)
	}
}

If I call doInput(app) - everything is OK, but when I change it to go doInput(app) - application hangs

Originally created by @kvj on GitHub (Jun 20, 2018). Original GitHub issue: https://github.com/rivo/tview/issues/134 I'm trying to get user input using `fmt.Scanf()` by temporarily suspending tview/tcell application and later resuming it. If `Suspend()` is called from same thread with `Run()`/`KeyboardInterceptor()` - everything works, I can get user input, but application hangs (`Run()` finishes) when goroutine is used. Following sample code demonstrates the issue: ```golang package main import ( "fmt" "log" "os" "github.com/gdamore/tcell" "github.com/rivo/tview" ) func doInput(app *tview.Application) { app.Suspend(func() { fmt.Printf("Input something: ") var code string if _, err := fmt.Scan(&code); err != nil { log.Fatalf("Unable to read authorization code %v", err) } fmt.Printf("\r\nInput: %s\r\n", code) }) } func main() { os.Setenv("TERM", "xterm-256color") box := tview.NewBox().SetBorder(true).SetTitle("Hello, world!") app := tview.NewApplication() pages := tview.NewPages() pages.AddPage("grid", box, true, true) app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { switch event.Key() { case tcell.KeyCtrlR: doInput(app) default: return event } return event }) if err := app.SetRoot(pages, true).Run(); err != nil { panic(err) } } ``` If I call `doInput(app)` - everything is OK, but when I change it to `go doInput(app)` - application hangs
kerem closed this issue 2026-03-04 01:01:58 +03:00
Author
Owner

@kvj commented on GitHub (Jun 20, 2018):

I believe there's an issue with mutex Lock()/Unlock() calls, event loop is terminated here: https://github.com/rivo/tview/blob/master/application.go#L113

<!-- gh-comment-id:398658916 --> @kvj commented on GitHub (Jun 20, 2018): I believe there's an issue with mutex `Lock()`/`Unlock()` calls, event loop is terminated here: https://github.com/rivo/tview/blob/master/application.go#L113
Author
Owner

@rivo commented on GitHub (Jun 28, 2018):

I've merged your PR so this issue is closed now.

<!-- gh-comment-id:401023137 --> @rivo commented on GitHub (Jun 28, 2018): I've merged your PR so this issue is closed now.
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#105
No description provided.