Placed pager functionality into the idle handler
authorrodin <rodin@ddfedd41-794f-dd11-ae45-00112f111e67>
Mon, 10 May 2010 20:21:26 +0000 (20:21 +0000)
committerrodin <rodin@ddfedd41-794f-dd11-ae45-00112f111e67>
Mon, 10 May 2010 20:21:26 +0000 (20:21 +0000)
libchimara/pager.c
libchimara/pager.h
libchimara/strio.c
libchimara/window.c

index 1fdbf4627b333ffb6d3c1ede74756345554ce514..a8904cf2a9cf2bb4bcc808ce1e25779301cf9596 100644 (file)
@@ -8,10 +8,6 @@
 static void
 move_pager_and_get_scroll_distance(GtkTextView *textview, gint *view_height, gint *scroll_distance)
 {
-       while( gtk_events_pending() ) {
-               gtk_main_iteration();
-       }
-
        GdkRectangle pagerpos, endpos, visiblerect;
        GtkTextIter oldpager, newpager, end;
        GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview);
@@ -19,7 +15,12 @@ move_pager_and_get_scroll_distance(GtkTextView *textview, gint *view_height, gin
        
        /* Get an iter at the lower right corner of the visible part of the buffer */
        gtk_text_view_get_visible_rect(textview, &visiblerect);
-       gtk_text_view_get_iter_at_location(textview, &newpager, visiblerect.x + visiblerect.width, visiblerect.y + visiblerect.height);
+       gtk_text_view_get_iter_at_location(
+               textview,
+               &newpager,
+               visiblerect.x + visiblerect.width,
+               visiblerect.y + visiblerect.height
+       );
        gtk_text_buffer_get_iter_at_mark(buffer, &oldpager, pager);
        
        gtk_text_buffer_move_mark(buffer, pager, &newpager);
@@ -30,8 +31,8 @@ move_pager_and_get_scroll_distance(GtkTextView *textview, gint *view_height, gin
        gtk_text_view_get_iter_location(textview, &newpager, &pagerpos);
        gtk_text_view_get_iter_location(textview, &end, &endpos);
 
-       /*g_printerr("View height = %d\n", visiblerect.height);
-       g_printerr("End - Pager = %d\n", endpos.y - pagerpos.y);*/
+       g_printerr("View height = %d\n", visiblerect.height);
+       g_printerr("End - Pager = %d\n", endpos.y - pagerpos.y);
        
        *view_height = visiblerect.height;
        *scroll_distance = endpos.y - pagerpos.y;
@@ -55,21 +56,23 @@ stop_paging(winid_t win)
        g_signal_handler_block(win->widget, win->pager_keypress_handler);
 }
 
-/* Update the pager position after new text is inserted in the buffer and the
-text view has calculated where it is */
-void
-pager_after_size_allocate(GtkTextView *view, GtkAllocation *allocation, winid_t win)
+/* Check whether paging should be done. This function is called inside the 
+ * idle handler, after the textview has finished updating. */
+gboolean
+pager_check(gpointer data)
 {
-       while(gtk_events_pending())
-               gtk_main_iteration();
-       
+
+       printf("pager check...\n");
+       winid_t win = (winid_t) data;
+
+
        /* Move the pager to the last visible character in the buffer */
        gint view_height, scroll_distance;
        move_pager_and_get_scroll_distance( GTK_TEXT_VIEW(win->widget), &view_height, &scroll_distance );
 
        if(view_height <= 1)
                /* Paging is unusable when window is too small */
-               return;
+               return FALSE;
        
        if(!win->currently_paging) {
                if(scroll_distance > view_height) {
@@ -84,20 +87,22 @@ pager_after_size_allocate(GtkTextView *view, GtkAllocation *allocation, winid_t
                }
                else if(scroll_distance > 0) {
                        GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(win->widget));
-                       gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(win->widget), gtk_text_buffer_get_mark(buffer, "end_position"));
-                       while( gtk_events_pending() ) {
-                               gtk_main_iteration();
-                       }
+                       GtkTextMark *end = gtk_text_buffer_get_mark(buffer, "end_position");
+
+                       gdk_threads_enter();
+                       gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(win->widget), end);
+                       gdk_threads_leave();
                }
        }
+
+       /* Returning FALSE to prevent this function from being called multiple times */
+       return FALSE;
 }
 
+/* When the user scrolls up in a textbuffer, start paging. */
 void
 pager_after_adjustment_changed(GtkAdjustment *adj, winid_t win)
 {
-       while(gtk_events_pending())
-               gtk_main_iteration();
-       
        /* Move the pager, etc. */
        gint scroll_distance, view_height;
        move_pager_and_get_scroll_distance( GTK_TEXT_VIEW(win->widget), &view_height, &scroll_distance );
@@ -162,3 +167,4 @@ pager_on_expose(GtkTextView *textview, GdkEventExpose *event, winid_t win)
 
        return FALSE; /* Propagate event further */
 }
+
index 87d0a4312dd6e0b300d3e34029d2068f394e12d9..3ee35d812d6aa4efc85b44b9e060790bb9b19952 100644 (file)
@@ -7,7 +7,8 @@
 
 G_GNUC_INTERNAL gboolean pager_on_expose(GtkTextView *textview, GdkEventExpose *event, winid_t win);
 G_GNUC_INTERNAL gboolean pager_on_key_press_event(GtkTextView *textview, GdkEventKey *event, winid_t win);
-G_GNUC_INTERNAL void pager_after_size_allocate(GtkTextView *view, GtkAllocation *allocation, winid_t win);
 G_GNUC_INTERNAL void pager_after_adjustment_changed(GtkAdjustment *adj, winid_t win);
+G_GNUC_INTERNAL gboolean pager_check(gpointer data);
+
 
 #endif
index bac31537c231a69fb4749df5afc54400118e1aac..ea9d7b5d5128a33d5a68a3ab93c367a1d294ae39 100644 (file)
@@ -4,6 +4,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
+#include <pager.h>
 #include <glib.h>
 #include <glib/gstdio.h>
 
@@ -62,6 +63,9 @@ flush_window_buffer(winid_t win)
                g_assert(glk);
                g_signal_emit_by_name(glk, "text-buffer-output", win->rock, win->buffer->str);
 
+               /* Schedule a check for the pager */
+               g_idle_add(pager_check, win);
+
        }
                break;
 
index 56cbd700e6d66f2a5d9b2f496073a18fcf91eb05..782acd1395232c54da35c7faa7550f6658468fc8 100644 (file)
@@ -552,13 +552,10 @@ glk_window_open(winid_t split, glui32 method, glui32 size, glui32 wintype,
                        /* Connect signal handlers */
                        
                        /* Pager */
-                       /* "size-allocate"? Really? WTF, GTK? */
-                       g_signal_connect_after( textview, "size-allocate", G_CALLBACK(pager_after_size_allocate), win );
                        win->pager_expose_handler = g_signal_connect_after( textview, "expose-event", G_CALLBACK(pager_on_expose), win );
                        g_signal_handler_block(textview, win->pager_expose_handler);
                        win->pager_keypress_handler = g_signal_connect( textview, "key-press-event", G_CALLBACK(pager_on_key_press_event), win );
                        g_signal_handler_block(textview, win->pager_keypress_handler);
-                       //g_signal_connect_after( textbuffer, "insert-text", G_CALLBACK(pager_after_insert_text), win );
                        GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolledwindow));
                        g_signal_connect_after(adj, "value-changed", G_CALLBACK(pager_after_adjustment_changed), win);