Re: [gtk-list] How to make escape cancel dialogs




On Fri, 14 May 1999, Neil Hodgson wrote:
> 
>     connecting to all the entry fields. Is there a similar (or better)
> technique for allowing Escape to cancel the dialogs. A better technique
> could be something like associating an accelerator table with the whole
> dialog, or attaching a key press handler to the dialog. I could not work out
> if key presses are propagated to parent widgets.
> 

Only GtkWindow (and therefore dialogs) actually receives key press events
from Gdk/X as far as I can tell, because Gtk never moves the X input focus
away from them. GtkWindow then dispatches the key event to the widget in
the window that has the Gtk input focus (which is different from the X
input focus).

If the last handler for the focus widget key press returns TRUE, then no
more processing is done. To install the last handler you'll have to use
gtk_signal_connect_after(). If the last handler returns FALSE, then
GtkWindow sends the key event to any accel group, and if that also returns
FALSE there are some default keybindings (such as space and the arrow
keys). Further complicating matters, there is a default key press handler
for GtkWidget that invokes any "bindings" the widget has. This default
handler runs before any user-connected handlers if you use
gtk_signal_connect(), that's why you have to use connect_after() if you
want to have the last handler.

Sorry for all the details - not sure how much you want. To explore things
yourself, try gtk_main_do_event() (gtkmain.c), and the GtkWidget and
GtkWindow default key press event handlers.

Key events do appear to be propagated to the parents of the widget that
actually received it, but since this is pretty much always (or maybe
definitely always) a GtkWindow, it is not very relevant - there are no
parents ever.

Anyway, to install an Escape handler: the nice way to do it is probably
to have an accel group for the dialog, but the simple way is to 
connect a callback to key_press_event for the window, and in this callback
call gtk_signal_emit_stop_by_name(). The reason you need to
emit_stop() is to prevent the default GtkWindow handler from running
(that's the code that sends the event to the focus widget and does the
accelerators; you don't want that to happen if you're destroying the
window). 

Another option, the one used by GnomeDialog (which by the way already does
all this stuff for you), is to subclass GtkWindow and override the key
press event handler. If you don't want to use Gnome, you might consider a
virtual cut-and-paste of GnomeDialog into your app, assuming your app is
GPL. No reason to reinvent the wheel.

HTH,
Havoc




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