[GH-ISSUE #421] SetInputCapture isn't fired on a parent component #307

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

Originally created by @k33nice on GitHub (Mar 27, 2020).
Original GitHub issue: https://github.com/rivo/tview/issues/421

For me, it's pretty unintuitive that SetInputCapture isn't called if a child is focused and the event key was fired. Also HasFocus method returns true for the parent block.

func main() {
	app := tview.NewApplication()

	first := tview.NewBox().SetBorder(true).SetTitle("First")
	second := tview.NewBox().SetBorder(true).SetTitle("Second")

	flex := tview.NewFlex().
		AddItem(first, 0, 1, false).
		AddItem(second, 0, 1, false)

	flex.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey {
		log.Print("Will never gets here")
		return e
	})

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

I've found a simple workaround. IMO it looks a bit hacky:

	app.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey {
		if flex.HasFocus() {
			flex.GetInputCapture()(e)
		}
	})
Originally created by @k33nice on GitHub (Mar 27, 2020). Original GitHub issue: https://github.com/rivo/tview/issues/421 For me, it's pretty unintuitive that `SetInputCapture` isn't called if a child is focused and the event key was fired. Also `HasFocus` method returns true for the parent block. ```go func main() { app := tview.NewApplication() first := tview.NewBox().SetBorder(true).SetTitle("First") second := tview.NewBox().SetBorder(true).SetTitle("Second") flex := tview.NewFlex(). AddItem(first, 0, 1, false). AddItem(second, 0, 1, false) flex.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey { log.Print("Will never gets here") return e }) if err := app.SetRoot(flex, true).SetFocus(first).Run(); err != nil { panic(err) } } ``` I've found a simple workaround. IMO it looks a bit hacky: ```go app.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey { if flex.HasFocus() { flex.GetInputCapture()(e) } }) ```
kerem closed this issue 2026-03-04 01:03:49 +03:00
Author
Owner

@rivo commented on GitHub (Mar 30, 2020):

I agree with you that this is not optimal. It was an early design decision to keep a global pointer to one element which has focus and route all keyboard input to it directly. Maybe I wasn't sure why one would want to handle some input higher up at the same time (in a Flex in your case). The HasFocus() function (which, also in retrospect, should not be public but that's another topic) was basically just there to indicate which element has focus (with a two-line border around it) and that wouldn't work if it applied only to leaf elements.

For the newly added mouse support, we do it differently: Mouse events bubble down the tree and can be intercepted anywhere along the way. I will probably look at implementing keyboard input the same way. But I'll have to check how much this affects backwards compatibility.

For now, your workaround is probably the only way to make this work.

<!-- gh-comment-id:605884139 --> @rivo commented on GitHub (Mar 30, 2020): I agree with you that this is not optimal. It was an early design decision to keep a global pointer to one element which has focus and route all keyboard input to it directly. Maybe I wasn't sure why one would want to handle some input higher up at the same time (in a `Flex` in your case). The `HasFocus()` function (which, also in retrospect, should not be public but that's another topic) was basically just there to indicate which element has focus (with a two-line border around it) and that wouldn't work if it applied only to leaf elements. For the newly added mouse support, we do it differently: Mouse events bubble down the tree and can be intercepted anywhere along the way. I will probably look at implementing keyboard input the same way. But I'll have to check how much this affects backwards compatibility. For now, your workaround is probably the only way to make this work.
Author
Owner

@rivo commented on GitHub (Aug 18, 2020):

I implemented this just now. Please let me know if it works for you as you expect.

<!-- gh-comment-id:675389076 --> @rivo commented on GitHub (Aug 18, 2020): I implemented this just now. Please let me know if it works for you as you expect.
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#307
No description provided.