diff --git a/gtk/gtklistbase.c b/gtk/gtklistbase.c index bf0657a04f..81c95d1a4d 100644 --- a/gtk/gtklistbase.c +++ b/gtk/gtklistbase.c @@ -37,6 +37,13 @@ #include "gtktypebuiltins.h" #include "gtkwidgetprivate.h" +/* Allow shadows to overdraw without immediately culling the widget at the viewport + * boundary. + * Choose this so that roughly 1 extra widget gets drawn on each side of the viewport, + * but not more. Icons are 16px, text height is somewhere there, too. + */ +#define GTK_LIST_BASE_CHILD_MAX_OVERDRAW 10 + typedef struct _RubberbandData RubberbandData; struct _RubberbandData @@ -1351,6 +1358,22 @@ gtk_list_base_size_allocate_child (GtkListBase *self, int height) { GtkAllocation child_allocation; + int self_width, self_height; + + self_width = gtk_widget_get_width (GTK_WIDGET (self)); + self_height = gtk_widget_get_height (GTK_WIDGET (self)); + + if (y + height + GTK_LIST_BASE_CHILD_MAX_OVERDRAW <= 0 || + y - GTK_LIST_BASE_CHILD_MAX_OVERDRAW >= self_height || + x + width + GTK_LIST_BASE_CHILD_MAX_OVERDRAW <= 0 || + x - GTK_LIST_BASE_CHILD_MAX_OVERDRAW >= self_width) + { + /* child is fully outside the viewport, hide it and don't allocate it */ + gtk_widget_set_child_visible (child, FALSE); + return; + } + + gtk_widget_set_child_visible (child, TRUE); if (gtk_list_base_get_orientation (GTK_LIST_BASE (self)) == GTK_ORIENTATION_VERTICAL) { @@ -1363,9 +1386,7 @@ gtk_list_base_size_allocate_child (GtkListBase *self, } else { - int mirror_point = gtk_widget_get_width (GTK_WIDGET (self)); - - child_allocation.x = mirror_point - x - width; + child_allocation.x = self_width - x - width; child_allocation.y = y; child_allocation.width = width; child_allocation.height = height; @@ -1382,9 +1403,7 @@ gtk_list_base_size_allocate_child (GtkListBase *self, } else { - int mirror_point = gtk_widget_get_width (GTK_WIDGET (self)); - - child_allocation.x = mirror_point - y - height; + child_allocation.x = self_width - y - height; child_allocation.y = x; child_allocation.width = height; child_allocation.height = width;