tags:

views:

130

answers:

3

I build a composite widget and would like it to have it's own accelerators (hotkeys) available only when it is in focus. The only Idea I have so far of how to accomplish this is to change out the accelerator group in the top level when ever my widget goes in and out of focus. It seems like there should be a better way.

A: 

Each widget class exposes pointers to its handlers as part of the widget class' struct. You can patch these at runtime, after calling gtk_init() but before entering the app's main loop.

So for instance, you could patch the key-press handler for GtkFoo like this:

static gboolean (*oldFooKeyPress)(GtkWidget* _widget, GdkEventKey* _event);
...
GtkWidgetClass* fooClass = GTK_WIDGET_CLASS(g_type_class_ref(GTK_TYPE_FOO));
oldFooKeyPress = fooClass->key_press_event;
fooClass->key_press_event = myFooKeyPress;

Then you could write myFooKeyPress() like this:

static gboolean myFooKeyPress(GtkWidget* widget, GdkEventKey* event)
{
    if (widget is one I am interested in &&
        event is a special accelerator for that widget)
    {
        do something special here
        and maybe return
    }

    return oldFooKeyPress(widget, event);
}

As I recall, when you do the patching above, invoking GTK_TYPE_FOO will initialize the Foo widget class if it hasn't already been initialized.

Bob Murphy
A: 

Looks like I need to use key bindings instead of accelerators

http://library.gnome.org/devel/gtk/unstable/gtk-Bindings.html

Cross reference of the GtkTextView shows how http://www.koders.com/c/fid959C3555A3004EA74AD6E0276122FC19673F9912.aspx?s=sort

AC
A: 

Here is class init function which is the solution I was looking for

static void
webview_class_init (WebviewClass *klass)
{

    GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);

    GtkBindingSet *binding_set;

    signals[ZOOM_IN] = g_signal_new_class_handler("zoom_in",
                    G_OBJECT_CLASS_TYPE (object_class),
                    G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                    G_CALLBACK (webview_zoom_in),
                    NULL, NULL,
                    g_cclosure_marshal_VOID__VOID,
                    G_TYPE_NONE, 1,
                    G_TYPE_BOOLEAN, TRUE);

    binding_set = gtk_binding_set_by_class (klass);

    gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_CONTROL_MASK,
                    "zoom_in", 1,
                    G_TYPE_BOOLEAN, TRUE);

 }
AC