[gtk+/rendering-cleanup-next: 145/199] Change semantics of the draw signal
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/rendering-cleanup-next: 145/199] Change semantics of the draw signal
- Date: Thu, 23 Sep 2010 21:31:17 +0000 (UTC)
commit 147e1e784593d0e3fa38d532185391e2e116fa75
Author: Benjamin Otte <otte redhat com>
Date: Tue Sep 14 16:42:16 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 0cef90f..4253fb5 100644
--- a/gtk/gtkhandlebox.c
+++ b/gtk/gtkhandlebox.c
@@ -927,20 +927,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),
@@ -991,8 +984,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);
@@ -1010,8 +1001,7 @@ gtk_handle_box_draw (GtkWidget *widget,
if (priv->child_detached)
gtk_handle_box_draw_ghost (hb, cr);
}
-
- 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);
return FALSE;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 14eadae..daa8454 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -5124,16 +5124,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))
{
@@ -5149,9 +5153,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;
@@ -5162,37 +5167,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 3ab1bd4..1e4d61b 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -950,7 +950,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]