mirror of
https://github.com/rivo/tview.git
synced 2026-04-27 05:45:49 +03:00
[GH-ISSUE #870] Issues with focus/blur when using flex layout #633
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/tview#633
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @carpii on GitHub (Aug 25, 2023).
Original GitHub issue: https://github.com/rivo/tview/issues/870
I'm using a flex layout, containing two frames. Top frame contains a form, bottom frame contains a table.
I'd like to handle focus/blur on both frames, but the docs suggest this is not possible when they are contained in a flex or grid.
So instead, I attach handlers to the form and table, but these never fire either.
It's not clear whether this is a bug, or just a known issue.
It feels like quite a major limitation though, since all but the most trivial apps will require some sort of layout container
@rivo commented on GitHub (Apr 4, 2024):
I'm following up on this issue but the code above cannot be run (no
mainand it also references functions that don't exist). Can you please post code that can be run?@carpii commented on GitHub (Apr 4, 2024):
Hi,
thanks for looking into this. I've updated the above code so it will build
debug output is sent to stderr...
then
tail -f debug.login a sep shellThe issues Im having..
Using mouse to select top and bottom frames, only ever emits
[FOCUS] table BOTTOMand[BLUR] table BOTTOMThere are never any FOCUS or BLUR events emitted for the top and bottom frames, nor for the form (in the top frame)
Since its able to emit events for the bottom TABLE, I expected it to do the same for the TOP FORM
Ideally I'd like to see events emitted for the frames themselves, and then perhaps the control contained within that frame which is getting the focus
I acknowledge mouse support in terminal is never ideal, and my app will primarily use keyboard to navigate. But even then if I am not getting the control or frame events, its making it quite difficult to develop without maintaining my own representation of the ui state
@rivo commented on GitHub (Apr 6, 2024):
Thank you. When I run your code, after clicking on the table first, then on the form, I get this in
debug.log:And I'm actually surprised that the "blur" event is invoked on the frame and the form. Mostly because the documentation says this:
FrameandFormare both also container primitives. AFramecontains another primitive. AFormcontains multiple other primitives (input fields, checkboxes, buttons etc.). When you click on a flex item to direct the focus to it, theFlexcomponent passes the click on to the item itself. Then the item, e.g. yourForm, passes it on again to the form item at the click position, e.g. an input field. (If there is no item at that position, the last selected item is chosen.)So your click, and therefore your focus/blur event, is only ever processed by a "leaf" in the layout tree and never by the nodes inbetween that leaf and the root node. (On a side note, when a border is drawn, the
HasFocus()method is called which, for container primitives, will call its contained primitives — essentially traversing the tree.)Long story short, the behaviour you're seeing is expected. I'm not sure how easy it would be to change this (and how it would affect existing applications). In any case, I would like to understand first what you're trying to achieve. Maybe you can explain a bit why your application needs this? There may be other ways to solve the issue you're having.
@rivo commented on GitHub (Apr 6, 2024):
So it seems that the "blur" events on the frame and the form are called during initialization. They briefly have focus when they are added to the layout and then lose it again when the other elements are added.
@carpii commented on GitHub (Apr 6, 2024):
Ok, thanks. I wanted to make sure its defined behavior I can rely on, rather than just a bug.
For use case, it will vary. I have lots of these multi frame screen layouts (sometimes with 3 frames, but mostly 2), and was looking for a generic way to detect when focus moves from one frame to another
From what I recall, in some cases I want to hit the db when the bottom frame recieves focus, or other times it will manipulate controls such as changing the bottom table from readonly to editable when its frame has focus).
There's no doubt a bunch of other use cases Ive since forgotten about, since development on this app has been stalled for a good while
I guess my plan now is to add a generic focus handler to every focusable control, peek which frame it belongs to, and if the 'focused frame' has changed, then simulate a frame focus event and invoke my screen-specific handler.
Unless you have any suggestions for a better way?
Cheers
@rivo commented on GitHub (Apr 7, 2024):
Well, since the same has been requested in #869, I might have to think about how to make this possible in container primitives as well. So far, the implementation is very simple: I keep a reference to the currently focused item. Then I can call
Blur()on that item when it loses focus.SetFocus()is also very simple: It just updates the reference.But if I want to include all primitives that the newly (or previously) focused element is contained in, I have to search the entire layout tree for it. There is currently no upwards reference (i.e. a
parentpointer) on elements and I prefer not to introduce that. (It would bring with it many other problems.)It's probably not difficult to implement but it will introduce a performance penalty. I guess it's acceptable, though. I don't think anyone has millions of input fields in their application.
@carpii commented on GitHub (Apr 8, 2024):
Ah I remember now. I think that's why I didnt just go ahead and implement the plan I mentioned above (since its not possible to take a control and identify which container it belongs to)
Any improvements you can come up with would be very welcome, and I think would probably be useful for other apps where the UI is dynamically created based on external data.
@rivo commented on GitHub (Aug 28, 2025):
With the latest commit, the "focus" and "blur" notifications are now invoked for all primitives along the hierarchy (see
SetFocusFuncandSetBlurFuncfor details). Please have a look and let me know if this solves your problem.@uqix commented on GitHub (Sep 8, 2025):
SetFocusFuncon form items in flex layout works now, thanks.