How to mark a custom widget as activatable in Vala?

Normally in gtk with bare C, you would mark a custom widget as activatable by setting the GtkWidgetClass property activate_signal to the signal that triggers activation.

GtkSwitch does it like so:

  signals[ACTIVATE] =
    g_signal_new (I_("activate"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
                  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkSwitchClass, activate),
                  NULL, NULL,
                  NULL,
                  G_TYPE_NONE, 0);
  widget_class->activate_signal = signals[ACTIVATE];

How do you do that in Vala? I don’t think I see any special support for this feature.

I’m not sure I understand.

Not every widget implements GtkActivatable. If you’re deriving from something that does then you can just use an override or connect to a signal as usual. If it’s a completely custom widget then you need to implement that yourself.

1 Like

I’m looking at gtk4, I should have been more specific. I don’t think GtkActivatable exists in gtk4?

But specifically, this is how gtk4’s gtk_widget_activate works:


gboolean
gtk_widget_activate (GtkWidget *widget)
{
  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);

  if (GTK_WIDGET_GET_CLASS (widget)->activate_signal)
    {
      /* FIXME: we should eventually check the signals signature here */
      g_signal_emit (widget, GTK_WIDGET_GET_CLASS (widget)->activate_signal, 0);

      return TRUE;
    }
  else
    return FALSE;
}

Which requires the ability to set a widget class’s activate_signal field – and that bit is what I’m unsure of how to do in vala.

I don’t think it really matters. I think you either override the method, connect to a signal or implement your own.

The GtkSwitch code you originally posted is doing exactly that, it’s defining it’s own signal to be emitted by the gtk_widget_activate code you just posted.

Which I’m guessing translates into something like

public class MyCustomActivatableWidget : Gtk.Widget {

    public signal void activate ();

    public MyCustomActivatableWidget () {
        activate.connect(on_activate);
    }

    public new bool activate () {
        activate();
        return true;
    }

    public on_activate () {
        // activated - do something
    }

}

I’m thinking that maybe explaining exactly what you want to accomplish rather than how you’re trying to accomplish it would be useful.

But, I’m no expert, far from it, so maybe there’s a way to do exactly what you want. Hopefully someone here has gone this route before and can tell you for certain.

1 Like

Thank you for your reply.

I don’t think it really matters. I think you either override the method, connect to a signal or implement your own.

If I were only dealing with code I wrote myself, yes - I can call a custom method to do whatever sort of work I want. Like your examples of overrides and signals etc.

But I’m specifically talking about making gtk_widget_activate in gtk4 work – which is the standard activation method that other bits of codes might call on my custom widget (like if I put it in another container like HdyActionRow in a listbox or similar).

To make gtk_widget_activate work, my custom class has to be able to set the class property activate_signal to some signal I add to my custom class.

All the code samples you demonstrated merely define signals and handlers called activate – but don’t set the class property above, so gtk_widget_activate would still do nothing in gtk4.

I don’t think vala gives me that capacity right now? But maybe there is some special syntax to do that?

In theory, if you can look up the signal id for a type with g_signal_lookup(), and you have access to the class structure, you can override GtkWidgetClass.activate_signal. The problem is that Vala might be hiding the signal registration well enough that you can’t really do that in your own class constructor function.

1 Like

All the code samples you demonstrated merely define signals and handlers called activate – but don’t set the class property above, so gtk_widget_activate would still do nothing in gtk4.

So you tried adding that bit of code to your class and it did what? Nothing?

Or did you not try it?


Nevermind, Gtk4 is not having any of that. Can’t even use new to hide activate.

I don’t see any way to access activate_signal in order to attach a signal ID to it.

I’d file a bug against Vala. That way you’ll at least get the official take on how to workaround this.

For reference, I’ve opened this MR with additional API for GtkWidget to access the activate_signal field.

1 Like

Oh thank you very much! That’s very kind to do that work.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.