Include GdkRegion in expose events - bug 51288 [PATCH]



Here is a patch that implements a GdkExposeEvent.region field, in addition
to the old area field. This lets app authors make more intelligent expose
handlers in case they draw something that takes a lot of time.

I think this is a great idea.

/ Alex

Index: docs/Changes-2.0.txt
===================================================================
RCS file: /cvs/gnome/gtk+/docs/Changes-2.0.txt,v
retrieving revision 1.11
diff -u -p -r1.11 Changes-2.0.txt
--- docs/Changes-2.0.txt	2001/02/09 00:40:45	1.11
+++ docs/Changes-2.0.txt	2001/02/28 11:57:07
@@ -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/02/28 11:57:07
@@ -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/02/28 11:57:07
@@ -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/02/28 11:57:07
@@ -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.38
diff -u -p -r1.38 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c	2001/02/27 20:39:59	1.38
+++ gdk/x11/gdkevents-x11.c	2001/02/28 11:57:08
@@ -954,6 +954,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;

@@ -988,6 +989,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/gtkmain.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.c,v
retrieving revision 1.151
diff -u -p -r1.151 gtkmain.c
--- gtk/gtkmain.c	2001/02/27 20:40:05	1.151
+++ gtk/gtkmain.c	2001/02/28 11:57:10
@@ -868,6 +868,11 @@ gtk_main_do_event (GdkEvent *event)
       break;

     case GDK_EXPOSE:
+      /* Make sure we catch any synthetic expose event that
+       * has no region set. */
+      if (event->expose.region == NULL)
+	g_warning ("Expose event with NULL region detected");
+
       if (event->any.window && GTK_WIDGET_DOUBLE_BUFFERED (event_widget))
 	gdk_window_begin_paint_rect (event->any.window, &event->expose.area);

Index: gtk/gtknotebook.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtknotebook.c,v
retrieving revision 1.80
diff -u -p -r1.80 gtknotebook.c
--- gtk/gtknotebook.c	2001/02/02 17:53:29	1.80
+++ gtk/gtknotebook.c	2001/02/28 11:57:11
@@ -2370,6 +2370,7 @@ 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;





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