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.
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.