Forum: Ruby-Gnome 2 type_register does not override default signal handler when the handler is included

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Dc33f4b5ce824bd2e6425c6ec770ac11?d=identicon&s=25 Kentaro Fukuchi (Guest)
on 2009-02-17 19:16
(Received via mailing list)
Attachment: sigtest.rb (2 KB)
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 Fukuchi
Ee6ffca720cc428d70247dcd7377dd48?d=identicon&s=25 Kouhei Sutou (Guest)
on 2009-02-20 14:25
(Received via mailing list)
Hi,

In <20090218025756.691310ef.fukuchi@megaui.net>
  "[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 Fukuchi <fukuchi@megaui.net> 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. ;-)


Thanks,
--
kou
C8de9c30687965f867b3609220799989?d=identicon&s=25 Masahiro Sakai (Guest)
on 2009-02-22 09:49
(Received via mailing list)
Hi,

From: Kouhei Sutou <kou@cozmixng.org>
Date: Fri, 20 Feb 2009 22:24:25 +0900 (JST)

> Hi,
>
> In <20090218025756.691310ef.fukuchi@megaui.net>
>   "[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 Fukuchi <fukuchi@megaui.net> 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 Sakai
Dc33f4b5ce824bd2e6425c6ec770ac11?d=identicon&s=25 Kentaro Fukuchi (Guest)
on 2009-02-25 04:23
(Received via mailing list)
On Sun, 22 Feb 2009 17:30:53 +0900 (JST)
Masahiro Sakai <masahiro.sakai@gmail.com> 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
This topic is locked and can not be replied to.