Re: Forcing expose before onscreen mapping



On 10/11/06, Matt Hoosier <mwhoosier gmail com> wrote:
When a GtkWindow first appears after gtk_widget_show() is called on
it, there is a moment during which it isn't yet rendered, and the X11
window's space is filled with all white background.

I understand that this is an artifact of the normal allocate -> map ->
expose progression. Is there a way to force that the window already
has a rendered copy of itself available for the first refresh cycle,
so that applications don't flicker to/from white at startup?

As I recall, windows can not be drawn on until they're mapped. But
once they're mapped, they're also visible, usually.

Hack that comes to mind, it may or may not help, could be to render
the window to an offscreen pixmap prior to showing it. Currently it's
a hack, there's better offscreen support in bugzilla, I think.
Possibly something like the following:

(On second thought gtk_widget_realize (window);
gdk_window_set_back_pixmap (window->window, NULL, FALSE); alone might
work, if I'm understanding the API docs correctly. Depends on window
manager.)

 gtk_window_iconify (window);
 gtk_widget_show (window);

 /* now the widgets should be in "visible enough" state, namely
mapped, to be drawn correctly but hopefully not visible to the user */

 /* render the widgets to an offsceen pixmap and set it as background pixmap */
 pixmap = gdk_pixmap_new (..., window->allocation.width,
window->allocation.height, ...);
 fake_expose_event (window, pixmap);
 gdk_window_set_back_pixmap (window->window, pixmap, FALSE);
 g_object_unref (pixmap);

 /* show the window and let it be drawn normally */
 gtk_window_deiconify (window);
 /* the following should probably be done after expose event */
 gdk_window_set_back_pixmap (window->window, NULL, FALSE);

/* found from gnome-control-center */
static void
fake_expose_event (GtkWidget *widget, GdkPixmap *pixmap)
{
       GdkWindow      *tmp_window;
       GdkEventExpose  event;

       tmp_window = widget->window;
       widget->window = pixmap;

       event.type = GDK_EXPOSE;
       event.window = widget->window;
       event.send_event = FALSE;
       event.area = widget->allocation;
       event.region = NULL;
       event.count = 0;

       gtk_widget_send_expose (widget, (GdkEvent *) &event);

       widget->window = tmp_window;
}

--
Tommi Komulainen                                 tommi komulainen iki fi



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