Re: Include GdkRegion in expose events - bug 51288 [PATCH]



Alexander Larsson <alla lysator liu se> writes:

> On 28 Feb 2001, Owen Taylor wrote:
> 
> > I think if we are going to break synthetic exposes, then we
> > should break them in a clear, reliable way and tell people
> > need to
> >
> > So, I'd propose make calling gtk_widget_event() with an
> > event of type GDK_EXPOSE illegal and if that is done
> > print out a informative message like:
> >
> >  "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()."
> >
> > With that change (and fixing gtknotebook.c to simple invalidate_rect
> > and not process_updates()), it should be fine to commit.
> 
> This wasn't as easy as it looked.
> 
> The problem is that all container expose handlers must generate synthetic
> expose events for all NO_WINDOW children. This means gtk_widget_event()
> is called with GDK_EXPOSE events.
> 
> This also means that code in all gtk+ container widgets like this:
>  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);
> 
> must be changed to something like this:
>  if (GTK_WIDGET_DRAWABLE (child->widget) &&
>      GTK_WIDGET_NO_WINDOW (child->widget) &&
>      gtk_widget_region_intersect (child->widget, event->region,
>                                   &child_event.region, &child_event.area))
>         {
>  	  gtk_widget_event (child->widget, (GdkEvent*) &child_event);
>           gdk_region_destroy (child_event.region);
>         }

This is, in fact rather nasty. We have:

 - We can't simply let people ignore the existence of the region field
   when generating synthetic exposes and calling gtk_widget_event()

 - gtk_widget_event() is in fact used pretty frequently, so we will
   break significant amounts of code this way.

The lucky thing is that the number of custom containers is probably
a fair bit smaller than the number of custom widgets. And I
think we can get some nice code cleanups here for container
writers. (If at the expense of a small slowdown.)

> This is a source incompatible change that needs changes in all container
> widgets. If you forget to change this in a widget, things will "kinda"
> work anyway. This can be both good (don't break source compat badly) and
> bad (hard to detect bugs).

I don't think "kind of works" is acceptable.

> If we want a clean break here we will probably need a *public*
> gtk_widget_expose_event () call, documenting when this function is
> supposed to be used. Then we make expose events in gtk_widget_event()
> invalid (g_warning + return). Do you want me do this?

Let's make a public-but-we-discourage-you function:

 gtk_widet_send_expose()

Used by gtk_main_do_event() and then a nice wrapper:

 gtk_container_propagate_expose (GtkContainer   *container,
                                 GtkWidget      *child,
                                 GdkEventExpose *event);

This function can take care of:

 - Checking if the child is drawable and NO_WINDOW
 - Checking if the region intersects the child's allocation
 - Translating the coordinates from event->window to child->window

In fact, we can even provide a default GtkContainer::expose 
method that containers can either use or chain to that will do for
almost all cases. (All cases? I can't really think of an
exception.)

Regards,
                                        Owen




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