diff options
author | Jasper St. Pierre <jstpierre@mecheye.net> | 2013-08-22 13:20:10 -0400 |
---|---|---|
committer | Jasper St. Pierre <jstpierre@mecheye.net> | 2013-08-26 19:06:07 -0400 |
commit | 6553b8beeeab2db526eeebf304ec80bd521074f5 (patch) | |
tree | 29c8099357cbf9180bcb1cfe439a150589058851 | |
parent | 59d35057e1cd8119db5c94747e7b6d271fdda5bb (diff) | |
download | gtk+-wip/opaque-region.tar.gz |
opaquewip/opaque-region
-rw-r--r-- | gtk/gtkwindow.c | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 434b2fee1f..861dc8134a 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -35,6 +35,8 @@ #include "gtkwindowprivate.h" #include "gtkaccelgroupprivate.h" #include "gtkbindings.h" +#include "gtkcsscornervalueprivate.h" +#include "gtkcssrgbavalueprivate.h" #include "gtkcssshadowsvalueprivate.h" #include "gtkkeyhash.h" #include "gtkmain.h" @@ -6462,6 +6464,80 @@ update_frame_extents (GtkWindow *window, #endif } +static void +corner_rect (cairo_rectangle_int_t *rect, + const GtkCssValue *value) +{ + rect->width = _gtk_css_corner_value_get_x (value, 100); + rect->height = _gtk_css_corner_value_get_y (value, 100); +} + +static void +subtract_corners_from_region (cairo_region_t *region, + cairo_rectangle_int_t *extents, + GtkStyleContext *context) +{ + cairo_rectangle_int_t rect; + + corner_rect (&rect, _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS)); + rect.x = extents->x; + rect.y = extents->y; + cairo_region_subtract_rectangle (region, &rect); + + corner_rect (&rect, _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS)); + rect.x = extents->x + extents->width - rect.width; + rect.y = extents->y; + cairo_region_subtract_rectangle (region, &rect); + + corner_rect (&rect, _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS)); + rect.x = extents->x; + rect.y = extents->y + extents->height - rect.height; + cairo_region_subtract_rectangle (region, &rect); + + corner_rect (&rect, _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS)); + rect.x = extents->x + extents->width - rect.width; + rect.y = extents->y + extents->height - rect.height; + cairo_region_subtract_rectangle (region, &rect); +} + +static void +update_opaque_region (GtkWindow *window, + GtkBorder *border, + const GtkAllocation *allocation) +{ + const GdkRGBA *color; + cairo_region_t *opaque_region; + GtkStyleContext *context; + + if (!gtk_widget_get_realized (GTK_WIDGET (window))) + return; + + context = gtk_widget_get_style_context (GTK_WIDGET (window)); + color = _gtk_css_rgba_value_get_rgba (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BACKGROUND_COLOR)); + + if (color->alpha >= 1.0) + { + cairo_rectangle_int_t rect; + + rect.x = border->left; + rect.y = border->top; + rect.width = allocation->width - border->left - border->right; + rect.height = allocation->height - border->top - border->bottom; + + opaque_region = cairo_region_create_rectangle (&rect); + + subtract_corners_from_region (opaque_region, &rect, context); + } + else + { + opaque_region = NULL; + } + + gdk_window_set_opaque_region (gtk_widget_get_window (GTK_WIDGET (window)), opaque_region); + + cairo_region_destroy (opaque_region); +} + /* _gtk_window_set_allocation: * @window: a #GtkWindow * @allocation: the original allocation for the window @@ -6508,7 +6584,10 @@ _gtk_window_set_allocation (GtkWindow *window, priv->title_height = 0; if (priv->client_decorated) - update_frame_extents (window, &window_border); + { + update_frame_extents (window, &window_border); + update_opaque_region (window, &window_border, &child_allocation); + } if (priv->title_box != NULL && priv->decorated && |