Programmatically resize a box split (Next browser)

Hi!

I’m working on Next browser, an infinitely extensible web browser. The
GNU/Linux backend is webkitgtk. The GTK layout is very simple:

  • Top-level window
    • GTK box
      • webview widget
      • “minibuffer” widget (As in Emacs, a mix of command input and status display.)

The widgets are added the the GTK box with gtk_box_pack_end.
So far so good.

I’d like the minibuffer widget to occupy a specific, customizable height, say 50 pixels,
while the web view fills the rest.

Unfortunately, using gtk_widget_set_size_request works only the first time.
Subsequent calls always display the minibuffer with the first height.

See https://github.com/atlas-engineer/next/blob/master/ports/gtk-webkit/window.h#L367:

gint64 window_set_minibuffer_height(Window *window, gint64 height) {
	g_message("Window %s resizes its minibuffer to %li", window->identifier, height);
	if (height == 0) {
		gtk_widget_hide(GTK_WIDGET(window->minibuffer->web_view));
		return 0;
	}

	// TODO: Changing the size request of an existing object does not seem to work here.
	gtk_widget_set_size_request(GTK_WIDGET(window->minibuffer->web_view), -1, height);
	gtk_widget_show(GTK_WIDGET(window->minibuffer->web_view));
	window->minibuffer_height = height;

	gint minimum_height;
	gint natural_height;
	gtk_widget_get_preferred_height(GTK_WIDGET(window->minibuffer->web_view), &minimum_height, &natural_height);
	g_debug("minimum height %li, natural_height %li", minimum_height, natural_height);
	return natural_height;
}

Am I missing something?

Thanks in advance, cheers!

If you haven’t figured this out already, it would be helpful to post a minimal standalone example of the problem you’re having.

Yes, here is a snippet that reproduces my issue:

#include <gtk/gtk.h>

void print_heights(GtkWidget *widget) {
	gint minimum_height;
	gint natural_height;
	gtk_widget_get_preferred_height(widget, &minimum_height, &natural_height);
	g_message("minimum height %li, natural_height %li", minimum_height, natural_height);
}

static void callback (GtkWidget *widget, gpointer data) {
	GtkWidget *window = data;

	GList *children = gtk_container_get_children(GTK_CONTAINER(window));
	GtkWidget *mainbox = GTK_WIDGET(children->data);

	GList *box_children = gtk_container_get_children(GTK_CONTAINER(mainbox));
	GtkWidget *bottom_widget;
	if (g_list_length(box_children) == 1) {
		bottom_widget = gtk_label_new("foobar");
		gtk_widget_set_size_request(GTK_WIDGET(bottom_widget), -1, 100);
		gtk_box_pack_end(GTK_BOX(mainbox), GTK_WIDGET(bottom_widget), FALSE, FALSE, 0);
	} else {
		bottom_widget = GTK_WIDGET(box_children->data);
		gtk_widget_set_size_request(GTK_WIDGET(bottom_widget), -1, 200);
		g_message ("resizing");
	}

	gtk_widget_show_all(window);
	print_heights(bottom_widget);
}

int main(int argc, char *argv[]) {
	GError *error = NULL;

	gtk_init_with_args(&argc, &argv, "", NULL, NULL, &error);
	if (error) {
		g_error("%s", error->message);
		g_error_free(error);
		return EXIT_FAILURE;
	}

	GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);

	GtkWidget *mainbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
	gtk_container_add(GTK_CONTAINER(window), mainbox);

	GtkWidget *top_widget = gtk_button_new_with_label ("Hello World");
	g_signal_connect (top_widget, "clicked", G_CALLBACK (callback), window);
	gtk_box_pack_start(GTK_BOX(mainbox), GTK_WIDGET(top_widget), TRUE, TRUE, 0);

	gtk_widget_show_all(window);

	gtk_main();

	return EXIT_SUCCESS;
}

Compile with

$CC `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0` main.c

When you click on the button, it spawns a new label in the box.
Clicking again should resize this container. The g_message shows that thr natural size has changed, but the rendering remains the same.

box_children->data is the button; box_children->next->data would be the label.

By the way, I used the GTK Inspector to solve this. It showed that the label’s height-request was not changing, and that if I changed it in the inspector, the label resized.

You are right, iwas box_children->next->data, my bad.
I cannot reproduce the issue with my minimal example.

In Next browser, the inspector shows that the “height-request” is
changing, but it does not in practice.
Unless I’m mistaken, the only difference with my minimal example is that
the 2 widgets in the box are WebKit views.

Any idea?

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