Всем привет. Есть вот такая програмка, демонстрирующая поведение GTK+ при изменении размера контейнера (в данном случае GtkWindow):
#include <gtk/gtk.h>
static void
window_resize_cb (GtkWidget *window, GtkAllocation *allocation, gpointer data)
{
g_message ("window: new size %dx%d", allocation->width, allocation->height);
}
static void
button_resize_cb (GtkWidget *window, GtkAllocation *allocation, gpointer data)
{
g_message ("button: new size %dx%d", allocation->width, allocation->height);
}
static void
window_size_request_cb (GtkWidget *window, GtkRequisition *requisition, gpointer data)
{
g_message ("window: request size %dx%d", requisition->width, requisition->height);
}
static void
button_size_request_cb (GtkWidget *window, GtkRequisition *requisition, gpointer data)
{
g_message ("button: request size %dx%d", requisition->width, requisition->height);
}
int
main (int argc, char *argv[])
{
GtkWidget *window, *button;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
button = gtk_button_new_with_label ("some label");
gtk_container_add (GTK_CONTAINER (window), button);
g_signal_connect (G_OBJECT (window), "size-allocate",
G_CALLBACK (window_resize_cb), NULL);
g_signal_connect (G_OBJECT (button), "size-allocate",
G_CALLBACK (button_resize_cb), NULL);
g_signal_connect (G_OBJECT (window), "size-request",
G_CALLBACK (window_size_request_cb), NULL);
g_signal_connect (G_OBJECT (button), "size-request",
G_CALLBACK (button_size_request_cb), NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
Собираем так: gcc -Wall -pedantic `pkg-config --cflags --libs gtk+-2.0` resizing.c -o resizing
Запускаем:
.$ ./resizing
** Message: button: request size 74x29
** Message: window: request size 94x49
** Message: button: new size 74x29
** Message: window: new size 94x49
-- здесь вопросов нету. Теперь делаем разовый ресайз окна средствами WM --
** Message: window: request size 94x49
** Message: button: new size 84x29
** Message: window: new size 104x49
** Message: window: request size 94x49
** Message: window: new size 104x49
Вот здесь начинаются вопросы.
Насколько мне известно, для вычисления новых размеров компонентов внутри контейнера,
контейнер рекурсивно запрашивает *желаемые* размеры "детей" (структура GtkRequisition). Это стадия 1.
Потом происходит фактическое выделение размеров (структура GtkAllocation). Это стадия 2.
В нормальных условиях, если свойство "resizable" окна не установлено в FALSE, то реальные размеры компонентов будут такими, какими они были на стадии 1.
Мы же видим следующее:
> ** Message: window: request size 94x49
Окно запрашивает старый размер
> ** Message: button: new size 84x29
Кнопка получает новый размер
> ** Message: window: new size 104x49
Окно получает новый размер
> ** Message: window: request size 94x49
Окно запрашивает старый размер и ...
> ** Message: window: new size 104x49
... получает новый.
Какая-то ерунда получается.
У меня есть подозрение, что я как-то неправильно полагаюсь на сигналы size-request и size-allocate,
хотя даже при этом условии как-то всё происходит странно.
Если кто-то в этом что-то понимает, поясните, плиз.
>>>