Attaching a signal to a GTK3 declared widget

So thanks to the help of Björn I am able to declare GTK3 controls from scratch. Adding signals – GTK events – to such a widget works too in the case of a button:

Private Sub AttachSignals()
  #If TargetLinux
    InstanceDict.Value(Mid) =  new WeakRef(Self)
    Dim c As cstring = "clicked"
    Call g_signal_connect_object(mid, c, AddressOf ActionHandler, nil, &h1ff)
End Sub

When I try the same for a GTKSwitch, but now with a “state-set” tag and a modified Handler that returns a Boolean as in the docs, this method will never fire. Here is the shared method head I am referencing:

Private Shared Function StateSetHandler(button as ptr, state as boolean, Data as ptr) As Boolean

Any ideas what might be the fault? Tell me if you need a demo project to test. And thanks a lot!

Probably not solution to your question but at least fix for some things

gboolean resolves to gint which resolves to int, making it basically int32_t

Xojo Boolean resolves to int8_t

So you need to adjust your callback signatures according to this.

Are you sure that is so? And even if, it will not translate correctly to Boolean anyway?
I changed code just to be sure, but to no avail. Weird while GTK.Entry textfields have their events working, even if the signal handler was not added as a shared method aus supposed to be.

On button it looks like userData and handler are reversed, but still action handler works too. Not so for switch.

Uploaded the state so far to GitHub - UBogun/XojoGTKLib: Basic classes that could serve as a fundament for building a Xojo Library in case someone wants to have a look.

P.S. Weird too that g_signal_is_valid_name will return false for state-set and clicked(!). See code commented out in Window.Open event.

100% sure you can see the typedef for Xojo Boolean in the Plugin SDK, and you can see the typedef for gboolean with simple google search.

One is 4 bytes and the other is 1 byte, meaning your function callback will never work or in best case work and clubber memory.

This one here that you listed:
`Private Shared Function StateSetHandler(button as ptr, state as boolean, Data as ptr) As Boolean

Would need to be:
Private Shared Function StateSetHandler(button as ptr, state as Int32, Data as ptr) As Int32

Thank you, but I had that already declared as you described and just only reverted back to a previous stage when I found it will not change anything. Anyway, for the sake of correct parameter alignment I will go back to int32.

Got it solved. I did not include your Boolean/Uint32 handling – I am not using the plugin SDK but declares and went on the assumption that most compilers will internally handle a Boolean like an Integer, and adding a random data Ptr showed every callback input variable will be correct.
I’ll upload to the repo but in short:

– For signals that respond to a property change, you do not use signal_connect_object but signal_connect_data. I did not include a closure handler where I probably could return a Boolean to the calling API function. It’s enough for me to register changes at this moment.

– In the Switch example, the signal is added with
signals.Add g_signal_connect_data(mid, "state-set", AddressOf statesetHandler, Ptr(1234), Nil, CType(GTKLib.GObject.SignalFlags.Detailed, UInt32))

1234 is just to check if userData will show this value.

Private Shared Sub StateSetHandler(button as ptr, state as boolean, data as ptr)
  #If TargetLinux
    If InstanceDict.HasKey(button) Then
      var w As WeakRef = InstanceDict.Value(button)
      If w.Value <> Nil Then
        var b As GTKLib.GTKSwitch = GTKLib.GTKSwitch(w.Value)
      End If
    End If
    #Pragma unused button
    #Pragma Unused data
    #Pragma Unused state
End Sub

All that should possibly be added is an internal “isInitialized” Boolean so that the event will not fire upon construction too.

1 Like