# GTK signals in Ruby

**URL:** <https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384>\
**Category:** Ruby-Gnome 2\
**Created:** [September 2, 2011, 11:59am UTC](https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384 "2011-09-02T11:59:14Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubstep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/cdc98d/32.png) [@dubstep](https://www.ruby-forum.com/u/dubstep)\
**Post date:** [September 2, 2011, 11:59am UTC](https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384/1 "2011-09-02T11:59:14Z")

</div>

Hello,

After investigating what Gtk::Builder does with callbacks I figured  
out there are issues.

The first issue is mismatch between GTK C callbacks and GTK Ruby  
callbacks.

In C the GTK functions have a required first argument which is pointer  
to self. This is because C has no notion of object and self has to be  
passed explicitly.

Then in C to get rid of a window you call gtk\_widget\_destroy(window)  
but in ruby you call window.destroy meaning that methods take one  
fewer argument than gtk C functions.

This is not accounted for by signal\_connect in Ruby.

In C when you connect a signal the first argument passed to the  
handler is the object that triggered the signal and it is passed as  
pointer to that kind of object. Obviously, this is meant to be the  
self pointer. If the signal passes additional data or the user  
supplied additional data when connecting the signal this is passed in  
additional arguments. When the signal is connected as swapped the user  
data and self is swapped when calling the callback.

Now in Ruby you don’t connect a function, you connect a method. This  
method is already attached to an object - ‘self’. The first argument  
passed in by GTK is totally redundant when the receiver is the object  
which triggers the signal. Worse, when connecting existing GTK  
function as a signal handler and it takes any arguments in Ruby  
(unlike destroy which takes none because it takes only one in C) you  
have to wrap it to discard this first argument. Now I don’t expect  
this to be very common use but the possibility exists in C but not in  
Ruby.

Another issue is argument count. While in C extra arguments are  
ignored in Ruby they are ignored so long as you connect a block. When  
you connect a method and GTK passes extra arguments your callback  
fails and your application crashes. In C extra arguments are just  
ignored which is often used. Again, you may need to wrap a method in  
Ruby to make it a useful callback if the argument count does not  
match.

Either of this could be resolved by inserting a wrapper automatically  
at gobj\_sig\_connect\_impl to discard any extra args and/or discard the  
first arg when it is the same as the receiver.  
I am not sure if this is useful and wanted feature, though. It would  
change the API but if anybody used the cases that would change then  
they would see these issues for sure. Still it’s easy enough to  
rearrange arguments and redispatch the callbacks in user Ruby code,  
too.

The other issue is with Gtk::Builder. Given the issues above it does a  
lousy job of connecting signals, it can’t do any better. The results  
are nowhere near what the C connections would be.

What works properly are signals with no user data (object in glade  
files). Builder calls the user supplied block to get a handler and  
connects that. The swapped option does not make any sense in this case  
and is rightfully ignored.

What somewhat works are swapped signals with user data. These are  
often used to connect a “close” button to call a function which  
disposes of a window when the button is clicked. As these functions  
take only the window in C and no arguments in Ruby this works OK - all  
arguments are ignored. Connecting a GTK function that takes arguments  
would not work this way because of the extra argument generated when  
going between C and Ruby.

What is broken are signals with user data which are _not_ swapped.  
They are simply handled as swapped, the swapped flag is ignored  
completely. I guess these should be connected just like signals  
without user data but pass in the extra argument. It’s not quite  
consistent with C gtk and never will be so long as the extra argument  
is generated but at least it would be an useful option.

Thanks

Michal

---

<div class="post-metadata">

**Author:** ![Michal\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/779978/32.png) [@Michal\_S](https://www.ruby-forum.com/u/Michal_S)\
**Post date:** [September 6, 2011, 9:20am UTC](https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384/2 "2011-09-06T09:20:42Z")

</div>

I just wanted to say I’m interested on this topic, but don’t quite have  
time right now to give a thoughtfull answer.

I’ll try to get back to this topic before the week-end.

regards

Simon

---

<div class="post-metadata">

**Author:** ![Michal\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/779978/32.png) [@Michal\_S](https://www.ruby-forum.com/u/Michal_S)\
**Post date:** [September 21, 2011, 3:01pm UTC](https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384/3 "2011-09-21T15:01:43Z")

</div>

Michal S. wrote in post #1019765:

> Hello,
> 
> After investigating what Gtk::Builder does with callbacks I figured  
> […]  
> data and self is swapped when calling the callback.

Agreed.

> Now in Ruby you don’t connect a function, you connect a method. This  
> method is already attached to an object - ‘self’. The first argument  
> passed in by GTK is totally redundant when the receiver is the object  
> which triggers the signal.

I agree with this : The fist argument looks like self. But it is not.  
For example :

require ‘gtk2’

def on\_click(object)  
puts object.label  
end

my\_button = Gtk::Button.new(“My label”)  
my\_button.signal\_connect(‘clicked’) do |button|  
on\_click(button) # should always work  
on\_click(my\_button) # works, but bad practice  
on\_click(self) # does not work (on 1.9.2 at least)  
end

my\_button.signal\_emit(‘clicked’)

It fails with “undefined method `label’ for main:Object”, because self  
is not anymore the button when the callback is called.  
That’s because ‘self’ is not the object the method is called from, but  
the current object.  
So, while you might think ‘self’ is ‘button’, it is not when the  
callback is called.

> Worse, when connecting existing GTK  
> function as a signal handler and it takes any arguments in Ruby  
> (unlike destroy which takes none because it takes only one in C) you  
> have to wrap it to discard this first argument. Now I don’t expect  
> this to be very common use but the possibility exists in C but not in  
> Ruby.

It seems you are confusing the ‘destroy’ method, and the ‘destroy’  
signal.  
The ‘destroy’ method takes no argument, but the ‘destroy’ signal does.

method :  
[http://ruby-gnome2.sourceforge.jp/hiki.cgi?Gtk%3A%3AObject#destroy](http://ruby-gnome2.sourceforge.jp/hiki.cgi?Gtk%3A%3AObject#destroy)  
signal :  
[http://ruby-gnome2.sourceforge.jp/hiki.cgi?Gtk%3A%3AObject#destroy%3A+self](http://ruby-gnome2.sourceforge.jp/hiki.cgi?Gtk%3A%3AObject#destroy%3A+self)

Also, I’m not sure I get your point. Are you talking about auto calling  
a method on the widget based on event-type ?

Or are you talking about glade, and you want to directly connect the  
handler you create as a method call to the object which received the  
event ?  
So, instead of :  
builder.connect\_signals {|handler| method(handler) }

you would like the default to be something like :  
def my\_connect(handler, \*args)  
args[0].send(handler)  
end

Am I right ?

> Another issue is argument count. While in C extra arguments are  
> ignored in Ruby they are ignored so long as you connect a block. When  
> you connect a method and GTK passes extra arguments your callback  
> fails and your application crashes. In C extra arguments are just  
> ignored which is often used. Again, you may need to wrap a method in  
> Ruby to make it a useful callback if the argument count does not  
> match.

Reading this, I really think you are trying to connect signal to methods  
directly, and that you should write a custom method to use in  
‘connect\_signals’.

I’m not a C programmer, but, are you saying that I can call something  
like this, and it will work ?

gtk\_window\_move(p\_win, 100, 200, 345, “foo”, NULL);

I really doubt it.

Or is it gtk\_builder in C which discards the extra args ?

> Either of this could be resolved by inserting a wrapper automatically  
> at gobj\_sig\_connect\_impl to discard any extra args and/or discard the  
> first arg when it is the same as the receiver.

I think it should be done by the programmer, not by Ruby-gnome.

> I am not sure if this is useful and wanted feature, though. It would]  
> change the API but if anybody used the cases that would change then  
> they would see these issues for sure. Still it’s easy enough to  
> rearrange arguments and redispatch the callbacks in user Ruby code,  
> too.

My code would not work with what you are proposing. I almost never use  
the handler name to call a method of the same name.

> The other issue is with Gtk::Builder. Given the issues above it does a  
> lousy job of connecting signals, it can’t do any better. The results  
> are nowhere near what the C connections would be.

I disagree, it does its job good, lacking only one feature : user\_data.  
The results are just the same as in C, afaik.

> What works properly are signals with no user data (object in glade  
> files). Builder calls the user supplied block to get a handler and  
> connects that. The swapped option does not make any sense in this case  
> and is rightfully ignored.

Agreed.

> What somewhat works are swapped signals with user data. These are  
> often used to connect a “close” button to call a function which  
> disposes of a window when the button is clicked. As these functions  
> take only the window in C and no arguments in Ruby this works OK - all  
> arguments are ignored. Connecting a GTK function that takes arguments  
> would not work this way because of the extra argument generated when  
> going between C and Ruby.

Just to be sure, you are talking about having a swapped handler with  
name ‘gtk\_window\_destroy’ ? So, C code calls  
gtk\_window\_destroy(user\_data) where user\_data is the window, without  
writing any code ?

If that’s it, I think it’s a corner case of C, where you use functions,  
and not methods. I don’t think it is ruby to mimic this behaviour.

> What is broken are signals with user data which are _not_ swapped.  
> They are simply handled as swapped, the swapped flag is ignored  
> completely. I guess these should be connected just like signals  
> without user data but pass in the extra argument. It’s not quite  
> consistent with C gtk and never will be so long as the extra argument  
> is generated but at least it would be an useful option.

I agree there is something strange going on with user\_data. However I  
disagree that swapped signals function properly.

the connect\_signals from Gtk::Builder should pass user\_data, as last  
argument if not swapped, or as first if swapped. And it should be up to  
the programmer to connect as he wants to.

regards

Simon

---

<div class="post-metadata">

**Author:** ![Michal\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/779978/32.png) [@Michal\_S](https://www.ruby-forum.com/u/Michal_S)\
**Post date:** [September 21, 2011, 4:06pm UTC](https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384/4 "2011-09-21T16:06:36Z")

</div>

On 21 September 2011 15:01, Simon A.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > method is already attached to an object - ‘self’. The first argument  
> > end  
> > It fails with “undefined method `label’ for main:Object”, because self  
> > is not anymore the button when the callback is called.

It depends on the method invoked as the callback.

It is perfectly possible to detect if the callback is attached to the  
triggering object or another object at attach time and it is also  
possible to detect that a callback is triggered on the triggering  
object at trigger time.

> That’s because ‘self’ is not the object the method is called from, but  
> the current object.

The ‘current’ object is the object whose method was attached as the  
signal handler. You can pick it so that the ‘self’ matches or not, and  
you can also know in advance if it will (such as in the builder  
connect\_signals).

> It seems you are confusing the ‘destroy’ method, and the ‘destroy’  
> signal.  
> The ‘destroy’ method takes no argument, but the ‘destroy’ signal does.

Indeed, that’s the difference between Ruby and C.

In C the destroy method takes ‘self’, and the signal callback gets  
‘self’ and ‘data’, possibly swapped.

In Ruby the destroy method takes no arguments, and the callback still  
gets ‘self’ and ‘data’, and the method is no longer compatible with  
the signal.

> Also, I’m not sure I get your point. Are you talking about auto calling  
> a method on the widget based on event-type ?

I am talking about using existing methods as signal handlers.

> Or are you talking about glade, and you want to directly connect the  
> handler you create as a method call to the object which received the  
> event ?  
> So, instead of :  
> builder.connect\_signals {|handler| method(handler) }
> 
> you would like the default to be something like :  
> def my\_connect(handler, \*args)  
> args[0].send(handler)  
> args[0].send(handler, \*(args[1..-1])) more precisely to make it look  
> like what C does

Plus extra arguments should be discarded.

> end
> 
> Am I right ?

That’s one way of using the signal connections in Glade, and one that  
works quite well for quite a few signals in C.

For the most common which take only ‘self’ in C it is hacked in  
connect\_signals in Ruby Builder so that it works but it’s not exactly  
consistent. The moment you try to call a method that takes arguments  
it will fail.

> directly, and that you should write a custom method to use in  
> ‘connect\_signals’.

Yes, I can write wrappers for any methods I want to connect as  
callbacks, sure.

The wrapper can handle extra arguments or whatnot without any issues.

> I’m not a C programmer, but, are you saying that I can call something  
> like this, and it will work ?
> 
> gtk\_window\_move(p\_win, 100, 200, 345, “foo”, NULL);
> 
> I really doubt it.

I am not sure what you are trying to demonstrate here.

You can definitely call gtk\_widget\_destroy(p\_win, 100, 200, 345,  
“foo”, NULL) and it will work and it is what the callbacks do all the  
time. They call gtk\_widget\_destroy(p\_win, p\_button).

> Or is it gtk\_builder in C which discards the extra args ?

Don’t think so. C calling convention discards extra arguments  
automagically.

> > Either of this could be resolved by inserting a wrapper automatically  
> > at gobj\_sig\_connect\_impl to discard any extra args and/or discard the  
> > first arg when it is the same as the receiver.
> 
> I think it should be done by the programmer, not by Ruby-gnome.

At the very least it should be well documented what the builder does  
because it is very inconsistent for various cases and very different  
from the C builder.

> > I am not sure if this is useful and wanted feature, though. It would]  
> > change the API but if anybody used the cases that would change then  
> > they would see these issues for sure. Still it’s easy enough to  
> > rearrange arguments and redispatch the callbacks in user Ruby code,  
> > too.
> 
> My code would not work with what you are proposing. I almost never use  
> the handler name to call a method of the same name.

Then your code _would_ work.

> > The other issue is with Gtk::Builder. Given the issues above it does a  
> > lousy job of connecting signals, it can’t do any better. The results  
> > are nowhere near what the C connections would be.
> 
> I disagree, it does its job good, lacking only one feature : user\_data.  
> The results are just the same as in C, afaik.

Well, when you remove half of the features and then say that the other  
half works .. even that is not true.

It handles user\_data as the swapped flag, and ignores the swapped flag.

That’s definitely bogus.

> > disposes of a window when the button is clicked. As these functions  
> > take only the window in C and no arguments in Ruby this works OK - all  
> > arguments are ignored. Connecting a GTK function that takes arguments  
> > would not work this way because of the extra argument generated when  
> > going between C and Ruby.
> 
> Just to be sure, you are talking about having a swapped handler with  
> name ‘gtk\_window\_destroy’ ? So, C code calls  
> gtk\_window\_destroy(user\_data) where user\_data is the window, without  
> writing any code ?

Yes, it does that.

> If that’s it, I think it’s a corner case of C, where you use functions,  
> and not methods. I don’t think it is ruby to mimic this behaviour.

But it is glade to do such, and ruby-gnome2 claims to support glade.

> > What is broken are signals with user data which are _not_ swapped.  
> > They are simply handled as swapped, the swapped flag is ignored  
> > completely. I guess these should be connected just like signals  
> > without user data but pass in the extra argument. It’s not quite  
> > consistent with C gtk and never will be so long as the extra argument  
> > is generated but at least it would be an useful option.
> 
> I agree there is something strange going on with user\_data. However I  
> disagree that swapped signals function properly.

yes, they won’t if multiple arguments were passed in to the callback  
but there are quite few such signals, if any.

> the connect\_signals from Gtk::Builder should pass user\_data, as last  
> argument if not swapped, or as first if swapped. And it should be up to  
> the programmer to connect as he wants to.

That would definitely suck more, especially since you do _not_ get  
anything but the method name to decide what to do when connecting the  
handler.

For the user to be able to decide how to connect the signal they would  
have to know all of

- signal name
- triggering object
- user data

Then the connection function would be just something like  
signals\_each{  
signal\_connect \*(connector signal, trigger, data, swapped)  
}

that is the user would supply all the arguments based on all the  
signal data read from the glade layout.

Thanks

Michal

---

<div class="post-metadata">

**Author:** ![Michal\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/779978/32.png) [@Michal\_S](https://www.ruby-forum.com/u/Michal_S)\
**Post date:** [September 21, 2011, 5:43pm UTC](https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384/5 "2011-09-21T17:43:43Z")

</div>

On Wed, Sep 21, 2011 at 15:01, Simon A.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> on\_click(my\_button) # works, but bad practice

Why is this a bad practice?

---

<div class="post-metadata">

**Author:** ![Michal\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/779978/32.png) [@Michal\_S](https://www.ruby-forum.com/u/Michal_S)\
**Post date:** [September 21, 2011, 6:08pm UTC](https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384/6 "2011-09-21T18:08:23Z")

</div>

Nikolai W. wrote in post #1023132:

> On Wed, Sep 21, 2011 at 15:01, Simon A.  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > on\_click(my\_button) # works, but bad practice
> 
> Why is this a bad practice?

It seems to me that when you have both the same object as external and  
local scope, local should be used.

It will ease refactor also. This example might not be the best to  
demonstrate the problem though.

I understand it is a subjective topic.

---

<div class="post-metadata">

**Author:** ![Michal\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/779978/32.png) [@Michal\_S](https://www.ruby-forum.com/u/Michal_S)\
**Post date:** [September 22, 2011, 10:45am UTC](https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384/7 "2011-09-22T10:45:56Z")

</div>

On 21 September 2011 18:31, Simon A.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> When you define a method, ‘self’ is the object the method will be called  
> onto.  
> When you call a method which takes a block, inside the block, ‘self’ is  
> not the object you call the method onto, it is the object you are in.

This is true but does not apply to builder. Builder connects methods.

> It’s obvious with an array :
> 
> a = [1, 2, 3]  
> a.each do |item|
> 
> # self is not a
> 
> end
> 
> However, I understand you would like self to be set so it is the object  
> which triggered the signal.

Not necessarily. What I am saying is that when you attach a method on  
the object which triggers the signal as signal handler you get  
redundant reference to self passed as the first argument which makes  
the signal interface incompatible with the ruby-gnome2 method  
interface.

> Just that I’m not a C programmer, at all. I didn’t think C would discard  
> any extras by itself.
> 
> Anyway, I feel you have a strong C background, and you would like ruby  
> to behave like C. However, I don’t think it can. In one languauge, you

No, I would like the builder to behave logically. If the current  
behaviour were at least documented it would be obvious it’s bogus.

> have global functions with arguments, and in another, you haves messages  
> sent to objects. While ruby can mimic C a great deal, I don’t think you  
> can imitate every corner case.
> 
> I understand the usefullness to call gtk\_window\_destroy(p\_win,  
> p\_button), and it will work without any effort in C, but I still think  
> it is a C corner case impossible to mimic in ruby.

It is already emulated partially. Builder already mimics this  
particular case by attaching a block discarding the extra arguments  
instead of the method when the provided method does not take  
arguments.

> In most (all?) cases, you will need a dispatcher.

Why should you need a dispatcher?

The glib signals system is done so that you shall not need any  
additional dispatcher. It can trigger multiple handlers for a single  
signal, you can register the handlers in a particular order, you can  
pass the handler additional user data, and you can even swap the order  
in which the triggering object and extra data are passed.

Thanks

Michal

---

<div class="post-metadata">

**Author:** ![Michal\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/779978/32.png) [@Michal\_S](https://www.ruby-forum.com/u/Michal_S)\
**Post date:** [September 22, 2011, 1:33pm UTC](https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384/8 "2011-09-22T13:33:50Z")

</div>

On 22 September 2011 10:44, Michal S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > 
> 
> redundant reference to self passed as the first argument which makes
> 
> > >
> 
> instead of the method when the provided method does not take  
> arguments.

It’s also explained in the g\_signal “hello world” :  
[http://developer.gnome.org/gtk-tutorial/2.90/x159.html](http://developer.gnome.org/gtk-tutorial/2.90/x159.html)

Thanks

Michal

---

<div class="post-metadata">

**Author:** ![Michal\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/779978/32.png) [@Michal\_S](https://www.ruby-forum.com/u/Michal_S)\
**Post date:** [September 21, 2011, 6:31pm UTC](https://www.ruby-forum.com/t/gtk-signals-in-ruby/211384/9 "2011-09-21T18:31:38Z")

</div>

Michal S. wrote in post #1023105:

> > That’s because ‘self’ is not the object the method is called from, but  
> > the current object.
> 
> The ‘current’ object is the object whose method was attached as the  
> signal handler. You can pick it so that the ‘self’ matches or not, and  
> you can also know in advance if it will (such as in the builder  
> connect\_signals).

What I wanted to say was not clear.  
When you define a method, ‘self’ is the object the method will be called  
onto.  
When you call a method which takes a block, inside the block, ‘self’ is  
not the object you call the method onto, it is the object you are in.

It’s obvious with an array :

a = [1, 2, 3]  
a.each do |item|

# self is not a

end

However, I understand you would like self to be set so it is the object  
which triggered the signal.

> > I’m not a C programmer, but, are you saying that I can call something  
> > like this, and it will work ?
> > 
> > gtk\_window\_move(p\_win, 100, 200, 345, “foo”, NULL);
> > 
> > I really doubt it.
> 
> I am not sure what you are trying to demonstrate here.

Just that I’m not a C programmer, at all. I didn’t think C would discard  
any extras by itself.

Anyway, I feel you have a strong C background, and you would like ruby  
to behave like C. However, I don’t think it can. In one languauge, you  
have global functions with arguments, and in another, you haves messages  
sent to objects. While ruby can mimic C a great deal, I don’t think you  
can imitate every corner case.

I understand the usefullness to call gtk\_window\_destroy(p\_win,  
p\_button), and it will work without any effort in C, but I still think  
it is a C corner case impossible to mimic in ruby.

In most (all?) cases, you will need a dispatcher.

I fully agree though that the documentation is not very good, and the  
current behaviour is bogus and confusing.
