Redrawing patch
- From: Soeren Sandmann <sandmann daimi au dk>
- To: gtk-devel-list gnome org
- Subject: Redrawing patch
- Date: 11 Nov 2001 23:15:19 +0100
Here is a patch that
- makes --gtk-debug=updates more entertaining to look at and
only draw on the exact region that is being redrawn
- fixes what I think is a typo in gdk_invalidate_maybe_recurse().
Instead of actually recursing, the function called
gdk_window_invalidate_region() with invalidate_children=TRUE
The patch makes the function actually recurse down the window
tree, based on the child_func(). If it is really intended to
just "recurse" one level and then invalidate everything from
there, I think the documentation should have a note about it
- makes GtkFrame !redraw_on_allocate and handle invalidations
itself in ->size_allocation()
This uncovered a bug where there would sometimes be rounding
errors in a calculation in gtk_frame_paint(). I think this fix
should go in, even if the rest of the patch is rejected.
- Makes GtkViewport !redraw_on_allocate. This is a really simple
change that makes the viewport not invalidate all of its child
if the child is a NO_WINDOW widget.
Søren
? drawing.patch
Index: docs/Changes-2.0.txt
===================================================================
RCS file: /cvs/gnome/gtk+/docs/Changes-2.0.txt,v
retrieving revision 1.38
diff -u -r1.38 Changes-2.0.txt
--- docs/Changes-2.0.txt 2001/11/04 22:57:01 1.38
+++ docs/Changes-2.0.txt 2001/11/11 22:09:49
@@ -509,8 +509,9 @@
longer need to gtk_widget_push_cmap (gtk_preview_get_cmap ()) in
your code.
-* The GtkBox, GtkTable, and GtkAlignment widgets now call
- gtk_widget_set_redraw_on_allocate (widget, FALSE); on themselves.
- If you want to actually draw contents in a widget derived from
- one of these widgets, you'll probably want to change this
- in your init() function.
+* The GtkBox, GtkTable, GtkViewport, GtkFrame and GtkAlignment widgets
+ now call gtk_widget_set_redraw_on_allocate (widget, FALSE); on
+ themselves. If you want to actually draw contents in a widget
+ derived from one of these widgets, you'll probably want to change
+ this in your init() function.
+
Index: gdk/gdkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.c,v
retrieving revision 1.124
diff -u -r1.124 gdkwindow.c
--- gdk/gdkwindow.c 2001/11/04 22:57:02 1.124
+++ gdk/gdkwindow.c 2001/11/11 22:09:50
@@ -1984,7 +1984,7 @@
if (debug_updates)
{
- /* Make sure we see the red invalid area before redrawing. */
+ /* Make sure we see the invalid colored area before redrawing. */
gdk_flush ();
g_usleep (70000);
}
@@ -2151,6 +2151,82 @@
gdk_region_destroy (region);
}
+static GdkColor
+get_ugly_color (void)
+{
+ static int x;
+ GdkColor ugly_color;
+
+ x++;
+ if (x == 1)
+ {
+ ugly_color.pixel = 0;
+ ugly_color.red = 50000;
+ ugly_color.green = 20000;
+ ugly_color.blue = 20000;
+ }
+ else if (x == 2)
+ {
+ ugly_color.pixel = 0;
+ ugly_color.red = 20000;
+ ugly_color.green = 20000;
+ ugly_color.blue = 50000;
+ }
+ else if (x == 3)
+ {
+ ugly_color.pixel = 0;
+ ugly_color.red = 65000;
+ ugly_color.green = 65000;
+ ugly_color.blue = 20000;
+ }
+ else
+ {
+ ugly_color.pixel = 0;
+ ugly_color.red = 20000;
+ ugly_color.green = 60000;
+ ugly_color.blue = 20000;
+
+ x = 0;
+ }
+
+ return ugly_color;
+}
+
+static void
+draw_ugly_color (GdkWindow *window,
+ GdkRegion *region)
+{
+ /* Draw ugly color all over the newly-invalid region */
+ GdkRectangle *ugly_rects;
+ gint n_ugly_rects;
+ int i;
+
+ gdk_region_get_rectangles (region, &ugly_rects, &n_ugly_rects);
+
+ for (i = 0; i < n_ugly_rects; i++)
+ {
+ GdkColor ugly_color = get_ugly_color ();
+ GdkGC *ugly_gc;
+
+ ugly_gc = gdk_gc_new (window);
+ gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color);
+
+ gdk_draw_rectangle (window,
+ ugly_gc,
+ TRUE,
+ ugly_rects[i].x, ugly_rects[i].y,
+ ugly_rects[i].width, ugly_rects[i].height);
+
+ g_object_unref (G_OBJECT (ugly_gc));
+ }
+
+ gdk_flush ();
+
+ g_free (ugly_rects);
+
+ g_usleep (10000);
+}
+
/**
* gdk_window_invalidate_maybe_recurse:
* @window: a #GdkWindow
@@ -2200,26 +2276,7 @@
if (!gdk_region_empty (visible_region))
{
if (debug_updates)
- {
- /* Draw ugly color all over the newly-invalid region */
- GdkRectangle ugly_rect;
- GdkGC *ugly_gc;
- GdkColor ugly_color = { 0, 60000, 10000, 10000 };
-
- ugly_gc = gdk_gc_new (window);
-
- gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color);
-
- gdk_region_get_clipbox (visible_region, &ugly_rect);
-
- gdk_draw_rectangle (window,
- ugly_gc,
- TRUE,
- ugly_rect.x, ugly_rect.y,
- ugly_rect.width, ugly_rect.height);
-
- g_object_unref (G_OBJECT (ugly_gc));
- }
+ draw_ugly_color (window, visible_region);
if (private->update_area)
{
@@ -2256,7 +2313,7 @@
child_region = gdk_region_copy (visible_region);
gdk_region_offset (child_region, -x, -y);
- gdk_window_invalidate_region ((GdkWindow *)child, child_region, TRUE);
+ gdk_window_invalidate_maybe_recurse ((GdkWindow *)child, child_region, child_func, user_data);
gdk_region_destroy (child_region);
}
Index: gtk/gtkframe.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkframe.c,v
retrieving revision 1.41
diff -u -r1.41 gtkframe.c
--- gtk/gtkframe.c 2001/11/04 22:57:03 1.41
+++ gtk/gtkframe.c 2001/11/11 22:09:50
@@ -184,6 +184,8 @@
static void
gtk_frame_init (GtkFrame *frame)
{
+ gtk_widget_set_redraw_on_allocate (GTK_WIDGET (frame), FALSE);
+
frame->label_widget = NULL;
frame->shadow_type = GTK_SHADOW_ETCHED_IN;
frame->label_xalign = 0.0;
@@ -522,8 +524,10 @@
xalign = 1 - frame->label_xalign;
height_extra = MAX (0, child_requisition.height - widget->style->xthickness);
- y -= height_extra * (1 - frame->label_yalign);
- height += height_extra * (1 - frame->label_yalign);
+ height_extra *= (1 - frame->label_yalign);
+
+ y -= height_extra;
+ height += height_extra;
x2 = widget->style->xthickness + (frame->child_allocation.width - child_requisition.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_SIDE_PAD;
@@ -594,6 +598,28 @@
}
static void
+gtk_frame_invalidate_border (GtkFrame *frame)
+{
+ GtkWidget *widget = GTK_WIDGET (frame);
+
+ if (GTK_WIDGET_REALIZED (widget))
+ {
+ GdkRegion *border;
+ GdkRegion *child_area;
+
+ border = gdk_region_rectangle (&(widget->allocation));
+ child_area = gdk_region_rectangle (&(frame->child_allocation));
+
+ gdk_region_subtract (border, child_area);
+
+ gdk_window_invalidate_region (widget->window, border, FALSE);
+
+ gdk_region_destroy (child_area);
+ gdk_region_destroy (border);
+ }
+}
+
+static void
gtk_frame_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
@@ -601,24 +627,18 @@
GtkBin *bin = GTK_BIN (widget);
GtkAllocation new_allocation;
+ gtk_frame_invalidate_border (frame);
+
widget->allocation = *allocation;
gtk_frame_compute_child_allocation (frame, &new_allocation);
- /* If the child allocation changed, that means that the frame is drawn
- * in a new place, so we must redraw the entire widget.
- */
- if (GTK_WIDGET_MAPPED (widget) &&
- (new_allocation.x != frame->child_allocation.x ||
- new_allocation.y != frame->child_allocation.y ||
- new_allocation.width != frame->child_allocation.width ||
- new_allocation.height != frame->child_allocation.height))
- gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
-
if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
gtk_widget_size_allocate (bin->child, &new_allocation);
frame->child_allocation = new_allocation;
+
+ gtk_frame_invalidate_border (frame);
if (frame->label_widget && GTK_WIDGET_VISIBLE (frame->label_widget))
{
Index: gtk/gtkviewport.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkviewport.c,v
retrieving revision 1.50
diff -u -r1.50 gtkviewport.c
--- gtk/gtkviewport.c 2001/11/02 21:16:54 1.50
+++ gtk/gtkviewport.c 2001/11/11 22:09:51
@@ -217,6 +217,7 @@
gtk_viewport_init (GtkViewport *viewport)
{
GTK_WIDGET_UNSET_FLAGS (viewport, GTK_NO_WINDOW);
+ gtk_widget_set_redraw_on_allocate (GTK_WIDGET (viewport), FALSE);
gtk_container_set_resize_mode (GTK_CONTAINER (viewport), GTK_RESIZE_QUEUE);
@@ -654,6 +655,8 @@
if (GTK_WIDGET_REALIZED (widget))
{
+ gdk_window_invalidate_rect (widget->window, NULL, FALSE);
+
gdk_window_move_resize (widget->window,
allocation->x + border_width,
allocation->y + border_width,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]