GNOME Bugzilla – Bug 613728
Rationalize GtkTreeView focus
Last modified: 2018-02-10 03:41:10 UTC
There are several problems with focusing in GtkTreeView: * It is not always obvious when the tree has the focus; this is wrong. If the tree is focused, regardless of selection mode or whether it has any rows at all, it should always be visually obvious that the tree indeed has the focus. Right now, there may or may not be a dotted line around the selected row, depending on whether you clicked on the row or moved to it with the Up/Down keys. A tree with zero rows may or may not have a dotted line around it depending on the theme. * Focusing a treeview may change its selection; this is wrong. See bug #492206 for a patch to fix GTK_SELECTION_SINGLE. For GTK_SELECTION_BROWSE, we should a) focus the tree, and show a dotted line around the first row, but don't change the selection; b) actually select a row once the user actually navigates inside the tree. * If the treeview doesn't have focus, then hitting Tab to focus it will focus the headers. This is wrong. The actual content area should get the focus first, and *then* hitting Shift-Tab should let you focus the headers.
(In reply to comment #0) > * It is not always obvious when the tree has the focus; this is wrong. If the > tree is focused, regardless of selection mode or whether it has any rows at > all, it should always be visually obvious that the tree indeed has the focus. > Right now, there may or may not be a dotted line around the selected row, > depending on whether you clicked on the row or moved to it with the Up/Down > keys. The dotted line is only drawn when the last "navigation" that occurred was triggered by the keyboard. As soon as the mouse is used again the dotted line is no longer drawn. This has been implemented like this in tree view since the early beginning and can be described as a "feature". I do not know why it was implemented like this, neither do I have an idea whether this is wrong or correct. I can certainly agree with your argument that this is inconsistent. When a tree has rows, but no selection, there can be a case where you cannot differentiate between focused or not focused using the color of the selection background, and a dotted line is not visible. > A tree with zero rows may or may not have a dotted line around it > depending on the theme. By default a dotted line is drawn, again this might depend on the keyboard/mouse state (unsure). If themes can override this behavior, well ... > * Focusing a treeview may change its selection; this is wrong. See bug #492206 > for a patch to fix GTK_SELECTION_SINGLE. For GTK_SELECTION_BROWSE, we should > a) focus the tree, and show a dotted line around the first row, but don't > change the selection; b) actually select a row once the user actually navigates > inside the tree. The behavior you describe for GTK_SELECTION_BROWSE has been implemented somewhere and has been discussed on bugzilla in the past, but I cannot recall in which bug so quickly. There have been arguments in favor of and against changing selection on focus in the past, again I cannot recall where so quickly, I would need to find the time to dig this up. > * If the treeview doesn't have focus, then hitting Tab to focus it will focus > the headers. This is wrong. The actual content area should get the focus > first, and *then* hitting Shift-Tab should let you focus the headers. Fully agree with this. What should happen in this case when you hit tab when the tree view has focus? Should the focus go to the header as well or to the next widget in the chain? For the latter case, then the headers are not in the focus chain "by default" (unless you use shift-tab) -- are there any a11y issues with this?
(In reply to comment #1) > The dotted line is only drawn when the last "navigation" that occurred was > triggered by the keyboard. As soon as the mouse is used again the dotted line > is no longer drawn. This has been implemented like this in tree view since the > early beginning and can be described as a "feature". I do not know why it was > implemented like this, neither do I have an idea whether this is wrong or > correct. I can certainly agree with your argument that this is inconsistent. I think it's inconsistent and overkill :) It's just easier to always show a focus indicator. > When a tree has rows, but no selection, there can be a case where you cannot > differentiate between focused or not focused using the color of the selection > background, and a dotted line is not visible. Correct. In this case the cursor row should be dotted. > > A tree with zero rows may or may not have a dotted line around it > > depending on the theme. > > By default a dotted line is drawn, again this might depend on the > keyboard/mouse state (unsure). If themes can override this behavior, well ... Yeah, the theme is broken :) I just checked murrine's source, and it has different code for drawing a treeview's background and the background of rows. We need to check the popular themes to see if they do the right thing. > The behavior you describe for GTK_SELECTION_BROWSE has been implemented > somewhere and has been discussed on bugzilla in the past Doesn't work for me in 2.18.6, and gtk_tree_view_focus_to_cursor() will call _real_set_cursor(clear_and_select=TRUE) for BROWSE. So this is not implemented. > in which bug so quickly. There have been arguments in favor of and against > changing selection on focus in the past, again I cannot recall where so > quickly, I would need to find the time to dig this up. Thanks, it would be helpful to look at those arguments, but I think it's wrong to change the selection upon focusing. You don't expect a toggle button to change its state when you focus it; you don't expect data to change when you use FocusFollowsMouse and shove the mouse around, etc. > > the headers. This is wrong. The actual content area should get the focus > > first, and *then* hitting Shift-Tab should let you focus the headers. > > Fully agree with this. What should happen in this case when you hit tab when > the tree view has focus? Should the focus go to the header as well or to the > next widget in the chain? The next widget in the chain. > For the latter case, then the headers are not in the > focus chain "by default" (unless you use shift-tab) -- are there any a11y > issues with this? Hopefully not - the headers are still reachable, just not with forward-Tab always. Anyway, interacting with the list of items is *much* more common than using the headers; we shouldn't make the list of items hard to reach just because the headers are present.
(In reply to comment #2) > > The behavior you describe for GTK_SELECTION_BROWSE has been implemented > > somewhere and has been discussed on bugzilla in the past > > Doesn't work for me in 2.18.6, and gtk_tree_view_focus_to_cursor() will call > _real_set_cursor(clear_and_select=TRUE) for BROWSE. So this is not > implemented. With "somewhere" I meant to say that I didn't fully remember where this was done. Overnight I suddenly remembered; I wanted to refer to the up/down key handling. If a tree view has focus, but no selection, then on the first key up/down press the focus will not move but the currently focused row will be selected. On subsequent up/down key presses the focus (and selection) will then move. See bug 324480 for discussion. > Thanks, it would be helpful to look at those arguments, but I think it's wrong > to change the selection upon focusing. You don't expect a toggle button to > change its state when you focus it; you don't expect data to change when you > use FocusFollowsMouse and shove the mouse around, etc. Yes, I agree. > Hopefully not - the headers are still reachable, just not with forward-Tab > always. Anyway, interacting with the list of items is *much* more common than > using the headers; we shouldn't make the list of items hard to reach just > because the headers are present. It makes sense to me. In bug 312855 it was discussed that the headers should not be reachable at all with focus, but this was marked as WONTFIX. Changing the focus chain for the headers to be accessible with shift+tab would not break this decision, as the headers will still be reachable like you say. I am open for change in this area, as long as the a11y people / keynav authority (Calum Benson used to help us out with keynav issues occasionally) agree. I have been hesitant to change keynav things without feedback from them.
Created attachment 172374 [details] [review] gtk2-bgo613728-treeview-tab-focus.diff I've pushed this to master, gtk-2-24, and gtk-2-22. This makes the treeview focus the actual list, not the headers, when you first Tab into it. You can then hit Shift-Tab to focus the headers. This really makes keynav feel a lot nicer!
I just posted a patch on bug #492206 to make the treeview not change the selection, just the cursor row, when it gets focused. This makes it work very well, of course, as just focusing the tree no longer modifies the user's data. However, this uncovered another bug, which I filed as bug #656848. The treeview doesn't set a cursor_row if it already has the focus and you populate it afterwards - in that case, you get no focus indicator at all. I'm looking into this.
(In reply to comment #2) > (In reply to comment #1) > > The behavior you describe for GTK_SELECTION_BROWSE has been implemented > > somewhere and has been discussed on bugzilla in the past > > Doesn't work for me in 2.18.6, and gtk_tree_view_focus_to_cursor() will call > _real_set_cursor(clear_and_select=TRUE) for BROWSE. So this is not > implemented. > Perhaps the selection for GTK_SELECTION_BROWSE should be set as soon as the treeview is populated (or this mode set). That way as long as there is some data one of the rows is selected as the GTK_SELECTION_BROWSE would imply and no state changes on focusing the control.
(In reply to comment #6) > Perhaps the selection for GTK_SELECTION_BROWSE should be set as soon as the > treeview is populated (or this mode set). That way as long as there is some > data one of the rows is selected as the GTK_SELECTION_BROWSE would imply and no > state changes on focusing the control. Unfortunately this goes against the "GTK+ shouldn't pick an option for you" principle. I'm pretty sure I've seen other toolkits use the unselected-or-one-and-only-one scheme for lists, and it sounds like the right thing to do for GTK_SELECTION_BROWSE.
As there is no way to unselect something in a treeview UI other than selecting something else this is the only possible difference between GTK_SELECTION_BROWSE GTK_SELECTION_SINGLE from the user's point of view. When you create a radio group exactly one of the radio buttons is selected, too. And the callback which is triggered by frobbing the buttons is called only when the another button is selected by the user but not on showing the dialog with the group. Still you can query the group and exactly one button will be selected. This is not GTK picking an option for you. This is the programmer picking an option for you by instantiating a control that automatically has some option selected. The UI is presented to the user for the possibility to make a different selection than the default but it is made so that it is not possible to select nothing so long there are some options to select from.
(In reply to comment #8) > As there is no way to unselect something in a treeview UI other than selecting > something else this is the only possible difference between > GTK_SELECTION_BROWSE GTK_SELECTION_SINGLE from the user's point of view. You can unselect a row by control-clicking a selected row. (But not in BROWSE mode, because the point of that mode is to always have a row selected).
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue for it.