listview: Fix culling issues when using CSS padding

We were culling children based on the content box, but clipping via
overflow happens on the padding box, so we need to use that one instead.

Fixes issues with items not being visible / disappearing in Nautilus
when they are near the border.

Resolves #5380
This commit is contained in:
Benjamin Otte
2023-03-16 21:27:35 +01:00
parent ef3c515cf1
commit a0382ef495

View File

@@ -23,6 +23,7 @@
#include "gtkadjustment.h" #include "gtkadjustment.h"
#include "gtkbitset.h" #include "gtkbitset.h"
#include "gtkcssboxesprivate.h"
#include "gtkcssnodeprivate.h" #include "gtkcssnodeprivate.h"
#include "gtkcsspositionvalueprivate.h" #include "gtkcsspositionvalueprivate.h"
#include "gtkdragsourceprivate.h" #include "gtkdragsourceprivate.h"
@@ -1324,6 +1325,8 @@ update_autoscroll (GtkListBase *self,
/* /*
* gtk_list_base_size_allocate_child: * gtk_list_base_size_allocate_child:
* @self: The listbase * @self: The listbase
* @boxes: The CSS boxes of @self to allow for proper
* clipping
* @child: The child * @child: The child
* @x: top left coordinate in the across direction * @x: top left coordinate in the across direction
* @y: top right coordinate in the along direction * @y: top right coordinate in the along direction
@@ -1336,6 +1339,7 @@ update_autoscroll (GtkListBase *self,
**/ **/
static void static void
gtk_list_base_size_allocate_child (GtkListBase *self, gtk_list_base_size_allocate_child (GtkListBase *self,
GtkCssBoxes *boxes,
GtkWidget *child, GtkWidget *child,
int x, int x,
int y, int y,
@@ -1343,10 +1347,9 @@ gtk_list_base_size_allocate_child (GtkListBase *self,
int height) int height)
{ {
GtkAllocation child_allocation; GtkAllocation child_allocation;
int self_width, self_height; int self_width;
self_width = gtk_widget_get_width (GTK_WIDGET (self)); self_width = gtk_widget_get_width (GTK_WIDGET (self));
self_height = gtk_widget_get_height (GTK_WIDGET (self));
if (gtk_list_base_get_orientation (GTK_LIST_BASE (self)) == GTK_ORIENTATION_VERTICAL) if (gtk_list_base_get_orientation (GTK_LIST_BASE (self)) == GTK_ORIENTATION_VERTICAL)
{ {
@@ -1379,14 +1382,14 @@ gtk_list_base_size_allocate_child (GtkListBase *self,
child_allocation.height = width; child_allocation.height = width;
} }
if (!gdk_rectangle_intersect (&child_allocation, if (!graphene_rect_intersection (gtk_css_boxes_get_padding_rect (boxes),
&(GdkRectangle) { &GRAPHENE_RECT_INIT(
- GTK_LIST_BASE_CHILD_MAX_OVERDRAW, child_allocation.x + GTK_LIST_BASE_CHILD_MAX_OVERDRAW,
- GTK_LIST_BASE_CHILD_MAX_OVERDRAW, child_allocation.y + GTK_LIST_BASE_CHILD_MAX_OVERDRAW,
self_width + GTK_LIST_BASE_CHILD_MAX_OVERDRAW, child_allocation.width + 2 * GTK_LIST_BASE_CHILD_MAX_OVERDRAW,
self_height + GTK_LIST_BASE_CHILD_MAX_OVERDRAW child_allocation.height + 2 * GTK_LIST_BASE_CHILD_MAX_OVERDRAW
}, ),
NULL)) NULL))
{ {
/* child is fully outside the viewport, hide it and don't allocate it */ /* child is fully outside the viewport, hide it and don't allocate it */
gtk_widget_set_child_visible (child, FALSE); gtk_widget_set_child_visible (child, FALSE);
@@ -1399,7 +1402,8 @@ gtk_list_base_size_allocate_child (GtkListBase *self,
} }
static void static void
gtk_list_base_allocate_children (GtkListBase *self) gtk_list_base_allocate_children (GtkListBase *self,
GtkCssBoxes *boxes)
{ {
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self); GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
GtkListTile *tile; GtkListTile *tile;
@@ -1415,6 +1419,7 @@ gtk_list_base_allocate_children (GtkListBase *self)
if (tile->widget) if (tile->widget)
{ {
gtk_list_base_size_allocate_child (GTK_LIST_BASE (self), gtk_list_base_size_allocate_child (GTK_LIST_BASE (self),
boxes,
tile->widget, tile->widget,
tile->area.x - dx, tile->area.x - dx,
tile->area.y - dy, tile->area.y - dy,
@@ -1511,7 +1516,8 @@ gtk_list_base_get_rubberband_coords (GtkListBase *self,
} }
static void static void
gtk_list_base_allocate_rubberband (GtkListBase *self) gtk_list_base_allocate_rubberband (GtkListBase *self,
GtkCssBoxes *boxes)
{ {
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self); GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
GtkRequisition min_size; GtkRequisition min_size;
@@ -1531,6 +1537,7 @@ gtk_list_base_allocate_rubberband (GtkListBase *self)
rect.y -= offset_y; rect.y -= offset_y;
gtk_list_base_size_allocate_child (self, gtk_list_base_size_allocate_child (self,
boxes,
priv->rubberband->widget, priv->rubberband->widget,
rect.x, rect.y, rect.width, rect.height); rect.x, rect.y, rect.width, rect.height);
} }
@@ -1974,10 +1981,14 @@ gtk_list_base_update_adjustments (GtkListBase *self)
void void
gtk_list_base_allocate (GtkListBase *self) gtk_list_base_allocate (GtkListBase *self)
{ {
GtkCssBoxes boxes;
gtk_css_boxes_init (&boxes, GTK_WIDGET (self));
gtk_list_base_update_adjustments (self); gtk_list_base_update_adjustments (self);
gtk_list_base_allocate_children (self); gtk_list_base_allocate_children (self, &boxes);
gtk_list_base_allocate_rubberband (self); gtk_list_base_allocate_rubberband (self, &boxes);
} }
GtkScrollablePolicy GtkScrollablePolicy