[gtk+/rendering-cleanup-next: 144/153] Change semantics of the draw signal



commit d0df7cf7088eac8529e1723b536bee935dc954e6
Author: Benjamin Otte <otte redhat com>
Date:   Fri Sep 10 20:29:05 2010 +0200

    Change semantics of the draw signal
    
    Previously, we tried to move the context's origin to the widget's top
    left location, no matter what window the paint was happening on. Now we
    only do that for child windows of the widget's window and leave the
    context untouched for windows that the widget has created outside its
    own hierarchy. In those casses, we also don't clip the context to
    the widget's allocation.
    
    Includes fixes to GtkHandlebox for this effect and fixes all known
    issues with it.
    
    These semantics assume that gtk_widget_draw() should only draw the parts
    of a widget that are inside child windows and not draw stuff that is
    located in completely different GdkWindows. In the handlebox case, it
    means that it should only draw the handle when it is attached, but not
    when it isn't. We'll likely need a special draw function for the
    detached handlebox if we want to draw it.

 gtk/gtkhandlebox.c |   14 +----------
 gtk/gtkwidget.c    |   62 ++++++++++++++++++++++++++--------------------------
 gtk/gtkwidget.h    |    3 +-
 3 files changed, 35 insertions(+), 44 deletions(-)
---
diff --git a/gtk/gtkhandlebox.c b/gtk/gtkhandlebox.c
index 9ff1aae..d11ee8a 100644
--- a/gtk/gtkhandlebox.c
+++ b/gtk/gtkhandlebox.c
@@ -922,20 +922,13 @@ gtk_handle_box_paint (GtkWidget      *widget,
   GtkHandleBoxPrivate *priv = hb->priv;
   GtkBin *bin = GTK_BIN (widget);
   GtkWidget *child;
-  gint x, y, width, height;
+  gint width, height;
   GdkRectangle rect;
   gint handle_position;
   GtkOrientation handle_orientation;
 
   handle_position = effective_handle_position (hb);
 
-  cairo_save (cr);
-
-  gdk_window_get_origin (gtk_widget_get_window (widget), &x, &y);
-  cairo_translate (cr, -x, -y);
-  gdk_window_get_origin (priv->bin_window, &x, &y);
-  cairo_translate (cr, x, y);
-
   gdk_drawable_get_size (priv->bin_window, &width, &height);
 
   gtk_cairo_paint_box (gtk_widget_get_style (widget),
@@ -986,8 +979,6 @@ gtk_handle_box_paint (GtkWidget      *widget,
                     rect.x, rect.y, rect.width, rect.height, 
                     handle_orientation);
 
-  cairo_restore (cr);
-
   child = gtk_bin_get_child (bin);
   if (child != NULL && gtk_widget_get_visible (child))
     GTK_WIDGET_CLASS (gtk_handle_box_parent_class)->draw (widget, cr, w, h);
@@ -1007,8 +998,7 @@ gtk_handle_box_draw (GtkWidget *widget,
       if (priv->child_detached)
         gtk_handle_box_draw_ghost (hb, cr, width, height);
     }
-
-  if (gtk_cairo_should_draw_window (cr, priv->bin_window))
+  else if (gtk_cairo_should_draw_window (cr, priv->bin_window))
     gtk_handle_box_paint (widget, cr, width, height);
   
   return FALSE;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index d67a67e..7df192f 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4734,16 +4734,20 @@ gtk_cairo_should_draw_window (cairo_t *cr,
  */
 void
 _gtk_widget_draw_internal (GtkWidget *widget,
-                           cairo_t   *cr)
+                           cairo_t   *cr,
+                           gboolean   clip_to_size)
 {
   if (!gtk_widget_is_drawable (widget))
     return;
 
-  cairo_rectangle (cr, 
-                   0, 0,
-                   widget->priv->allocation.width,
-                   widget->priv->allocation.height);
-  cairo_clip (cr);
+  if (clip_to_size)
+    {
+      cairo_rectangle (cr, 
+                       0, 0,
+                       widget->priv->allocation.width,
+                       widget->priv->allocation.height);
+      cairo_clip (cr);
+    }
 
   if (gdk_cairo_get_clip_rectangle (cr, NULL))
     {
@@ -4761,9 +4765,10 @@ static gboolean
 gtk_widget_real_expose_event (GtkWidget      *widget,
 			      GdkEventExpose *expose)
 {
-  GdkWindow *window;
+  GdkWindow *window, *w;
   gboolean result = FALSE;
   cairo_t *cr;
+  int x, y;
 
   if (!gtk_widget_is_drawable (widget))
     return FALSE;
@@ -4774,37 +4779,32 @@ gtk_widget_real_expose_event (GtkWidget      *widget,
   gdk_cairo_region (cr, expose->region);
   cairo_clip (cr);
 
-  /* translate cairo context properly */
-  window = gtk_widget_get_window (widget);
-  if (window != expose->window)
+  if (!gtk_widget_get_has_window (widget))
     {
-      int x, y;
-
-      if (gdk_window_get_parent (expose->window) == window)
-        {
-          gdk_window_get_position (expose->window, &x, &y);
-        }
-      else
-        {
-          int ex, ey;
-          gdk_window_get_origin (expose->window, &ex, &ey);
-          gdk_window_get_origin (window, &x, &y);
-          x = ex - x;
-          y = ey - y;
-        }
-
-      cairo_translate (cr, -x, -y);
+      x = widget->priv->allocation.x;
+      y = widget->priv->allocation.y;
+    }
+  else
+    {
+      x = 0;
+      y = 0;
     }
 
+  /* translate cairo context properly */
+  window = gtk_widget_get_window (widget);
 
-  if (!gtk_widget_get_has_window (widget))
+  for (w = expose->window; w && w != window; w = gdk_window_get_parent (w))
     {
-      cairo_translate (cr,
-                       widget->priv->allocation.x,
-                       widget->priv->allocation.y);
+      int wx, wy;
+      gdk_window_get_position (w, &wx, &wy);
+      x -= wx;
+      y -= wy;
     }
 
-  _gtk_widget_draw_internal (widget, cr);
+  if (w)
+    cairo_translate (cr, x, y);
+
+  _gtk_widget_draw_internal (widget, cr, w != NULL);
 
   /* unset here, so if someone keeps a reference to cr we
    * don't leak the window. */
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 8524c72..9e46f57 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -888,7 +888,8 @@ void            gtk_requisition_free     (GtkRequisition       *requisition);
 GdkEventExpose *  _gtk_cairo_get_event                    (cairo_t      *cr);
 
 void              _gtk_widget_draw_internal               (GtkWidget    *widget,
-                                                           cairo_t      *cr);
+                                                           cairo_t      *cr,
+                                                           gboolean      clip_to_size);
 void              _gtk_widget_set_has_default             (GtkWidget    *widget,
                                                            gboolean      has_default);
 void              _gtk_widget_set_has_grab                (GtkWidget    *widget,



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