Re: Yet Another GtkText Bug...




Thomas Mailund Jensen <mailund@daimi.aau.dk> writes:

> Here's another program that crashes the text widget...I don't know if
> it's related to the other bugs...
> 
> Run the program, typein "foobar" (or something else with more than 3
> lettes), and then press F1.

OK, here is a set of patches which seems to fix all of the 
problems in your two test programs. (Fingers crossed....)

Let me know how they work for you. Thanks for the reports,

(The gtktext.c chunk should apply cleanly to either 1.0.5 or 1.1.0)

                                        Owen

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.353.2.69
diff -u -r1.353.2.69 ChangeLog
--- ChangeLog	1998/08/03 06:10:26	1.353.2.69
+++ ChangeLog	1998/08/03 23:27:56
@@ -1,3 +1,15 @@
+Mon Aug  3 19:24:48 1998  Owen Taylor  <otaylor@redhat.com>
+
+	* gtk/gtktext.c (gtk_text_forward_delete): Undraw the
+	  cursor before (possibly) deleting the cursor's text
+	  property.
+
+	* gtk/gtktext.c (correct_cache_delete): More attempts
+	  to clean the line-start cache up after inserting
+	  a property. Among other things, make sure to
+	  fix up text->current_line, since it is used to 
+	  refetch the changed lines.
+
 Sun Aug 02 23:09:56 1998  George Lebl  <jirka@5z.com>
 
 	* gtk/gtkclist.c: draw the buttons during a "draw" as well,
Index: gtk/gtkentry.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkentry.c,v
retrieving revision 1.44.2.1
diff -u -r1.44.2.1 gtkentry.c
--- gtkentry.c	1998/05/10 07:34:25	1.44.2.1
+++ gtkentry.c	1998/08/03 23:27:56
@@ -570,6 +570,9 @@
       entry->cursor = NULL;
     }
 
+  if (GTK_WIDGET_HAS_FOCUS (widget))
+    gtk_im_end ();
+  
   if (GTK_WIDGET_CLASS (parent_class)->unrealize)
     (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
 }
Index: gtk/gtktext.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktext.c,v
retrieving revision 1.38.2.4
diff -u -r1.38.2.4 gtktext.c
--- gtktext.c	1998/07/16 01:13:08	1.38.2.4
+++ gtktext.c	1998/08/03 23:27:56
@@ -798,6 +798,10 @@
   
   if (!text->freeze && (text->line_start_cache != NULL))
     {
+      /* We need to undraw the cursor here, since we may later
+       * delete the cursor's property
+       */
+      undraw_cursor (text, FALSE);
       find_line_containing_point (text, text->point.index, TRUE);
       compute_lines_pixels (text, nchars, &old_lines, &old_height);
     }
@@ -824,8 +828,8 @@
       MIN(nchars, editable->selection_end_pos - text->point.index);
   /* We'll reset the cursor later anyways if we aren't frozen */
   if (text->point.index < text->cursor_mark.index)
-    text->cursor_mark.index -=
-      MIN(nchars, text->cursor_mark.index - text->point.index);
+    move_mark_n (&text->cursor_mark, 
+		 -MIN(nchars, text->cursor_mark.index - text->point.index));
 
   move_gap_to_point (text);
 
@@ -834,7 +838,10 @@
   delete_text_property (text, nchars);
 
   if (!text->freeze && (text->line_start_cache != NULL))
-    delete_expose (text, nchars, old_lines, old_height);
+    {
+      delete_expose (text, nchars, old_lines, old_height);
+      draw_cursor (text, FALSE);
+    }
 
   if (frozen)
     gtk_text_thaw (text);
@@ -2297,8 +2304,6 @@
 
   text->cursor_virtual_x = 0;
 
-  undraw_cursor (text, FALSE);
-
   correct_cache_delete (text, nchars, old_lines);
 
   pixel_height = pixel_height_of(text, text->current_line) -
@@ -2350,8 +2355,6 @@
 
   find_cursor (text, TRUE);
 
-  draw_cursor (text, FALSE);
-
   if (old_pixels != new_pixels)
     process_exposes (text);
   
@@ -2366,15 +2369,41 @@
   GList *cache;
   GtkPropertyMark *start;
   GtkPropertyMark *end;
+  gboolean was_split = FALSE;
+
+  /* We need to distinguish whether the property was split in the
+   * insert or not, so we check if the point (which points after
+   * the insertion here), points to the same character as the
+   * point before. Ugh.
+   */
+  if (nchars > 0)
+    {
+      GtkPropertyMark tmp_mark = text->point;
+      move_mark_n (&tmp_mark, -1);
+
+      if (tmp_mark.property != text->point.property)
+	was_split = TRUE;
+    }
   
-  /* If we split a property exactly at the beginning of the
+  /* If we inserted a property exactly at the beginning of the
    * line, we have to correct here, or fetch_lines will
    * fetch junk.
+   *
+   * This also handles the case when we split exactly
+   *  at the beginning and start->offset is now invalid
    */
 
   start = &CACHE_DATA(text->current_line).start;
-  if (start->offset == MARK_CURRENT_PROPERTY (start)->length)
-    SET_PROPERTY_MARK (start, start->property->next, 0);
+  if (was_split)
+    {
+      /* If we split exactly at the beginning... */
+      if (start->offset ==  MARK_CURRENT_PROPERTY (start)->length)
+	SET_PROPERTY_MARK (start, start->property->next, 0);
+      /* If we inserted a property at the beginning of the text... */
+      else if ((start->property == text->point.property) &&
+	       (start->index == text->point.index - nchars))
+	SET_PROPERTY_MARK (start, start->property->prev, 0);
+    }
 
   /* Now correct the offsets, and check for start or end marks that
    * are after the point, yet point to a property before the point's
@@ -2394,7 +2423,7 @@
 	*start = text->point;
       else if (start->index >= text->point.index - nchars)
 	{
-	  if (start->property == text->point.property)
+	  if (!was_split && start->property == text->point.property)
 	    move_mark_n(start, nchars);
 	  else
 	    {
@@ -2414,7 +2443,7 @@
 	*end = text->point;
       if (end->index >= text->point.index - nchars)
 	{
-	  if (end->property == text->point.property)
+	  if (!was_split && end->property == text->point.property)
 	    move_mark_n(end, nchars);
 	  else 
 	    {
@@ -2766,6 +2795,24 @@
 delete_text_property (GtkText* text, guint nchars)
 {
   /* Delete nchars forward from point. */
+
+  /* Deleting text properties is problematical, because we
+   * might be storing around marks pointing to a property.
+   *
+   * The marks in question and how we handle them are:
+   *
+   *  point: We know the new value, since it will be at the
+   *         end of the deleted text, and we move it there
+   *         first.
+   *  cursor: We just remove the mark and set it equal to the
+   *         point after the operation.
+   *  line-start cache: We replace most affected lines.
+   *         The current line gets used to fetch the new
+   *         lines so, if necessary, (delete at the beginning
+   *         of a line) we fix it up by setting it equal to the
+   *         point.
+   */
+
   TextProperty *prop;
   GList        *tmp;
   gint          is_first;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]