X Event signals

The Widget class has some special signals which correspond to the underlying X-Windows events. These are suffixed by _event; for instance, Widget::signal_button_press_event().

You might occasionally find it useful to handle X events when there's something you can't accomplish with normal signals. Gtk::Button, for example, does not send mouse-pointer coordinates with its clicked signal, but you could handle button_press_event if you needed this information. X events are also often used to handle key-presses.

These signals behave slightly differently. The value returned from the signal handler indicates whether it has fully "handled" the event. If the value is false then gtkmm will pass the event on to the next signal handler. If the value is true then no other signal handlers will need to be called.

Handling an X event doesn't affect the Widget's other signals. If you handle button_press_event for Gtk::Button, you'll still be able to get the clicked signal. They are emitted at (nearly) the same time.

Note also that not all widgets receive all X events by default. To receive additional X events, you can use Gtk::Widget::set_events() before showing the widget, or Gtk::Widget::add_events() after showing the widget. However, some widgets must first be placed inside an EventBox widget. See the Widgets Without X-Windows chapter.

Here's a simple example:

bool on_button_press(GdkEventButton* event);
Gtk::Button button("label");
button.signal_button_press_event().connect( sigc::ptr_fun(&on_button_press) );

When the mouse is over the button and a mouse button is pressed, on_button_press() will be called.

GdkEventButton is a structure containing the event's parameters, such as the coordinates of the mouse pointer at the time the button was pressed. There are several different types of GdkEvent structures for the various events.

Signal Handler sequence

By default, your signal handlers are called after any previously-connected signal handlers. However, this can be a problem with the X Event signals. For instance, the existing signal handlers, or the default signal handler, might return true to stop other signal handlers from being called. To specify that your signal handler should be called before the other signal handlers, so that it will always be called, you can specify false for the optional after parameter. For instance,

button.signal_button_press_event().connect( sigc::ptr_fun(&on_mywindow_button_press), false );

The event is delivered first to the widget the event occurred in. If all signal handlers in that widget return false (indicating that the event has not been handled), then the signal will be propagated to the parent widget and emitted there. This continues all the way up to the top-level widget if no one handles the event.