fret
fret

Reputation: 1590

Why doesn't my GtkBox update until I resize the whole window?

When I attach a menu to a window I detach the existing root control, add a vertical GtkBox to hold the menu and the root control and then attach that box to the GtkWindow, like so:

Gtk::GtkWidget *menubar = GTK_WIDGET(Info.obj);

Wnd->_VBox = Gtk::gtk_box_new(Gtk::GTK_ORIENTATION_VERTICAL, 0);

Gtk::GtkBox *vbox = GTK_BOX(Wnd->_VBox);
Gtk::GtkContainer *wndcontainer = GTK_CONTAINER(Wnd->Wnd);

g_object_ref(Wnd->_Root);

gtk_container_remove(wndcontainer, Wnd->_Root);
gtk_box_pack_start(vbox, menubar, false, false, 0);
gtk_box_pack_end(vbox, Wnd->_Root, true, true, 0);
gtk_container_add(wndcontainer, Wnd->_VBox);

gtk_widget_show_all(GTK_WIDGET(Wnd->Wnd));

g_object_unref(Wnd->_Root);

gtk_window_add_accel_group(Wnd->Wnd, AccelGrp);

In practice it looks like this:

https://i.imgur.com/LtzQEHu.gifv

What I'd like is the menu to appear in the correct place automatically without having to resize the window to force a layout update.

I've tried calling gtk_widget_queue_draw on the window but that made no difference. Am I doing something wrong here? Can a call an extra function to invalidate the layout and get it to refresh?

Upvotes: 1

Views: 448

Answers (2)

fret
fret

Reputation: 1590

So while it should "just work" out of the box. And indeed on my Raspberry Pi the code does just do what it's supposed to do, this is still an issue on my Ubuntu 18 VM. I have found somewhat of a work around to kick the GtkBox into reconfiguring the child widget's layout:

GdkRectangle allocation = Wnd->GetClient();
g_signal_emit_by_name(G_OBJECT(vbox), "size-allocate", GTK_WIDGET(vbox), &allocation, NULL, NULL);

The menu now appears in the right location automatically. It seems like a "hack" that may stop working in the future or crash on some systems? IDK. But in terms of right now and Ubuntu 18, I don't have anything better.

Upvotes: 0

ntd
ntd

Reputation: 7434

It's difficult to answer without having a minimal reproducible example. Your code in not even plain GTK or gtkmm... it seems to be some exotic variant between the two.

Here is my attempt: I tried to be as close as possible to your code. The issue you are describing is not present though.

/* gcc -o test test.c $(pkg-config --cflags --libs gtk+-3.0) */
#include <gtk/gtk.h>

static GMenu *
menu_model(void)
{
    GMenu *menu = g_menu_new();
    g_menu_append(menu, "File", NULL);
    g_menu_append(menu, "Edit", NULL);
    g_menu_append(menu, "Project", NULL);
    /* ... */
    return menu;
}

int main(int argc, char **argv)
{
    GtkWidget *window;
    GMenuModel *model;
    GtkWidget *menubar;
    GtkWidget *content;
    GtkWidget *vbox;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    model = G_MENU_MODEL(menu_model());
    menubar = gtk_menu_bar_new_from_model(model);
    g_object_unref(model);

    content = gtk_label_new("Some content here");

    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
    gtk_box_pack_end(GTK_BOX(vbox), content, TRUE, TRUE, 0);
    gtk_container_add(GTK_CONTAINER(window), vbox);

    gtk_widget_show_all(GTK_WIDGET(window));
    gtk_main();
    return 0;
}

Upvotes: 1

Related Questions