forked from AuroraMiddleware/gtk
textview: Use GtkGestureDrag for text selection/DnD
remaining code in button press/release, motion notify, and grab notify handlers has been shuffled to be managed by this gesture.
This commit is contained in:
parent
a4da4f8dfa
commit
f47138b653
@ -134,10 +134,8 @@ struct _GtkTextViewPrivate
|
||||
guint blink_time; /* time in msec the cursor has blinked since last user event */
|
||||
guint im_spot_idle;
|
||||
gchar *im_module;
|
||||
GdkDevice *grab_device;
|
||||
GdkDevice *dnd_device;
|
||||
|
||||
gulong selection_drag_handler;
|
||||
GtkTextHandle *text_handle;
|
||||
GtkWidget *selection_bubble;
|
||||
guint selection_bubble_timeout_id;
|
||||
@ -192,16 +190,11 @@ struct _GtkTextViewPrivate
|
||||
guint first_validate_idle; /* Idle to revalidate onscreen portion, runs before resize */
|
||||
guint incremental_validate_idle; /* Idle to revalidate offscreen portions, runs after redraw */
|
||||
|
||||
gint pending_place_cursor_button;
|
||||
|
||||
GtkTextMark *dnd_mark;
|
||||
|
||||
GtkIMContext *im_context;
|
||||
GtkWidget *popup_menu;
|
||||
|
||||
gint drag_start_x;
|
||||
gint drag_start_y;
|
||||
|
||||
GSList *children;
|
||||
|
||||
GtkTextPendingScroll *pending_scroll;
|
||||
@ -209,6 +202,7 @@ struct _GtkTextViewPrivate
|
||||
GtkPixelCache *pixel_cache;
|
||||
|
||||
GtkGesture *multipress_gesture;
|
||||
GtkGesture *drag_gesture;
|
||||
|
||||
/* Default style settings */
|
||||
gint pixels_above_lines;
|
||||
@ -315,6 +309,8 @@ enum
|
||||
PROP_POPULATE_ALL
|
||||
};
|
||||
|
||||
static GQuark quark_text_selection_data = 0;
|
||||
|
||||
static void gtk_text_view_finalize (GObject *object);
|
||||
static void gtk_text_view_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -342,8 +338,6 @@ static void gtk_text_view_unrealize (GtkWidget *widget);
|
||||
static void gtk_text_view_style_updated (GtkWidget *widget);
|
||||
static void gtk_text_view_direction_changed (GtkWidget *widget,
|
||||
GtkTextDirection previous_direction);
|
||||
static void gtk_text_view_grab_notify (GtkWidget *widget,
|
||||
gboolean was_grabbed);
|
||||
static void gtk_text_view_state_flags_changed (GtkWidget *widget,
|
||||
GtkStateFlags previous_state);
|
||||
|
||||
@ -352,6 +346,14 @@ static void gtk_text_view_multipress_gesture_pressed (GtkGestureMultiPress *gest
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkTextView *text_view);
|
||||
static void gtk_text_view_drag_gesture_update (GtkGestureDrag *gesture,
|
||||
gdouble offset_x,
|
||||
gdouble offset_y,
|
||||
GtkTextView *text_view);
|
||||
static void gtk_text_view_drag_gesture_end (GtkGestureDrag *gesture,
|
||||
gdouble offset_x,
|
||||
gdouble offset_y,
|
||||
GtkTextView *text_view);
|
||||
|
||||
static gint gtk_text_view_event (GtkWidget *widget,
|
||||
GdkEvent *event);
|
||||
@ -359,14 +361,10 @@ static gint gtk_text_view_key_press_event (GtkWidget *widget,
|
||||
GdkEventKey *event);
|
||||
static gint gtk_text_view_key_release_event (GtkWidget *widget,
|
||||
GdkEventKey *event);
|
||||
static gint gtk_text_view_button_release_event (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
static gint gtk_text_view_focus_in_event (GtkWidget *widget,
|
||||
GdkEventFocus *event);
|
||||
static gint gtk_text_view_focus_out_event (GtkWidget *widget,
|
||||
GdkEventFocus *event);
|
||||
static gint gtk_text_view_motion_event (GtkWidget *widget,
|
||||
GdkEventMotion *event);
|
||||
static gint gtk_text_view_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
static gboolean gtk_text_view_focus (GtkWidget *widget,
|
||||
@ -458,7 +456,9 @@ static void gtk_text_view_start_selection_drag (GtkTextView *text
|
||||
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);
|
||||
const GdkEvent *event,
|
||||
gint x,
|
||||
gint y);
|
||||
static void gtk_text_view_check_cursor_blink (GtkTextView *text_view);
|
||||
static void gtk_text_view_pend_cursor_blink (GtkTextView *text_view);
|
||||
static void gtk_text_view_stop_cursor_blink (GtkTextView *text_view);
|
||||
@ -669,7 +669,6 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
|
||||
widget_class->unrealize = gtk_text_view_unrealize;
|
||||
widget_class->style_updated = gtk_text_view_style_updated;
|
||||
widget_class->direction_changed = gtk_text_view_direction_changed;
|
||||
widget_class->grab_notify = gtk_text_view_grab_notify;
|
||||
widget_class->state_flags_changed = gtk_text_view_state_flags_changed;
|
||||
widget_class->get_preferred_width = gtk_text_view_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_text_view_get_preferred_height;
|
||||
@ -677,10 +676,8 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
|
||||
widget_class->event = gtk_text_view_event;
|
||||
widget_class->key_press_event = gtk_text_view_key_press_event;
|
||||
widget_class->key_release_event = gtk_text_view_key_release_event;
|
||||
widget_class->button_release_event = gtk_text_view_button_release_event;
|
||||
widget_class->focus_in_event = gtk_text_view_focus_in_event;
|
||||
widget_class->focus_out_event = gtk_text_view_focus_out_event;
|
||||
widget_class->motion_notify_event = gtk_text_view_motion_event;
|
||||
widget_class->draw = gtk_text_view_draw;
|
||||
widget_class->focus = gtk_text_view_focus;
|
||||
widget_class->drag_begin = gtk_text_view_drag_begin;
|
||||
@ -1481,6 +1478,9 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_TEXT_VIEW_ACCESSIBLE);
|
||||
test_touchscreen = g_getenv ("GTK_TEST_TOUCHSCREEN") != NULL;
|
||||
|
||||
quark_text_selection_data =
|
||||
g_quark_from_static_string ("gtk-text-view-text-selection-data");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1549,11 +1549,6 @@ gtk_text_view_init (GtkTextView *text_view)
|
||||
priv->text_window = text_window_new (GTK_TEXT_WINDOW_TEXT,
|
||||
widget, 200, 200);
|
||||
|
||||
priv->drag_start_x = -1;
|
||||
priv->drag_start_y = -1;
|
||||
|
||||
priv->pending_place_cursor_button = 0;
|
||||
|
||||
/* We handle all our own redrawing */
|
||||
gtk_widget_set_redraw_on_allocate (widget, FALSE);
|
||||
|
||||
@ -1564,6 +1559,17 @@ gtk_text_view_init (GtkTextView *text_view)
|
||||
g_signal_connect (priv->multipress_gesture, "pressed",
|
||||
G_CALLBACK (gtk_text_view_multipress_gesture_pressed),
|
||||
widget);
|
||||
|
||||
priv->drag_gesture = gtk_gesture_drag_new (widget);
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->drag_gesture),
|
||||
FALSE);
|
||||
gtk_gesture_attach (priv->drag_gesture, GTK_PHASE_BUBBLE);
|
||||
g_signal_connect (priv->drag_gesture, "drag-update",
|
||||
G_CALLBACK (gtk_text_view_drag_gesture_update),
|
||||
widget);
|
||||
g_signal_connect (priv->drag_gesture, "drag-end",
|
||||
G_CALLBACK (gtk_text_view_drag_gesture_end),
|
||||
widget);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3255,6 +3261,9 @@ gtk_text_view_finalize (GObject *object)
|
||||
gtk_gesture_detach (priv->multipress_gesture);
|
||||
g_object_unref (priv->multipress_gesture);
|
||||
|
||||
gtk_gesture_detach (priv->drag_gesture);
|
||||
g_object_unref (priv->drag_gesture);
|
||||
|
||||
if (priv->tabs)
|
||||
pango_tab_array_free (priv->tabs);
|
||||
|
||||
@ -4518,30 +4527,6 @@ gtk_text_view_unobscure_mouse_cursor (GtkTextView *text_view)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_grab_notify (GtkWidget *widget,
|
||||
gboolean was_grabbed)
|
||||
{
|
||||
GtkTextViewPrivate *priv;
|
||||
|
||||
priv = GTK_TEXT_VIEW (widget)->priv;
|
||||
|
||||
if (priv->grab_device &&
|
||||
gtk_widget_device_is_shadowed (widget, priv->grab_device))
|
||||
{
|
||||
if (priv->drag_start_x >= 0)
|
||||
{
|
||||
priv->drag_start_x = -1;
|
||||
priv->drag_start_y = -1;
|
||||
}
|
||||
|
||||
gtk_text_view_end_selection_drag (GTK_TEXT_VIEW (widget));
|
||||
gtk_text_view_unobscure_mouse_cursor (GTK_TEXT_VIEW (widget));
|
||||
priv->grab_device = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Events
|
||||
*/
|
||||
@ -5123,16 +5108,14 @@ gtk_text_view_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
|
||||
gtk_widget_get_modifier_mask (GTK_WIDGET (text_view),
|
||||
GDK_MODIFIER_INTENT_EXTEND_SELECTION)))
|
||||
{
|
||||
priv->grab_device = gdk_event_get_device (event);
|
||||
priv->drag_start_x = x;
|
||||
priv->drag_start_y = y;
|
||||
priv->pending_place_cursor_button = button;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_view_start_selection_drag (text_view, &iter,
|
||||
SELECT_CHARACTERS, event);
|
||||
/* Claim the sequence on the drag gesture, but attach no selection data */
|
||||
gtk_gesture_set_state (priv->drag_gesture,
|
||||
GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_text_view_start_selection_drag (text_view, &iter,
|
||||
SELECT_CHARACTERS, event);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
@ -5164,71 +5147,6 @@ gtk_text_view_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
|
||||
gtk_event_controller_reset (GTK_EVENT_CONTROLLER (gesture));
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_text_view_button_release_event (GtkWidget *widget, GdkEventButton *event)
|
||||
{
|
||||
GtkTextView *text_view;
|
||||
GtkTextViewPrivate *priv;
|
||||
GdkDevice *device;
|
||||
|
||||
text_view = GTK_TEXT_VIEW (widget);
|
||||
priv = text_view->priv;
|
||||
device = gdk_event_get_source_device ((GdkEvent *) event);
|
||||
|
||||
if (event->window != priv->text_window->bin_window)
|
||||
return FALSE;
|
||||
|
||||
if (event->button == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
if (priv->drag_start_x >= 0)
|
||||
{
|
||||
priv->drag_start_x = -1;
|
||||
priv->drag_start_y = -1;
|
||||
}
|
||||
|
||||
if (gtk_text_view_end_selection_drag (GTK_TEXT_VIEW (widget)))
|
||||
{
|
||||
if (test_touchscreen ||
|
||||
gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN)
|
||||
gtk_text_view_selection_bubble_popup_set (text_view);
|
||||
return TRUE;
|
||||
}
|
||||
else if (priv->pending_place_cursor_button == event->button)
|
||||
{
|
||||
GtkTextHandleMode mode;
|
||||
GtkTextIter iter;
|
||||
|
||||
/* Unselect everything; we clicked inside selection, but
|
||||
* didn't move by the drag threshold, so just clear selection
|
||||
* and place cursor.
|
||||
*/
|
||||
gtk_text_layout_get_iter_at_pixel (priv->layout,
|
||||
&iter,
|
||||
event->x + priv->xoffset,
|
||||
event->y + priv->yoffset);
|
||||
|
||||
gtk_text_buffer_place_cursor (get_buffer (text_view), &iter);
|
||||
gtk_text_view_check_cursor_blink (text_view);
|
||||
|
||||
if (priv->text_handle)
|
||||
{
|
||||
if (test_touchscreen || gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN)
|
||||
mode = GTK_TEXT_HANDLE_MODE_CURSOR;
|
||||
else
|
||||
mode = GTK_TEXT_HANDLE_MODE_NONE;
|
||||
|
||||
gtk_text_view_update_handles (text_view, mode);
|
||||
}
|
||||
|
||||
priv->pending_place_cursor_button = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
keymap_direction_changed (GdkKeymap *keymap,
|
||||
GtkTextView *text_view)
|
||||
@ -5310,52 +5228,6 @@ gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_text_view_motion_event (GtkWidget *widget, GdkEventMotion *event)
|
||||
{
|
||||
GtkTextView *text_view;
|
||||
GtkTextViewPrivate *priv;
|
||||
|
||||
text_view = GTK_TEXT_VIEW (widget);
|
||||
priv = text_view->priv;
|
||||
|
||||
gtk_text_view_unobscure_mouse_cursor (text_view);
|
||||
|
||||
if (event->window == priv->text_window->bin_window &&
|
||||
priv->drag_start_x >= 0)
|
||||
{
|
||||
gint x = event->x;
|
||||
gint y = event->y;
|
||||
|
||||
gdk_event_request_motions (event);
|
||||
|
||||
if (gtk_drag_check_threshold (widget,
|
||||
priv->drag_start_x,
|
||||
priv->drag_start_y,
|
||||
x, y))
|
||||
{
|
||||
GtkTextIter iter;
|
||||
gint buffer_x, buffer_y;
|
||||
|
||||
gtk_text_view_window_to_buffer_coords (text_view,
|
||||
GTK_TEXT_WINDOW_TEXT,
|
||||
priv->drag_start_x,
|
||||
priv->drag_start_y,
|
||||
&buffer_x,
|
||||
&buffer_y);
|
||||
|
||||
gtk_text_layout_get_iter_at_pixel (priv->layout,
|
||||
&iter,
|
||||
buffer_x, buffer_y);
|
||||
|
||||
gtk_text_view_start_selection_dnd (text_view, &iter, event);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_paint (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
@ -6765,6 +6637,37 @@ gtk_text_view_unselect (GtkTextView *text_view)
|
||||
&insert);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_iter_from_gesture (GtkTextView *text_view,
|
||||
GtkTextIter *iter,
|
||||
gint *x,
|
||||
gint *y)
|
||||
{
|
||||
gdouble start_x, start_y, offset_x, offset_y;
|
||||
GtkTextViewPrivate *priv;
|
||||
gint xcoord, ycoord;
|
||||
|
||||
priv = text_view->priv;
|
||||
|
||||
if (!gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (priv->drag_gesture),
|
||||
&start_x, &start_y) ||
|
||||
!gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (priv->drag_gesture),
|
||||
&offset_x, &offset_y))
|
||||
return FALSE;
|
||||
|
||||
xcoord = start_x + offset_x + priv->xoffset;
|
||||
ycoord = start_y + offset_y + priv->yoffset;
|
||||
gtk_text_layout_get_iter_at_pixel (priv->layout, iter, xcoord, ycoord);
|
||||
|
||||
if (x)
|
||||
*x = xcoord;
|
||||
|
||||
if (y)
|
||||
*y = ycoord;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
get_iter_at_pointer (GtkTextView *text_view,
|
||||
GdkDevice *device,
|
||||
@ -6794,16 +6697,14 @@ get_iter_at_pointer (GtkTextView *text_view,
|
||||
|
||||
static void
|
||||
move_mark_to_pointer_and_scroll (GtkTextView *text_view,
|
||||
const gchar *mark_name,
|
||||
GdkDevice *device,
|
||||
GdkInputSource source)
|
||||
const gchar *mark_name)
|
||||
{
|
||||
GtkTextIter newplace;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextMark *mark;
|
||||
|
||||
buffer = get_buffer (text_view);
|
||||
get_iter_at_pointer (text_view, device, &newplace, NULL, NULL);
|
||||
get_iter_from_gesture (text_view, &newplace, NULL, NULL);
|
||||
|
||||
mark = gtk_text_buffer_get_mark (buffer, mark_name);
|
||||
|
||||
@ -6983,42 +6884,73 @@ selection_data_free (SelectionData *data)
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static gint
|
||||
selection_motion_event_handler (GtkTextView *text_view,
|
||||
GdkEventMotion *event,
|
||||
SelectionData *data)
|
||||
static void
|
||||
gtk_text_view_drag_gesture_update (GtkGestureDrag *gesture,
|
||||
gdouble offset_x,
|
||||
gdouble offset_y,
|
||||
GtkTextView *text_view)
|
||||
{
|
||||
GtkTextViewPrivate *priv;
|
||||
GdkInputSource input_source;
|
||||
GdkEventSequence *sequence;
|
||||
gdouble start_x, start_y;
|
||||
gboolean is_touchscreen;
|
||||
const GdkEvent *event;
|
||||
SelectionData *data;
|
||||
GdkDevice *device;
|
||||
|
||||
priv = text_view->priv;
|
||||
gdk_event_request_motions (event);
|
||||
data = g_object_get_qdata (G_OBJECT (gesture), quark_text_selection_data);
|
||||
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
|
||||
event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
|
||||
gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
|
||||
|
||||
device = gdk_event_get_source_device ((GdkEvent *) event);
|
||||
input_source = gdk_device_get_source (device);
|
||||
|
||||
if (priv->grab_device != event->device)
|
||||
return FALSE;
|
||||
|
||||
if (data->granularity == SELECT_CHARACTERS)
|
||||
if (!data)
|
||||
{
|
||||
move_mark_to_pointer_and_scroll (text_view, "insert",
|
||||
event->device, input_source);
|
||||
/* If no data is attached, the initial press happened within the current
|
||||
* text selection, check for drag and drop to be initiated.
|
||||
*/
|
||||
if (gtk_drag_check_threshold (GTK_WIDGET (text_view), start_x, start_y,
|
||||
start_x + offset_x, start_y + offset_y))
|
||||
{
|
||||
GtkTextIter iter;
|
||||
gint buffer_x, buffer_y;
|
||||
|
||||
gtk_text_view_window_to_buffer_coords (text_view,
|
||||
GTK_TEXT_WINDOW_TEXT,
|
||||
start_x, start_y,
|
||||
&buffer_x,
|
||||
&buffer_y);
|
||||
|
||||
gtk_text_layout_get_iter_at_pixel (text_view->priv->layout,
|
||||
&iter, buffer_x, buffer_y);
|
||||
|
||||
gtk_text_view_start_selection_dnd (text_view, &iter, event,
|
||||
start_x, start_y);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
device = gdk_event_get_source_device (event);
|
||||
|
||||
is_touchscreen = test_touchscreen ||
|
||||
gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN;
|
||||
|
||||
if (data->granularity == SELECT_CHARACTERS)
|
||||
{
|
||||
move_mark_to_pointer_and_scroll (text_view, "insert");
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkTextIter cursor, start, end;
|
||||
GtkTextIter orig_start, orig_end;
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
|
||||
buffer = get_buffer (text_view);
|
||||
|
||||
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);
|
||||
|
||||
get_iter_at_pointer (text_view, event->device, &cursor, NULL, NULL);
|
||||
|
||||
get_iter_from_gesture (text_view, &cursor, NULL, NULL);
|
||||
|
||||
start = cursor;
|
||||
extend_selection (text_view, data->granularity, &start, &end);
|
||||
|
||||
@ -7039,19 +6971,86 @@ selection_motion_event_handler (GtkTextView *text_view,
|
||||
*/
|
||||
if (text_view->priv->scroll_timeout != 0) /* reset on every motion event */
|
||||
g_source_remove (text_view->priv->scroll_timeout);
|
||||
|
||||
|
||||
text_view->priv->scroll_timeout =
|
||||
gdk_threads_add_timeout (50, selection_scan_timeout, text_view);
|
||||
g_source_set_name_by_id (text_view->priv->scroll_timeout, "[gtk+] selection_scan_timeout");
|
||||
|
||||
if (test_touchscreen || input_source == GDK_SOURCE_TOUCHSCREEN)
|
||||
if (is_touchscreen)
|
||||
{
|
||||
_gtk_text_view_ensure_text_handles (text_view);
|
||||
gtk_text_view_update_handles (text_view, GTK_TEXT_HANDLE_MODE_SELECTION);
|
||||
gtk_text_view_show_magnifier (text_view, event->x, event->y);
|
||||
gtk_text_view_show_magnifier (text_view, start_x + offset_x,
|
||||
start_y + offset_y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_drag_gesture_end (GtkGestureDrag *gesture,
|
||||
gdouble offset_x,
|
||||
gdouble offset_y,
|
||||
GtkTextView *text_view)
|
||||
{
|
||||
GdkEventSequence *sequence;
|
||||
gdouble start_x, start_y;
|
||||
GtkTextViewPrivate *priv;
|
||||
gboolean is_touchscreen;
|
||||
const GdkEvent *event;
|
||||
GdkDevice *device;
|
||||
|
||||
priv = text_view->priv;
|
||||
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
|
||||
gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
|
||||
|
||||
g_object_set_qdata (G_OBJECT (gesture), quark_text_selection_data, NULL);
|
||||
gtk_text_view_unobscure_mouse_cursor (text_view);
|
||||
|
||||
if (priv->scroll_timeout != 0)
|
||||
{
|
||||
g_source_remove (priv->scroll_timeout);
|
||||
priv->scroll_timeout = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
if (priv->magnifier_popover)
|
||||
gtk_widget_hide (priv->magnifier_popover);
|
||||
|
||||
/* Check whether the drag was cancelled rather than finished */
|
||||
if (!gtk_gesture_handles_sequence (GTK_GESTURE (gesture), sequence))
|
||||
return;
|
||||
|
||||
event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
|
||||
device = gdk_event_get_source_device (event);
|
||||
is_touchscreen = test_touchscreen ||
|
||||
gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN;
|
||||
|
||||
if (is_touchscreen)
|
||||
gtk_text_view_selection_bubble_popup_set (text_view);
|
||||
|
||||
if (!gtk_drag_check_threshold (GTK_WIDGET (text_view), start_x, start_y,
|
||||
start_x + offset_x, start_y + offset_y))
|
||||
{
|
||||
GtkTextHandleMode mode = GTK_TEXT_HANDLE_MODE_NONE;
|
||||
GtkTextIter iter;
|
||||
|
||||
/* Unselect everything; we clicked inside selection, but
|
||||
* didn't move by the drag threshold, so just clear selection
|
||||
* and place cursor.
|
||||
*/
|
||||
gtk_text_layout_get_iter_at_pixel (priv->layout, &iter,
|
||||
start_x + offset_x + priv->xoffset,
|
||||
start_y + offset_y + priv->yoffset);
|
||||
|
||||
gtk_text_buffer_place_cursor (get_buffer (text_view), &iter);
|
||||
gtk_text_view_check_cursor_blink (text_view);
|
||||
|
||||
if (priv->text_handle)
|
||||
{
|
||||
if (is_touchscreen)
|
||||
mode = GTK_TEXT_HANDLE_MODE_CURSOR;
|
||||
|
||||
gtk_text_view_update_handles (text_view, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -7067,14 +7066,10 @@ gtk_text_view_start_selection_drag (GtkTextView *text_view,
|
||||
SelectionData *data;
|
||||
GdkModifierType state;
|
||||
|
||||
if (text_view->priv->selection_drag_handler != 0)
|
||||
return;
|
||||
|
||||
priv = text_view->priv;
|
||||
data = g_new0 (SelectionData, 1);
|
||||
data->granularity = granularity;
|
||||
|
||||
priv->grab_device = gdk_event_get_device (event);
|
||||
buffer = get_buffer (text_view);
|
||||
|
||||
cursor = *iter;
|
||||
@ -7128,11 +7123,11 @@ gtk_text_view_start_selection_drag (GtkTextView *text_view,
|
||||
&orig_end, TRUE);
|
||||
gtk_text_view_check_cursor_blink (text_view);
|
||||
|
||||
text_view->priv->selection_drag_handler = g_signal_connect_data (text_view,
|
||||
"motion-notify-event",
|
||||
G_CALLBACK (selection_motion_event_handler),
|
||||
data,
|
||||
(GClosureNotify) selection_data_free, 0);
|
||||
g_object_set_qdata_full (G_OBJECT (priv->drag_gesture),
|
||||
quark_text_selection_data,
|
||||
data, (GDestroyNotify) selection_data_free);
|
||||
gtk_gesture_set_state (priv->drag_gesture,
|
||||
GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
}
|
||||
|
||||
/* returns whether we were really dragging */
|
||||
@ -7143,23 +7138,15 @@ gtk_text_view_end_selection_drag (GtkTextView *text_view)
|
||||
|
||||
priv = text_view->priv;
|
||||
|
||||
if (!priv->grab_device)
|
||||
if (!gtk_gesture_is_active (priv->drag_gesture))
|
||||
return FALSE;
|
||||
|
||||
if (priv->selection_drag_handler == 0)
|
||||
return FALSE;
|
||||
|
||||
g_signal_handler_disconnect (text_view, priv->selection_drag_handler);
|
||||
priv->selection_drag_handler = 0;
|
||||
|
||||
if (priv->scroll_timeout != 0)
|
||||
{
|
||||
g_source_remove (priv->scroll_timeout);
|
||||
priv->scroll_timeout = 0;
|
||||
}
|
||||
|
||||
priv->grab_device = NULL;
|
||||
|
||||
if (priv->magnifier_popover)
|
||||
gtk_widget_hide (priv->magnifier_popover);
|
||||
|
||||
@ -7499,7 +7486,9 @@ drag_begin_cb (GtkWidget *widget,
|
||||
static void
|
||||
gtk_text_view_start_selection_dnd (GtkTextView *text_view,
|
||||
const GtkTextIter *iter,
|
||||
GdkEventMotion *event)
|
||||
const GdkEvent *event,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GtkTargetList *target_list;
|
||||
|
||||
@ -7509,13 +7498,7 @@ gtk_text_view_start_selection_dnd (GtkTextView *text_view,
|
||||
G_CALLBACK (drag_begin_cb), NULL);
|
||||
gtk_drag_begin_with_coordinates (GTK_WIDGET (text_view), target_list,
|
||||
GDK_ACTION_COPY | GDK_ACTION_MOVE,
|
||||
1, (GdkEvent*)event,
|
||||
text_view->priv->drag_start_x,
|
||||
text_view->priv->drag_start_y);
|
||||
|
||||
text_view->priv->drag_start_x = -1;
|
||||
text_view->priv->drag_start_y = -1;
|
||||
text_view->priv->pending_place_cursor_button = 0;
|
||||
1, (GdkEvent*) event, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user