index

How I fight against flickering in X windows

subtitle: how i made a gift to my eyes

By "Flickering" i mean filling an area on the screen/monitor uselessly with a different color, before drawing the useful content.

Table of Contents:

patches:

You can see summary of the method, to patch your application!

Billy Biggs (vektor) contacted me and pointed me at anti-flicker efforts in Eclipse( A visual comparison of Eclipse and Firefox's menu redrawing) and gtk+ menus(Eclipse on SWT/GTK+ Performance Notes). He has pages dedicated to the problem:
http://scanline.ca:

" 1 Jun 2005: Goodbye flash "

points at an excellent article by Dave Marsh, which explains why I see bold letters when moving windows on an LCD monitor.

How it started --

When working with graphical applications, I noticed, that in certain situations they flicker: fill an area uselessly with a different color, before drawing the intended (useful) content. Example: try to run xmag, then enlarge the window (the zoom).

Now that I have so my windows flicker-free, i appreciate I can go on reading, while resizing.

the trivial case

In May 2005 i played with window resizing code in Sawfish WM, and learnt about the importance of Gravity and backgroundPixmap. I noted, that Mozilla browser used "None" backgroundPixmap to avoid such flickering. (I noted it just by seeing its behaviour, not by looking at the sources!)

For explanation of what None means for backgroundPixmap, I quote (tha last paragraph) from X11R6.4 Xlib Reference Manual

when no valid contents are available for regions of a window and either the regions are visible or the server is maintaining backing store, the server automatically tiles the regions with the window's background unless the window has a background of none. if the background is none, the previous screen contents from other windows of the same depth as the window are simply left in place as long as the contents come

in other words, when I switch to a new window (the window is brought above the previously active window), the server does not draw any color/pattern in the newly exposed parts of the new (raised) active window.

If such a step was made, a flickering would occur, unless the window was trivial: just that pattern. there are some programs, which set the pattern to useful data, for example gv, or (xloadimage); this is a nice approach, and i have nothing to add to it.

notes:

in october, i realized (I woke with the idea in my head), that windows full of image data don't need any background: background is not visible, it can only cause flickering (when a new area is exposed): the program does not rely on server filling the exposed areas automatically. If one deactivates this automatic fill, no wrong artifacts will arise!

So it was a trivial change to assure, that backgroundpixmap of such windows be set to none. And in fact, the program xv (still considered a "best tool for some sort of light image editing work") is now much more pleasant (with 3 line modification).

xv links:

After this discovery, i started to look around for applications of this easy-to-do fix. the application i use a lot, and which causes a lot of flickering is xterm.

flicker free X terminal emulator


This year i looked at the code of EOG and saw the piecewise rendering. This may have influenced me to get the idea of paint the terminal window piecewise cell by cell.

When i resize, or expose xterm window, i notice flickering. To make hacking simple, i installed rxvt. it is derived from xvt, which avoids the use of the x toolkit.

(rxvt technical reference)

Researching for ways to optimize the output (text screen redrawing), i learnt:

quote from 0.6.3. drawing image text characters

XDdrawImageString:

some applications, in particular terminal emulators, need to print image text in which both the foreground and background bits of each character are painted. this prevents annoying flicker on many displays.

to help you understand it (how it prevents flickering), think: if there was no such call, to print text,

one would have to fill the area with background, and then use XDrawString to produce the foreground. With the special call, it all happens piecewise (the flickering occurs on 1 line only; still noticable).

But then with this call available, the terminals SHOULD NOT set the background-pixmap ! ...And in fact rxvt did set background(-pixmap) to black, so when exposing its windows, I did notice the flickering.

With a little modification I avoid it: I set the background pixmap to None, and changed all XClearArea calls to (explicit) XFillRectangle with the background color. (The hypothetical window background color is now the foreground color of the Fill)

What remains to be done, is flicker-free window resizing!

how to remove flickering on window resizing

If i resize a top window, and its subwindows will be resized as well and change its contents, should have window gravity as StaticGravity. The VT window of rxvt is such, in case of full screen applications: Think of a centered dialog.

Or, another situation where StaticGravity is necessary: Imagine you have a small terminal window with just ordinary shell (bash,zsh...), and enlarge it. When the contents of the VT (the actual text) will surely change by inserting some lines at the beginning (as is the case when there is scroll back/history) North*Gravity is useless. Static is the only acceptable.

idea

To make rxvt work w/o background (implicit filling), I had to make a boolean attached to every cell (position): is the contents (of the cell's rectangle on the screen) to be redrawn?

Then, when we redraw modifications, if the bit is set, the cell is redrawn, regardless if the application didn't change the text at that position.

modifying terminal applications to avoid flickering

The fact that the terminal does not flicker on expose, or even on window resize, does not mean, that applications cannot cause another type of flickering: If they clean the screen (and the terminal fills the area with its default background color), and then draws a big area with the foreground (hi contrasted) color, you can notice flickering.

I introduced 2 escape/control sequences so that such applications can me modified easily to avoid such flickering:

And another pair:

note: I should verify (& find bettter alternative) that these are backward compatible!

I have introduced other Escape sequences in my rxvt patch, i document them in another page

Emacs

Again, initial hacking seems easier with no toolkit activated (plain xlib). And it uses glyph matrix (current & desired to see what changed) .... so it was not difficult.

Get the CVS sources, apply my patch, and compile a version which does not use hi-level toolkits. My experiments have indeed been limited to Xlib only. I have to prepare a bit before addressing Xt and Gtk.

CFLAGS="-mtune=athlon-xp -march=athlon-xp -O2 -pipe -g -ggdb3" ./configure --with-png --with-jpeg --without-xim --with-x-toolkit=no --without-gtk; nice -n 15 make bootstrap

-O3 gives:

Loading font-lock (source)...
Wrong type argument: listp, [-134870392 [-134870392 #0 make[2]: *** [bootstrap-emacs] Segmentation fault (core dumped)

announcement email --- i'm shocked, nobody has replied, despite 14 downloads of the patch! after a month someone replied (gmane), but I think I'm on my own.

GV

yes, the postscript viewer. Browsing through critique of X protocol I noticed some flickering. To verify, I produced a PS file w/ 2 identical pages
psselect  -p1,1  protocol.pdf.ps   test.ps

Then tried to change pages in test.ps inside GV. Then it was obvious. I asked jemarch on IRC, and he talked about new versions (gtk+-2!), but I had to look at the C sources---it's Xt based!

Given the occasion, I tuned the Eye-Guide line: wider, and longer-staying (2 seconds). It uses the XOR trick.

The solution to my problem was very easy: I found it by chance! the --nopixmap option. It seems, that on slow connections this does flicker. I'll have to review it.

GTK+

I think, that gtk+ is trivial to convert to use background None. I'm testing it currently, it's a couple of lines changes in gtk+-2.8.8/gdk/x11/gdkwindow-x11.c and it is correct in case of widgets which use double-buffering. EOG, gqview do not, and so you will see some artifacts.

related: Performance notes on background flickering and http://mail.gnome.org/archives/wm-spec-list/2002-December/msg00025.html

My Curiosity: My original comment, before verifying that indeed double buffered toolkit is trivial to convert to backtroun None: GtkImage and many other widgets should be converted to not use background.

A test case for seeing the unpleasant flicker is: tree-view with a solid color filled column: the column is not an X window, so when you expose it, it will be filled by the background (color) of the tree-view window, and only then overwritten w/ the color. I don't have this problem anymore!

read more

History:

Note: on October 22 2005 I exclaimed on IRC:

i've just realized a flaw in many programs w/ image output: they set the background pixelmap (different to None). While when a window is in foreground (focused) it's nice to have its pixmap, or maybe in general when resizing it, but when i change the stacking order, it's awful to see the white flash (in the exposed area), before the area is filled w/ the image. mozilla does the right thing, in this respect.

and now, on 30 Nov. (i.e. after 40 days of hacking) I have all running (non-gtk) apps flicker free (emacs, terminal ...). I can resize windows without the fear of flicker.
and on December 16 I started to have gtk+ flicker-free on all my gentoo boxes.

Future

Reactions, other's

negative

enberg    I've never noticed any flicker in emacs
not-twb  enberg: I concur.
mmc      enberg: then try to resize any emacs X window.
enbert   heh, I resize my Emacs window once every 3 years or so

not-twb  mmc: you probably are resizing with the mouse.
mmc      assuming your WM has alt-tab cycling.
not-twb  I use :resize +200 or :split 1/3.
mmc      not-twb: i resize w/ mouse or keyboard ... that's irrelevant.
not-twb: mmc: no it's not.
         mmc: if you resize with the mouse, many WMs will refresh every pixel moved.
          ...aewm does NOT do that, so you won't get any flickering if you use it.

twb    mmc: no one else believes in the Flicker!
twb    You're trying to sell a prosthesis to a health man.

positive

what does the competition do?

MS windows

I think that the default Image viewer (in windows XP) does use "background None": when i resize it quickly, i see the frame enclose parts (pixels) with the unerneath windows visible.

the media-player panel inside IE windows does flicker on resize. Terrible.