This patch makes GtkEntry widget use the 'backspace_deletes_character'
Pango logical attribute to determine the proper behavior of backspace key.

Patch was made against 2004-05-01 CVS Head snapshot.

Theppitak Karoonboonyanan <thep@linux.thai.net>

diff -Nuar gtk+/gtk/gtkentry.c gtk+-bs/gtk/gtkentry.c
--- gtk+/gtk/gtkentry.c	2004-05-01 16:45:36.000000000 +0700
+++ gtk+-bs/gtk/gtkentry.c	2004-05-01 16:46:06.000000000 +0700
@@ -295,6 +295,9 @@
 static gint         gtk_entry_move_logically           (GtkEntry       *entry,
 							gint            start,
 							gint            count);
+static gint         gtk_entry_move_backspace           (GtkEntry       *entry,
+							gint            start,
+							gint            count);
 static gint         gtk_entry_move_forward_word        (GtkEntry       *entry,
 							gint            start);
 static gint         gtk_entry_move_backward_word       (GtkEntry       *entry,
@@ -737,13 +740,13 @@
   
   gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0,
 				"delete_from_cursor", 2,
-				G_TYPE_ENUM, GTK_DELETE_CHARS,
+				G_TYPE_ENUM, GTK_DELETE_BACKSPACE,
 				G_TYPE_INT, -1);
 
   /* Make this do the same as Backspace, to help with mis-typing */
   gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_SHIFT_MASK,
                                 "delete_from_cursor", 2,
-                                G_TYPE_ENUM, GTK_DELETE_CHARS,
+                                G_TYPE_ENUM, GTK_DELETE_BACKSPACE,
                                 G_TYPE_INT, -1);
 
   gtk_binding_entry_add_signal (binding_set, GDK_Delete, GDK_CONTROL_MASK,
@@ -2325,6 +2328,10 @@
     case GTK_DELETE_WHITESPACE:
       gtk_entry_delete_whitespace (entry);
       break;
+    case GTK_DELETE_BACKSPACE:
+      end_pos = gtk_entry_move_backspace (entry, entry->current_pos, count);
+      gtk_editable_delete_text (editable, MIN (start_pos, end_pos), MAX (start_pos, end_pos));
+      break;
     }
   
   gtk_entry_pend_cursor_blink (entry);
@@ -3282,6 +3289,56 @@
 }
 
 static gint
+gtk_entry_move_backspace (GtkEntry *entry,
+			  gint      start,
+			  gint      count)
+{
+  gint new_pos = start;
+
+  g_return_val_if_fail ((count < 0), new_pos);
+
+  /* Prevent any leak of information */
+  if (!entry->visible)
+    {
+      new_pos = CLAMP (start + count, 0, entry->text_length);
+    }
+  else if (entry->text)
+    {
+      PangoLayout *layout = gtk_entry_ensure_layout (entry, FALSE);
+      PangoLogAttr *log_attrs;
+      gint n_attrs;
+
+      pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
+
+      while (count < 0 && new_pos > 0)
+	{
+	  if (new_pos == n_attrs
+	      || log_attrs[new_pos].backspace_deletes_character)
+	    {
+	      do
+		{
+	          new_pos--;
+	          count++;
+		}
+	      while (count < 0 && new_pos > 0 && !log_attrs[new_pos].is_cursor_position);
+	    }
+	  else
+	    {
+	      do
+	        new_pos--;
+	      while (new_pos > 0 && !log_attrs[new_pos].is_cursor_position);
+	  
+	      count++;
+	    }
+	}
+      
+      g_free (log_attrs);
+    }
+
+  return new_pos;
+}
+
+static gint
 gtk_entry_move_forward_word (GtkEntry *entry,
 			     gint      start)
 {
diff -Nuar gtk+/gtk/gtkenums.h gtk+-bs/gtk/gtkenums.h
--- gtk+/gtk/gtkenums.h	2004-05-01 16:45:36.000000000 +0700
+++ gtk+-bs/gtk/gtkenums.h	2004-05-01 16:46:06.000000000 +0700
@@ -101,7 +101,8 @@
   GTK_DELETE_DISPLAY_LINE_ENDS,
   GTK_DELETE_PARAGRAPH_ENDS,      /* like C-k in Emacs (or its reverse) */
   GTK_DELETE_PARAGRAPHS,          /* C-k in pico, kill whole line */
-  GTK_DELETE_WHITESPACE           /* M-\ in Emacs */
+  GTK_DELETE_WHITESPACE,          /* M-\ in Emacs */
+  GTK_DELETE_BACKSPACE
 } GtkDeleteType;
 
 /* Focus movement types */
diff -Nuar gtk+/gtk/gtktypebuiltins.c gtk+-bs/gtk/gtktypebuiltins.c
--- gtk+/gtk/gtktypebuiltins.c	2004-05-01 16:45:36.000000000 +0700
+++ gtk+-bs/gtk/gtktypebuiltins.c	2004-05-01 16:46:06.000000000 +0700
@@ -415,6 +415,7 @@
       { GTK_DELETE_PARAGRAPH_ENDS, "GTK_DELETE_PARAGRAPH_ENDS", "paragraph-ends" },
       { GTK_DELETE_PARAGRAPHS, "GTK_DELETE_PARAGRAPHS", "paragraphs" },
       { GTK_DELETE_WHITESPACE, "GTK_DELETE_WHITESPACE", "whitespace" },
+      { GTK_DELETE_BACKSPACE, "GTK_DELETE_BACKSPACE", "backspace" },
       { 0, NULL, NULL }
     };
     etype = g_enum_register_static ("GtkDeleteType", values);
