mirror of
https://github.com/rivo/tview.git
synced 2026-04-26 21:35:54 +03:00
[GH-ISSUE #263] Global focus handling/cycling #202
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/tview#202
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 @urandom on GitHub (Apr 6, 2019).
Original GitHub issue: https://github.com/rivo/tview/issues/263
This is more of a question/brainstorming than an issue.
Currently there doesn't seem to be an easy way of doing global focus cycling as is seen in other UIs: pressing Tab moves the focus to the next focus candidate, and Shift-tab moves the focus to the previous one, where the candidate list is usually generated by widget placement (top-bottom/left-right, or top-bottom/right-left for RTL locales) and may or may not be overridden by developer preferences (focus indices). Are there any plans to implement this?
I'm currently trying to set this up manually by setting input captures on a per-widget basis with indication what are the previous/next ones in the hierarchy. This works sort-of-ok, however there are certain places where things break down. One of the unexpected ones I recently bumped into was the fact that other primitives may unexpectedly gain focus (such as when certain widgets are drawn), and that causes my chain to break.
As a side note, I'd probably be able to mitigate this if there was some sort of event system in place I could use to listen to. That was I'd not even need to set up a per-widget capture, but instead just listen for a focus event and act accordingly. Not sure if that's on the roadmap, though I'd be happy to work on implementing it.
@vladsol commented on GitHub (Apr 21, 2019):
So, at this moment, there is no simple solution to switch focus between items in flexbox container?
@diamondburned commented on GitHub (Apr 22, 2019):
I think with enough poking around the Flex container and its InputHandler, you could whip something up fairly quickly. The idea is:
I'm currently experimenting with the same type of Primitive, only with proper scrolling support (like a ScrolledWindow+Box), but that'll take me some time.
Edit1: https://github.com/gdamore/tcell/issues/95
@rivo commented on GitHub (May 13, 2019):
You have raised multiple points which are related but not the same:
tviewprimitive.Flex.Flexto include shifting the focus.There are a lot of things to consider but the two most relevant ones to this issue are:
Flexinto aFlex. Or aGridinto aPagewhich contains aFlex.Flex,Grid,Pages, orForm), it is passed on to its contained primitive. From the point of view of the application, only aButton,InputFieldetc. can have focus but never aFlexor aGrid.If you designate some kind of key combination (e.g.
TaborBackTabwhich isShift-Tab) to shifting the focus, which one of your container primitives should react to it? On a Mac, for example,Cmd-Tabswitches between applications, other combinations switch between windows of the same application, yet other combinations between tabs, andTabitself between elements on those tabs/pages. We don't have this hierarchy (apps/pages/tabs/elements) intviewand we don't have many key combinations at our disposal. It is not clear where aTab/BackTabshould apply.We also have the problem that we then may steal keyboard input from contained primitives. Many primitives already use
TabandBackTab. But if we make aFlexreact to it, what happens to the primitive that usesTabalready (for example,DropDown)?Formkind of already does this: It allows to move from form item to form item usingTab/BackTab. But this is done using theFormIteminterface which must implement theSetFinishedFunc()callback so the bottom-level primitives decide themselves when it's ok to lose focus.So I think these points need to be clarified first before any implementation starts.
@microo8 commented on GitHub (Jun 26, 2019):
We can take example from the web. On the web the browser knows what to do with a
TaborBackTabat all times.When you have focus on a input and press
Tabthen the next input/button/link/... will get focus. Doesn't matter it it is in a div in a div in a form (in tview's it would be flex in a flex in a form).I think it does it recursively. If you have focus in a input and press
Tabthe input knows that it is the only thing that can have focus, so it calls it's parents for it to select the next item to have focus. If the next item is a div, it cannot have focus (like Flex cannot have focus), so it asks it's first children to have focus. When the input was then'thchild of the div, then the div will ask it'sn+1'thchild. When the input was the last child of the div, the div will ask it's parent to select the next item, and so on.For the DropDown I would suggest to change the controls to something else. And if you want some other behavior for the
Tabkey in other Primitives, there will be a function that explicitly sets the function to call for thatPrimitive.@rivo commented on GitHub (Jun 30, 2019):
It is true that browsers know how to deal with a
TaborBacktab. I have to say, though, that I'm not happy with the browsers' handling. It is not clear at all to users where the focus goes next when they pressTab. I frequently end up on some odd link, just because the programmers didn't bother to set thetabindexcorrectly and the default is the result of some DOM structure only remotely related to what I see on screen. If anything, I think browsers are a bad example on how to implementTabnavigation.In a
tviewForm, for example, pressingTabcontinually will keep the focus within the form at all times. It could be quite frustrating if after the last element, the focus would suddenly shift to some other, possibly unrelated element on the page that happens to be next in line in a depth-first traversal.My philosophy here is that the expected behaviour very much depends on the application. I don't see a general solution that fits everyone.
tviewshould provide the tools to define that behaviour as needed. I'm open to suggestions on how this could be achieved.@rivo commented on GitHub (Aug 29, 2019):
I can reopen this when there is new information.
@JCzz commented on GitHub (Feb 2, 2021):
I am unable to read:
if event.Key() == tcell.KeyUp {...Is it related to this?
Note: I am on MacOs