Pager bug fixed.... or is it?
authorrodin <rodin@ddfedd41-794f-dd11-ae45-00112f111e67>
Sat, 17 Apr 2010 22:30:02 +0000 (22:30 +0000)
committerrodin <rodin@ddfedd41-794f-dd11-ae45-00112f111e67>
Sat, 17 Apr 2010 22:30:02 +0000 (22:30 +0000)
libchimara/input.c
libchimara/pager.c
libchimara/pager.h
libchimara/window.c

index c740809a0f36c69a0b61e18f97bc5334ac8697de..ddc41d8b216fe7ba14ccdc8359f1f41b2616fe66 100644 (file)
@@ -27,18 +27,6 @@ request_char_event_common(winid_t win, gboolean unicode)
        g_signal_handler_unblock( win->widget, win->char_input_keypress_handler );
 
        gdk_threads_enter();
-
-       /*
-       if(win->type == wintype_TextBuffer)
-       {
-               GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(win->widget) );
-               GtkTextIter iter;
-               gtk_text_buffer_get_end_iter(buffer, &iter);
-               gtk_text_buffer_place_cursor(buffer, &iter);
-               gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(win->widget), gtk_text_buffer_get_insert(buffer));
-               // Why doesn't this always work?? 
-       } */
-
        gtk_widget_grab_focus( GTK_WIDGET(win->widget) );
        gdk_threads_leave();
 
@@ -193,9 +181,6 @@ text_buffer_request_line_event_common(winid_t win, glui32 maxlen, gboolean inser
                gtk_text_buffer_get_end_iter(buffer, &end_iter); /* update after text insertion */
        }
 
-    /* Scroll to input point */
-    gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(win->widget), input_position);
-
        /* Apply the correct style to the input prompt */
        GtkTextIter input_iter;
     gtk_text_buffer_get_iter_at_mark(buffer, &input_iter, input_position);
index f9a0a32c69fa0b670ba01162603ec988e401513e..8fa8031a1ccc08ab4ecbe8f6b15ed626c6492cd1 100644 (file)
@@ -5,9 +5,13 @@
 /* Helper function: move the pager to the last visible position in the buffer,
  and return the distance between the pager and the end of the buffer in buffer
  coordinates */
-static gint
-move_pager_and_get_scroll_distance(GtkTextView *textview)
+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);
@@ -25,11 +29,12 @@ move_pager_and_get_scroll_distance(GtkTextView *textview)
        gtk_text_buffer_get_iter_at_mark(buffer, &newpager, pager);
        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);
-       
-       return endpos.y - pagerpos.y;
+       *view_height = visiblerect.height;
+       *scroll_distance = endpos.y - pagerpos.y;
 }
 
 /* Helper function: turn on paging for this textview */
@@ -50,18 +55,32 @@ 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 */
+/* Update the pager position after new text is inserted in the buffer and the
+text view has calculated where it is */
 void
-pager_after_insert_text(GtkTextBuffer *buffer, GtkTextIter *location, gchar *text, gint len, winid_t win)
+pager_after_size_allocate(GtkTextView *view, GtkAllocation *allocation, winid_t win)
 {
        while(gtk_events_pending())
                gtk_main_iteration();
        
        /* Move the pager to the last visible character in the buffer */
-       gint scroll_distance = move_pager_and_get_scroll_distance( GTK_TEXT_VIEW(win->widget) );
+       gint view_height, scroll_distance;
+       move_pager_and_get_scroll_distance( GTK_TEXT_VIEW(win->widget), &view_height, &scroll_distance );
        
-       if(scroll_distance > 0 && !win->currently_paging)
-               start_paging(win);
+       if(!win->currently_paging) {
+               if(scroll_distance > view_height) {
+                       start_paging(win);
+                       /* Seriously... */
+                       gdk_window_invalidate_rect(gtk_widget_get_window(win->widget), NULL, TRUE);
+               }
+               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();
+                       }
+               }
+       }
 }
 
 void
@@ -71,7 +90,8 @@ pager_after_adjustment_changed(GtkAdjustment *adj, winid_t win)
                gtk_main_iteration();
        
        /* Move the pager, etc. */
-       gint scroll_distance = move_pager_and_get_scroll_distance( GTK_TEXT_VIEW(win->widget) );
+       gint scroll_distance, view_height;
+       move_pager_and_get_scroll_distance( GTK_TEXT_VIEW(win->widget), &view_height, &scroll_distance );
        
        if(scroll_distance > 0 && !win->currently_paging)
                start_paging(win);
@@ -86,11 +106,6 @@ pager_after_adjustment_changed(GtkAdjustment *adj, winid_t win)
 gboolean
 pager_on_key_press_event(GtkTextView *textview, GdkEventKey *event, winid_t win)
 {
-       /*** ALTERNATIVE, POSSIBLY INFERIOR, METHOD OF SCROLLING ***
-       GtkTextMark *pagermark = gtk_text_buffer_get_mark(buffer, "pager_position");
-       gtk_text_view_scroll_to_mark(textview, pagermark, 0.0, TRUE, 0.0, 0.0);
-       */
-
        GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(win->frame) );
        gdouble step_increment, page_size, upper, lower, value;
        g_object_get(adj, 
@@ -131,12 +146,6 @@ pager_on_expose(GtkTextView *textview, GdkEventExpose *event, winid_t win)
 
        /* Draw the 'more' tag */
        GdkGC *context = gdk_gc_new(GDK_DRAWABLE(event->window));
-       /*
-       gdk_draw_layout_with_colors(event->window, context, 
-               winx + winwidth - promptwidth, 
-               winy + winheight - promptheight, 
-               prompt, &white, &red);
-       */
        gdk_draw_layout(event->window, context, 
                winx + winwidth - promptwidth, 
                winy + winheight - promptheight, 
index 1979646610b98e264bcc3c59be27b473ea8a02f7..87d0a4312dd6e0b300d3e34029d2068f394e12d9 100644 (file)
@@ -7,7 +7,7 @@
 
 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_insert_text(GtkTextBuffer *buffer, GtkTextIter *location, gchar *text, gint len, 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);
 
 #endif
index e8bcf3724a9a947fc86998d34231189121cd6ac1..6c635393303bcf2a49a8ffe9f71f3201011b2f3f 100644 (file)
@@ -547,11 +547,13 @@ glk_window_open(winid_t split, glui32 method, glui32 size, glui32 wintype,
                        /* Connect signal handlers */
                        
                        /* Pager */
-                       win->pager_expose_handler = g_signal_connect( textview, "expose-event", G_CALLBACK(pager_on_expose), win );
+                       /* "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 );
+                       //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);
 
@@ -571,10 +573,11 @@ glk_window_open(winid_t split, glui32 method, glui32 size, glui32 wintype,
                        (for line input) */
                        gtk_text_buffer_create_tag(textbuffer, "uneditable", "editable", FALSE, "editable-set", TRUE, NULL);
 
-                       /* Mark the position where the user will input text */
+                       /* Mark the position where the user will input text and the end mark */
                        GtkTextIter end;
                        gtk_text_buffer_get_end_iter(textbuffer, &end);
                        gtk_text_buffer_create_mark(textbuffer, "input_position", &end, TRUE);
+                       gtk_text_buffer_create_mark(textbuffer, "end_position", &end, FALSE);
 
                        /* Create the pager position mark; it stands for the last character in the buffer
                         that has been on-screen */