summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2009-12-21 11:29:12 -0500
committerMatthias Clasen <mclasen@redhat.com>2010-01-07 15:54:57 -0500
commit1eb83b8a693b992dd17ff1365fd960663ad2ace5 (patch)
tree5df38c44351966247c1f9d30176f9390e8b4aef0
parentf07fced38c8879f76238a6badceae8151e139ad0 (diff)
downloadgdk-pixbuf-1eb83b8a693b992dd17ff1365fd960663ad2ace5.tar.gz
Improve selection/arrow key behaviour in GtkTextView
This patch makes the text view behave more similar to entries. Patch by Michael Natterer, see bug 50942 (cherry picked from commit c0d8b71bc5d4b404727b03053d27eaf35e7309b7)
-rw-r--r--gtk/gtktextview.c52
1 files changed, 44 insertions, 8 deletions
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 0c41e24c2..3c0958a27 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -337,6 +337,7 @@ static void gtk_text_view_paste_done_handler (GtkTextBuffer *buffer,
static void gtk_text_view_get_cursor_location (GtkTextView *text_view,
GdkRectangle *pos);
static void gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view,
+ GtkTextIter *cursor,
gint *x,
gint *y);
static void gtk_text_view_set_virtual_cursor_pos (GtkTextView *text_view,
@@ -5031,6 +5032,7 @@ gtk_text_view_move_cursor_internal (GtkTextView *text_view,
{
GtkTextIter insert;
GtkTextIter newplace;
+ gboolean cancel_selection = FALSE;
gint cursor_x_pos = 0;
GtkDirectionType leave_direction = -1;
@@ -5107,20 +5109,46 @@ 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_insert (get_buffer (text_view)));
+
+ if (! extend_selection)
+ {
+ GtkTextIter sel_bound;
+
+ gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &sel_bound,
+ gtk_text_buffer_get_selection_bound (get_buffer (text_view)));
+
+ /* if we move forward, assume the cursor is at the end of the selection;
+ * if we move backward, assume the cursor is at the start
+ */
+ if (count > 0)
+ gtk_text_iter_order (&sel_bound, &insert);
+ else
+ gtk_text_iter_order (&insert, &sel_bound);
+
+ /* if we actually have a selection, just move *to* the beginning/end
+ * of the selection and not *from* there on LOGICAL_POSITIONS
+ * and VISUAL_POSITIONS movement
+ */
+ if (! gtk_text_iter_equal (&sel_bound, &insert))
+ cancel_selection = TRUE;
+ }
+
newplace = insert;
if (step == GTK_MOVEMENT_DISPLAY_LINES)
- gtk_text_view_get_virtual_cursor_pos (text_view, &cursor_x_pos, NULL);
+ gtk_text_view_get_virtual_cursor_pos (text_view, &insert, &cursor_x_pos, NULL);
switch (step)
{
case GTK_MOVEMENT_LOGICAL_POSITIONS:
- gtk_text_iter_forward_visible_cursor_positions (&newplace, count);
+ if (! cancel_selection)
+ gtk_text_iter_forward_visible_cursor_positions (&newplace, count);
break;
case GTK_MOVEMENT_VISUAL_POSITIONS:
- gtk_text_layout_move_iter_visually (text_view->layout,
- &newplace, count);
+ if (! cancel_selection)
+ gtk_text_layout_move_iter_visually (text_view->layout,
+ &newplace, count);
break;
case GTK_MOVEMENT_WORDS:
@@ -5229,7 +5257,7 @@ gtk_text_view_move_cursor_internal (GtkTextView *text_view,
g_signal_emit_by_name (text_view, "move-focus", leave_direction);
}
}
- else
+ else if (! cancel_selection)
{
gtk_widget_error_bell (GTK_WIDGET (text_view));
}
@@ -5382,7 +5410,7 @@ gtk_text_view_scroll_pages (GtkTextView *text_view,
}
else
{
- gtk_text_view_get_virtual_cursor_pos (text_view, &cursor_x_pos, &cursor_y_pos);
+ gtk_text_view_get_virtual_cursor_pos (text_view, NULL, &cursor_x_pos, &cursor_y_pos);
oldval = adj->value;
newval = adj->value;
@@ -5463,7 +5491,7 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view,
}
else
{
- gtk_text_view_get_virtual_cursor_pos (text_view, &cursor_x_pos, &cursor_y_pos);
+ gtk_text_view_get_virtual_cursor_pos (text_view, NULL, &cursor_x_pos, &cursor_y_pos);
oldval = adj->value;
newval = adj->value;
@@ -7480,14 +7508,22 @@ gtk_text_view_get_cursor_location (GtkTextView *text_view,
static void
gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view,
+ GtkTextIter *cursor,
gint *x,
gint *y)
{
+ GtkTextIter insert;
GdkRectangle pos;
+ if (cursor)
+ insert = *cursor;
+ else
+ gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
+ gtk_text_buffer_get_insert (get_buffer (text_view)));
+
if ((x && text_view->virtual_cursor_x == -1) ||
(y && text_view->virtual_cursor_y == -1))
- gtk_text_view_get_cursor_location (text_view, &pos);
+ gtk_text_layout_get_cursor_locations (text_view->layout, &insert, &pos, NULL);
if (x)
{