diff --git a/gtk/gtkgridview.c b/gtk/gtkgridview.c index 6ee96d9df5..17b0ca5a36 100644 --- a/gtk/gtkgridview.c +++ b/gtk/gtkgridview.c @@ -204,7 +204,7 @@ cell_augment (GtkRbTree *tree, * index of the returned row * @offset: (out caller-allocates) (optional): stores the offset * in pixels between y and top of cell. - * @offset: (out caller-allocates) (optional): stores the height + * @size: (out caller-allocates) (optional): stores the height * of the cell * * Gets the Cell that occupies the leftmost position in the row at offset @@ -413,6 +413,19 @@ gtk_grid_view_get_allocation_across (GtkListBase *base, return TRUE; } +static int +gtk_grid_view_compute_total_height (GtkGridView *self) +{ + Cell *cell; + CellAugment *aug; + + cell = gtk_list_item_manager_get_root (self->item_manager); + if (cell == NULL) + return 0; + aug = gtk_list_item_manager_get_item_augment (self->item_manager, cell); + return aug->size; +} + static gboolean gtk_grid_view_get_position_from_allocation (GtkListBase *base, int across, @@ -428,6 +441,7 @@ gtk_grid_view_get_position_from_allocation (GtkListBase *base, return FALSE; n_items = gtk_list_base_get_n_items (base); + along = CLAMP (along, 0, gtk_grid_view_compute_total_height (self) - 1); if (!gtk_grid_view_get_cell_at_y (self, along, &pos, @@ -467,16 +481,19 @@ gtk_grid_view_get_items_in_rect (GtkListBase *base, result = gtk_bitset_new_empty (); + if (rect->y >= gtk_grid_view_compute_total_height (self)) + return result; + n_items = gtk_list_base_get_n_items (base); if (n_items == 0) return result; - first_column = floor (rect->x / self->column_width); - last_column = floor ((rect->x + rect->width) / self->column_width); + first_column = fmax (floor (rect->x / self->column_width), 0); + last_column = fmin (floor ((rect->x + rect->width) / self->column_width), self->n_columns - 1); if (!gtk_grid_view_get_cell_at_y (self, rect->y, &first_row, NULL, NULL)) first_row = rect->y < 0 ? 0 : n_items - 1; if (!gtk_grid_view_get_cell_at_y (self, rect->y + rect->height, &last_row, NULL, NULL)) - last_row = rect->y < 0 ? 0 : n_items - 1; + last_row = rect->y + rect->height < 0 ? 0 : n_items - 1; gtk_bitset_add_rectangle (result, first_row + first_column, @@ -722,19 +739,6 @@ cell_set_size (Cell *cell, gtk_rb_tree_node_mark_dirty (cell); } -static int -gtk_grid_view_compute_total_height (GtkGridView *self) -{ - Cell *cell; - CellAugment *aug; - - cell = gtk_list_item_manager_get_root (self->item_manager); - if (cell == NULL) - return 0; - aug = gtk_list_item_manager_get_item_augment (self->item_manager, cell); - return aug->size; -} - static void gtk_grid_view_size_allocate (GtkWidget *widget, int width, diff --git a/gtk/gtklistbase.c b/gtk/gtklistbase.c index b5d0d35a7a..86f408a562 100644 --- a/gtk/gtklistbase.c +++ b/gtk/gtklistbase.c @@ -1583,25 +1583,28 @@ gtk_list_base_stop_rubberband (GtkListBase *self, return; rubberband_selection = gtk_list_base_get_items_in_rect (self, &rect); - if (gtk_bitset_is_empty (rubberband_selection)) - { - gtk_bitset_unref (rubberband_selection); - return; - } if (modify && extend) /* Ctrl + Shift */ { - GtkBitset *current; - guint min = gtk_bitset_get_minimum (rubberband_selection); - guint max = gtk_bitset_get_maximum (rubberband_selection); - /* toggle the rubberband, keep the rest */ - current = gtk_selection_model_get_selection_in_range (model, min, max - min + 1); - selected = gtk_bitset_copy (current); - gtk_bitset_unref (current); - gtk_bitset_intersect (selected, rubberband_selection); - gtk_bitset_difference (selected, rubberband_selection); + if (gtk_bitset_is_empty (rubberband_selection)) + { + selected = gtk_bitset_ref (rubberband_selection); + mask = gtk_bitset_ref (rubberband_selection); + } + else + { + GtkBitset *current; + guint min = gtk_bitset_get_minimum (rubberband_selection); + guint max = gtk_bitset_get_maximum (rubberband_selection); + /* toggle the rubberband, keep the rest */ + current = gtk_selection_model_get_selection_in_range (model, min, max - min + 1); + selected = gtk_bitset_copy (current); + gtk_bitset_unref (current); + gtk_bitset_intersect (selected, rubberband_selection); + gtk_bitset_difference (selected, rubberband_selection); - mask = gtk_bitset_ref (rubberband_selection); + mask = gtk_bitset_ref (rubberband_selection); + } } else if (modify) /* Ctrl */ { diff --git a/gtk/gtklistview.c b/gtk/gtklistview.c index 69b822b316..b81ad3f23a 100644 --- a/gtk/gtklistview.c +++ b/gtk/gtklistview.c @@ -377,6 +377,9 @@ gtk_list_view_get_items_in_rect (GtkListBase *base, result = gtk_bitset_new_empty (); + if (rect->y >= gtk_list_view_get_list_height (self)) + return result; + n_items = gtk_list_base_get_n_items (base); if (n_items == 0) return result; @@ -390,7 +393,7 @@ gtk_list_view_get_items_in_rect (GtkListBase *base, if (row) last = gtk_list_item_manager_get_item_position (self->item_manager, row); else - last = rect->y < 0 ? 0 : n_items - 1; + last = rect->y + rect->height < 0 ? 0 : n_items - 1; gtk_bitset_add_range_closed (result, first, last); return result; @@ -425,6 +428,8 @@ gtk_list_view_get_position_from_allocation (GtkListBase *base, if (across >= self->list_width) return FALSE; + along = CLAMP (along, 0, gtk_list_view_get_list_height (self) - 1); + row = gtk_list_view_get_row_at_y (self, along, &remaining); if (row == NULL) return FALSE;