In gtk2 the following code snippet works to pack widgets into a gtk_dialog window, using the vbox and action_area of the GtkDialog structure:
window=gtk_dialog_new();
gtk_container_set_border_width((GtkContainer *)window, 0);
scrolled_window=gtk_scrolled_window_new(NULL,NULL);
gtk_container_set_border_width((GtkContainer *)scrolled_window, 10);
gtk_scrolled_window_set_shadow_type((GtkScrolledWindow *)scrolled_window, GTK_SHADOW_IN);
gtk_scrolled_window_set_policy((GtkScrolledWindow *)scrolled_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start((GtkBox *) (GtkDialog *)window->vbox), scrolled_window, TRUE, TRUE, 0);
gtk_widget_show(scrolled_window);
label=gtk_label_new(text);
gtk_label_set_use_markup((GtkLabel *)label, TRUE);
gtk_label_set_selectable((GtkLabel *)label, TRUE);
gtk_label_set_line_wrap((GtkLabel *)label, FALSE);
gtk_scrolled_window_add_with_viewport((GtkScrolledWindow *)scrolled_window, label);
gtk_widget_show(label);
button=gtk_button_new_with_label("close");
g_signal_connect_swapped(button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
gtk_widget_set_can_default(button, TRUE);
gtk_box_pack_start((GtkBox *) (GtkDialog *)window->action_area), button, TRUE, TRUE, 0);
gtk_widget_grab_default(button);
gtk_widget_show (button);
gtk_widget_show(window);
However in gtk3 this is not completely valid code any more. And it will not compile.
If I replace instances of:
(GtkBox *) (GtkDialog *)window->vbox
with:
(GtkBox *) (GtkDialog *)window
And do the same with instances of action_area the code will compile but the window will not show the extra packed widgets, just the ones the dialog comes with by default.
More information, which to me is a bit contradictory https://developer.gnome.org/gtk3/stable/GtkDialog.html#GtkDialog-struct
The GtkDialog contains only private fields and should not be directly accessed.
But when I read this on the same page it seems to contradict the previous quote https://developer.gnome.org/gtk3/stable/GtkDialog.html#gtk-dialog-add-action-widget
If you want to add a non-activatable widget, simply pack it into the action_area field of the GtkDialog struct.
Earlier in that document it states under GtkDialog as GtkBuildable
The GtkDialog implementation of the GtkBuildable interface exposes the vbox and action_area as internal children with the names “vbox” and “action_area”.
But I don't really know how to do that using the GtkBuildable interface neither do I want to. Or perhaps that is exactly what I did in gtk2 and it stopped working in gtk3...?
My question is how can I convert the gtk2 code to work with gtk3 with as few changes as possible. I have been searching for quite a while but found no answer yet. The existing gtk3 documentation leaves me going in circles. Maybe I just miss something totally obvious. Or perhaps you are not supposed to do this anymore and have to use a window instead of a dialog?
Thanks to the answer below I was able to change the code to this working one, it will also eliminate a deprecated warning about gtk_dialog_get_action_area() by using gtk_dialog_add_button()
window=gtk_dialog_new();
gtk_container_set_border_width((GtkContainer *)window, 0);
scrolled_window=gtk_scrolled_window_new(NULL,NULL);
gtk_container_set_border_width((GtkContainer *)scrolled_window, 10);
gtk_scrolled_window_set_shadow_type((GtkScrolledWindow *)scrolled_window, GTK_SHADOW_IN);
gtk_scrolled_window_set_policy((GtkScrolledWindow *)scrolled_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start((GtkBox *) (GtkDialog *) (gtk_dialog_get_content_area(window)), scrolled_window, TRUE, TRUE, 0);
gtk_widget_show(scrolled_window);
label=gtk_label_new(text);
gtk_label_set_use_markup((GtkLabel *)label, TRUE);
gtk_label_set_selectable((GtkLabel *)label, TRUE);
gtk_label_set_line_wrap((GtkLabel *)label, FALSE);
gtk_container_add((GtkContainer *)scrolled_window, label);
gtk_widget_show(label);
button=gtk_dialog_add_button((GtkDialog *)window, "close", GTK_RESPONSE_CLOSE);
g_signal_connect_swapped(button, "response", (GCallback *)gtk_widget_destroy, window);
gtk_widget_set_can_default(button, TRUE);
gtk_widget_grab_default(button);
gtk_widget_show(button);
gtk_widget_show(window);
gtk_dialog_run((GtkDialog*)window);
gtk_widget_destroy(window);
For the top section you gtk_dialog_get_content_area
. This will return a VBox, where you can pack your own widgets.
For the bottom section you either gtk_dialog_add_button
or gtk_dialog_add_action_widget
.
The GtkDialog contains only private fields and should not be directly accessed.
If you want to add a non-activatable widget, simply pack it into the action_area field of the GtkDialog struct.
You should obtain a pointer to action_area with deprecated (!)gtk_dialog_get_action_area
, but that will not allow to register a response id.