[gtk/wip/baedert/single-node-window] /o\



commit 58535870b72d9ce1fe59c058126fdff7308db1e9
Author: Timm Bäder <mail baedert org>
Date:   Sat May 2 18:50:53 2020 +0200

    /o\

 gtk/gtkwidget.c                |  49 ++++-
 gtk/gtkwindow.c                | 434 ++++++++++++++++-------------------------
 gtk/gtkwindowprivate.h         |   4 -
 gtk/theme/Adwaita/_common.scss |  35 ++--
 tests/testwidgetfocus.c        |   2 +-
 5 files changed, 226 insertions(+), 298 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 8a2344c386..085b6a6fe2 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -3448,19 +3448,25 @@ gtk_widget_get_surface_allocation (GtkWidget     *widget,
 {
   GtkWidget *parent;
   graphene_rect_t bounds;
+  int native_x, native_y;
 
   /* Don't consider the parent == widget case here. */
   parent = _gtk_widget_get_parent (widget);
   while (parent && !GTK_IS_NATIVE (parent))
     parent = _gtk_widget_get_parent (parent);
 
+  if (GTK_IS_NATIVE (parent))
+    gtk_native_get_surface_transform (GTK_NATIVE (parent), &native_x, &native_y);
+  else
+    native_x = native_y = 0;
+
   g_assert (GTK_IS_WINDOW (parent) || GTK_IS_POPOVER (parent));
 
   if (gtk_widget_compute_bounds (widget, parent, &bounds))
     {
       *allocation = (GtkAllocation){
-        floorf (bounds.origin.x),
-        floorf (bounds.origin.y),
+        floorf (bounds.origin.x) + native_x,
+        floorf (bounds.origin.y) + native_y,
         ceilf (bounds.size.width),
         ceilf (bounds.size.height)
       };
@@ -4557,11 +4563,29 @@ translate_event_coordinates (GdkEvent  *event,
 
   event_widget = gtk_get_event_widget (event);
 
+
   if (!gtk_widget_compute_point (event_widget,
                                  widget,
                                  &GRAPHENE_POINT_INIT (event_x, event_y),
                                  &p))
     return FALSE;
+  /* POAH */
+  if (G_LIKELY (GTK_IS_NATIVE (event_widget)))
+    {
+      int transform_x, transform_y;
+
+      gtk_native_get_surface_transform (GTK_NATIVE (event_widget), &transform_x, &transform_y);
+
+      p.x -= transform_x;
+      p.y -= transform_y;
+    }
+
+  /*g_message ("Translating event from %s to %s: (%f, %f) -> (%f, %f)",*/
+             /*G_OBJECT_TYPE_NAME (event_widget), G_OBJECT_TYPE_NAME (widget),*/
+             /*event_x, event_y,*/
+             /*p.x, p.y);*/
+
+
 
   *x = p.x;
   *y = p.y;
@@ -9976,6 +10000,18 @@ gtk_widget_pick (GtkWidget    *widget,
   if (!gtk_widget_can_be_picked (widget, flags))
     return NULL;
 
+  if (GTK_IS_NATIVE (widget))
+    {
+      int nx, ny;
+
+      gtk_native_get_surface_transform (GTK_NATIVE (widget), &nx, &ny);
+
+      g_message ("%s is a GtkNative, so subtracting %d/%d from the picking coordinates",
+                 G_OBJECT_TYPE_NAME (widget), nx, ny);
+      x -= nx;
+      y -= ny;
+    }
+
   return gtk_widget_do_pick (widget, x, y, flags);
 }
 
@@ -11635,10 +11671,10 @@ gtk_widget_render (GtkWidget            *widget,
                    GdkSurface           *surface,
                    const cairo_region_t *region)
 {
+  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
   GtkSnapshot *snapshot;
   GskRenderer *renderer;
   GskRenderNode *root;
-  int x, y;
   gint64 before_snapshot = g_get_monotonic_time ();
   gint64 before_render = 0;
 
@@ -11650,9 +11686,12 @@ gtk_widget_render (GtkWidget            *widget,
     return;
 
   snapshot = gtk_snapshot_new ();
-  gtk_native_get_surface_transform (GTK_NATIVE (widget), &x, &y);
-  gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
+
+  gtk_snapshot_save (snapshot);
+  gtk_snapshot_transform (snapshot, priv->transform);
   gtk_widget_snapshot (widget, snapshot);
+  gtk_snapshot_restore (snapshot);
+
   root = gtk_snapshot_free_to_node (snapshot);
 
   if (GDK_PROFILER_IS_RUNNING)
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 2114695361..fc1694fa34 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -246,8 +246,6 @@ typedef struct
   GdkSurface  *surface;
   GskRenderer *renderer;
 
-  cairo_region_t *extra_input_region;
-
   GList *foci;
 
   GtkConstraintSolver *constraint_solver;
@@ -738,6 +736,7 @@ gtk_window_class_init (GtkWindowClass *klass)
   widget_class->move_focus = gtk_window_move_focus;
   widget_class->measure = gtk_window_measure;
   widget_class->css_changed = gtk_window_css_changed;
+  /*widget_class->contains = gtk_window_contains;*/
 
   klass->activate_default = gtk_window_real_activate_default;
   klass->activate_focus = gtk_window_real_activate_focus;
@@ -1288,155 +1287,101 @@ constraints_for_edge (GdkSurfaceEdge edge)
     }
 }
 
-static gboolean
-edge_under_coordinates (GtkWindow     *window,
-                        gint           x,
-                        gint           y,
-                        GdkSurfaceEdge  edge)
+static int
+get_edge_for_coordinates (GtkWindow *window,
+                          double     x,
+                          double     y)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-  GtkAllocation allocation;
-  GtkStyleContext *context;
-  gint handle_v, handle_h;
-  GtkBorder border;
   gboolean supports_edge_constraints;
-  guint constraints;
+  GtkBorder handle_size;
+  GtkCssBoxes css_boxes;
+  const graphene_rect_t *border_rect;
+
+#define edge_or_minus_one(edge) ((priv->edge_constraints & constraints_for_edge (edge)) ? edge : -1)
 
   if (!priv->client_decorated ||
       !priv->resizable ||
       priv->fullscreen ||
       priv->maximized)
-    return FALSE;
+    return -1;
 
   supports_edge_constraints = gdk_toplevel_supports_edge_constraints (GDK_TOPLEVEL (priv->surface));
-  constraints = constraints_for_edge (edge);
 
   if (!supports_edge_constraints && priv->tiled)
-    return FALSE;
+    return -1;
 
-  if (supports_edge_constraints &&
-      (priv->edge_constraints & constraints) != constraints)
-    return FALSE;
-
-  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);*/
+  gtk_css_boxes_init (&css_boxes, GTK_WIDGET (window));
+  border_rect = gtk_css_boxes_get_border_rect (&css_boxes);
 
   if (priv->use_client_shadow)
     {
-      handle_h = MIN (RESIZE_HANDLE_SIZE, allocation.width / 2);
-      handle_v = MIN (RESIZE_HANDLE_SIZE, allocation.height / 2);
-      get_shadow_width (window, &border);
+      /* TODO: Should probably not use the entire shadow size, hmm */
+      get_shadow_width (window, &handle_size);
     }
   else
     {
-      handle_h = 0;
-      handle_v = 0;
-      gtk_style_context_get_padding (context, &border);
+      /* Use border */
+      handle_size.left = 10;
+      handle_size.top = 10;
+      handle_size.right = 10;
+      handle_size.bottom = 10;
+      get_shadow_width (window, &handle_size);
     }
 
-  /*gtk_style_context_restore (context);*/
-
-  /* Check whether the click falls outside the handle area */
-  if (x >= allocation.x + border.left &&
-      x < allocation.x + allocation.width - border.right &&
-      y >= allocation.y + border.top &&
-      y < allocation.y + allocation.height - border.bottom)
-    return FALSE;
-
-  /* Check X axis */
-  if (x < allocation.x + border.left + handle_h)
+  if (x < 0 && x >= -handle_size.left)
     {
-      if (edge != GDK_SURFACE_EDGE_NORTH_WEST &&
-          edge != GDK_SURFACE_EDGE_WEST &&
-          edge != GDK_SURFACE_EDGE_SOUTH_WEST &&
-          edge != GDK_SURFACE_EDGE_NORTH &&
-          edge != GDK_SURFACE_EDGE_SOUTH)
-        return FALSE;
+      if (y < 0 && y >= -handle_size.top)
+        return edge_or_minus_one (GDK_SURFACE_EDGE_NORTH_WEST);
 
-      if ((edge == GDK_SURFACE_EDGE_NORTH ||
-           edge == GDK_SURFACE_EDGE_SOUTH) &&
-          (priv->edge_constraints & constraints_for_edge (GDK_SURFACE_EDGE_WEST)))
-        return FALSE;
+      if (y > border_rect->size.height && y <= border_rect->size.height + handle_size.bottom)
+        return edge_or_minus_one (GDK_SURFACE_EDGE_SOUTH_WEST);
+
+      return edge_or_minus_one (GDK_SURFACE_EDGE_WEST);
     }
-  else if (x >= allocation.x + allocation.width - border.right - handle_h)
+  else if (x > border_rect->size.width && x <= border_rect->size.width + handle_size.right)
     {
-      if (edge != GDK_SURFACE_EDGE_NORTH_EAST &&
-          edge != GDK_SURFACE_EDGE_EAST &&
-          edge != GDK_SURFACE_EDGE_SOUTH_EAST &&
-          edge != GDK_SURFACE_EDGE_NORTH &&
-          edge != GDK_SURFACE_EDGE_SOUTH)
-        return FALSE;
+      if (y < 0 && y >= -handle_size.top)
+        return edge_or_minus_one (GDK_SURFACE_EDGE_NORTH_EAST);
 
-      if ((edge == GDK_SURFACE_EDGE_NORTH ||
-           edge == GDK_SURFACE_EDGE_SOUTH) &&
-          (priv->edge_constraints & constraints_for_edge (GDK_SURFACE_EDGE_EAST)))
-        return FALSE;
+      if (y > border_rect->size.height && y <= border_rect->size.height + handle_size.bottom)
+        return edge_or_minus_one (GDK_SURFACE_EDGE_SOUTH_EAST);
+
+      return edge_or_minus_one (GDK_SURFACE_EDGE_EAST);
     }
-  else if (edge != GDK_SURFACE_EDGE_NORTH &&
-           edge != GDK_SURFACE_EDGE_SOUTH)
-    return FALSE;
 
-  /* Check Y axis */
-  if (y < allocation.y + border.top + handle_v)
+  if (y < 0 && y >= - handle_size.top)
     {
-      if (edge != GDK_SURFACE_EDGE_NORTH_WEST &&
-          edge != GDK_SURFACE_EDGE_NORTH &&
-          edge != GDK_SURFACE_EDGE_NORTH_EAST &&
-          edge != GDK_SURFACE_EDGE_EAST &&
-          edge != GDK_SURFACE_EDGE_WEST)
-        return FALSE;
-
-      if ((edge == GDK_SURFACE_EDGE_EAST ||
-           edge == GDK_SURFACE_EDGE_WEST) &&
-          (priv->edge_constraints & constraints_for_edge (GDK_SURFACE_EDGE_NORTH)))
-        return FALSE;
+      /* NORTH_EAST is handled elsewhere */
+      return edge_or_minus_one (GDK_SURFACE_EDGE_NORTH);
     }
-  else if (y > allocation.y + allocation.height - border.bottom - handle_v)
+  else if (y > border_rect->size.height && y <= border_rect->size.height + handle_size.bottom)
     {
-      if (edge != GDK_SURFACE_EDGE_SOUTH_WEST &&
-          edge != GDK_SURFACE_EDGE_SOUTH &&
-          edge != GDK_SURFACE_EDGE_SOUTH_EAST &&
-          edge != GDK_SURFACE_EDGE_EAST &&
-          edge != GDK_SURFACE_EDGE_WEST)
-        return FALSE;
-
-      if ((edge == GDK_SURFACE_EDGE_EAST ||
-           edge == GDK_SURFACE_EDGE_WEST) &&
-          (priv->edge_constraints & constraints_for_edge (GDK_SURFACE_EDGE_SOUTH)))
-        return FALSE;
+      return edge_or_minus_one (GDK_SURFACE_EDGE_SOUTH);
     }
-  else if (edge != GDK_SURFACE_EDGE_WEST &&
-           edge != GDK_SURFACE_EDGE_EAST)
-    return FALSE;
 
-  return TRUE;
+  return -1;
 }
 
 static void
 gtk_window_capture_motion (GtkWidget *widget,
-                           gdouble    x,
-                           gdouble    y)
+                           double     x,
+                           double     y)
 {
   GtkWindow *window = GTK_WINDOW (widget);
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-  gint i;
   const gchar *cursor_names[8] = {
     "nw-resize", "n-resize", "ne-resize",
     "w-resize",               "e-resize",
     "sw-resize", "s-resize", "se-resize"
   };
+  int edge;
 
   g_clear_object (&priv->resize_cursor);
 
-  for (i = 0; i < 8; i++)
-    {
-      if (edge_under_coordinates (GTK_WINDOW (widget), x, y, i))
-        {
-          priv->resize_cursor = gdk_cursor_new_from_name (cursor_names[i], NULL);
-          break;
-        }
-    }
+  edge = get_edge_for_coordinates (window, x, y);
+  if (edge != -1)
+    priv->resize_cursor = gdk_cursor_new_from_name (cursor_names[edge], NULL);
 
   gtk_window_maybe_update_cursor (window, widget, NULL);
 }
@@ -1498,6 +1443,8 @@ gtk_window_init (GtkWindow *window)
 
   widget = GTK_WIDGET (window);
 
+  gtk_widget_set_overflow (widget, GTK_OVERFLOW_HIDDEN);
+
   priv->title = NULL;
   priv->geometry_info = NULL;
   priv->focus_widget = NULL;
@@ -1891,11 +1838,15 @@ gtk_window_native_get_surface_transform (GtkNative *native,
                                          int       *y)
 {
   GtkBorder shadow;
+  GtkCssBoxes css_boxes;
+  const graphene_rect_t *border_rect;
 
   get_shadow_width (GTK_WINDOW (native), &shadow);
+  gtk_css_boxes_init (&css_boxes, GTK_WIDGET (native));
+  border_rect = gtk_css_boxes_get_border_rect (&css_boxes);
 
-  *x = shadow.left;
-  *y = shadow.right;
+  *x = shadow.left - border_rect->origin.x;
+  *y = shadow.top  - border_rect->origin.y;
 }
 
 static void
@@ -3683,7 +3634,6 @@ gtk_window_finalize (GObject *object)
   GtkWindow *window = GTK_WINDOW (object);
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
 
-  g_clear_pointer (&priv->extra_input_region, cairo_region_destroy);
   g_free (priv->title);
   gtk_window_release_application (window);
 
@@ -4137,138 +4087,89 @@ check_scale_changed (GtkWindow *window)
     _gtk_widget_scale_changed (widget);
 }
 
-static void
-sum_borders (GtkBorder *one,
-             GtkBorder *two)
-{
-  one->top += two->top;
-  one->right += two->right;
-  one->bottom += two->bottom;
-  one->left += two->left;
-}
-
-static void
-max_borders (GtkBorder *one,
-             GtkBorder *two)
-{
-  one->top = MAX (one->top, two->top);
-  one->right = MAX (one->right, two->right);
-  one->bottom = MAX (one->bottom, two->bottom);
-  one->left = MAX (one->left, two->left);
-}
-
-static void
-subtract_borders (GtkBorder *one,
-                  GtkBorder *two)
-{
-  one->top -= two->top;
-  one->right -= two->right;
-  one->bottom -= two->bottom;
-  one->left -= two->left;
-}
-
 static void
 get_shadow_width (GtkWindow *window,
                   GtkBorder *shadow_width)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-  GtkBorder border = { 0 };
-  GtkBorder d = { 0 };
+  GtkBorder shadow;
   GtkBorder margin;
-  GtkStyleContext *context;
-  GtkCssValue *shadows;
-
-  *shadow_width = border;
+  GtkCssStyle *style;
 
   if (!priv->decorated)
-    return;
+    goto out;
 
   if (!priv->client_decorated &&
       !(gtk_window_should_use_csd (window) &&
         gtk_window_supports_client_shadow (window)))
-    return;
+    goto out;
 
   if (priv->maximized ||
       priv->fullscreen)
-    return;
-
-  context = _gtk_widget_get_style_context (GTK_WIDGET (window));
+    goto out;
 
-  /* Always sum border + padding */
-  gtk_style_context_get_border (context, &border);
-  gtk_style_context_get_padding (context, &d);
-  sum_borders (&d, &border);
+  style = gtk_css_node_get_style (gtk_widget_get_css_node (GTK_WIDGET (window)));
 
   /* Calculate the size of the drop shadows ... */
-  shadows = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BOX_SHADOW);
-  gtk_css_shadow_value_get_extents (shadows, &border);
+  gtk_css_shadow_value_get_extents (style->background->box_shadow, &shadow);
 
   /* ... and compare it to the margin size, which we use for resize grips */
-  gtk_style_context_get_margin (context, &margin);
-  max_borders (&border, &margin);
+  gtk_style_context_get_margin (gtk_widget_get_style_context (GTK_WIDGET (window)), &margin);
+
+  shadow_width->left = MAX (shadow.left, margin.left);
+  shadow_width->top = MAX (shadow.top, margin.top);
+  shadow_width->right = MAX (shadow.right, margin.right);
+  shadow_width->bottom = MAX (shadow.bottom, margin.bottom);
+
+  g_assert_cmpint (shadow_width->left, >=, 0);
+  g_assert_cmpint (shadow_width->top, >=, 0);
+  g_assert_cmpint (shadow_width->right, >=, 0);
+  g_assert_cmpint (shadow_width->bottom, >=, 0);
+  /*g_message ("%s: %d, %d, %d, %d", __FUNCTION__,*/
+             /*shadow_width->left,*/
+             /*shadow_width->top,*/
+             /*shadow_width->right,*/
+             /*shadow_width->bottom);*/
+  return;
 
-  sum_borders (&d, &border);
-  *shadow_width = d;
+out:
+  *shadow_width = (GtkBorder) {0, 0, 0, 0};
 }
 
 static void
 update_csd_shape (GtkWindow *window)
 {
-  GtkWidget *widget = (GtkWidget *)window;
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
   cairo_rectangle_int_t rect;
-  GtkBorder border, tmp;
   GtkBorder window_border;
-  GtkStyleContext *context;
 
   if (!priv->client_decorated)
     return;
 
-  context = _gtk_widget_get_style_context (widget);
-
-  /*gtk_style_context_save_to_node (context, priv->decoration_node);*/
-  gtk_style_context_get_margin (context, &border);
-  gtk_style_context_get_border (context, &tmp);
-  sum_borders (&border, &tmp);
-  gtk_style_context_get_padding (context, &tmp);
-  sum_borders (&border, &tmp);
-  /*gtk_style_context_restore (context);*/
   get_shadow_width (window, &window_border);
 
   /* update the input shape, which makes it so that clicks
-   * outside the border windows go through.
-   */
-
-  subtract_borders (&window_border, &border);
-
+   * outside the border windows go through. */
   rect.x = window_border.left;
   rect.y = window_border.top;
-  rect.width = gtk_widget_get_allocated_width (widget) - window_border.left - window_border.right;
-  rect.height = gtk_widget_get_allocated_height (widget) - window_border.top - window_border.bottom;
+  rect.width = gdk_surface_get_width (priv->surface) - window_border.left - window_border.right;
+  rect.height = gdk_surface_get_height (priv->surface) - window_border.top - window_border.bottom;
+
+
+  rect.x = 0;
+  rect.y = 0;
+  rect.width = gdk_surface_get_width (priv->surface);
+  rect.height = gdk_surface_get_height (priv->surface);
 
   if (rect.width > 0 && rect.height > 0)
     {
       cairo_region_t *region = cairo_region_create_rectangle (&rect);
 
-      if (priv->extra_input_region)
-        cairo_region_intersect (region, priv->extra_input_region);
-
       gdk_surface_set_input_region (priv->surface, region);
       cairo_region_destroy (region);
     }
 }
 
-void
-gtk_window_set_extra_input_region (GtkWindow      *window,
-                                   cairo_region_t *region)
-{
-  GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-
-  g_clear_pointer (&priv->extra_input_region, cairo_region_destroy);
-  priv->extra_input_region = cairo_region_copy (region);
-  update_csd_shape (window);
-}
-
 static void
 corner_rect (cairo_rectangle_int_t *rect,
              const GtkCssValue     *value)
@@ -4280,7 +4181,7 @@ corner_rect (cairo_rectangle_int_t *rect,
 static void
 subtract_decoration_corners_from_region (cairo_region_t        *region,
                                          cairo_rectangle_int_t *extents,
-                                         GtkStyleContext       *context,
+                                         GtkCssStyle           *style,
                                          GtkWindow             *window)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
@@ -4292,64 +4193,64 @@ subtract_decoration_corners_from_region (cairo_region_t        *region,
       priv->maximized)
     return;
 
-  /*gtk_style_context_save_to_node (context, priv->decoration_node);*/
-
-  corner_rect (&rect, _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS));
+  corner_rect (&rect, style->border->border_top_left_radius);
   rect.x = extents->x;
   rect.y = extents->y;
   cairo_region_subtract_rectangle (region, &rect);
 
-  corner_rect (&rect, _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS));
+  corner_rect (&rect, style->border->border_top_right_radius);
   rect.x = extents->x + extents->width - rect.width;
   rect.y = extents->y;
   cairo_region_subtract_rectangle (region, &rect);
 
-  corner_rect (&rect, _gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS));
+  corner_rect (&rect, style->border->border_bottom_left_radius);
   rect.x = extents->x;
   rect.y = extents->y + extents->height - rect.height;
   cairo_region_subtract_rectangle (region, &rect);
 
-  corner_rect (&rect, _gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS));
+  corner_rect (&rect, style->border->border_bottom_right_radius);
   rect.x = extents->x + extents->width - rect.width;
   rect.y = extents->y + extents->height - rect.height;
   cairo_region_subtract_rectangle (region, &rect);
-
-  /*gtk_style_context_restore (context);*/
 }
 
 static void
-update_opaque_region (GtkWindow           *window,
-                      const GtkBorder     *border,
-                      const GtkAllocation *allocation)
+update_opaque_region (GtkWindow       *window,
+                      const GtkBorder *border)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
   GtkWidget *widget = GTK_WIDGET (window);
   cairo_region_t *opaque_region;
-  GtkStyleContext *context;
   gboolean is_opaque = FALSE;
+  GtkCssStyle *style;
 
   if (!_gtk_widget_get_realized (widget))
-      return;
+    return;
 
-  context = gtk_widget_get_style_context (widget);
+  style = gtk_css_node_get_style (gtk_widget_get_css_node (GTK_WIDGET (window)));
 
-  is_opaque = gdk_rgba_is_opaque (gtk_css_color_value_get_rgba (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_BACKGROUND_COLOR)));
+  is_opaque = gdk_rgba_is_opaque (gtk_css_color_value_get_rgba (style->background->background_color));
 
-  if (gtk_widget_get_opacity (widget) < 1.0)
+  if (is_opaque && gtk_widget_get_opacity (widget) < 1.0)
     is_opaque = FALSE;
 
   if (is_opaque)
     {
       cairo_rectangle_int_t rect;
+      GtkCssBoxes css_boxes;
+      const graphene_rect_t *border_rect;
+
+      gtk_css_boxes_init (&css_boxes, widget);
+      border_rect = gtk_css_boxes_get_margin_rect (&css_boxes);
 
       rect.x = border->left;
       rect.y = border->top;
-      rect.width = allocation->width - border->left - border->right;
-      rect.height = allocation->height - border->top - border->bottom;
+      rect.width = border_rect->size.width - border->left - border->right;
+      rect.height = border_rect->size.height - border->top - border->bottom;
 
       opaque_region = cairo_region_create_rectangle (&rect);
 
-      subtract_decoration_corners_from_region (opaque_region, &rect, context, window);
+      subtract_decoration_corners_from_region (opaque_region, &rect, style, window);
     }
   else
     {
@@ -4362,20 +4263,22 @@ update_opaque_region (GtkWindow           *window,
 }
 
 static void
-update_realized_window_properties (GtkWindow     *window,
-                                   GtkAllocation *child_allocation,
-                                   GtkBorder     *window_border)
+update_realized_window_properties (GtkWindow       *window,
+                                   GtkAllocation   *child_allocation,
+                                   const GtkBorder *window_border)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
 
   if (priv->surface && priv->client_decorated && priv->use_client_shadow)
-    gdk_surface_set_shadow_width (priv->surface,
-                                  window_border->left,
-                                  window_border->right,
-                                  window_border->top,
-                                  window_border->bottom);
+    {
+      gdk_surface_set_shadow_width (priv->surface,
+                                    window_border->left,
+                                    window_border->right,
+                                    window_border->top,
+                                    window_border->bottom);
+    }
 
-  update_opaque_region (window, window_border, child_allocation);
+  update_opaque_region (window, window_border);
   update_csd_shape (window);
 }
 
@@ -4405,6 +4308,7 @@ gtk_window_realize (GtkWidget *widget)
       allocation.y = shadow.top;
       allocation.width = request.width - shadow.left - shadow.right;
       allocation.height = request.height - shadow.top - shadow.bottom;
+
       gtk_widget_size_allocate (widget, &allocation, -1);
 
       gtk_widget_queue_resize (widget);
@@ -4857,15 +4761,13 @@ static GtkWindowRegion
 get_active_region_type (GtkWindow *window, gint x, gint y)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
-  gint i;
 
   if (priv->client_decorated)
     {
-      for (i = 0; i < 8; i++)
-        {
-          if (edge_under_coordinates (window, x, y, i))
-            return i;
-        }
+      int edge = get_edge_for_coordinates (window, x, y);
+
+      if (edge != -1)
+        return (GtkWindowRegion)edge;
     }
 
   return GTK_WINDOW_REGION_CONTENT;
@@ -5288,13 +5190,11 @@ gtk_window_css_changed (GtkWidget         *widget,
   if (!_gtk_widget_get_alloc_needed (widget) &&
       (change == NULL || gtk_css_style_change_changes_property (change, GTK_CSS_PROPERTY_BACKGROUND_COLOR)))
     {
-      GtkAllocation allocation;
-      GtkBorder window_border;
+      GtkBorder shadow;
 
-      gtk_widget_get_allocation (widget, &allocation);
-      get_shadow_width (window, &window_border);
+      get_shadow_width (window, &shadow);
 
-      update_opaque_region (window, &window_border, &allocation);
+      update_opaque_region (window, &shadow);
     }
 }
 
@@ -5358,7 +5258,6 @@ _gtk_window_unset_focus_and_default (GtkWindow *window,
 /* This function doesn't constrain to geometry hints */
 static void
 gtk_window_compute_configure_request_size (GtkWindow   *window,
-                                           GdkGeometry *geometry,
                                            guint        flags,
                                            gint        *width,
                                            gint        *height)
@@ -5396,12 +5295,6 @@ gtk_window_compute_configure_request_size (GtkWindow   *window,
           if (info->default_height > 0)
             *height = default_height_csd;
         }
-
-      GtkBorder shadow = {0, };
-      get_shadow_width (window, &shadow);
-
-      *width = *width + shadow.left + shadow.right;
-      *height = *height + shadow.top + shadow.bottom;
     }
   else
     {
@@ -5415,20 +5308,19 @@ gtk_window_compute_configure_request_size (GtkWindow   *window,
       /* Unless we are maximized or fullscreen */
       gtk_window_get_remembered_size (window, width, height);
     }
+  else if (info)
+    {
+      gint resize_width_csd = info->resize_width;
+      gint resize_height_csd = info->resize_height;
+      gtk_window_update_csd_size (window,
+                                  &resize_width_csd, &resize_height_csd,
+                                  INCLUDE_CSD_SIZE);
 
-  /*else if (info)*/
-    /*{*/
-      /*gint resize_width_csd = info->resize_width;*/
-      /*gint resize_height_csd = info->resize_height;*/
-      /*gtk_window_update_csd_size (window,*/
-                                  /*&resize_width_csd, &resize_height_csd,*/
-                                  /*INCLUDE_CSD_SIZE);*/
-
-      /*if (info->resize_width > 0)*/
-        /**width = resize_width_csd;*/
-      /*if (info->resize_height > 0)*/
-        /**height = resize_height_csd;*/
-    /*}*/
+      if (info->resize_width > 0)
+        *width = resize_width_csd;
+      if (info->resize_height > 0)
+        *height = resize_height_csd;
+    }
 
   /* Don't ever request zero width or height, it's not supported by
      gdk. The size allocation code will round it to 1 anyway but if
@@ -5453,7 +5345,7 @@ gtk_window_compute_configure_request (GtkWindow    *window,
 
   gtk_window_compute_hints (window, &new_geometry, &new_flags);
   gtk_window_compute_configure_request_size (window,
-                                             &new_geometry, new_flags,
+                                             new_flags,
                                              &w, &h);
   gtk_window_update_fixed_size (window, &new_geometry, w, h);
   gtk_window_constrain_size (window,
@@ -5475,14 +5367,10 @@ gtk_window_compute_configure_request (GtkWindow    *window,
       y = 0;
     }
 
-  GtkBorder shadow = {0, };
-
-  /*get_shadow_width (window, &shadow);*/
-
   request->x = x;
   request->y = y;
-  request->width = w + shadow.left + shadow.right;
-  request->height = h + shadow.top + shadow.bottom;
+  request->width = w;
+  request->height = h;
 
   if (geometry)
     *geometry = new_geometry;
@@ -5660,11 +5548,13 @@ gtk_window_move_resize (GtkWindow *window)
 
       gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1,
                           &min, NULL, NULL, NULL);
-      allocation.width = MAX (min, current_width);
+      allocation.width = MAX (min, current_width - shadow.left - shadow.right);
       gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, allocation.width,
                           &min, NULL, NULL, NULL);
-      allocation.height = MAX (min, current_height);
+      allocation.height = MAX (min, current_height - shadow.top - shadow.bottom);
 
+      /*g_message ("size_allocate 1: %d, %d, %d, %d",*/
+                 /*allocation.x, allocation.y, allocation.width, allocation.height);*/
       gtk_widget_size_allocate (widget, &allocation, -1);
 
       /* If the configure request changed, it means that
@@ -5776,17 +5666,16 @@ gtk_window_move_resize (GtkWindow *window)
       if (configure_request_pos_changed)
         g_warning ("configure request position changed. This should not happen. Ignoring the position");
 
-      gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, current_height - shadow.top - shadow.bottom,
-                          &min_width, NULL, NULL, NULL);
-      gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, current_width - shadow.left - shadow.right,
-                          &min_height, NULL, NULL, NULL);
-
       /* Our configure request didn't change size, but maybe some of
        * our child widgets have. Run a size allocate with our current
        * size to make sure that we re-layout our child widgets. */
-      allocation.x = shadow.left;
-      allocation.y = shadow.top;
+
+      gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, current_height - shadow.top - shadow.bottom,
+                          &min_width, NULL, NULL, NULL);
       allocation.width = MAX (current_width - shadow.left - shadow.right, min_width);
+
+      gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, allocation.width,
+                          &min_height, NULL, NULL, NULL);
       allocation.height = MAX (current_height - shadow.top - shadow.bottom, min_height);
 
       gtk_widget_size_allocate (widget, &allocation, -1);
@@ -5898,6 +5787,7 @@ gtk_window_update_fixed_size (GtkWindow   *window,
       if (info->default_width > -1)
         {
           gint w = MAX (MAX (default_width_csd, new_width), new_geometry->min_width);
+          g_critical ("TODO: Probably need to add the shadow size here as well");
           new_geometry->min_width = w;
           new_geometry->max_width = w;
         }
@@ -5918,12 +5808,13 @@ gtk_window_update_fixed_size (GtkWindow   *window,
  */
 static void
 gtk_window_compute_hints (GtkWindow   *window,
-                         GdkGeometry *new_geometry,
-                         guint       *new_flags)
+                          GdkGeometry *new_geometry,
+                          guint       *new_flags)
 {
   GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
   GtkWidget *widget;
   GtkRequisition requisition;
+  GtkBorder shadow;
 
   widget = GTK_WIDGET (window);
 
@@ -5947,10 +5838,11 @@ gtk_window_compute_hints (GtkWindow   *window,
   new_geometry->base_width = 0;
   new_geometry->base_height = 0;
 
+  get_shadow_width (window, &shadow);
   *new_flags |= GDK_HINT_MIN_SIZE;
-  new_geometry->min_width = requisition.width;
-  new_geometry->min_height = requisition.height;
-  
+  new_geometry->min_width = requisition.width + shadow.left + shadow.right;
+  new_geometry->min_height = requisition.height + shadow.top + shadow.bottom;
+
   if (!priv->resizable)
     {
       *new_flags |= GDK_HINT_MAX_SIZE;
diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h
index 32141ad77a..8ed1564b5a 100644
--- a/gtk/gtkwindowprivate.h
+++ b/gtk/gtkwindowprivate.h
@@ -132,10 +132,6 @@ GtkWidget *      gtk_window_pick_popover (GtkWindow   *window,
                                           double       y,
                                           GtkPickFlags flags);
 
-void             gtk_window_set_extra_input_region (GtkWindow      *window,
-                                                    cairo_region_t *region);
-
-
 G_END_DECLS
 
 #endif /* __GTK_WINDOW_PRIVATE_H__ */
diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss
index 3a32cf2667..d14239ccbd 100644
--- a/gtk/theme/Adwaita/_common.scss
+++ b/gtk/theme/Adwaita/_common.scss
@@ -4052,8 +4052,8 @@ colorchooser .popover.osd { border-radius: 5px; }
 /**********************
  * Window Decorations *
  *********************/
-decoration,
-window {
+window,
+dialog {
   border-radius: $window_radius $window_radius 0 0;
   // lamefun trick to get rounded borders regardless of CSD use
   border-width: 0px;
@@ -4063,13 +4063,24 @@ window {
   $_wm_border: if($variant=='light', transparentize(black, 0.77), transparentize($borders_color, 0.1));
   $_wm_border_backdrop: if($variant=='light', transparentize(black, 0.82), transparentize($borders_color, 
0.1));
 
-  box-shadow: 0 3px 9px 1px transparentize(black, 0.5),
-              0 0 0 1px $_wm_border; //doing borders with box-shadow
+  &.csd {
+    border-radius: 20px;
+    box-shadow: 0 3px 9px 1px transparentize(black, 0.5),
+                0 0 0 1px $_wm_border; //doing borders with box-shadow
+    //margin: 10px;
+  }
 
-  // FIXME rationalize shadows
+  &.solid-csd {
+    margin: 0;
+    padding: 14px;
+    border: solid 1px $borders_color;
+    border-radius: 0;
+    box-shadow: inset 0 0 0 3px $headerbar_color, inset 0 1px $top_hilight;
+
+    &:backdrop { box-shadow: inset 0 0 0 3px $backdrop_bg_color, inset 0 1px $top_hilight; }
+  }
 
-  // this is used for the resize cursor area
-  //margin: 10px;
+  // FIXME rationalize shadows
 
   &:backdrop {
     // the transparent shadow here is to enforce that the shadow extents don't
@@ -4112,16 +4123,6 @@ window {
                 0 0 0 1px transparentize($_wm_border, 0.1);
   }
 
-  .solid-csd > & {
-    margin: 0;
-    padding: 4px;
-    background-color: $borders_color;
-    border: solid 1px $borders_color;
-    border-radius: 0;
-    box-shadow: inset 0 0 0 3px $headerbar_color, inset 0 1px $top_hilight;
-
-    &:backdrop { box-shadow: inset 0 0 0 3px $backdrop_bg_color, inset 0 1px $top_hilight; }
-  }
 }
 
 // catch all extend :)
diff --git a/tests/testwidgetfocus.c b/tests/testwidgetfocus.c
index 9a9ea5302a..d0c8d58436 100644
--- a/tests/testwidgetfocus.c
+++ b/tests/testwidgetfocus.c
@@ -295,7 +295,7 @@ main(int argc, char **argv)
   window = gtk_window_new ();
   widget = g_object_new (GTK_TYPE_FOCUS_WIDGET, NULL);
 
-  gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
+  /*gtk_window_set_decorated (GTK_WINDOW (window), FALSE);*/
 
   gtk_window_set_child (GTK_WINDOW (window), widget);
   g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]