There are some problems with your code: a) you don't need to add_with_viewport, since the textview handles scrolling itself b) you should set up the widget hierarchy before filling and scrolling Doing these changes (see first attachment) already helps a lot, but there seem to be some problems with embedded widgets and scrolling, causing the the textview to end up scrolled some way down, but not to the very bottom. Doing c) avoid the nested textviews and simply insert the messages in the main textview (see second attachment) makes the scrolling work flawlessly. Matthias
#include <stdio.h> #include <gtk/gtk.h> int main(int argc, char **argv) { GtkWidget *window; GtkWidget *main_tv; GtkTextBuffer *buf; GtkTextTagTable *tag_table; GtkTextBuffer *insert_buf; GtkWidget *insert_tv; GtkTextIter iter; GtkTextIter finito; gint i = 0; GtkTextChildAnchor *anchor; GtkWidget *sw; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request (window, 600, 100); gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, TRUE); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit),NULL); main_tv = gtk_text_view_new(); gtk_text_view_set_editable (GTK_TEXT_VIEW (main_tv), FALSE); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (main_tv), GTK_WRAP_CHAR); gtk_text_view_set_left_margin (GTK_TEXT_VIEW (main_tv), 2); buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (main_tv)); tag_table = gtk_text_buffer_get_tag_table(buf); sw = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_container_add(GTK_CONTAINER(sw),main_tv); gtk_container_add(GTK_CONTAINER(window),sw); gtk_widget_show_all(window); for (i=0;i<25;i++) { insert_buf = gtk_text_buffer_new(tag_table); insert_tv = gtk_text_view_new_with_buffer(insert_buf); gtk_widget_show (insert_tv); gtk_text_buffer_get_start_iter (insert_buf, &iter); gchar *txt = g_strdup_printf("this is message %d\n for you\n", i); gtk_text_buffer_insert(insert_buf,&iter,txt, -1); g_free (txt); gtk_text_buffer_get_end_iter (buf, &finito); gtk_text_buffer_insert(buf,&finito,"\n", -1); gtk_text_buffer_get_end_iter (buf, &finito); anchor = gtk_text_buffer_create_child_anchor(buf,&finito); gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(main_tv),GTK_WIDGET(insert_tv),anchor); gtk_text_buffer_get_end_iter (buf, &finito); gtk_text_buffer_place_cursor (buf, &finito); gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (main_tv), gtk_text_buffer_get_insert (buf), 0.0, FALSE, 0.5,0.5); } gtk_main(); return 0; }
#include <stdio.h> #include <gtk/gtk.h> int main(int argc, char **argv) { GtkWidget *window; GtkWidget *main_tv; GtkTextBuffer *buf; GtkTextIter finito; gint i = 0; GtkWidget *sw; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request (window, 600, 100); gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, TRUE); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit),NULL); main_tv = gtk_text_view_new(); gtk_text_view_set_editable (GTK_TEXT_VIEW (main_tv), FALSE); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (main_tv), GTK_WRAP_CHAR); gtk_text_view_set_left_margin (GTK_TEXT_VIEW (main_tv), 2); buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (main_tv)); sw = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_container_add(GTK_CONTAINER(sw),main_tv); gtk_container_add(GTK_CONTAINER(window),sw); gtk_widget_show_all(window); for (i=0;i<25;i++) { gchar *txt = g_strdup_printf("this is message %d\n for you\n\n", i); gtk_text_buffer_get_end_iter (buf, &finito); gtk_text_buffer_insert(buf,&finito,txt, -1); g_free (txt); gtk_text_buffer_place_cursor (buf, &finito); gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (main_tv), gtk_text_buffer_get_insert (buf), 0.0, FALSE, 0.5,0.5); } gtk_main(); return 0; }