[gtk+] entry: use a gadget



commit 35c243b26f851680b276c9604ada01fb0a242b77
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Dec 5 22:17:51 2015 -0500

    entry: use a gadget
    
    Use a gadget for the entry. Selection and progress still
    just use a CSS node. Most things seem to work correctly
    with non-zero margin or padding.

 gtk/gtkentry.c      |  489 +++++++++++++++++++++++++++++----------------------
 gtk/gtkspinbutton.c |    4 -
 2 files changed, 280 insertions(+), 213 deletions(-)
---
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 7d97451..4b86e41 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -70,6 +70,7 @@
 #include "gtktoolbar.h"
 #include "gtkmagnifierprivate.h"
 #include "gtkcssnodeprivate.h"
+#include "gtkcsscustomgadgetprivate.h"
 
 #include "a11y/gtkentryaccessible.h"
 
@@ -204,6 +205,7 @@ struct _GtkEntryPrivate
   GtkGesture    *drag_gesture;
   GtkGesture    *multipress_gesture;
 
+  GtkCssGadget  *gadget;
   GtkCssNode    *selection_node;
   GtkCssNode    *progress_node;
 
@@ -278,7 +280,6 @@ struct _EntryIconInfo
   GtkCssGadget *gadget;
   GdkEventSequence *current_sequence;
   GdkDevice *device;
-  GtkCssNode *css_node;
 };
 
 struct _GtkEntryPasswordHint
@@ -693,6 +694,27 @@ static void         buffer_connect_signals             (GtkEntry       *entry);
 static void         buffer_disconnect_signals          (GtkEntry       *entry);
 static GtkEntryBuffer *get_buffer                      (GtkEntry       *entry);
 
+static void     gtk_entry_measure  (GtkCssGadget        *gadget,
+                                    GtkOrientation       orientation,
+                                    int                  for_size,
+                                    int                 *minimum,
+                                    int                 *natural,
+                                    int                 *minimum_baseline,
+                                    int                 *natural_baseline,
+                                    gpointer             data);
+static void     gtk_entry_allocate (GtkCssGadget        *gadget,
+                                    const GtkAllocation *allocation,
+                                    int                  baseline,
+                                    GtkAllocation       *out_clip,
+                                    gpointer             data);
+static gboolean gtk_entry_render   (GtkCssGadget        *gadget,
+                                    cairo_t             *cr,
+                                    int                  x,
+                                    int                  y,
+                                    int                  width,
+                                    int                  height,
+                                    gpointer             data);
+
 G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
                          G_ADD_PRIVATE (GtkEntry)
                          G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
@@ -2672,6 +2694,7 @@ static void
 gtk_entry_init (GtkEntry *entry)
 {
   GtkEntryPrivate *priv;
+  GtkCssNode *widget_node;
 
   entry->priv = gtk_entry_get_instance_private (entry);
   priv = entry->priv;
@@ -2726,6 +2749,15 @@ gtk_entry_init (GtkEntry *entry)
                     G_CALLBACK (gtk_entry_multipress_gesture_pressed), entry);
   gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->multipress_gesture), 0);
   gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (priv->multipress_gesture), TRUE);
+
+  widget_node = gtk_widget_get_css_node (GTK_WIDGET (entry));
+  priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
+                                                     GTK_WIDGET (entry),
+                                                     gtk_entry_measure,
+                                                     gtk_entry_allocate,
+                                                     gtk_entry_render,
+                                                     NULL,
+                                                     NULL);
 }
 
 static void
@@ -2770,8 +2802,7 @@ static gint
 get_icon_width (GtkEntry             *entry,
                 GtkEntryIconPosition  icon_pos)
 {
-  GtkEntryPrivate *priv = entry->priv;
-  EntryIconInfo *icon_info = priv->icons[icon_pos];
+  EntryIconInfo *icon_info = entry->priv->icons[icon_pos];
   gint width;
 
   if (!icon_info)
@@ -2922,19 +2953,16 @@ gtk_entry_finalize (GObject *object)
 
   for (i = 0; i < MAX_ICONS; i++)
     {
-      if ((icon_info = priv->icons[i]) != NULL)
-        {
-          if (icon_info->target_list != NULL)
-            {
-              gtk_target_list_unref (icon_info->target_list);
-              icon_info->target_list = NULL;
-            }
+      icon_info = priv->icons[i];
+      if (icon_info == NULL)
+        continue;
 
-          g_clear_object (&icon_info->gadget);
+      if (icon_info->target_list != NULL)
+        gtk_target_list_unref (icon_info->target_list);
 
-          g_slice_free (EntryIconInfo, icon_info);
-          priv->icons[i] = NULL;
-        }
+      g_clear_object (&icon_info->gadget);
+
+      g_slice_free (EntryIconInfo, icon_info);
     }
 
   if (priv->cached_layout)
@@ -2965,6 +2993,8 @@ gtk_entry_finalize (GObject *object)
   if (priv->attrs)
     pango_attr_list_unref (priv->attrs);
 
+  g_clear_object (&priv->gadget);
+
   G_OBJECT_CLASS (gtk_entry_parent_class)->finalize (object);
 }
 
@@ -3226,7 +3256,9 @@ update_node_ordering (GtkEntry *entry)
   icon_info = priv->icons[icon_pos];
   if (icon_info)
     {
-      GtkCssNode *node = gtk_css_gadget_get_node (icon_info->gadget);
+      GtkCssNode *node;
+
+      node = gtk_css_gadget_get_node (icon_info->gadget);
       parent = gtk_css_node_get_parent (node);
       sibling = gtk_css_node_get_first_child (parent);
       if (node != sibling)
@@ -3249,7 +3281,6 @@ construct_icon_info (GtkWidget            *widget,
   priv->icons[icon_pos] = icon_info;
 
   widget_node = get_entry_node (widget);
-
   icon_info->gadget = gtk_icon_helper_new_named ("image", widget);
   _gtk_icon_helper_set_force_scale_pixbuf (GTK_ICON_HELPER (icon_info->gadget), TRUE);
   gtk_css_node_set_parent (gtk_css_gadget_get_node (icon_info->gadget), widget_node);
@@ -3434,152 +3465,149 @@ gtk_entry_unrealize (GtkWidget *widget)
     }
 }
 
-void
-_gtk_entry_get_borders (GtkEntry *entry,
-                        GtkBorder *border_out)
+static void
+gtk_entry_get_preferred_width (GtkWidget *widget,
+                               gint      *minimum,
+                               gint      *natural)
 {
-  GtkWidget *widget = GTK_WIDGET (entry);
-  GtkBorder padding, border;
-  GtkStyleContext *context;
-  GtkStateFlags state;
+  gtk_css_gadget_get_preferred_size (GTK_ENTRY (widget)->priv->gadget,
+                                     GTK_ORIENTATION_HORIZONTAL,
+                                     -1,
+                                     minimum, natural,
+                                     NULL, NULL);
+}
 
-  context = gtk_widget_get_style_context (widget);
-  state = gtk_style_context_get_state (context);
-  gtk_style_context_get_padding (context, state, &padding);
-  gtk_style_context_get_border (context, state, &border);
+static void
+gtk_entry_get_preferred_height (GtkWidget *widget,
+                                gint      *minimum,
+                                gint      *natural)
+{
+  gtk_css_gadget_get_preferred_size (GTK_ENTRY (widget)->priv->gadget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     -1,
+                                     minimum, natural,
+                                     NULL, NULL);
+}
 
-  border_out->top = padding.top + border.top;
-  border_out->bottom = padding.bottom + border.bottom;
-  border_out->left = padding.left + border.left;
-  border_out->right = padding.right + border.right;
+static void
+gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
+                                                      gint       width,
+                                                      gint      *minimum,
+                                                      gint      *natural,
+                                                      gint      *minimum_baseline,
+                                                      gint      *natural_baseline)
+{
+  gtk_css_gadget_get_preferred_size (GTK_ENTRY (widget)->priv->gadget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     width,
+                                     minimum, natural,
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
-gtk_entry_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
+gtk_entry_measure (GtkCssGadget   *gadget,
+                   GtkOrientation  orientation,
+                   int             for_size,
+                   int            *minimum,
+                   int            *natural,
+                   int            *minimum_baseline,
+                   int            *natural_baseline,
+                   gpointer        unused)
 {
-  GtkEntry *entry = GTK_ENTRY (widget);
-  GtkEntryPrivate *priv = entry->priv;
-  PangoFontMetrics *metrics;
-  GtkBorder borders;
+  GtkWidget *widget;
+  GtkEntry *entry;
+  GtkEntryPrivate *priv;
   PangoContext *context;
-  gint icon_width, i;
-  gint min, nat;
-  gint char_width;
-  gint digit_width;
-  gint char_pixels;
+  PangoFontMetrics *metrics;
 
-  _gtk_entry_get_borders (entry, &borders);
+  widget = gtk_css_gadget_get_owner (gadget);
+  entry = GTK_ENTRY (widget);
+  priv = entry->priv;
 
   context = gtk_widget_get_pango_context (widget);
   metrics = pango_context_get_metrics (context,
                                        pango_context_get_font_description (context),
                                        pango_context_get_language (context));
 
-  char_width = pango_font_metrics_get_approximate_char_width (metrics);
-  digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
-  char_pixels = (MAX (char_width, digit_width) + PANGO_SCALE - 1) / PANGO_SCALE;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      gint icon_width, i;
+      gint min, nat;
+      gint char_width;
+      gint digit_width;
+      gint char_pixels;
 
-  pango_font_metrics_unref (metrics);
+      char_width = pango_font_metrics_get_approximate_char_width (metrics);
+      digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
+      char_pixels = (MAX (char_width, digit_width) + PANGO_SCALE - 1) / PANGO_SCALE;
 
-  if (priv->width_chars < 0)
-    min = MIN_ENTRY_WIDTH + borders.left + borders.right;
-  else
-    min = char_pixels * priv->width_chars + borders.left + borders.right;
+      if (priv->width_chars < 0)
+        min = MIN_ENTRY_WIDTH;
+      else
+        min = char_pixels * priv->width_chars;
 
-  if (priv->max_width_chars < 0)
-    nat = MIN_ENTRY_WIDTH + borders.left + borders.right;
-  else
-    nat = char_pixels * priv->max_width_chars + borders.left + borders.right;
+      if (priv->max_width_chars < 0)
+        nat = MIN_ENTRY_WIDTH;
+      else
+        nat = char_pixels * priv->max_width_chars;
 
-  icon_width = 0;
-  for (i = 0; i < MAX_ICONS; i++)
-    icon_width += get_icon_width (entry, i);
+      icon_width = 0;
+      for (i = 0; i < MAX_ICONS; i++)
+        icon_width += get_icon_width (entry, i);
 
-  min = MAX (min, icon_width);
-  nat = MAX (min, nat);
+      min = MAX (min, icon_width);
+      nat = MAX (min, nat);
 
-  *minimum = min;
-  *natural = nat;
-}
+      *minimum = min;
+      *natural = nat;
+    }
+  else
+    {
+      gint height, baseline;
+      gint icon_height, i;
+      PangoLayout *layout;
 
-static void
-gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                      gint       width,
-                                                      gint      *minimum,
-                                                      gint      *natural,
-                                                      gint      *minimum_baseline,
-                                                      gint      *natural_baseline)
-{
-  GtkEntry *entry = GTK_ENTRY (widget);
-  GtkEntryPrivate *priv = entry->priv;
-  PangoFontMetrics *metrics;
-  GtkBorder borders;
-  PangoContext *context;
-  gint height, baseline;
-  PangoLayout *layout;
-  int icon_min, icon_nat;
+      layout = gtk_entry_ensure_layout (entry, TRUE);
 
-  layout = gtk_entry_ensure_layout (entry, TRUE);
-  context = gtk_widget_get_pango_context (widget);
+      priv->ascent = pango_font_metrics_get_ascent (metrics);
+      priv->descent = pango_font_metrics_get_descent (metrics);
 
-  metrics = pango_context_get_metrics (context,
-                                       pango_context_get_font_description (context),
-                                      pango_context_get_language (context));
+      pango_layout_get_pixel_size (layout, NULL, &height);
 
-  priv->ascent = pango_font_metrics_get_ascent (metrics);
-  priv->descent = pango_font_metrics_get_descent (metrics);
-  pango_font_metrics_unref (metrics);
+      height = MAX (height, PANGO_PIXELS (priv->ascent + priv->descent));
 
-  _gtk_entry_get_borders (entry, &borders);
-  pango_layout_get_pixel_size (layout, NULL, &height);
+      baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
 
-  height = MAX (height, PANGO_PIXELS (priv->ascent + priv->descent));
-  height += borders.top + borders.bottom;
+      icon_height = 0;
+      for (i = 0; i < MAX_ICONS; i++)
+        {
+          EntryIconInfo *icon_info = priv->icons[i];
+          gint h;
 
-  baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
-  baseline += borders.top;
+          if (!icon_info)
+            continue;
 
-  *minimum = height;
-  *natural = height;
-  if (minimum_baseline)
-    *minimum_baseline = baseline;
-  if (natural_baseline)
-    *natural_baseline = baseline;
+          gtk_css_gadget_get_preferred_size (icon_info->gadget,
+                                             GTK_ORIENTATION_VERTICAL,
+                                             -1,
+                                             NULL, &h,
+                                             NULL, NULL);
+          icon_height = MAX (icon_height, h);
+        }
 
-  if (priv->icons[GTK_ENTRY_ICON_PRIMARY])
-    {
-      gtk_css_gadget_get_preferred_size (priv->icons[GTK_ENTRY_ICON_PRIMARY]->gadget,
-                                         GTK_ORIENTATION_VERTICAL,
-                                         -1,
-                                         &icon_min, &icon_nat,
-                                         NULL, NULL);
-      *minimum = MAX (*minimum, icon_min);
-      *natural = MAX (*natural, icon_nat);
-    }
-  if (priv->icons[GTK_ENTRY_ICON_SECONDARY])
-    {
-      gtk_css_gadget_get_preferred_size (priv->icons[GTK_ENTRY_ICON_SECONDARY]->gadget,
-                                         GTK_ORIENTATION_VERTICAL,
-                                         -1,
-                                         &icon_min, &icon_nat,
-                                         NULL, NULL);
-      *minimum = MAX (*minimum, icon_min);
-      *natural = MAX (*natural, icon_nat);
+      *minimum = MAX (height, icon_height);
+      *natural = MAX (height, icon_height);
+
+      if (icon_height > height)
+        baseline += (icon_height - height) / 2;
+
+      if (minimum_baseline)
+        *minimum_baseline = baseline;
+      if (natural_baseline)
+        *natural_baseline = baseline;
     }
-}
 
-static void
-gtk_entry_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
-{
-  gtk_entry_get_preferred_height_and_baseline_for_width (widget,
-                                                         -1,
-                                                         minimum,
-                                                         natural,
-                                                         NULL, NULL);
+  pango_font_metrics_unref (metrics);
 }
 
 static void
@@ -3645,12 +3673,10 @@ gtk_entry_get_text_area_size (GtkEntry *entry,
   GtkAllocation allocation;
   gint req_height, unused;
   gint frame_height;
-  GtkBorder borders;
 
   gtk_entry_get_preferred_height_and_baseline_for_width (widget, -1, &req_height, &unused, NULL, NULL);
 
-  gtk_widget_get_allocation (widget, &allocation);
-  _gtk_entry_get_borders (entry, &borders);
+  gtk_css_gadget_get_content_allocation (entry->priv->gadget, &allocation, NULL);
 
   if (gtk_widget_get_realized (widget))
     get_frame_size (entry, TRUE, NULL, NULL, NULL, &frame_height);
@@ -3658,16 +3684,16 @@ gtk_entry_get_text_area_size (GtkEntry *entry,
     frame_height = req_height;
 
   if (x)
-    *x = borders.left;
+    *x = 0;
 
   if (y)
-    *y = floor ((frame_height - req_height) / 2) + borders.top;
+    *y = floor ((frame_height - req_height) / 2);
 
   if (width)
-    *width = allocation.width - borders.left - borders.right;
+    *width = allocation.width;
 
   if (height)
-    *height = req_height - borders.top - borders.bottom;
+    *height = req_height;
 }
 
 static void
@@ -3697,11 +3723,11 @@ gtk_entry_get_frame_size (GtkEntry *entry,
 {
   GtkAllocation allocation;
   GtkWidget *widget = GTK_WIDGET (entry);
-  gint req_height, req_baseline, unused;
+  gint req_height, req_baseline, unused, unused2;
 
-  gtk_entry_get_preferred_height_and_baseline_for_width (widget, -1, &req_height, &unused, &req_baseline, 
&unused);
+  gtk_entry_get_preferred_height_and_baseline_for_width (widget, -1, &req_height, &unused, &req_baseline, 
&unused2);
 
-  gtk_widget_get_allocation (widget, &allocation);
+  gtk_css_gadget_get_content_allocation (entry->priv->gadget, &allocation, NULL);
 
   if (x)
     *x = allocation.x;
@@ -3724,12 +3750,7 @@ get_frame_size (GtkEntry *entry,
                 gint     *width,
                 gint     *height)
 {
-  GtkEntryClass *class;
-  GtkWidget *widget = GTK_WIDGET (entry);
-
-  g_return_if_fail (GTK_IS_ENTRY (entry));
-
-  class = GTK_ENTRY_GET_CLASS (entry);
+  GtkEntryClass *class = GTK_ENTRY_GET_CLASS (entry);
 
   g_assert (class->get_frame_size != NULL);
   class->get_frame_size (entry, x, y, width, height);
@@ -3737,7 +3758,8 @@ get_frame_size (GtkEntry *entry,
   if (!relative_to_window)
     {
       GtkAllocation allocation;
-      gtk_widget_get_allocation (widget, &allocation);
+
+      gtk_widget_get_allocation (GTK_WIDGET (entry), &allocation);
 
       if (x)
         *x -= allocation.x;
@@ -3751,12 +3773,13 @@ gtk_entry_size_allocate (GtkWidget     *widget,
                         GtkAllocation *allocation)
 {
   GtkEntry *entry = GTK_ENTRY (widget);
+  GdkRectangle clip;
 
   gtk_widget_set_allocation (widget, allocation);
 
   if (gtk_widget_get_realized (widget))
     {
-      GtkEntryCompletion* completion;
+      GtkEntryCompletion *completion;
 
       place_windows (entry);
       gtk_entry_recompute (entry);
@@ -3766,7 +3789,70 @@ gtk_entry_size_allocate (GtkWidget     *widget,
         _gtk_entry_completion_resize_popup (completion);
     }
 
-  _gtk_widget_set_simple_clip (widget, NULL);
+  gtk_css_gadget_allocate (entry->priv->gadget,
+                           allocation,
+                           gtk_widget_get_allocated_baseline (widget),
+                           &clip);
+
+  gtk_widget_set_clip (widget, &clip);
+}
+
+static void
+gtk_entry_allocate (GtkCssGadget        *gadget,
+                    const GtkAllocation *allocation,
+                    int                  baseline,
+                    GtkAllocation       *out_clip,
+                    gpointer             data)
+{
+  GtkWidget *widget;
+  GtkEntryPrivate *priv;
+  gint i;
+
+  widget = gtk_css_gadget_get_owner (gadget);
+  priv = GTK_ENTRY (widget)->priv;
+
+  out_clip->x = 0;
+  out_clip->y = 0;
+  out_clip->width = 0;
+  out_clip->height = 0;
+
+  for (i = 0; i < MAX_ICONS; i++)
+    {
+      EntryIconInfo *icon_info = priv->icons[i];
+      GtkAllocation icon_alloc;
+      GdkRectangle clip;
+      gint dummy, width, height;
+
+      if (!icon_info)
+        continue;
+
+      gtk_css_gadget_get_preferred_size (icon_info->gadget,
+                                         GTK_ORIENTATION_HORIZONTAL,
+                                         -1,
+                                         &dummy, &width,
+                                         NULL, NULL);
+      gtk_css_gadget_get_preferred_size (icon_info->gadget,
+                                         GTK_ORIENTATION_VERTICAL,
+                                         -1,
+                                         &dummy, &height,
+                                         NULL, NULL);
+
+      if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL && i == GTK_ENTRY_ICON_PRIMARY) ||
+          (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR && i == GTK_ENTRY_ICON_SECONDARY))
+        icon_alloc.x = allocation->x + allocation->width - width;
+      else
+        icon_alloc.x = allocation->x;
+      icon_alloc.y = allocation->y + (allocation->height - height) / 2;
+      icon_alloc.width = width;
+      icon_alloc.height = height;
+
+      gtk_css_gadget_allocate (icon_info->gadget,
+                               &icon_alloc,
+                               baseline,
+                               &clip);
+
+      gdk_rectangle_union (out_clip, &clip, out_clip);
+    }
 }
 
 static gboolean
@@ -3793,7 +3879,7 @@ gtk_entry_draw_frame (GtkWidget       *widget,
                       GtkStyleContext *context,
                       cairo_t         *cr)
 {
-  gint x = 0, y = 0, width, height;
+  gint y = 0, width, height;
   gint frame_x, frame_y;
 
   cairo_save (cr);
@@ -3809,17 +3895,9 @@ gtk_entry_draw_frame (GtkWidget       *widget,
   if (GTK_IS_SPIN_BUTTON (widget) &&
       gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_VERTICAL)
     {
-      GtkBorder borders;
-
       gtk_entry_get_text_area_size (GTK_ENTRY (widget), NULL, &y, NULL, &height);
-      _gtk_entry_get_borders (GTK_ENTRY (widget), &borders);
-
-      y -= borders.top;
-      height += borders.top + borders.bottom;
     }
 
-  gtk_render_background (context, cr, x, y, width, height);
-  gtk_render_frame (context, cr, x, y, width, height);
 
   gtk_entry_draw_progress (widget, context, cr);
 
@@ -3835,12 +3913,8 @@ get_progress_area (GtkWidget *widget,
 {
   GtkEntry *entry = GTK_ENTRY (widget);
   GtkEntryPrivate *private = entry->priv;
-  GtkStyleContext *context;
-  GtkBorder border, entry_borders;
   gint frame_width, text_area_width, text_area_height;
 
-  context = gtk_widget_get_style_context (widget);
-  _gtk_entry_get_borders (entry, &entry_borders);
   get_text_area_size (entry,
                       x, y,
                       &text_area_width, &text_area_height);
@@ -3848,10 +3922,8 @@ get_progress_area (GtkWidget *widget,
                   NULL, NULL,
                   &frame_width, NULL);
 
-  *x -= entry_borders.left;
-  *y -= entry_borders.top;
-  *width = text_area_width + entry_borders.left + entry_borders.right;
-  *height = text_area_height + entry_borders.top + entry_borders.bottom;
+  *width = text_area_width;
+  *height = text_area_height;
 
   /* if the text area got resized by a subclass, subtract the left/right
    * border width, so that the progress bar won't extend over the resized
@@ -3859,34 +3931,8 @@ get_progress_area (GtkWidget *widget,
    */
   if (frame_width > *width)
     {
-      gtk_style_context_get_border (context,
-                                    gtk_style_context_get_state (context),
-                                    &border);
       if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
-        {
-          *x = (frame_width - *width) + border.left;
-          *width -= border.left;
-        }
-      else
-        {
-          *width -= border.right;
-        }
-    }
-
-  if (private->progress_node)
-    {
-      GtkBorder margin;
-
-      gtk_style_context_save_to_node (context, private->progress_node);
-      gtk_style_context_get_margin (context,
-                                    gtk_style_context_get_state (context),
-                                    &margin);
-      gtk_style_context_restore (context);
-
-      *x += margin.left;
-      *y += margin.top;
-      *width -= margin.left + margin.right;
-      *height -= margin.top + margin.bottom;
+        *x = (frame_width - *width);
     }
 
   if (private->progress_pulse_mode)
@@ -3939,15 +3985,34 @@ gtk_entry_draw_progress (GtkWidget       *widget,
   gtk_style_context_restore (context);
 }
 
-static gint
+static gboolean
 gtk_entry_draw (GtkWidget *widget,
                cairo_t   *cr)
 {
-  GtkEntry *entry = GTK_ENTRY (widget);
+  gtk_css_gadget_draw (GTK_ENTRY (widget)->priv->gadget, cr);
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+static gboolean
+gtk_entry_render (GtkCssGadget *gadget,
+                  cairo_t      *cr,
+                  int           x,
+                  int           y,
+                  int           width,
+                  int           height,
+                  gpointer      data)
+{
+  GtkWidget *widget;
+  GtkEntry *entry;
   GtkStyleContext *context;
-  GtkEntryPrivate *priv = entry->priv;
+  GtkEntryPrivate *priv;
   int i;
 
+  widget = gtk_css_gadget_get_owner (gadget);
+  entry = GTK_ENTRY (widget);
+  priv = entry->priv;
+
   if (gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
     {
       context = gtk_widget_get_style_context (widget);
@@ -3955,6 +4020,15 @@ gtk_entry_draw (GtkWidget *widget,
       /* Draw entry_bg, shadow, progress and focus */
       gtk_entry_draw_frame (widget, context, cr);
 
+      /* Draw icons */
+      for (i = 0; i < MAX_ICONS; i++)
+        {
+          EntryIconInfo *icon_info = priv->icons[i];
+
+          if (icon_info != NULL)
+            gtk_css_gadget_draw (icon_info->gadget, cr);
+        }
+
       /* Draw text and cursor */
       cairo_save (cr);
 
@@ -3983,7 +4057,7 @@ gtk_entry_draw (GtkWidget *widget,
         }
     }
 
-  return GDK_EVENT_PROPAGATE;
+  return FALSE;
 }
 
 static gint
@@ -4583,7 +4657,7 @@ gtk_entry_show_magnifier (GtkEntry *entry,
 
   gtk_entry_ensure_magnifier (entry);
 
-  gtk_widget_get_allocation (GTK_WIDGET (entry), &allocation);
+  gtk_css_gadget_get_content_allocation (entry->priv->gadget, &allocation, NULL);
   get_icon_allocations (entry, &primary, &secondary);
   get_text_area_size (entry, NULL, &win_y, NULL, NULL);
   get_frame_size (entry, FALSE, NULL, &frame_y, NULL, NULL);
@@ -6440,7 +6514,8 @@ draw_text_with_color (GtkEntry *entry,
       cairo_clip (cr);
 
       gtk_render_background (context, cr,
-                             0, 0, allocation.width, allocation.height);
+                             0, 0,
+                             allocation.width, allocation.height);
 
       cairo_move_to (cr, x, y);
       gtk_style_context_get_color (context, gtk_style_context_get_state (context), &text_color);
@@ -6528,7 +6603,7 @@ gtk_entry_draw_text (GtkEntry *entry,
                        progress_width, progress_height);
       cairo_clip (cr);
       cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
-  
+
       draw_text_with_color (entry, cr, &text_color);
       cairo_restore (cr);
 
@@ -7039,7 +7114,6 @@ gtk_entry_move_adjustments (GtkEntry *entry)
   GtkAdjustment *adjustment;
   PangoContext *context;
   PangoFontMetrics *metrics;
-  GtkBorder borders;
   gint x, layout_x;
   gint char_width;
 
@@ -7047,13 +7121,12 @@ gtk_entry_move_adjustments (GtkEntry *entry)
   if (!adjustment)
     return;
 
-  gtk_widget_get_allocation (widget, &allocation);
+  gtk_css_gadget_get_content_allocation (entry->priv->gadget, &allocation, NULL);
 
   /* Cursor/char position, layout offset, border width, and widget allocation */
   gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &x, NULL);
   get_layout_position (entry, &layout_x, NULL);
-  _gtk_entry_get_borders (entry, &borders);
-  x += allocation.x + layout_x + borders.left;
+  x += allocation.x + layout_x;
 
   /* Approximate width of a char, so user can see what is ahead/behind */
   context = gtk_widget_get_pango_context (widget);
@@ -7650,7 +7723,7 @@ gtk_entry_get_text_area (GtkEntry     *entry,
       GtkAllocation allocation;
       gint x, y;
 
-      gtk_widget_get_allocation (GTK_WIDGET (entry), &allocation);
+      gtk_css_gadget_get_content_allocation (entry->priv->gadget, &allocation, NULL);
       gdk_window_get_position (priv->text_area, &x, &y);
 
       text_area->x = x - allocation.x;
@@ -9567,7 +9640,6 @@ popup_position_func (GtkMenu   *menu,
   GdkScreen *screen;
   GtkRequisition menu_req;
   GdkRectangle monitor;
-  GtkBorder borders;
   gint monitor_num, strong_x, height;
  
   g_return_if_fail (gtk_widget_get_realized (widget));
@@ -9585,9 +9657,8 @@ popup_position_func (GtkMenu   *menu,
                                  &menu_req, NULL);
   height = gdk_window_get_height (priv->text_area);
   gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &strong_x, NULL);
-  _gtk_entry_get_borders (entry, &borders);
 
-  *x += borders.left + strong_x - priv->scroll_offset;
+  *x += 0 + strong_x - priv->scroll_offset;
   if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
     *x -= menu_req.width;
 
@@ -9852,7 +9923,7 @@ bubble_targets_received (GtkClipboard     *clipboard,
   if (priv->populate_all)
     g_signal_emit (entry, signals[POPULATE_POPUP], 0, box);
 
-  gtk_widget_get_allocation (GTK_WIDGET (entry), &allocation);
+  gtk_css_gadget_get_content_allocation (entry->priv->gadget, &allocation, NULL);
 
   gtk_entry_get_cursor_locations (entry, CURSOR_STANDARD, &start_x, NULL);
 
diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c
index ca28fc7..f634abc 100644
--- a/gtk/gtkspinbutton.c
+++ b/gtk/gtkspinbutton.c
@@ -1213,7 +1213,6 @@ gtk_spin_button_get_preferred_width (GtkWidget *widget,
   if (gtk_entry_get_width_chars (entry) < 0)
     {
       gint width, w;
-      GtkBorder borders;
       PangoLayout *layout;
       gchar *str;
 
@@ -1234,9 +1233,6 @@ gtk_spin_button_get_preferred_width (GtkWidget *widget,
       width = MAX (width, w);
       g_free (str);
 
-      _gtk_entry_get_borders (entry, &borders);
-      width += borders.left + borders.right;
-
       *minimum = width;
       *natural = width;
 


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