summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-09-14 16:42:16 +0200
committerBenjamin Otte <otte@redhat.com>2010-09-26 15:11:42 +0200
commit45744d9a5fa4e51963a3abc1793cabdb51e42211 (patch)
tree38853e6f18fcfbd2826ca7f794f531a94a74a31d
parent0acec382c8deacabac089b70131e6ea531f936e1 (diff)
downloadgtk+-45744d9a5fa4e51963a3abc1793cabdb51e42211.tar.gz
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.
-rw-r--r--gtk/gtkhandlebox.c14
-rw-r--r--gtk/gtkwidget.c62
-rw-r--r--gtk/gtkwidget.h3
3 files changed, 35 insertions, 44 deletions
diff --git a/gtk/gtkhandlebox.c b/gtk/gtkhandlebox.c
index 0cef90f51b..4253fb50e3 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 3a41b72fe8..8b77e21e52 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 3ab1bd43e8..1e4d61ba30 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,