[gtk+] treeview: Use drag gesture for rubberband selection/DnD
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] treeview: Use drag gesture for rubberband selection/DnD
- Date: Wed, 11 Jun 2014 15:51:48 +0000 (UTC)
commit 3f084e3ab546d896a2711af8b942d4b8a89ac58e
Author: Carlos Garnacho <carlosg gnome org>
Date: Wed Jun 11 16:16:16 2014 +0200
treeview: Use drag gesture for rubberband selection/DnD
This gesture acts only on events from the bin window, and checks that
either the pressed row is draggable, or the conditions for rubberband
selection apply.
gtk/gtktreeview.c | 390 ++++++++++++++++++++++++++++++-----------------------
1 files changed, 222 insertions(+), 168 deletions(-)
---
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 09a406f..2be6c72 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -439,6 +439,7 @@ struct _GtkTreeViewPrivate
/* Gestures */
GtkGesture *multipress_gesture;
GtkGesture *column_multipress_gesture;
+ GtkGesture *drag_gesture; /* Rubberbanding, row DnD */
GtkGesture *column_drag_gesture; /* Column reordering, resizing */
/* Tooltip support */
@@ -610,8 +611,6 @@ static gint gtk_tree_view_focus (GtkWidget *widget,
GtkDirectionType direction);
static void gtk_tree_view_grab_focus (GtkWidget *widget);
static void gtk_tree_view_style_updated (GtkWidget *widget);
-static void gtk_tree_view_grab_notify (GtkWidget *widget,
- gboolean was_grabbed);
static void gtk_tree_view_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state);
@@ -751,8 +750,7 @@ static void gtk_tree_view_clamp_node_visible (GtkTreeView
static void gtk_tree_view_clamp_column_visible (GtkTreeView *tree_view,
GtkTreeViewColumn *column,
gboolean focus_to_cell);
-static gboolean gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
- GdkEventMotion *event);
+static gboolean gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view);
static void gtk_tree_view_focus_to_cursor (GtkTreeView *tree_view);
static void gtk_tree_view_move_cursor_up_down (GtkTreeView *tree_view,
gint count);
@@ -910,6 +908,19 @@ static void gtk_tree_view_column_drag_gesture_end (GtkGestureDrag *ges
gdouble offset_y,
GtkTreeView *tree_view);
+static void gtk_tree_view_drag_gesture_begin (GtkGestureDrag *gesture,
+ gdouble start_x,
+ gdouble start_y,
+ GtkTreeView *tree_view);
+static void gtk_tree_view_drag_gesture_update (GtkGestureDrag *gesture,
+ gdouble offset_x,
+ gdouble offset_y,
+ GtkTreeView *tree_view);
+static void gtk_tree_view_drag_gesture_end (GtkGestureDrag *gesture,
+ gdouble offset_x,
+ gdouble offset_y,
+ GtkTreeView *tree_view);
+
static guint tree_view_signals [LAST_SIGNAL] = { 0 };
@@ -972,7 +983,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
widget_class->focus = gtk_tree_view_focus;
widget_class->grab_focus = gtk_tree_view_grab_focus;
widget_class->style_updated = gtk_tree_view_style_updated;
- widget_class->grab_notify = gtk_tree_view_grab_notify;
widget_class->state_flags_changed = gtk_tree_view_state_flags_changed;
widget_class->queue_draw_region = gtk_tree_view_queue_draw_region;
@@ -1872,6 +1882,19 @@ gtk_tree_view_init (GtkTreeView *tree_view)
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER
(tree_view->priv->column_multipress_gesture),
GTK_PHASE_CAPTURE);
+ tree_view->priv->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (tree_view));
+ gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (tree_view->priv->drag_gesture), FALSE);
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (tree_view->priv->drag_gesture),
+ GDK_BUTTON_PRIMARY);
+ g_signal_connect (tree_view->priv->drag_gesture, "drag-begin",
+ G_CALLBACK (gtk_tree_view_drag_gesture_begin), tree_view);
+ g_signal_connect (tree_view->priv->drag_gesture, "drag-update",
+ G_CALLBACK (gtk_tree_view_drag_gesture_update), tree_view);
+ g_signal_connect (tree_view->priv->drag_gesture, "drag-end",
+ G_CALLBACK (gtk_tree_view_drag_gesture_end), tree_view);
+ gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (tree_view->priv->drag_gesture),
+ GTK_PHASE_CAPTURE);
+
tree_view->priv->column_drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (tree_view));
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (tree_view->priv->column_drag_gesture), FALSE);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (tree_view->priv->column_drag_gesture),
@@ -2273,6 +2296,7 @@ gtk_tree_view_destroy (GtkWidget *widget)
tree_view->priv->pixel_cache = NULL;
g_clear_object (&tree_view->priv->multipress_gesture);
+ g_clear_object (&tree_view->priv->drag_gesture);
g_clear_object (&tree_view->priv->column_multipress_gesture);
g_clear_object (&tree_view->priv->column_drag_gesture);
@@ -2512,6 +2536,8 @@ gtk_tree_view_realize (GtkWidget *widget)
gtk_gesture_set_window (tree_view->priv->multipress_gesture,
tree_view->priv->bin_window);
+ gtk_gesture_set_window (tree_view->priv->drag_gesture,
+ tree_view->priv->bin_window);
}
static void
@@ -2589,6 +2615,7 @@ gtk_tree_view_unrealize (GtkWidget *widget)
}
gtk_gesture_set_window (tree_view->priv->multipress_gesture, NULL);
+ gtk_gesture_set_window (tree_view->priv->drag_gesture, NULL);
GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->unrealize (widget);
}
@@ -3045,6 +3072,56 @@ gtk_tree_view_get_expander_size (GtkTreeView *tree_view)
}
static void
+get_current_selection_modifiers (GtkWidget *widget,
+ gboolean *modify,
+ gboolean *extend)
+{
+ GdkModifierType state = 0;
+ GdkModifierType mask;
+
+ *modify = FALSE;
+ *extend = FALSE;
+
+ if (gtk_get_current_event_state (&state))
+ {
+ mask = gtk_widget_get_modifier_mask (widget, GDK_MODIFIER_INTENT_MODIFY_SELECTION);
+ if ((state & mask) == mask)
+ *modify = TRUE;
+ mask = gtk_widget_get_modifier_mask (widget, GDK_MODIFIER_INTENT_EXTEND_SELECTION);
+ if ((state & mask) == mask)
+ *extend = TRUE;
+ }
+}
+
+static void
+gtk_tree_view_drag_gesture_begin (GtkGestureDrag *gesture,
+ gdouble start_x,
+ gdouble start_y,
+ GtkTreeView *tree_view)
+{
+ gint bin_x, bin_y;
+
+ gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, start_x, start_y,
+ &bin_x, &bin_y);
+ tree_view->priv->press_start_x = tree_view->priv->rubber_band_x = bin_x;
+ tree_view->priv->press_start_y = tree_view->priv->rubber_band_y = bin_y;
+
+ if (tree_view->priv->rubber_banding_enable
+ && gtk_tree_selection_get_mode (tree_view->priv->selection) == GTK_SELECTION_MULTIPLE)
+ {
+ gboolean modify, extend;
+
+ tree_view->priv->press_start_y += tree_view->priv->dy;
+ tree_view->priv->rubber_band_y += tree_view->priv->dy;
+ tree_view->priv->rubber_band_status = RUBBER_BAND_MAYBE_START;
+
+ get_current_selection_modifiers (GTK_WIDGET (tree_view), &modify, &extend);
+ tree_view->priv->rubber_band_modify = modify;
+ tree_view->priv->rubber_band_extend = extend;
+ }
+}
+
+static void
gtk_tree_view_column_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
gint n_press,
gdouble x,
@@ -3174,12 +3251,8 @@ gtk_tree_view_button_press (GtkWidget *widget,
gint depth;
gint new_y;
gint y_offset;
- gint dval;
- gint pre_val, aft_val;
GtkTreeViewColumn *column = NULL;
- gint column_handled_click = FALSE;
gboolean rtl;
- gboolean node_selected;
GdkModifierType extend_mod_mask;
GdkModifierType modify_mod_mask;
@@ -3329,7 +3402,6 @@ gtk_tree_view_button_press (GtkWidget *widget,
gtk_tree_path_free (anchor);
return TRUE;
}
- column_handled_click = TRUE;
}
}
if (anchor)
@@ -3342,10 +3414,6 @@ gtk_tree_view_button_press (GtkWidget *widget,
modify_mod_mask =
gtk_widget_get_modifier_mask (widget, GDK_MODIFIER_INTENT_MODIFY_SELECTION);
- /* select */
- node_selected = GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED);
- pre_val = gtk_adjustment_get_value (tree_view->priv->vadjustment);
-
/* we only handle selection modifications on the first button press
*/
if (event->type == GDK_BUTTON_PRESS)
@@ -3390,42 +3458,6 @@ gtk_tree_view_button_press (GtkWidget *widget,
tree_view->priv->extend_selection_pressed = FALSE;
}
- /* the treeview may have been scrolled because of _set_cursor,
- * correct here
- */
-
- aft_val = gtk_adjustment_get_value (tree_view->priv->vadjustment);
- dval = pre_val - aft_val;
-
- cell_area.y += dval;
- background_area.y += dval;
-
- /* Save press to possibly begin a drag
- */
- if (!column_handled_click &&
- !tree_view->priv->in_grab &&
- tree_view->priv->pressed_button < 0)
- {
- tree_view->priv->pressed_button = event->button;
- tree_view->priv->press_start_x = event->x;
- tree_view->priv->press_start_y = event->y;
-
- if (tree_view->priv->rubber_banding_enable
- && !node_selected
- && gtk_tree_selection_get_mode (tree_view->priv->selection) == GTK_SELECTION_MULTIPLE)
- {
- tree_view->priv->press_start_y += tree_view->priv->dy;
- tree_view->priv->rubber_band_x = event->x;
- tree_view->priv->rubber_band_y = event->y + tree_view->priv->dy;
- tree_view->priv->rubber_band_status = RUBBER_BAND_MAYBE_START;
-
- if ((event->state & modify_mod_mask) == modify_mod_mask)
- tree_view->priv->rubber_band_modify = TRUE;
- if ((event->state & extend_mod_mask) == extend_mod_mask)
- tree_view->priv->rubber_band_extend = TRUE;
- }
- }
-
return TRUE;
}
@@ -3540,6 +3572,15 @@ gtk_tree_view_column_drag_gesture_end (GtkGestureDrag *gesture,
gtk_tree_view_button_release_column_resize (tree_view);
}
+static void
+gtk_tree_view_drag_gesture_end (GtkGestureDrag *gesture,
+ gdouble offset_x,
+ gdouble offset_y,
+ GtkTreeView *tree_view)
+{
+ gtk_tree_view_stop_rubber_band (tree_view);
+}
+
static gboolean
button_event_modifies_selection (GdkEventButton *event)
{
@@ -3552,9 +3593,6 @@ gtk_tree_view_button_release (GtkWidget *widget,
{
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
- if (tree_view->priv->rubber_band_status)
- gtk_tree_view_stop_rubber_band (tree_view);
-
if (tree_view->priv->pressed_button == event->button)
tree_view->priv->pressed_button = -1;
@@ -4190,13 +4228,26 @@ gtk_tree_view_vertical_autoscroll (GtkTreeView *tree_view)
gint y;
gint offset;
- gdk_window_get_device_position (tree_view->priv->bin_window,
- gdk_device_manager_get_client_pointer (
- gdk_display_get_device_manager (
- gtk_widget_get_display (GTK_WIDGET (tree_view)))),
- NULL, &y, NULL);
- y += tree_view->priv->dy;
+ if (gtk_gesture_is_recognized (tree_view->priv->drag_gesture))
+ {
+ GdkEventSequence *sequence;
+ gdouble py;
+ sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE
(tree_view->priv->drag_gesture));
+ gtk_gesture_get_point (tree_view->priv->drag_gesture, sequence, NULL, &py);
+ gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, 0, py,
+ NULL, &y);
+ }
+ else
+ {
+ gdk_window_get_device_position (tree_view->priv->bin_window,
+ gdk_device_manager_get_client_pointer (
+ gdk_display_get_device_manager (
+ gtk_widget_get_display (GTK_WIDGET (tree_view)))),
+ NULL, &y, NULL);
+ }
+
+ y += tree_view->priv->dy;
gtk_tree_view_get_visible_rect (tree_view, &visible_rect);
/* see if we are near the edge. */
@@ -4417,9 +4468,22 @@ gtk_tree_view_update_rubber_band_selection (GtkTreeView *tree_view)
{
GtkRBTree *start_tree, *end_tree;
GtkRBNode *start_node, *end_node;
+ gdouble start_y, offset_y;
+ gint bin_y;
+
+ if (!gtk_gesture_is_active (tree_view->priv->drag_gesture))
+ return;
- _gtk_rbtree_find_offset (tree_view->priv->tree, MIN (tree_view->priv->press_start_y,
tree_view->priv->rubber_band_y), &start_tree, &start_node);
- _gtk_rbtree_find_offset (tree_view->priv->tree, MAX (tree_view->priv->press_start_y,
tree_view->priv->rubber_band_y), &end_tree, &end_node);
+ gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (tree_view->priv->drag_gesture),
+ NULL, &offset_y);
+ gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (tree_view->priv->drag_gesture),
+ NULL, &start_y);
+ gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, 0, start_y,
+ NULL, &bin_y);
+ bin_y = MAX (0, bin_y + offset_y + tree_view->priv->dy);
+
+ _gtk_rbtree_find_offset (tree_view->priv->tree, MIN (tree_view->priv->press_start_y, bin_y), &start_tree,
&start_node);
+ _gtk_rbtree_find_offset (tree_view->priv->tree, MAX (tree_view->priv->press_start_y, bin_y), &end_tree,
&end_node);
/* Handle the start area first */
if (!tree_view->priv->rubber_band_start_node)
@@ -4520,25 +4584,31 @@ gtk_tree_view_update_rubber_band_selection (GtkTreeView *tree_view)
static void
gtk_tree_view_update_rubber_band (GtkTreeView *tree_view)
{
- gint x, y;
+ gdouble start_x, start_y, offset_x, offset_y, x, y;
GdkRectangle old_area;
GdkRectangle new_area;
GdkRectangle common;
cairo_region_t *invalid_region;
+ gint bin_x, bin_y;
+
+ if (!gtk_gesture_is_recognized (tree_view->priv->drag_gesture))
+ return;
old_area.x = MIN (tree_view->priv->press_start_x, tree_view->priv->rubber_band_x);
old_area.y = MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y) - tree_view->priv->dy;
old_area.width = ABS (tree_view->priv->rubber_band_x - tree_view->priv->press_start_x) + 1;
old_area.height = ABS (tree_view->priv->rubber_band_y - tree_view->priv->press_start_y) + 1;
- gdk_window_get_device_position (tree_view->priv->bin_window,
- gdk_device_manager_get_client_pointer (
- gdk_display_get_device_manager (
- gtk_widget_get_display (GTK_WIDGET (tree_view)))),
- &x, &y, NULL);
+ gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (tree_view->priv->drag_gesture),
+ &offset_x, &offset_y);
+ gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (tree_view->priv->drag_gesture),
+ &start_x, &start_y);
+ gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, start_x, start_y,
+ &bin_x, &bin_y);
+ bin_y += tree_view->priv->dy;
- x = MAX (x, 0);
- y = MAX (y, 0) + tree_view->priv->dy;
+ x = MAX (bin_x + offset_x, 0);
+ y = MAX (bin_y + offset_y, 0);
new_area.x = MIN (tree_view->priv->press_start_x, x);
new_area.y = MIN (tree_view->priv->press_start_y, y) - tree_view->priv->dy;
@@ -4579,8 +4649,22 @@ static void
gtk_tree_view_paint_rubber_band (GtkTreeView *tree_view,
cairo_t *cr)
{
+ gdouble start_x, start_y, offset_x, offset_y;
GdkRectangle rect;
GtkStyleContext *context;
+ gint bin_x, bin_y;
+
+ if (!gtk_gesture_is_recognized (tree_view->priv->drag_gesture))
+ return;
+
+ gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (tree_view->priv->drag_gesture),
+ &offset_x, &offset_y);
+ gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (tree_view->priv->drag_gesture),
+ &start_x, &start_y);
+ gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, start_x, start_y,
+ &bin_x, &bin_y);
+ bin_x = MAX (0, bin_x + offset_x);
+ bin_y = MAX (0, bin_y + offset_y + tree_view->priv->dy);
cairo_save (cr);
@@ -4589,10 +4673,10 @@ gtk_tree_view_paint_rubber_band (GtkTreeView *tree_view,
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RUBBERBAND);
- rect.x = MIN (tree_view->priv->press_start_x, tree_view->priv->rubber_band_x);
- rect.y = MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y) - tree_view->priv->dy;
- rect.width = ABS (tree_view->priv->press_start_x - tree_view->priv->rubber_band_x) + 1;
- rect.height = ABS (tree_view->priv->press_start_y - tree_view->priv->rubber_band_y) + 1;
+ rect.x = MIN (tree_view->priv->press_start_x, bin_x);
+ rect.y = MIN (tree_view->priv->press_start_y, bin_y) - tree_view->priv->dy;
+ rect.width = ABS (tree_view->priv->press_start_x - bin_x) + 1;
+ rect.height = ABS (tree_view->priv->press_start_y - bin_y) + 1;
gdk_cairo_rectangle (cr, &rect);
cairo_clip (cr);
@@ -4632,25 +4716,24 @@ gtk_tree_view_column_drag_gesture_update (GtkGestureDrag *gesture,
gtk_tree_view_motion_drag_column (tree_view, x, y);
}
-static gboolean
-gtk_tree_view_motion_bin_window (GtkWidget *widget,
- GdkEventMotion *event)
+static void
+gtk_tree_view_drag_gesture_update (GtkGestureDrag *gesture,
+ gdouble offset_x,
+ gdouble offset_y,
+ GtkTreeView *tree_view)
{
- GtkTreeView *tree_view;
- GtkRBTree *tree;
- GtkRBNode *node;
- gint new_y;
-
- tree_view = (GtkTreeView *) widget;
-
if (tree_view->priv->tree == NULL)
- return FALSE;
+ {
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
+ return;
+ }
if (tree_view->priv->rubber_band_status == RUBBER_BAND_MAYBE_START)
{
gtk_tree_view_update_rubber_band (tree_view);
tree_view->priv->rubber_band_status = RUBBER_BAND_ACTIVE;
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
else if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE)
{
@@ -4658,29 +4741,11 @@ gtk_tree_view_motion_bin_window (GtkWidget *widget,
add_scroll_timeout (tree_view);
}
-
- /* only check for an initiated drag when a button is pressed */
- if (tree_view->priv->pressed_button >= 0
- && !tree_view->priv->rubber_band_status)
- gtk_tree_view_maybe_begin_dragging_row (tree_view, event);
-
- new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, event->y);
- if (new_y < 0)
- new_y = 0;
-
- _gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
-
- /* If we are currently pressing down a button, we don't want to prelight anything else. */
- if ((tree_view->priv->button_pressed_node != NULL) &&
- (tree_view->priv->button_pressed_node != node))
- node = NULL;
-
- tree_view->priv->event_last_x = event->x;
- tree_view->priv->event_last_y = event->y;
-
- prelight_or_select (tree_view, tree, node, event->x, event->y);
-
- return TRUE;
+ else if (!tree_view->priv->rubber_band_status)
+ {
+ if (gtk_tree_view_maybe_begin_dragging_row (tree_view))
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
+ }
}
static gboolean
@@ -4688,13 +4753,29 @@ gtk_tree_view_motion (GtkWidget *widget,
GdkEventMotion *event)
{
GtkTreeView *tree_view;
+ GtkRBTree *tree;
+ GtkRBNode *node;
+ gint new_y;
tree_view = (GtkTreeView *) widget;
- if (event->window == tree_view->priv->bin_window)
- return gtk_tree_view_motion_bin_window (widget, event);
+ if (tree_view->priv->tree)
+ {
+ /* If we are currently pressing down a button, we don't want to prelight anything else. */
+ if (gtk_gesture_is_active (tree_view->priv->drag_gesture) ||
+ gtk_gesture_is_active (tree_view->priv->multipress_gesture))
+ node = NULL;
- return FALSE;
+ new_y = MAX (0, TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, event->y));
+
+ _gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
+
+ tree_view->priv->event_last_x = event->x;
+ tree_view->priv->event_last_y = event->y;
+ prelight_or_select (tree_view, tree, node, event->x, event->y);
+ }
+
+ return GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->motion_notify_event (widget, event);
}
/* Invalidate the focus rectangle near the edge of the bin_window; used when
@@ -7659,31 +7740,34 @@ get_logical_dest_row (GtkTreeView *tree_view,
}
static gboolean
-gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
- GdkEventMotion *event)
+gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view)
{
GtkWidget *widget = GTK_WIDGET (tree_view);
+ gdouble start_x, start_y, offset_x, offset_y;
+ GdkEventSequence *sequence;
+ const GdkEvent *event;
GdkDragContext *context;
TreeViewDragInfo *di;
GtkTreePath *path = NULL;
gint button;
- gint cell_x, cell_y;
- gint drag_start_x, drag_start_y;
GtkTreeModel *model;
gboolean retval = FALSE;
+ gint bin_x, bin_y;
di = get_info (tree_view);
if (di == NULL || !di->source_set)
goto out;
- if (tree_view->priv->pressed_button < 0)
+ if (!gtk_gesture_is_recognized (tree_view->priv->drag_gesture))
goto out;
- if (!gtk_drag_check_threshold (widget,
- tree_view->priv->press_start_x,
- tree_view->priv->press_start_y,
- event->x, event->y))
+ gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (tree_view->priv->drag_gesture),
+ &start_x, &start_y);
+ gtk_gesture_drag_get_offset (GTK_GESTURE_DRAG (tree_view->priv->drag_gesture),
+ &offset_x, &offset_y);
+
+ if (!gtk_drag_check_threshold (widget, 0, 0, offset_x, offset_y))
goto out;
model = gtk_tree_view_get_model (tree_view);
@@ -7691,16 +7775,16 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
if (model == NULL)
goto out;
- button = tree_view->priv->pressed_button;
- tree_view->priv->pressed_button = -1;
+ button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (tree_view->priv->drag_gesture));
- gtk_tree_view_get_path_at_pos (tree_view,
- tree_view->priv->press_start_x,
- tree_view->priv->press_start_y,
- &path,
- NULL,
- &cell_x,
- &cell_y);
+ /* Deny the multipress gesture */
+ gtk_gesture_set_state (GTK_GESTURE (tree_view->priv->multipress_gesture),
+ GTK_EVENT_SEQUENCE_DENIED);
+
+ gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, start_x, start_y,
+ &bin_x, &bin_y);
+ gtk_tree_view_get_path_at_pos (tree_view, bin_x, bin_y, &path,
+ NULL, NULL, NULL);
if (path == NULL)
goto out;
@@ -7713,21 +7797,20 @@ gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
if (!(GDK_BUTTON1_MASK << (button - 1) & di->start_button_mask))
goto out;
- /* Now we can begin the drag */
-
retval = TRUE;
- gtk_tree_view_convert_bin_window_to_widget_coords (tree_view,
- tree_view->priv->press_start_x,
- tree_view->priv->press_start_y,
- &drag_start_x, &drag_start_y);
+ /* Now we can begin the drag */
+ gtk_gesture_set_state (GTK_GESTURE (tree_view->priv->drag_gesture),
+ GTK_EVENT_SEQUENCE_CLAIMED);
+ sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (tree_view->priv->drag_gesture));
+ event = gtk_gesture_get_last_event (GTK_GESTURE (tree_view->priv->drag_gesture), sequence);
context = gtk_drag_begin_with_coordinates (widget,
gtk_drag_source_get_target_list (widget),
di->source_actions,
button,
(GdkEvent*)event,
- drag_start_x, drag_start_y);
+ start_x, start_y);
set_source_row (context, model, path);
@@ -12933,9 +13016,7 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
if (gtk_widget_get_mapped (GTK_WIDGET (tree_view)))
{
- /* now that we've collapsed all rows, we want to try to set the prelight
- * again. To do this, we fake a motion event and send it to ourselves. */
-
+ /* now that we've collapsed all rows, we want to try to set the prelight again */
child = gdk_window_get_device_position (gdk_window_get_parent (tree_view->priv->bin_window),
gdk_device_manager_get_client_pointer (
gdk_display_get_device_manager (
@@ -12943,19 +13024,10 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
&x, &y, NULL);
if (child == tree_view->priv->bin_window)
{
- GdkEventMotion event;
- gint child_x, child_y;
-
- gdk_window_get_position (child, &child_x, &child_y);
-
- event.window = tree_view->priv->bin_window;
- event.x = x - child_x;
- event.y = y - child_y;
+ y = MAX (0, TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, y));
- /* despite the fact this isn't a real event, I'm almost positive it will
- * never trigger a drag event. maybe_drag is the only function that uses
- * more than just event.x and event.y. */
- gtk_tree_view_motion_bin_window (GTK_WIDGET (tree_view), &event);
+ _gtk_rbtree_find_offset (tree_view->priv->tree, y, &tree, &node);
+ prelight_or_select (tree_view, tree_view->priv->tree, node, x, y);
}
}
@@ -15869,24 +15941,6 @@ gtk_tree_view_set_row_separator_func (GtkTreeView *tree_view,
gtk_widget_queue_resize (GTK_WIDGET (tree_view));
}
-
-static void
-gtk_tree_view_grab_notify (GtkWidget *widget,
- gboolean was_grabbed)
-{
- GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
-
- tree_view->priv->in_grab = !was_grabbed;
-
- if (!was_grabbed)
- {
- tree_view->priv->pressed_button = -1;
-
- if (tree_view->priv->rubber_band_status)
- gtk_tree_view_stop_rubber_band (tree_view);
- }
-}
-
static void
gtk_tree_view_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]