The gtk+ key handling system

As far as I am concerned, gtk+ uses two systems of keypress handling:

  1. Key Accelerators
  2. static gint gtk_*_key_press[_event] (GtkWidget *widget, GdkEventKey *event) functions

The key accelerators are used to tell the widget to "activate". I haven't explored them very much, as they are almost exclusive to menu items. There is probably more to them, however.

The work I have been focusing on deals with the gtk_*_key_press[_event] functions for the various widgets that have them. Essentially, any widget that must deal with keyboard input on a regular basis has a function of the form:

static gint gtk_<widget name>_key_press (GtkWidget *widget, GdkEventKey *event)
or
static gint gtk_<widget name>_key_press_event (GtkWidget *widget, GdkEventKey *event)

There are a few exceptions, but this is the general form.

Each of these functions are usually one large switch statement (in the case of a widget that has only one or two keys to respond to, it may even be a simple if) comparing the keyval and state of the incoming GdkEventKey to the key (e.g. the right arrow) and keyboard mask (e.g. ctrl, shift, or alt) that it should respond to.

Staring blankly at all of these switch statements eventually led me to a realization. For any given keypress, a widget will have a very small and well defined number of possible reactions. All of these reactions are defined by the switch and if statements. There are no other reactions (except no reaction, which is taken care of by simply doing nothing).

It therefore became evident to me that any system I made would contain a set of possible actions that a widget might perform, and a corresponding list of keypresses that would trigger each particular response.

With this in mind, I went through all of the widgets using these gtk_*_key_press functions and built a text file of all the events and what keypresses trigger them by default that I could easily figure out. They are the remainder of this page, in alphabetical order... :D


The Actions/Keys:

Legend: all the funky keys in here (like right arrow, left arrow, tab, etc.) are represented by their entries in the gdk/gdkkeysyms.h file. They should be fairly straightforward.

GtkCalendar (gtkcalendar.c) in function gtk_calendar_key_press:
        GTK_CALENDAR_SEL_UP - GDK_Up
                - move date selection box up
        GTK_CALENDAR_SEL_DOWN - GDK_Down
                - move date selection box down
        GTK_CALENDAR_SEL_LEFT - GDK_Left
                - move date selection box to the left
	GTK_CALENDAR_SEL_RIGHT  - GDK_Right
	        - move date selection box to the right
        GTK_CALENDAR_SEL_SEL  - GDK_Space
                -  give currently highlighted date (under the
                   selection box) focus (changes months if selected
                   date belongs to an adjacent month
        GTK_CALENDAR_MONTH_NEXT - <ctrl> + GDK_Right
	        - moves the calendar to the next month
        GTK_CALENDAR_MONTH_PREV - <ctrl> + GDK_Left
	        - move calendar to the previous month
        GTK_CALENDAR_YEAR_PREV - <ctrl> + GDK_Up
	        - move calendar to previous year
        GTK_CALENDAR_YEAR_NEXT - <ctrl> + GDK_Down
                - move calendar to next year
GtkCList (gtkclist.c) in function gtk_clist_keypress:
        GTK_CLIST_FOCUS_FORWARD - GDK_Tab, GDK_ISO_Left_Tab
	        - put focus on the next widget in the clist
	GTK_CLIST_FOCUS_BACKWARD - <shift> + GDK_Tab, <shift> + GDK_ISO_Left_Tab
	        - put focus on the previous widget in the clist
GtkCombo (gtkcombo.c) in function gtk_combo_list_key_press
        GTK_COMBO_ENTRY_UNSELECT - GDK_Escape
                - hide self if popped up, else unselect item

                      in function gtk_combo_entry_key_press
        GTK_COMBO_ENTRY_AUTOCOMPLETE - <alt> + GDK_Tab
	        - attempt to autocomplete a text entry
        GTK_COMBO_ENTRY_PREV - GDK_Up, GDK_KP_Up, <alt> + p, <alt> + P
                - select previous entry in combo list
        GTK_COMBO_ENTRY_NEXT - GDK_Down, GDK_KP_Down; <alt> + n, <alt> + N
                - select next entry in combo list

                      in function gtk_combo_window_key_press
        GTK_COMBO_ENTRY_SEL - GDK_Return, GDK_KP_Enter
                - hide self if popped up, keep selection
GtkDnD (gtkdnd) in function gtk_drag_key_cb
        GTK_DND_ABORT_DND - GDK_Escape
	        - abort a drag and drop operation

                in function gtk_drag_get_event_actions
	GTK_DND_ACTION_LINK - <ctrl> + <shift>
		- make a DND operation a 'link'
	GTK_DND_ACTION_COPY - <ctrl>
		- make a DND operation a 'copy'
	GTK_DND_ACTION_MOVE - <shift>
		- make a DND operation a 'move'
	GTK_DND_ACTION_ASK - <alt>
		- inquire about a DND operation? 
GtkEntry (gtkentry.c) in function gtk_entry_key_press
        GTK_ENTRY_DELETE_CHAR_PREV - GDK_Backspace 
                - delete previous character (or selection)
        GTK_ENTRY_DELETE_WORD_PREV - <ctrl> + GDK_Backspace
                - delete previous word    (or selection)
        GTK_ENTRY_DELETE_LINE - GDK_Clear
                - delete current line
        GTK_ENTRY_CLIPBOARD_PASTE - <shift> + GDK_Insert
                - insert from clipboard
        GTK_ENTRY_CLIPBOARD_COPY - <ctrl> + GDK_Insert	
                - copy to clipboard
        GTK_ENTRY_INSERT_TOGGLE - GDK_Insert
                - toggle insert (not implemented)
        GTK_ENTRY_CLIPBOARD_CUT - <shift> + GDK_Delete  
                - delete selection and copy to clipboard
        GTK_ENTRY_DELETE_CHAR_NEXT - GDK_Delete
	        - delete next character (or selection)
	GTK_ENTRY_DELETE_WORD_NEXT - <ctrl> + GDK_Delete
		- delete next word
        GTK_ENTRY_CURSOR_TO_LINE_BEGINNING - GDK_Home
	        - move cursor to beginning of line
        GTK_ENTRY_CURSOR_TO_LINE_END - GDK_End
                - move cursor to end of line
        GTK_ENTRY_SELECTION_LEFT - <shift> + GDK_Left
                - extend/shrink selection one character to the left
        GTK_ENTRY_CURSOR_BACK_WORD - <ctrl> + GDK_Left
                - move cursor back one word
	GTK_ENTRY_CURSOR_BACK_CHAR - GDK_Left
                - move cursor back one character
        GTK_ENTRY_SELECTION_RIGHT - <shift> + GDK_Right
                - extend/shrink selection one character to the right
        GTK_ENTRY_CURSOR_FORWARD_WORD - <ctrl> + GDK_Right
                -  move cursor forward one word
        GTK_ENTRY_CURSOR_FORWARD_CHAR - GDK_Right
                -  move cursor forward one character
        GTK_ENTRY_ACTIVATE - GDK_Return
                - 'gtk_widget_activate (widget);'
        GTK_ENTRY_IGNORE - GDK_Tab, GDK_Escape
	        - explicitly ignored and passed up to the parent so they don't end up in the text.

GtkFileSel (gtkfilesel.c) in function gtk_file_selection_key_press
        GTK_FILESEL_ACT_CHANGE - GDK_Tab
                - activate changes based on dir selections before
                  changing widget focus
GtkFontSel (gtkfontsel.c) in function gtk_font_selection_on_clist_key_press
        GTK_FONTSEL_FONT_PREV - GDK_Up
                - select previous font in clist
        GTK_FONTSEL_FONT_NEXT - GDK_Down
                - select next font in clist
GtkNotebook (gtknotebook.c) in function gtk_notebook_key_press
        GTK_NOTEBOOK_UP - GDK_Up
                - move based on tab positions or something
                        select current page if tabs are along bottom
        GTK_NOTEBOOK_LEFT - GDK_Left
                - move based on tab positions or something
                  select current page if tabs are on right
        GTK_NOTEBOOK_DOWN - GDK_Down
                - move based on tab positions or something
                  select current page if tabs are on top
        GTK_NOTEBOOK_RIGHT - GDK_Right
                - yes, there is a pattern here
        GTK_NOTEBOOK_TAB_NEXT - GDK_Tab;GDK_ISO_Left_Tab
                - move to next tab/widget
        GTK_NOTEBOOK_TAB_FIRST - GDK_Home
                - go to first tab
        GTK_NOTEBOOK_TAB_LAST - GDK_End
                - go to last tab
        GTK_NOTEBOOK_TAB_SEL - GDK_Return;GDK_space
                - select the currently highlighted page/tab
GtkOptionMenu (gtkoptionmenu.c) in function gtk_option_menu_key_press
        GTK_OPTION_MENU_POPUP_CHILD
                - pop up child menu
GtkPlug (gtkplug.c) in function gtk_plug_key_press_event
        GTK_PLUG_ACTIVATE_SELECTED - GDK_space
                - activate selected widget
	GTK_PLUG_ACTIVATE_DEFAULT - GDK_Return;GDK_KP_Enter
                - activate default widget, selected widget otherwise
	GTK_PLUG_DIR_UP - GDK_Up
                - pass it on
        GTK_PLUG_DIR_DOWN - GDK_Down
                - pass it on
        GTK_PLUG_DIR_LEFT - GDK_Left
                - pass it on
        GTK_PLUG_DIR_RIGHT - GDK_Right
                - pass it on
        GTK_PLUG_DIR_TAB_FORWARD - GDK_Tab
                - pass on tab
	GTK_PLUG_DIR_TAB_BACKWARD - <shift> + GDK_Tab
                - pass on backwards tab
GtkSpinButton (gtkspinbutton.c) in function gtk_spin_button_key_press
        GTK_SPIN_BUTTON_UP_LITTLE - GDK_Up
                - spin a bit
        GTK_SPIN_BUTTON_DOWN_LITTLE - GDK_Down
                - spin a bit
        GTK_SPIN_BUTTON_UP_LOTS - GDK_Page_Up
                - spin a lot
        GTK_SPIN_BUTTON_DOWN_LOTS - GDK_Page_Down
                - spin a lot
GtkText (gtktext.c) in function gtk_text_key_press
        GTK_TEXT_TO_TOP - <ctrl> + GDK_Home
                - cursor to top of area
	GTK_TEXT_TO_LINE_BEGINNING - GDK_Home
                - cursor to line beginning
        GTK_TEXT_TO_BOTTOM - <ctrl> + GDK_End
                - cursor to bottom of area
	GTK_TEXT_TO_LINE_END - GDK_End
                - bring selection with you
        GTK_TEXT_PAGE_UP - GDK_Page_Up
                - page up
	GTK_TEXT_PAGE_DOWN - GDK_Page_Down
                - page down
        GTK_TEXT_TO_PREV_ROW - GDK_Up
                - move up a row
        GTK_TEXT_TO_NEXT_ROW - GDK_Down
                - move down a row
        GTK_TEXT_BACK_CHAR - GDK_Left
                - move left a character 
        GTK_TEXT_BACK_WORD - <ctrl> + GDK_Left
		- move left a word
	GTK_TEXT_FORWARD_CHAR - GDK_Right
                - move right a character
	GTK_TEXT_FORWARD_WORD - <ctrl> + GDK_Right
		- more right a word
	GTK_TEXT_DELETE_WORD_PREV - <ctrl> + GDK_Backspace
                - delete prev word
	GTK_TEXT_DELETE_CHAR_PREV - GDK_Backspace
                -  delete prev char
        GTK_TEXT_DELETE_LINE - GDK_Clear
                - delete line
        GTK_TEXT_CLIPBOARD_PASTE - <shift> + GDK_Insert
                -  paste
	GTK_TEXT_CLIPBOARD_COPY - <ctrl> + GDK_Insert
                -  copy
	GTK_TEXT_TOGGLE_INSERT - GDK_Insert
                - toggle insert (not implemented)
        GTK_TEXT_DELETE_WORD_NEXT - <ctrl> + GDK_Delete
                - delete next word
	GTK_TEXT_DELETE_CHAR_NEXT - GDK_Delete
                -  delete next char
	GTK_TEXT_CLIPBOARD_CUT - <shift> + GDK_Delete
		- cut selection to clipboard
        GTK_TEXT_INSERT_TAB - GDK_Tab
                - INSERT A TAB CHARACTER!
        GTK_TEXT_ACTIVATE_TEXT - <ctrl> + GDK_Return
                - activate text(?)
	GTK_TEXT_INSERT_NEWLINE - GDK_Return
                -  insert a newline!
	GTK_TEXT_IGNORE - GDK_Escape
                explicitly ignored so as not to end up in the text
	GTK_TEXT_SHIFT_MASK - <shift>
		 - modifier key used to make each motion involve the current
		   selection: used to change selection's size
GtkWindow (gtkwindow.c) in function gtk_window_key_press_event
        GTK_WINDOW_ACTIVATE_SELECTED - GDK_space
                - activate the widget with focus
        GTK_WINDOW_ACTIVATE_DEFAULT - GDK_Return;GDK_KP_Enter
                - activate default widget, selected if no default
        GTK_WINDOW_SEL_UP - GDK_Up;GDK_KP_Up
                - move focus in the direction pressed
        GTK_WINDOW_SEL_DOWN - GDK_Down;GDK_KP_Down
                - move focus in the direction pressed
        GTK_WINDOW_SEL_LEFT - GDK_Left;GDK_KP_Left
                - move focus in the direction pressed
        GTK_WINDOW_SEL_RIGHT - GDK_Right;GDK_KP_Right
                - move focus in the direction pressed
        GTK_WINDOW_SEL_TAB_FORWARD - GDK_Tab;GDK_ISO_Left_Tab
                - move focus in the direction pressed
	GTK_WINDOW_SEL_TAB_BACKWARD - <shift> + GDK_Tab; <shift> + GDK_ISO_Left_Tab
                - move focus backwards tabbed-like