forked from AuroraMiddleware/gtk
treeview: Move all button press/release management to the multipress gesture
The multipress gesture on the bin window now also does all the business related to row selection. As row selection and activation can't be easily decoupled, this fixes certain problems around ::row-activated being emitted on NULL paths. Fixes https://bugzilla.gnome.org/show_bug.cgi?id=731455 and https://bugzilla.gnome.org/show_bug.cgi?id=731018
This commit is contained in:
parent
3f084e3ab5
commit
89f38b5fc6
@ -322,7 +322,6 @@ struct _GtkTreeViewPrivate
|
||||
GtkRBNode *button_pressed_node;
|
||||
GtkRBTree *button_pressed_tree;
|
||||
|
||||
gint pressed_button;
|
||||
gint press_start_x;
|
||||
gint press_start_y;
|
||||
|
||||
@ -591,10 +590,6 @@ static gboolean gtk_tree_view_enter_notify (GtkWidget *widget,
|
||||
GdkEventCrossing *event);
|
||||
static gboolean gtk_tree_view_leave_notify (GtkWidget *widget,
|
||||
GdkEventCrossing *event);
|
||||
static gboolean gtk_tree_view_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
static gboolean gtk_tree_view_button_release (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
#if 0
|
||||
static gboolean gtk_tree_view_configure (GtkWidget *widget,
|
||||
GdkEventConfigure *event);
|
||||
@ -895,6 +890,17 @@ static void gtk_tree_view_column_multipress_gesture_pressed (GtkGestureMultiPres
|
||||
gdouble y,
|
||||
GtkTreeView *tree_view);
|
||||
|
||||
static void gtk_tree_view_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
|
||||
gint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkTreeView *tree_view);
|
||||
static void gtk_tree_view_multipress_gesture_released (GtkGestureMultiPress *gesture,
|
||||
gint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkTreeView *tree_view);
|
||||
|
||||
static void gtk_tree_view_column_drag_gesture_begin (GtkGestureDrag *gesture,
|
||||
gdouble start_x,
|
||||
gdouble start_y,
|
||||
@ -962,8 +968,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
|
||||
widget_class->get_preferred_width = gtk_tree_view_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_tree_view_get_preferred_height;
|
||||
widget_class->size_allocate = gtk_tree_view_size_allocate;
|
||||
widget_class->button_press_event = gtk_tree_view_button_press;
|
||||
widget_class->button_release_event = gtk_tree_view_button_release;
|
||||
/*widget_class->configure_event = gtk_tree_view_configure;*/
|
||||
widget_class->motion_notify_event = gtk_tree_view_motion;
|
||||
widget_class->draw = gtk_tree_view_draw;
|
||||
@ -1761,41 +1765,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_TREE_VIEW_ACCESSIBLE);
|
||||
}
|
||||
|
||||
static void
|
||||
_tree_view_multipress_pressed (GtkGestureMultiPress *gesture,
|
||||
gint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkTreeView *tree_view)
|
||||
{
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreePath *path;
|
||||
gint bin_x, bin_y;
|
||||
|
||||
gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y,
|
||||
&bin_x, &bin_y);
|
||||
gtk_tree_view_get_path_at_pos (tree_view, bin_x, bin_y,
|
||||
&path, &column, NULL, NULL);
|
||||
|
||||
if (n_press == 2 || (n_press == 1 && tree_view->priv->activate_on_single_click))
|
||||
{
|
||||
gtk_tree_view_row_activated (tree_view, path, column);
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (n_press == 1)
|
||||
{
|
||||
tree_view->priv->button_pressed_node = tree_view->priv->prelight_node;
|
||||
tree_view->priv->button_pressed_tree = tree_view->priv->prelight_tree;
|
||||
}
|
||||
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
}
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_init (GtkTreeView *tree_view)
|
||||
{
|
||||
@ -1819,7 +1788,6 @@ gtk_tree_view_init (GtkTreeView *tree_view)
|
||||
tree_view->priv->x_drag = 0;
|
||||
tree_view->priv->drag_pos = -1;
|
||||
tree_view->priv->header_has_focus = FALSE;
|
||||
tree_view->priv->pressed_button = -1;
|
||||
tree_view->priv->press_start_x = -1;
|
||||
tree_view->priv->press_start_y = -1;
|
||||
tree_view->priv->reorderable = FALSE;
|
||||
@ -1869,9 +1837,11 @@ gtk_tree_view_init (GtkTreeView *tree_view)
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (tree_view->priv->multipress_gesture),
|
||||
GDK_BUTTON_PRIMARY);
|
||||
g_signal_connect (tree_view->priv->multipress_gesture, "pressed",
|
||||
G_CALLBACK (_tree_view_multipress_pressed), tree_view);
|
||||
G_CALLBACK (gtk_tree_view_multipress_gesture_pressed), tree_view);
|
||||
g_signal_connect (tree_view->priv->multipress_gesture, "released",
|
||||
G_CALLBACK (gtk_tree_view_multipress_gesture_released), tree_view);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (tree_view->priv->multipress_gesture),
|
||||
GTK_PHASE_TARGET);
|
||||
GTK_PHASE_BUBBLE);
|
||||
|
||||
tree_view->priv->column_multipress_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (tree_view));
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (tree_view->priv->column_multipress_gesture), FALSE);
|
||||
@ -3093,6 +3063,263 @@ get_current_selection_modifiers (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
|
||||
gint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkTreeView *tree_view)
|
||||
{
|
||||
gint vertical_separator, horizontal_separator;
|
||||
GtkWidget *widget = GTK_WIDGET (tree_view);
|
||||
GdkRectangle background_area, cell_area;
|
||||
GtkTreeViewColumn *column = NULL;
|
||||
GdkEventSequence *sequence;
|
||||
GdkModifierType modifiers;
|
||||
const GdkEvent *event;
|
||||
gint new_y, y_offset;
|
||||
gint bin_x, bin_y;
|
||||
GtkTreePath *path;
|
||||
GtkRBNode *node;
|
||||
GtkRBTree *tree;
|
||||
gint depth;
|
||||
guint button;
|
||||
GList *list;
|
||||
gboolean rtl;
|
||||
|
||||
rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
|
||||
gtk_tree_view_stop_editing (tree_view, FALSE);
|
||||
gtk_widget_style_get (widget,
|
||||
"vertical-separator", &vertical_separator,
|
||||
"horizontal-separator", &horizontal_separator,
|
||||
NULL);
|
||||
|
||||
/* Because grab_focus can cause reentrancy, we delay grab_focus until after
|
||||
* we're done handling the button press.
|
||||
*/
|
||||
gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y,
|
||||
&bin_x, &bin_y);
|
||||
button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
|
||||
if (n_press > 1)
|
||||
gtk_gesture_set_state (tree_view->priv->drag_gesture,
|
||||
GTK_EVENT_SEQUENCE_DENIED);
|
||||
|
||||
/* Empty tree? */
|
||||
if (tree_view->priv->tree == NULL)
|
||||
{
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
return;
|
||||
}
|
||||
|
||||
/* are we in an arrow? */
|
||||
if (tree_view->priv->prelight_node &&
|
||||
tree_view->priv->arrow_prelit &&
|
||||
gtk_tree_view_draw_expanders (tree_view))
|
||||
{
|
||||
if (button == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
tree_view->priv->button_pressed_node = tree_view->priv->prelight_node;
|
||||
tree_view->priv->button_pressed_tree = tree_view->priv->prelight_tree;
|
||||
gtk_tree_view_queue_draw_arrow (tree_view,
|
||||
tree_view->priv->prelight_tree,
|
||||
tree_view->priv->prelight_node);
|
||||
}
|
||||
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
return;
|
||||
}
|
||||
|
||||
/* find the node that was clicked */
|
||||
new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, bin_y);
|
||||
if (new_y < 0)
|
||||
new_y = 0;
|
||||
y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
/* We clicked in dead space */
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the path and the node */
|
||||
path = _gtk_tree_path_new_from_rbtree (tree, node);
|
||||
|
||||
if (row_is_separator (tree_view, NULL, path))
|
||||
{
|
||||
gtk_tree_path_free (path);
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
return;
|
||||
}
|
||||
|
||||
depth = gtk_tree_path_get_depth (path);
|
||||
background_area.y = y_offset + bin_y;
|
||||
background_area.height = gtk_tree_view_get_row_height (tree_view, node);
|
||||
background_area.x = 0;
|
||||
|
||||
/* Let the column have a chance at selecting it. */
|
||||
rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
|
||||
for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
|
||||
list; list = (rtl ? list->prev : list->next))
|
||||
{
|
||||
GtkTreeViewColumn *candidate = list->data;
|
||||
|
||||
if (!gtk_tree_view_column_get_visible (candidate))
|
||||
continue;
|
||||
|
||||
background_area.width = gtk_tree_view_column_get_width (candidate);
|
||||
if ((background_area.x > bin_x) ||
|
||||
(background_area.x + background_area.width <= bin_x))
|
||||
{
|
||||
background_area.x += background_area.width;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we found the focus column */
|
||||
column = candidate;
|
||||
cell_area = background_area;
|
||||
cell_area.width -= horizontal_separator;
|
||||
cell_area.height -= vertical_separator;
|
||||
cell_area.x += horizontal_separator/2;
|
||||
cell_area.y += vertical_separator/2;
|
||||
if (gtk_tree_view_is_expander_column (tree_view, column))
|
||||
{
|
||||
if (!rtl)
|
||||
cell_area.x += (depth - 1) * tree_view->priv->level_indentation;
|
||||
cell_area.width -= (depth - 1) * tree_view->priv->level_indentation;
|
||||
|
||||
if (gtk_tree_view_draw_expanders (tree_view))
|
||||
{
|
||||
gint expander_size = gtk_tree_view_get_expander_size (tree_view);
|
||||
if (!rtl)
|
||||
cell_area.x += depth * expander_size;
|
||||
cell_area.width -= depth * expander_size;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (column == NULL)
|
||||
{
|
||||
gtk_tree_path_free (path);
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
_gtk_tree_view_set_focus_column (tree_view, column);
|
||||
|
||||
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
|
||||
event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
|
||||
gdk_event_get_state (event, &modifiers);
|
||||
|
||||
/* decide if we edit */
|
||||
if (button == GDK_BUTTON_PRIMARY &&
|
||||
!(modifiers & gtk_accelerator_get_default_mod_mask ()))
|
||||
{
|
||||
GtkTreePath *anchor;
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
|
||||
gtk_tree_view_column_cell_set_cell_data (column,
|
||||
tree_view->priv->model,
|
||||
&iter,
|
||||
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT),
|
||||
node->children?TRUE:FALSE);
|
||||
|
||||
if (tree_view->priv->anchor)
|
||||
anchor = gtk_tree_row_reference_get_path (tree_view->priv->anchor);
|
||||
else
|
||||
anchor = NULL;
|
||||
|
||||
if ((anchor && !gtk_tree_path_compare (anchor, path))
|
||||
|| !_gtk_tree_view_column_has_editable_cell (column))
|
||||
{
|
||||
GtkCellEditable *cell_editable = NULL;
|
||||
|
||||
/* FIXME: get the right flags */
|
||||
guint flags = 0;
|
||||
|
||||
if (_gtk_tree_view_column_cell_event (column,
|
||||
(GdkEvent *)event,
|
||||
&cell_area, flags))
|
||||
{
|
||||
GtkCellArea *area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column));
|
||||
cell_editable = gtk_cell_area_get_edit_widget (area);
|
||||
|
||||
if (cell_editable != NULL)
|
||||
{
|
||||
gtk_tree_path_free (path);
|
||||
gtk_tree_path_free (anchor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (anchor)
|
||||
gtk_tree_path_free (anchor);
|
||||
}
|
||||
|
||||
/* we only handle selection modifications on the first button press
|
||||
*/
|
||||
if (n_press == 1)
|
||||
{
|
||||
GtkCellRenderer *focus_cell;
|
||||
gboolean modify, extend;
|
||||
|
||||
get_current_selection_modifiers (widget, &modify, &extend);
|
||||
tree_view->priv->modify_selection_pressed = modify;
|
||||
tree_view->priv->extend_selection_pressed = extend;
|
||||
|
||||
/* We update the focus cell here, this is also needed if the
|
||||
* column does not contain an editable cell. In this case,
|
||||
* GtkCellArea did not receive the event for processing (and
|
||||
* could not update the focus cell).
|
||||
*/
|
||||
focus_cell = _gtk_tree_view_column_get_cell_at_pos (column,
|
||||
&cell_area,
|
||||
&background_area,
|
||||
bin_x, bin_y);
|
||||
|
||||
if (focus_cell)
|
||||
gtk_tree_view_column_focus_cell (column, focus_cell);
|
||||
|
||||
if (modify)
|
||||
{
|
||||
gtk_tree_view_real_set_cursor (tree_view, path, CLAMP_NODE);
|
||||
gtk_tree_view_real_toggle_cursor_row (tree_view);
|
||||
}
|
||||
else if (extend)
|
||||
{
|
||||
gtk_tree_view_real_set_cursor (tree_view, path, CLAMP_NODE);
|
||||
gtk_tree_view_real_select_cursor_row (tree_view, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_tree_view_real_set_cursor (tree_view, path, CLEAR_AND_SELECT | CLAMP_NODE);
|
||||
}
|
||||
|
||||
tree_view->priv->modify_selection_pressed = FALSE;
|
||||
tree_view->priv->extend_selection_pressed = FALSE;
|
||||
}
|
||||
|
||||
if (n_press == 2 || (n_press == 1 && tree_view->priv->activate_on_single_click))
|
||||
gtk_tree_view_row_activated (tree_view, path, column);
|
||||
else
|
||||
{
|
||||
if (n_press == 1)
|
||||
{
|
||||
tree_view->priv->button_pressed_node = tree_view->priv->prelight_node;
|
||||
tree_view->priv->button_pressed_tree = tree_view->priv->prelight_tree;
|
||||
}
|
||||
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
}
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_drag_gesture_begin (GtkGestureDrag *gesture,
|
||||
gdouble start_x,
|
||||
@ -3217,253 +3444,6 @@ gtk_tree_view_column_drag_gesture_begin (GtkGestureDrag *gesture,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tree_view_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
|
||||
GList *list;
|
||||
GdkRectangle background_area;
|
||||
GdkRectangle cell_area;
|
||||
gint vertical_separator;
|
||||
gint horizontal_separator;
|
||||
gboolean path_is_selectable;
|
||||
|
||||
gtk_tree_view_stop_editing (tree_view, FALSE);
|
||||
gtk_widget_style_get (widget,
|
||||
"vertical-separator", &vertical_separator,
|
||||
"horizontal-separator", &horizontal_separator,
|
||||
NULL);
|
||||
|
||||
/* Don't handle extra mouse buttons events, let them bubble up */
|
||||
if (event->button > 5)
|
||||
return FALSE;
|
||||
|
||||
/* Because grab_focus can cause reentrancy, we delay grab_focus until after
|
||||
* we're done handling the button press.
|
||||
*/
|
||||
|
||||
if (event->window == tree_view->priv->bin_window)
|
||||
{
|
||||
GtkRBNode *node;
|
||||
GtkRBTree *tree;
|
||||
GtkTreePath *path;
|
||||
gint depth;
|
||||
gint new_y;
|
||||
gint y_offset;
|
||||
GtkTreeViewColumn *column = NULL;
|
||||
gboolean rtl;
|
||||
GdkModifierType extend_mod_mask;
|
||||
GdkModifierType modify_mod_mask;
|
||||
|
||||
/* Empty tree? */
|
||||
if (tree_view->priv->tree == NULL)
|
||||
{
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* are we in an arrow? */
|
||||
if (tree_view->priv->prelight_node &&
|
||||
tree_view->priv->arrow_prelit &&
|
||||
gtk_tree_view_draw_expanders (tree_view))
|
||||
{
|
||||
if (event->button == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
tree_view->priv->button_pressed_node = tree_view->priv->prelight_node;
|
||||
tree_view->priv->button_pressed_tree = tree_view->priv->prelight_tree;
|
||||
gtk_tree_view_queue_draw_arrow (GTK_TREE_VIEW (widget),
|
||||
tree_view->priv->prelight_tree,
|
||||
tree_view->priv->prelight_node);
|
||||
}
|
||||
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* find the node that was clicked */
|
||||
new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, event->y);
|
||||
if (new_y < 0)
|
||||
new_y = 0;
|
||||
y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
/* We clicked in dead space */
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Get the path and the node */
|
||||
path = _gtk_tree_path_new_from_rbtree (tree, node);
|
||||
path_is_selectable = !row_is_separator (tree_view, NULL, path);
|
||||
|
||||
if (!path_is_selectable)
|
||||
{
|
||||
gtk_tree_path_free (path);
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
depth = gtk_tree_path_get_depth (path);
|
||||
background_area.y = y_offset + event->y;
|
||||
background_area.height = gtk_tree_view_get_row_height (tree_view, node);
|
||||
background_area.x = 0;
|
||||
|
||||
|
||||
/* Let the column have a chance at selecting it. */
|
||||
rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
|
||||
for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
|
||||
list; list = (rtl ? list->prev : list->next))
|
||||
{
|
||||
GtkTreeViewColumn *candidate = list->data;
|
||||
|
||||
if (!gtk_tree_view_column_get_visible (candidate))
|
||||
continue;
|
||||
|
||||
background_area.width = gtk_tree_view_column_get_width (candidate);
|
||||
if ((background_area.x > (gint) event->x) ||
|
||||
(background_area.x + background_area.width <= (gint) event->x))
|
||||
{
|
||||
background_area.x += background_area.width;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we found the focus column */
|
||||
column = candidate;
|
||||
cell_area = background_area;
|
||||
cell_area.width -= horizontal_separator;
|
||||
cell_area.height -= vertical_separator;
|
||||
cell_area.x += horizontal_separator/2;
|
||||
cell_area.y += vertical_separator/2;
|
||||
if (gtk_tree_view_is_expander_column (tree_view, column))
|
||||
{
|
||||
if (!rtl)
|
||||
cell_area.x += (depth - 1) * tree_view->priv->level_indentation;
|
||||
cell_area.width -= (depth - 1) * tree_view->priv->level_indentation;
|
||||
|
||||
if (gtk_tree_view_draw_expanders (tree_view))
|
||||
{
|
||||
gint expander_size = gtk_tree_view_get_expander_size (tree_view);
|
||||
if (!rtl)
|
||||
cell_area.x += depth * expander_size;
|
||||
cell_area.width -= depth * expander_size;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (column == NULL)
|
||||
{
|
||||
gtk_tree_path_free (path);
|
||||
grab_focus_and_unset_draw_keyfocus (tree_view);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_gtk_tree_view_set_focus_column (tree_view, column);
|
||||
|
||||
/* decide if we edit */
|
||||
if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY &&
|
||||
!(event->state & gtk_accelerator_get_default_mod_mask ()))
|
||||
{
|
||||
GtkTreePath *anchor;
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
|
||||
gtk_tree_view_column_cell_set_cell_data (column,
|
||||
tree_view->priv->model,
|
||||
&iter,
|
||||
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT),
|
||||
node->children?TRUE:FALSE);
|
||||
|
||||
if (tree_view->priv->anchor)
|
||||
anchor = gtk_tree_row_reference_get_path (tree_view->priv->anchor);
|
||||
else
|
||||
anchor = NULL;
|
||||
|
||||
if ((anchor && !gtk_tree_path_compare (anchor, path))
|
||||
|| !_gtk_tree_view_column_has_editable_cell (column))
|
||||
{
|
||||
GtkCellEditable *cell_editable = NULL;
|
||||
|
||||
/* FIXME: get the right flags */
|
||||
guint flags = 0;
|
||||
|
||||
if (_gtk_tree_view_column_cell_event (column,
|
||||
(GdkEvent *)event,
|
||||
&cell_area, flags))
|
||||
{
|
||||
GtkCellArea *area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column));
|
||||
cell_editable = gtk_cell_area_get_edit_widget (area);
|
||||
|
||||
if (cell_editable != NULL)
|
||||
{
|
||||
gtk_tree_path_free (path);
|
||||
gtk_tree_path_free (anchor);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (anchor)
|
||||
gtk_tree_path_free (anchor);
|
||||
}
|
||||
|
||||
extend_mod_mask =
|
||||
gtk_widget_get_modifier_mask (widget, GDK_MODIFIER_INTENT_EXTEND_SELECTION);
|
||||
|
||||
modify_mod_mask =
|
||||
gtk_widget_get_modifier_mask (widget, GDK_MODIFIER_INTENT_MODIFY_SELECTION);
|
||||
|
||||
/* we only handle selection modifications on the first button press
|
||||
*/
|
||||
if (event->type == GDK_BUTTON_PRESS)
|
||||
{
|
||||
GtkCellRenderer *focus_cell;
|
||||
|
||||
if ((event->state & modify_mod_mask) == modify_mod_mask)
|
||||
tree_view->priv->modify_selection_pressed = TRUE;
|
||||
if ((event->state & extend_mod_mask) == extend_mod_mask)
|
||||
tree_view->priv->extend_selection_pressed = TRUE;
|
||||
|
||||
/* We update the focus cell here, this is also needed if the
|
||||
* column does not contain an editable cell. In this case,
|
||||
* GtkCellArea did not receive the event for processing (and
|
||||
* could not update the focus cell).
|
||||
*/
|
||||
focus_cell = _gtk_tree_view_column_get_cell_at_pos (column,
|
||||
&cell_area,
|
||||
&background_area,
|
||||
event->x,
|
||||
event->y);
|
||||
|
||||
if (focus_cell)
|
||||
gtk_tree_view_column_focus_cell (column, focus_cell);
|
||||
|
||||
if (event->state & modify_mod_mask)
|
||||
{
|
||||
gtk_tree_view_real_set_cursor (tree_view, path, CLAMP_NODE);
|
||||
gtk_tree_view_real_toggle_cursor_row (tree_view);
|
||||
}
|
||||
else if (event->state & extend_mod_mask)
|
||||
{
|
||||
gtk_tree_view_real_set_cursor (tree_view, path, CLAMP_NODE);
|
||||
gtk_tree_view_real_select_cursor_row (tree_view, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_tree_view_real_set_cursor (tree_view, path, CLEAR_AND_SELECT | CLAMP_NODE);
|
||||
}
|
||||
|
||||
tree_view->priv->modify_selection_pressed = FALSE;
|
||||
tree_view->priv->extend_selection_pressed = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* column drag gesture helper */
|
||||
static gboolean
|
||||
gtk_tree_view_button_release_drag_column (GtkTreeView *tree_view)
|
||||
@ -3581,61 +3561,55 @@ gtk_tree_view_drag_gesture_end (GtkGestureDrag *gesture,
|
||||
gtk_tree_view_stop_rubber_band (tree_view);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
button_event_modifies_selection (GdkEventButton *event)
|
||||
static void
|
||||
gtk_tree_view_multipress_gesture_released (GtkGestureMultiPress *gesture,
|
||||
gint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkTreeView *tree_view)
|
||||
{
|
||||
return (event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) != 0;
|
||||
}
|
||||
gboolean modify, extend;
|
||||
guint button;
|
||||
|
||||
static gboolean
|
||||
gtk_tree_view_button_release (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
|
||||
button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
|
||||
|
||||
if (tree_view->priv->pressed_button == event->button)
|
||||
tree_view->priv->pressed_button = -1;
|
||||
if (button != GDK_BUTTON_PRIMARY ||
|
||||
tree_view->priv->button_pressed_node == NULL ||
|
||||
tree_view->priv->button_pressed_node != tree_view->priv->prelight_node)
|
||||
return;
|
||||
|
||||
if (tree_view->priv->button_pressed_node == NULL)
|
||||
return FALSE;
|
||||
get_current_selection_modifiers (GTK_WIDGET (tree_view), &modify, &extend);
|
||||
|
||||
if (event->button == GDK_BUTTON_PRIMARY
|
||||
&& tree_view->priv->button_pressed_node == tree_view->priv->prelight_node)
|
||||
if (tree_view->priv->arrow_prelit)
|
||||
{
|
||||
if (tree_view->priv->arrow_prelit)
|
||||
{
|
||||
GtkTreePath *path = NULL;
|
||||
GtkTreePath *path = NULL;
|
||||
|
||||
path = _gtk_tree_path_new_from_rbtree (tree_view->priv->button_pressed_tree,
|
||||
tree_view->priv->button_pressed_node);
|
||||
/* Actually activate the node */
|
||||
if (tree_view->priv->button_pressed_node->children == NULL)
|
||||
gtk_tree_view_real_expand_row (tree_view, path,
|
||||
tree_view->priv->button_pressed_tree,
|
||||
tree_view->priv->button_pressed_node,
|
||||
FALSE, TRUE);
|
||||
else
|
||||
gtk_tree_view_real_collapse_row (GTK_TREE_VIEW (widget), path,
|
||||
tree_view->priv->button_pressed_tree,
|
||||
tree_view->priv->button_pressed_node, TRUE);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
else if (tree_view->priv->activate_on_single_click
|
||||
&& !button_event_modifies_selection (event))
|
||||
{
|
||||
GtkTreePath *path = NULL;
|
||||
path = _gtk_tree_path_new_from_rbtree (tree_view->priv->button_pressed_tree,
|
||||
tree_view->priv->button_pressed_node);
|
||||
/* Actually activate the node */
|
||||
if (tree_view->priv->button_pressed_node->children == NULL)
|
||||
gtk_tree_view_real_expand_row (tree_view, path,
|
||||
tree_view->priv->button_pressed_tree,
|
||||
tree_view->priv->button_pressed_node,
|
||||
FALSE, TRUE);
|
||||
else
|
||||
gtk_tree_view_real_collapse_row (tree_view, path,
|
||||
tree_view->priv->button_pressed_tree,
|
||||
tree_view->priv->button_pressed_node, TRUE);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
else if (tree_view->priv->activate_on_single_click && !modify && !extend)
|
||||
{
|
||||
GtkTreePath *path = NULL;
|
||||
|
||||
path = _gtk_tree_path_new_from_rbtree (tree_view->priv->button_pressed_tree,
|
||||
tree_view->priv->button_pressed_node);
|
||||
gtk_tree_view_row_activated (tree_view, path, tree_view->priv->focus_column);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
tree_view->priv->button_pressed_tree = NULL;
|
||||
tree_view->priv->button_pressed_node = NULL;
|
||||
path = _gtk_tree_path_new_from_rbtree (tree_view->priv->button_pressed_tree,
|
||||
tree_view->priv->button_pressed_node);
|
||||
gtk_tree_view_row_activated (tree_view, path, tree_view->priv->focus_column);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
tree_view->priv->button_pressed_tree = NULL;
|
||||
tree_view->priv->button_pressed_node = NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -12992,8 +12966,7 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
|
||||
selection_changed = gtk_tree_view_unref_and_check_selection_tree (tree_view, node->children);
|
||||
|
||||
/* Stop a pending double click */
|
||||
tree_view->priv->last_button_x = -1;
|
||||
tree_view->priv->last_button_y = -1;
|
||||
gtk_event_controller_reset (GTK_EVENT_CONTROLLER (tree_view->priv->multipress_gesture));
|
||||
|
||||
_gtk_tree_view_accessible_remove (tree_view, node->children, NULL);
|
||||
_gtk_tree_view_accessible_remove_state (tree_view,
|
||||
@ -15236,9 +15209,6 @@ gtk_tree_view_search_button_press_event (GtkWidget *widget,
|
||||
keyb_device = gdk_device_get_associated_device (event->device);
|
||||
gtk_tree_view_search_dialog_hide (widget, tree_view, keyb_device);
|
||||
|
||||
if (event->window == tree_view->priv->bin_window)
|
||||
gtk_tree_view_button_press (GTK_WIDGET (tree_view), event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user