Difference between setting visibility with Builder and gtk_widget_set_visible?

New to GTK here, I made a basic program which tries to create an empty ApplicationWindow with a menubar as seen here

#include <gtk-3.0/gtk/gtk.h>
#include <assert.h>

void activate(GtkApplication *app) {
    GtkBuilder *builder = gtk_builder_new();
    assert(gtk_builder_add_from_file(builder, "window.ui", NULL));
	assert(gtk_builder_add_from_file(builder, "menu.ui", NULL));
    GObject *window = gtk_builder_get_object(builder, "window");
    gtk_window_set_application(GTK_WINDOW(window), app);
    GObject *menubar = gtk_builder_get_object(builder, "menubar");
    gtk_application_set_menubar(app, G_MENU_MODEL(menubar));
}

int main(int argc, char **argv) {
    GtkApplication *app = gtk_application_new(NULL,
#ifdef GLIB_VERSION_2_74
            G_APPLICATION_DEFAULT_FLAGS
#else
            G_APPLICATION_FLAGS_NONE
#endif
    );
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
    g_application_run(G_APPLICATION(app), argc, argv);
}

I’m using an older version of Gio, which is why I have that ifdef but it shouldn’t matter cause I also tried this on an up-to-date machine
window.ui:

<interface>
    <object class="GtkApplicationWindow" id="window">
        <property name="default-width">600</property>
        <property name="default-height">400</property>
        <property name="visible">t</property>
    </object>
</interface>

menu.ui

<interface>
    <menu id="menubar">
        <submenu>
            <attribute name="label">File</attribute>
            <item>
                <attribute name="label">Open</attribute>
            </item>
        </submenu>
    </menu>
</interface>

When I do this, the menubar doesn’t show
image
But, if I remove the <property name="visible">t</property> line in window.ui and use
gtk_widget_set_visible(GTK_WIDGET(window), TRUE);
at the end of the activate function instead it works
image
Why does this happen?

Looking at the GTK 3 source code, it appears that the menu bar stuff is done when the window is being “realized” (which is done as part of making it visible in that gtk_builder_add_from_file() call, confirmed with a debugger). So when the UI file sets that property, it is already realized (and made visible) before you calling gtk_window_set_application() and gtk_application_set_menubar(). GtkApplicationWindow doesn’t appear to keep track whenever its GtkApplication or that menu bar changes to accommodate that situation. (A quick look at GTK 4 version it seems it has the same behaviour.)

Oh, so there is no way to add a menubar to an ApplicationWindow once it’s been made visible once? In this case being when it’s added to the Builder from the menu file. I tried setting it to not visible after building with gtk_widget_set_visible(GTK_WIDGET(window), FALSE); right after the line with GObject *window = gtk_builder_get_object(builder, "window"); but it didn’t work like so

void activate(GtkApplication *app, gpointer *data) {
    GtkBuilder *builder = gtk_builder_new();
    assert(gtk_builder_add_from_file(builder, "window.ui", NULL));
	assert(gtk_builder_add_from_file(builder, "menu.ui", NULL));
    GObject *window = gtk_builder_get_object(builder, "window");
	gtk_widget_set_visible(GTK_WIDGET(window), FALSE);
    gtk_window_set_application(GTK_WINDOW(window), app);
    GObject *menubar = gtk_builder_get_object(builder, "menubar");
    gtk_application_set_menubar(app, G_MENU_MODEL(menubar));

	gtk_widget_set_visible(GTK_WIDGET(window), TRUE);
}

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