summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-02-15 16:12:26 +0000
committerMatthias Clasen <mclasen@redhat.com>2019-02-15 16:12:26 +0000
commitbea1a02edd161658f96f63c12694a8b3acce9c93 (patch)
tree91b9008dea6090023a370e8ef88ad7acc344e74a
parent74d6d81db920d4c03a609a0eb2fbc35395e18e28 (diff)
parentc44c44ee2510415c3b796e973ac3f525e5d512b9 (diff)
downloadgtk+-bea1a02edd161658f96f63c12694a8b3acce9c93.tar.gz
Merge branch 'wip/otte/boxes' into 'master'
GtkCssBoxes See merge request GNOME/gtk!584
-rw-r--r--docs/reference/gtk/gtk4-sections.txt1
-rw-r--r--gtk/a11y/gtkentryaccessible.c2
-rw-r--r--gtk/gtk.h1
-rw-r--r--gtk/gtkcontainer.c57
-rw-r--r--gtk/gtkcontainer.h5
-rw-r--r--gtk/gtkcssboxesimplprivate.h495
-rw-r--r--gtk/gtkcssboxesprivate.h91
-rw-r--r--gtk/gtkcssnodeprivate.h30
-rw-r--r--gtk/gtkcssnumbervalueprivate.h6
-rw-r--r--gtk/gtkcssrgbavalueprivate.h2
-rw-r--r--gtk/gtkcssstyleprivate.h6
-rw-r--r--gtk/gtkinvisible.c44
-rw-r--r--gtk/gtkinvisibleprivate.h2
-rw-r--r--gtk/gtkprintoperation-win32.c2
-rw-r--r--gtk/gtkrenderbackground.c107
-rw-r--r--gtk/gtkrenderbackgroundprivate.h7
-rw-r--r--gtk/gtkrenderborder.c177
-rw-r--r--gtk/gtkrenderborderprivate.h15
-rw-r--r--gtk/gtkroot.c104
-rw-r--r--gtk/gtkroot.h59
-rw-r--r--gtk/gtkrootprivate.h16
-rw-r--r--gtk/gtksnapshot.c33
-rw-r--r--gtk/gtktypes.h1
-rw-r--r--gtk/gtkwidget.c388
-rw-r--r--gtk/gtkwidget.h12
-rw-r--r--gtk/gtkwidgetpaintable.c10
-rw-r--r--gtk/gtkwidgetprivate.h46
-rw-r--r--gtk/gtkwindow.c104
-rw-r--r--gtk/gtkwindowprivate.h5
-rw-r--r--gtk/inspector/logs.c4
-rw-r--r--gtk/inspector/window.c4
-rw-r--r--gtk/meson.build2
32 files changed, 1255 insertions, 583 deletions
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index fd48280bed..b6fc344d36 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -751,7 +751,6 @@ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID
gtk_container_add
gtk_container_remove
gtk_container_add_with_properties
-gtk_container_check_resize
gtk_container_foreach
gtk_container_get_children
gtk_container_get_path_for_child
diff --git a/gtk/a11y/gtkentryaccessible.c b/gtk/a11y/gtkentryaccessible.c
index f8aaabad87..3b8bcf3b23 100644
--- a/gtk/a11y/gtkentryaccessible.c
+++ b/gtk/a11y/gtkentryaccessible.c
@@ -961,7 +961,7 @@ gtk_entry_accessible_get_character_extents (AtkText *text,
pango_layout_index_to_pos (gtk_entry_get_layout (entry), index, &char_rect);
pango_extents_to_pixels (&char_rect, NULL);
- _gtk_widget_get_allocation (widget, &allocation);
+ gtk_widget_get_allocation (widget, &allocation);
surface = gtk_widget_get_surface (widget);
gdk_surface_get_origin (surface, &x_surface, &y_surface);
diff --git a/gtk/gtk.h b/gtk/gtk.h
index c79f1a9dfb..368ce0ca69 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -176,6 +176,7 @@
#include <gtk/gtkrecentmanager.h>
#include <gtk/gtkrender.h>
#include <gtk/gtkrevealer.h>
+#include <gtk/gtkroot.h>
#include <gtk/gtkscale.h>
#include <gtk/gtkscalebutton.h>
#include <gtk/gtkscrollable.h>
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 58085d3135..f1ef23e8e4 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -34,12 +34,11 @@
#include "gtkpopovermenu.h"
#include "gtkprivate.h"
#include "gtkmarshalers.h"
-#include "gtkshortcutssection.h"
-#include "gtkshortcutswindow.h"
#include "gtksizerequest.h"
#include "gtkstylecontextprivate.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
+#include "gtkwindowprivate.h"
#include "a11y/gtkcontaineraccessibleprivate.h"
@@ -129,7 +128,6 @@ struct _GtkContainerPrivate
enum {
ADD,
REMOVE,
- CHECK_RESIZE,
SET_FOCUS_CHILD,
LAST_SIGNAL
};
@@ -148,7 +146,6 @@ static void gtk_container_add_unimplemented (GtkContainer *container
GtkWidget *widget);
static void gtk_container_remove_unimplemented (GtkContainer *container,
GtkWidget *widget);
-static void gtk_container_real_check_resize (GtkContainer *container);
static void gtk_container_compute_expand (GtkWidget *widget,
gboolean *hexpand_p,
gboolean *vexpand_p);
@@ -284,7 +281,6 @@ gtk_container_class_init (GtkContainerClass *class)
class->add = gtk_container_add_unimplemented;
class->remove = gtk_container_remove_unimplemented;
- class->check_resize = gtk_container_real_check_resize;
class->forall = NULL;
class->set_focus_child = gtk_container_real_set_focus_child;
class->child_type = NULL;
@@ -308,14 +304,6 @@ gtk_container_class_init (GtkContainerClass *class)
NULL,
G_TYPE_NONE, 1,
GTK_TYPE_WIDGET);
- container_signals[CHECK_RESIZE] =
- g_signal_new (I_("check-resize"),
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkContainerClass, check_resize),
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 0);
container_signals[SET_FOCUS_CHILD] =
g_signal_new (I_("set-focus-child"),
G_OBJECT_CLASS_TYPE (gobject_class),
@@ -1397,7 +1385,10 @@ gtk_container_idle_sizer (GdkFrameClock *clock,
*/
if (gtk_widget_needs_allocate (GTK_WIDGET (container)))
{
- gtk_container_check_resize (container);
+ if (GTK_IS_WINDOW (container))
+ gtk_window_check_resize (GTK_WINDOW (container));
+ else
+ g_warning ("gtk_container_idle_sizer() called on a non-window");
}
if (!gtk_container_needs_idle_sizer (container))
@@ -1460,44 +1451,6 @@ _gtk_container_queue_restyle (GtkContainer *container)
gtk_container_start_idle_sizer (container);
}
-void
-gtk_container_check_resize (GtkContainer *container)
-{
- g_return_if_fail (GTK_IS_CONTAINER (container));
-
- g_signal_emit (container, container_signals[CHECK_RESIZE], 0);
-}
-
-static void
-gtk_container_real_check_resize (GtkContainer *container)
-{
- GtkWidget *widget = GTK_WIDGET (container);
- GtkAllocation allocation;
- GtkRequisition requisition;
- int baseline;
-
- if (_gtk_widget_get_alloc_needed (widget))
- {
- if (!_gtk_widget_is_toplevel (widget))
- {
- gtk_widget_get_preferred_size (widget, &requisition, NULL);
- gtk_widget_get_allocated_size (widget, &allocation, &baseline);
-
- if (allocation.width < requisition.width)
- allocation.width = requisition.width;
- if (allocation.height < requisition.height)
- allocation.height = requisition.height;
- gtk_widget_size_allocate (widget, &allocation, baseline);
- }
- else
- gtk_widget_queue_resize (widget);
- }
- else
- {
- gtk_widget_ensure_allocate (widget);
- }
-}
-
static GtkSizeRequestMode
gtk_container_get_request_mode (GtkWidget *widget)
{
diff --git a/gtk/gtkcontainer.h b/gtk/gtkcontainer.h
index 8f07f97408..4e2aa50aec 100644
--- a/gtk/gtkcontainer.h
+++ b/gtk/gtkcontainer.h
@@ -56,7 +56,6 @@ struct _GtkContainer
* @parent_class: The parent class.
* @add: Signal emitted when a widget is added to container.
* @remove: Signal emitted when a widget is removed from container.
- * @check_resize: Signal emitted when a size recalculation is needed.
* @forall: Invokes callback on each child of container. The callback handler
* may remove the child.
* @set_focus_child: Sets the focused child of container.
@@ -78,7 +77,6 @@ struct _GtkContainerClass
GtkWidget *widget);
void (*remove) (GtkContainer *container,
GtkWidget *widget);
- void (*check_resize) (GtkContainer *container);
void (*forall) (GtkContainer *container,
GtkCallback callback,
gpointer callback_data);
@@ -126,9 +124,6 @@ void gtk_container_remove (GtkContainer *container,
GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
-void gtk_container_check_resize (GtkContainer *container);
-
-GDK_AVAILABLE_IN_ALL
void gtk_container_foreach (GtkContainer *container,
GtkCallback callback,
gpointer callback_data);
diff --git a/gtk/gtkcssboxesimplprivate.h b/gtk/gtkcssboxesimplprivate.h
new file mode 100644
index 0000000000..98c1b71e0d
--- /dev/null
+++ b/gtk/gtkcssboxesimplprivate.h
@@ -0,0 +1,495 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2019 Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_CSS_BOXES_IMPL_PRIVATE_H__
+#define __GTK_CSS_BOXES_IMPL_PRIVATE_H__
+
+#include "gtkcssboxesprivate.h"
+
+#include "gtkcsscornervalueprivate.h"
+#include "gtkcssnodeprivate.h"
+#include "gtkcssnumbervalueprivate.h"
+#include "gtkwidgetprivate.h"
+
+/* This file is included from gtkcssboxesprivate.h */
+
+static inline void
+gtk_css_boxes_init (GtkCssBoxes *boxes,
+ GtkWidget *widget)
+{
+ GtkWidgetPrivate *priv = widget->priv;
+
+ gtk_css_boxes_init_content_box (boxes,
+ gtk_css_node_get_style (priv->cssnode),
+ 0, 0,
+ priv->width,
+ priv->height);
+}
+
+static inline void
+gtk_css_boxes_init_content_box (GtkCssBoxes *boxes,
+ GtkCssStyle *style,
+ double x,
+ double y,
+ double width,
+ double height)
+{
+ memset (boxes, 0, sizeof (GtkCssBoxes));
+
+ boxes->style = style;
+ boxes->box[GTK_CSS_AREA_CONTENT_BOX].bounds = GRAPHENE_RECT_INIT (x, y, width, height);
+ boxes->has_rect[GTK_CSS_AREA_CONTENT_BOX] = TRUE;
+}
+
+static inline void
+gtk_css_boxes_init_border_box (GtkCssBoxes *boxes,
+ GtkCssStyle *style,
+ double x,
+ double y,
+ double width,
+ double height)
+{
+ memset (boxes, 0, sizeof (GtkCssBoxes));
+
+ boxes->style = style;
+ boxes->box[GTK_CSS_AREA_BORDER_BOX].bounds = GRAPHENE_RECT_INIT (x, y, width, height);
+ boxes->has_rect[GTK_CSS_AREA_BORDER_BOX] = TRUE;
+}
+
+static inline void
+gtk_css_boxes_rect_grow (GskRoundedRect *dest,
+ GskRoundedRect *src,
+ GtkCssStyle *style,
+ int top_property,
+ int right_property,
+ int bottom_property,
+ int left_property)
+{
+ double top = _gtk_css_number_value_get (gtk_css_style_get_value (style, top_property), 100);
+ double right = _gtk_css_number_value_get (gtk_css_style_get_value (style, right_property), 100);
+ double bottom = _gtk_css_number_value_get (gtk_css_style_get_value (style, bottom_property), 100);
+ double left = _gtk_css_number_value_get (gtk_css_style_get_value (style, left_property), 100);
+
+ dest->bounds.origin.x = src->bounds.origin.x - left;
+ dest->bounds.origin.y = src->bounds.origin.y - top;
+ dest->bounds.size.width = src->bounds.size.width + left + right;
+ dest->bounds.size.height = src->bounds.size.height + top + bottom;
+}
+
+static inline void
+gtk_css_boxes_rect_shrink (GskRoundedRect *dest,
+ GskRoundedRect *src,
+ GtkCssStyle *style,
+ int top_property,
+ int right_property,
+ int bottom_property,
+ int left_property)
+{
+ double top = _gtk_css_number_value_get (gtk_css_style_get_value (style, top_property), 100);
+ double right = _gtk_css_number_value_get (gtk_css_style_get_value (style, right_property), 100);
+ double bottom = _gtk_css_number_value_get (gtk_css_style_get_value (style, bottom_property), 100);
+ double left = _gtk_css_number_value_get (gtk_css_style_get_value (style, left_property), 100);
+
+ /* FIXME: Do we need underflow checks here? */
+ dest->bounds.origin.x = src->bounds.origin.x + left;
+ dest->bounds.origin.y = src->bounds.origin.y + top;
+ dest->bounds.size.width = src->bounds.size.width - left - right;
+ dest->bounds.size.height = src->bounds.size.height - top - bottom;
+}
+
+static inline void gtk_css_boxes_compute_padding_rect (GtkCssBoxes *boxes);
+
+static inline const graphene_rect_t *
+gtk_css_boxes_get_rect (GtkCssBoxes *boxes,
+ GtkCssArea area)
+{
+ switch (area)
+ {
+ case GTK_CSS_AREA_BORDER_BOX:
+ return gtk_css_boxes_get_border_rect (boxes);
+ case GTK_CSS_AREA_PADDING_BOX:
+ return gtk_css_boxes_get_padding_rect (boxes);
+ case GTK_CSS_AREA_CONTENT_BOX:
+ return gtk_css_boxes_get_content_rect (boxes);
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
+
+static inline void
+gtk_css_boxes_compute_border_rect (GtkCssBoxes *boxes)
+{
+ if (boxes->has_rect[GTK_CSS_AREA_BORDER_BOX])
+ return;
+
+ gtk_css_boxes_compute_padding_rect (boxes);
+
+ gtk_css_boxes_rect_grow (&boxes->box[GTK_CSS_AREA_BORDER_BOX],
+ &boxes->box[GTK_CSS_AREA_PADDING_BOX],
+ boxes->style,
+ GTK_CSS_PROPERTY_BORDER_TOP_WIDTH,
+ GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH,
+ GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
+ GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH);
+
+ boxes->has_rect[GTK_CSS_AREA_BORDER_BOX] = TRUE;
+}
+
+static inline void
+gtk_css_boxes_compute_padding_rect (GtkCssBoxes *boxes)
+{
+ if (boxes->has_rect[GTK_CSS_AREA_PADDING_BOX])
+ return;
+
+ if (boxes->has_rect[GTK_CSS_AREA_BORDER_BOX])
+ {
+ gtk_css_boxes_rect_shrink (&boxes->box[GTK_CSS_AREA_PADDING_BOX],
+ &boxes->box[GTK_CSS_AREA_BORDER_BOX],
+ boxes->style,
+ GTK_CSS_PROPERTY_BORDER_TOP_WIDTH,
+ GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH,
+ GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
+ GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH);
+ }
+ else
+ {
+ gtk_css_boxes_rect_grow (&boxes->box[GTK_CSS_AREA_PADDING_BOX],
+ &boxes->box[GTK_CSS_AREA_CONTENT_BOX],
+ boxes->style,
+ GTK_CSS_PROPERTY_PADDING_TOP,
+ GTK_CSS_PROPERTY_PADDING_RIGHT,
+ GTK_CSS_PROPERTY_PADDING_BOTTOM,
+ GTK_CSS_PROPERTY_PADDING_LEFT);
+ }
+
+ boxes->has_rect[GTK_CSS_AREA_PADDING_BOX] = TRUE;
+}
+
+static inline void
+gtk_css_boxes_compute_content_rect (GtkCssBoxes *boxes)
+{
+ if (boxes->has_rect[GTK_CSS_AREA_CONTENT_BOX])
+ return;
+
+ gtk_css_boxes_compute_padding_rect (boxes);
+
+ gtk_css_boxes_rect_shrink (&boxes->box[GTK_CSS_AREA_CONTENT_BOX],
+ &boxes->box[GTK_CSS_AREA_PADDING_BOX],
+ boxes->style,
+ GTK_CSS_PROPERTY_PADDING_TOP,
+ GTK_CSS_PROPERTY_PADDING_RIGHT,
+ GTK_CSS_PROPERTY_PADDING_BOTTOM,
+ GTK_CSS_PROPERTY_PADDING_LEFT);
+
+ boxes->has_rect[GTK_CSS_AREA_CONTENT_BOX] = TRUE;
+}
+
+static inline void
+gtk_css_boxes_compute_margin_rect (GtkCssBoxes *boxes)
+{
+ if (boxes->has_rect[GTK_CSS_AREA_MARGIN_BOX])
+ return;
+
+ gtk_css_boxes_compute_border_rect (boxes);
+
+ gtk_css_boxes_rect_grow (&boxes->box[GTK_CSS_AREA_MARGIN_BOX],
+ &boxes->box[GTK_CSS_AREA_BORDER_BOX],
+ boxes->style,
+ GTK_CSS_PROPERTY_MARGIN_TOP,
+ GTK_CSS_PROPERTY_MARGIN_RIGHT,
+ GTK_CSS_PROPERTY_MARGIN_BOTTOM,
+ GTK_CSS_PROPERTY_MARGIN_LEFT);
+
+ boxes->has_rect[GTK_CSS_AREA_MARGIN_BOX] = TRUE;
+}
+
+static inline void
+gtk_css_boxes_compute_outline_rect (GtkCssBoxes *boxes)
+{
+ graphene_rect_t *dest, *src;
+ double d;
+
+ if (boxes->has_rect[GTK_CSS_AREA_OUTLINE_BOX])
+ return;
+
+ gtk_css_boxes_compute_border_rect (boxes);
+
+ dest = &boxes->box[GTK_CSS_AREA_OUTLINE_BOX].bounds;
+ src = &boxes->box[GTK_CSS_AREA_BORDER_BOX].bounds;
+
+ d = _gtk_css_number_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_OUTLINE_OFFSET), 100) +
+ _gtk_css_number_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_OUTLINE_WIDTH), 100);
+
+ dest->origin.x = src->origin.x - d;
+ dest->origin.y = src->origin.y - d;
+ dest->size.width = src->size.width + d + d;
+ dest->size.height = src->size.height + d + d;
+
+ boxes->has_rect[GTK_CSS_AREA_OUTLINE_BOX] = TRUE;
+}
+
+static inline const graphene_rect_t *
+gtk_css_boxes_get_margin_rect (GtkCssBoxes *boxes)
+{
+ gtk_css_boxes_compute_margin_rect (boxes);
+
+ return &boxes->box[GTK_CSS_AREA_MARGIN_BOX].bounds;
+}
+
+static inline const graphene_rect_t *
+gtk_css_boxes_get_border_rect (GtkCssBoxes *boxes)
+{
+ gtk_css_boxes_compute_border_rect (boxes);
+
+ return &boxes->box[GTK_CSS_AREA_BORDER_BOX].bounds;
+}
+
+static inline const graphene_rect_t *
+gtk_css_boxes_get_padding_rect (GtkCssBoxes *boxes)
+{
+ gtk_css_boxes_compute_padding_rect (boxes);
+
+ return &boxes->box[GTK_CSS_AREA_PADDING_BOX].bounds;
+}
+
+static inline const graphene_rect_t *
+gtk_css_boxes_get_content_rect (GtkCssBoxes *boxes)
+{
+ gtk_css_boxes_compute_content_rect (boxes);
+
+ return &boxes->box[GTK_CSS_AREA_CONTENT_BOX].bounds;
+}
+
+static inline const graphene_rect_t *
+gtk_css_boxes_get_outline_rect (GtkCssBoxes *boxes)
+{
+ gtk_css_boxes_compute_outline_rect (boxes);
+
+ return &boxes->box[GTK_CSS_AREA_OUTLINE_BOX].bounds;
+}
+
+/* clamp border radius, following CSS specs */
+static inline void
+gtk_css_boxes_clamp_border_radius (GskRoundedRect *box)
+{
+ gdouble factor = 1.0;
+ gdouble corners;
+
+ corners = box->corner[GSK_CORNER_TOP_LEFT].width + box->corner[GSK_CORNER_TOP_RIGHT].width;
+ if (corners != 0)
+ factor = MIN (factor, box->bounds.size.width / corners);
+
+ corners = box->corner[GSK_CORNER_TOP_RIGHT].height + box->corner[GSK_CORNER_BOTTOM_RIGHT].height;
+ if (corners != 0)
+ factor = MIN (factor, box->bounds.size.height / corners);
+
+ corners = box->corner[GSK_CORNER_BOTTOM_RIGHT].width + box->corner[GSK_CORNER_BOTTOM_LEFT].width;
+ if (corners != 0)
+ factor = MIN (factor, box->bounds.size.width / corners);
+
+ corners = box->corner[GSK_CORNER_TOP_LEFT].height + box->corner[GSK_CORNER_BOTTOM_LEFT].height;
+ if (corners != 0)
+ factor = MIN (factor, box->bounds.size.height / corners);
+
+ box->corner[GSK_CORNER_TOP_LEFT].width *= factor;
+ box->corner[GSK_CORNER_TOP_LEFT].height *= factor;
+ box->corner[GSK_CORNER_TOP_RIGHT].width *= factor;
+ box->corner[GSK_CORNER_TOP_RIGHT].height *= factor;
+ box->corner[GSK_CORNER_BOTTOM_RIGHT].width *= factor;
+ box->corner[GSK_CORNER_BOTTOM_RIGHT].height *= factor;
+ box->corner[GSK_CORNER_BOTTOM_LEFT].width *= factor;
+ box->corner[GSK_CORNER_BOTTOM_LEFT].height *= factor;
+}
+
+static inline void
+gtk_css_boxes_apply_border_radius (GskRoundedRect *box,
+ const GtkCssValue *top_left,
+ const GtkCssValue *top_right,
+ const GtkCssValue *bottom_right,
+ const GtkCssValue *bottom_left)
+{
+ box->corner[GSK_CORNER_TOP_LEFT].width = _gtk_css_corner_value_get_x (top_left, box->bounds.size.width);
+ box->corner[GSK_CORNER_TOP_LEFT].height = _gtk_css_corner_value_get_y (top_left, box->bounds.size.height);
+
+ box->corner[GSK_CORNER_TOP_RIGHT].width = _gtk_css_corner_value_get_x (top_right, box->bounds.size.width);
+ box->corner[GSK_CORNER_TOP_RIGHT].height = _gtk_css_corner_value_get_y (top_right, box->bounds.size.height);
+
+ box->corner[GSK_CORNER_BOTTOM_RIGHT].width = _gtk_css_corner_value_get_x (bottom_right, box->bounds.size.width);
+ box->corner[GSK_CORNER_BOTTOM_RIGHT].height = _gtk_css_corner_value_get_y (bottom_right, box->bounds.size.height);
+
+ box->corner[GSK_CORNER_BOTTOM_LEFT].width = _gtk_css_corner_value_get_x (bottom_left, box->bounds.size.width);
+ box->corner[GSK_CORNER_BOTTOM_LEFT].height = _gtk_css_corner_value_get_y (bottom_left, box->bounds.size.height);
+
+ gtk_css_boxes_clamp_border_radius (box);
+}
+
+/* NB: width and height must be >= 0 */
+static inline void
+gtk_css_boxes_shrink_border_radius (graphene_size_t *dest,
+ const graphene_size_t *src,
+ double width,
+ double height)
+{
+ dest->width = src->width - width;
+ dest->height = src->height - height;
+
+ if (dest->width <= 0 || dest->height <= 0)
+ {
+ dest->width = 0;
+ dest->height = 0;
+ }
+}
+
+static inline void
+gtk_css_boxes_shrink_corners (GskRoundedRect *dest,
+ const GskRoundedRect *src)
+{
+ double top = dest->bounds.origin.y - src->bounds.origin.y;
+ double right = src->bounds.origin.x + src->bounds.size.width - dest->bounds.origin.x - dest->bounds.size.width;
+ double bottom = src->bounds.origin.y + src->bounds.size.height - dest->bounds.origin.y - dest->bounds.size.height;
+ double left = dest->bounds.origin.x - src->bounds.origin.x;
+
+ gtk_css_boxes_shrink_border_radius (&dest->corner[GSK_CORNER_TOP_LEFT],
+ &src->corner[GSK_CORNER_TOP_LEFT],
+ top, left);
+ gtk_css_boxes_shrink_border_radius (&dest->corner[GSK_CORNER_TOP_RIGHT],
+ &src->corner[GSK_CORNER_TOP_RIGHT],
+ top, right);
+ gtk_css_boxes_shrink_border_radius (&dest->corner[GSK_CORNER_BOTTOM_RIGHT],
+ &src->corner[GSK_CORNER_BOTTOM_RIGHT],
+ bottom, right);
+ gtk_css_boxes_shrink_border_radius (&dest->corner[GSK_CORNER_BOTTOM_LEFT],
+ &src->corner[GSK_CORNER_BOTTOM_LEFT],
+ bottom, left);
+}
+
+static inline void
+gtk_css_boxes_compute_border_box (GtkCssBoxes *boxes)
+{
+ if (boxes->has_box[GTK_CSS_AREA_BORDER_BOX])
+ return;
+
+ gtk_css_boxes_compute_border_rect (boxes);
+
+ gtk_css_boxes_apply_border_radius (&boxes->box[GTK_CSS_AREA_BORDER_BOX],
+ gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS),
+ gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS),
+ gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS),
+ gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS));
+
+ boxes->has_box[GTK_CSS_AREA_BORDER_BOX] = TRUE;
+}
+
+static inline void
+gtk_css_boxes_compute_padding_box (GtkCssBoxes *boxes)
+{
+ if (boxes->has_box[GTK_CSS_AREA_PADDING_BOX])
+ return;
+
+ gtk_css_boxes_compute_border_box (boxes);
+ gtk_css_boxes_compute_padding_rect (boxes);
+
+ gtk_css_boxes_shrink_corners (&boxes->box[GTK_CSS_AREA_PADDING_BOX],
+ &boxes->box[GTK_CSS_AREA_BORDER_BOX]);
+
+ boxes->has_box[GTK_CSS_AREA_PADDING_BOX] = TRUE;
+}
+
+static inline void
+gtk_css_boxes_compute_content_box (GtkCssBoxes *boxes)
+{
+ if (boxes->has_box[GTK_CSS_AREA_CONTENT_BOX])
+ return;
+
+ gtk_css_boxes_compute_padding_box (boxes);
+ gtk_css_boxes_compute_content_rect (boxes);
+
+ gtk_css_boxes_shrink_corners (&boxes->box[GTK_CSS_AREA_CONTENT_BOX],
+ &boxes->box[GTK_CSS_AREA_PADDING_BOX]);
+
+ boxes->has_box[GTK_CSS_AREA_CONTENT_BOX] = TRUE;
+}
+
+static inline void
+gtk_css_boxes_compute_outline_box (GtkCssBoxes *boxes)
+{
+ if (boxes->has_box[GTK_CSS_AREA_OUTLINE_BOX])
+ return;
+
+ gtk_css_boxes_compute_outline_rect (boxes);
+
+ gtk_css_boxes_apply_border_radius (&boxes->box[GTK_CSS_AREA_OUTLINE_BOX],
+ gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_OUTLINE_TOP_LEFT_RADIUS),
+ gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_OUTLINE_TOP_RIGHT_RADIUS),
+ gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_OUTLINE_BOTTOM_RIGHT_RADIUS),
+ gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_OUTLINE_BOTTOM_LEFT_RADIUS));
+
+ boxes->has_box[GTK_CSS_AREA_OUTLINE_BOX] = TRUE;
+}
+
+static inline const GskRoundedRect *
+gtk_css_boxes_get_box (GtkCssBoxes *boxes,
+ GtkCssArea area)
+{
+ switch (area)
+ {
+ case GTK_CSS_AREA_BORDER_BOX:
+ return gtk_css_boxes_get_border_box (boxes);
+ case GTK_CSS_AREA_PADDING_BOX:
+ return gtk_css_boxes_get_padding_box (boxes);
+ case GTK_CSS_AREA_CONTENT_BOX:
+ return gtk_css_boxes_get_content_box (boxes);
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
+
+static inline const GskRoundedRect *
+gtk_css_boxes_get_border_box (GtkCssBoxes *boxes)
+{
+ gtk_css_boxes_compute_border_box (boxes);
+
+ return &boxes->box[GTK_CSS_AREA_BORDER_BOX];
+}
+
+static inline const GskRoundedRect *
+gtk_css_boxes_get_padding_box (GtkCssBoxes *boxes)
+{
+ gtk_css_boxes_compute_padding_box (boxes);
+
+ return &boxes->box[GTK_CSS_AREA_PADDING_BOX];
+}
+
+static inline const GskRoundedRect *
+gtk_css_boxes_get_content_box (GtkCssBoxes *boxes)
+{
+ gtk_css_boxes_compute_content_box (boxes);
+
+ return &boxes->box[GTK_CSS_AREA_CONTENT_BOX];
+}
+
+static inline const GskRoundedRect *
+gtk_css_boxes_get_outline_box (GtkCssBoxes *boxes)
+{
+ gtk_css_boxes_compute_outline_box (boxes);
+
+ return &boxes->box[GTK_CSS_AREA_OUTLINE_BOX];
+}
+
+#endif /* __GTK_CSS_BOXES_IMPL_PRIVATE_H__ */
diff --git a/gtk/gtkcssboxesprivate.h b/gtk/gtkcssboxesprivate.h
new file mode 100644
index 0000000000..d90ba1e598
--- /dev/null
+++ b/gtk/gtkcssboxesprivate.h
@@ -0,0 +1,91 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 2019 Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_CSS_BOXES_PRIVATE_H__
+#define __GTK_CSS_BOXES_PRIVATE_H__
+
+#include "gtkcsstypesprivate.h"
+
+G_BEGIN_DECLS
+
+/*
+ * The idea behind this file is that it provides an on-stack representation
+ * for all the CSS boxes one can have to deal with in the CSS box model so that
+ * higher level code can use convenient and readable function calls instead of
+ * doing complicated math.
+ *
+ * However, because computing all those rectangles is prohibitively expensive,
+ * this struct does it lazily.
+ * And then we inline all the code, so that whenever we use this struct, the
+ * compiler can optimize out the parts we don't need in that particular use
+ * case.
+ */
+
+typedef struct _GtkCssBoxes GtkCssBoxes;
+
+/* ahem...
+ * Let's extend GtkCssArea a bit here. */
+#define GTK_CSS_AREA_MARGIN_BOX (3)
+#define GTK_CSS_AREA_OUTLINE_BOX (4)
+#define GTK_CSS_AREA_N_BOXES (5)
+
+
+struct _GtkCssBoxes
+{
+ GtkCssStyle *style;
+ GskRoundedRect box[GTK_CSS_AREA_N_BOXES];
+ gboolean has_rect[GTK_CSS_AREA_N_BOXES]; /* TRUE if we have initialized just the bounds rect */
+ gboolean has_box[GTK_CSS_AREA_N_BOXES]; /* TRUE if we have initialized the whole box */
+};
+
+static inline void gtk_css_boxes_init (GtkCssBoxes *boxes,
+ GtkWidget *widget);
+static inline void gtk_css_boxes_init_content_box (GtkCssBoxes *boxes,
+ GtkCssStyle *style,
+ double x,
+ double y,
+ double width,
+ double height);
+static inline void gtk_css_boxes_init_border_box (GtkCssBoxes *boxes,
+ GtkCssStyle *style,
+ double x,
+ double y,
+ double width,
+ double height);
+
+static inline const graphene_rect_t * gtk_css_boxes_get_rect (GtkCssBoxes *boxes,
+ GtkCssArea area);
+static inline const graphene_rect_t * gtk_css_boxes_get_margin_rect (GtkCssBoxes *boxes);
+static inline const graphene_rect_t * gtk_css_boxes_get_border_rect (GtkCssBoxes *boxes);
+static inline const graphene_rect_t * gtk_css_boxes_get_padding_rect (GtkCssBoxes *boxes);
+static inline const graphene_rect_t * gtk_css_boxes_get_content_rect (GtkCssBoxes *boxes);
+static inline const graphene_rect_t * gtk_css_boxes_get_outline_rect (GtkCssBoxes *boxes);
+
+static inline const GskRoundedRect * gtk_css_boxes_get_box (GtkCssBoxes *boxes,
+ GtkCssArea area);
+static inline const GskRoundedRect * gtk_css_boxes_get_border_box (GtkCssBoxes *boxes);
+static inline const GskRoundedRect * gtk_css_boxes_get_padding_box (GtkCssBoxes *boxes);
+static inline const GskRoundedRect * gtk_css_boxes_get_content_box (GtkCssBoxes *boxes);
+static inline const GskRoundedRect * gtk_css_boxes_get_outline_box (GtkCssBoxes *boxes);
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_BOXES_PRIVATE_H__ */
+
+/* and finally include the actual code for the functions */
+#include "gtkcssboxesimplprivate.h"
+
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index 8c71733192..7335fb30da 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -106,28 +106,28 @@ void gtk_css_node_insert_before (GtkCssNode *
GtkCssNode *cssnode,
GtkCssNode *next_sibling);
-GtkCssNode * gtk_css_node_get_parent (GtkCssNode *cssnode);
-GtkCssNode * gtk_css_node_get_first_child (GtkCssNode *cssnode);
-GtkCssNode * gtk_css_node_get_last_child (GtkCssNode *cssnode);
-GtkCssNode * gtk_css_node_get_previous_sibling(GtkCssNode *cssnode);
-GtkCssNode * gtk_css_node_get_next_sibling (GtkCssNode *cssnode);
+GtkCssNode * gtk_css_node_get_parent (GtkCssNode *cssnode) G_GNUC_PURE;
+GtkCssNode * gtk_css_node_get_first_child (GtkCssNode *cssnode) G_GNUC_PURE;
+GtkCssNode * gtk_css_node_get_last_child (GtkCssNode *cssnode) G_GNUC_PURE;
+GtkCssNode * gtk_css_node_get_previous_sibling(GtkCssNode *cssnode) G_GNUC_PURE;
+GtkCssNode * gtk_css_node_get_next_sibling (GtkCssNode *cssnode) G_GNUC_PURE;
void gtk_css_node_set_visible (GtkCssNode *cssnode,
gboolean visible);
-gboolean gtk_css_node_get_visible (GtkCssNode *cssnode);
+gboolean gtk_css_node_get_visible (GtkCssNode *cssnode) G_GNUC_PURE;
void gtk_css_node_set_name (GtkCssNode *cssnode,
/*interned*/const char*name);
-/*interned*/const char *gtk_css_node_get_name (GtkCssNode *cssnode);
+/*interned*/const char *gtk_css_node_get_name (GtkCssNode *cssnode) G_GNUC_PURE;
void gtk_css_node_set_widget_type (GtkCssNode *cssnode,
GType widget_type);
-GType gtk_css_node_get_widget_type (GtkCssNode *cssnode);
+GType gtk_css_node_get_widget_type (GtkCssNode *cssnode) G_GNUC_PURE;
void gtk_css_node_set_id (GtkCssNode *cssnode,
/*interned*/const char*id);
-/*interned*/const char *gtk_css_node_get_id (GtkCssNode *cssnode);
+/*interned*/const char *gtk_css_node_get_id (GtkCssNode *cssnode) G_GNUC_PURE;
void gtk_css_node_set_state (GtkCssNode *cssnode,
GtkStateFlags state_flags);
-GtkStateFlags gtk_css_node_get_state (GtkCssNode *cssnode);
+GtkStateFlags gtk_css_node_get_state (GtkCssNode *cssnode) G_GNUC_PURE;
void gtk_css_node_set_classes (GtkCssNode *cssnode,
const char **classes);
char ** gtk_css_node_get_classes (GtkCssNode *cssnode);
@@ -136,13 +136,13 @@ void gtk_css_node_add_class (GtkCssNode *
void gtk_css_node_remove_class (GtkCssNode *cssnode,
GQuark style_class);
gboolean gtk_css_node_has_class (GtkCssNode *cssnode,
- GQuark style_class);
+ GQuark style_class) G_GNUC_PURE;
const GQuark * gtk_css_node_list_classes (GtkCssNode *cssnode,
guint *n_classes);
const GtkCssNodeDeclaration *
- gtk_css_node_get_declaration (GtkCssNode *cssnode);
-GtkCssStyle * gtk_css_node_get_style (GtkCssNode *cssnode);
+ gtk_css_node_get_declaration (GtkCssNode *cssnode) G_GNUC_PURE;
+GtkCssStyle * gtk_css_node_get_style (GtkCssNode *cssnode) G_GNUC_PURE;
void gtk_css_node_invalidate_style_provider
@@ -157,8 +157,8 @@ void gtk_css_node_validate (GtkCssNode *
gboolean gtk_css_node_init_matcher (GtkCssNode *cssnode,
GtkCssMatcher *matcher);
GtkWidgetPath * gtk_css_node_create_widget_path (GtkCssNode *cssnode);
-const GtkWidgetPath * gtk_css_node_get_widget_path (GtkCssNode *cssnode);
-GtkStyleProvider * gtk_css_node_get_style_provider (GtkCssNode *cssnode);
+const GtkWidgetPath * gtk_css_node_get_widget_path (GtkCssNode *cssnode) G_GNUC_PURE;
+GtkStyleProvider * gtk_css_node_get_style_provider (GtkCssNode *cssnode) G_GNUC_PURE;
void gtk_css_node_print (GtkCssNode *cssnode,
GtkStyleContextPrintFlags flags,
diff --git a/gtk/gtkcssnumbervalueprivate.h b/gtk/gtkcssnumbervalueprivate.h
index 3ea9af6b7b..faf7dad5c9 100644
--- a/gtk/gtkcssnumbervalueprivate.h
+++ b/gtk/gtkcssnumbervalueprivate.h
@@ -61,8 +61,8 @@ gboolean gtk_css_number_value_can_parse (GtkCssParser *par
GtkCssValue * _gtk_css_number_value_parse (GtkCssParser *parser,
GtkCssNumberParseFlags flags);
-GtkCssDimension gtk_css_number_value_get_dimension (const GtkCssValue *value);
-gboolean gtk_css_number_value_has_percent (const GtkCssValue *value);
+GtkCssDimension gtk_css_number_value_get_dimension (const GtkCssValue *value) G_GNUC_PURE;
+gboolean gtk_css_number_value_has_percent (const GtkCssValue *value) G_GNUC_PURE;
GtkCssValue * gtk_css_number_value_multiply (const GtkCssValue *value,
double factor);
GtkCssValue * gtk_css_number_value_add (GtkCssValue *value1,
@@ -72,7 +72,7 @@ GtkCssValue * gtk_css_number_value_try_add (const GtkCssValue *val
gint gtk_css_number_value_get_calc_term_order (const GtkCssValue *value);
double _gtk_css_number_value_get (const GtkCssValue *number,
- double one_hundred_percent);
+ double one_hundred_percent) G_GNUC_PURE;
G_END_DECLS
diff --git a/gtk/gtkcssrgbavalueprivate.h b/gtk/gtkcssrgbavalueprivate.h
index 4a2909dde4..60a0cffd6f 100644
--- a/gtk/gtkcssrgbavalueprivate.h
+++ b/gtk/gtkcssrgbavalueprivate.h
@@ -28,7 +28,7 @@ G_BEGIN_DECLS
GtkCssValue * _gtk_css_rgba_value_new_from_rgba (const GdkRGBA *rgba);
-const GdkRGBA * _gtk_css_rgba_value_get_rgba (const GtkCssValue *rgba);
+const GdkRGBA * _gtk_css_rgba_value_get_rgba (const GtkCssValue *rgba) G_GNUC_PURE;
G_END_DECLS
diff --git a/gtk/gtkcssstyleprivate.h b/gtk/gtkcssstyleprivate.h
index 536b4b8a23..a17dc4203f 100644
--- a/gtk/gtkcssstyleprivate.h
+++ b/gtk/gtkcssstyleprivate.h
@@ -61,13 +61,13 @@ struct _GtkCssStyleClass
GType gtk_css_style_get_type (void) G_GNUC_CONST;
GtkCssValue * gtk_css_style_get_value (GtkCssStyle *style,
- guint id);
+ guint id) G_GNUC_PURE;
GtkCssSection * gtk_css_style_get_section (GtkCssStyle *style,
- guint id);
+ guint id) G_GNUC_PURE;
GtkBitmask * gtk_css_style_add_difference (GtkBitmask *accumulated,
GtkCssStyle *style,
GtkCssStyle *other);
-gboolean gtk_css_style_is_static (GtkCssStyle *style);
+gboolean gtk_css_style_is_static (GtkCssStyle *style) G_GNUC_PURE;
char * gtk_css_style_to_string (GtkCssStyle *style);
gboolean gtk_css_style_print (GtkCssStyle *style,
diff --git a/gtk/gtkinvisible.c b/gtk/gtkinvisible.c
index 37821039a6..9b66f3a9c8 100644
--- a/gtk/gtkinvisible.c
+++ b/gtk/gtkinvisible.c
@@ -23,11 +23,13 @@
*/
#include "config.h"
-#include <gdk/gdk.h>
+
#include "gtkinvisibleprivate.h"
-#include "gtkwidgetprivate.h"
-#include "gtkprivate.h"
+
#include "gtkintl.h"
+#include "gtkprivate.h"
+#include "gtkroot.h"
+#include "gtkwidgetprivate.h"
/**
@@ -69,7 +71,24 @@ static void gtk_invisible_get_property (GObject *object,
GParamSpec *pspec);
static void gtk_invisible_constructed (GObject *object);
-G_DEFINE_TYPE_WITH_PRIVATE (GtkInvisible, gtk_invisible, GTK_TYPE_WIDGET)
+static GdkDisplay *
+gtk_invisible_root_get_display (GtkRoot *root)
+{
+ GtkInvisible *invisible = GTK_INVISIBLE (root);
+
+ return invisible->priv->display;
+}
+
+static void
+gtk_invisible_root_interface_init (GtkRootInterface *iface)
+{
+ iface->get_display = gtk_invisible_root_get_display;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GtkInvisible, gtk_invisible, GTK_TYPE_WIDGET,
+ G_ADD_PRIVATE (GtkInvisible)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ROOT,
+ gtk_invisible_root_interface_init))
static void
gtk_invisible_class_init (GtkInvisibleClass *class)
@@ -107,7 +126,6 @@ gtk_invisible_init (GtkInvisible *invisible)
priv = invisible->priv;
gtk_widget_set_has_surface (GTK_WIDGET (invisible), TRUE);
- _gtk_widget_set_is_toplevel (GTK_WIDGET (invisible), TRUE);
g_object_ref_sink (invisible);
@@ -201,22 +219,6 @@ gtk_invisible_set_display (GtkInvisible *invisible,
gtk_widget_realize (widget);
}
-/**
- * gtk_invisible_get_display:
- * @invisible: a #GtkInvisible.
- *
- * Returns the #GdkDisplay object associated with @invisible
- *
- * Returns: (transfer none): the associated #GdkDisplay.
- **/
-GdkDisplay *
-gtk_invisible_get_display (GtkInvisible *invisible)
-{
- g_return_val_if_fail (GTK_IS_INVISIBLE (invisible), NULL);
-
- return invisible->priv->display;
-}
-
static void
gtk_invisible_realize (GtkWidget *widget)
{
diff --git a/gtk/gtkinvisibleprivate.h b/gtk/gtkinvisibleprivate.h
index f625a35684..c65053bca0 100644
--- a/gtk/gtkinvisibleprivate.h
+++ b/gtk/gtkinvisibleprivate.h
@@ -74,8 +74,6 @@ GtkWidget* gtk_invisible_new_for_display(GdkDisplay *display);
GDK_AVAILABLE_IN_ALL
void gtk_invisible_set_display (GtkInvisible *invisible,
GdkDisplay *display);
-GDK_AVAILABLE_IN_ALL
-GdkDisplay*gtk_invisible_get_display (GtkInvisible *invisible);
G_END_DECLS
diff --git a/gtk/gtkprintoperation-win32.c b/gtk/gtkprintoperation-win32.c
index ac18261c71..4f21c1f17f 100644
--- a/gtk/gtkprintoperation-win32.c
+++ b/gtk/gtkprintoperation-win32.c
@@ -1382,8 +1382,6 @@ pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
SetWindowLongPtrW (wnd, GWLP_USERDATA, (LONG_PTR)op);
- _gtk_widget_set_is_toplevel (plug, TRUE);
-
gtk_window_set_modal (GTK_WINDOW (plug), TRUE);
op_win32->embed_widget = plug;
gtk_container_add (GTK_CONTAINER (plug), op->priv->custom_widget);
diff --git a/gtk/gtkrenderbackground.c b/gtk/gtkrenderbackground.c
index 0be739f679..32e0305cab 100644
--- a/gtk/gtkrenderbackground.c
+++ b/gtk/gtkrenderbackground.c
@@ -25,6 +25,7 @@
#include "gtkcssarrayvalueprivate.h"
#include "gtkcssbgsizevalueprivate.h"
+#include "gtkcssboxesprivate.h"
#include "gtkcsscornervalueprivate.h"
#include "gtkcssenumvalueprivate.h"
#include "gtkcssimagevalueprivate.h"
@@ -47,49 +48,43 @@
*/
#include "fallback-c89.c"
-typedef struct _GtkThemingBackground GtkThemingBackground;
-
-#define N_BOXES (3)
-
-struct _GtkThemingBackground {
- GtkCssStyle *style;
-
- GskRoundedRect boxes[N_BOXES];
-};
-
static void
-gtk_theming_background_snapshot_color (const GtkThemingBackground *bg,
- GtkSnapshot *snapshot,
- const GdkRGBA *bg_color,
- const GtkCssValue *background_image)
+gtk_theming_background_snapshot_color (GtkCssBoxes *boxes,
+ GtkSnapshot *snapshot,
+ const GdkRGBA *bg_color,
+ const GtkCssValue *background_image)
{
- gint n_values = _gtk_css_array_value_get_n_values (background_image);
- GtkCssArea clip = _gtk_css_area_value_get
+ const GskRoundedRect *box;
+ gint n_values;
+ GtkCssArea clip;
+
+ n_values = _gtk_css_array_value_get_n_values (background_image);
+ clip = _gtk_css_area_value_get
(_gtk_css_array_value_get_nth
- (gtk_css_style_get_value (bg->style, GTK_CSS_PROPERTY_BACKGROUND_CLIP),
+ (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BACKGROUND_CLIP),
n_values - 1));
+ box = gtk_css_boxes_get_box (boxes, clip);
- if (gsk_rounded_rect_is_rectilinear (&bg->boxes[clip]))
+ if (gsk_rounded_rect_is_rectilinear (box))
{
gtk_snapshot_append_color (snapshot,
bg_color,
- &bg->boxes[clip].bounds);
+ &box->bounds);
}
else
{
- gtk_snapshot_push_rounded_clip (snapshot,
- &bg->boxes[clip]);
+ gtk_snapshot_push_rounded_clip (snapshot, box);
gtk_snapshot_append_color (snapshot,
bg_color,
- &bg->boxes[clip].bounds);
+ &box->bounds);
gtk_snapshot_pop (snapshot);
}
}
static void
-gtk_theming_background_snapshot_layer (const GtkThemingBackground *bg,
- guint idx,
- GtkSnapshot *snapshot)
+gtk_theming_background_snapshot_layer (GtkCssBoxes *bg,
+ guint idx,
+ GtkSnapshot *snapshot)
{
GtkCssRepeatStyle hrepeat, vrepeat;
const GtkCssValue *pos, *repeat;
@@ -112,11 +107,11 @@ gtk_theming_background_snapshot_layer (const GtkThemingBackground *bg,
vrepeat = _gtk_css_background_repeat_value_get_y (repeat);
- origin = &bg->boxes[
- _gtk_css_area_value_get (
- _gtk_css_array_value_get_nth (
- gtk_css_style_get_value (bg->style, GTK_CSS_PROPERTY_BACKGROUND_ORIGIN),
- idx))];
+ origin = gtk_css_boxes_get_box (bg,
+ _gtk_css_area_value_get (
+ _gtk_css_array_value_get_nth (
+ gtk_css_style_get_value (bg->style, GTK_CSS_PROPERTY_BACKGROUND_ORIGIN),
+ idx)));
width = origin->bounds.size.width;
height = origin->bounds.size.height;
@@ -124,11 +119,11 @@ gtk_theming_background_snapshot_layer (const GtkThemingBackground *bg,
if (width <= 0 || height <= 0)
return;
- clip = &bg->boxes[
- _gtk_css_area_value_get (
- _gtk_css_array_value_get_nth (
- gtk_css_style_get_value (bg->style, GTK_CSS_PROPERTY_BACKGROUND_CLIP),
- idx))];
+ clip = gtk_css_boxes_get_box (bg,
+ _gtk_css_area_value_get (
+ _gtk_css_array_value_get_nth (
+ gtk_css_style_get_value (bg->style, GTK_CSS_PROPERTY_BACKGROUND_CLIP),
+ idx)));
_gtk_css_bg_size_value_compute_size (_gtk_css_array_value_get_nth (gtk_css_style_get_value (bg->style, GTK_CSS_PROPERTY_BACKGROUND_SIZE), idx),
image,
@@ -274,28 +269,10 @@ gtk_theming_background_snapshot_layer (const GtkThemingBackground *bg,
gtk_snapshot_pop (snapshot);
}
-static void
-gtk_theming_background_init (GtkThemingBackground *bg,
- GtkCssStyle *style,
- double width,
- double height)
-{
- bg->style = style;
-
- gtk_rounded_boxes_init_for_style (&bg->boxes[GTK_CSS_AREA_BORDER_BOX],
- &bg->boxes[GTK_CSS_AREA_PADDING_BOX],
- &bg->boxes[GTK_CSS_AREA_CONTENT_BOX],
- style,
- 0, 0, width, height);
-}
-
void
-gtk_css_style_snapshot_background (GtkCssStyle *style,
- GtkSnapshot *snapshot,
- gdouble width,
- gdouble height)
+gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
+ GtkSnapshot *snapshot)
{
- GtkThemingBackground bg;
gint idx;
GtkCssValue *background_image;
GtkCssValue *box_shadow;
@@ -304,9 +281,9 @@ gtk_css_style_snapshot_background (GtkCssStyle *style,
gint number_of_layers;
GskBlendMode *blend_mode_values;
- background_image = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_IMAGE);
- bg_color = _gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_COLOR));
- box_shadow = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BOX_SHADOW);
+ background_image = gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BACKGROUND_IMAGE);
+ bg_color = _gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BACKGROUND_COLOR));
+ box_shadow = gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BOX_SHADOW);
/* This is the common default case of no background */
if (gdk_rgba_is_clear (bg_color) &&
@@ -315,15 +292,13 @@ gtk_css_style_snapshot_background (GtkCssStyle *style,
_gtk_css_shadows_value_is_none (box_shadow))
return;
- gtk_theming_background_init (&bg, style, width, height);
-
gtk_snapshot_push_debug (snapshot, "CSS background");
gtk_css_shadows_value_snapshot_outset (box_shadow,
snapshot,
- &bg.boxes[GTK_CSS_AREA_BORDER_BOX]);
+ gtk_css_boxes_get_border_box (boxes));
- blend_modes = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BACKGROUND_BLEND_MODE);
+ blend_modes = gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BACKGROUND_BLEND_MODE);
number_of_layers = _gtk_css_array_value_get_n_values (background_image);
blend_mode_values = g_alloca (sizeof (GskBlendMode) * number_of_layers);
@@ -336,25 +311,25 @@ gtk_css_style_snapshot_background (GtkCssStyle *style,
}
if (!gdk_rgba_is_clear (bg_color))
- gtk_theming_background_snapshot_color (&bg, snapshot, bg_color, background_image);
+ gtk_theming_background_snapshot_color (boxes, snapshot, bg_color, background_image);
for (idx = number_of_layers - 1; idx >= 0; idx--)
{
if (blend_mode_values[idx] == GSK_BLEND_MODE_DEFAULT)
{
- gtk_theming_background_snapshot_layer (&bg, idx, snapshot);
+ gtk_theming_background_snapshot_layer (boxes, idx, snapshot);
}
else
{
gtk_snapshot_pop (snapshot);
- gtk_theming_background_snapshot_layer (&bg, idx, snapshot);
+ gtk_theming_background_snapshot_layer (boxes, idx, snapshot);
gtk_snapshot_pop (snapshot);
}
}
gtk_css_shadows_value_snapshot_inset (box_shadow,
snapshot,
- &bg.boxes[GTK_CSS_AREA_PADDING_BOX]);
+ gtk_css_boxes_get_padding_box (boxes));
gtk_snapshot_pop (snapshot);
}
diff --git a/gtk/gtkrenderbackgroundprivate.h b/gtk/gtkrenderbackgroundprivate.h
index a812b3ef7a..43aaf17580 100644
--- a/gtk/gtkrenderbackgroundprivate.h
+++ b/gtk/gtkrenderbackgroundprivate.h
@@ -24,14 +24,13 @@
#include <cairo.h>
#include "gtkcsstypesprivate.h"
+#include "gtkcssboxesprivate.h"
#include "gtktypes.h"
G_BEGIN_DECLS
-void gtk_css_style_snapshot_background (GtkCssStyle *style,
- GtkSnapshot *snapshot,
- gdouble width,
- gdouble height);
+void gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
+ GtkSnapshot *snapshot);
diff --git a/gtk/gtkrenderborder.c b/gtk/gtkrenderborder.c
index 1c568532ce..08a05f692f 100644
--- a/gtk/gtkrenderborder.c
+++ b/gtk/gtkrenderborder.c
@@ -251,13 +251,10 @@ gtk_border_image_compute_slice_size (GtkBorderImageSliceSize sizes[3],
}
static void
-gtk_border_image_render (GtkBorderImage *image,
- const double border_width[4],
- cairo_t *cr,
- gdouble x,
- gdouble y,
- gdouble width,
- gdouble height)
+gtk_border_image_render (GtkBorderImage *image,
+ const float border_width[4],
+ cairo_t *cr,
+ const graphene_rect_t *rect)
{
cairo_surface_t *surface, *slice;
GtkBorderImageSliceSize vertical_slice[3], horizontal_slice[3];
@@ -267,7 +264,7 @@ gtk_border_image_render (GtkBorderImage *image,
_gtk_css_image_get_concrete_size (image->source,
0, 0,
- width, height,
+ rect->size.width, rect->size.height,
&source_width, &source_height);
/* XXX: Optimize for (source_width == width && source_height == height) */
@@ -285,15 +282,15 @@ gtk_border_image_render (GtkBorderImage *image,
_gtk_css_number_value_get (_gtk_css_border_value_get_top (image->slice), source_height),
_gtk_css_number_value_get (_gtk_css_border_value_get_bottom (image->slice), source_height));
gtk_border_image_compute_border_size (horizontal_border,
- x,
- width,
+ rect->origin.x,
+ rect->size.width,
border_width[GTK_CSS_LEFT],
border_width[GTK_CSS_RIGHT],
_gtk_css_border_value_get_left (image->width),
_gtk_css_border_value_get_right (image->width));
gtk_border_image_compute_border_size (vertical_border,
- y,
- height,
+ rect->origin.y,
+ rect->size.height,
border_width[GTK_CSS_TOP],
border_width[GTK_CSS_BOTTOM],
_gtk_css_border_value_get_top (image->width),
@@ -423,12 +420,12 @@ set_stroke_style (cairo_t *cr,
}
static void
-render_frame_stroke (cairo_t *cr,
- GskRoundedRect *border_box,
- const double border_width[4],
- GdkRGBA colors[4],
- guint hidden_side,
- GtkBorderStyle stroke_style)
+render_frame_stroke (cairo_t *cr,
+ const GskRoundedRect *border_box,
+ const double border_width[4],
+ GdkRGBA colors[4],
+ guint hidden_side,
+ GtkBorderStyle stroke_style)
{
gboolean different_colors, different_borders;
GskRoundedRect stroke_box;
@@ -510,12 +507,12 @@ render_frame_stroke (cairo_t *cr,
}
static void
-snapshot_frame_stroke (GtkSnapshot *snapshot,
- GskRoundedRect *outline,
- const float border_width[4],
- GdkRGBA colors[4],
- guint hidden_side,
- GtkBorderStyle stroke_style)
+snapshot_frame_stroke (GtkSnapshot *snapshot,
+ const GskRoundedRect *outline,
+ const float border_width[4],
+ GdkRGBA colors[4],
+ guint hidden_side,
+ GtkBorderStyle stroke_style)
{
double double_width[4] = { border_width[0], border_width[1], border_width[2], border_width[3] };
cairo_t *cr;
@@ -539,11 +536,11 @@ color_shade (const GdkRGBA *color,
}
static void
-snapshot_border (GtkSnapshot *snapshot,
- GskRoundedRect *border_box,
- const float border_width[4],
- GdkRGBA colors[4],
- GtkBorderStyle border_style[4])
+snapshot_border (GtkSnapshot *snapshot,
+ const GskRoundedRect *border_box,
+ const float border_width[4],
+ GdkRGBA colors[4],
+ GtkBorderStyle border_style[4])
{
guint hidden_side = 0;
guint i, j;
@@ -661,136 +658,86 @@ snapshot_border (GtkSnapshot *snapshot,
}
void
-gtk_css_style_snapshot_border (GtkCssStyle *style,
- GtkSnapshot *snapshot,
- gdouble width,
- gdouble height)
+gtk_css_style_snapshot_border (GtkCssBoxes *boxes,
+ GtkSnapshot *snapshot)
{
GtkBorderImage border_image;
float border_width[4];
- border_width[0] = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 100);
- border_width[1] = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH), 100);
- border_width[2] = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH), 100);
- border_width[3] = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH), 100);
+ border_width[0] = _gtk_css_number_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 100);
+ border_width[1] = _gtk_css_number_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH), 100);
+ border_width[2] = _gtk_css_number_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH), 100);
+ border_width[3] = _gtk_css_number_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH), 100);
- if (gtk_border_image_init (&border_image, style))
+ if (gtk_border_image_init (&border_image, boxes->style))
{
cairo_t *cr;
- graphene_rect_t bounds;
- double double_width[4] = { border_width[0], border_width[1], border_width[2], border_width[3] };
+ const graphene_rect_t *bounds;
- graphene_rect_init (&bounds, 0, 0, width, height);
+ bounds = gtk_css_boxes_get_border_rect (boxes);
gtk_snapshot_push_debug (snapshot, "CSS border image");
- cr = gtk_snapshot_append_cairo (snapshot,
- &bounds);
- gtk_border_image_render (&border_image, double_width, cr, 0, 0, width, height);
+ cr = gtk_snapshot_append_cairo (snapshot, bounds);
+ gtk_border_image_render (&border_image, border_width, cr, bounds);
cairo_destroy (cr);
gtk_snapshot_pop (snapshot);
}
else
{
GtkBorderStyle border_style[4];
- GskRoundedRect border_box;
GdkRGBA colors[4];
graphene_simd4f_t alpha_test_vector;
/* Optimize the most common case of "This widget has no border" */
- if (border_width[0] == 0 &&
- border_width[1] == 0 &&
- border_width[2] == 0 &&
- border_width[3] == 0)
+ if (graphene_rect_equal (gtk_css_boxes_get_border_rect (boxes),
+ gtk_css_boxes_get_padding_rect (boxes)))
return;
- colors[0] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_COLOR));
- colors[1] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR));
- colors[2] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR));
- colors[3] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_LEFT_COLOR));
+ colors[0] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_TOP_COLOR));
+ colors[1] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR));
+ colors[2] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR));
+ colors[3] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_LEFT_COLOR));
alpha_test_vector = graphene_simd4f_init (colors[0].alpha, colors[1].alpha, colors[2].alpha, colors[3].alpha);
if (graphene_simd4f_is_zero4 (alpha_test_vector))
return;
- border_style[0] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_STYLE));
- border_style[1] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE));
- border_style[2] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE));
- border_style[3] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_LEFT_STYLE));
-
- gtk_rounded_boxes_init_for_style (&border_box, NULL, NULL, style, 0, 0, width, height);
+ border_style[0] = _gtk_css_border_style_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_TOP_STYLE));
+ border_style[1] = _gtk_css_border_style_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE));
+ border_style[2] = _gtk_css_border_style_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE));
+ border_style[3] = _gtk_css_border_style_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BORDER_LEFT_STYLE));
gtk_snapshot_push_debug (snapshot, "CSS border");
- snapshot_border (snapshot, &border_box, border_width, colors, border_style);
+ snapshot_border (snapshot,
+ gtk_css_boxes_get_border_box (boxes),
+ border_width,
+ colors,
+ border_style);
gtk_snapshot_pop (snapshot);
}
}
-static void
-compute_outline_rect (GtkCssStyle *style,
- gdouble x,
- gdouble y,
- gdouble width,
- gdouble height,
- cairo_rectangle_t *out_rect)
-{
- double offset, owidth;
-
- owidth = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_WIDTH), 100);
- offset = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_OFFSET), 100);
-
- if (width <= -2 * offset)
- {
- x += width / 2;
- out_rect->x = x - owidth;
- out_rect->width = 2 * owidth;
- }
- else
- {
- out_rect->x = x - offset - owidth;
- out_rect->width = width + 2 * (offset + owidth);
- }
-
- if (height <= -2 * offset)
- {
- y += height / 2;
- out_rect->y = y - owidth;
- out_rect->height = 2 * owidth;
- }
- else
- {
- out_rect->y = y - offset - owidth;
- out_rect->height = height + 2 * (offset + owidth);
- }
-
-}
-
void
-gtk_css_style_snapshot_outline (GtkCssStyle *style,
- GtkSnapshot *snapshot,
- gdouble width,
- gdouble height)
+gtk_css_style_snapshot_outline (GtkCssBoxes *boxes,
+ GtkSnapshot *snapshot)
{
GtkBorderStyle border_style[4];
- GskRoundedRect border_box;
float border_width[4];
GdkRGBA colors[4];
- border_style[0] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_STYLE));
+ border_style[0] = _gtk_css_border_style_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_OUTLINE_STYLE));
if (border_style[0] != GTK_BORDER_STYLE_NONE)
{
- cairo_rectangle_t rect;
-
- compute_outline_rect (style, 0, 0, width, height, &rect);
-
border_style[1] = border_style[2] = border_style[3] = border_style[0];
- border_width[0] = _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_WIDTH), 100);
+ border_width[0] = _gtk_css_number_value_get (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_OUTLINE_WIDTH), 100);
border_width[3] = border_width[2] = border_width[1] = border_width[0];
- colors[0] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_COLOR));
+ colors[0] = *_gtk_css_rgba_value_get_rgba (gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_OUTLINE_COLOR));
colors[3] = colors[2] = colors[1] = colors[0];
- _gtk_rounded_box_init_rect (&border_box, rect.x, rect.y, rect.width, rect.height);
- _gtk_rounded_box_apply_outline_radius_for_style (&border_box, style);
-
- snapshot_border (snapshot, &border_box, border_width, colors, border_style);
+ snapshot_border (snapshot,
+ gtk_css_boxes_get_outline_box (boxes),
+ border_width,
+ colors,
+ border_style);
}
}
diff --git a/gtk/gtkrenderborderprivate.h b/gtk/gtkrenderborderprivate.h
index 60cb7a016e..ded54fbd71 100644
--- a/gtk/gtkrenderborderprivate.h
+++ b/gtk/gtkrenderborderprivate.h
@@ -23,21 +23,16 @@
#define __GTK_RENDER_BORDER_H__
#include "gtkborder.h"
-#include "gtkcssimageprivate.h"
-#include "gtkcssvalueprivate.h"
+#include "gtkcssboxesprivate.h"
#include "gtktypes.h"
G_BEGIN_DECLS
-void gtk_css_style_snapshot_border (GtkCssStyle *style,
- GtkSnapshot *snapshot,
- gdouble width,
- gdouble height);
+void gtk_css_style_snapshot_border (GtkCssBoxes *boxes,
+ GtkSnapshot *snapshot);
-void gtk_css_style_snapshot_outline (GtkCssStyle *style,
- GtkSnapshot *snapshot,
- gdouble width,
- gdouble height);
+void gtk_css_style_snapshot_outline (GtkCssBoxes *boxes,
+ GtkSnapshot *snapshot);
G_END_DECLS
diff --git a/gtk/gtkroot.c b/gtk/gtkroot.c
new file mode 100644
index 0000000000..1907786e95
--- /dev/null
+++ b/gtk/gtkroot.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "config.h"
+
+#include "gtkrootprivate.h"
+
+/**
+ * SECTION:root
+ * @Title: GtkRoot
+ * @Short_description: Root widgets
+ * @See_also: #GtkWindow
+ *
+ * #GtkRoot is the interface implemented by all widgets that can act as a toplevel
+ * widget to a hierarchy of widgets. The root widget takes care of providing the
+ * connection to the windowing system and manages layout, drawing and event delivery
+ * for its widget hierarchy.
+ *
+ * The obvious example of a #GtkRoot is #GtkWindow.
+ */
+
+G_DEFINE_INTERFACE (GtkRoot, gtk_root, GTK_TYPE_WIDGET)
+
+static GdkDisplay *
+gtk_root_default_get_display (GtkRoot *self)
+{
+ return gdk_display_get_default ();
+}
+
+static GskRenderer *
+gtk_root_default_get_renderer (GtkRoot *self)
+{
+ return NULL;
+}
+
+static void
+gtk_root_default_get_surface_transform (GtkRoot *self,
+ int *x,
+ int *y)
+{
+ *x = 0;
+ *y = 0;
+}
+
+static void
+gtk_root_default_init (GtkRootInterface *iface)
+{
+ iface->get_display = gtk_root_default_get_display;
+ iface->get_renderer = gtk_root_default_get_renderer;
+ iface->get_surface_transform = gtk_root_default_get_surface_transform;
+}
+
+GdkDisplay *
+gtk_root_get_display (GtkRoot *self)
+{
+ GtkRootInterface *iface;
+
+ g_return_val_if_fail (GTK_IS_ROOT (self), NULL);
+
+ iface = GTK_ROOT_GET_IFACE (self);
+ return iface->get_display (self);
+}
+
+GskRenderer *
+gtk_root_get_renderer (GtkRoot *self)
+{
+ GtkRootInterface *iface;
+
+ g_return_val_if_fail (GTK_IS_ROOT (self), NULL);
+
+ iface = GTK_ROOT_GET_IFACE (self);
+ return iface->get_renderer (self);
+}
+
+void
+gtk_root_get_surface_transform (GtkRoot *self,
+ int *x,
+ int *y)
+{
+ GtkRootInterface *iface;
+
+ g_return_if_fail (GTK_IS_ROOT (self));
+ g_return_if_fail (x != 0);
+ g_return_if_fail (y != 0);
+
+ iface = GTK_ROOT_GET_IFACE (self);
+ return iface->get_surface_transform (self, x, y);
+}
diff --git a/gtk/gtkroot.h b/gtk/gtkroot.h
new file mode 100644
index 0000000000..e3494fcc7a
--- /dev/null
+++ b/gtk/gtkroot.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#ifndef __GTK_ROOT_H__
+#define __GTK_ROOT_H__
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_ROOT (gtk_root_get_type ())
+
+GDK_AVAILABLE_IN_ALL
+G_DECLARE_INTERFACE (GtkRoot, gtk_root, GTK, ROOT, GtkWidget)
+
+/**
+ * GtkRootIface:
+ *
+ * The list of functions that must be implemented for the #GtkRoot interface.
+ */
+struct _GtkRootInterface
+{
+ /*< private >*/
+ GTypeInterface g_iface;
+
+ /*< public >*/
+ GdkDisplay * (* get_display) (GtkRoot *self);
+ GskRenderer * (* get_renderer) (GtkRoot *self);
+
+ void (* get_surface_transform) (GtkRoot *root,
+ int *x,
+ int *y);
+};
+
+
+G_END_DECLS
+
+#endif /* __GTK_ROOT_H__ */
diff --git a/gtk/gtkrootprivate.h b/gtk/gtkrootprivate.h
new file mode 100644
index 0000000000..07ddc380e5
--- /dev/null
+++ b/gtk/gtkrootprivate.h
@@ -0,0 +1,16 @@
+#ifndef __GTK_ROOT_PRIVATE_H__
+#define __GTK_ROOT_PRIVATE_H__
+
+#include "gtkroot.h"
+
+G_BEGIN_DECLS
+
+GdkDisplay * gtk_root_get_display (GtkRoot *root);
+GskRenderer * gtk_root_get_renderer (GtkRoot *self);
+
+void gtk_root_get_surface_transform (GtkRoot *self,
+ int *x,
+ int *y);
+G_END_DECLS
+
+#endif /* __GTK_ROOT_PRIVATE_H__ */
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index 7eb12dd33e..3f7f100608 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -1263,14 +1263,15 @@ gtk_snapshot_render_background (GtkSnapshot *snapshot,
gdouble width,
gdouble height)
{
+ GtkCssBoxes boxes;
+
g_return_if_fail (snapshot != NULL);
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
- gtk_snapshot_offset (snapshot, x, y);
- gtk_css_style_snapshot_background (gtk_style_context_lookup_style (context),
- snapshot,
- width, height);
- gtk_snapshot_offset (snapshot, -x, -y);
+ gtk_css_boxes_init_border_box (&boxes,
+ gtk_style_context_lookup_style (context),
+ x, y, width, height);
+ gtk_css_style_snapshot_background (&boxes, snapshot);
}
/**
@@ -1294,14 +1295,15 @@ gtk_snapshot_render_frame (GtkSnapshot *snapshot,
gdouble width,
gdouble height)
{
+ GtkCssBoxes boxes;
+
g_return_if_fail (snapshot != NULL);
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
- gtk_snapshot_offset (snapshot, x, y);
- gtk_css_style_snapshot_border (gtk_style_context_lookup_style (context),
- snapshot,
- width, height);
- gtk_snapshot_offset (snapshot, -x, -y);
+ gtk_css_boxes_init_border_box (&boxes,
+ gtk_style_context_lookup_style (context),
+ x, y, width, height);
+ gtk_css_style_snapshot_border (&boxes, snapshot);
}
/**
@@ -1325,14 +1327,15 @@ gtk_snapshot_render_focus (GtkSnapshot *snapshot,
gdouble width,
gdouble height)
{
+ GtkCssBoxes boxes;
+
g_return_if_fail (snapshot != NULL);
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
- gtk_snapshot_offset (snapshot, x, y);
- gtk_css_style_snapshot_outline (gtk_style_context_lookup_style (context),
- snapshot,
- width, height);
- gtk_snapshot_offset (snapshot, -x, -y);
+ gtk_css_boxes_init_border_box (&boxes,
+ gtk_style_context_lookup_style (context),
+ x, y, width, height);
+ gtk_css_style_snapshot_outline (&boxes, snapshot);
}
/**
diff --git a/gtk/gtktypes.h b/gtk/gtktypes.h
index fc58058821..5d1218f189 100644
--- a/gtk/gtktypes.h
+++ b/gtk/gtktypes.h
@@ -39,6 +39,7 @@ typedef struct _GtkClipboard GtkClipboard;
typedef struct _GtkEventController GtkEventController;
typedef struct _GtkGesture GtkGesture;
typedef struct _GtkRequisition GtkRequisition;
+typedef struct _GtkRoot GtkRoot;
typedef struct _GtkSelectionData GtkSelectionData;
typedef struct _GtkSettings GtkSettings;
typedef GdkSnapshot GtkSnapshot;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 9207a46b1d..6f871e9ab0 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -34,6 +34,7 @@
#include "gtkbuildable.h"
#include "gtkbuilderprivate.h"
#include "gtkcontainerprivate.h"
+#include "gtkcssboxesprivate.h"
#include "gtkcssfiltervalueprivate.h"
#include "gtkcssfontvariationsvalueprivate.h"
#include "gtkcssnumbervalueprivate.h"
@@ -507,6 +508,7 @@ enum {
PROP_0,
PROP_NAME,
PROP_PARENT,
+ PROP_ROOT,
PROP_WIDTH_REQUEST,
PROP_HEIGHT_REQUEST,
PROP_VISIBLE,
@@ -602,6 +604,8 @@ static void gtk_widget_real_move_focus (GtkWidget
GtkDirectionType direction);
static gboolean gtk_widget_real_keynav_failed (GtkWidget *widget,
GtkDirectionType direction);
+static void gtk_widget_root (GtkWidget *widget);
+static void gtk_widget_unroot (GtkWidget *widget);
#ifdef G_ENABLE_CONSISTENCY_CHECKS
static void gtk_widget_verify_invariants (GtkWidget *widget);
static void gtk_widget_push_verify_invariants (GtkWidget *widget);
@@ -854,6 +858,18 @@ gtk_widget_real_grab_notify (GtkWidget *widget,
}
static void
+gtk_widget_real_root (GtkWidget *widget)
+{
+ gtk_widget_forall (widget, (GtkCallback) gtk_widget_root, NULL);
+}
+
+static void
+gtk_widget_real_unroot (GtkWidget *widget)
+{
+ gtk_widget_forall (widget, (GtkCallback) gtk_widget_unroot, NULL);
+}
+
+static void
gtk_widget_class_init (GtkWidgetClass *klass)
{
static GObjectNotifyContext cpn_context = { 0, NULL, NULL };
@@ -899,6 +915,8 @@ gtk_widget_class_init (GtkWidgetClass *klass)
klass->unmap = gtk_widget_real_unmap;
klass->realize = gtk_widget_real_realize;
klass->unrealize = gtk_widget_real_unrealize;
+ klass->root = gtk_widget_real_root;
+ klass->unroot = gtk_widget_real_unroot;
klass->size_allocate = gtk_widget_real_size_allocate;
klass->get_request_mode = gtk_widget_real_get_request_mode;
klass->measure = gtk_widget_real_measure;
@@ -948,6 +966,19 @@ gtk_widget_class_init (GtkWidgetClass *klass)
GTK_TYPE_WIDGET,
GTK_PARAM_READABLE|G_PARAM_EXPLICIT_NOTIFY);
+ /**
+ * GtkWidget:root:
+ *
+ * The #GtkRoot widget of the widget tree containing this widget or %NULL if
+ * the widget is not contained in a root widget.
+ */
+ widget_props[PROP_ROOT] =
+ g_param_spec_object ("root",
+ P_("Root widget"),
+ P_("The root widget in the widget tree."),
+ GTK_TYPE_ROOT,
+ GTK_PARAM_READABLE|G_PARAM_EXPLICIT_NOTIFY);
+
widget_props[PROP_WIDTH_REQUEST] =
g_param_spec_int ("width-request",
P_("Width request"),
@@ -2368,6 +2399,9 @@ gtk_widget_get_property (GObject *object,
case PROP_PARENT:
g_value_set_object (value, priv->parent);
break;
+ case PROP_ROOT:
+ g_value_set_object (value, priv->root);
+ break;
case PROP_WIDTH_REQUEST:
{
int w;
@@ -2810,10 +2844,6 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
priv->visible = gtk_widget_class_get_visible_by_default (g_class);
priv->child_visible = TRUE;
priv->name = NULL;
- priv->allocation.x = -1;
- priv->allocation.y = -1;
- priv->allocation.width = 0;
- priv->allocation.height = 0;
priv->user_alpha = 255;
priv->alpha = 255;
priv->surface = NULL;
@@ -2822,7 +2852,7 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
priv->last_child = NULL;
priv->prev_sibling = NULL;
priv->next_sibling = NULL;
- priv->allocated_baseline = -1;
+ priv->baseline = -1;
priv->allocated_size_baseline = -1;
priv->sensitive = TRUE;
@@ -2872,6 +2902,9 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class)
gtk_css_node_set_visible (priv->cssnode, priv->visible);
/* need to set correct type here, and only class has the correct type here */
gtk_css_node_set_widget_type (priv->cssnode, G_TYPE_FROM_CLASS (g_class));
+
+ if (g_type_is_a (G_TYPE_FROM_CLASS (g_class), GTK_TYPE_ROOT))
+ priv->root = (GtkRoot *) widget;
}
@@ -2999,6 +3032,46 @@ gtk_widget_new (GType type,
return widget;
}
+static void
+gtk_widget_root (GtkWidget *widget)
+{
+ GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
+ /* roots are rooted by default */
+ if (GTK_IS_ROOT (widget))
+ return;
+
+ g_assert (priv->root == NULL);
+ g_assert (!priv->realized);
+ g_assert (priv->parent);
+ g_assert (priv->parent->priv->root);
+
+ priv->root = priv->parent->priv->root;
+
+ GTK_WIDGET_GET_CLASS (widget)->root (widget);
+
+ g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_ROOT]);
+}
+
+static void
+gtk_widget_unroot (GtkWidget *widget)
+{
+ GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
+ /* roots are rooted by default and cannot be unrooted */
+ if (GTK_IS_ROOT (widget))
+ return;
+
+ g_assert (priv->root);
+ g_assert (!priv->realized);
+
+ GTK_WIDGET_GET_CLASS (widget)->unroot (widget);
+
+ priv->root = NULL;
+
+ g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_ROOT]);
+}
+
/**
* gtk_widget_unparent:
* @widget: a #GtkWidget
@@ -3044,12 +3117,15 @@ gtk_widget_unparent (GtkWidget *widget)
/* Reset the width and height here, to force reallocation if we
* get added back to a new parent.
*/
- priv->allocation.width = 0;
- priv->allocation.height = 0;
+ priv->width = 0;
+ priv->height = 0;
if (_gtk_widget_get_realized (widget))
gtk_widget_unrealize (widget);
+ if (priv->root)
+ gtk_widget_unroot (widget);
+
/* If we are unanchoring the child, we save around the toplevel
* to emit hierarchy changed
*/
@@ -3107,10 +3183,9 @@ gtk_widget_unparent (GtkWidget *widget)
gtk_list_list_model_item_removed (old_parent->priv->children_observer, old_prev_sibling);
if (toplevel)
- {
- _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
- g_object_unref (toplevel);
- }
+ _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
+
+ g_clear_object (&toplevel);
/* Now that the parent pointer is nullified and the hierarchy-changed
* already passed, go ahead and unset the parent window, if we are unparenting
@@ -4145,6 +4220,12 @@ gtk_widget_size_allocate (GtkWidget *widget,
real_allocation = *allocation;
+ baseline_changed = priv->allocated_size_baseline != baseline;
+ size_changed = (priv->allocated_size.width != real_allocation.width ||
+ priv->allocated_size.height != real_allocation.height);
+ position_changed = (priv->allocated_size.x != real_allocation.x ||
+ priv->allocated_size.y != real_allocation.y);
+
priv->allocated_size = *allocation;
priv->allocated_size_baseline = baseline;
@@ -4233,16 +4314,6 @@ gtk_widget_size_allocate (GtkWidget *widget,
real_allocation.height = MAX (1, real_allocation.height);
}
- baseline_changed = priv->allocated_baseline != baseline;
- size_changed = (priv->allocation.width != real_allocation.width ||
- priv->allocation.height != real_allocation.height);
- position_changed = (priv->allocation.x != real_allocation.x ||
- priv->allocation.y != real_allocation.y);
-
- /* Set the widget allocation to real_allocation now, pass the smaller allocation to the vfunc */
- priv->allocation = real_allocation;
- priv->allocated_baseline = baseline;
-
if (!alloc_needed && !size_changed && !baseline_changed)
{
/* Still have to move the window... */
@@ -4265,6 +4336,9 @@ gtk_widget_size_allocate (GtkWidget *widget,
get_box_border (style, &border);
get_box_padding (style, &padding);
+ priv->transform.x = real_allocation.x + margin.left + border.left + padding.left;
+ priv->transform.y = real_allocation.y + margin.top + border.top + padding.top;
+
/* Since gtk_widget_measure does it for us, we can be sure here that
* the given alloaction is large enough for the css margin/bordder/padding */
real_allocation.x = 0;
@@ -4277,6 +4351,10 @@ gtk_widget_size_allocate (GtkWidget *widget,
if (baseline >= 0)
baseline -= margin.top + border.top + padding.top;
+ priv->width = real_allocation.width;
+ priv->height = real_allocation.height;
+ priv->baseline = baseline;
+
if (g_signal_has_handler_pending (widget, widget_signals[SIZE_ALLOCATE], 0, FALSE))
g_signal_emit (widget, widget_signals[SIZE_ALLOCATE], 0,
real_allocation.width,
@@ -4380,23 +4458,8 @@ gtk_widget_get_origin_relative_to_parent (GtkWidget *widget,
int *origin_x,
int *origin_y)
{
- GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
- GtkBorder margin, border, padding;
- GtkCssStyle *style;
-
- style = gtk_css_node_get_style (priv->cssnode);
- get_box_margin (style, &margin);
- get_box_border (style, &border);
- get_box_padding (style, &padding);
-
- /* allocation is relative to the parent's origin */
- *origin_x = priv->allocation.x;
- *origin_y = priv->allocation.y;
-
- /* ... but points to the upper left, excluding widget margins
- * but including all the css properties */
- *origin_x += margin.left + border.left + padding.left;
- *origin_y += margin.top + border.top + padding.top;
+ *origin_x = widget->priv->transform.x;
+ *origin_y = widget->priv->transform.y;
}
/**
@@ -5008,18 +5071,6 @@ gtk_widget_real_mnemonic_activate (GtkWidget *widget,
return TRUE;
}
-static GskRenderer *
-gtk_widget_get_renderer (GtkWidget *widget)
-{
- GtkWidget *toplevel;
-
- toplevel = _gtk_widget_get_toplevel (widget);
- if (_gtk_widget_is_toplevel (toplevel))
- return gtk_window_get_renderer (GTK_WINDOW (toplevel));
-
- return NULL;
-}
-
#define WIDGET_REALIZED_FOR_EVENT(widget, event) \
(event->any.type == GDK_FOCUS_CHANGE || _gtk_widget_get_realized(widget))
@@ -6185,10 +6236,10 @@ _gtk_widget_set_visible_flag (GtkWidget *widget,
if (!visible)
{
- priv->allocation.x = -1;
- priv->allocation.y = -1;
- priv->allocation.width = 0;
- priv->allocation.height = 0;
+ priv->transform.x = 0;
+ priv->transform.y = 0;
+ priv->width = 0;
+ priv->height = 0;
memset (&priv->allocated_size, 0, sizeof (priv->allocated_size));
priv->allocated_size_baseline = 0;
gtk_widget_update_paintables (widget);
@@ -6278,8 +6329,8 @@ gtk_widget_set_has_surface (GtkWidget *widget,
priv->no_surface_set = TRUE;
/* GdkSurface has a min size of 1×1 */
- priv->allocation.width = 1;
- priv->allocation.height = 1;
+ priv->width = 1;
+ priv->height = 1;
}
/**
@@ -6315,20 +6366,9 @@ gtk_widget_get_has_surface (GtkWidget *widget)
gboolean
gtk_widget_is_toplevel (GtkWidget *widget)
{
- GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
- return priv->toplevel;
-}
-
-void
-_gtk_widget_set_is_toplevel (GtkWidget *widget,
- gboolean is_toplevel)
-{
- GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-
- priv->toplevel = is_toplevel;
+ return GTK_IS_ROOT (widget);
}
/**
@@ -6603,7 +6643,11 @@ gtk_widget_reposition_after (GtkWidget *widget,
}
if (priv->parent->priv->anchored && prev_parent == NULL)
- _gtk_widget_propagate_hierarchy_changed (widget, NULL);
+ {
+ _gtk_widget_propagate_hierarchy_changed (widget, NULL);
+ }
+ if (parent->priv->root && priv->root == NULL)
+ gtk_widget_root (widget);
if (prev_parent == NULL)
g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_PARENT]);
@@ -6687,6 +6731,25 @@ gtk_widget_get_parent (GtkWidget *widget)
return priv->parent;
}
+/**
+ * gtk_widget_get_root:
+ * @widget: a #GtkWidget
+ *
+ * Returns the #GtkRoot widget of @widget or %NULL if the widget is not contained
+ * inside a widget tree with a root widget.
+ *
+ * #GtkRoot widgets will return themselves here.
+ *
+ * Returns: (transfer none) (nullable): the root widget of @widget, or %NULL
+ **/
+GtkRoot *
+gtk_widget_get_root (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+ return _gtk_widget_get_root (widget);
+}
+
static void
gtk_widget_real_direction_changed (GtkWidget *widget,
GtkTextDirection previous_direction)
@@ -6899,7 +6962,7 @@ gtk_widget_verify_invariants (GtkWidget *widget)
g_warning ("%s %p is mapped but not visible",
G_OBJECT_TYPE_NAME (widget), widget);
- if (!priv->toplevel)
+ if (!GTK_IS_ROOT (widget))
{
if (!priv->child_visible)
g_warning ("%s %p is mapped but not child_visible",
@@ -6947,7 +7010,7 @@ gtk_widget_verify_invariants (GtkWidget *widget)
G_OBJECT_TYPE_NAME (widget), widget);
#endif
}
- else if (!priv->toplevel)
+ else if (!GTK_IS_ROOT (widget))
{
/* No parent or parent not realized on non-toplevel implies... */
@@ -6969,7 +7032,7 @@ gtk_widget_verify_invariants (GtkWidget *widget)
G_OBJECT_TYPE_NAME (parent), parent,
G_OBJECT_TYPE_NAME (widget), widget);
}
- else if (!widget->priv->toplevel)
+ else if (!GTK_IS_ROOT (widget))
{
/* No parent or parent not mapped on non-toplevel implies... */
@@ -11130,11 +11193,19 @@ gtk_widget_get_allocation (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+ const graphene_rect_t *margin_rect;
+ GtkCssBoxes boxes;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (allocation != NULL);
- *allocation = priv->allocation;
+ gtk_css_boxes_init (&boxes, widget);
+ margin_rect = gtk_css_boxes_get_margin_rect (&boxes);
+
+ allocation->x = priv->transform.x + ceil (margin_rect->origin.x);
+ allocation->y = priv->transform.y + ceil (margin_rect->origin.y);
+ allocation->width = ceil (margin_rect->size.width);
+ allocation->height = ceil (margin_rect->size.height);
}
/**
@@ -11216,18 +11287,12 @@ gtk_widget_pick (GtkWidget *widget,
case GTK_OVERFLOW_HIDDEN:
{
- GtkBorder margin, border, padding;
- GtkCssStyle *style;
-
- style = gtk_css_node_get_style (priv->cssnode);
- get_box_margin (style, &margin);
- get_box_border (style, &border);
- get_box_padding (style, &padding);
-
- if (x < -padding.left ||
- y < -padding.top ||
- x >= priv->allocation.width - margin.left - margin.right - border.left - border.right - padding.left ||
- y >= priv->allocation.height - margin.top - margin.bottom - border.top - border.bottom - padding.top)
+ GtkCssBoxes boxes;
+
+ gtk_css_boxes_init (&boxes, widget);
+
+ if (!graphene_rect_contains_point (gtk_css_boxes_get_padding_rect (&boxes),
+ &GRAPHENE_POINT_INIT (x, y)))
return NULL;
}
break;
@@ -11259,39 +11324,26 @@ gtk_widget_compute_bounds (GtkWidget *widget,
GtkWidget *target,
graphene_rect_t *out_bounds)
{
- GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
- GtkBorder margin, border, padding;
- GtkCssStyle *style;
- GtkAllocation alloc;
+ GtkCssBoxes boxes;
+ int x, y;
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (GTK_IS_WIDGET (target), FALSE);
g_return_val_if_fail (out_bounds != NULL, FALSE);
- style = gtk_css_node_get_style (priv->cssnode);
- get_box_margin (style, &margin);
- get_box_border (style, &border);
- get_box_padding (style, &padding);
-
- alloc.x = - (padding.left + border.left);
- alloc.y = - (padding.top + border.top);
- alloc.width = priv->allocation.width - margin.left - margin.right;
- alloc.height = priv->allocation.height -margin.top - margin.bottom;
-
if (!gtk_widget_translate_coordinates (widget,
target,
- alloc.x, alloc.y,
- &alloc.x, &alloc.y))
+ 0, 0,
+ &x, &y))
{
graphene_rect_init_from_rect (out_bounds, graphene_rect_zero ());
return FALSE;
}
- graphene_rect_init (out_bounds,
- alloc.x,
- alloc.y,
- alloc.width,
- alloc.height);
+ gtk_css_boxes_init (&boxes, widget);
+ graphene_rect_offset_r (gtk_css_boxes_get_border_rect (&boxes),
+ x, y,
+ out_bounds);
return TRUE;
}
@@ -11307,11 +11359,13 @@ gtk_widget_compute_bounds (GtkWidget *widget,
int
gtk_widget_get_allocated_width (GtkWidget *widget)
{
- GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+ GtkCssBoxes boxes;
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
- return priv->allocation.width;
+ gtk_css_boxes_init (&boxes, widget);
+
+ return gtk_css_boxes_get_margin_rect (&boxes)->size.width;
}
/**
@@ -11325,11 +11379,13 @@ gtk_widget_get_allocated_width (GtkWidget *widget)
int
gtk_widget_get_allocated_height (GtkWidget *widget)
{
- GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+ GtkCssBoxes boxes;
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
- return priv->allocation.height;
+ gtk_css_boxes_init (&boxes, widget);
+
+ return gtk_css_boxes_get_margin_rect (&boxes)->size.height;
}
/**
@@ -11352,7 +11408,7 @@ gtk_widget_get_allocated_baseline (GtkWidget *widget)
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
- if (priv->allocated_baseline == -1)
+ if (priv->baseline == -1)
return -1;
style = gtk_css_node_get_style (priv->cssnode);
@@ -11360,7 +11416,7 @@ gtk_widget_get_allocated_baseline (GtkWidget *widget)
get_box_border (style, &border);
get_box_padding (style, &padding);
- return priv->allocated_baseline - margin.top - border.top - padding.top;
+ return priv->baseline - margin.top - border.top - padding.top;
}
/**
@@ -12948,36 +13004,24 @@ gtk_widget_reset_controllers (GtkWidget *widget)
}
static inline void
-gtk_widget_maybe_add_debug_render_nodes (GtkWidget *widget,
- GtkSnapshot *snapshot)
+gtk_widget_maybe_add_debug_render_nodes (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GdkDisplay *display = _gtk_widget_get_display (widget);
- GtkCssStyle *style;
- GtkBorder margin, border, padding;
-
- /* We should be offset to priv->allocation at this point */
if (GTK_DISPLAY_DEBUG_CHECK (display, BASELINES))
{
- int baseline = gtk_widget_get_allocated_baseline (widget);
-
- if (baseline != -1)
+ if (priv->baseline != -1)
{
GdkRGBA red = {1, 0, 0, 1};
graphene_rect_t bounds;
- style = gtk_css_node_get_style (priv->cssnode);
- get_box_margin (style, &margin);
- get_box_border (style, &border);
- get_box_padding (style, &padding);
-
/* Baselines are relative to the widget's origin,
* and we are offset to the widget's allocation here */
graphene_rect_init (&bounds,
- 0,
- margin.top + border.top + padding.top + baseline,
- priv->allocation.width, 1);
+ 0, priv->baseline,
+ priv->width, 1);
gtk_snapshot_append_color (snapshot,
&red,
&bounds);
@@ -12992,7 +13036,7 @@ gtk_widget_maybe_add_debug_render_nodes (GtkWidget *widget,
graphene_rect_init (&bounds,
0, 0,
- priv->allocation.width, priv->allocation.height);
+ priv->width, priv->height);
gtk_snapshot_append_color (snapshot,
&blue,
@@ -13009,74 +13053,43 @@ gtk_widget_create_render_node (GtkWidget *widget,
{
GtkWidgetClass *klass = GTK_WIDGET_GET_CLASS (widget);
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+ GtkCssBoxes boxes;
GtkCssValue *filter_value;
double opacity;
- GtkCssStyle *style;
- GtkAllocation allocation;
- GtkBorder margin, border, padding;
GtkSnapshot *snapshot;
opacity = priv->alpha / 255.0;
if (opacity <= 0.0)
return NULL;
+ gtk_css_boxes_init (&boxes, widget);
snapshot = gtk_snapshot_new_with_parent (parent_snapshot);
- _gtk_widget_get_allocation (widget, &allocation);
gtk_snapshot_push_debug (snapshot,
- "RenderNode for %s %p @ %d x %d",
- G_OBJECT_TYPE_NAME (widget), widget,
- allocation.width, allocation.height);
+ "RenderNode for %s %p",
+ G_OBJECT_TYPE_NAME (widget), widget);
filter_value = _gtk_style_context_peek_property (_gtk_widget_get_style_context (widget), GTK_CSS_PROPERTY_FILTER);
gtk_css_filter_value_push_snapshot (filter_value, snapshot);
- style = gtk_css_node_get_style (priv->cssnode);
- get_box_margin (style, &margin);
- get_box_border (style, &border);
- get_box_padding (style, &padding);
-
if (opacity < 1.0)
gtk_snapshot_push_opacity (snapshot, opacity);
if (!GTK_IS_WINDOW (widget))
{
- gtk_snapshot_offset (snapshot, margin.left, margin.top);
- gtk_css_style_snapshot_background (style,
- snapshot,
- allocation.width - margin.left - margin.right,
- allocation.height - margin.top - margin.bottom);
- gtk_css_style_snapshot_border (style,
- snapshot,
- allocation.width - margin.left - margin.right,
- allocation.height - margin.top - margin.bottom);
- gtk_snapshot_offset (snapshot, - margin.left, - margin.top);
+ gtk_css_style_snapshot_background (&boxes, snapshot);
+ gtk_css_style_snapshot_border (&boxes, snapshot);
}
- /* Offset to content allocation */
- gtk_snapshot_offset (snapshot, margin.left + padding.left + border.left, margin.top + border.top + padding.top);
-
if (priv->overflow == GTK_OVERFLOW_HIDDEN)
- {
- gtk_snapshot_push_clip (snapshot,
- &GRAPHENE_RECT_INIT (- padding.left,
- - padding.top,
- allocation.width - margin.left - margin.right - border.left - border.right,
- allocation.height - margin.top - margin.bottom - border.top - border.bottom));
- }
+ gtk_snapshot_push_clip (snapshot, gtk_css_boxes_get_padding_rect (&boxes));
klass->snapshot (widget, snapshot);
if (priv->overflow == GTK_OVERFLOW_HIDDEN)
gtk_snapshot_pop (snapshot);
- gtk_snapshot_offset (snapshot, - (padding.left + border.left), -(border.top + padding.top));
-
- gtk_css_style_snapshot_outline (style,
- snapshot,
- allocation.width - margin.left - margin.right,
- allocation.height - margin.top - margin.bottom);
- gtk_snapshot_offset (snapshot, - margin.left, - margin.top);
+ gtk_css_style_snapshot_outline (&boxes, snapshot);
if (opacity < 1.0)
gtk_snapshot_pop (snapshot);
@@ -13137,17 +13150,24 @@ gtk_widget_render (GtkWidget *widget,
GtkSnapshot *snapshot;
GskRenderer *renderer;
GskRenderNode *root;
+ int x, y;
+
+ if (!GTK_IS_ROOT (widget))
+ return;
/* We only render double buffered on native windows */
if (!gdk_surface_has_native (surface))
return;
- renderer = gtk_widget_get_renderer (widget);
+ renderer = gtk_root_get_renderer (GTK_ROOT (widget));
if (renderer == NULL)
return;
snapshot = gtk_snapshot_new ();
+ gtk_root_get_surface_transform (GTK_ROOT (widget), &x, &y);
+ gtk_snapshot_offset (snapshot, x, y);
gtk_widget_snapshot (widget, snapshot);
+ gtk_snapshot_offset (snapshot, -x, -y);
root = gtk_snapshot_free_to_node (snapshot);
if (root != NULL)
@@ -13459,14 +13479,12 @@ gtk_widget_snapshot_child (GtkWidget *widget,
GtkWidget *child,
GtkSnapshot *snapshot)
{
- GtkWidgetPrivate *priv = gtk_widget_get_instance_private (child);
int x, y;
g_return_if_fail (_gtk_widget_get_parent (child) == widget);
g_return_if_fail (snapshot != NULL);
- x = priv->allocation.x;
- y = priv->allocation.y;
+ gtk_widget_get_origin_relative_to_parent (child, &x, &y);
gtk_snapshot_offset (snapshot, x, y);
gtk_widget_snapshot (child, snapshot);
@@ -13658,20 +13676,10 @@ int
gtk_widget_get_width (GtkWidget *widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
- GtkBorder margin, border, padding;
- GtkCssStyle *style;
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
- style = gtk_css_node_get_style (priv->cssnode);
- get_box_margin (style, &margin);
- get_box_border (style, &border);
- get_box_padding (style, &padding);
-
- return priv->allocation.width -
- margin.left - margin.right -
- border.left - border.right -
- padding.left - padding.right;
+ return priv->width;
}
/**
@@ -13688,18 +13696,8 @@ int
gtk_widget_get_height (GtkWidget *widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
- GtkBorder margin, border, padding;
- GtkCssStyle *style;
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
- style = gtk_css_node_get_style (priv->cssnode);
- get_box_margin (style, &margin);
- get_box_border (style, &border);
- get_box_padding (style, &padding);
-
- return priv->allocation.height -
- margin.top - margin.bottom -
- border.top - border.bottom -
- padding.top - padding.bottom;
+ return priv->height;
}
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 9b89f70246..7e6b91b041 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -152,6 +152,9 @@ struct _GtkWidget
* widget is destroyed, which means that gtk_widget_unrealize() has
* been called or the widget has been unmapped (that is, it is going
* to be hidden).
+ * @root: Called when the widget gets added to a #GtkRoot widget.
+ * @unroot: Called when the widget is about to be removed from its
+ * #GtkRoot widget.
* @size_allocate: Signal emitted to get the widget allocation.
* @state_flags_changed: Signal emitted when the widget state changes,
* see gtk_widget_get_state_flags().
@@ -247,6 +250,8 @@ struct _GtkWidgetClass
void (* unmap) (GtkWidget *widget);
void (* realize) (GtkWidget *widget);
void (* unrealize) (GtkWidget *widget);
+ void (* root) (GtkWidget *widget);
+ void (* unroot) (GtkWidget *widget);
void (* size_allocate) (GtkWidget *widget,
int width,
int height,
@@ -559,13 +564,16 @@ GDK_AVAILABLE_IN_ALL
void gtk_widget_set_parent (GtkWidget *widget,
GtkWidget *parent);
GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_widget_get_parent (GtkWidget *widget);
+GtkWidget * gtk_widget_get_parent (GtkWidget *widget);
+
+GDK_AVAILABLE_IN_ALL
+GtkRoot * gtk_widget_get_root (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
void gtk_widget_set_parent_surface (GtkWidget *widget,
GdkSurface *parent_surface);
GDK_AVAILABLE_IN_ALL
-GdkSurface * gtk_widget_get_parent_surface (GtkWidget *widget);
+GdkSurface * gtk_widget_get_parent_surface (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
void gtk_widget_set_child_visible (GtkWidget *widget,
diff --git a/gtk/gtkwidgetpaintable.c b/gtk/gtkwidgetpaintable.c
index 976b29d2c7..531b1332fc 100644
--- a/gtk/gtkwidgetpaintable.c
+++ b/gtk/gtkwidgetpaintable.c
@@ -92,13 +92,15 @@ gtk_widget_paintable_paintable_snapshot (GdkPaintable *paintable,
else if (self->snapshot_count > 0)
{
graphene_matrix_t transform;
+ graphene_rect_t bounds;
gtk_snapshot_push_clip (snapshot,
&GRAPHENE_RECT_INIT(0, 0, width, height));
- graphene_matrix_init_scale (&transform,
- width / gtk_widget_get_allocated_width (self->widget),
- height / gtk_widget_get_allocated_height (self->widget),
- 1.0);
+ gtk_widget_compute_bounds (self->widget, self->widget, &bounds);
+ graphene_matrix_init_from_2d (&transform,
+ width / bounds.size.width, 0.0,
+ 0.0, height / bounds.size.height,
+ bounds.origin.x, bounds.origin.y);
gtk_snapshot_push_transform (snapshot, &transform);
gtk_widget_snapshot (self->widget, snapshot);
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 26c33ba0bc..35753b6736 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -32,6 +32,7 @@
#include "gtkcsstypesprivate.h"
#include "gtkeventcontroller.h"
#include "gtklistlistmodelprivate.h"
+#include "gtkrootprivate.h"
#include "gtksizerequestcacheprivate.h"
#include "gtkwindowprivate.h"
#include "gtkinvisibleprivate.h"
@@ -55,7 +56,6 @@ struct _GtkWidgetPrivate
#endif
guint in_destruction : 1;
- guint toplevel : 1;
guint anchored : 1;
guint no_surface : 1;
guint no_surface_set : 1;
@@ -124,6 +124,11 @@ struct _GtkWidgetPrivate
*/
gchar *name;
+ /* The root this widget belongs to or %NULL if widget is not
+ * rooted or is a #GtkRoot itself.
+ */
+ GtkRoot *root;
+
/* The list of attached windows to this widget.
* We keep a list in order to call reset_style to all of them,
* recursively.
@@ -141,8 +146,13 @@ struct _GtkWidgetPrivate
/* The widget's allocated size */
GtkAllocation allocated_size;
gint allocated_size_baseline;
- GtkAllocation allocation;
- gint allocated_baseline;
+ struct {
+ int x;
+ int y;
+ } transform;
+ int width;
+ int height;
+ int baseline;
/* The widget's requested sizes */
SizeRequestCache requests;
@@ -221,8 +231,6 @@ void _gtk_widget_set_has_default (GtkWidget *widget,
gboolean has_default);
void _gtk_widget_set_has_grab (GtkWidget *widget,
gboolean has_grab);
-void _gtk_widget_set_is_toplevel (GtkWidget *widget,
- gboolean is_toplevel);
void _gtk_widget_grab_notify (GtkWidget *widget,
gboolean was_grabbed);
@@ -385,7 +393,7 @@ _gtk_widget_get_realized (GtkWidget *widget)
static inline gboolean
_gtk_widget_is_toplevel (GtkWidget *widget)
{
- return widget->priv->toplevel;
+ return GTK_IS_ROOT (widget);
}
static inline GtkStateFlags
@@ -414,20 +422,21 @@ _gtk_widget_get_toplevel (GtkWidget *widget)
return widget;
}
+static inline GtkRoot *
+_gtk_widget_get_root (GtkWidget *widget)
+{
+ return widget->priv->root;
+}
+
static inline GdkDisplay *
_gtk_widget_get_display (GtkWidget *widget)
{
- GtkWidget *toplevel = _gtk_widget_get_toplevel (widget);
+ GtkRoot *root = _gtk_widget_get_root (widget);
- if (_gtk_widget_is_toplevel (toplevel))
- {
- if (GTK_IS_WINDOW (toplevel))
- return gtk_window_get_display (GTK_WINDOW (toplevel));
- else if (GTK_IS_INVISIBLE (toplevel))
- return gtk_invisible_get_display (GTK_INVISIBLE (widget));
- }
+ if (root == NULL)
+ return gdk_display_get_default ();
- return gdk_display_get_default ();
+ return gtk_root_get_display (root);
}
static inline GtkStyleContext *
@@ -451,13 +460,6 @@ _gtk_widget_get_surface (GtkWidget *widget)
return widget->priv->surface;
}
-static inline void
-_gtk_widget_get_allocation (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- *allocation = widget->priv->allocation;
-}
-
static inline GtkWidget *
_gtk_widget_get_prev_sibling (GtkWidget *widget)
{
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index b101fc7376..ab5061d5f4 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -61,6 +61,7 @@
#include "gtkpointerfocusprivate.h"
#include "gtkpopoverprivate.h"
#include "gtkprivate.h"
+#include "gtkroot.h"
#include "gtkseparatormenuitem.h"
#include "gtksettings.h"
#include "gtksnapshot.h"
@@ -432,7 +433,6 @@ static void gtk_window_focus_out (GtkWidget *widget);
static void surface_state_changed (GtkWidget *widget);
static void gtk_window_remove (GtkContainer *container,
GtkWidget *widget);
-static void gtk_window_check_resize (GtkContainer *container);
static void gtk_window_forall (GtkContainer *container,
GtkCallback callback,
gpointer callback_data);
@@ -562,6 +562,9 @@ static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
const gchar *tagname,
gpointer user_data);
+/* GtkRoot */
+static void gtk_window_root_interface_init (GtkRootInterface *iface);
+
static void ensure_state_flag_backdrop (GtkWidget *widget);
static void unset_titlebar (GtkWindow *window);
static void on_titlebar_title_notify (GtkHeaderBar *titlebar,
@@ -576,7 +579,9 @@ static void gtk_window_update_debugging (void);
G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
G_ADD_PRIVATE (GtkWindow)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
- gtk_window_buildable_interface_init))
+ gtk_window_buildable_interface_init)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ROOT,
+ gtk_window_root_interface_init))
static void
add_tab_bindings (GtkBindingSet *binding_set,
@@ -809,7 +814,6 @@ gtk_window_class_init (GtkWindowClass *klass)
container_class->add = gtk_window_add;
container_class->remove = gtk_window_remove;
- container_class->check_resize = gtk_window_check_resize;
container_class->forall = gtk_window_forall;
klass->set_focus = gtk_window_real_set_focus;
@@ -1724,7 +1728,7 @@ edge_under_coordinates (GtkWindow *window,
(priv->edge_constraints & constraints) != constraints)
return FALSE;
- _gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
+ gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
context = _gtk_widget_get_style_context (GTK_WIDGET (window));
gtk_style_context_save_to_node (context, priv->decoration_node);
@@ -1862,7 +1866,6 @@ gtk_window_init (GtkWindow *window)
widget = GTK_WIDGET (window);
gtk_widget_set_has_surface (widget, TRUE);
- _gtk_widget_set_is_toplevel (widget, TRUE);
_gtk_widget_set_anchored (widget, TRUE);
priv->title = NULL;
@@ -2495,6 +2498,50 @@ gtk_window_buildable_custom_finished (GtkBuildable *buildable,
}
}
+static GdkDisplay *
+gtk_window_root_get_display (GtkRoot *root)
+{
+ GtkWindow *window = GTK_WINDOW (root);
+ GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+
+ return priv->display;
+}
+
+static GskRenderer *
+gtk_window_root_get_renderer (GtkRoot *root)
+{
+ GtkWindow *self = GTK_WINDOW (root);
+ GtkWindowPrivate *priv = gtk_window_get_instance_private (self);
+
+ return priv->renderer;
+}
+
+static void
+gtk_window_root_get_surface_transform (GtkRoot *root,
+ int *x,
+ int *y)
+{
+ GtkWindow *self = GTK_WINDOW (root);
+ GtkStyleContext *context;
+ GtkBorder margin, border, padding;
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (self));
+ gtk_style_context_get_margin (context, &margin);
+ gtk_style_context_get_border (context, &border);
+ gtk_style_context_get_padding (context, &padding);
+
+ *x = margin.left + border.left + padding.left;
+ *y = margin.top + border.top + padding.top;
+}
+
+static void
+gtk_window_root_interface_init (GtkRootInterface *iface)
+{
+ iface->get_display = gtk_window_root_get_display;
+ iface->get_renderer = gtk_window_root_get_renderer;
+ iface->get_surface_transform = gtk_window_root_get_surface_transform;
+}
+
/**
* gtk_window_new:
* @type: type of window
@@ -5224,7 +5271,7 @@ gtk_window_move (GtkWindow *window,
{
GtkAllocation allocation;
- _gtk_widget_get_allocation (widget, &allocation);
+ gtk_widget_get_allocation (widget, &allocation);
/* we have now sent a request with this position
* with currently-active constraints, so toggle flag.
@@ -5704,7 +5751,6 @@ gtk_window_show (GtkWidget *widget)
{
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
- GtkContainer *container = GTK_CONTAINER (window);
if (!_gtk_widget_is_toplevel (GTK_WIDGET (widget)))
{
@@ -5718,7 +5764,7 @@ gtk_window_show (GtkWidget *widget)
gtk_widget_realize (widget);
- gtk_container_check_resize (container);
+ gtk_window_check_resize (window);
gtk_widget_map (widget);
@@ -6017,7 +6063,7 @@ popover_get_rect (GtkWindowPopover *popover,
gdouble min, max;
gtk_widget_get_preferred_size (popover->widget, NULL, &req);
- _gtk_widget_get_allocation (GTK_WIDGET (window), &win_alloc);
+ gtk_widget_get_allocation (GTK_WIDGET (window), &win_alloc);
get_shadow_width (window, &win_border);
win_alloc.x += win_border.left;
@@ -6403,7 +6449,7 @@ gtk_window_realize (GtkWidget *widget)
g_return_if_fail (!_gtk_widget_get_realized (widget));
}
- _gtk_widget_get_allocation (widget, &allocation);
+ gtk_widget_get_allocation (widget, &allocation);
if (priv->hardcoded_surface)
{
@@ -6781,7 +6827,7 @@ gtk_window_configure (GtkWindow *window,
* have been a queued resize from child widgets, and so we
* need to reallocate our children in case *they* changed.
*/
- _gtk_widget_get_allocation (widget, &allocation);
+ gtk_widget_get_allocation (widget, &allocation);
if (priv->configure_request_count == 0 &&
(allocation.width == width && allocation.height == height))
{
@@ -7002,7 +7048,7 @@ get_active_region_type (GtkWindow *window, gint x, gint y)
gtk_widget_get_visible (priv->title_box) &&
gtk_widget_get_child_visible (priv->title_box))
{
- _gtk_widget_get_allocation (priv->title_box, &allocation);
+ gtk_widget_get_allocation (priv->title_box, &allocation);
if (allocation.x <= x && allocation.x + allocation.width > x &&
allocation.y <= y && allocation.y + allocation.height > y)
return GTK_WINDOW_REGION_TITLE;
@@ -7157,13 +7203,15 @@ gtk_window_remove (GtkContainer *container,
GTK_CONTAINER_CLASS (gtk_window_parent_class)->remove (container, widget);
}
-static void
-gtk_window_check_resize (GtkContainer *container)
+void
+gtk_window_check_resize (GtkWindow *self)
{
- if (!_gtk_widget_get_alloc_needed (GTK_WIDGET (container)))
- GTK_CONTAINER_CLASS (gtk_window_parent_class)->check_resize (container);
- else if (gtk_widget_get_visible (GTK_WIDGET (container)))
- gtk_window_move_resize (GTK_WINDOW (container));
+ GtkWidget *widget = GTK_WIDGET (self);
+
+ if (!_gtk_widget_get_alloc_needed (widget))
+ gtk_widget_ensure_allocate (widget);
+ else if (gtk_widget_get_visible (widget))
+ gtk_window_move_resize (self);
}
static void
@@ -7380,7 +7428,7 @@ gtk_window_style_updated (GtkWidget *widget)
GtkAllocation allocation;
GtkBorder window_border;
- _gtk_widget_get_allocation (widget, &allocation);
+ gtk_widget_get_allocation (widget, &allocation);
get_shadow_width (window, &window_border);
update_opaque_region (window, &window_border, &allocation);
@@ -7926,7 +7974,7 @@ gtk_window_compute_configure_request (GtkWindow *window,
gdk_surface_get_origin (surface, &ox, &oy);
- _gtk_widget_get_allocation (parent_widget, &allocation);
+ gtk_widget_get_allocation (parent_widget, &allocation);
x = ox + (allocation.width - w) / 2;
y = oy + (allocation.height - h) / 2;
@@ -9427,14 +9475,6 @@ gtk_window_on_theme_variant_changed (GtkSettings *settings,
}
#endif
-GdkDisplay *
-gtk_window_get_display (GtkWindow *window)
-{
- GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-
- return priv->display;
-}
-
/**
* gtk_window_is_active:
* @window: a #GtkWindow
@@ -10557,14 +10597,6 @@ gtk_window_unexport_handle (GtkWindow *window)
#endif
}
-GskRenderer *
-gtk_window_get_renderer (GtkWindow *window)
-{
- GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-
- return priv->renderer;
-}
-
static void
gtk_window_add_pointer_focus (GtkWindow *window,
GtkPointerFocus *focus)
diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h
index 1de4e0bedb..de0c853f77 100644
--- a/gtk/gtkwindowprivate.h
+++ b/gtk/gtkwindowprivate.h
@@ -54,6 +54,7 @@ void _gtk_window_set_allocation (GtkWindow *window,
int width,
int height,
GtkAllocation *allocation_out);
+void gtk_window_check_resize (GtkWindow *self);
typedef void (*GtkWindowKeysForeachFunc) (GtkWindow *window,
guint keyval,
@@ -120,8 +121,6 @@ GdkTexture * gtk_window_get_icon_for_size (GtkWindow *window,
void gtk_window_set_hardcoded_surface (GtkWindow *window,
GdkSurface *surface);
-GdkDisplay *gtk_window_get_display (GtkWindow *window);
-
/* Exported handles */
typedef void (*GtkWindowHandleExported) (GtkWindow *window,
@@ -133,8 +132,6 @@ gboolean gtk_window_export_handle (GtkWindow *window,
gpointer user_data);
void gtk_window_unexport_handle (GtkWindow *window);
-GskRenderer *gtk_window_get_renderer (GtkWindow *window);
-
GtkWidget * gtk_window_lookup_pointer_focus_widget (GtkWindow *window,
GdkDevice *device,
GdkEventSequence *sequence);
diff --git a/gtk/inspector/logs.c b/gtk/inspector/logs.c
index a8c59ceba6..1bc73c7629 100644
--- a/gtk/inspector/logs.c
+++ b/gtk/inspector/logs.c
@@ -35,7 +35,7 @@
#include "gtkprivate.h"
#include "gtkdebug.h"
#include "gdkinternals.h"
-#include "gtkwindowprivate.h"
+#include "gtkrootprivate.h"
#include "gskdebugprivate.h"
#include "gskrendererprivate.h"
@@ -146,7 +146,7 @@ flag_toggled (GtkWidget *button,
if (toplevel == gtk_widget_get_toplevel (button)) /* skip the inspector */
continue;
- renderer = gtk_window_get_renderer (GTK_WINDOW (toplevel));
+ renderer = gtk_root_get_renderer (GTK_ROOT (toplevel));
if (!renderer)
continue;
diff --git a/gtk/inspector/window.c b/gtk/inspector/window.c
index 3239cd5770..9bdced31e4 100644
--- a/gtk/inspector/window.c
+++ b/gtk/inspector/window.c
@@ -51,10 +51,10 @@
#include "gtklabel.h"
#include "gtkmodulesprivate.h"
#include "gtkprivate.h"
+#include "gtkrootprivate.h"
#include "gtkstack.h"
#include "gtktreeviewcolumn.h"
#include "gtkwindowgroup.h"
-#include "gtkwindowprivate.h"
G_DEFINE_TYPE (GtkInspectorWindow, gtk_inspector_window, GTK_TYPE_WINDOW)
@@ -273,7 +273,7 @@ gtk_inspector_window_realize (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_inspector_window_parent_class)->realize (widget);
- renderer = gtk_window_get_renderer (GTK_WINDOW (widget));
+ renderer = gtk_root_get_renderer (GTK_ROOT (widget));
gsk_renderer_set_debug_flags (renderer, 0);
}
diff --git a/gtk/meson.build b/gtk/meson.build
index 3ebb1b5867..558232b9e7 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -314,6 +314,7 @@ gtk_public_sources = files([
'gtkrendericon.c',
'gtkrendernodepaintable.c',
'gtkrevealer.c',
+ 'gtkroot.c',
'gtkroundedbox.c',
'gtkscale.c',
'gtkscalebutton.c',
@@ -551,6 +552,7 @@ gtk_public_headers = files([
'gtkrecentmanager.h',
'gtkrender.h',
'gtkrevealer.h',
+ 'gtkroot.h',
'gtkscale.h',
'gtkscalebutton.h',
'gtkscrollable.h',