Let it snow!

New: xsnow shows the Moon! (ok, you need a compositing display manager)

Xsnow: what does it do?

Xsnow is an application that animates snowfall, Santa and some scenery on your desktop. It is NOT a kind of screen saver: snow is falling, Santa rides his sleigh with reindeer while you are using your system. Xsnow runs on most varieties of Linux, and probably on other Unix systems as well.


In 1984, my colleague Rick Jansen created an application for the Apple Macintosh computer, called, if I remember well: snow. This application animated snow on the desktop, including snowflakes, fallen snow and even Santa flying through the air.

Later on Rick acquired a real system, a Silicon Graphics workstation, and soon he produced a version of snow that could run in an X11 environment: xsnow, first released in 1993. This version shows fallen snow not only at the bottom if the desktop, but also on windows. (Maybe the Macintosh version did this also, difficult to verify now). More information, including links to other implementations, is available on Wikipedia. Rick is still working on snow for the Mac, the program is baptized iSnow. It appears that much eye candy has been added in due time. One could almost be temped to acquire an Apple system to run iSnow! And then, there is even a shareware version, winsnow, that runs on MS Windows.

It seems that xsnow was received well by the community, despite the fact that is was not released in the Public Domain :-(. When you look for xsnow on the WWW, you will find complaints that xsnow does not function well on modern desktops like Gnome and KDE. It seems that there was a solution for KDE, but I found that that solution does not works any more. In Debian, under non-free, xsnow is still offered (version 1.42), but it only works on 'simple' window managers like FVWM that use the root window to place the windows. When you start this version of xsnow, in general you see nothing, because it is snowing behind the desktop.

Towards Gnome xsnow

I waited some years for somebody to solve the snowing-but-not-visible issue, but alas, no solution was provided. So, after almost finishing my findent project, I decided to have a look, in November or December 2018. Before Christmas 2018, I had something running. I let Rick know, and he was very pleased, he said. I succeeded to polish xsnow further and was able to offer a dependable version months before Christmas 2019.


Xsnow has old roots and is adapting to new environments, visible in the code, which is a good thing for an application like xsnow. For example, there is no convention whatsoever for the naming of variables and functions. Something like 'windonfallensnow' can be spelled like: 'windonfallensnow', 'wind_on_fallen_snow', 'WindOnFallenSnow', WOFS and so on. The language used is C, (not C++ as would be the obvious choice now, however: see 'Technical issues' (no, not Python or Ruby: we really need some performance)), with many global variables, sometimes with not very helpful names. The choice whether a function and accompanying header files are placed is separate files or in xsnow.c, is based on the moment of the day, or the flipping of a coin. Xsnow-1.42 hardly used floating point arithmetic, xsnow-2.0 uses a mix of floating point and integer arithmetic, floating point gradually taking over. The documentation contains references to systems that are extinct for many years, but description of new flags has been noted to creep in. Xsnow's genes show traces of findent, and even of some Hitchhikers Guide. The genes for 'toon.h' are almost gone, there are at this moment better ways to find the window to snow in. The program became aware of the fact the Santa's sleigh is pulled by 8 reindeers: Dasher, Dancer, Prancer, Vixen, Comet, Cupid, Dunder and Blixem. Later on, Rudolf could be added. It seems that some of the pixmaps are evolving in that direction.


Since version 3.1.0, xsnow has, next to the 7 handcrafted snow flakes, 1000 other randomly generated snowflakes. The 7 snowflakes are still used. If you want only these snowflakes, click 'vintage' in the snow tab.


Falling snow is nice, and so are flocking birds. The behaviour of a flock of birds is an emergent thing, birds follow only a few simple rules to display a nice show. In short: birds want to fly at constant speed, fly in the same direction as neighbours and keep a certain distance to neighbours. Luckily, birds are also attracted by an attraction point like a tree, otherwise they would quickly leave the screen... Just search on the WWW for 'flocking birds' and the like and you will find much information about this subject, but no working programs. So I was tempted to try to program this behaviour and visualize it, in 3D. After some tests it appeared that this project was very well doable, and could relatively easily be incorporated in xsnow.

Technical issues

C vs C++

Xsnow is written in C. However, because I needed a reliable hash function to maintain a cache of bird surfaces, some C++ has been crept in. To store the bird surfaces, an 'unordered_map' is used if available. Otherwise, 'map' is used, which is not implemented as a hash function but as a binary tree. The WWW recommends to compile the main program with C++ when using a mix of C and C++, so a very small main() is written in C++, which calls the original C main() function. All sources have been adapted to compile using C++, so, if you are a C++ adept, you can do:
   CC=g++ ./configure
   make install


The original xsnow-1.42 has an more ore less ad-hoc timing mechanism. The program offers many flags to tweak the speed of Santa, the speed of snow and the like. Xsnow-2.0 has a more straight forward timing mechanism, in principle, every speed is defined in pixels/second.

The updating and drawing of Santa are decoupled, so the refreshing rate of Santa does not affect His speed.

Fallen snow (bottom and on windows) is nice in xsnow-1.42, but after running for some time, the visualization of fallen snow is not realistic. Therefore I use now a complete new strategy for the handling of fallen snow.

The handling of wind is changed in xsnow-2.0: it is now more or less windy all the time, but the original code from xsnow-1.42 is still used to experience more dramatic wind effects. The algorithm for the sensibility to wind of Santa and snow has been changed: The velocities of Santa and snow are changed by the wind.

In xsnow-1.42 an fixed-length array was used to hold the snow flakes. In xsnow-2.0, the flakes are in a double-linked list. This makes it possible to add snow flakes at random times, for example when converting fallen snow to snow flakes. Furthermore, the amount of snow is now determined by the rate the flakes are produced and removed. The production rate is given in flakes per second per pixel (i.e. the width of the window measured in pixels). This has the effect that, in a steady state situation, a larger window shows more flakes than a smaller one.

Inspired by project wsnow, written in JavaScript, I searched for an equivalent for setTimeout() in gdk/gtk. Indeed there is g_timeout_add_full(), which I overlooked or did not understand in the past. For 2.0.20 I rewrote all timed events using that function, which led to a better readable and simpler code. No double linked list any more for snow.

Since version 3.0.0, the preferred way for animation is GTK/Cairo: repainting the whole screen at ca. 25 frames/second. This results in a better quality, but the availability of an alpha channel (compositing window manager) is compulsive. Therefore, the old method is still used in FVWM-like environments and available in alpha channel environments. Tracking of the snow flakes is done in two ways:

  • X11: usage of g_timeout_add_full()
  • GTK/Cairo: the C++ construct 'set' or 'unordered_set'

Ok, this gets a bit confusing, here an overview:

Environment Snow (inclusive Santa etc.) Snow flakes tracking Birds
No alpha channel Use existing (root) window, draw with X11 g_timeout_add_full() No birds
Alpha channel Use separate transparent window, draw with X11 g_timeout_add_full() GTK/Cairo in own transparent window
or: Use same window as birds, draw with GTK/Cairo (unordered_)set GTK/Cairo in same window as snow

Added animations:

  • meteorites: On a gnome-like desktop, these are drawn and removed as described above. In other windows, the drawing and removing are done using GXxor.

  • stars: they are drawn in the air, are persistent, but change colour now and then, giving the illusion of twinkling. Stars try to be visible through fallen snow, this is not as it should be. Working on it.

  • scenery: using xsnow -treetype nnn you can choose what kind of scenery you want to see (Thanks to Carla Vermin-Anderson). More tree types are coming. Items are placed randomly, in contrast with xsnow-1.42. Care is taken that falling snow flakes are not interfering with the scenery, using Regions.

  • disappearing fallen snow: when a window is destroyed, the fallen snow on it is converted to snowflakes. Nice!

  • Santa now plows away the fallen snow He encounters.

  • in 2.0.20 a polar bear is added to the scenery. While it does not fit in the rest of the scenery, people kept asking... Moreover, in this version the movement of Santa is enhanced. Santa runs smoother now, and the vertical movements are much less jerky.

  • birds since version 3.0.0. The birds are flying using GTK/Cairo and need an own transparent click-through window. In Gnome, KDE, XFCE, etc. the birds will fly, but in FVWM, LXDE, etc. the birds are not able to fly.


Before version 2.10, xsnow refused to run on Wayland (that is the proposed successor of X11 and is the default on recent Debian-derived installations). I was prepared for major code changes in xsnow, but, after lots of googling, I found a solution, at least for xsnow: simply set the environment variable GDK_BACKEND=x11. So, before the gtk environment is initialized (using gtk_init()), xsnow sets (using setenv()) that variable to the desired value. Of course, the official GDK documentation has something about the issue . It could very well be that things work thanks to XWayland, I really don't know very much about X11 and Wayland. In Wayland, applications have only a restricted control over the windows that are not owned by the application. So, xsnow cannot snow in other windows. But for many of the windows the information about the where-abouts are available to xsnow. For example, xsnow is snowing on the windows of firefox, gimp, gvim, xsnow, xterm, xclock and xcalc, but not on the windows of aislerioth, gedit, nautilus and gnome-terminal.

Other desktops

  • In KDE xsnow-2.0 works. You can specify a monochrome background if there are problems.

  • In FVWM there are no problems.

  • In LXDE and XFCE there are no problems.

  • In Mint xsnow works the same as in Gnome.

  • In Raspbian (Raspberry pi's default desktop) xsnow runs by detecting the desktop is LXDE.

Desktop issues

  • In FVWM, xsnow works as the vintage one: simply painting on the root window.

  • In LXDE, xsnow detects this environment and will snow on the window with the name 'pcmanfm'.

  • In XFCE, xsnow detects this environment and will snow on the window with the name 'Desktop'.

  • In more advanced desktops (GNOME, KDE, ...) xsnow creates a transparent click-through window to paint on. This window can be placed below all other windows, or before. The birds window is placed just below the snow window.

  • It seems there is something wrong with the Breeze theme: xsnow works, but the buttons behave strangely.

  • Xsnow-2.0 can snow in arbitrary windows, you can choose one (using xsnow -xwininfo), or you can specify a window-id (using xsnow -id window-id). Using the flag '-xwininfo', it often happens that it is snowing (again!) behind the window you seem to select. I am working on this issue. Using the flag '-xwininfo' turns exposures on, unless you specify '-noexposures'.

  • The location of the top of the windows, including the decorations, is a known issue on the web. I found a solution for this issue: see the code in wmctrl.c (from the xsnow tarball). And, by looking at the code of the programs wmctrl and xwininfo and xprop, I was able to incorporate the things I need in xsnow with respect to choosing a window, locate a window etc.

  • In FVWM-like environments, xsnow starts on all workspaces. Since version 2.0.16 you can choose: run on all workspaces or run only in the current workspace. This version also survives the 'show desktop' button or key combination. Among the downloads I included shell scripts 'startondesktop' and 'startonalldesktops' (I should have called then 'startonworkspace' and 'startonworkspaces'...) that you can try to start xsnow on (a subset of) all workspaces if xsnow itself does not run in all workspaces on your system..

Graphical front end

My agenda showed some free hours on Kings-day (27 April 2019), which gave me the opportunity to finish the graphical front end. The front end is written using GTK3 and Glade as a designer tool. Details are in ui.c, ui.h, ui.glade, main.c: do_uicheck().


Since version 2.0~pre5, xsnow is equipped with the standard './configure; make; sudo make install' suite. Even 'make distcheck' works.

If you are running some kind of Debian (Ubuntu, Mint, ...) system and your hardware is of type amd64: On the downloads page, you find a debian package. Download and sudo apt install ./xsnow_[custom:xsnow-version]-1_amd64.deb and you are done. Xsnow will be installed under '/usr/games'.

In general, installing is done like this:

  • resolve the following dependencies:
  • libx11-dev
  • libxpm-dev
  • libxt-dev
  • pkg-config
  • libxml2-dev
  • libgtk-3-dev
  • In debian-like environments (including Raspbian):
    sudo apt install libx11-dev libxpm-dev libxt-dev pkg-config libxml2-dev libgtk-3-dev
  • In other environments (Suse, Redhat, ...): I am sure you know how to install these packages ;-)
  • Download the file xsnow-[custom:xsnow-version].tar.gz (see the Downloads page)
    umask 022
    tar xf xsnow-[custom:xsnow-version].tar.gz
    cd xsnow-[custom:xsnow-version]
    sudo make install
  • Xsnow should now be installed as /usr/local/bin/xsnow


Xsnow and X11 and GTK

Xsnow is based on X11, the graphical frontend is written using GTK-3. I tried to create a GTK-3-only version of xsnow, and encountered the following problems:

  • Performance: using GTK, the process xsnow and Xorg use both more than half a cpu. With xsnow-x11, only Xorg is very busy, xsnow itself uses a few percent.
  • Getting information about other windows is not really possible, it seems. So xsnow would not be able to snow on windows.

For now, I abandoned the xsnow-gtk project.

I picked up the xsnow-gtk project again, having learned from implementing the birds. Since version 3.0.5, in desktops like Gnome, you have the option to snow using X11 (the old method), or using GTK and Cairo, using the same window as the birds are using. The birds are always using GTK/Cairo.

Xsnow on Apple IOS

There will never be a version of xsnow for Apple IOS, because there is already a very good nephew of xsnow available for Apple IOS. Search for 'iSnow' in the Apple store or have a look at this page. I guess this is enough explanation for Apple IOS users. I have no access to such a system, so I cannot test. BTW: iSnow is written by Rick Jansen, so quality is guaranteed.

Xsnow on MS Windows

I am certainly not planning to port xsnow to windows. Once upon a time there was 'winsnow' (also created by Rick Jansen), but I am unaware of the status. There is some info here. There is a poor man's version of xsnow that runs in a browser (even an Windows browser!): wsnow.