diff options
author | Matthias Clasen <mclasen@redhat.com> | 2006-03-28 17:28:19 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2006-03-28 17:28:19 +0000 |
commit | 38994e574cb1f6c866d6f31413ee4dedc1bb0ca1 (patch) | |
tree | ac48d30bb0db5d214e0a01d1d88e477e83f08ae8 /gtk/gtktextview.c | |
parent | 97c07a14f352ac2e3e80307ddbf11fa25ef04daa (diff) | |
download | gtk+-38994e574cb1f6c866d6f31413ee4dedc1bb0ca1.tar.gz |
Fix drag-selection after double-click. (#323862, Benjamin Berg)
2006-03-28 Matthias Clasen <mclasen@redhat.com>
* gtk/gtktextview.c (gtk_text_view_start_selection_drag):
(selection_motion_event_handler): Fix drag-selection after
double-click. (#323862, Benjamin Berg)
* gtk/gtktextview.c (get_iter_at_pointer): Factor this out
into a function and use it in move_mark_to_pointer_and_scroll,
drag_scan_timeout and selection_motion_event_handler.
(Paolo Borelli)
Diffstat (limited to 'gtk/gtktextview.c')
-rw-r--r-- | gtk/gtktextview.c | 141 |
1 files changed, 71 insertions, 70 deletions
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 2d1ec400cb..35a3ff7b87 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -5435,37 +5435,41 @@ gtk_text_view_unselect (GtkTextView *text_view) } static void -move_mark_to_pointer_and_scroll (GtkTextView *text_view, - const gchar *mark_name) +get_iter_at_pointer (GtkTextView *text_view, + GtkTextIter *iter) { gint x, y; GdkModifierType state; - GtkTextIter newplace; - /* DV(g_print (G_STRLOC": begin\n")); */ - gdk_window_get_pointer (text_view->text_window->bin_window, &x, &y, &state); - - /* DV(g_print (G_STRLOC": get iter at pixel\n"); */ + gtk_text_layout_get_iter_at_pixel (text_view->layout, - &newplace, + iter, x + text_view->xoffset, y + text_view->yoffset); +} - { - GtkTextMark *mark = - gtk_text_buffer_get_mark (get_buffer (text_view), mark_name); - - /* This may invalidate the layout */ - DV(g_print (G_STRLOC": move mark\n")); - gtk_text_buffer_move_mark (get_buffer (text_view), - mark, - &newplace); +static void +move_mark_to_pointer_and_scroll (GtkTextView *text_view, + const gchar *mark_name) +{ + GtkTextIter newplace; + GtkTextMark *mark; - DV(g_print (G_STRLOC": scrolling onscreen\n")); - gtk_text_view_scroll_mark_onscreen (text_view, mark); - } + get_iter_at_pointer (text_view, &newplace); + + mark = gtk_text_buffer_get_mark (get_buffer (text_view), mark_name); + + /* This may invalidate the layout */ + DV(g_print (G_STRLOC": move mark\n")); + + gtk_text_buffer_move_mark (get_buffer (text_view), + mark, + &newplace); + + DV(g_print (G_STRLOC": scrolling onscreen\n")); + gtk_text_view_scroll_mark_onscreen (text_view, mark); DV (g_print ("first validate idle leaving %s is %d\n", G_STRLOC, text_view->first_validate_idle)); @@ -5496,22 +5500,14 @@ static gint drag_scan_timeout (gpointer data) { GtkTextView *text_view; - gint x, y; - GdkModifierType state; GtkTextIter newplace; GDK_THREADS_ENTER (); text_view = GTK_TEXT_VIEW (data); - gdk_window_get_pointer (text_view->text_window->bin_window, - &x, &y, &state); - - gtk_text_layout_get_iter_at_pixel (text_view->layout, - &newplace, - x + text_view->xoffset, - y + text_view->yoffset); - + get_iter_at_pointer (text_view, &newplace); + gtk_text_buffer_move_mark (get_buffer (text_view), text_view->dnd_mark, &newplace); @@ -5643,42 +5639,25 @@ selection_motion_event_handler (GtkTextView *text_view, { gint x, y; GdkModifierType state; - GtkTextIter start, end; - GtkTextIter ins, bound; + GtkTextIter cursor, start, end; + GtkTextIter orig_start, orig_end; GtkTextBuffer *buffer; - gboolean extend; buffer = get_buffer (text_view); - gtk_text_buffer_get_iter_at_mark (buffer, &ins, data->orig_start); - gtk_text_buffer_get_iter_at_mark (buffer, &bound, data->orig_end); + gtk_text_buffer_get_iter_at_mark (buffer, &orig_start, data->orig_start); + gtk_text_buffer_get_iter_at_mark (buffer, &orig_end, data->orig_end); - gdk_window_get_pointer (text_view->text_window->bin_window, - &x, &y, &state); - - gtk_text_layout_get_iter_at_pixel (text_view->layout, - &start, - event->x + text_view->xoffset, - event->y + text_view->yoffset); + get_iter_at_pointer (text_view, &cursor); - extend = !gtk_text_iter_in_range (&start, &ins, &bound); - + start = cursor; extend_selection (text_view, data->granularity, &start, &end); - if (extend) - { - /* Extend selection */ - gtk_text_iter_order (&ins, &start); - gtk_text_iter_order (&end, &bound); - gtk_text_buffer_select_range (buffer, &ins, &bound); - } + /* either the selection extends to the front, or end (or not) */ + if (gtk_text_iter_compare (&cursor, &orig_start) < 0) + gtk_text_buffer_select_range (buffer, &start, &orig_end); else - { - /* Shrink selection */ - gtk_text_iter_order (&ins, &start); - gtk_text_iter_order (&end, &bound); - gtk_text_buffer_select_range (buffer, &ins, &end); - } + gtk_text_buffer_select_range (buffer, &end, &orig_start); gtk_text_view_scroll_mark_onscreen (text_view, gtk_text_buffer_get_insert (buffer)); @@ -5703,7 +5682,8 @@ gtk_text_view_start_selection_drag (GtkTextView *text_view, const GtkTextIter *iter, GdkEventButton *button) { - GtkTextIter start, end; + GtkTextIter cursor, ins, bound; + GtkTextIter orig_start, orig_end; GtkTextBuffer *buffer; SelectionData *data; @@ -5722,31 +5702,52 @@ gtk_text_view_start_selection_drag (GtkTextView *text_view, buffer = get_buffer (text_view); - start = *iter; + cursor = *iter; + ins = cursor; - extend_selection (text_view, data->granularity, &start, &end); + extend_selection (text_view, data->granularity, &ins, &bound); + orig_start = ins; + orig_end = bound; if (button->state & GDK_SHIFT_MASK) { /* Extend selection */ + GtkTextIter old_ins, old_bound; GtkTextIter old_start, old_end; - gtk_text_buffer_get_selection_bounds (buffer, &old_start, &old_end); - - gtk_text_iter_order (&start, &old_start); - gtk_text_iter_order (&old_end, &end); + gtk_text_buffer_get_iter_at_mark (buffer, &old_ins, gtk_text_buffer_get_insert (buffer)); + gtk_text_buffer_get_iter_at_mark (buffer, &old_bound, gtk_text_buffer_get_selection_bound (buffer)); + old_start = old_ins; + old_end = old_bound; + gtk_text_iter_order (&old_start, &old_end); - /* Now start is the first of the starts, and end is the - * last of the ends - */ + /* move the front cursor, if the mouse is in front of the selection. Should the + * cursor however be inside the selection (this happens on tripple click) then we + * move the side which was last moved (current insert mark) */ + if (gtk_text_iter_compare (&cursor, &old_start) <= 0 || + (gtk_text_iter_compare (&cursor, &old_end) < 0 && + gtk_text_iter_compare (&old_ins, &old_bound) <= 0)) + { + bound = old_end; + orig_start = old_end; + orig_end = old_end; + } + else + { + ins = bound; + bound = old_start; + orig_end = bound; + orig_start = bound; + } } - gtk_text_buffer_select_range (buffer, &end, &start); + gtk_text_buffer_select_range (buffer, &ins, &bound); + gtk_text_iter_order (&orig_start, &orig_end); data->orig_start = gtk_text_buffer_create_mark (buffer, NULL, - &start, TRUE); + &orig_start, TRUE); data->orig_end = gtk_text_buffer_create_mark (buffer, NULL, - &end, TRUE); + &orig_end, TRUE); gtk_text_view_check_cursor_blink (text_view); |