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.
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:
points at an excellent article by Dave Marsh, which explains why I see bold letters when moving windows on an LCD monitor.
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.
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.
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.
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!
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.
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.
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
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.
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.
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!
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.
I haven't seen the flickering since I'm rarely running remotely (well, cygwin would do this - it paints very slowly - I seem to recall that it doesn't implement shared memory operations). mmc: Let me know if you set about integrating the anti-flicker method. I'm interested, but will have to study it a little, to see. I downloaded the rxvt and elinks patches, will probably look at those this weekend.
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.
schmorp when an app clears the screen schmorp and then redraws it schmorp then this isn't flicker mmc i call that flicker. Paco-Paco yeah, the method it sounds like you're using, mmc, doesn't prevent that flicker .... schmorp it's extremely annoying with mozilla already, no need to add more nuisances schmorp setting the bg pixmap to None will just show garbage on screen until the window schmorp gets refreshed (which can be multiple seconds) Paco-Paco oh, I hate that schmorp users tend to be very confused by this behaviour in mozilal already Paco-Paco BIG TIMEyou can see the whole discussion
mmc raster: what would you think about converting programs to use background_pixmap None in order to remove flickering? raster: well, 2 edged blade: u remove flicker but add redraw "trails" raster: the greater the latency, the worse the trailsraster: personally i will take the trails over the flicker myself
raster: and i think its a very good thing and apps should do it raster: as much as possible (or toolkits) raster: it saves double-draw by the gpu/gfx chip anyway mmc i'm working on it http://maruska.dyndns.org/wiki/flicker raster: working on ancient sw there! raster: :) raster: it'd be better to change gtk/qt to do it
the media-player panel inside IE windows does flicker on resize. Terrible.