Re: Event Propagation problem



A long reply to a long question. The most interesting part is at the end of the reply.

The propagation of keyboard events is more complicated than the description in the Gtkmm tutorial shows. When I helped Pedro with the Keyboard Events chapter, he found this description:
http://faq.pygtk.org/index.py?file=faq03.011.htp&req=show
(If you're very interested, see bug https://bugzilla.gnome.org/show_bug.cgi?id=661857)

The last paragraph in the pygtk FAQ reads:

"Keyboard events are handled differently. When your window receives a keyboard event, it is first dispatched to the toplevel window, which will check if it matches any keyboard shortcuts. If the key press doesn't match a shortcut, then the event is dispatched to the child widget that currently has focus."

Because we were not sure if that still holds (written Nov 2002), we decided not to mention it in the gtkmm tutorial.

Now I looked in gtk+'s source code to see how events (especially keyboard events) are really handled.

Start at gtk_main_do_event(). The description of that function is incomplete. It does not at all mention the most interesting part of how keyboard events are handled, perhaps because that happens in gtk_propagate_event() to which the event is usually sent. The description of gtk_propagate_event() is equally incomplete. It does not send keyboard events to the window with keyboard focus, but to the toplevel window (GtkWindow, Gtk::Window in gtkmm). gtk_propagate_event() calls gtk_widget_event(), which emits the key-press-event or key-release-event signal. GtkWindow's default handler for the key-press-event first calls gtk_window_activate_key(), which activates mnemonics and accelerators. If gtk_window_activate_key() returns TRUE, the event is considered fully handled. If gtk_window_activate_key() returns FALSE, gtk_window_propagate_key_event() is called, and at last the event is sent to the widget with keyboard focus, and propagated as described in the gtkmm tutorial.

I think you actually have a chance to get the keyboard event before gtk_window_activate_key(). Connect your event handler to the key-press-event signal (and perhaps also to key-release-event) in the toplevel widget (Gtk::Window). Connect with after=false. Then your event handler will be called before GtkWindow's default event handler, and you have a chance to mark the event fully handled (by returning true) before gtk_window_activate_key() is called. Example (the 'false' parameter is important!):

window->signal_key_press_event().connect(sigc::mem_fun(*this, &MyWindow::on_key_event), false);

Kjell

2012-01-13 04:26, lecas malecas skrev:
Actually, I'm not sure if this would fix it, since you're using
accelerator keys (those keys could be checked first before the event
is emited in the widget?.. not sure).

If it doesn't work, try to have the shortcuts in an event function on
the Gtk::Window, instead of as an accelerator.

On Fri, Jan 13, 2012 at 1:17 AM, lecas malecas<darkiiiiii gmail com>  wrote:
You could try overriding the event functions (for example: virtual
bool on_key_press_event (GdkEventKey* event)).


On Thu, Jan 12, 2012 at 7:15 PM, Carlos Lopez Gonzalez
<carloslopezgonzalez yahoo es>  wrote:
Hi!
First of all I want to say sorry for the long post, but the existing code is
long to explain.
According to the Event Propagation lesson from the Grkmm Programming book,
one even that happens in a widget can be handled by it by connecting the
correspondent signal to the event handler. If the handler returns true, the
event isn't propagated upstream to the parent containers of the widget.

I'm having troubles obtaining the intended result:





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]