Re: an additional argument flag
- From: Owen Taylor <owt1 cornell edu>
- To: Kenneth Albanowski <kjahds kjahds com>
- Cc: gtk-list redhat com
- Subject: Re: an additional argument flag
- Date: 23 Feb 1998 00:54:06 -0500
Kenneth Albanowski <kjahds@kjahds.com> writes:
> On 22 Feb 1998, Tero Pulkkinen wrote:
>
> > Deriving from widgets is the only thing we need to do with gtk--. No
> > black magic involved. Deriving from widgets currently requires that
> > we rewrite all *_new() methods. On some widgets this cut/paste is kinda
> > large as there is static methods called from *_new() methods :)
>
> Have you found some way of deal with class signals (or whatever you want
> to call the signal slots that are held in the class object) in a
> reasonable manner? Then again, C++ isn't an interpreter, so you won't have
> many of the difficulties I ran into with Perl.
I think the difficulty that you are referring to is that you
want to override the default handlers, but the default handlers
don't go through the marshalling system.
I think there is a an easy solution to this:
Signal handlers are called in the order:
default handlers of type RUN_FIRST or RUN_BOTH
signals connected normally
default handlers of type RUN_AFTER or RUN_BOTH.
signals connect "after"
Also, signals connected for a certain type are run in the
order connected. So to override a signal, that is say RUN_AFTER,
for a Foo widget, you use a (GTK) class derived from Foo, and
"simply" zero out the default handler, and attach your substitute
"after". (default handler = NULL, means no default handler)
There are some details to be worked out, but that is the general
scheme. You probably don't want to follow gtk-- and hook
every default handler through Perl, because there would be
too much overhead - instead I would use something like:
@MyFoo::ISA = qw(Gtk::Foo);
sub new {
my $pkg = shift;
my $self = $pkg->SUPER::new();
$self->override ("realize" => \&my_realize,
"size_request" => \&my_size_request);
}
The big problem is to simulate things, that in C look like:
static void
gtk_menu_item_destroy (GtkObject *object)
{
GtkMenuItem *menu_item;
g_return_if_fail (object != NULL);
g_return_if_fail (GTK_IS_MENU_ITEM (object));
menu_item = GTK_MENU_ITEM (object);
if (menu_item->submenu)
gtk_widget_destroy (menu_item->submenu);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
The problem is that last line - basically it either requires writing
some customf XS code for each signal, or marshalling the arguments
back from Perl into a GtkArgs structure than calling the C Marshaller
for the signal on the parent's default handler.
If there was a way of connecting a signal handler before
a "RUN_FIRST" handler, there would be an easy, if inelegant
way of handling such chaining - simply, if the signal handler
is chained, don't NULL out the default handler for the overriden
signal. But adding signals that are connected "before" is
not really an attractive possibility - this would approximately
increase overhead by 50% for every signal emission.
GTK definitely wasn't designed to allow deriving new widget
types in interpreted languages (or any language other than C) -
and I'm somewhat dubious of the worthwhile-ness of the goal.
The multi-lingual nature of GTK will be best served if new
widgets are written in C. On the other hand, if people
want to do it, there should be a way.
Regards,
Owen
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]