This note describes areas where implementation of keynav for panels was difficult. - PanelWidget and objects on the panel such as launchers and applets need to be focusable Both the PanelWidget and objects on the panel need to be focusable in order to invoke the context menu using only the keyboard. In the normal course of things, GTK+ does not support a widget and its children be focusable. Instead of requiring the PanelWidget be focusable we have introduced a key binding Ctrl+F10 which pops up the panel's context menu. So a PanelWidget is focusable only when it does not have any children. There is, therefore, no need for the key binding Ctrl+Tab to move the focus to the PanelWidget from an applet or a launcher. The function panel_widget_real_focus is PanelWidget's default signal handler for focus signal. This function is called when either PanelWidget or a child has focus and Tab or arrow keys are used to move focus. If the PanelWidget has focus and the PanelWidget has children the GTK_CAN_FOCUS flag is unset so that a child can receive focus. - An applet with a tooltip receives focus If an applet has a tooltip, the applet will receive focus so that the tooltip can be displayed, even if the applet contains focusable widgets. The focusable widgets in the applet can be traversed using the arrow keys. - Tab should move focus from within an applet to the next object on the panel This is implemented by defining an action signal "move_focus_out_of_applet" on MatePanelApplet and binding Tab and Shift+Tab to this action. When focus is in an applet the event is passed to the focus widget then its children until a toplevel is reached unless the event is handled. This is done in gtk_window_key_press_event(). The original implemementation for "move_focus_out_of_applet" had the action signal defined on MatePanelAppletFrame but as a GtkSocket always reports a key press event as being handled when the GtkPlug is in a different process, the event has not passed to the MatePanelAppletFrame. The implementation for "moving_focus_out_of_applet" sets a flag moving_focus_out so that the function mate_panel_applet_focus() which is MatePanelApplet's default signal handler for focus signal will not attempt to move the focus within the applet if this flag is set. - Implementing key bindings If focus is in an applet which is in another process, the GtkSocket will report the key stroke as having been handled. This means that key bindings will not be activated. The workaround for this is to handle those key strokes in panel_event() a signal handler for the event signal in panel.c. However, we only want to handle some keybindings, for example we do not want to handle Shift+F10, which displays the context menu, and Ctrl+F1, which displays the tooltip, but we do want to handle Ctrl+F10 which displays the panel's context menu. - Focus indication We need a mechanism that will make visible which panel has focus. We also need to do this without impacting current behaviour. We set the state of a PanelWidget to GTK_STATE_SELECTED whan focus is in a PanelWidget. We provide a default panel rc file mate-panelrc, which is installed in $(datadir). This rc file sets the default default color for SELECTED for any widget which is a descended from a PanelWidget or MatePanelApplet to be the same as the NORMAL colour. If there is a requirement to make panel focus indication visible, the following lines added to ~/.gtkrc-2.0 will make a selected panel prelight color. style "prelight-selected" { fg[SELECTED] = { 0, 0, 0 } bg[SELECTED] = { 0xea60, 0xea60, 0xea60 } } widget_class "*PanelWidget*" style "prelight-selected" widget_class "*MatePanelApplet*" style "prelight-selected"