Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Mail Systems
Eclipse Documentation

How To Guides
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Problem Solutions




Gtk+/Gnome Application Development
Prev Home Next

Receiving GDK Events in GTK+

In a GTK+ program, you will never receive GDK events directly. Instead, all events are passed to a GtkWidget, which emits a corresponding signal. You handle events by connecting handlers to GtkWidget signals.

The X server sends each X client a stream of events. Events are sent and received in the order of their occurrence. GDK converts each XEvent it receives into a GdkEvent, then places events in a queue. GTK+ monitors GDK's event queue; for each event received, it decides which widget (if any) should receive the event. The GtkWidget base class defines signals for most event types (such as "button_press_event"); it also defines a generic "event" signal. The GTK+ main loop calls gtk_widget_event() to deliver an event to a widget; this function first emits the "event" signal, then emits a signal for the specific event type (if appropriate). Some events are handled in special ways; notably, drag-and-drop events do not directly correspond to drag-and-drop signals.

In general, events go to the widget owning the GdkWindow the event occurred on. However, there are certain special cases.

if a widget has the grab (i.e., if gtk_grab_add() was called, see the section called Grabs in the chapter called GTK+ Basics), certain events will only be forwarded to the widget with the grab, or the children of that widget. Events that occur on other widgets are ignored. Only certain user-initiated events such as button events and key events are affected by a grab.

Widget sensitivity (see the section called Sensitivity in the chapter called GTK+ Basics) also affects where events are sent. Events representing user interaction are not forwarded to insensitive widgets.

As you might expect, widgets with no associated GdkWindow do not originate events; X only sends events to windows. There is one exception: containers synthesize expose events for their windowless children.

The GTK+ main loop propagates certain events from child widgets to their parent containers. That is, for each event, a signal is emitted first from a child widget, then from its immediate parent, then from the parent's parent, and so on. For example, if you click a GtkMenuItem, it ignores the button press and lets the menu it's a part of handle it. Some events are not propagated; Table 4 gives details.

Event propagation ends once a widget "handles" the event. This ensures that only one user-visible change results from any user action. Handlers for GtkWidget's event signals must return a gint value. Recall that the last signal handler to run determines the return value of a signal emission---see the section called Emitting A Signal in the chapter called The GTK+ Object and Type System. All event signals are GTK_RUN_LAST, so the return value will come from:

  • The last handler connected with gtk_signal_connect_after(), if any.

  • Otherwise, the widget's default signal handler, if any.

  • Otherwise, the last handler connected with gtk_signal_connect(), if any.

  • Otherwise, the default return value is FALSE.

If the emission of an event signal returns TRUE, the GTK+ main loop will stop propagating the current event. If it returns FALSE, the main loop will propagate the event to the widget's parent. Recall that each event results in two signal emissions: a generic "event" signal and a specific signal (such as "button_press_event" or "key_press_event"). If either emission returns TRUE, event propagation ends. The return value from the generic "event" signal has one additional effect: if TRUE, the second, more specific signal will not be emitted.

Table 4 summarizes how GtkWidget signals correspond to event types, which events are affected by an active grab, and which events are propagated from parent to child. Signal handlers for all event signals should return a gint and take three arguments: the widget emitting the signal, the event which triggered the signal, and a user data pointer.

Table 4. GtkWidget Events

Event Type GtkWidget Signal Propagated? Grabbed?
GDK_DELETE "delete_event" No No
GDK_DESTROY "destroy_event" No No
GDK_EXPOSE "expose_event" No No
GDK_MOTION_NOTIFY "motion_notify_event" Yes Yes
GDK_BUTTON_PRESS "button_press_event" Yes Yes
GDK_2BUTTON_PRESS "button_press_event" Yes Yes
GDK_3BUTTON_PRESS "button_press_event" Yes Yes
GDK_BUTTON_RELEASE "button_release_event" Yes Yes
GDK_KEY_PRESS "key_press_event" Yes Yes
GDK_KEY_RELEASE "key_release_event" Yes Yes
GDK_ENTER_NOTIFY "enter_notify_event" No Yes
GDK_LEAVE_NOTIFY "leave_notify_event" No Yes [PD] footnote!
GDK_FOCUS_CHANGE "focus_in_event", "focus_out_event" No No
GDK_CONFIGURE "configure_event" No No
GDK_MAP "map_event" No No
GDK_UNMAP "unmap_event" No No
GDK_PROPERTY_NOTIFY "property_notify_event" No No
GDK_SELECTION_CLEAR "selection_clear_event" No No
GDK_SELECTION_REQUEST "selection_request_event" No No
GDK_SELECTION_NOTIFY "selection_notify_event" No No
GDK_PROXIMITY_IN "proximity_in_event" Yes Yes
GDK_PROXIMITY_OUT "proximity_out_event" Yes Yes
GDK_CLIENT_EVENT "client_event" No No
GDK_VISIBILITY_NOTIFY "visibility_notify_event" No No
GDK_NO_EXPOSE "no_expose_event" No No
Gtk+/Gnome Application Development
Prev Home Next

  Published under free license. Design by Interspire