Keynav implementation issues
- From: Owen Taylor <otaylor redhat com>
- To: gtk-devel-list gnome org
- Cc: padraig obriain sun com
- Subject: Keynav implementation issues
- Date: 12 Oct 2001 01:58:11 -0400
The following is a list of "hard" implementation issues I'm aware of
in the outstanding keynav bugs, with some thoughts about possible ways
of dealing with them. (This isn't meant to list issues which are
questions of "what should we do" just issues of "how do we do it".)
There are more questions in the following than answers, but hopefully
listing this stuff will allow us to move forward in figuring out
the right way to handle each problem.
If you know of additional issues I've missed here, please let me know.
Regards,
Owen
Bindings on parent widgets:
The keynav design calls for various bindings on widgets that should
take effect if focus is on any child widgets. This include:
Ctrl-PgUp/PgDown to switch pages in a notebook
Ctrl-Tab to focus out of notebook
F8 to focus through GtkPaned splitter bars "currently in context"
F6 to to focus among panes "currently in context"
The Swing key binding system has a concept where key bindings can:
- Apply only when the widget has focus
- Apply when the widget or any child has focus
- Apply when any widget in the same toplevel has focus
While something like this could be implemented in GTK+, it probably
is overkill. There are various possibilities:
- Hack all such keybindings into GtkWindow.
- When focus is moved inside such a widget, set up a temporary
signal connection on the toplevel and handle keystrokes there.
- Make GTK+ propagate keystrokes not just to the focus widget
then to the toplevel but through all intermediate widgets
as well.
I suspect the last one is the best solution, though there is some
risk of unintended side effects if you have nested widgets taking
key input.
Remembering the "last focus" within a child widget.
The keynav spec specifies that when switching between pages of a
notebook with Ctrl-PgUp/PgDown or between panes with F6, the last
focused widget in each page or tab is remembered and returned to.
You can almost keep track of what descendent of a container has focus
by watching calls to set_focus_child(), however this doesn't quite
work because toplevel->focus_widget isn't set at this point. This
could be gotten around by setting up a temporary connection to
::set_focus on the toplevel whenever you get a call to
::set_focus_child with child != NULL. Or we could change it so we:
unset the old container focus widgets
set toplevel->focus_widget
set the container focus widgets
(This would require moving some code from
gtk_widget_real_grab_focus() to gtk_window_real_set_focus())
Keynav for toolbars:
The keynav spec specifies that F10 switches between all menus and
toolbars in the current window. Keynav in menus in GTK+ is not
currently handled through the focus system. However, toolbars can
contain normal widgets entries in them and probably need to go
through the normal focus system.
(This does raise the issue that if you things like a location entry
in a toolbar, the location entry possibly should be part of the main
focus chain.)
Padraig's current patch in #54047 takes the approach of making key
navigation in toolbars work like that menus - with a grab and
handling keystrokes more or less directly without having the focus.
A different approach would be to handle key navigation in a GtkMenu
with menus popped down through the normal focus system. (But not put
menu bars and toolbars in the normal focus chain.) So, F10 would
focus the menu bar, toolbar, etc, but not establish a grab. The grab
would only be established when the first menu was popped up.
(There would then need to be some mechanism for saving the focus
within the main window since the focus was actually being moved;
this is related to the above issue.)
Mnemonics activation without alt:
The proposal suggests that if the current control doesn't accept
keyboard input, then mnemonics should be accessible without
the Alt key.
One way that it might be possible to do this is to handle
unmodified mnemonics in gtk_widget_real_key_press_event(); if
a keystroke was not otherwise intercepted, then it would
be interpreted as a menomic. Problems with this are:
- There is no requirement currently for widgets to chain
up their key_press handlers - they can simply call
gtk_bindings_activate() themselves.
- If a widget handled only some unmodified keystrokes and
not others, the result could be quite confusing.
A different technique would be to have some sort of widget
flag "handles_custom_key_input" and do processing of
unmodified mnemonics only if the focus widget didn't have
that flag set. I don't particularly like this idea though -
people are likely to forget to set/clear this flag; plus
it just doesn't seem to be the "GTK+ way".
A simpler fallback (also suggested) would be to make whether
unmodified mnemonics are allowed as a GtkWindow property,
which could be defaulted to the correct value for
GtkMessageBox.
Popping down tooltips
(I'm not sure if there was a final decision on what the desired
behavior was. In some experimentation, it seemed to me that
what might be nice would be if Ctrl-F1 put the window into
a "keyboard tooltips mode" where the tooltip was always displayed
for the currently focused widget and never for the mouse,
and Escape would cancel that mode. Perhaps focusing out of the
toplevel would deactivate the mode as well.)
When a tooltip is popped up via the Ctrl-F1 binding, Escape should
pop it back down. This poses a problem because Escape has a different
function that should take unless tooltips are popped up.
If you are willing to hard-code Escape, there are multiple ways
of doing this - just hardcoding it into gtk_window_key_press()
would be the simplest. A little more general than hardcoding
would be to do it like F10 is currently handled - as a string
setting that is converted into a key stroke.
A more general approach would be to add an idea of an "optional
keybinding" - if the action signals connected to a key
binding have boolean return values and they all return FALSE,
then the key press is considered not handled.
(I don't think the gtk_binding_set_enable_signal() approach taken
in the patch attached to #53614 is quite right because we only
know the default binding set, not every binding set that might
be attached to a widget, and, what's more, the default binding
set is global to the entire application, and in GTK+-2.2, will
be global across all displays. An enable/disable API would have
to be on a signal/widget basis, not a signal/binding-set basis.
But using signal return values may be nicer.)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]