Unknown template error

I’m attempting to create a composite widget and getting the following error from the compiler:

../src/theme_switcher.vala:21.5-21.43: error: Unknown template `ThemeSwitcher' in ui file `../src/theme_switcher.ui'
   21 |     public class ThemeSwitcher : Gtk.Widget {

My ui file begins as so:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <template class="ThemeSwitcher" parent="GtkWidget">

And in theme_switcher.vala:

namespace Vapad {
    [GtkTemplate (ui = "/org/hitchhiker_linux/vapad/theme_switcher.ui")]
    public class ThemeSwitcher : Gtk.Widget {

I don’t understand why this is not compiling.

Can you try using “VapadThemeSwitcher” in the ui file?

That change allows it to compile, but now I get a different error when popping up the menu that this is a part of.

(vapad:18410): Gtk-WARNING **: 18:17:03.177: Trying to snapshot GtkBox 0x560e2ea84df0 without a current allocation

There is a GtkBox which is the direct child of the composite widget.

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <template class="VapadThemeSwitcher" parent="GtkWidget">
    <child>
      <object class="GtkBox">
        <property name="orientation">horizontal</property>
        <property name="halign">fill</property>
        <property name="hexpand">true</property>

can you post all the gtk relevant code of the class ThemeSwitcher?

Sure. No much there yet until this is working.

theme_switcher.ui

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <template class="VapadThemeSwitcher" parent="GtkWidget">
    <child>
      <object class="GtkBox">
        <property name="orientation">horizontal</property>
        <property name="halign">fill</property>
        <property name="hexpand">true</property>
        <child>
          <object class="GtkCheckButton" id="system_button">
            <property name="hexpand">true</property>
            <property name="halign">center</property>
            <property name="tooltip-text" translatable="yes">Follow system style</property>
            <accessibility>
              <property name="label" translatable="yes">Follow system style</property>
            </accessibility>
          </object>
        </child>
        <child>
          <object class="GtkCheckButton" id="light_button">
            <property name="hexpand">true</property>
            <property name="halign">center</property>
            <property name="tooltip-text" translatable="yes">Light style</property>
            <accessibility>
              <property name="label" translatable="yes">Light style</property>
            </accessibility>
          </object>
        </child>
        <child>
          <object class="GtkCheckButton" id="dark_button">
            <property name="hexpand">true</property>
            <property name="halign">center</property>
            <property name="tooltip-text" translatable="yes">Dark style</property>
            <property name="group">light_button</property>
            <accessibility>
              <property name="label" translatable="yes">Dark style</property>
            </accessibility>
          </object>
        </child>
      </object>
    </child>
  </template>
</interface>

theme_switcher.vala

namespace Vapad {
    [GtkTemplate (ui = "/org/hitchhiker_linux/vapad/theme_switcher.ui")]
    public class ThemeSwitcher : Gtk.Widget {
        [GtkChild]
        private unowned Gtk.CheckButton system_button;
        [GtkChild]
        private unowned Gtk.CheckButton light_button;
        [GtkChild]
        private unowned Gtk.CheckButton dark_button;

        public ThemeSwitcher () {
            Object ();
        }
    }
}

For custom GTK4 widgets a bit more is needed, like setting a layout manager. But maybe you could try to also just derive from AdwBin?

I’ve never derived directly from GtkWidget before, so I was experimenting a bit actually. But yes, after adding a layout manager in “constructed” it worked as expected.

Going back a step, I find it curious that I had to rename the type to VapadThemeSwitcher in the ui file. I haven’t had to do that for application windows or dialogs, so it seems oddly inconsistent. It makes a certain amount of sense that the namespace would have to be prepended, but I don’t understand why that would be the case here when it isn’t for toplevels.