Re: Avoiding flickering



Ivan Popivanov wrote:

> Hi,
>
> It seems to me that you totally missed my point. I'll try to be more
> precise. Imagine a situation (the same as in last letter) that you have
> a parent window and a child window. The child window occupies the whole
> parent area, in other words the parent is not visible at all (toplevel
> widget and for example a clist inside it). Whats the way X server does
> the redraw? First the parent and after that the child. When the parent
> got redrawn it WILL overwrite the child contents. This has nothing to do
> with gravity! On slow systems there will always be flickering! But there
> is only one exception - namely, the parent has no background (pixel or
> pixmap). So, setting no default background, we can achieve no X server
> redrawing. Even if you write a small application using a toplevel window
> with no default background, there WILL be a flickering in current
> release of gtk. Why - simply because of the BAD child redrawing. Now,
> maybe the reason for clearing of the whole child area is window gravity,
> and maybe it is impossible to the clearing and redrawing in one pass (I
> wouldn't believe this, because in my example with clist, it (the clist)
> draws in the whole its (child window) area, so there is no need to clear
> it explicitly, but that's what the code in clist really does!), but even
> in that case, if you use double buffering, you should only buffer the
> child drawing! That already means sparing a memory of about 1 Mb! If you
> implement only a double buffering, without modifying the parts I've
> already mentioned, everyone will use double buffering for all windows to
> avoid flickering - another drawback in gtk is the number of windows it
> uses, but more on this later - so I'll let you calculate the expenses
> speaking in Mbs of RAM.
> Don't tell it is impossible to do because of ... (mainly gravity).
> Windows does this and there is no reason to believe that X server
> imposes restrictions in that sense.
>
> You may ask, why I am not providing an example. I'll provide one as soon
> as possible. I actually have coded the example with parent and clist for
> a child, but I am currently changing the code of clist because of the
> horrible redrawing there - refill the entire area as many times as possible.
>
> I have mentioned the problem (in my opinion, of course) with the number
> of windows in gtk. For such simple things (as buttons in clist title
> bar, buttons in toolbar, menu items and so on) gtk uses different windows.
> I'd like to remind you, that in Microsoft Word 2 all of the buttons in
> toolbar were actually windows. Since Microsoft Word 6.0 all buttons in the
> toolbar share only one window - the toolbar's one. That is the winning strategy -
> create usable components, without overloading the system. I am sure, if gtk
> minimizes the number of windows it uses, there will be a great
> increase in performances. In that case, your double buffering (if you
> are still sure we need it :-) will not be so expensive!
>
> Maybe this letter is unrelated to this mailing list. Maybe it is too
> long and proposes a tons of dirty work in gtk developing (nobody likes
> that stuff:-). If this is the case - just let me know and I'll stop
> sending such kind of letters. I am just trying to help. In my opinion,
> gtk is the only graphical API, that can evolve in the UNIX equivalent to
> Windows GUI - both in features and performances.
>
>         Ivan
>
> --
> Sent through Global Message Exchange - http://www.gmx.net
>
> --
>          To unsubscribe: mail gtk-devel-list-request@redhat.com with
>                        "unsubscribe" as the Subject.

I agree with you.
However, I don't know what this gravity bit is. Could anyone explain it to me so I
know I am not saying fool things?
Anyway, I agree with you in that many of the flickering of Gtk is due to a complete
redraw of the background of a window for then repainting the widgets over the
cleared window. This is annoying,  specially when resizing a window ( in opaque mode
obviously).
Although I don't think this will actually resolve all of the flickering problems, it
could reduce a lot of them, so many applications could run quite smoothly without
needing double-buffered support (or even drawing the widgets over a pixmap).
Something has to be buggy in the way GTK draws widgets, because I think QT doesn't
use strange things like double-buffer (except perhaps back-storing widgets in a
pixmap for things like the panel on the desktop) and it runs quite smoothly
(sometimes even better that Windows, that theoretically has more polished
video-drivers that X has). Have you tried to scroll continuously a text in Kedit? It
actually runs very smoothly. Is it possible that widgets in GTK are redrawing
themselves more times than needed?
If double-buffer is going to increase a lot the use of memory, then by all means
GTK should try to speed things up without using it.

Another idea to avoid flickering (kick my bottom hardly if I'm completely wrong):
See attached example, and when running it, try opaque maximizing it.
The example simply consist of a table with 30x30 buttons attached inside it.
When the window has totally maximized and as widget redrawing if so slow, the table
still try to redraw itself a few times.
What is happening in the resize? I don't know if I'm right, so please correct me:
The window receives the resize request, so it clears itself with the default bg
color and them communicate the table (its child) of the resize. Them the table
communicate the resize its children (the buttons). Then the children based on the
size requested by its parent (the table), get its correct size, and communicate it
to its parent the table. Then the table initiates the redrawing of the children with
the correct size.
But, what happens when the table receives another resize request while it is still
redrawing its children (as asking them for the resize). I suspect from the execution
of the attached example, that until the table gets completely redrawn, it cannot
process the next resize event.
As Ivan noted, not clearing the window with the bg color could greatly reduce the
sensation of flickering. But would it help too if the table (a container in the end)
could stop a resize request in course if it receives another one?. If containers
could work that way, I think that responsiveness to user will improve a lot (at
least in resize or redrawing requests, that are where GTK flickers more). I think
Windows uses that approach in the some tree widgets. If the tree hasn't been
completely redrawn but the user scrolls it, them the redrawing stops and restarts.
Would this be difficult to implement in GTK?
#include <gtk/gtk.h>

#define MAX_BUTTON	20

typedef struct
{
  gint x;
  gint y;
} par;

void click(GtkWidget *emisor,par *datos)
{
  g_print("%dx%d\n",datos->x,datos->y);
}

int main(int argc,char **argv)
{
  GtkWidget *ventana;
  GtkWidget *boton;
  GtkWidget *table;


  gtk_init(&argc,&argv);

  ventana=gtk_window_new(GTK_WINDOW_TOPLEVEL);

  gtk_signal_connect(GTK_OBJECT(ventana),"delete_event",GTK_SIGNAL_FUNC(gtk_main_quit),NULL);

  table=gtk_table_new(MAX_BUTTON,MAX_BUTTON,TRUE);

  {
    int i,j;
    char nombre[80];
    par mi_par[MAX_BUTTON][MAX_BUTTON];

    for (j=0; j<MAX_BUTTON; j++)
      for (i=0; i<MAX_BUTTON; i++)
      {
        sprintf(nombre,"%dx%d",i,j);
        boton=gtk_button_new_with_label(nombre);
        mi_par[i][j].x=i;
        mi_par[i][j].y=j;
        gtk_signal_connect(GTK_OBJECT(boton),"clicked",GTK_SIGNAL_FUNC(click),(gpointer) &mi_par[i][j]);
        gtk_table_attach_defaults(GTK_TABLE(table),boton,i,i+1,j,j+1);
      }
  }

  gtk_container_add(GTK_CONTAINER(ventana),table);
  gtk_widget_show_all(GTK_WIDGET(ventana));

  gtk_main();
}


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