Re: keynav question



Tapan,

I have attached notes I made a few months ago about how keynav works,
I believe that they are accurate. If you have further questions I will try to 
help.

Padraig

> 
> 
> Hello, 
> 
> I am working on a Gtk app where i want to have some standard
> keyboard / icon based navigation to shift focus between widgets /
> screens.
> 
> I see from some stuff at developer.gnome.org that this is already
> being done to a certain extent.  Now my question is
> 
> - Where is the keyboard nav code to be found?  Where can i see how
> the keyboard events are handled and processed?  (Im somewhat new w/
> Gtk so the more specificity the better... ;)
> 
> Presumably this will allow me to answer my 2nd question...
> 
> - How can i emit these signals myself?
> 
> Thanks for your help,
> Tapan
> 
> ---------------------------------------------------
> Tapan Parikh
> tap2k yahoo com
> http://www.cs.washington.edu/homes/tapan/
> 
> 
> 
> 
> _______________________________________________
> gtk-devel-list mailing list
> gtk-devel-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-devel-list
Normally, focus is moved from widget to widget by pressing Tab, Shift+Tab and
the arrow keys.

In the file gtkwindow.c the action signal "move_focus" is defined. There are
a number of calls to gtk_binding_entry_add_signal() which define how 
move_focus signal handler should be called in response to a particular key 
strokes, i.e. Tab, Shift+Tab and arrow keys. These are the key bindings for 
the top level.  

I digress to discuss how a key_press_event is handled. A key press will cause
a key_press_event signal to be emitted on the GtkWindow; this happens in 
gtkmain.c but we do not need to go there for this discussion. As this
signal, defined in gtkwidget.c, is a RUN_LAST signal, any signal
handlers defined for that signal are executed before the default signal handler,
which is gtk_window_key_press_event(). This function first
checks whether the key press is a mnemonic or accelerator and, if so,
handles it (_gtk_window_activate_key). If there is a focus widget, the
key press event is passed to the focus widget to be handled (gtk_widget_event).
If not handled it is passed up the hierarchy to the parent widgets. If no
widget has handled the event the parent class's key_press_event function
is called. This causes gtk_widget_real_key_press_event() to be called which
activates the binding defined for the event on the window. This is what causes
the function gtk_window_move_focus() to be called when, for example, Tab is 
pressed to move focus.

The function gtk_window_move_focus() calls gtk_widget_child_focus(). This 
function emits a "focus" signal on the calling widget, which in this case
is a GtkWindow and this causes gtk_window_focus() to be called.

When a widget has focus each GtkContainer in the hierarchy between the
GtkWindow and the focus widget has focus_child set to the ancestor of the
focus widget.

The function gtk_window_focus() normally causes gtk_widget_child_focus() to be
called for the focus_child of the window. Note that the focus_child for the 
window is different from the focus_widget for the window.

The most important file for understanding how focus movement works is 
gtkcontainer.c as most widgets in the hierarchy derive from GtkContainer. 
The function gtk_container_focus() is GtkContainer's default signal handler 
for "focus" signal.

The function gtk_container_focus() does not permit a GtkContainer and its
children to be focusable. 

The function gtk_container_focus() builds a list of the children using the
requested direction to determine the order of the children in the list and
then moves focus to the next child.

There are  number of problems in this area with the arrow keys (e.g.
bug 60690) but they are not easy to fix.

A particular widget, e.g. GtkEntry for the key stroke GDK_Left, can override 
this action by defining its own key bindings. These key bindings are activated
when the widget has focus, by the default key_press event signal handler for 
GtkWidget, the function gtk_widget_real_key_press_event referred to earlier.


Keyboard navigation for menus uses something completely different. 

Activation of the menu bar using F10. 

In gtksettings.c, the default keybinding to activate the menu bar is specified 
as F10. When a GtkMenuBar is added to the widget hierarchy, 
gtk_widget_set_parent() is called for the GtkMenuBar. This function emits
the signal "hierarchy-changed". GtkMenuBar defines a default signal
handler for that signal, gtk_menu_bar_hierarchy_changed(). This function
calls add_to_window() which defines a signal handler, window_key_press_handler,
for the signal key_press_event, for the first GtkMenuBar added to the 
GtkWindow. This means that when there is a GtkMenuBar in the GtkWindow, every 
keystroke will cause the function window_key_press_handler() to be called before
the default signal handler gtk_window_key_press_event_handler discussed
earlier.. If the key was F10, the activate_item signal is emitted for the 
first child of the GtkMenuBar.

The default signal handler for this signal, gtk_menu_item_real_activate_item,
calls gtk_grab_add() and pops up a window. This has the effect that when an 
event is processed in gtk_main_do_event() the event is sent to the window of
the popped up menu.

The comments the block Terminology in gtkmenushell.c are useful in
understanding menu navigation and the appropriate terminology.

Navigating of menus and menubars is controlled by the action signal defined in
gtkmenushell.c Both GtkMenuBar and GtkMenu, which derive from GtkMenuShell,
define key bindings (the arrow keys) for move_current and the default signal 
handler for move_current is gtk_real_menu_shell_move_current() actually moves
the current menu item.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]