GNOME Bugzilla – Bug 53612
KEYNAV: GtkNotebook
Last modified: 2011-02-04 16:09:32 UTC
NB I've used the term "page label" here to refer to the label on a notebook page's tab control, to try and avoid using the word "tab" in different contexts too much! In containers such as the notebook control, the widget that has focus should take priority over the container when processing navigation keys-- e.g. in a multi-line input field on a notebook page, the input field should process the Ctrl+Tab shortcut, not the notebook. Navigate out of noteboook: - If last control on frontmost page of notebook has focus, pressing Tab should move focus to the first control after the notebook. - If the frontmost page label has focus, Shift+Tab should move focus to the last control before the notebook. - If any control on the frontmost page of the notebook (including its page label) has focus, Ctrl+Tab (*) should move focus to the first control after the notebook. - If any control on the frontmost page of the notebook (including its page label) has focus, Shift+Ctrl+Tab should move focus to the last control before the notebook. Navigate between page tabs: - When any page label has focus, left and right arrow keys should move focus to the previous/next page label without bringing that page to the front. (It's been suggested that this should *not* wrap around, I'm not sure about this). - When any control in the notebook has focus (including any page label), Ctrl+PgUp should bring the next tab to the front, and Ctrl+PgDn should bring the previous tab to the front. In either case, the control on the new frontmost page that last had focus is given focus again. (This should also wrap around or not, depending on what we decide to do in the left/right arrow key case above.) Navigate between page labels and page content: - When any page label has focus, pressing Enter should bring that page to the front but leave focus on the page label - When any page label has focus, pressing Tab or Ctrl+down arrow should give focus to the first control on that page, bringing the selected page to the front if necessary - When any control on the frontmost page has focus, pressing Ctrl+up arrow should give focus to that page's label. (*) Latest build of Sawfish (0.38) defaults to Ctrl+Tab for window-cycling-- we'd need to push back on this to support the proposed keybindings, as Ctrl+Tab is suggested here and elsewhere as the "navigate me out of this container" shortcut. [Check http://developer.gnome.org/projects/gap/keyboardnav.html for any later proposals that may not have filtered through to this bug report yet]
Created attachment 5627 [details] [review] Patch to gtk to address some of this bug
The attached patch address the following issues: 1) If any control on the frontmost page of the notebook (including its page label) has focus, Ctrl+Tab (*) should move focus to the first control after the notebook. If any control on the frontmost page of the notebook (including its page label) has focus, Shift+Ctrl+Tab should move focus to the last control before the notebook. 2) When any control in the notebook has focus (including any page label), Ctrl+PgUp should bring the next tab to the front, and Ctrl+PgDn should bring the previous tab to the front. In either case, the control on the new frontmost page that last had focus is given focus again. 3) When any page label has focus, pressing Tab or Ctrl+down arrow should give focus to the first control on that page, bringing the selected page to the front if necessary. 4) When any control on the frontmost page has focus, pressing Ctrl+up arrow should give focus to that page's label. For 1), 2) and 4) a signal move_focus_out, move_focus_page, move_focus_up is defined for the required operation and if an ancestor of the focus widget supports the required operation it happens. For 3) a signal move_focus and key bindings are defined in gtknotebook.c to implement the operation.
If the tab label has a mnemonic, should pressing the mnemonic focus the first widget in the page or the last focused widget in the page?
My vote would actually be that if a tab label has a mnemonic, using that mnemonic should bring that page to the front but leave focus on the tab label itself. Moving focus to a control other than the one you explicitly specify when you press an access key just doesn't feel right to me, and it's not something we do anywhere else. (Aside: we currently suggest in the HIG that tab labels shouldn't really have mnemonics anyway, but that is still subject to change...)
I think the idea of focusing the widget in the page is that the mnemonic on the tab label corresponds to the page, just as the mnemonic on a label next to an entry corresponds to the entry. That is the label itself is not the control the mnemonic applies to. Though this interpretation would suggest that tab labels should not be in the focus chain, maybe.
Well, if Havoc's interpretation is the one we want to put on it, I guess the focus should do whatever it does when you hit Ctrl+PgUp/Dn to flip between tabs, which is to move to the last-focused widget on that tab IIRC. (However, as he says, the analogy is slightly flawed, since with text boxes etc, the target widget itself doesn't have its own mnemonic in addition to its label's mnemonic, whereas in this case it does.) It still feels odd to me, though; if I press an access key, that's where my eye is looking, and therefore where I expect the focus to go. Of course, if people follow the HIG as it stands, the problem won't arise anyway :)
Hmmm, I see the tab-label mnemonic as a bit like the mnemonic on a label next to an entry, but it is true that you can click on the tab label and you can't on the entry label... I'm not sure that focusing the tab label is _useful_ even if it is consistent. But I've made it work that way for now. (As for the desirability of tab mnemonics, I just fix implement this stuff, I don't decide whether to use it or not :-) I just implemented the last-focus widget remembering for Ctrl-PageUp/Down and it seems a little odd to me because it ends up feeling rather unpredictable where the focus goes. I'm wondering if we should just (like windows) focus the first widget. [ An idea I had was that the ideal might be forgetting the last focus widget when "Control" was released, but even if this was easy to implement (it isn't at all), jrb opines that users wouldn't figure this out, and I may agree ] Tue Jan 15 12:23:33 2002 Owen Taylor <otaylor@redhat.com> * gtk/gtknotebook.c (gtk_notebook_mnemonic_activate_switch_page): focus the activated tab, not the page. (#53612) * gtk/gtknotebook.c (gtk_notebook_set_focus_child): Track the last focus descendant of the page. * gtk/gtknotebook.c (gtk_notebook_real_switch_page): If the focus was on the previous page, move it to the last focused widget / first element on the new page, if possible, or if not, to the notebook itself. (#68224, reported by Jonathan Blandford)
Adding GNOME2 keyword to all keynav bugs per sander's request. You can filter on the phrase 'luis doing GNOME2 work' to catch all instances of this so that you can ignore them.
The following commit fixes all known problems with GtkNotebook focusing. The only thing that might not be right is that t the Control-down=> in Control-up => out bindings rotate with the notebook. It could be argued that for accessibility reasons we should support the union of the tabs-on-the-left and tabs-on-the-top bindings. (Blind user doesn't care about where the tabs are.) But what would you do about tabs on right, tabs on bottom? Keeping it visually right seems to avoid a can of worms here. Thu Feb 7 19:52:00 2002 Owen Taylor <otaylor@redhat.com> * gtk/gtknotebook.[ch]: Add ::move-focus-out signal to handle Control[-Shift]-Tab and Control-arrow bindings and implement bindings as per #53612. * gtk/gtktextview.c (gtk_text_view_move_focus): Fix fetching the toplevel for plug-socket. * gtk/gtknotebook.c (gtk_notebook_class_init): Remove bindings for Return/Enter to select the page. * gtk/gtknotebook.c (gtk_notebook_change_current_page): Beep at ends. * gtk/gtknotebook.c (focus_tabs_move): Don't wrap around and beep at ends. * gtk/gtknotebook.c (gtk_notebook_focus): When focusing into the page with the arrow keys, focus the first widget, not the directionally closest widget.