Event signals are emitted as a result of some user input, for instance a key press
or a mouse motion. Usually you don't handle these events directly. Instead, you use
a subclass of Gtk::EventController
, such as Gtk::EventControllerKey
or Gtk::GestureClick
. Event controllers can be added to a
widget with Gtk::Widget::add_controller()
.
You might occasionally find it useful to handle 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
Gtk::GestureClick::signal_pressed()
if you needed this
information. Gtk::EventControllerKey::signal_key_pressed()
is often used to handle key-presses.
Some event controller 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 event doesn't affect the Widget's other signals. If you handle
Gtk::GestureClick::signal_pressed()
for
Gtk::Button
, you'll still be able to get the
clicked
signal. They are emitted at (nearly) the same time.
Here's a simple example:
void on_button_press(int n_press, double x, double y); Gtk::Button button("label"); auto controller = Gtk::GestureClick::create(); controller->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); controller->signal_pressed().connect(sigc::ptr_fun(&on_button_press)); button.add_controller(controller);
When the mouse is over the button and a mouse button is pressed,
on_button_press()
will be called.
The call to set_propagation_phase()
is necessary in
this case because the GtkButton
C class adds an event
controller, handling button clicks in the capture phase. GtkButton
claims the event, meaning that the event is not propagated in the bubble phase,
where event controllers handle events by default.
By default, signal handlers that return void are called after
any previously-connected signal handlers. However, this can be a problem with
event signals that can stop event propagation by returning true
.
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,
you can specify false
for the after
parameter.
This connect()
parameter is optional, if the signal handler
returns void. For instance,
key_controller->signal_key_pressed().connect(sigc::ptr_fun(&on_mywindow_key_pressed), false);
The event is propagated between widgets in 3 phases.
The Input Handling chapter in the GTK documentation describes user input handling in more detail.