diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c index 557d9fdac2..b8e87094b2 100644 --- a/gtk/gtkbox.c +++ b/gtk/gtkbox.c @@ -791,6 +791,8 @@ gtk_box_size_allocate_no_center (GtkWidget *widget, i++; } } + + _gtk_widget_set_simple_clip (widget); } static void @@ -1158,6 +1160,8 @@ gtk_box_size_allocate_with_center (GtkWidget *widget, child_allocation.height = center_size; } gtk_widget_size_allocate_with_baseline (priv->center->widget, &child_allocation, baseline); + + _gtk_widget_set_simple_clip (widget); } static void diff --git a/gtk/gtkgrid.c b/gtk/gtkgrid.c index 5c93571ccf..98080fccbc 100644 --- a/gtk/gtkgrid.c +++ b/gtk/gtkgrid.c @@ -24,6 +24,7 @@ #include "gtkorientableprivate.h" #include "gtksizerequest.h" +#include "gtkwidgetprivate.h" #include "gtkprivate.h" #include "gtkintl.h" @@ -1677,6 +1678,8 @@ gtk_grid_size_allocate (GtkWidget *widget, gtk_grid_request_position (&request, 1); gtk_grid_request_allocate_children (&request); + + _gtk_widget_set_simple_clip (widget); } static gboolean diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index acb7316517..70dd74eb1f 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -15414,6 +15414,49 @@ _gtk_widget_supports_clip (GtkWidget *widget) return widget->priv->supports_clip; } +static void +union_with_clip (GtkWidget *widget, + gpointer clip) +{ + GtkAllocation widget_clip; + + if (!gtk_widget_is_drawable (widget)) + return; + + gtk_widget_get_clip (widget, &widget_clip); + + gdk_rectangle_union (&widget_clip, clip, clip); +} + +/** + * _gtk_widget_set_simple_clip: + * @widget: + * + * This is a convenience function for gtk_widget_set_clip(), if you + * just want to set the clip for @widget based on its allocation, + * CSS properties and - if the widget is a #GtkContainer - its + * children. gtk_widget_set_allocation() must have been called + * and all children must have been allocated with + * gtk_widget_size_allocate() before calling this function. It is + * therefor a good idea to call this function last in your + * implementation of GtkWidget::size_allocate(). + * + * If your widget overdraws its contents, you cannot use this + * function and must call gtk_widget_set_clip() yourself. + **/ +void +_gtk_widget_set_simple_clip (GtkWidget *widget) +{ + GtkAllocation clip; + + gtk_widget_get_allocation (widget, &clip); + + if (GTK_IS_CONTAINER (widget)) + gtk_container_forall (GTK_CONTAINER (widget), union_with_clip, &clip); + + gtk_widget_set_clip (widget, &clip); +} + /** * gtk_widget_get_allocation: * @widget: a #GtkWidget diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index 8f2a9d5ecc..ebb06099e7 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -133,7 +133,8 @@ void _gtk_widget_buildable_finish_accelerator (GtkWidget *widget, GtkStyle * _gtk_widget_get_style (GtkWidget *widget); void _gtk_widget_set_style (GtkWidget *widget, GtkStyle *style); -gboolean _gtk_widget_supports_clip (GtkWidget *widget); +gboolean _gtk_widget_supports_clip (GtkWidget *widget); +void _gtk_widget_set_simple_clip (GtkWidget *widget); typedef gboolean (*GtkCapturedEventHandler) (GtkWidget *widget, GdkEvent *event);