[gtk+] window: rework the CSD theming layer
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] window: rework the CSD theming layer
- Date: Mon, 22 Apr 2013 22:12:12 +0000 (UTC)
commit 7bbbb01ff521065c10d41185cc64f2823a5a6c9c
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Mon Apr 22 17:28:23 2013 -0400
window: rework the CSD theming layer
Instead of having three different boxes and style classes, we can just
get away with the regular background box, plus a window-frame, which
contains the external frame, together with the window drop shadows.
GtkWindow now has special code to ensure the backing actual window is
allocated big enough to accomodate the shadows (using the shadow size
calculations introduced in the previous commit). We also use the margin
value to determine the size of the invisible borders (which can then be
different than the shadow).
gtk/gtkwindow.c | 255 +++++++++++++++++++++++++++++---------------------------
1 file changed, 133 insertions(+), 122 deletions(-)
---
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index c4086e7..fe00a5c 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -35,6 +35,7 @@
#include "gtkwindowprivate.h"
#include "gtkaccelgroupprivate.h"
#include "gtkbindings.h"
+#include "gtkcssshadowsvalueprivate.h"
#include "gtkkeyhash.h"
#include "gtkmain.h"
#include "gtkmnemonichash.h"
@@ -6067,68 +6068,65 @@ set_grip_position (GtkWindow *window)
}
static void
-get_decoration_borders (GtkWidget *widget,
- GtkBorder *window_border,
- GtkBorder *outer_border)
+sum_borders (GtkBorder *one,
+ GtkBorder *two)
{
+ one->top += two->top;
+ one->right += two->right;
+ one->bottom += two->bottom;
+ one->left += two->left;
+}
+
+static void
+get_decoration_size (GtkWidget *widget,
+ GtkBorder *decorations)
+{
+ GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
+ GtkBorder border = { 0 };
+ GtkBorder margin;
GtkStyleContext *context;
GtkStateFlags state;
- GdkWindow *window;
- gboolean maximized = FALSE;
- const GtkBorder empty = { 0 };
- GtkBorder outer;
+ GtkCssValue *shadows;
+
+ *decorations = border;
+ if (!priv->client_decorated)
+ return;
+
+ if (gtk_window_get_maximized (GTK_WINDOW (widget)))
+ return;
+
+ state = gtk_widget_get_state_flags (widget);
context = gtk_widget_get_style_context (widget);
- state = gtk_style_context_get_state (context);
- window = gtk_widget_get_window (widget);
- if (window != NULL)
- maximized = gdk_window_get_state (window) & GDK_WINDOW_STATE_MAXIMIZED;
- if (window_border != NULL)
- {
- if (maximized)
- {
- *window_border = empty;
- }
- else
- {
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, "window-border");
- gtk_style_context_get_border (context, state, window_border);
- gtk_style_context_restore (context);
- }
- }
+ gtk_style_context_save (context);
+ gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BACKGROUND);
+ gtk_style_context_add_class (context, "window-frame");
- if (window_border != NULL || outer_border != NULL)
- {
- if (maximized)
- {
- outer = empty;
- }
- else
- {
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, "window-outer-border");
- gtk_style_context_get_border (context, state, &outer);
- gtk_style_context_restore (context);
- }
+ /* Always sum border + padding */
+ gtk_style_context_get_border (context, state, decorations);
+ gtk_style_context_get_padding (context, state, &border);
+ sum_borders (decorations, &border);
- if (outer_border != NULL)
- {
- *outer_border = outer;
- }
- else
- {
- window_border->left += outer.left;
- window_border->right += outer.right;
- window_border->top += outer.top;
- window_border->bottom += outer.bottom;
- }
- }
+ /* Calculate the size of the drop shadows ... */
+ shadows = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BOX_SHADOW);
+ _gtk_css_shadows_value_get_extents (shadows, &border);
+
+ /* ... and compare it to the margin size, which we use for resize grips */
+ gtk_style_context_get_margin (context, state, &margin);
+
+ border.top = MAX (border.top, margin.top);
+ border.right = MAX (border.right, margin.right);
+ border.bottom = MAX (border.bottom, margin.bottom);
+ border.left = MAX (border.left, margin.left);
+
+ sum_borders (decorations, &border);
+
+ gtk_style_context_restore (context);
}
static void
-update_border_windows (GtkWindow *window, GtkBorder *border)
+update_border_windows (GtkWindow *window)
{
GtkWidget *widget = (GtkWidget *)window;
GtkWindowPrivate *priv = window->priv;
@@ -6137,10 +6135,20 @@ update_border_windows (GtkWindow *window, GtkBorder *border)
cairo_region_t *region;
cairo_rectangle_int_t rect;
gint width, height;
+ GtkBorder border;
+ GtkStyleContext *context;
if (priv->border_window[0] == NULL)
return;
+ context = gtk_widget_get_style_context (widget);
+ gtk_style_context_save (context);
+ gtk_style_context_add_class (context, "window-frame");
+ gtk_style_context_get_margin (context,
+ gtk_widget_get_state_flags (widget),
+ &border);
+ gtk_style_context_restore (context);
+
if (!priv->resizable || gtk_window_get_maximized (window))
{
resize_h = resize_v = FALSE;
@@ -6165,31 +6173,31 @@ update_border_windows (GtkWindow *window, GtkBorder *border)
"decoration-resize-handle", &handle,
NULL);
- width = gtk_widget_get_allocated_width (widget) - (border->left + border->right);
- height = gtk_widget_get_allocated_height (widget) - (border->top + border->bottom);
+ width = gtk_widget_get_allocated_width (widget) - (border.left + border.right);
+ height = gtk_widget_get_allocated_height (widget) - (border.top + border.bottom);
if (resize_h && resize_v)
{
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_NORTH_WEST],
0, 0,
- border->left + handle, border->top + handle);
+ border.left + handle, border.top + handle);
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_NORTH_EAST],
- border->left + width - handle, 0,
- border->right + handle, border->top + handle);
+ border.left + width - handle, 0,
+ border.right + handle, border.top + handle);
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_SOUTH_WEST],
- 0, border->top + height - handle,
- border->left + handle, border->bottom + handle);
+ 0, border.top + height - handle,
+ border.left + handle, border.bottom + handle);
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_SOUTH_EAST],
- border->left + width - handle, border->top + height - handle,
- border->right + handle, border->bottom + handle);
+ border.left + width - handle, border.top + height - handle,
+ border.right + handle, border.bottom + handle);
rect.x = 0;
rect.y = 0;
- rect.width = border->left + handle;
- rect.height = border->top + handle;
+ rect.width = border.left + handle;
+ rect.height = border.top + handle;
region = cairo_region_create_rectangle (&rect);
- rect.x = border->left;
- rect.y = border->top;
+ rect.x = border.left;
+ rect.y = border.top;
rect.width = handle;
rect.height = handle;
cairo_region_subtract_rectangle (region, &rect);
@@ -6199,11 +6207,11 @@ update_border_windows (GtkWindow *window, GtkBorder *border)
rect.x = 0;
rect.y = 0;
- rect.width = border->right + handle;
- rect.height = border->top + handle;
+ rect.width = border.right + handle;
+ rect.height = border.top + handle;
region = cairo_region_create_rectangle (&rect);
rect.x = 0;
- rect.y = border->top;
+ rect.y = border.top;
rect.width = handle;
rect.height = handle;
cairo_region_subtract_rectangle (region, &rect);
@@ -6213,10 +6221,10 @@ update_border_windows (GtkWindow *window, GtkBorder *border)
rect.x = 0;
rect.y = 0;
- rect.width = border->left + handle;
- rect.height = border->bottom + handle;
+ rect.width = border.left + handle;
+ rect.height = border.bottom + handle;
region = cairo_region_create_rectangle (&rect);
- rect.x = border->left;
+ rect.x = border.left;
rect.y = 0;
rect.width = handle;
rect.height = handle;
@@ -6227,8 +6235,8 @@ update_border_windows (GtkWindow *window, GtkBorder *border)
rect.x = 0;
rect.y = 0;
- rect.width = border->right + handle;
- rect.height = border->bottom + handle;
+ rect.width = border.right + handle;
+ rect.height = border.bottom + handle;
region = cairo_region_create_rectangle (&rect);
rect.x = 0;
rect.y = 0;
@@ -6258,21 +6266,21 @@ update_border_windows (GtkWindow *window, GtkBorder *border)
if (resize_h)
{
- x = border->left + handle;
+ x = border.left + handle;
w = width - 2 * handle;
}
else
{
x = 0;
- w = width + border->left + border->right;
+ w = width + border.left + border.right;
}
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_NORTH],
x, 0,
- w, border->top);
+ w, border.top);
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_SOUTH],
- x, border->top + height,
- w, border->bottom);
+ x, border.top + height,
+ w, border.bottom);
gdk_window_show (priv->border_window[GDK_WINDOW_EDGE_NORTH]);
gdk_window_show (priv->border_window[GDK_WINDOW_EDGE_SOUTH]);
@@ -6289,22 +6297,22 @@ update_border_windows (GtkWindow *window, GtkBorder *border)
if (resize_v)
{
- y = border->top + handle;
+ y = border.top + handle;
h = height - 2 * handle;
}
else
{
y = 0;
- h = height + border->top + border->bottom;
+ h = height + border.top + border.bottom;
}
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_WEST],
0, y,
- border->left, h);
+ border.left, h);
gdk_window_move_resize (priv->border_window[GDK_WINDOW_EDGE_EAST],
- border->left + width, y,
- border->right, h);
+ border.left + width, y,
+ border.right, h);
gdk_window_show (priv->border_window[GDK_WINDOW_EDGE_WEST]);
gdk_window_show (priv->border_window[GDK_WINDOW_EDGE_EAST]);
@@ -6352,7 +6360,7 @@ _gtk_window_set_allocation (GtkWindow *window,
gtk_widget_set_allocation (widget, allocation);
- get_decoration_borders (widget, &window_border, NULL);
+ get_decoration_size (widget, &window_border);
border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
child_allocation.x = 0;
@@ -6407,7 +6415,7 @@ _gtk_window_set_allocation (GtkWindow *window,
{
update_grip_visibility (window);
set_grip_position (window);
- update_border_windows (window, &window_border);
+ update_border_windows (window);
}
}
@@ -6554,6 +6562,7 @@ gtk_window_style_updated (GtkWidget *widget)
{
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = window->priv;
+ GdkRGBA transparent = { 0.0, 0.0, 0.0, 0.0 };
GdkRectangle rect;
GTK_WIDGET_CLASS (gtk_window_parent_class)->style_updated (widget);
@@ -6566,6 +6575,13 @@ gtk_window_style_updated (GtkWidget *widget)
set_grip_shape (window);
}
+
+ if (gtk_widget_get_realized (widget))
+ {
+ gdk_window_set_background_rgba (gtk_widget_get_window (widget),
+ &transparent);
+ gtk_widget_queue_resize (widget);
+ }
}
static void
@@ -6783,12 +6799,10 @@ gtk_window_get_resize_grip_area (GtkWindow *window,
g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
- if (!window->priv->has_resize_grip)
+ if (!priv->has_resize_grip)
return FALSE;
- if (priv->client_decorated)
- get_decoration_borders (widget, &window_border, NULL);
-
+ get_decoration_size (widget, &window_border);
gtk_widget_get_allocation (widget, &allocation);
gtk_widget_style_get (widget,
@@ -7449,7 +7463,7 @@ gtk_window_get_preferred_width (GtkWidget *widget,
if (priv->decorated &&
!priv->fullscreen)
{
- get_decoration_borders (widget, &window_border, NULL);
+ get_decoration_size (widget, &window_border);
if (priv->title_box != NULL)
gtk_widget_get_preferred_width (priv->title_box,
@@ -7498,7 +7512,7 @@ gtk_window_get_preferred_width_for_height (GtkWidget *widget,
if (priv->decorated &&
!priv->fullscreen)
{
- get_decoration_borders (widget, &window_border, NULL);
+ get_decoration_size (widget, &window_border);
if (priv->title_box != NULL)
gtk_widget_get_preferred_width_for_height (priv->title_box,
@@ -7551,7 +7565,7 @@ gtk_window_get_preferred_height (GtkWidget *widget,
if (priv->decorated &&
!priv->fullscreen)
{
- get_decoration_borders (widget, &window_border, NULL);
+ get_decoration_size (widget, &window_border);
if (priv->title_box != NULL)
gtk_widget_get_preferred_height (priv->title_box,
@@ -7602,7 +7616,7 @@ gtk_window_get_preferred_height_for_width (GtkWidget *widget,
if (priv->decorated &&
!priv->fullscreen)
{
- get_decoration_borders (widget, &window_border, NULL);
+ get_decoration_size (widget, &window_border);
if (priv->title_box != NULL)
gtk_widget_get_preferred_height_for_width (priv->title_box,
@@ -8827,17 +8841,14 @@ gtk_window_draw (GtkWidget *widget,
GtkStyleContext *context;
gboolean ret = FALSE;
GtkAllocation allocation;
- GtkBorder inner_border = { 0 };
- GtkBorder outer_border = { 0 };
+ GtkBorder window_border;
gint title_height;
context = gtk_widget_get_style_context (widget);
+ get_decoration_size (widget, &window_border);
gtk_widget_get_allocation (widget, &allocation);
- if (priv->client_decorated)
- get_decoration_borders (widget, &inner_border, &outer_border);
-
if (!gtk_widget_get_app_paintable (widget) &&
gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
{
@@ -8848,25 +8859,22 @@ gtk_window_draw (GtkWidget *widget,
{
gtk_style_context_save (context);
- gtk_style_context_add_class (context, "window-border");
+ gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BACKGROUND);
+ gtk_style_context_add_class (context, "window-frame");
+
gtk_render_background (context, cr,
- inner_border.left + outer_border.left,
- inner_border.top + outer_border.top,
+ window_border.left, window_border.top,
allocation.width -
- (inner_border.left + inner_border.right +
- outer_border.left + outer_border.right),
+ (window_border.left + window_border.right),
allocation.height -
- (inner_border.top + inner_border.bottom +
- outer_border.top + outer_border.bottom));
+ (window_border.top + window_border.bottom));
gtk_render_frame (context, cr,
- outer_border.left,
- outer_border.top,
- allocation.width - (outer_border.left + outer_border.right),
- allocation.height - (outer_border.top + outer_border.bottom));
- gtk_style_context_remove_class (context, "window-border");
- gtk_style_context_add_class (context, "window-outer-border");
- gtk_render_frame (context, cr,
- 0, 0, allocation.width, allocation.height);
+ window_border.left, window_border.top,
+ allocation.width -
+ (window_border.left + window_border.right),
+ allocation.height -
+ (window_border.top + window_border.bottom));
+
gtk_style_context_restore (context);
}
@@ -8874,20 +8882,23 @@ gtk_window_draw (GtkWidget *widget,
title_height = gtk_widget_get_allocated_height (priv->title_box);
else
title_height = 0;
- gtk_style_context_save (context);
- gtk_style_context_add_class (context, "window-content");
+
gtk_render_background (context, cr,
- inner_border.left + outer_border.left,
- inner_border.top + outer_border.top +
- title_height,
+ window_border.left,
+ window_border.top + title_height,
allocation.width -
- (inner_border.left + inner_border.right +
- outer_border.left + outer_border.right),
+ (window_border.left + window_border.right),
allocation.height -
- (inner_border.top + inner_border.bottom +
- outer_border.top + outer_border.bottom +
+ (window_border.top + window_border.bottom +
title_height));
- gtk_style_context_restore (context);
+ gtk_render_frame (context, cr,
+ window_border.left,
+ window_border.top + title_height,
+ allocation.width -
+ (window_border.left + window_border.right),
+ allocation.height -
+ (window_border.top + window_border.bottom +
+ title_height));
}
if (GTK_WIDGET_CLASS (gtk_window_parent_class)->draw)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]