Re: key bindings



Jaap Karssenberg said:
I would like to add custom key bindings to a widget, preferably binding
keys directly to perl subroutines. Now I found in the Gtk reference this
page <http://developer.gnome.org/doc/API/2.0/gtk/gtk-Bindings.html> but
this is totally unhelpful due to the lack of descriptions/explanations.

you're not kidding -- no commentary at all.  peeking through the gtk+ 2.2.1
source (because that's what i have sitting around) at gtkbindings.c, this
appears to be something that has been ported from the old type and signal
system but retained as a convenience wrapper.  the bindings functions are used
from several widgets within gtk itself to add key handlers to widget
*classes*.

this is not likely to be useful to you for two reasons:

1. since this works on a GtkObjectClass (that is, a GObjectClass), there's
really no good way to use it from perl.  in C you can add stuff to your class
struct in your type's class_init, but the way subclassing works from perl, you
don't get that hook -- Glib::Type->register needs to do the work of your
typical class_init function, and there are currently no hooks for GtkBindings
in Glib::Type::register.

2. there is no type mapping for GtkBinding, and in fact the string GtkBinding
occurs nowhere in the gtk2-perl source code.

i don't think this is a show-stopper.  read on.


Could someone show me how to bind a key to a perl sub ?

you can rather easily implement something that does this, in pure perl, even. 
there's accelerators and accelerator maps, of which GtkBinding seems to be the
old version, and there's the key-press and key-release events from gdk.

personally, i would try the key-press and/or key-release events, just because
i don't know all that much about accelerators.  you can either connect a
handler to every object of that class that gets created, or override the
default handler in a subclass to install your code once for *all* objects of
that class.

#
# warning, untested code:
#
use Glib::Object::Subclass
    ...
    signals => {
        ...
        key_press_event => \&real_key_press_event,
        key_release_event => \&real_key_release_event,
        ...
    },
    ...
    ;

use Gtk2::Gdk::Keysyms;
sub real_key_press_event {
    my ($widget, $event) = @_;
    if ($event->keyval == $Gtk2::Gdk::Keysyms{PageUp}) {
        if (grep {/control-mask/}, @{ $event->state }) {
            # user is holding ctrl, do something different
            $widget->frob_by_ten_pages;
        } else {
            $widget->frob_by_page;
        }
        # we handled it
        return 1;
    }
    ...
    # if we didn't handle it, we need to explicitly call the parent!
    # this is not a normal signal handler, we're being called *instead* *of*
    # the normal class closure -- thus we need to chain up manually.
    $widget->signal_chain_from_overridden;
    return 0;
}






-- 
muppet <scott at asofyet dot org>



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