Re: Problems with expose_event->region patch



On Wed, 7 Mar 2001, Alexander Larsson wrote:

> In practice we may be able to get most of the benefits of expose regions
> by doing "clear area, propagate to NO_WINDOW childer the old way, render
> area or region (they are equal now)". Then non-container !NO_WINDOW
> widgets can use use expose region to optimize their redraw.
>
> The case of leaf !NO_WINDOW widgets is problably the case where using
> regions to repaint is most useful anyway. This could be drawing areas used
> as canvases and whatnot.

This does in fact work. Here is a patch that does it.
The Changes-2.0 part needs some additions.

/ Alex

Index: docs/Changes-2.0.txt
===================================================================
RCS file: /cvs/gnome/gtk+/docs/Changes-2.0.txt,v
retrieving revision 1.12
diff -u -p -r1.12 Changes-2.0.txt
--- docs/Changes-2.0.txt	2001/02/28 19:07:43	1.12
+++ docs/Changes-2.0.txt	2001/03/07 13:59:27
@@ -286,6 +286,15 @@ Incompatible Changes from GTK+-1.2 to GT
   implementation, since they will already have working expose_event
   implementations. The draw method was rarely called in practice
   anyway.
+
+- The GdkExposeEvent has a new region field. This can be used instead
+  of the area field if you want a more exact representation of the
+  area to update. If your code sends any synthetic expose events, make
+  sure you initialize the region field, by using something like:
+   event.region = gdk_region_rectangle (event.area);
+  Note that sending synthetic expose events isn't really a good way to
+  expose (parts of) a window anymore, you should use
+  gdk_window_invalidate_rect() or gdk_window_invalidate_region() instead.

 - GtkText and GtkTree are buggy and broken. We don't recommend using
   them, and changing old code to avoid them is a good idea. The
Index: gdk/gdkevents.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkevents.c,v
retrieving revision 1.34
diff -u -p -r1.34 gdkevents.c
--- gdk/gdkevents.c	2001/02/27 20:39:46	1.34
+++ gdk/gdkevents.c	2001/03/07 13:59:27
@@ -322,8 +322,12 @@ gdk_event_copy (GdkEvent *event)
       gdk_drag_context_ref (event->dnd.context);
       break;

-    default:
+    case GDK_EXPOSE:
+      if (event->expose.region)
+	new_event->expose.region = gdk_region_copy (event->expose.region);
       break;
+   default:
+      break;
     }

   return new_event;
@@ -384,7 +388,12 @@ gdk_event_free (GdkEvent *event)
       if (event->button.axes)
 	g_free (event->button.axes);
       break;
-
+
+    case GDK_EXPOSE:
+      if (event->expose.region)
+	gdk_region_destroy (event->expose.region);
+      break;
+
     case GDK_MOTION_NOTIFY:
       if (event->motion.axes)
 	g_free (event->motion.axes);
Index: gdk/gdkevents.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkevents.h,v
retrieving revision 1.12
diff -u -p -r1.12 gdkevents.h
--- gdk/gdkevents.h	2001/02/27 20:39:47	1.12
+++ gdk/gdkevents.h	2001/03/07 13:59:27
@@ -215,6 +215,7 @@ struct _GdkEventExpose
   GdkWindow *window;
   gint8 send_event;
   GdkRectangle area;
+  GdkRegion *region;
   gint count; /* If non-zero, how many more events follow. */
 };

Index: gdk/gdkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.c,v
retrieving revision 1.109
diff -u -p -r1.109 gdkwindow.c
--- gdk/gdkwindow.c	2001/02/27 20:39:47	1.109
+++ gdk/gdkwindow.c	2001/03/07 13:59:27
@@ -1748,6 +1748,8 @@ gdk_window_process_updates_internal (Gdk
 	{
 	  GdkEvent event;
 	  GdkRectangle window_rect;
+	  GdkRegion *expose_region;
+	  GdkRegion *window_region;
           gint width, height;

           if (debug_updates)
@@ -1769,16 +1771,28 @@ gdk_window_process_updates_internal (Gdk
 	  event.expose.type = GDK_EXPOSE;
 	  event.expose.window = gdk_window_ref (window);
 	  event.expose.count = 0;
-
-	  gdk_region_get_clipbox (update_area, &event.expose.area);
-	  if (gdk_rectangle_intersect (&event.expose.area, &window_rect, &event.expose.area))
+
+	  if (save_region)
+	    expose_region = gdk_region_copy (update_area);
+	  else
+	    expose_region = update_area;
+	  window_region = gdk_region_rectangle (&window_rect);
+	  gdk_region_intersect (expose_region,
+				window_region);
+	  gdk_region_destroy (window_region);
+
+	  event.expose.region = expose_region;
+	  gdk_region_get_clipbox (expose_region, &event.expose.area);
+
+	  if (!gdk_region_empty (expose_region))
 	    {
 	      (*gdk_event_func) (&event, gdk_event_data);
 	    }

+	  if (expose_region != update_area)
+	    gdk_region_destroy (expose_region);
 	  gdk_window_unref (window);
 	}
-
       if (!save_region)
 	gdk_region_destroy (update_area);
     }
Index: gdk/x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.41
diff -u -p -r1.41 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c	2001/03/03 21:34:18	1.41
+++ gdk/x11/gdkevents-x11.c	2001/03/07 13:59:28
@@ -973,6 +973,7 @@ gdk_event_translate (GdkEvent *event,
 	  {
 	    event->expose.type = GDK_EXPOSE;
 	    event->expose.area = expose_rect;
+	    event->expose.region = gdk_region_rectangle (&expose_rect);
 	    event->expose.window = window;
 	    event->expose.count = xevent->xexpose.count;

@@ -1007,6 +1008,7 @@ gdk_event_translate (GdkEvent *event,
 	  {
 	    event->expose.type = GDK_EXPOSE;
 	    event->expose.area = expose_rect;
+	    event->expose.region = gdk_region_rectangle (&expose_rect);
 	    event->expose.window = window;
 	    event->expose.count = xevent->xgraphicsexpose.count;

Index: gtk/gtkcontainer.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcontainer.h,v
retrieving revision 1.35
diff -u -p -r1.35 gtkcontainer.h
--- gtk/gtkcontainer.h	2000/12/11 17:47:24	1.35
+++ gtk/gtkcontainer.h	2001/03/07 13:59:28
@@ -130,6 +130,9 @@ void     gtk_container_foreach_full (Gtk
 GList*   gtk_container_children     (GtkContainer       *container);
 gboolean gtk_container_focus        (GtkContainer       *container,
 				     GtkDirectionType    direction);
+void     gtk_container_propagate_expose (GtkContainer   *container,
+					 GtkWidget      *child,
+					 GdkEventExpose *event);

 /* Widget-level methods */

Index: gtk/gtkcontainer.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcontainer.c,v
retrieving revision 1.70
diff -u -p -r1.70 gtkcontainer.c
--- gtk/gtkcontainer.c	2001/02/03 01:09:39	1.70
+++ gtk/gtkcontainer.c	2001/03/07 13:59:28
@@ -96,6 +96,8 @@ static void     gtk_container_children_c
 						    gpointer           client_data);
 static void     gtk_container_show_all             (GtkWidget         *widget);
 static void     gtk_container_hide_all             (GtkWidget         *widget);
+static gint     gtk_container_expose               (GtkWidget         *widget,
+						    GdkEventExpose    *event);


 static gchar* gtk_container_child_default_composite_name (GtkContainer *container,
@@ -172,6 +174,7 @@ gtk_container_class_init (GtkContainerCl

   widget_class->show_all = gtk_container_show_all;
   widget_class->hide_all = gtk_container_hide_all;
+  widget_class->expose_event = gtk_container_expose;

   class->add = gtk_container_add_unimplemented;
   class->remove = gtk_container_remove_unimplemented;
@@ -1962,4 +1965,83 @@ gtk_container_hide_all (GtkWidget *widge
   gtk_container_foreach (GTK_CONTAINER (widget),
 			 (GtkCallback) gtk_widget_hide_all,
 			 NULL);
+}
+
+
+static void
+gtk_container_expose_child (GtkWidget *child,
+			    gpointer   client_data)
+{
+  struct {
+    GtkWidget *container;
+    GdkEventExpose *event;
+  } *data = client_data;
+
+  gtk_container_propagate_expose (GTK_CONTAINER (data->container),
+				  child,
+				  data->event);
+}
+
+static gint
+gtk_container_expose (GtkWidget      *widget,
+		      GdkEventExpose *event)
+{
+  struct {
+    GtkWidget *container;
+    GdkEventExpose *event;
+  } data;
+
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_CONTAINER (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    {
+      data.container = widget;
+      data.event = event;
+
+      gtk_container_foreach (GTK_CONTAINER (widget),
+			     gtk_container_expose_child,
+			     &data);
+    }
+
+  return TRUE;
+}
+
+
+/**
+ * gtk_container_propagate_expose:
+ * @container: a #GtkContainer
+ * @child: a child of @container
+ * @event: a expose event sent to container
+ *
+ * Some windows (those without GdkWindows) need to get synthetic expose
+ * events, since they don't get expose events otherwise. This function
+ * should be used by all containers to propagate expose events. It handles
+ * correct intersecting and coordinate translation of the event.
+ **/
+void
+gtk_container_propagate_expose (GtkContainer   *container,
+				GtkWidget      *child,
+				GdkEventExpose *event)
+{
+  GdkEventExpose child_event;
+
+  g_return_if_fail (GTK_IS_CONTAINER (container));
+  g_return_if_fail (GTK_IS_WIDGET (child));
+  g_return_if_fail (event != NULL);
+
+  if (GTK_WIDGET_DRAWABLE (child) &&
+      GTK_WIDGET_NO_WINDOW (child))
+    {
+      child_event = *event;
+
+      if (gtk_widget_intersect (child, &event->area, &child_event.area))
+	{
+	  child_event.region = gdk_region_rectangle (&child_event.area);
+	  gtk_widget_send_expose (child, (GdkEvent *)&child_event);
+	  gdk_region_destroy (child_event.region);
+	}
+    }
 }
Index: gtk/gtkwidget.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.h,v
retrieving revision 1.91
diff -u -p -r1.91 gtkwidget.h
--- gtk/gtkwidget.h	2001/02/28 19:07:46	1.91
+++ gtk/gtkwidget.h	2001/03/07 13:59:34
@@ -469,6 +469,8 @@ void	   gtk_widget_unlock_accelerators (
 gboolean   gtk_widget_accelerators_locked (GtkWidget	       *widget);
 gint	   gtk_widget_event		  (GtkWidget	       *widget,
 					   GdkEvent	       *event);
+gint       gtk_widget_send_expose         (GtkWidget           *widget,
+					   GdkEvent            *event);

 gboolean   gtk_widget_activate		     (GtkWidget	       *widget);
 gboolean   gtk_widget_set_scroll_adjustments (GtkWidget        *widget,
@@ -642,6 +644,7 @@ void	     gtk_widget_class_path	   (GtkW
 					    guint     *path_length,
 					    gchar    **path,
 					    gchar    **path_reversed);
+

 #if	defined (GTK_TRACE_OBJECTS) && defined (__GNUC__)
 #  define gtk_widget_ref gtk_object_ref
Index: gtk/gtkwidget.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.c,v
retrieving revision 1.188
diff -u -p -r1.188 gtkwidget.c
--- gtk/gtkwidget.c	2001/03/06 05:49:26	1.188
+++ gtk/gtkwidget.c	2001/03/07 13:59:33
@@ -182,6 +182,8 @@ static void gtk_widget_set_style_interna
 						  gboolean	 initial_emission);
 static void gtk_widget_set_style_recurse	 (GtkWidget	*widget,
 						  gpointer	 client_data);
+static gint gtk_widget_event_internal            (GtkWidget     *widget,
+						  GdkEvent      *event);

 static GtkWidgetAuxInfo* gtk_widget_aux_info_new     (void);
 static void		 gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
@@ -2250,11 +2252,61 @@ gint
 gtk_widget_event (GtkWidget *widget,
 		  GdkEvent  *event)
 {
-  gboolean return_val;
-  gint signal_num;
+  g_return_val_if_fail (widget != NULL, TRUE);
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
+
+  if (event->type == GDK_EXPOSE)
+    {
+      g_warning ("Events of type GDK_EXPOSE cannot be synthesized. To get "
+		 "the same effect, call gdk_window_invalidate_rect/region(), "
+		 "followed by gdk_window_process_updates().");
+      return TRUE;
+    }
+
+  return gtk_widget_event_internal (widget, event);
+}

+
+/**
+ * gtk_widget_send_expose:
+ * @widget: a #GtkWidget
+ * @event: a expose #GdkEvent
+ *
+ * Very rarely-used function. This function is used to emit
+ * an expose event signals on a widget. This function is not
+ * normally used directly. The only time it is used is when
+ * propagating an expose event to a child NO_WINDOW widget, and
+ * that is normally done using gtk_container_propagate_expose.
+ *
+ * If you just want to synthesize an expose event, use
+ * gdk_window_invalidate_rect() to invalidate a region of the
+ * window.
+ *
+ * Return value: return from the event signal emission (%TRUE if the event was handled)
+ **/
+gint
+gtk_widget_send_expose (GtkWidget *widget,
+			GdkEvent  *event)
+{
   g_return_val_if_fail (widget != NULL, TRUE);
   g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
+  g_return_val_if_fail (event != NULL, TRUE);
+  g_return_val_if_fail (event->type == GDK_EXPOSE, TRUE);
+
+  if (event->type != GDK_EXPOSE)
+    return TRUE;
+
+  return gtk_widget_event_internal (widget, event);
+}
+
+/* This internal function is called from gtkmain.c
+ * to allow it to pass expose events. */
+static gint
+gtk_widget_event_internal (GtkWidget *widget,
+			   GdkEvent  *event)
+{
+  gboolean return_val;
+  gint signal_num;

   gtk_widget_ref (widget);
   return_val = FALSE;
Index: gtk/gtkbin.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkbin.c,v
retrieving revision 1.24
diff -u -p -r1.24 gtkbin.c
--- gtk/gtkbin.c	2001/02/09 00:40:47	1.24
+++ gtk/gtkbin.c	2001/03/07 13:59:28
@@ -31,8 +31,6 @@ static void gtk_bin_class_init (GtkBinCl
 static void gtk_bin_init       (GtkBin         *bin);
 static void gtk_bin_map        (GtkWidget      *widget);
 static void gtk_bin_unmap      (GtkWidget      *widget);
-static gint gtk_bin_expose     (GtkWidget      *widget,
-			        GdkEventExpose *event);
 static void gtk_bin_add        (GtkContainer   *container,
 			        GtkWidget      *widget);
 static void gtk_bin_remove     (GtkContainer   *container,
@@ -87,7 +85,6 @@ gtk_bin_class_init (GtkBinClass *class)

   widget_class->map = gtk_bin_map;
   widget_class->unmap = gtk_bin_unmap;
-  widget_class->expose_event = gtk_bin_expose;

   container_class->add = gtk_bin_add;
   container_class->remove = gtk_bin_remove;
@@ -150,32 +147,6 @@ gtk_bin_unmap (GtkWidget *widget)
   if (bin->child && GTK_WIDGET_MAPPED (bin->child))
     gtk_widget_unmap (bin->child);
 }
-
-static gint
-gtk_bin_expose (GtkWidget      *widget,
-		GdkEventExpose *event)
-{
-  GtkBin *bin;
-  GdkEventExpose child_event;
-
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_BIN (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
-    {
-      bin = GTK_BIN (widget);
-
-      child_event = *event;
-      if (bin->child && GTK_WIDGET_DRAWABLE (bin->child) &&
-	  GTK_WIDGET_NO_WINDOW (bin->child) &&
-	  gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	gtk_widget_event (bin->child, (GdkEvent*) &child_event);
-    }
-
-  return FALSE;
-}
-

 static void
 gtk_bin_add (GtkContainer *container,
Index: gtk/gtkbox.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkbox.c,v
retrieving revision 1.29
diff -u -p -r1.29 gtkbox.c
--- gtk/gtkbox.c	2000/12/13 01:34:38	1.29
+++ gtk/gtkbox.c	2001/03/07 13:59:28
@@ -51,8 +51,6 @@ static void gtk_box_set_arg    (GtkObjec
 				guint           arg_id);
 static void gtk_box_map        (GtkWidget      *widget);
 static void gtk_box_unmap      (GtkWidget      *widget);
-static gint gtk_box_expose     (GtkWidget      *widget,
-			        GdkEventExpose *event);
 static void gtk_box_add        (GtkContainer   *container,
 			        GtkWidget      *widget);
 static void gtk_box_remove     (GtkContainer   *container,
@@ -126,7 +124,6 @@ gtk_box_class_init (GtkBoxClass *class)

   widget_class->map = gtk_box_map;
   widget_class->unmap = gtk_box_unmap;
-  widget_class->expose_event = gtk_box_expose;

   container_class->add = gtk_box_add;
   container_class->remove = gtk_box_remove;
@@ -627,41 +624,6 @@ gtk_box_unmap (GtkWidget *widget)
 	  GTK_WIDGET_MAPPED (child->widget))
 	gtk_widget_unmap (child->widget);
     }
-}
-
-static gint
-gtk_box_expose (GtkWidget      *widget,
-		GdkEventExpose *event)
-{
-  GtkBox *box;
-  GtkBoxChild *child;
-  GdkEventExpose child_event;
-  GList *children;
-
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_BOX (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
-    {
-      box = GTK_BOX (widget);
-
-      child_event = *event;
-
-      children = box->children;
-      while (children)
-	{
-	  child = children->data;
-	  children = children->next;
-
-	  if (GTK_WIDGET_DRAWABLE (child->widget) &&
-	      GTK_WIDGET_NO_WINDOW (child->widget) &&
-	      gtk_widget_intersect (child->widget, &event->area, &child_event.area))
-	    gtk_widget_event (child->widget, (GdkEvent*) &child_event);
-	}
-    }
-
-  return FALSE;
 }

 static void
Index: gtk/gtkbutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkbutton.c,v
retrieving revision 1.53
diff -u -p -r1.53 gtkbutton.c
--- gtk/gtkbutton.c	2001/03/06 15:51:09	1.53
+++ gtk/gtkbutton.c	2001/03/07 13:59:28
@@ -142,9 +142,8 @@ gtk_button_class_init (GtkButtonClass *k
   object_class = (GtkObjectClass*) klass;
   widget_class = (GtkWidgetClass*) klass;
   container_class = (GtkContainerClass*) klass;
-
-  parent_class = gtk_type_class (GTK_TYPE_BIN);
-
+
+  parent_class = g_type_class_peek_parent (klass);

   object_class->set_arg = gtk_button_set_arg;
   object_class->get_arg = gtk_button_get_arg;
@@ -715,7 +714,6 @@ gtk_button_expose (GtkWidget      *widge
 		   GdkEventExpose *event)
 {
   GtkBin *bin;
-  GdkEventExpose child_event;

   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_BUTTON (widget), FALSE);
@@ -726,13 +724,10 @@ gtk_button_expose (GtkWidget      *widge
       bin = GTK_BIN (widget);

       gtk_button_paint (widget, &event->area);
-
-      child_event = *event;
-      if (bin->child && GTK_WIDGET_NO_WINDOW (bin->child) &&
-	  gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+
+      (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
     }
-
+
   return FALSE;
 }

Index: gtk/gtkcheckbutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkcheckbutton.c,v
retrieving revision 1.25
diff -u -p -r1.25 gtkcheckbutton.c
--- gtk/gtkcheckbutton.c	2001/02/28 19:07:44	1.25
+++ gtk/gtkcheckbutton.c	2001/03/07 13:59:28
@@ -243,7 +243,6 @@ gtk_check_button_expose (GtkWidget
   GtkCheckButton *check_button;
   GtkToggleButton *toggle_button;
   GtkBin *bin;
-  GdkEventExpose child_event;

   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_CHECK_BUTTON (widget), FALSE);
@@ -259,16 +258,13 @@ gtk_check_button_expose (GtkWidget
 	{
 	  gtk_check_button_paint (widget, &event->area);

-	  child_event = *event;
-	  if (bin->child && GTK_WIDGET_NO_WINDOW (bin->child) &&
-	      gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	    gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+	  if (bin->child)
+	    gtk_container_propagate_expose (GTK_CONTAINER (widget),
+					    bin->child,
+					    event);
 	}
-      else
-	{
-	  if (GTK_WIDGET_CLASS (parent_class)->expose_event)
-	    (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
-	}
+      else if (GTK_WIDGET_CLASS (parent_class)->expose_event)
+	(* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
     }

   return FALSE;
Index: gtk/gtkeventbox.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkeventbox.c,v
retrieving revision 1.20
diff -u -p -r1.20 gtkeventbox.c
--- gtk/gtkeventbox.c	2000/12/04 01:15:36	1.20
+++ gtk/gtkeventbox.c	2001/03/07 13:59:28
@@ -41,6 +41,8 @@ static gint gtk_event_box_expose
 						   GdkEventExpose     *event);


+static GtkBinClass *parent_class = NULL;
+
 GtkType
 gtk_event_box_get_type (void)
 {
@@ -71,6 +73,8 @@ gtk_event_box_class_init (GtkEventBoxCla
 {
   GtkWidgetClass *widget_class;

+  parent_class = gtk_type_class (GTK_TYPE_BIN);
+
   widget_class = (GtkWidgetClass*) class;

   widget_class->realize = gtk_event_box_realize;
@@ -204,24 +208,15 @@ static gint
 gtk_event_box_expose (GtkWidget      *widget,
 		     GdkEventExpose *event)
 {
-  GtkBin *bin;
-  GdkEventExpose child_event;
-
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_EVENT_BOX (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);

   if (GTK_WIDGET_DRAWABLE (widget))
     {
-      bin = GTK_BIN (widget);
-
       gtk_event_box_paint (widget, &event->area);

-      child_event = *event;
-      if (bin->child &&
-	  GTK_WIDGET_NO_WINDOW (bin->child) &&
-	  gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+      (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
     }

   return FALSE;
Index: gtk/gtkfixed.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfixed.c,v
retrieving revision 1.23
diff -u -p -r1.23 gtkfixed.c
--- gtk/gtkfixed.c	2000/12/04 01:15:36	1.23
+++ gtk/gtkfixed.c	2001/03/07 13:59:29
@@ -37,8 +37,6 @@ static void gtk_fixed_size_allocate (Gtk
 				     GtkAllocation    *allocation);
 static void gtk_fixed_paint         (GtkWidget        *widget,
 				     GdkRectangle     *area);
-static gint gtk_fixed_expose        (GtkWidget        *widget,
-				     GdkEventExpose   *event);
 static void gtk_fixed_add           (GtkContainer     *container,
 				     GtkWidget        *widget);
 static void gtk_fixed_remove        (GtkContainer     *container,
@@ -95,7 +93,6 @@ gtk_fixed_class_init (GtkFixedClass *cla
   widget_class->realize = gtk_fixed_realize;
   widget_class->size_request = gtk_fixed_size_request;
   widget_class->size_allocate = gtk_fixed_size_allocate;
-  widget_class->expose_event = gtk_fixed_expose;

   container_class->add = gtk_fixed_add;
   container_class->remove = gtk_fixed_remove;
@@ -347,41 +344,6 @@ gtk_fixed_paint (GtkWidget    *widget,
     gdk_window_clear_area (widget->window,
 			   area->x, area->y,
 			   area->width, area->height);
-}
-
-static gint
-gtk_fixed_expose (GtkWidget      *widget,
-		  GdkEventExpose *event)
-{
-  GtkFixed *fixed;
-  GtkFixedChild *child;
-  GdkEventExpose child_event;
-  GList *children;
-
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_FIXED (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
-    {
-      fixed = GTK_FIXED (widget);
-
-      child_event = *event;
-
-      children = fixed->children;
-      while (children)
-	{
-	  child = children->data;
-	  children = children->next;
-
-	  if (GTK_WIDGET_NO_WINDOW (child->widget) &&
-	      gtk_widget_intersect (child->widget, &event->area,
-				    &child_event.area))
-	    gtk_widget_event (child->widget, (GdkEvent*) &child_event);
-	}
-    }
-
-  return FALSE;
 }

 static void
Index: gtk/gtkframe.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkframe.c,v
retrieving revision 1.34
diff -u -p -r1.34 gtkframe.c
--- gtk/gtkframe.c	2001/02/02 17:53:29	1.34
+++ gtk/gtkframe.c	2001/03/07 13:59:29
@@ -399,6 +399,7 @@ gtk_frame_paint (GtkWidget    *widget,

 	  x2 = widget->style->xthickness + (frame->child_allocation.width - child_requisition.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_SIDE_PAD;

+
 	  gtk_paint_shadow_gap (widget->style, widget->window,
 				GTK_STATE_NORMAL, frame->shadow_type,
 				area, widget, "frame",
@@ -418,27 +419,11 @@ static gboolean
 gtk_frame_expose (GtkWidget      *widget,
 		  GdkEventExpose *event)
 {
-  GtkBin *bin = GTK_BIN (widget);
-  GtkFrame *frame = GTK_FRAME (widget);
-  GdkEventExpose child_event;
-
   if (GTK_WIDGET_DRAWABLE (widget))
     {
       gtk_frame_paint (widget, &event->area);

-      if (bin->child && GTK_WIDGET_NO_WINDOW (bin->child))
-	{
-	  child_event = *event;
-	  if (gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	    gtk_widget_event (bin->child, (GdkEvent*) &child_event);
-	}
-
-      if (frame->label_widget && GTK_WIDGET_NO_WINDOW (frame->label_widget))
-	{
-	  child_event = *event;
-	  if (gtk_widget_intersect (frame->label_widget, &event->area, &child_event.area))
-	    gtk_widget_event (frame->label_widget, (GdkEvent*) &child_event);
-	}
+      (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
     }

   return FALSE;
Index: gtk/gtkhandlebox.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkhandlebox.c,v
retrieving revision 1.74
diff -u -p -r1.74 gtkhandlebox.c
--- gtk/gtkhandlebox.c	2001/03/05 15:09:02	1.74
+++ gtk/gtkhandlebox.c	2001/03/07 13:59:29
@@ -813,7 +813,6 @@ gtk_handle_box_paint (GtkWidget      *wi
   if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
     {
       GdkRectangle child_area;
-      GdkEventExpose child_event;

       if (!event) /* we were called from draw() */
 	{
@@ -821,13 +820,7 @@ gtk_handle_box_paint (GtkWidget      *wi
 	    gtk_widget_draw (bin->child, &child_area);
 	}
       else /* we were called from expose() */
-	{
-	  child_event = *event;
-
-	  if (GTK_WIDGET_NO_WINDOW (bin->child) &&
-	      gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	    gtk_widget_event (bin->child, (GdkEvent *) &child_event);
-	}
+	(* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
     }
 }

Index: gtk/gtkimagemenuitem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkimagemenuitem.c,v
retrieving revision 1.2
diff -u -p -r1.2 gtkimagemenuitem.c
--- gtk/gtkimagemenuitem.c	2001/02/15 03:40:48	1.2
+++ gtk/gtkimagemenuitem.c	2001/03/07 13:59:29
@@ -35,8 +38,6 @@ static void gtk_image_menu_item_size_req
                                                       GtkRequisition   *requisition);
 static void gtk_image_menu_item_size_allocate        (GtkWidget        *widget,
                                                       GtkAllocation    *allocation);
-static gint gtk_image_menu_item_expose               (GtkWidget             *widget,
-						      GdkEventExpose        *event);
 static void gtk_image_menu_item_remove               (GtkContainer          *container,
                                                       GtkWidget             *child);
 static void gtk_image_menu_item_toggle_size_request  (GtkMenuItem           *menu_item,
@@ -110,7 +111,6 @@ gtk_image_menu_item_class_init (GtkImage

   parent_class = gtk_type_class (GTK_TYPE_MENU_ITEM);

-  widget_class->expose_event = gtk_image_menu_item_expose;
   widget_class->size_request = gtk_image_menu_item_size_request;
   widget_class->size_allocate = gtk_image_menu_item_size_allocate;
   widget_class->map = gtk_image_menu_item_map;
@@ -283,31 +283,6 @@ gtk_image_menu_item_size_allocate (GtkWi
     }
 }

-static gint
-gtk_image_menu_item_expose (GtkWidget      *widget,
-			    GdkEventExpose *event)
-{
-  GdkEventExpose child_event;
-  GtkImageMenuItem *image_menu_item;
-
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_IMAGE_MENU_ITEM (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  image_menu_item = GTK_IMAGE_MENU_ITEM (widget);
-
-  if (GTK_WIDGET_CLASS (parent_class)->expose_event)
-    (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
-
-  child_event = *event;
-  if (image_menu_item->image && GTK_WIDGET_DRAWABLE (image_menu_item->image) &&
-      GTK_WIDGET_NO_WINDOW (image_menu_item->image) &&
-      gtk_widget_intersect (image_menu_item->image, &event->area, &child_event.area))
-    gtk_widget_event (image_menu_item->image, (GdkEvent*) &child_event);
-
-  return FALSE;
-}
-
 static void
 gtk_image_menu_item_map (GtkWidget *widget)
 {
Index: gtk/gtklayout.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklayout.c,v
retrieving revision 1.34
diff -u -p -r1.34 gtklayout.c
--- gtk/gtklayout.c	2001/03/02 17:06:08	1.34
+++ gtk/gtklayout.c	2001/03/07 13:59:30
@@ -606,9 +606,7 @@ gtk_layout_size_allocate (GtkWidget
 static gint
 gtk_layout_expose (GtkWidget *widget, GdkEventExpose *event)
 {
-  GList *tmp_list;
   GtkLayout *layout;
-  GdkEventExpose child_event;

   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_LAYOUT (widget), FALSE);
@@ -618,18 +616,7 @@ gtk_layout_expose (GtkWidget *widget, Gd
   if (event->window != layout->bin_window)
     return FALSE;

-  tmp_list = layout->children;
-  while (tmp_list)
-    {
-      GtkLayoutChild *child = tmp_list->data;
-      tmp_list = tmp_list->next;
-
-      child_event = *event;
-      if (GTK_WIDGET_DRAWABLE (child->widget) &&
-	  GTK_WIDGET_NO_WINDOW (child->widget) &&
-	  gtk_widget_intersect (child->widget, &event->area, &child_event.area))
-	gtk_widget_event (child->widget, (GdkEvent*) &child_event);
-    }
+  (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);

   return FALSE;
 }
Index: gtk/gtklist.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklist.c,v
retrieving revision 1.54
diff -u -p -r1.54 gtklist.c
--- gtk/gtklist.c	2001/02/25 17:25:08	1.54
+++ gtk/gtklist.c	2001/03/07 13:59:30
@@ -68,8 +68,6 @@ static void gtk_list_map	     (GtkWidget
 static void gtk_list_unmap	     (GtkWidget	     *widget);
 static void gtk_list_style_set	     (GtkWidget      *widget,
 				      GtkStyle       *previous_style);
-static gint gtk_list_expose	     (GtkWidget	     *widget,
-				      GdkEventExpose *event);
 static gint gtk_list_motion_notify   (GtkWidget      *widget,
 				      GdkEventMotion *event);
 static gint gtk_list_button_press    (GtkWidget      *widget,
@@ -224,7 +222,6 @@ gtk_list_class_init (GtkListClass *class
   widget_class->unmap = gtk_list_unmap;
   widget_class->style_set = gtk_list_style_set;
   widget_class->realize = gtk_list_realize;
-  widget_class->expose_event = gtk_list_expose;
   widget_class->button_press_event = gtk_list_button_press;
   widget_class->button_release_event = gtk_list_button_release;
   widget_class->motion_notify_event = gtk_list_motion_notify;
@@ -833,40 +830,6 @@ gtk_list_button_release (GtkWidget	*widg
 	}
     }

-  return FALSE;
-}
-
-static gint
-gtk_list_expose (GtkWidget	*widget,
-		 GdkEventExpose *event)
-{
-  GtkList *list;
-  GtkWidget *child;
-  GdkEventExpose child_event;
-  GList *children;
-
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_LIST (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
-    {
-      list = GTK_LIST (widget);
-
-      child_event = *event;
-
-      children = list->children;
-      while (children)
-	{
-	  child = children->data;
-	  children = children->next;
-
-	  if (GTK_WIDGET_NO_WINDOW (child) &&
-	      gtk_widget_intersect (child, &event->area, &child_event.area))
-	    gtk_widget_event (child, (GdkEvent*) &child_event);
-	}
-    }
-
   return FALSE;
 }

Index: gtk/gtklistitem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklistitem.c,v
retrieving revision 1.25
diff -u -p -r1.25 gtklistitem.c
--- gtk/gtklistitem.c	2001/02/28 19:07:45	1.25
+++ gtk/gtklistitem.c	2001/03/07 13:59:30
@@ -483,16 +483,7 @@ gtk_list_item_expose (GtkWidget      *wi
                               0, 0, -1, -1);
         }

-      if (bin->child)
-	{
-          GdkEventExpose child_event;
-
-	  child_event = *event;
-
-	  if (GTK_WIDGET_NO_WINDOW (bin->child) &&
-	      gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	    gtk_widget_event (bin->child, (GdkEvent*) &child_event);
-	}
+      (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);

       if (GTK_WIDGET_HAS_FOCUS (widget))
         {
Index: gtk/gtkmain.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.c,v
retrieving revision 1.152
diff -u -p -r1.152 gtkmain.c
--- gtk/gtkmain.c	2001/03/03 21:34:18	1.152
+++ gtk/gtkmain.c	2001/03/07 13:59:30
@@ -871,7 +871,7 @@ gtk_main_do_event (GdkEvent *event)
       if (event->any.window && GTK_WIDGET_DOUBLE_BUFFERED (event_widget))
 	gdk_window_begin_paint_rect (event->any.window, &event->expose.area);

-      gtk_widget_event (event_widget, event);
+      gtk_widget_send_expose (event_widget, event);

       if (event->any.window && GTK_WIDGET_DOUBLE_BUFFERED (event_widget))
 	gdk_window_end_paint (event->any.window);
Index: gtk/gtkmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.c,v
retrieving revision 1.57
diff -u -p -r1.57 gtkmenu.c
--- gtk/gtkmenu.c	2001/03/05 17:07:19	1.57
+++ gtk/gtkmenu.c	2001/03/07 13:59:31
@@ -1367,34 +1367,15 @@ static gboolean
 gtk_menu_expose (GtkWidget	*widget,
 		 GdkEventExpose *event)
 {
-  GtkMenuShell *menu_shell;
-  GtkWidget *child;
-  GList *children;
-  GtkMenu *menu;
-
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_MENU (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);

-  menu_shell = GTK_MENU_SHELL (widget);
-  menu = GTK_MENU (widget);
-
   if (GTK_WIDGET_DRAWABLE (widget))
     {
-      GdkEventExpose child_event = *event;
-
       gtk_menu_paint (widget);

-      children = menu_shell->children;
-      while (children)
-	{
-	  child = children->data;
-	  children = children->next;
-
-	  if (GTK_WIDGET_NO_WINDOW (child) &&
-	      gtk_widget_intersect (child, &event->area, &child_event.area))
-	    gtk_widget_event (child, (GdkEvent*) &child_event);
-	}
+      (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
     }

   return FALSE;
Index: gtk/gtkmenubar.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenubar.c,v
retrieving revision 1.22
diff -u -p -r1.22 gtkmenubar.c
--- gtk/gtkmenubar.c	2001/02/13 05:44:47	1.22
+++ gtk/gtkmenubar.c	2001/03/07 13:59:31
@@ -58,6 +58,8 @@ static gint gtk_menu_bar_expose        (
 					GdkEventExpose  *event);


+static GtkMenuShellClass *parent_class = NULL;
+
 GtkType
 gtk_menu_bar_get_type (void)
 {
@@ -92,6 +94,8 @@ gtk_menu_bar_class_init (GtkMenuBarClass

   GtkBindingSet *binding_set;

+  parent_class = g_type_class_peek_parent (class);
+
   object_class = (GtkObjectClass*) class;
   widget_class = (GtkWidgetClass*) class;
   menu_shell_class = (GtkMenuShellClass*) class;
@@ -384,11 +388,6 @@ static gint
 gtk_menu_bar_expose (GtkWidget      *widget,
 		     GdkEventExpose *event)
 {
-  GtkMenuShell *menu_shell;
-  GdkEventExpose child_event;
-  GList *children;
-  GtkWidget *child;
-
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_MENU_BAR (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
@@ -396,20 +395,8 @@ gtk_menu_bar_expose (GtkWidget      *wid
   if (GTK_WIDGET_DRAWABLE (widget))
     {
       gtk_menu_bar_paint (widget, &event->area);
-
-      menu_shell = GTK_MENU_SHELL (widget);
-      child_event = *event;

-      children = menu_shell->children;
-      while (children)
-	{
-	  child = children->data;
-	  children = children->next;
-
-	  if (GTK_WIDGET_NO_WINDOW (child) &&
-	      gtk_widget_intersect (child, &event->area, &child_event.area))
-	    gtk_widget_event (child, (GdkEvent*) &child_event);
-	}
+      (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
     }

   return FALSE;
Index: gtk/gtkmenuitem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenuitem.c,v
retrieving revision 1.46
diff -u -p -r1.46 gtkmenuitem.c
--- gtk/gtkmenuitem.c	2001/02/13 05:44:47	1.46
+++ gtk/gtkmenuitem.c	2001/03/07 13:59:31
@@ -523,9 +523,6 @@ static gint
 gtk_menu_item_expose (GtkWidget      *widget,
 		      GdkEventExpose *event)
 {
-  GtkBin *bin;
-  GdkEventExpose child_event;
-
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_MENU_ITEM (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
@@ -533,17 +530,8 @@ gtk_menu_item_expose (GtkWidget      *wi
   if (GTK_WIDGET_DRAWABLE (widget))
     {
       gtk_menu_item_paint (widget, &event->area);
-
-      bin = GTK_BIN (widget);
-
-      if (bin->child)
-        {
-          child_event = *event;

-          if (GTK_WIDGET_NO_WINDOW (bin->child) &&
-              gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-            gtk_widget_event (bin->child, (GdkEvent*) &child_event);
-        }
+      (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
     }

   return FALSE;
Index: gtk/gtknotebook.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtknotebook.c,v
retrieving revision 1.81
diff -u -p -r1.81 gtknotebook.c
--- gtk/gtknotebook.c	2001/02/28 19:07:45	1.81
+++ gtk/gtknotebook.c	2001/03/07 13:59:31
@@ -958,7 +958,6 @@ gtk_notebook_expose (GtkWidget      *wid
 		     GdkEventExpose *event)
 {
   GtkNotebook *notebook;
-  GdkEventExpose child_event;
   GdkRectangle child_area;

   g_return_val_if_fail (widget != NULL, FALSE);
@@ -978,12 +977,11 @@ gtk_notebook_expose (GtkWidget      *wid
 	    gtk_notebook_draw_focus (widget);
 	}

-      child_event = *event;
-      if (notebook->cur_page &&
-	  GTK_WIDGET_NO_WINDOW (notebook->cur_page->child) &&
-	  gtk_widget_intersect (notebook->cur_page->child, &event->area,
-				&child_event.area))
-	gtk_widget_event (notebook->cur_page->child, (GdkEvent*) &child_event);
+
+      if (notebook->cur_page)
+	gtk_container_propagate_expose (GTK_CONTAINER (notebook),
+					notebook->cur_page->child,
+					event);
     }

   return FALSE;
@@ -2350,12 +2348,14 @@ gtk_notebook_draw_tab (GtkNotebook     *

           expose_event.window = page->tab_label->window;
           expose_event.area = child_area;
+          expose_event.region = gdk_region_rectangle (&child_area);
           expose_event.send_event = TRUE;
           expose_event.type = GDK_EXPOSE;
           expose_event.count = 0;

-          gtk_widget_event (page->tab_label,
-                            (GdkEvent*)&expose_event);
+          gtk_widget_send_expose (page->tab_label, (GdkEvent *)&expose_event);
+
+	  gdk_region_destroy (expose_event.region);
         }
     }
 }
Index: gtk/gtkoptionmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkoptionmenu.c,v
retrieving revision 1.37
diff -u -p -r1.37 gtkoptionmenu.c
--- gtk/gtkoptionmenu.c	2001/02/03 01:09:40	1.37
+++ gtk/gtkoptionmenu.c	2001/03/07 13:59:31
@@ -430,10 +430,6 @@ static gint
 gtk_option_menu_expose (GtkWidget      *widget,
 			GdkEventExpose *event)
 {
-  GtkWidget *child;
-  GdkEventExpose child_event;
-  gint remove_child;
-
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_OPTION_MENU (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
@@ -477,13 +473,9 @@ gtk_option_menu_expose (GtkWidget      *
       if (remove_child)
 	gtk_option_menu_remove_contents (GTK_OPTION_MENU (widget));
 #else
-      remove_child = FALSE;
-      child = GTK_BIN (widget)->child;
-      child_event = *event;
-      if (child && GTK_WIDGET_NO_WINDOW (child) &&
-	  gtk_widget_intersect (child, &event->area, &child_event.area))
-	gtk_widget_event (child, (GdkEvent*) &child_event);
-
+      gtk_container_propagate_expose (GTK_CONTAINER (widget),
+				      GTK_BIN (widget)->child,
+				      event);
 #endif /* 0 */
     }

Index: gtk/gtkpacker.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkpacker.c,v
retrieving revision 1.17
diff -u -p -r1.17 gtkpacker.c
--- gtk/gtkpacker.c	2000/12/13 01:34:40	1.17
+++ gtk/gtkpacker.c	2001/03/07 13:59:32
@@ -127,8 +127,6 @@ static void gtk_packer_class_init    (Gt
 static void gtk_packer_init          (GtkPacker        *packer);
 static void gtk_packer_map           (GtkWidget        *widget);
 static void gtk_packer_unmap         (GtkWidget        *widget);
-static gint gtk_packer_expose        (GtkWidget        *widget,
-                                      GdkEventExpose   *event);
 static void gtk_packer_size_request  (GtkWidget      *widget,
                                       GtkRequisition *requisition);
 static void gtk_packer_size_allocate (GtkWidget      *widget,
@@ -222,7 +220,6 @@ gtk_packer_class_init (GtkPackerClass *k

   widget_class->map = gtk_packer_map;
   widget_class->unmap = gtk_packer_unmap;
-  widget_class->expose_event = gtk_packer_expose;

   widget_class->size_request = gtk_packer_size_request;
   widget_class->size_allocate = gtk_packer_size_allocate;
@@ -891,40 +888,6 @@ gtk_packer_unmap (GtkWidget *widget)
 	  GTK_WIDGET_MAPPED (child->widget))
 	gtk_widget_unmap (child->widget);
     }
-}
-
-static gint
-gtk_packer_expose (GtkWidget      *widget,
-		   GdkEventExpose *event)
-{
-  GtkPacker *packer;
-  GtkPackerChild *child;
-  GdkEventExpose child_event;
-  GList *children;
-
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_PACKER (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
-    {
-      packer = GTK_PACKER (widget);
-
-      child_event = *event;
-
-      children = g_list_first(packer->children);
-      while (children)
-	{
-	  child = children->data;
-	  children = g_list_next(children);
-
-	  if (GTK_WIDGET_NO_WINDOW (child->widget) &&
-	      gtk_widget_intersect (child->widget, &event->area, &child_event.area))
-	    gtk_widget_event (child->widget, (GdkEvent*) &child_event);
-	}
-    }
-
-  return FALSE;
 }

 static void
Index: gtk/gtkpaned.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkpaned.c,v
retrieving revision 1.31
diff -u -p -r1.31 gtkpaned.c
--- gtk/gtkpaned.c	2001/02/03 01:09:40	1.31
+++ gtk/gtkpaned.c	2001/03/07 13:59:32
@@ -302,7 +302,6 @@ gtk_paned_expose (GtkWidget      *widget
 		  GdkEventExpose *event)
 {
   GtkPaned *paned;
-  GdkEventExpose child_event;

   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_PANED (widget), FALSE);
@@ -313,19 +312,7 @@ gtk_paned_expose (GtkWidget      *widget
       paned = GTK_PANED (widget);

       if (event->window != paned->handle)
-	{
-	  child_event = *event;
-
-	  if (paned->child1 &&
-	      GTK_WIDGET_NO_WINDOW (paned->child1) &&
-	      gtk_widget_intersect (paned->child1, &event->area, &child_event.area))
-	    gtk_widget_event (paned->child1, (GdkEvent *) &child_event);
-
-	  if (paned->child2 &&
-	      GTK_WIDGET_NO_WINDOW (paned->child2) &&
-	      gtk_widget_intersect (paned->child2, &event->area, &child_event.area))
-	    gtk_widget_event (paned->child2, (GdkEvent *) &child_event);
-	}
+	(* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
     }

   return FALSE;
Index: gtk/gtkscrolledwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkscrolledwindow.c,v
retrieving revision 1.46
diff -u -p -r1.46 gtkscrolledwindow.c
--- gtk/gtkscrolledwindow.c	2001/02/03 01:09:40	1.46
+++ gtk/gtkscrolledwindow.c	2001/03/07 13:59:32
@@ -598,21 +598,11 @@ static gint
 gtk_scrolled_window_expose (GtkWidget      *widget,
 			    GdkEventExpose *event)
 {
-  GtkBin *bin = GTK_BIN (widget);
-  GdkEventExpose child_event;
-
   if (GTK_WIDGET_DRAWABLE (widget))
     {
       gtk_scrolled_window_paint (widget, &event->area);
-
-      if (bin->child && GTK_WIDGET_VISIBLE (bin->child) && GTK_WIDGET_NO_WINDOW (bin->child))
-	{
-	  child_event = *event;
-	  if (gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	    gtk_widget_event (bin->child, (GdkEvent*) &child_event);
-	}

-      /* We rely on our knowledge that scrollbars are !NO_WINDOW widgets */
+      (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
     }

   return FALSE;
Index: gtk/gtktable.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktable.c,v
retrieving revision 1.40
diff -u -p -r1.40 gtktable.c
--- gtk/gtktable.c	2000/12/04 01:15:37	1.40
+++ gtk/gtktable.c	2001/03/07 13:59:32
@@ -55,8 +55,6 @@ static void gtk_table_init	    (GtkTable
 static void gtk_table_finalize	    (GObject	    *object);
 static void gtk_table_map	    (GtkWidget	    *widget);
 static void gtk_table_unmap	    (GtkWidget	    *widget);
-static gint gtk_table_expose	    (GtkWidget	    *widget,
-				     GdkEventExpose *event);
 static void gtk_table_size_request  (GtkWidget	    *widget,
 				     GtkRequisition *requisition);
 static void gtk_table_size_allocate (GtkWidget	    *widget,
@@ -145,7 +143,6 @@ gtk_table_class_init (GtkTableClass *cla

   widget_class->map = gtk_table_map;
   widget_class->unmap = gtk_table_unmap;
-  widget_class->expose_event = gtk_table_expose;
   widget_class->size_request = gtk_table_size_request;
   widget_class->size_allocate = gtk_table_size_allocate;

@@ -713,39 +710,6 @@ gtk_table_unmap (GtkWidget *widget)
 	  GTK_WIDGET_MAPPED (child->widget))
 	gtk_widget_unmap (child->widget);
     }
-}
-
-static gint
-gtk_table_expose (GtkWidget	 *widget,
-		  GdkEventExpose *event)
-{
-  GtkTable *table;
-  GtkTableChild *child;
-  GList *children;
-  GdkEventExpose child_event;
-
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_TABLE (widget), FALSE);
-
-  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
-    {
-      table = GTK_TABLE (widget);
-
-      child_event = *event;
-
-      children = table->children;
-      while (children)
-	{
-	  child = children->data;
-	  children = children->next;
-
-	  if (GTK_WIDGET_NO_WINDOW (child->widget) &&
-	      gtk_widget_intersect (child->widget, &event->area, &child_event.area))
-	    gtk_widget_event (child->widget, (GdkEvent*) &child_event);
-	}
-    }
-
-  return FALSE;
 }

 static void
Index: gtk/gtktogglebutton.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktogglebutton.c,v
retrieving revision 1.32
diff -u -p -r1.32 gtktogglebutton.c
--- gtk/gtktogglebutton.c	2001/02/19 22:25:30	1.32
+++ gtk/gtktogglebutton.c	2001/03/07 13:59:32
@@ -415,7 +415,7 @@ gtk_toggle_button_paint (GtkWidget    *w
         shadow_type = GTK_SHADOW_IN;
       else
 	shadow_type = GTK_SHADOW_OUT;
-
+
       if (button->relief != GTK_RELIEF_NONE ||
 	  (GTK_WIDGET_STATE(widget) != GTK_STATE_NORMAL &&
 	   GTK_WIDGET_STATE(widget) != GTK_STATE_INSENSITIVE))
@@ -451,19 +451,13 @@ static gint
 gtk_toggle_button_expose (GtkWidget      *widget,
 			  GdkEventExpose *event)
 {
-  GtkBin *bin;
-  GdkEventExpose child_event;
-
   if (GTK_WIDGET_DRAWABLE (widget))
     {
-      bin = GTK_BIN (widget);
-
       gtk_toggle_button_paint (widget, &event->area);
-
-      child_event = *event;
-      if (bin->child && GTK_WIDGET_NO_WINDOW (bin->child) &&
-	  gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+
+      gtk_container_propagate_expose (GTK_CONTAINER (widget),
+				      GTK_BIN (widget)->child,
+				      event);
     }

   return TRUE;
Index: gtk/gtktoolbar.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktoolbar.c,v
retrieving revision 1.45
diff -u -p -r1.45 gtktoolbar.c
--- gtk/gtktoolbar.c	2000/12/13 01:34:40	1.45
+++ gtk/gtktoolbar.c	2001/03/07 13:59:32
@@ -407,8 +413,7 @@ gtk_toolbar_expose (GtkWidget      *widg
   GtkToolbar *toolbar;
   GList *children;
   GtkToolbarChild *child;
-  GdkEventExpose child_event;
-
+
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_TOOLBAR (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
@@ -417,8 +422,6 @@ gtk_toolbar_expose (GtkWidget      *widg
     {
       toolbar = GTK_TOOLBAR (widget);

-      child_event = *event;
-
       for (children = toolbar->children; children; children = children->next)
 	{
 	  child = children->data;
@@ -428,9 +431,10 @@ gtk_toolbar_expose (GtkWidget      *widg
 	      if (toolbar->space_style == GTK_TOOLBAR_SPACE_LINE)
 		gtk_toolbar_paint_space_line (widget, &event->area, child);
 	    }
-	  else if (GTK_WIDGET_NO_WINDOW (child->widget)
-		   && gtk_widget_intersect (child->widget, &event->area, &child_event.area))
-	    gtk_widget_event (child->widget, (GdkEvent *) &child_event);
+	  else
+	    gtk_container_propagate_expose (GTK_CONTAINER (widget),
+					    child->widget,
+					    event);
 	}
     }

Index: gtk/gtktree.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktree.c,v
retrieving revision 1.42
diff -u -p -r1.42 gtktree.c
--- gtk/gtktree.c	2001/03/02 17:06:14	1.42
+++ gtk/gtktree.c	2001/03/07 13:59:32
@@ -47,8 +47,6 @@ static void gtk_tree_parent_set      (Gt
 				      GtkWidget      *previous_parent);
 static void gtk_tree_unmap           (GtkWidget      *widget);
 static void gtk_tree_realize         (GtkWidget      *widget);
-static gint gtk_tree_expose          (GtkWidget      *widget,
-				      GdkEventExpose *event);
 static gint gtk_tree_motion_notify   (GtkWidget      *widget,
 				      GdkEventMotion *event);
 static gint gtk_tree_button_press    (GtkWidget      *widget,
@@ -121,7 +119,6 @@ gtk_tree_class_init (GtkTreeClass *class
   widget_class->unmap = gtk_tree_unmap;
   widget_class->parent_set = gtk_tree_parent_set;
   widget_class->realize = gtk_tree_realize;
-  widget_class->expose_event = gtk_tree_expose;
   widget_class->motion_notify_event = gtk_tree_motion_notify;
   widget_class->button_press_event = gtk_tree_button_press;
   widget_class->button_release_event = gtk_tree_button_release;
@@ -440,42 +437,6 @@ gtk_tree_destroy (GtkObject *object)

   if (GTK_OBJECT_CLASS (parent_class)->destroy)
     (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-static gint
-gtk_tree_expose (GtkWidget      *widget,
-		 GdkEventExpose *event)
-{
-  GtkTree *tree;
-  GtkWidget *child;
-  GdkEventExpose child_event;
-  GList *children;
-
-
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_TREE (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
-  if (GTK_WIDGET_DRAWABLE (widget))
-    {
-      tree = GTK_TREE (widget);
-
-      child_event = *event;
-
-      children = tree->children;
-      while (children)
-	{
-	  child = children->data;
-	  children = children->next;
-
-	  if (GTK_WIDGET_NO_WINDOW (child) &&
-	      gtk_widget_intersect (child, &event->area, &child_event.area))
-	    gtk_widget_event (child, (GdkEvent*) &child_event);
-	}
-    }
-
-
-  return FALSE;
 }

 static void
Index: gtk/gtktreeitem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktreeitem.c,v
retrieving revision 1.46
diff -u -p -r1.46 gtktreeitem.c
--- gtk/gtktreeitem.c	2001/03/02 17:06:14	1.46
+++ gtk/gtktreeitem.c	2001/03/07 13:59:33
@@ -718,23 +718,15 @@ static gint
 gtk_tree_item_expose (GtkWidget      *widget,
 		      GdkEventExpose *event)
 {
-  GdkEventExpose child_event;
-  GtkBin *bin;
-
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_TREE_ITEM (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);

   if (GTK_WIDGET_DRAWABLE (widget))
     {
-      bin = GTK_BIN (widget);
-
       gtk_tree_item_paint (widget, &event->area);

-      child_event = *event;
-      if (bin->child && GTK_WIDGET_NO_WINDOW (bin->child) &&
-	  gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+      (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
    }

   return FALSE;
Index: gtk/gtkviewport.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkviewport.c,v
retrieving revision 1.42
diff -u -p -r1.42 gtkviewport.c
--- gtk/gtkviewport.c	2000/12/04 01:15:37	1.42
+++ gtk/gtkviewport.c	2001/03/07 13:59:33
@@ -562,10 +562,7 @@ gtk_viewport_expose (GtkWidget      *wid
 			     &event->area, widget, "viewportbin",
 			     0, 0, -1, -1);

-	  if ((bin->child != NULL) &&
-	      GTK_WIDGET_NO_WINDOW (bin->child) &&
-	      gtk_widget_intersect (bin->child, &event->area, &child_event.area))
-	    gtk_widget_event (bin->child, (GdkEvent*) &child_event);
+	  (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
 	}







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