]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktextview.c
Correct docs for program-name property. (#496689, Thomas Wood)
[~andy/gtk] / gtk / gtktextview.c
index 910125dbdcbf04048a81b9180fa499cc2fbb9d18..62c1783105367a00406eb6b860c896a22b34fab5 100644 (file)
@@ -107,6 +107,7 @@ typedef struct _GtkTextViewPrivate GtkTextViewPrivate;
 struct _GtkTextViewPrivate 
 {
   guint blink_time;  /* time in msec the cursor has blinked since last user event */
+  guint im_spot_idle;
 };
 
 
@@ -133,9 +134,9 @@ enum
   COPY_CLIPBOARD,
   PASTE_CLIPBOARD,
   TOGGLE_OVERWRITE,
-  MOVE_FOCUS,
   MOVE_VIEWPORT,
   SELECT_ALL,
+  TOGGLE_CURSOR_VISIBLE,
   LAST_SIGNAL
 };
 
@@ -205,6 +206,8 @@ static gint gtk_text_view_expose_event         (GtkWidget        *widget,
 static void gtk_text_view_draw_focus           (GtkWidget        *widget);
 static gboolean gtk_text_view_focus            (GtkWidget        *widget,
                                                 GtkDirectionType  direction);
+static void gtk_text_view_move_focus           (GtkWidget        *widget,
+                                                GtkDirectionType  direction_type);
 static void gtk_text_view_select_all           (GtkWidget        *widget,
                                                 gboolean          select);
 
@@ -256,7 +259,7 @@ static void gtk_text_view_move_cursor       (GtkTextView           *text_view,
 static void gtk_text_view_page_horizontally (GtkTextView          *text_view,
                                              gint                  count,
                                              gboolean              extend_selection);
-static void gtk_text_view_move_viewport     (GtkTextView           *text_view,
+static gboolean gtk_text_view_move_viewport (GtkTextView           *text_view,
                                              GtkScrollStep          step,
                                              gint                   count);
 static void gtk_text_view_set_anchor       (GtkTextView           *text_view);
@@ -276,7 +279,8 @@ static void gtk_text_view_cut_clipboard    (GtkTextView           *text_view);
 static void gtk_text_view_copy_clipboard   (GtkTextView           *text_view);
 static void gtk_text_view_paste_clipboard  (GtkTextView           *text_view);
 static void gtk_text_view_toggle_overwrite (GtkTextView           *text_view);
-static void gtk_text_view_move_focus       (GtkTextView           *text_view,
+static void gtk_text_view_toggle_cursor_visible (GtkTextView      *text_view);
+static void gtk_text_view_compat_move_focus(GtkTextView           *text_view,
                                             GtkDirectionType       direction_type);
 static void gtk_text_view_unselect         (GtkTextView           *text_view);
 
@@ -294,8 +298,7 @@ static void     gtk_text_view_reset_im_context       (GtkTextView        *text_v
 static void     gtk_text_view_start_selection_drag   (GtkTextView        *text_view,
                                                       const GtkTextIter  *iter,
                                                       GdkEventButton     *event);
-static gboolean gtk_text_view_end_selection_drag     (GtkTextView        *text_view,
-                                                      GdkEventButton     *event);
+static gboolean gtk_text_view_end_selection_drag     (GtkTextView        *text_view);
 static void     gtk_text_view_start_selection_dnd    (GtkTextView        *text_view,
                                                       const GtkTextIter  *iter,
                                                       GdkEventMotion     *event);
@@ -489,7 +492,16 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   widget_class->motion_notify_event = gtk_text_view_motion_event;
   widget_class->expose_event = gtk_text_view_expose_event;
   widget_class->focus = gtk_text_view_focus;
-  
+
+  /* need to override the base class function via override_class_closure,
+   * because the signal slot is not available in GtkWidgetCLass
+   */
+  g_signal_override_class_closure (g_signal_lookup ("move-focus",
+                                                    GTK_TYPE_WIDGET),
+                                   GTK_TYPE_TEXT_VIEW,
+                                   g_cclosure_new (G_CALLBACK (gtk_text_view_move_focus),
+                                                   NULL, NULL));
+
   widget_class->drag_begin = gtk_text_view_drag_begin;
   widget_class->drag_end = gtk_text_view_drag_end;
   widget_class->drag_data_get = gtk_text_view_drag_data_get;
@@ -516,7 +528,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   klass->copy_clipboard = gtk_text_view_copy_clipboard;
   klass->paste_clipboard = gtk_text_view_paste_clipboard;
   klass->toggle_overwrite = gtk_text_view_toggle_overwrite;
-  klass->move_focus = gtk_text_view_move_focus;
+  klass->move_focus = gtk_text_view_compat_move_focus;
   klass->set_scroll_adjustments = gtk_text_view_set_scroll_adjustments;
 
   /*
@@ -604,7 +616,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                                    g_param_spec_int ("indent",
                                                     P_("Indent"),
                                                     P_("Amount to indent the paragraph, in pixels"),
-                                                    0,
+                                                    G_MININT,
                                                     G_MAXINT,
                                                     0,
                                                     GTK_PARAM_READWRITE));
@@ -665,18 +677,32 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
 
   /**
    * GtkTextView::move-cursor: 
-   * @widget: the object which received the signal
+   * @text_view: the object which received the signal
    * @step: the granularity of the move, as a #GtkMovementStep
    * @count: the number of @step units to move
    * @extend_selection: %TRUE if the move should extend the selection
    *  
-   * The ::move-cursor signal is a keybinding signal which gets emitted
-   * when the user initiates a cursor movement. 
+   * The ::move-cursor signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which gets emitted when the user initiates a cursor movement. 
+   * If the cursor is not visible in @text_view, this signal causes
+   * the viewport to be moved instead.
    *
    * Applications should not connect to it, but may emit it with 
    * g_signal_emit_by_name() if they need to control scrolling 
    * programmatically.
    *
+   * The default bindings for this signal come in two variants,
+   * the variant with the Shift modifier extends the selection,
+   * the variant without the Shift modifer does not.
+   * There are too many key combinations to list them all here.
+   * <itemizedlist>
+   * <listitem>Arrow keys move by individual characters/lines</listitem>
+   * <listitem>Ctrl-arrow key combinations move by words/paragraphs</listitem>
+   * <listitem>Home/End keys move to the ends of the buffer</listitem>
+   * <listitem>PageUp/PageDown keys move vertically by pages</listitem>
+   * <listitem>Ctrl-PageUp/PageDown keys move horizontally by pages</listitem>
+   * </itemizedlist>
    */
   signals[MOVE_CURSOR] = 
     g_signal_new (I_("move_cursor"),
@@ -690,6 +716,21 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_INT, 
                  G_TYPE_BOOLEAN);
 
+  /**
+   * GtkTextView::page-horizontally:
+   * @text_view: the object which received the signal
+   * @count: the number of @step units to move
+   * @extend_selection: %TRUE if the move should extend the selection
+   *
+   * The ::page-horizontally signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which can be bound to key combinations to allow the user
+   * to initiate horizontal cursor movement by pages.  
+   * 
+   * This signal should not be used anymore, instead use the
+   * #GtkTextview::move-cursor signal with the #GTK_MOVEMENT_HORIZONTAL_PAGES
+   * granularity.
+   */
   signals[PAGE_HORIZONTALLY] =
     g_signal_new (I_("page_horizontally"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -701,6 +742,20 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_INT,
                  G_TYPE_BOOLEAN);
   
+  /**
+   * GtkTextView::move-viewport:
+   * @text_view: the object which received the signal
+   * @step: the granularity of the move, as a #GtkMovementStep
+   * @count: the number of @step units to move
+   *
+   * The ::move-viewport signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which can be bound to key combinations to allow the user
+   * to move the viewport, i.e. change what part of the text view
+   * is visible in a containing scrolled window.
+   *
+   * There are no default bindings for this signal.
+   */
   signals[MOVE_VIEWPORT] =
     _gtk_binding_signal_new (I_("move_viewport"),
                             G_OBJECT_CLASS_TYPE (gobject_class),
@@ -731,6 +786,25 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_NONE, 1,
                  G_TYPE_STRING);
 
+  /**
+   * GtkTextView::delete-from-cursor:
+   * @text_view: the object which received the signal
+   * @type: the granularity of the deletion, as a #GtkDeleteType
+   * @count: the number of @type units to delete
+   *
+   * The ::delete-from-cursor signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which gets emitted when the user initiates a text deletion.
+   *
+   * If the @type is %GTK_DELETE_CHARS, GTK+ deletes the selection
+   * if there is one, otherwise it deletes the requested number
+   * of characters.
+   *
+   * The default bindings for this signal are
+   * Delete for deleting a character, Ctrl-Delete for 
+   * deleting a word and Ctrl-Backspace for deleting a word 
+   * backwords.
+   */
   signals[DELETE_FROM_CURSOR] =
     g_signal_new (I_("delete_from_cursor"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -742,6 +816,17 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  GTK_TYPE_DELETE_TYPE,
                  G_TYPE_INT);
 
+  /**
+   * GtkTextView::backspace:
+   * @text_view: the object which received the signal
+   *
+   * The ::backspace signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which gets emitted when the user asks for it.
+   * 
+   * The default bindings for this signal are
+   * Backspace and Shift-Backspace.
+   */
   signals[BACKSPACE] =
     g_signal_new (I_("backspace"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -751,6 +836,17 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
 
+  /**
+   * GtkTextView::cut-clipboard:
+   * @text_view: the object which received the signal
+   *
+   * The ::cut-clipboard signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which gets emitted to cut the selection to the clipboard.
+   * 
+   * The default bindings for this signal are
+   * Ctrl-x and Shift-Delete.
+   */
   signals[CUT_CLIPBOARD] =
     g_signal_new (I_("cut_clipboard"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -760,6 +856,17 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
 
+  /**
+   * GtkTextView::copy-clipboard:
+   * @text_view: the object which received the signal
+   *
+   * The ::copy-clipboard signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which gets emitted to copy the selection to the clipboard.
+   * 
+   * The default bindings for this signal are
+   * Ctrl-c and Ctrl-Insert.
+   */
   signals[COPY_CLIPBOARD] =
     g_signal_new (I_("copy_clipboard"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -769,6 +876,18 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
 
+  /**
+   * GtkTextView::paste-clipboard:
+   * @text_view: the object which received the signal
+   *
+   * The ::paste-clipboard signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which gets emitted to paste the contents of the clipboard 
+   * into the text view.
+   * 
+   * The default bindings for this signal are
+   * Ctrl-v and Shift-Insert.
+   */
   signals[PASTE_CLIPBOARD] =
     g_signal_new (I_("paste_clipboard"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -778,6 +897,16 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
 
+  /**
+   * GtkTextView::toggle-overwrite:
+   * @text_view: the object which received the signal
+   *
+   * The ::toggle-overwrite signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which gets emitted to change the editability of the text view.
+   * 
+   * The default bindings for this signal is Insert.
+   */ 
   signals[TOGGLE_OVERWRITE] =
     g_signal_new (I_("toggle_overwrite"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -787,16 +916,6 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  _gtk_marshal_VOID__VOID,
                  G_TYPE_NONE, 0);
 
-  signals[MOVE_FOCUS] =
-    g_signal_new (I_("move_focus"),
-                 G_OBJECT_CLASS_TYPE (gobject_class),
-                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-                 G_STRUCT_OFFSET (GtkTextViewClass, move_focus),
-                 NULL, NULL,
-                 _gtk_marshal_VOID__ENUM,
-                 G_TYPE_NONE, 1,
-                 GTK_TYPE_DIRECTION_TYPE);
-  
   signals[SET_SCROLL_ADJUSTMENTS] =
     g_signal_new (I_("set_scroll_adjustments"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -819,6 +938,19 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                  G_TYPE_NONE, 1,
                  GTK_TYPE_MENU);
   
+  /**
+   * GtkTextView::select-all:
+   * @text_view: the object which received the signal
+   * @select: %TRUE to select, %FALSE to unselect
+   *
+   * The ::select-all signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which gets emitted to select or unselect the complete
+   * contents of the text view.
+   *
+   * The default bindings for this signal are Ctrl-a and Ctrl-/ 
+   * for selecting and Shift-Ctrl-a and Ctrl-\ for unselecting.
+   */
   signals[SELECT_ALL] =
     _gtk_binding_signal_new (I_("select_all"),
                             G_OBJECT_CLASS_TYPE (object_class),
@@ -826,10 +958,27 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                             G_CALLBACK (gtk_text_view_select_all),
                             NULL, NULL,
                             _gtk_marshal_VOID__BOOLEAN,
-                            G_TYPE_NONE, 1,
-                            G_TYPE_BOOLEAN, TRUE);
+                            G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+  /**
+   * GtkTextView::toggle-cursor-visible:
+   * @text_view: the object which received the signal
+   *
+   * The ::toggle-cursor-visible signal is a 
+   * <link linkend="keybinding-signals">keybinding signal</link> 
+   * which gets emitted to toggle the visibility of the cursor.
+   *
+   * The default binding for this signal is F7.
+   */ 
+  signals[TOGGLE_CURSOR_VISIBLE] =
+    _gtk_binding_signal_new (I_("toggle_cursor_visible"),
+                            G_OBJECT_CLASS_TYPE (object_class),
+                            G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                            G_CALLBACK (gtk_text_view_toggle_cursor_visible),
+                            NULL, NULL,
+                            _gtk_marshal_VOID__VOID,
+                            G_TYPE_NONE, 0);
 
-  
   /*
    * Key bindings
    */
@@ -1006,6 +1155,10 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   gtk_binding_entry_add_signal (binding_set, GDK_KP_Insert, 0,
                                "toggle_overwrite", 0);
 
+  /* Caret mode */
+  gtk_binding_entry_add_signal (binding_set, GDK_F7, 0,
+                               "toggle_cursor_visible", 0);
+
   /* Control-tab focus motion */
   gtk_binding_entry_add_signal (binding_set, GDK_Tab, GDK_CONTROL_MASK,
                                "move_focus", 1,
@@ -1106,7 +1259,7 @@ gtk_text_view_new (void)
  *
  * Creates a new #GtkTextView widget displaying the buffer
  * @buffer. One buffer can be shared among many widgets.
- * @buffer may be NULL to create a default buffer, in which case
+ * @buffer may be %NULL to create a default buffer, in which case
  * this function is equivalent to gtk_text_view_new(). The
  * text view adds its own reference count to the buffer; it does not
  * take over an existing reference.
@@ -1135,7 +1288,6 @@ gtk_text_view_new_with_buffer (GtkTextBuffer *buffer)
  * added to @buffer. If you owned a reference to @buffer before passing it
  * to this function, you must remove that reference yourself; #GtkTextView
  * will not "adopt" it.
- *
  **/
 void
 gtk_text_view_set_buffer (GtkTextView   *text_view,
@@ -1178,6 +1330,7 @@ gtk_text_view_set_buffer (GtkTextView   *text_view,
                                             text_view);
       g_object_unref (text_view->buffer);
       text_view->dnd_mark = NULL;
+      text_view->first_para_mark = NULL;
 
       if (GTK_WIDGET_REALIZED (text_view))
        {
@@ -1280,7 +1433,6 @@ gtk_text_view_get_buffer (GtkTextView *text_view)
  * currently-displayed portion.  If you have coordinates from an
  * event, you have to convert those to buffer coordinates with
  * gtk_text_view_window_to_buffer_coords().
- *
  **/
 void
 gtk_text_view_get_iter_at_location (GtkTextView *text_view,
@@ -1347,7 +1499,6 @@ gtk_text_view_get_iter_at_position (GtkTextView *text_view,
  * The rectangle position is in buffer coordinates; use
  * gtk_text_view_buffer_to_window_coords() to convert these
  * coordinates to coordinates for one of the windows in the text view.
- *
  **/
 void
 gtk_text_view_get_iter_location (GtkTextView       *text_view,
@@ -1372,7 +1523,6 @@ gtk_text_view_get_iter_location (GtkTextView       *text_view,
  * Gets the y coordinate of the top of the line containing @iter,
  * and the height of the line. The coordinate is a buffer coordinate;
  * convert to window coordinates with gtk_text_view_buffer_to_window_coords().
- *
  **/
 void
 gtk_text_view_get_line_yrange (GtkTextView       *text_view,
@@ -1449,22 +1599,25 @@ set_adjustment_clamped (GtkAdjustment *adj, gdouble val)
  * @text_view: a #GtkTextView
  * @iter: a #GtkTextIter
  * @within_margin: margin as a [0.0,0.5) fraction of screen size
- * @use_align: whether to use alignment arguments (if %FALSE, just get the mark onscreen)
- * @xalign: horizontal alignment of mark within visible area.
+ * @use_align: whether to use alignment arguments (if %FALSE, 
+ *    just get the mark onscreen)
+ * @xalign: horizontal alignment of mark within visible area
  * @yalign: vertical alignment of mark within visible area
  *
  * Scrolls @text_view so that @iter is on the screen in the position
  * indicated by @xalign and @yalign. An alignment of 0.0 indicates
- * left or top, 1.0 indicates right or bottom, 0.5 means center. If @use_align
- * is %FALSE, the text scrolls the minimal distance to get the mark onscreen,
- * possibly not scrolling at all. The effective screen for purposes
- * of this function is reduced by a margin of size @within_margin.
- * NOTE: This function uses the currently-computed height of the
- * lines in the text buffer. Note that line heights are computed
- * in an idle handler; so this function may not have the desired effect
- * if it's called before the height computations. To avoid oddness,
- * consider using gtk_text_view_scroll_to_mark() which saves a point
- * to be scrolled to after line validation.
+ * left or top, 1.0 indicates right or bottom, 0.5 means center. 
+ * If @use_align is %FALSE, the text scrolls the minimal distance to 
+ * get the mark onscreen, possibly not scrolling at all. The effective 
+ * screen for purposes of this function is reduced by a margin of size 
+ * @within_margin.
+ *
+ * Note that this function uses the currently-computed height of the
+ * lines in the text buffer. Line heights are computed in an idle 
+ * handler; so this function may not have the desired effect if it's 
+ * called before the height computations. To avoid oddness, consider 
+ * using gtk_text_view_scroll_to_mark() which saves a point to be 
+ * scrolled to after line validation.
  *
  * Return value: %TRUE if scrolling occurred
  **/
@@ -1839,22 +1992,66 @@ gtk_text_view_update_im_spot_location (GtkTextView *text_view)
   gtk_im_context_set_cursor_location (text_view->im_context, &area);
 }
 
+static gboolean
+do_update_im_spot_location (gpointer text_view)
+{
+  GtkTextViewPrivate *priv;
+
+  priv = GTK_TEXT_VIEW_GET_PRIVATE (text_view);
+  priv->im_spot_idle = 0;
+
+  gtk_text_view_update_im_spot_location (text_view);
+  return FALSE;
+}
+
+static void
+queue_update_im_spot_location (GtkTextView *text_view)
+{
+  GtkTextViewPrivate *priv;
+
+  priv = GTK_TEXT_VIEW_GET_PRIVATE (text_view);
+
+  /* Use priority a little higher than GTK_TEXT_VIEW_PRIORITY_VALIDATE,
+   * so we don't wait until the entire buffer has been validated. */
+  if (!priv->im_spot_idle)
+    priv->im_spot_idle = gdk_threads_add_idle_full (GTK_TEXT_VIEW_PRIORITY_VALIDATE - 1,
+                                                   do_update_im_spot_location,
+                                                   text_view,
+                                                   NULL);
+}
+
+static void
+flush_update_im_spot_location (GtkTextView *text_view)
+{
+  GtkTextViewPrivate *priv;
+
+  priv = GTK_TEXT_VIEW_GET_PRIVATE (text_view);
+
+  if (priv->im_spot_idle)
+    {
+      g_source_remove (priv->im_spot_idle);
+      priv->im_spot_idle = 0;
+      gtk_text_view_update_im_spot_location (text_view);
+    }
+}
+
 /**
  * gtk_text_view_scroll_to_mark:
  * @text_view: a #GtkTextView
  * @mark: a #GtkTextMark
  * @within_margin: margin as a [0.0,0.5) fraction of screen size
- * @use_align: whether to use alignment arguments (if %FALSE, just get the mark onscreen)
- * @xalign: horizontal alignment of mark within visible area.
+ * @use_align: whether to use alignment arguments (if %FALSE, just 
+ *    get the mark onscreen)
+ * @xalign: horizontal alignment of mark within visible area
  * @yalign: vertical alignment of mark within visible area
  *
  * Scrolls @text_view so that @mark is on the screen in the position
  * indicated by @xalign and @yalign. An alignment of 0.0 indicates
- * left or top, 1.0 indicates right or bottom, 0.5 means center. If @use_align
- * is %FALSE, the text scrolls the minimal distance to get the mark onscreen,
- * possibly not scrolling at all. The effective screen for purposes
- * of this function is reduced by a margin of size @within_margin.
- *
+ * left or top, 1.0 indicates right or bottom, 0.5 means center. 
+ * If @use_align is %FALSE, the text scrolls the minimal distance to 
+ * get the mark onscreen, possibly not scrolling at all. The effective 
+ * screen for purposes of this function is reduced by a margin of size 
+ * @within_margin.
  **/
 void
 gtk_text_view_scroll_to_mark (GtkTextView *text_view,
@@ -1891,7 +2088,6 @@ gtk_text_view_scroll_to_mark (GtkTextView *text_view,
  * 
  * Scrolls @text_view the minimum distance such that @mark is contained
  * within the visible area of the widget.
- * 
  **/
 void
 gtk_text_view_scroll_mark_onscreen (GtkTextView *text_view,
@@ -2043,6 +2239,8 @@ gtk_text_view_set_editable (GtkTextView *text_view,
 
       if (text_view->layout)
         {
+         gtk_text_layout_set_overwrite_mode (text_view->layout,
+                                             text_view->overwrite_mode && text_view->editable);
           text_view->layout->default_style->editable = text_view->editable;
           gtk_text_layout_default_style_changed (text_view->layout);
         }
@@ -2075,7 +2273,6 @@ gtk_text_view_get_editable (GtkTextView *text_view)
  * 
  * Sets the default number of blank pixels above paragraphs in @text_view.
  * Tags in the buffer for @text_view may override the defaults.
- * 
  **/
 void
 gtk_text_view_set_pixels_above_lines (GtkTextView *text_view,
@@ -2121,7 +2318,6 @@ gtk_text_view_get_pixels_above_lines (GtkTextView *text_view)
  * Sets the default number of pixels of blank space
  * to put below paragraphs in @text_view. May be overridden
  * by tags applied to @text_view's buffer. 
- * 
  **/
 void
 gtk_text_view_set_pixels_below_lines (GtkTextView *text_view,
@@ -2167,7 +2363,6 @@ gtk_text_view_get_pixels_below_lines (GtkTextView *text_view)
  * Sets the default number of pixels of blank space to leave between
  * display/wrapped lines within a paragraph. May be overridden by
  * tags in @text_view's buffer.
- * 
  **/
 void
 gtk_text_view_set_pixels_inside_wrap (GtkTextView *text_view,
@@ -2258,7 +2453,6 @@ gtk_text_view_get_justification (GtkTextView *text_view)
  * 
  * Sets the default left margin for text in @text_view.
  * Tags in the buffer may override the default.
- * 
  **/
 void
 gtk_text_view_set_left_margin (GtkTextView *text_view,
@@ -2304,7 +2498,6 @@ gtk_text_view_get_left_margin (GtkTextView *text_view)
  *
  * Sets the default right margin for text in the text view.
  * Tags in the buffer may override the default.
- * 
  **/
 void
 gtk_text_view_set_right_margin (GtkTextView *text_view,
@@ -2350,7 +2543,6 @@ gtk_text_view_get_right_margin (GtkTextView *text_view)
  *
  * Sets the default indentation for paragraphs in @text_view.
  * Tags in the buffer may override the default.
- * 
  **/
 void
 gtk_text_view_set_indent (GtkTextView *text_view,
@@ -2397,7 +2589,6 @@ gtk_text_view_get_indent (GtkTextView *text_view)
  *
  * Sets the default tab stops for paragraphs in @text_view.
  * Tags in the buffer may override the default.
- * 
  **/
 void
 gtk_text_view_set_tabs (GtkTextView   *text_view,
@@ -2434,7 +2625,8 @@ gtk_text_view_set_tabs (GtkTextView   *text_view,
  * "standard" (8-space) tabs are used. Free the return value
  * with pango_tab_array_free().
  * 
- * Return value: copy of default tab array, or %NULL if "standard" tabs are used; must be freed with pango_tab_array_free().
+ * Return value: copy of default tab array, or %NULL if "standard" 
+ *    tabs are used; must be freed with pango_tab_array_free().
  **/
 PangoTabArray*
 gtk_text_view_get_tabs (GtkTextView *text_view)
@@ -2444,6 +2636,12 @@ gtk_text_view_get_tabs (GtkTextView *text_view)
   return text_view->tabs ? pango_tab_array_copy (text_view->tabs) : NULL;
 }
 
+static void
+gtk_text_view_toggle_cursor_visible (GtkTextView *text_view)
+{
+  gtk_text_view_set_cursor_visible (text_view, !text_view->cursor_visible);
+}
+
 /**
  * gtk_text_view_set_cursor_visible:
  * @text_view: a #GtkTextView
@@ -2502,7 +2700,7 @@ gtk_text_view_get_cursor_visible (GtkTextView *text_view)
  * Moves the cursor to the currently visible region of the
  * buffer, it it isn't there already.
  *
- * Return value: TRUE if the cursor had to be moved.
+ * Return value: %TRUE if the cursor had to be moved.
  **/
 gboolean
 gtk_text_view_place_cursor_onscreen (GtkTextView *text_view)
@@ -2512,8 +2710,7 @@ gtk_text_view_place_cursor_onscreen (GtkTextView *text_view)
   g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
 
   gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
-                                    gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                              "insert"));
+                                    gtk_text_buffer_get_insert (get_buffer (text_view)));
 
   if (clamp_iter_onscreen (text_view, &insert))
     {
@@ -2545,8 +2742,10 @@ static void
 gtk_text_view_destroy (GtkObject *object)
 {
   GtkTextView *text_view;
-  
+  GtkTextViewPrivate *priv;
+
   text_view = GTK_TEXT_VIEW (object);
+  priv = GTK_TEXT_VIEW_GET_PRIVATE (text_view);
 
   gtk_text_view_remove_validate_idles (text_view);
   gtk_text_view_set_buffer (text_view, NULL);
@@ -2558,6 +2757,12 @@ gtk_text_view_destroy (GtkObject *object)
       text_view->scroll_timeout = 0;
     }
 
+  if (priv->im_spot_idle)
+    {
+      g_source_remove (priv->im_spot_idle);
+      priv->im_spot_idle = 0;
+    }
+
   (* GTK_OBJECT_CLASS (gtk_text_view_parent_class)->destroy) (object);
 }
 
@@ -3375,7 +3580,7 @@ changed_handler (GtkTextLayout     *layout,
             text_window_invalidate_rect (text_view->bottom_window,
                                          &redraw_rect);
 
-          gtk_text_view_update_im_spot_location (text_view);
+          queue_update_im_spot_location (text_view);
         }
     }
   
@@ -3723,7 +3928,7 @@ gtk_text_view_grab_notify (GtkWidget *widget,
 {
   if (!was_grabbed)
     {
-      gtk_text_view_end_selection_drag (GTK_TEXT_VIEW (widget), NULL);
+      gtk_text_view_end_selection_drag (GTK_TEXT_VIEW (widget));
       gtk_text_view_unobscure_mouse_cursor (GTK_TEXT_VIEW (widget));
     }
 }
@@ -3843,13 +4048,10 @@ gtk_text_view_event (GtkWidget *widget, GdkEvent *event)
   else if (event->type == GDK_KEY_PRESS ||
            event->type == GDK_KEY_RELEASE)
     {
-      GtkTextMark *insert;
       GtkTextIter iter;
 
-      insert = gtk_text_buffer_get_mark (get_buffer (text_view),
-                                         "insert");
-
-      gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &iter, insert);
+      gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &iter,
+                                        gtk_text_buffer_get_insert (get_buffer (text_view)));
 
       return emit_event_on_tags (widget, event, &iter);
     }
@@ -3871,6 +4073,9 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
       get_buffer (text_view) == NULL)
     return FALSE;
 
+  /* Make sure input method knows where it is */
+  flush_update_im_spot_location (text_view);
+
   insert = gtk_text_buffer_get_insert (get_buffer (text_view));
   gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &iter, insert);
   can_insert = gtk_text_iter_can_insert (&iter, text_view->editable);
@@ -3916,9 +4121,9 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
          obscure = TRUE;
        }
       else
-       gtk_text_view_move_focus (text_view,
-                                 (event->state & GDK_SHIFT_MASK) ?
-                                 GTK_DIR_TAB_BACKWARD: GTK_DIR_TAB_FORWARD);
+       g_signal_emit_by_name (text_view, "move-focus",
+                               (event->state & GDK_SHIFT_MASK) ?
+                               GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD);
 
       retval = TRUE;
     }
@@ -4041,7 +4246,7 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
     {
       GtkTextIter iter;
 
-      gtk_text_view_end_selection_drag (text_view, event);      
+      gtk_text_view_end_selection_drag (text_view);
 
       gtk_text_layout_get_iter_at_pixel (text_view->layout,
                                         &iter,
@@ -4073,7 +4278,7 @@ gtk_text_view_button_release_event (GtkWidget *widget, GdkEventButton *event)
           text_view->drag_start_y = -1;
         }
 
-      if (gtk_text_view_end_selection_drag (GTK_TEXT_VIEW (widget), event))
+      if (gtk_text_view_end_selection_drag (GTK_TEXT_VIEW (widget)))
         return TRUE;
       else if (text_view->pending_place_cursor_button == event->button)
         {
@@ -4140,6 +4345,8 @@ gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
 {
   GtkTextView *text_view = GTK_TEXT_VIEW (widget);
 
+  gtk_text_view_end_selection_drag (text_view);
+
   gtk_widget_queue_draw (widget);
 
   DV(g_print (G_STRLOC": focus_out_event\n"));
@@ -4170,10 +4377,10 @@ gtk_text_view_motion_event (GtkWidget *widget, GdkEventMotion *event)
   if (event->window == text_view->text_window->bin_window &&
       text_view->drag_start_x >= 0)
     {
-      gint x, y;
+      gint x = event->x;
+      gint y = event->y;
 
-      gdk_window_get_pointer (text_view->text_window->bin_window,
-                              &x, &y, NULL);
+      gdk_event_request_motions (event);
 
       if (gtk_drag_check_threshold (widget,
                                    text_view->drag_start_x, 
@@ -4371,6 +4578,17 @@ gtk_text_view_focus (GtkWidget        *widget,
     }
 }
 
+static void
+gtk_text_view_move_focus (GtkWidget        *widget,
+                          GtkDirectionType  direction_type)
+{
+  GtkTextView *text_view = GTK_TEXT_VIEW (widget);
+
+  if (GTK_TEXT_VIEW_GET_CLASS (text_view)->move_focus)
+    GTK_TEXT_VIEW_GET_CLASS (text_view)->move_focus (text_view,
+                                                     direction_type);
+}
+
 /*
  * Container
  */
@@ -4705,8 +4923,10 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
 
       switch (step) 
        {
-       case GTK_MOVEMENT_LOGICAL_POSITIONS:
         case GTK_MOVEMENT_VISUAL_POSITIONS:
+          leave_direction = count > 0 ? GTK_DIR_RIGHT : GTK_DIR_LEFT;
+          /* fall through */
+        case GTK_MOVEMENT_LOGICAL_POSITIONS:
         case GTK_MOVEMENT_WORDS:
          scroll_step = GTK_SCROLL_HORIZONTAL_STEPS;
          break;
@@ -4714,6 +4934,8 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
          scroll_step = GTK_SCROLL_HORIZONTAL_ENDS;
          break;          
         case GTK_MOVEMENT_DISPLAY_LINES:
+          leave_direction = count > 0 ? GTK_DIR_DOWN : GTK_DIR_UP;
+          /* fall through */
         case GTK_MOVEMENT_PARAGRAPHS:
         case GTK_MOVEMENT_PARAGRAPH_ENDS:
          scroll_step = GTK_SCROLL_STEPS;
@@ -4731,8 +4953,16 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
           scroll_step = GTK_SCROLL_PAGES;
           break;
        }
-      
-      gtk_text_view_move_viewport (text_view, scroll_step, count);
+
+      if (!gtk_text_view_move_viewport (text_view, scroll_step, count))
+        {
+          if (leave_direction != -1 &&
+              !gtk_widget_keynav_failed (GTK_WIDGET (text_view),
+                                         leave_direction))
+            {
+              g_signal_emit_by_name (text_view, "move-focus", leave_direction);
+            }
+        }
 
       return;
     }
@@ -4759,8 +4989,7 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
     }
 
   gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
-                                    gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                              "insert"));
+                                    gtk_text_buffer_get_insert (get_buffer (text_view)));
   newplace = insert;
 
   if (step == GTK_MOVEMENT_DISPLAY_LINES)
@@ -4870,8 +5099,7 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
     {
       DV(g_print (G_STRLOC": scrolling onscreen\n"));
       gtk_text_view_scroll_mark_onscreen (text_view,
-                                          gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                                    "insert"));
+                                          gtk_text_buffer_get_insert (get_buffer (text_view)));
 
       if (step == GTK_MOVEMENT_DISPLAY_LINES)
         gtk_text_view_set_virtual_cursor_pos (text_view, cursor_x_pos, -1);
@@ -4881,7 +5109,7 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
       if (!gtk_widget_keynav_failed (GTK_WIDGET (text_view),
                                      leave_direction))
         {
-          gtk_text_view_move_focus (text_view, leave_direction);
+          g_signal_emit_by_name (text_view, "move-focus", leave_direction);
         }
     }
   else
@@ -4912,7 +5140,7 @@ gtk_text_view_page_horizontally (GtkTextView     *text_view,
 }
 
 
-static void
+static gboolean
 gtk_text_view_move_viewport (GtkTextView     *text_view,
                              GtkScrollStep    step,
                              gint             count)
@@ -4956,7 +5184,7 @@ gtk_text_view_move_viewport (GtkTextView     *text_view,
       break;
     }
 
-  set_adjustment_clamped (adjustment, adjustment->value + count * increment);
+  return set_adjustment_clamped (adjustment, adjustment->value + count * increment);
 }
 
 static void
@@ -4965,8 +5193,7 @@ gtk_text_view_set_anchor (GtkTextView *text_view)
   GtkTextIter insert;
 
   gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
-                                    gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                              "insert"));
+                                    gtk_text_buffer_get_insert (get_buffer (text_view)));
 
   gtk_text_buffer_create_mark (get_buffer (text_view), "anchor", &insert, TRUE);
 }
@@ -4980,6 +5207,7 @@ gtk_text_view_scroll_pages (GtkTextView *text_view,
   gdouble oldval;
   GtkAdjustment *adj;
   gint cursor_x_pos, cursor_y_pos;
+  GtkTextMark *insert_mark;
   GtkTextIter old_insert;
   GtkTextIter new_insert;
   GtkTextIter anchor;
@@ -4989,6 +5217,8 @@ gtk_text_view_scroll_pages (GtkTextView *text_view,
   
   adj = text_view->vadjustment;
 
+  insert_mark = gtk_text_buffer_get_insert (get_buffer (text_view));
+
   /* Make sure we start from the current cursor position, even
    * if it was offscreen, but don't queue more scrolls if we're
    * already behind.
@@ -4996,15 +5226,12 @@ gtk_text_view_scroll_pages (GtkTextView *text_view,
   if (text_view->pending_scroll)
     cancel_pending_scroll (text_view);
   else
-    gtk_text_view_scroll_mark_onscreen (text_view,
-                                       gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                                 "insert"));
+    gtk_text_view_scroll_mark_onscreen (text_view, insert_mark);
 
   /* Validate the region that will be brought into view by the cursor motion
    */
   gtk_text_buffer_get_iter_at_mark (get_buffer (text_view),
-                                    &old_insert,
-                                    gtk_text_buffer_get_mark (get_buffer (text_view), "insert"));
+                                    &old_insert, insert_mark);
 
   if (count < 0)
     {
@@ -5059,9 +5286,7 @@ gtk_text_view_scroll_pages (GtkTextView *text_view,
    * only guarantees 1 pixel onscreen.
    */
   DV(g_print (G_STRLOC": scrolling onscreen\n"));
-  gtk_text_view_scroll_mark_onscreen (text_view,
-                                      gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                                "insert"));
+  gtk_text_view_scroll_mark_onscreen (text_view, insert_mark);
 
   return !gtk_text_iter_equal (&old_insert, &new_insert);
 }
@@ -5075,6 +5300,7 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view,
   gdouble oldval;
   GtkAdjustment *adj;
   gint cursor_x_pos, cursor_y_pos;
+  GtkTextMark *insert_mark;
   GtkTextIter old_insert;
   GtkTextIter new_insert;
   gint y, height;
@@ -5083,6 +5309,8 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view,
 
   adj = text_view->hadjustment;
 
+  insert_mark = gtk_text_buffer_get_insert (get_buffer (text_view));
+
   /* Make sure we start from the current cursor position, even
    * if it was offscreen, but don't queue more scrolls if we're
    * already behind.
@@ -5090,15 +5318,13 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view,
   if (text_view->pending_scroll)
     cancel_pending_scroll (text_view);
   else
-    gtk_text_view_scroll_mark_onscreen (text_view,
-                                       gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                                 "insert"));
+    gtk_text_view_scroll_mark_onscreen (text_view, insert_mark);
 
   /* Validate the line that we're moving within.
    */
   gtk_text_buffer_get_iter_at_mark (get_buffer (text_view),
-                                    &old_insert,
-                                    gtk_text_buffer_get_mark (get_buffer (text_view), "insert"));
+                                    &old_insert, insert_mark);
+
   gtk_text_layout_get_line_yrange (text_view->layout, &old_insert, &y, &height);
   gtk_text_layout_validate_yrange (text_view->layout, &old_insert, y, y + height);
   /* FIXME do we need to update the adjustment ranges here? */
@@ -5147,9 +5373,7 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view,
    * only guarantees 1 pixel onscreen.
    */
   DV(g_print (G_STRLOC": scrolling onscreen\n"));
-  gtk_text_view_scroll_mark_onscreen (text_view,
-                                      gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                                "insert"));
+  gtk_text_view_scroll_mark_onscreen (text_view, insert_mark);
 
   return !gtk_text_iter_equal (&old_insert, &new_insert);
 }
@@ -5212,10 +5436,8 @@ gtk_text_view_delete_from_cursor (GtkTextView   *text_view,
         return;
     }
 
-  gtk_text_buffer_get_iter_at_mark (get_buffer (text_view),
-                                    &insert,
-                                    gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                              "insert"));
+  gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
+                                    gtk_text_buffer_get_insert (get_buffer (text_view)));
 
   start = insert;
   end = insert;
@@ -5316,7 +5538,7 @@ gtk_text_view_delete_from_cursor (GtkTextView   *text_view,
 
       DV(g_print (G_STRLOC": scrolling onscreen\n"));
       gtk_text_view_scroll_mark_onscreen (text_view,
-                                          gtk_text_buffer_get_mark (get_buffer (text_view), "insert"));
+                                          gtk_text_buffer_get_insert (get_buffer (text_view)));
     }
   else
     {
@@ -5398,7 +5620,20 @@ gtk_text_view_paste_clipboard (GtkTextView *text_view)
 static void
 gtk_text_view_toggle_overwrite (GtkTextView *text_view)
 {
+  if (text_view->text_window)
+    text_window_invalidate_cursors (text_view->text_window);
+
   text_view->overwrite_mode = !text_view->overwrite_mode;
+
+  if (text_view->layout)
+    gtk_text_layout_set_overwrite_mode (text_view->layout,
+                                       text_view->overwrite_mode && text_view->editable);
+
+  if (text_view->text_window)
+    text_window_invalidate_cursors (text_view->text_window);
+
+  gtk_text_view_pend_cursor_blink (text_view);
+
   g_object_notify (G_OBJECT (text_view), "overwrite");
 }
 
@@ -5437,21 +5672,20 @@ gtk_text_view_set_overwrite (GtkTextView *text_view,
   overwrite = overwrite != FALSE;
 
   if (text_view->overwrite_mode != overwrite)
-    {
-      text_view->overwrite_mode = overwrite;
-
-      g_object_notify (G_OBJECT (text_view), "overwrite");
-    }
+    gtk_text_view_toggle_overwrite (text_view);
 }
 
 /**
  * gtk_text_view_set_accepts_tab:
  * @text_view: A #GtkTextView
- * @accepts_tab: %TRUE if pressing the Tab key should insert a tab character, %FALSE, if pressing the Tab key should move the keyboard focus.
+ * @accepts_tab: %TRUE if pressing the Tab key should insert a tab 
+ *    character, %FALSE, if pressing the Tab key should move the 
+ *    keyboard focus.
  * 
- * Sets the behavior of the text widget when the Tab key is pressed. If @accepts_tab
- * is %TRUE a tab character is inserted. If @accepts_tab is %FALSE the keyboard focus
- * is moved to the next widget in the focus chain.
+ * Sets the behavior of the text widget when the Tab key is pressed. 
+ * If @accepts_tab is %TRUE, a tab character is inserted. If @accepts_tab 
+ * is %FALSE the keyboard focus is moved to the next widget in the focus 
+ * chain.
  * 
  * Since: 2.4
  **/
@@ -5478,7 +5712,8 @@ gtk_text_view_set_accepts_tab (GtkTextView *text_view,
  * Returns whether pressing the Tab key inserts a tab characters.
  * gtk_text_view_set_accepts_tab().
  * 
- * Return value: %TRUE if pressing the Tab key inserts a tab character, %FALSE if pressing the Tab key moves the keyboard focus.
+ * Return value: %TRUE if pressing the Tab key inserts a tab character, 
+ *   %FALSE if pressing the Tab key moves the keyboard focus.
  * 
  * Since: 2.4
  **/
@@ -5491,16 +5726,45 @@ gtk_text_view_get_accepts_tab (GtkTextView *text_view)
 }
 
 static void
-gtk_text_view_move_focus (GtkTextView     *text_view,
-                          GtkDirectionType direction_type)
+gtk_text_view_compat_move_focus (GtkTextView     *text_view,
+                                 GtkDirectionType direction_type)
 {
-  GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (text_view));
+  GSignalInvocationHint *hint = g_signal_get_invocation_hint (text_view);
 
-  if (!GTK_WIDGET_TOPLEVEL (toplevel))
-    return;
+  /*  as of GTK+ 2.12, the "move-focus" signal has been moved to GtkWidget,
+   *  the evil code below makes sure that both emitting the signal and
+   *  calling the virtual function directly continue to work as expetcted
+   */
+
+  if (hint->signal_id == g_signal_lookup ("move-focus", GTK_TYPE_WIDGET))
+    {
+      /*  if this is a signal emission, chain up  */
+
+      GValue instance_and_params[2] = { { 0, }, { 0, } };
+      GValue return_value = { 0, };
+
+      g_value_init (&instance_and_params[0], GTK_TYPE_WIDGET);
+      g_value_set_object (&instance_and_params[0], text_view);
+
+      g_value_init (&instance_and_params[1], GTK_TYPE_DIRECTION_TYPE);
+      g_value_set_enum (&instance_and_params[1], direction_type);
+
+      g_value_init (&return_value, G_TYPE_BOOLEAN);
+
+      g_signal_chain_from_overridden (instance_and_params, &return_value);
+
+      g_value_unset (&instance_and_params[0]);
+      g_value_unset (&instance_and_params[1]);
+      g_value_unset (&return_value);
+    }
+  else
+    {
+      /*  otherwise emit the signal, since somebody called the virtual
+       *  function directly
+       */
 
-  /* Propagate to toplevel */
-  g_signal_emit_by_name (toplevel, "move_focus", direction_type);
+      g_signal_emit_by_name (text_view, "move-focus", direction_type);
+    }
 }
 
 /*
@@ -5512,14 +5776,11 @@ gtk_text_view_unselect (GtkTextView *text_view)
 {
   GtkTextIter insert;
 
-  gtk_text_buffer_get_iter_at_mark (get_buffer (text_view),
-                                    &insert,
-                                    gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                              "insert"));
+  gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
+                                    gtk_text_buffer_get_insert (get_buffer (text_view)));
 
   gtk_text_buffer_move_mark (get_buffer (text_view),
-                             gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                       "selection_bound"),
+                             gtk_text_buffer_get_selection_bound (get_buffer (text_view)),
                              &insert);
 }
 
@@ -5580,8 +5841,7 @@ selection_scan_timeout (gpointer data)
 
   DV(g_print (G_STRLOC": calling move_mark_to_pointer_and_scroll\n"));
   gtk_text_view_scroll_mark_onscreen (text_view, 
-                                     gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                               "insert"));
+                                     gtk_text_buffer_get_insert (get_buffer (text_view)));
 
   return TRUE; /* remain installed. */
 }
@@ -5748,6 +6008,8 @@ selection_motion_event_handler (GtkTextView    *text_view,
                                GdkEventMotion *event, 
                                SelectionData  *data)
 {
+  gdk_event_request_motions (event);
+
   if (data->granularity == SELECT_CHARACTERS) 
     {
       move_mark_to_pointer_and_scroll (text_view, "insert");
@@ -5876,8 +6138,7 @@ gtk_text_view_start_selection_drag (GtkTextView       *text_view,
 
 /* returns whether we were really dragging */
 static gboolean
-gtk_text_view_end_selection_drag (GtkTextView    *text_view, 
-                                 GdkEventButton *event)
+gtk_text_view_end_selection_drag (GtkTextView    *text_view) 
 {
   if (text_view->selection_drag_handler == 0)
     return FALSE;
@@ -5984,6 +6245,9 @@ gtk_text_view_ensure_layout (GtkTextView *text_view)
       else
         gtk_text_layout_set_cursor_visible (text_view->layout, FALSE);
 
+      gtk_text_layout_set_overwrite_mode (text_view->layout,
+                                         text_view->overwrite_mode && text_view->editable);
+
       ltr_context = gtk_widget_create_pango_context (GTK_WIDGET (text_view));
       pango_context_set_base_dir (ltr_context, PANGO_DIRECTION_LTR);
       rtl_context = gtk_widget_create_pango_context (GTK_WIDGET (text_view));
@@ -6096,7 +6360,7 @@ gtk_text_view_destroy_layout (GtkTextView *text_view)
         }
       
       gtk_text_view_stop_cursor_blink (text_view);
-      gtk_text_view_end_selection_drag (text_view, NULL);
+      gtk_text_view_end_selection_drag (text_view);
 
       g_object_unref (text_view->layout);
       text_view->layout = NULL;
@@ -6897,8 +7161,7 @@ gtk_text_view_commit_text (GtkTextView   *text_view,
          
          gtk_text_buffer_get_iter_at_mark (get_buffer (text_view),
                                            &insert,
-                                           gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                                     "insert"));
+                                           gtk_text_buffer_get_insert (get_buffer (text_view)));
          if (!gtk_text_iter_ends_line (&insert))
            gtk_text_view_delete_from_cursor (text_view, GTK_DELETE_CHARS, 1);
        }
@@ -6915,8 +7178,7 @@ gtk_text_view_commit_text (GtkTextView   *text_view,
   gtk_text_view_set_virtual_cursor_pos (text_view, -1, -1);
   DV(g_print (G_STRLOC": scrolling onscreen\n"));
   gtk_text_view_scroll_mark_onscreen (text_view,
-                                      gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                                "insert"));
+                                      gtk_text_buffer_get_insert (get_buffer (text_view)));
 }
 
 static void
@@ -6947,8 +7209,7 @@ gtk_text_view_preedit_changed_handler (GtkIMContext *context,
 
   if (GTK_WIDGET_HAS_FOCUS (text_view))
     gtk_text_view_scroll_mark_onscreen (text_view,
-                                       gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                                 "insert"));
+                                       gtk_text_buffer_get_insert (get_buffer (text_view)));
 }
 
 static gboolean
@@ -7072,8 +7333,7 @@ gtk_text_view_get_cursor_location  (GtkTextView   *text_view,
   GtkTextIter insert;
   
   gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
-                                    gtk_text_buffer_get_mark (get_buffer (text_view),
-                                                              "insert"));
+                                    gtk_text_buffer_get_insert (get_buffer (text_view)));
 
   gtk_text_layout_get_cursor_locations (text_view->layout, &insert, pos, NULL);
 }
@@ -7708,6 +7968,12 @@ text_window_invalidate_cursors (GtkTextWindow *win)
   gtk_text_buffer_get_iter_at_mark (text_view->buffer, &iter,
                                     gtk_text_buffer_get_insert (text_view->buffer));
 
+  if (_gtk_text_layout_get_block_cursor (text_view->layout, &strong))
+    {
+      text_window_invalidate_rect (win, &strong);
+      return;
+    }
+
   gtk_text_layout_get_cursor_locations (text_view->layout, &iter,
                                         &strong, &weak);
 
@@ -8182,7 +8448,7 @@ set_window_width (GtkTextView      *text_view,
                                    width, 0);
           /* if the widget is already realized we need to realize the child manually */
           if (GTK_WIDGET_REALIZED (text_view))
-            text_window_realize (*winp, GTK_WIDGET (text_view)->window);
+            text_window_realize (*winp, GTK_WIDGET (text_view));
         }
       else
         {
@@ -8222,7 +8488,7 @@ set_window_height (GtkTextView      *text_view,
 
           /* if the widget is already realized we need to realize the child manually */
           if (GTK_WIDGET_REALIZED (text_view))
-            text_window_realize (*winp, GTK_WIDGET (text_view)->window);
+            text_window_realize (*winp, GTK_WIDGET (text_view));
         }
       else
         {
@@ -8448,7 +8714,6 @@ add_child (GtkTextView      *text_view,
  * @anchor: a #GtkTextChildAnchor in the #GtkTextBuffer for @text_view
  * 
  * Adds a child widget in the text buffer, at the given @anchor.
- * 
  **/
 void
 gtk_text_view_add_child_at_anchor (GtkTextView          *text_view,
@@ -8482,8 +8747,8 @@ gtk_text_view_add_child_at_anchor (GtkTextView          *text_view,
  * @ypos: Y position of child in window coordinates
  *
  * Adds a child at fixed coordinates in one of the text widget's
- * windows.  The window must have nonzero size (see
- * gtk_text_view_set_border_window_size()).  Note that the child
+ * windows. The window must have nonzero size (see
+ * gtk_text_view_set_border_window_size()). Note that the child
  * coordinates are given relative to the #GdkWindow in question, and
  * that these coordinates have no sane relationship to scrolling. When
  * placing a child in #GTK_TEXT_WINDOW_WIDGET, scrolling is
@@ -8497,14 +8762,13 @@ gtk_text_view_add_child_at_anchor (GtkTextView          *text_view,
  * would be to update all child positions when the scroll adjustments
  * change or the text buffer changes. See bug 64518 on
  * bugzilla.gnome.org for status of fixing this issue.
- *
  **/
 void
-gtk_text_view_add_child_in_window (GtkTextView          *text_view,
-                                   GtkWidget            *child,
-                                   GtkTextWindowType     which_window,
-                                   gint                  xpos,
-                                   gint                  ypos)
+gtk_text_view_add_child_in_window (GtkTextView       *text_view,
+                                   GtkWidget         *child,
+                                   GtkTextWindowType  which_window,
+                                   gint               xpos,
+                                   gint               ypos)
 {
   GtkTextViewChild *vc;
 
@@ -8529,13 +8793,12 @@ gtk_text_view_add_child_in_window (GtkTextView          *text_view,
  * @ypos: new Y position in window coordinates
  *
  * Updates the position of a child, as for gtk_text_view_add_child_in_window().
- * 
  **/
 void
-gtk_text_view_move_child          (GtkTextView          *text_view,
-                                   GtkWidget            *child,
-                                   gint                  xpos,
-                                   gint                  ypos)
+gtk_text_view_move_child (GtkTextView *text_view,
+                          GtkWidget   *child,
+                          gint         xpos,
+                          gint         ypos)
 {
   GtkTextViewChild *vc;
 
@@ -8567,10 +8830,10 @@ gtk_text_view_move_child          (GtkTextView          *text_view,
  * @text_view: a #GtkTextView
  * @iter: a #GtkTextIter
  * 
- * Moves the given @iter forward by one display (wrapped) line.  A
- * display line is different from a paragraph. Paragraphs are
+ * Moves the given @iter forward by one display (wrapped) line.
+ * display line is different from a paragraph. Paragraphs are
  * separated by newlines or other paragraph separator characters.
- * Display lines are created by line-wrapping a paragraph.  If
+ * Display lines are created by line-wrapping a paragraph. If
  * wrapping is turned off, display lines and paragraphs will be the
  * same. Display lines are divided differently for each view, since
  * they depend on the view's width; paragraphs are the same in all
@@ -8595,10 +8858,10 @@ gtk_text_view_forward_display_line (GtkTextView *text_view,
  * @text_view: a #GtkTextView
  * @iter: a #GtkTextIter
  * 
- * Moves the given @iter backward by one display (wrapped) line.  A
- * display line is different from a paragraph. Paragraphs are
+ * Moves the given @iter backward by one display (wrapped) line.
+ * display line is different from a paragraph. Paragraphs are
  * separated by newlines or other paragraph separator characters.
- * Display lines are created by line-wrapping a paragraph.  If
+ * Display lines are created by line-wrapping a paragraph. If
  * wrapping is turned off, display lines and paragraphs will be the
  * same. Display lines are divided differently for each view, since
  * they depend on the view's width; paragraphs are the same in all
@@ -8623,10 +8886,10 @@ gtk_text_view_backward_display_line (GtkTextView *text_view,
  * @text_view: a #GtkTextView
  * @iter: a #GtkTextIter
  * 
- * Moves the given @iter forward to the next display line end.  A
- * display line is different from a paragraph. Paragraphs are
+ * Moves the given @iter forward to the next display line end.
+ * display line is different from a paragraph. Paragraphs are
  * separated by newlines or other paragraph separator characters.
- * Display lines are created by line-wrapping a paragraph.  If
+ * Display lines are created by line-wrapping a paragraph. If
  * wrapping is turned off, display lines and paragraphs will be the
  * same. Display lines are divided differently for each view, since
  * they depend on the view's width; paragraphs are the same in all
@@ -8651,10 +8914,10 @@ gtk_text_view_forward_display_line_end (GtkTextView *text_view,
  * @text_view: a #GtkTextView
  * @iter: a #GtkTextIter
  * 
- * Moves the given @iter backward to the next display line start.  A
- * display line is different from a paragraph. Paragraphs are
+ * Moves the given @iter backward to the next display line start.
+ * display line is different from a paragraph. Paragraphs are
  * separated by newlines or other paragraph separator characters.
- * Display lines are created by line-wrapping a paragraph.  If
+ * Display lines are created by line-wrapping a paragraph. If
  * wrapping is turned off, display lines and paragraphs will be the
  * same. Display lines are divided differently for each view, since
  * they depend on the view's width; paragraphs are the same in all
@@ -8701,7 +8964,8 @@ gtk_text_view_starts_display_line (GtkTextView       *text_view,
  * gtk_text_view_move_visually:
  * @text_view: a #GtkTextView
  * @iter: a #GtkTextIter
- * @count:   number of characters to move (negative moves left, positive moves right)
+ * @count: number of characters to move (negative moves left, 
+ *    positive moves right)
  *
  * Move the iterator a given number of characters visually, treating
  * it as the strong cursor position. If @count is positive, then the
@@ -8710,7 +8974,7 @@ gtk_text_view_starts_display_line (GtkTextView       *text_view,
  * cursor position will be @count positions to the left of the old
  * cursor position.
  *
- * In the presence of bidirection text, the correspondence
+ * In the presence of bi-directional text, the correspondence
  * between logical and visual order will depend on the direction
  * of the current run, and there may be jumps when the cursor
  * is moved off of the end of a run.