Type_register does not override default signal handler when the handler is included

Hi all,

When you want to override a default signal handler in your new class
widget,
calling type_register is the best and only way in the current ruby-gtk2.

class MyLabel < Gtk::Label
type_register
def signal_do_expose_event(e)

end
end

Ruby-gtk2 finds the newly defined signal handler by wathcing method
definitions
by using ‘method_added’. However, it does not work if a signal handler
is defined
in a module and the class included it.

module NiceBehaviour
def signal_do_expose_event(e)

end
end

class NiceLabel < Gtk::Label
type_register
include NiceBehaviour
end

I attached a working sample to this message. Run it and resize the
window.

Is there any nice trick to avoid this problem? Or should we add a new
method
to Ruby-gtk2? (just like the old signal_override()?)

Kentaro F.

Hi,

In [email protected]
“[ruby-gnome2-devel-en] type_register does not override default signal
handler when the handler is included” on Wed, 18 Feb 2009 02:57:56
+0900,
Kentaro F. [email protected] wrote:

class NiceLabel < Gtk::Label
type_register
include NiceBehaviour
end

I attached a working sample to this message. Run it and resize the window.

Is there any nice trick to avoid this problem? Or should we add a new method
to Ruby-gtk2? (just like the old signal_override()?)

There is no workaround for the problem. You need to define
callback method in your class. We should fix the problem in
the next release.

You can also use ruby-gnome2-devel-ja. :wink:

Thanks,

kou

Hi,

From: Kouhei S. [email protected]
Date: Fri, 20 Feb 2009 22:24:25 +0900 (JST)

Hi,

In [email protected]
“[ruby-gnome2-devel-en] type_register does not override default signal handler when the handler is included” on Wed, 18 Feb 2009 02:57:56 +0900,
Kentaro F. [email protected] wrote:

Ruby-gtk2 finds the newly defined signal handler by wathcing method definitions
by using ‘method_added’. However, it does not work if a signal handler is defined
in a module and the class included it.

Is there any nice trick to avoid this problem? Or should we add a new method
to Ruby-gtk2? (just like the old signal_override()?)

There is no workaround for the problem. You need to define
callback method in your class. We should fix the problem in
the next release.

Fixing the problem may be difficult.

If #signal_do_expose is defined in the class C, Ruby-gtk2 includes in
C a corresponding module (say M) having #signal_do_expose. Then
“super” in C#signal_do_expose invokes M#signal_do_expose and it calls
g_signal_chain_from_overridden() to chain up to parent handlers in GTK
side.

But if #signal_do_expose is defined in a module M2 this trick does not
work, since relative ordering of M and M2 in C’s inheritance hierarchy
is indeterminate.

To be honest, I regret that I adopted such a tricky mechanism, and
now I think that the old signal_override() was a right way…

Regards,

– Masahiro S.

On Sun, 22 Feb 2009 17:30:53 +0900 (JST)
Masahiro S. [email protected] wrote:

is indeterminate.
One possible option is overriding Class#include method in type_register.

class Class
def include (*args)
super
args.each {|mod|
mod.instance_methods.each {|method|
if method.match (/^signal_do_/)

end
}
}
end
end

Even if two or more modules are included, it would be possible to
override signal handlers in the order the user expected.

To be honest, I regret that I adopted such a tricky mechanism, and
now I think that the old signal_override() was a right way…

“Convention over configuration” is not so bad. However there still be
a complicated fault in above trick when signal handlers are added to
a module AFTER it is included. To avoid all of this kind of fault,
we have to hook all signal calls of GObject and it causes serious
performance loss.

Is it able to provide BOTH of them, automagical overriding of
signal_do_*
and signal_override()? Most developers are happy with signal_do_*, and
some hackers are allowed to explore the limitation of the library with
signal_override().

Kentaro