Commit 38994e57 authored by Matthias Clasen's avatar Matthias Clasen Committed by Matthias Clasen
Browse files

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)
parent 97c07a14
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)
2006-03-28 Matthias Clasen <mclasen@redhat.com> 2006-03-28 Matthias Clasen <mclasen@redhat.com>
* gtk/gtktextview.c (gtk_text_view_do_popup) * gtk/gtktextview.c (gtk_text_view_do_popup)
......
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)
2006-03-28 Matthias Clasen <mclasen@redhat.com> 2006-03-28 Matthias Clasen <mclasen@redhat.com>
* gtk/gtktextview.c (gtk_text_view_do_popup) * gtk/gtktextview.c (gtk_text_view_do_popup)
......
...@@ -5435,37 +5435,41 @@ gtk_text_view_unselect (GtkTextView *text_view) ...@@ -5435,37 +5435,41 @@ gtk_text_view_unselect (GtkTextView *text_view)
} }
static void static void
move_mark_to_pointer_and_scroll (GtkTextView *text_view, get_iter_at_pointer (GtkTextView *text_view,
const gchar *mark_name) GtkTextIter *iter)
{ {
gint x, y; gint x, y;
GdkModifierType state; GdkModifierType state;
GtkTextIter newplace;
/* DV(g_print (G_STRLOC": begin\n")); */
gdk_window_get_pointer (text_view->text_window->bin_window, gdk_window_get_pointer (text_view->text_window->bin_window,
&x, &y, &state); &x, &y, &state);
/* DV(g_print (G_STRLOC": get iter at pixel\n"); */
gtk_text_layout_get_iter_at_pixel (text_view->layout, gtk_text_layout_get_iter_at_pixel (text_view->layout,
&newplace, iter,
x + text_view->xoffset, x + text_view->xoffset,
y + text_view->yoffset); y + text_view->yoffset);
}
{ static void
GtkTextMark *mark = move_mark_to_pointer_and_scroll (GtkTextView *text_view,
gtk_text_buffer_get_mark (get_buffer (text_view), mark_name); const gchar *mark_name)
{
GtkTextIter newplace;
GtkTextMark *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 */ /* This may invalidate the layout */
DV(g_print (G_STRLOC": move mark\n")); DV(g_print (G_STRLOC": move mark\n"));
gtk_text_buffer_move_mark (get_buffer (text_view), gtk_text_buffer_move_mark (get_buffer (text_view),
mark, mark,
&newplace); &newplace);
DV(g_print (G_STRLOC": scrolling onscreen\n")); DV(g_print (G_STRLOC": scrolling onscreen\n"));
gtk_text_view_scroll_mark_onscreen (text_view, mark); gtk_text_view_scroll_mark_onscreen (text_view, mark);
}
DV (g_print ("first validate idle leaving %s is %d\n", DV (g_print ("first validate idle leaving %s is %d\n",
G_STRLOC, text_view->first_validate_idle)); G_STRLOC, text_view->first_validate_idle));
...@@ -5496,21 +5500,13 @@ static gint ...@@ -5496,21 +5500,13 @@ static gint
drag_scan_timeout (gpointer data) drag_scan_timeout (gpointer data)
{ {
GtkTextView *text_view; GtkTextView *text_view;
gint x, y;
GdkModifierType state;
GtkTextIter newplace; GtkTextIter newplace;
GDK_THREADS_ENTER (); GDK_THREADS_ENTER ();
text_view = GTK_TEXT_VIEW (data); text_view = GTK_TEXT_VIEW (data);
gdk_window_get_pointer (text_view->text_window->bin_window, get_iter_at_pointer (text_view, &newplace);
&x, &y, &state);
gtk_text_layout_get_iter_at_pixel (text_view->layout,
&newplace,
x + text_view->xoffset,
y + text_view->yoffset);
gtk_text_buffer_move_mark (get_buffer (text_view), gtk_text_buffer_move_mark (get_buffer (text_view),
text_view->dnd_mark, text_view->dnd_mark,
...@@ -5643,42 +5639,25 @@ selection_motion_event_handler (GtkTextView *text_view, ...@@ -5643,42 +5639,25 @@ selection_motion_event_handler (GtkTextView *text_view,
{ {
gint x, y; gint x, y;
GdkModifierType state; GdkModifierType state;
GtkTextIter start, end; GtkTextIter cursor, start, end;
GtkTextIter ins, bound; GtkTextIter orig_start, orig_end;
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
gboolean extend;
buffer = get_buffer (text_view); 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, &orig_start, data->orig_start);
gtk_text_buffer_get_iter_at_mark (buffer, &bound, data->orig_end); 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);
extend = !gtk_text_iter_in_range (&start, &ins, &bound); get_iter_at_pointer (text_view, &cursor);
start = cursor;
extend_selection (text_view, data->granularity, &start, &end); extend_selection (text_view, data->granularity, &start, &end);
if (extend) /* either the selection extends to the front, or end (or not) */
{ if (gtk_text_iter_compare (&cursor, &orig_start) < 0)
/* Extend selection */ gtk_text_buffer_select_range (buffer, &start, &orig_end);
gtk_text_iter_order (&ins, &start);
gtk_text_iter_order (&end, &bound);
gtk_text_buffer_select_range (buffer, &ins, &bound);
}
else else
{ gtk_text_buffer_select_range (buffer, &end, &orig_start);
/* Shrink selection */
gtk_text_iter_order (&ins, &start);
gtk_text_iter_order (&end, &bound);
gtk_text_buffer_select_range (buffer, &ins, &end);
}
gtk_text_view_scroll_mark_onscreen (text_view, gtk_text_view_scroll_mark_onscreen (text_view,
gtk_text_buffer_get_insert (buffer)); gtk_text_buffer_get_insert (buffer));
...@@ -5703,7 +5682,8 @@ gtk_text_view_start_selection_drag (GtkTextView *text_view, ...@@ -5703,7 +5682,8 @@ gtk_text_view_start_selection_drag (GtkTextView *text_view,
const GtkTextIter *iter, const GtkTextIter *iter,
GdkEventButton *button) GdkEventButton *button)
{ {
GtkTextIter start, end; GtkTextIter cursor, ins, bound;
GtkTextIter orig_start, orig_end;
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
SelectionData *data; SelectionData *data;
...@@ -5722,31 +5702,52 @@ gtk_text_view_start_selection_drag (GtkTextView *text_view, ...@@ -5722,31 +5702,52 @@ gtk_text_view_start_selection_drag (GtkTextView *text_view,
buffer = get_buffer (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) if (button->state & GDK_SHIFT_MASK)
{ {
/* Extend selection */ /* Extend selection */
GtkTextIter old_ins, old_bound;
GtkTextIter old_start, old_end; GtkTextIter old_start, old_end;
gtk_text_buffer_get_selection_bounds (buffer, &old_start, &old_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);
gtk_text_iter_order (&start, &old_start); /* move the front cursor, if the mouse is in front of the selection. Should the
gtk_text_iter_order (&old_end, &end); * cursor however be inside the selection (this happens on tripple click) then we
* move the side which was last moved (current insert mark) */
/* Now start is the first of the starts, and end is the if (gtk_text_iter_compare (&cursor, &old_start) <= 0 ||
* last of the ends (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, 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, data->orig_end = gtk_text_buffer_create_mark (buffer, NULL,
&end, TRUE); &orig_end, TRUE);
gtk_text_view_check_cursor_blink (text_view); gtk_text_view_check_cursor_blink (text_view);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment