diff --git a/ChangeLog b/ChangeLog
index e4fd99b74cf1838c10617bae73d4c2e8e0385973..b38cb36e8a6304dd26eccd24f46420d4e7a12e6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-05-28 jeromeg
+
+Add a throbber to notify activity during the ZimageZ upload.
+
+Take KatzeThrobber from Midori and relicense it to GPL2. Thanks a lot
+to Christian Dywan.
+
 2009-05-26 jeromeg
 
 Add Danish translation for the documentation (Lars Christian Jensen).
diff --git a/docs/manual/da/xfce4-screenshooter.html b/docs/manual/da/xfce4-screenshooter.html
new file mode 100644
index 0000000000000000000000000000000000000000..210d4fe3904b134ad958d5a1a28de1c6e0c7a094
--- /dev/null
+++ b/docs/manual/da/xfce4-screenshooter.html
@@ -0,0 +1 @@
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Xfce4 Screenshooter</title><link rel="stylesheet" href="../xfce.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.73.2"><link rel="start" href="#xfce4-screenshooter" title="Xfce4 Screenshooter"><link rel="next" href="#intro" title="Introduktion til xfce4-screenshooter"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article" lang="da"><div class="titlepage"><div><div><h2 class="title"><a name="xfce4-screenshooter"></a>Xfce4 Screenshooter</h2></div><div><div class="authorgroup"><div class="author"><h3 class="author"><span class="firstname">Jérôme</span> <span class="surname">Guelfucci</span></h3><div class="affiliation"><div class="address"><p><code class="email">&lt;<a class="email" href="mailto:jeromeg@xfce.org">jeromeg@xfce.org</a>&gt;</code></p></div></div></div></div></div><div><span xmlns="http://www.w3.org/TR/xhtml1/transitional" class="releaseinfo">Denne manual beskriver version xfce4-screenshooter 1.5.1.1svn-r07416.<br></br></span></div><div><p class="copyright">Ophavsret © 2008, 2009 Jérôme Guelfucci</p></div><div><div class="legalnotice"><a name="legalnotice"></a><p>Der gives hermed tilladelse til kopiere, distribuere og/eller ændre dette dokument under betingelserne af GNU Free Documentation License, Version 1.1 eller enhver senere version udgivet af Free Software Foundation, med ingen ufravigelige dele; ingen forsidetekst, og ingen bagsidetekst. Hele licensteksten er til rådighed på <a class="ulink" href="http://www.gnu.org/" target="_top">Free Software Foundation</a>.</p></div></div><div><p class="pubdate">February 2009</p></div></div><hr></div><div class="toc"><p><b>Indholdsfortegnelse</b></p><dl><dt><span class="sect1"><a href="#intro">Introduktion til xfce4-screenshooter</a></span></dt><dt><span class="sect1"><a href="#using-the-application">Brug af programmet</a></span></dt><dd><dl><dt><span class="sect2"><a href="#user-interface">Vha. brugergrænsefladen</a></span></dt><dt><span class="sect2"><a href="#command-line">Vha. kommandolinjen</a></span></dt></dl></dd><dt><span class="sect1"><a href="#panel-plugin">Brug af udvidelsesmodulet til panelet i Xfce</a></span></dt><dd><dl><dt><span class="sect2"><a href="#add">Tilføjelse af udvidelsesmodulet</a></span></dt><dt><span class="sect2"><a href="#set">Indstilling af udvidelsesmodulet</a></span></dt><dt><span class="sect2"><a href="#use">Brug af udvidelsesmodulet</a></span></dt></dl></dd></dl></div><div class="sect1" lang="da"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="intro"></a>Introduktion til xfce4-screenshooter</h2></div></div></div><p>Dette program giver dig mulighed for at tage et billede af hele skærmen, det aktive vindue eller en markeret region. Du kan indstille forsinkelsen før billedet er taget og handlingen med billeder udføres: gemme det som en PNG-fil, kopiere det til udklipsholderen eller åbne det med et andet program.</p><p>Et udvidelsesmodul til panelet i Xfce er også tilgængeligt.</p></div><div class="sect1" lang="da"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="using-the-application"></a>Brug af programmet</h2></div></div></div><div class="sect2" lang="da"><div class="titlepage"><div><div><h3 class="title"><a name="user-interface"></a>Vha. brugergrænsefladen</h3></div></div></div><p>For at starte programmet skal du bruge "Skærmbillede"-elementet i kategorien "Tilbehør" fra hovedmenuen i Xfce.</p><p>Dette vindue vil blive vist:</p><div class="screenshot"><div class="mediaobject"><img src="images/xfce4-screenshooter-dialog.png" alt="Vinduet i Xfce4 Screenshooter"></div></div><div class="sect3" lang="da"><div class="titlepage"><div><div><h4 class="title"><a name="region-to-capture"></a>Område der skal tages et billede af</h4></div></div></div><p>Tilvalget <span class="emphasis"><em>"Område der skal tages billede af"</em></span> tillader dig at indstille, hvorfra skærmbilledet skal tages:</p><div class="itemizedlist"><ul type="disc"><li>"Hele skærmen" tager et skærmbillede af hele skærmen, som du ser den.</li><li>"Aktive vindue" tager et billede af det aktive vindue, hvilket er det der, var aktivt før denne dialog kom frem, eller hvis du indstiller en forsinkelse, er det vinduet, der er aktivt efter udløb af forsinkelsen.</li><li>"Vælg et område" tillader dig at vælge det område der skal tages et billede af, ved at klikke på et punkt på skærmen, og uden at slippe musen, trække den til det modsatte hjørne af regionen og slippe museknappen.</li></ul></div></div><div class="sect3" lang="da"><div class="titlepage"><div><div><h4 class="title"><a name="delay"></a>Forsinkelse før der tages et skærmbillede</h4></div></div></div><p>Tilvalget <span class="emphasis"><em>"Forsinkelse før skærmbilledet bliver taget"</em></span>, tillader dig at indstille den tid, der går fra du trykker på <span class="emphasis"><em>"Tag skærmbillede"</em></span>-knappen, og til at skærmbilledet rent faktisk bliver taget. Denne forsinkelse giver dig tid til at åbne menuer, eller udføre enhver handling du ønsker at vist i skærmbilledet.</p></div><div class="sect3" lang="da"><div class="titlepage"><div><div><h4 class="title"><a name="action"></a>Handling</h4></div></div></div><p>Tilvalget <span class="emphasis"><em>"Handling"</em></span> giver dig mulighed for at vælge, hvad der skal gøres med skærmbilledet. Der er tre valgmuligheder.</p><div class="sect4" lang="da"><div class="titlepage"><div><div><h5 class="title"><a name="save"></a>Gem</h5></div></div></div><p>Tilvalget <span class="emphasis"><em>"Gem"</em></span>, gemmer skærmbilledet i en PNG-fil. Hvis du afkrydser <span class="emphasis"><em>"Gem som standard i"</em></span>-feltet, vil skærmbilledet blive gemt i mappen til højre, lige efter du trykker på <span class="emphasis"><em>"Tag skærmbillede"</em></span>-knappen, uden at vise et gem-vindue. Ellers vil gem-vinduet blive vist sammen med en forhåndsvisning af skærmbilledet. Du ville så kunne indstille, hvor det skal gemmes, samt navnet på filen.</p></div><div class="sect4" lang="da"><div class="titlepage"><div><div><h5 class="title"><a name="copy-to-clipboard"></a>Kopiér til udklipsholderen</h5></div></div></div><p>Tilvalget <span class="emphasis"><em>"Kopiér til udklipsholder"</em></span>, lader dig indsætte skærmbilledet i et andet program, så som en tekstbehandler. Afsluttes programmet før skærmbilledet er indsat, vil billedet ofte blive slettet fra udklipsholderen. Nogle udklipsholdere kan dog undgå dette.</p></div><div class="sect4" lang="da"><div class="titlepage"><div><div><h5 class="title"><a name="open-with"></a>Åbn med</h5></div></div></div><p>Tilvalget <span class="emphasis"><em>"Åbn med"</em></span> gemmer skærmbilledet i systemets midlertidige katalog og åbner det med valgte program, ved at bruge rullegardinlisten herunder. Programmer der understøtter billeder, er automatisk fundet og tilføjet til rullegardinlisten.</p></div></div></div><div class="sect2" lang="da"><div class="titlepage"><div><div><h3 class="title"><a name="command-line"></a>Vha. kommandolinjen</h3></div></div></div><p>Kommandlinjetilvalg lader dig tage skærmbilleder hurtigt. De lader dig også indstille knappen Prt Scrn, som findes i det øverste højre hjørne på de fleste tastaturer, til at tage skærmbilledet. For at gøre dette, skal du indstille tastaturgenvejene i dit skrivebordsmiljø, således at det starter xfce4-screenshooter, med en eller flere af de følgende tilvalg, når der trykkes på Prt Scrn-knappen.</p><div class="sect3" lang="da"><div class="titlepage"><div><div><h4 class="title"><a name="options"></a>Kommandolinjetilvalg</h4></div></div></div><div class="sect4" lang="da"><div class="titlepage"><div><div><h5 class="title"><a name="w-option"></a>Tilvalget -w</h5></div></div></div><p>Tilvalget <span class="emphasis"><em>-w</em></span>, lader dig tage et skærmbillede af det aktive vindue.</p></div><div class="sect4" lang="da"><div class="titlepage"><div><div><h5 class="title"><a name="f-option"></a>Tilvalget -f</h5></div></div></div><p>Tilvalget <span class="emphasis"><em>-f</em></span>, lader dig tage et skærmbillede af hele skærmen.</p></div><div class="sect4" lang="da"><div class="titlepage"><div><div><h5 class="title"><a name="r-option"></a>Tilvalget -r</h5></div></div></div><p>Tilvalget <span class="emphasis"><em>-r</em></span>, lader dig vælge et område, der skal tages et billede af, ved at klikke på et punkt på skærmen, og uden at slippe museknappen, trække musen til det modsatte hjørne af det område, og så slippe museknappen.</p></div><div class="sect4" lang="da"><div class="titlepage"><div><div><h5 class="title"><a name="d-option"></a>Tilvalget -d</h5></div></div></div><p>Tilvalget <span class="emphasis"><em>-d</em></span> efterfulgt af et positivt heltal, lader dig indstille en forsinkelse før skærmbilledet bliver taget med tilvalget <span class="emphasis"><em>-f</em></span>, <span class="emphasis"><em>-w</em></span> eller <span class="emphasis"><em>-r</em></span>.</p></div><div class="sect4" lang="da"><div class="titlepage"><div><div><h5 class="title"><a name="s-option"></a>Tilvalget -s</h5></div></div></div><p>Tilvalget <span class="emphasis"><em>-s</em></span> efterfulgt af stien til en eksisterende mappe, lader dig indstille, hvortil skærmbilledet skal gemmes. Dette tilvalg virker kun ,hvis man bruger den sammen med tilvalget <span class="emphasis"><em>-f</em></span>, <span class="emphasis"><em>-w</em></span> eller <span class="emphasis"><em>-r</em></span>. Kombineret med tilvalget <span class="emphasis"><em>-h</em></span> (se herunder), kan den bruges til at gemme en fil til en bestemt sti, uden at vise nogen gem-vindue.</p></div><div class="sect4" lang="da"><div class="titlepage"><div><div><h5 class="title"><a name="h-option"></a>Tilvalget -h</h5></div></div></div><p>Hvis du angiver tilvalget <span class="emphasis"><em>-h</em></span>, vil skærmbilledet automatisk blive gemt uden at vise nogen gem-vindue. Dette tilvalg virker kun, hvis det bruges sammen med tilvalget <span class="emphasis"><em>-f</em></span>, <span class="emphasis"><em>-w</em></span> eller <span class="emphasis"><em>-r</em></span>. Tilvalget <span class="emphasis"><em>s-</em></span>, lader dig indstille hvor det skal gemmes, hvis der er behov herfor.</p></div><div class="sect4" lang="da"><div class="titlepage"><div><div><h5 class="title"><a name="o-option"></a>Tilvalget -o</h5></div></div></div><p>Hvis tilvalget <span class="emphasis"><em>-o</em></span> er angivet, efterfulgt af et programnavn, vil skærmbilledet blive gemt i systemets midlertidige katalog og blive åbnet med det program der er nævnt efter tilvalget <span class="emphasis"><em>-o</em></span>. Dette tilvalg virker kun, hvis det bruges sammen med tilvalget <span class="emphasis"><em>-f</em></span>, <span class="emphasis"><em>-w</em></span> eller <span class="emphasis"><em>-r</em></span>.</p></div></div></div></div><div class="sect1" lang="da"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="panel-plugin"></a>Brug af udvidelsesmodulet til panelet i Xfce</h2></div></div></div><div class="sect2" lang="da"><div class="titlepage"><div><div><h3 class="title"><a name="add"></a>Tilføjelse af udvidelsesmodulet</h3></div></div></div><p>For at tilføje udvidelsesmodulet; højreklik på panelet og vælg <span class="emphasis"><em>"Tilføj nyt element""emphasis&gt;. V"Sk, og tilf</em></span></p></div><div class="sect2" lang="da"><div class="titlepage"><div><div><h3 class="title"><a name="set"></a>Indstilling af udvidelsesmodulet</h3></div></div></div><p>Du kan indstille, hvordan skærmbilleder bliver taget ved at højreklikke på udvidelsesmodulet og vælge <span class="emphasis"><em>"Indstil"<span class="emphasis"><em>. En indstillingsmenu, der ligner indstillingsmenuen til hovedprogrammet, vil vise sig. Se venligst ovenfor, for diverse indstillinger.</em></span></em></span></p></div><div class="sect2" lang="da"><div class="titlepage"><div><div><h3 class="title"><a name="use"></a>Brug af udvidelsesmodulet</h3></div></div></div><p>For at tage et skærmbillede; klik da bare på udvidelsesmodulet.</p></div></div></div></body></html>
diff --git a/lib/Makefile.am b/lib/Makefile.am
index a198d45cf0c1974db7f4a839a701ebcc7f5ce043..8740a8afd8dbbb401af16fc065456339b42221e5 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -34,6 +34,7 @@ libscreenshooter_la_SOURCES +=	\
 	$(libscreenshooter_built_sources) \
   exo-job.c exo-job.h \
 	exo-simple-job.c exo-simple-job.h \
+	katze-throbber.c katze-throbber.h \
 	screenshooter-job.c screenshooter-job.h \
 	screenshooter-simple-job.c screenshooter-simple-job.h \
 	screenshooter-zimagez.c screenshooter-zimagez.h \
diff --git a/lib/katze-throbber.c b/lib/katze-throbber.c
new file mode 100644
index 0000000000000000000000000000000000000000..2b916ffe0d325a8b32bf8ac74ad0aa720cfe7bb9
--- /dev/null
+++ b/lib/katze-throbber.c
@@ -0,0 +1,954 @@
+/*  $Id$
+ *  
+ *  Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * */
+
+#include "katze-throbber.h"
+
+#include <glib/gi18n.h>
+#include <math.h>
+
+struct _KatzeThrobber
+{
+    GtkMisc parent_instance;
+
+    GtkIconSize icon_size;
+    gchar* icon_name;
+    GdkPixbuf* pixbuf;
+    gchar* stock_id;
+    gboolean animated;
+    gchar* static_icon_name;
+    GdkPixbuf* static_pixbuf;
+    gchar* static_stock_id;
+
+    gint index;
+    gint timer_id;
+    gint width;
+    gint height;
+};
+
+G_DEFINE_TYPE (KatzeThrobber, katze_throbber, GTK_TYPE_MISC);
+
+enum
+{
+    PROP_0,
+
+    PROP_ICON_SIZE,
+    PROP_ICON_NAME,
+    PROP_PIXBUF,
+    PROP_ANIMATED,
+    PROP_STATIC_ICON_NAME,
+    PROP_STATIC_PIXBUF,
+    PROP_STATIC_STOCK_ID
+};
+
+static void
+katze_throbber_dispose (GObject* object);
+
+static void
+katze_throbber_set_property (GObject* object,
+                             guint prop_id,
+                             const GValue* value,
+                             GParamSpec* pspec);
+
+static void
+katze_throbber_get_property (GObject* object,
+                             guint prop_id,
+                             GValue* value,
+                             GParamSpec* pspec);
+
+static void
+katze_throbber_destroy (GtkObject* object);
+
+static void
+katze_throbber_realize (GtkWidget* widget);
+
+static void
+katze_throbber_unrealize (GtkWidget* widget);
+
+static void
+katze_throbber_map (GtkWidget* widget);
+
+static void
+katze_throbber_unmap (GtkWidget* widget);
+
+static void
+katze_throbber_style_set (GtkWidget* widget,
+                          GtkStyle* style);
+
+static void
+katze_throbber_screen_changed (GtkWidget* widget,
+                               GdkScreen* screen_prev);
+
+static void
+katze_throbber_size_request (GtkWidget*      widget,
+                             GtkRequisition* requisition);
+
+static gboolean
+katze_throbber_expose_event (GtkWidget*      widget,
+                             GdkEventExpose* event);
+
+static void
+icon_theme_changed (KatzeThrobber* throbber);
+
+static gboolean
+katze_throbber_timeout (KatzeThrobber* throbber);
+
+static void
+katze_throbber_timeout_destroy (KatzeThrobber* throbber);
+
+/**
+ * katze_assign:
+ * @lvalue: a pointer
+ * @rvalue: the new value
+ *
+ * Frees @lvalue if needed and assigns it the value of @rvalue.
+ * */
+#define katze_assign(lvalue, rvalue) \
+    if (1) \
+    { \
+        g_free (lvalue); \
+        lvalue = rvalue; \
+    }
+
+/**
+ * katze_object_assign:
+ * @lvalue: a gobject
+ * @rvalue: the new value
+ *
+ * Unrefs @lvalue if needed and assigns it the value of @rvalue.
+ * */
+#define katze_object_assign(lvalue, rvalue) \
+    if (1) \
+    { \
+        if (lvalue) \
+            g_object_unref (lvalue); \
+        lvalue = rvalue; \
+    }
+
+static void
+katze_throbber_class_init (KatzeThrobberClass* class)
+{
+    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->dispose = katze_throbber_dispose;
+    gobject_class->set_property = katze_throbber_set_property;
+    gobject_class->get_property = katze_throbber_get_property;
+
+    GtkObjectClass* object_class = GTK_OBJECT_CLASS (class);
+    object_class->destroy = katze_throbber_destroy;
+
+    GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (class);
+    widget_class->realize = katze_throbber_realize;
+    widget_class->unrealize = katze_throbber_unrealize;
+    widget_class->map = katze_throbber_map;
+    widget_class->unmap = katze_throbber_unmap;
+    widget_class->style_set = katze_throbber_style_set;
+    widget_class->screen_changed = katze_throbber_screen_changed;
+    widget_class->size_request = katze_throbber_size_request;
+    widget_class->expose_event = katze_throbber_expose_event;
+
+    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_ICON_SIZE,
+                                     g_param_spec_int (
+                                     "icon-size",
+                                     "Icon size",
+                                     "Symbolic size to use for the animation",
+                                     0, G_MAXINT, GTK_ICON_SIZE_MENU,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_ICON_NAME,
+                                     g_param_spec_string (
+                                     "icon-name",
+                                     "Icon Name",
+                                     "The name of an icon containing animation frames",
+                                     "process-working",
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_PIXBUF,
+                                     g_param_spec_object (
+                                     "pixbuf",
+                                     "Pixbuf",
+                                     "A GdkPixbuf containing animation frames",
+                                     GDK_TYPE_PIXBUF,
+                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_ANIMATED,
+                                     g_param_spec_boolean (
+                                     "animated",
+                                     "Animated",
+                                     "Whether the throbber should be animated",
+                                     FALSE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_STATIC_ICON_NAME,
+                                     g_param_spec_string (
+                                     "static-icon-name",
+                                     "Static Icon Name",
+                                     "The name of an icon to be used as the static image",
+                                     NULL,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_PIXBUF,
+                                     g_param_spec_object (
+                                     "static-pixbuf",
+                                     "Static Pixbuf",
+                                     "A GdkPixbuf to be used as the static image",
+                                     GDK_TYPE_PIXBUF,
+                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_STATIC_STOCK_ID,
+                                     g_param_spec_string (
+                                     "static-stock-id",
+                                     "Static Stock ID",
+                                     "The stock ID of an icon to be used as the static image",
+                                     NULL,
+                                     flags));
+}
+
+static void
+katze_throbber_init (KatzeThrobber *throbber)
+{
+    GTK_WIDGET_SET_FLAGS (throbber, GTK_NO_WINDOW);
+
+    throbber->timer_id = -1;
+}
+
+static void
+katze_throbber_dispose (GObject* object)
+{
+    KatzeThrobber* throbber = KATZE_THROBBER (object);
+
+    if (G_UNLIKELY (throbber->timer_id >= 0))
+        g_source_remove (throbber->timer_id);
+
+    (*G_OBJECT_CLASS (katze_throbber_parent_class)->dispose) (object);
+}
+
+static void
+katze_throbber_destroy (GtkObject* object)
+{
+    KatzeThrobber* throbber = KATZE_THROBBER (object);
+
+    katze_assign (throbber->icon_name, NULL);
+    katze_object_assign (throbber->pixbuf, NULL);
+    katze_assign (throbber->static_icon_name, NULL);
+    katze_object_assign (throbber->static_pixbuf, NULL);
+    katze_assign (throbber->static_stock_id, NULL);
+
+    GTK_OBJECT_CLASS (katze_throbber_parent_class)->destroy (object);
+}
+
+static void
+katze_throbber_set_property (GObject*      object,
+                             guint         prop_id,
+                             const GValue* value,
+                             GParamSpec*   pspec)
+{
+    KatzeThrobber* throbber = KATZE_THROBBER (object);
+
+    switch (prop_id)
+    {
+    case PROP_ICON_SIZE:
+        katze_throbber_set_icon_size (throbber, g_value_get_int (value));
+        break;
+    case PROP_ICON_NAME:
+        katze_throbber_set_icon_name (throbber, g_value_get_string (value));
+        break;
+    case PROP_PIXBUF:
+        katze_throbber_set_pixbuf (throbber, g_value_get_object (value));
+        break;
+    case PROP_ANIMATED:
+        katze_throbber_set_animated (throbber, g_value_get_boolean (value));
+        break;
+    case PROP_STATIC_ICON_NAME:
+        katze_throbber_set_static_icon_name (throbber, g_value_get_string (value));
+        break;
+    case PROP_STATIC_PIXBUF:
+        katze_throbber_set_static_pixbuf (throbber, g_value_get_object (value));
+        break;
+    case PROP_STATIC_STOCK_ID:
+        katze_throbber_set_static_stock_id (throbber, g_value_get_string (value));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+katze_throbber_get_property (GObject*    object,
+                             guint       prop_id,
+                             GValue*     value,
+                             GParamSpec* pspec)
+{
+    KatzeThrobber* throbber = KATZE_THROBBER (object);
+
+    switch (prop_id)
+    {
+    case PROP_ICON_SIZE:
+        g_value_set_int (value, katze_throbber_get_icon_size (throbber));
+        break;
+    case PROP_ICON_NAME:
+        g_value_set_string (value, katze_throbber_get_icon_name (throbber));
+        break;
+    case PROP_PIXBUF:
+        g_value_set_object (value, katze_throbber_get_pixbuf (throbber));
+        break;
+    case PROP_ANIMATED:
+        g_value_set_boolean (value, katze_throbber_get_animated (throbber));
+        break;
+    case PROP_STATIC_ICON_NAME:
+        g_value_set_string (value, katze_throbber_get_static_icon_name (throbber));
+        break;
+    case PROP_STATIC_PIXBUF:
+        g_value_set_object (value, katze_throbber_get_static_pixbuf (throbber));
+        break;
+    case PROP_STATIC_STOCK_ID:
+        g_value_set_string (value, katze_throbber_get_static_stock_id (throbber));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+/**
+ * katze_throbber_new:
+ *
+ * Creates a new throbber widget.
+ *
+ * Return value: a new #KatzeThrobber
+ **/
+GtkWidget*
+katze_throbber_new (void)
+{
+    KatzeThrobber* throbber = g_object_new (KATZE_TYPE_THROBBER,
+                                            NULL);
+
+    return GTK_WIDGET (throbber);
+}
+
+/**
+ * katze_throbber_set_icon_size:
+ * @throbber: a #KatzeThrobber
+ * @icon_size: the new icon size
+ *
+ * Sets the desired size of the throbber image. The animation and static image
+ * will be displayed in this size. If a pixbuf is used for the animation every
+ * single frame is assumed to have this size.
+ **/
+void
+katze_throbber_set_icon_size (KatzeThrobber* throbber,
+                              GtkIconSize    icon_size)
+{
+    GtkSettings* gtk_settings;
+
+    g_return_if_fail (KATZE_IS_THROBBER (throbber));
+    gtk_settings = gtk_widget_get_settings (GTK_WIDGET (throbber));
+    g_return_if_fail (gtk_icon_size_lookup_for_settings (gtk_settings,
+                                                         icon_size,
+                                                         &throbber->width,
+                                                         &throbber->height));
+
+    throbber->icon_size = icon_size;
+
+    g_object_notify (G_OBJECT (throbber), "icon-size");
+
+    gtk_widget_queue_draw (GTK_WIDGET (throbber));
+}
+
+/**
+ * katze_throbber_set_icon_name:
+ * @throbber: a #KatzeThrobber
+ * @icon_name: an icon name or %NULL
+ *
+ * Sets the name of an icon that should provide the animation frames.
+ *
+ * The pixbuf is automatically invalidated.
+ **/
+void
+katze_throbber_set_icon_name (KatzeThrobber*  throbber,
+                              const gchar*    icon_name)
+{
+    g_return_if_fail (KATZE_IS_THROBBER (throbber));
+
+    katze_assign (throbber->icon_name, g_strdup (icon_name));
+
+    if (icon_name)
+        icon_theme_changed (throbber);
+
+    g_object_notify (G_OBJECT (throbber), "icon-name");
+}
+
+/**
+ * katze_throbber_set_pixbuf:
+ * @throbber: a #KatzeThrobber
+ * @pixbuf: a #GdkPixbuf or %NULL
+ *
+ * Sets the pixbuf that should provide the animation frames. Every frame
+ * is assumed to have the icon size of the throbber, which can be specified
+ * with katze_throbber_set_icon_size ().
+ *
+ * The icon name is automatically invalidated.
+ **/
+void
+katze_throbber_set_pixbuf (KatzeThrobber* throbber,
+                           GdkPixbuf*     pixbuf)
+{
+    g_return_if_fail (KATZE_IS_THROBBER (throbber));
+    g_return_if_fail (!pixbuf || GDK_IS_PIXBUF (pixbuf));
+
+    katze_object_assign (throbber->pixbuf, pixbuf);
+
+    g_object_freeze_notify (G_OBJECT (throbber));
+
+    if (pixbuf)
+    {
+        g_object_ref (pixbuf);
+
+        katze_assign (throbber->icon_name, NULL);
+        g_object_notify (G_OBJECT (throbber), "icon-name");
+    }
+
+    gtk_widget_queue_draw (GTK_WIDGET (throbber));
+
+    g_object_notify (G_OBJECT (throbber), "pixbuf");
+    g_object_thaw_notify (G_OBJECT (throbber));
+}
+
+/**
+ * katze_throbber_set_animated:
+ * @throbber: a #KatzeThrobber
+ * @animated: %TRUE to animate the throbber
+ *
+ * Sets the animation state of the throbber.
+ **/
+void
+katze_throbber_set_animated (KatzeThrobber*  throbber,
+                             gboolean        animated)
+{
+    g_return_if_fail (KATZE_IS_THROBBER (throbber));
+
+    if (G_UNLIKELY (throbber->animated == animated))
+        return;
+
+    throbber->animated = animated;
+
+    if (animated && (throbber->timer_id < 0))
+        throbber->timer_id = g_timeout_add_full (
+                         G_PRIORITY_LOW, 50,
+                         (GSourceFunc)katze_throbber_timeout,
+                         throbber,
+                         (GDestroyNotify)katze_throbber_timeout_destroy);
+
+    gtk_widget_queue_draw (GTK_WIDGET (throbber));
+
+    g_object_notify (G_OBJECT (throbber), "animated");
+}
+
+/**
+ * katze_throbber_set_static_icon_name:
+ * @throbber: a #KatzeThrobber
+ * @icon_name: an icon name or %NULL
+ *
+ * Sets the name of an icon that should provide the static image.
+ *
+ * The static pixbuf and stock ID are automatically invalidated.
+ **/
+void
+katze_throbber_set_static_icon_name (KatzeThrobber*  throbber,
+                                     const gchar*    icon_name)
+{
+    g_return_if_fail (KATZE_IS_THROBBER (throbber));
+
+    katze_assign (throbber->static_icon_name, g_strdup (icon_name));
+
+    g_object_freeze_notify (G_OBJECT (throbber));
+
+    if (icon_name)
+    {
+        katze_assign (throbber->static_stock_id, NULL);
+
+        icon_theme_changed (throbber);
+
+        g_object_notify (G_OBJECT (throbber), "static-pixbuf");
+        g_object_notify (G_OBJECT (throbber), "static-stock-id");
+    }
+
+    g_object_notify (G_OBJECT (throbber), "static-icon-name");
+    g_object_thaw_notify (G_OBJECT (throbber));
+}
+
+/**
+ * katze_throbber_set_static_pixbuf:
+ * @throbber: a #KatzeThrobber
+ * @pixbuf: a #GdkPixbuf or %NULL
+ *
+ * Sets the pixbuf that should provide the static image. The pixbuf is
+ * assumed to have the icon size of the throbber, which can be specified
+ * with katze_throbber_set_icon_size ().
+ *
+ * The static icon name and stock ID are automatically invalidated.
+ **/
+void
+katze_throbber_set_static_pixbuf (KatzeThrobber* throbber,
+                                  GdkPixbuf*     pixbuf)
+{
+    g_return_if_fail (KATZE_IS_THROBBER (throbber));
+    g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
+
+    katze_object_assign (throbber->static_pixbuf, pixbuf);
+
+    g_object_freeze_notify (G_OBJECT (throbber));
+
+    if (pixbuf)
+    {
+        g_object_ref (pixbuf);
+
+        katze_assign (throbber->static_icon_name, NULL);
+        katze_assign (throbber->static_stock_id, NULL);
+
+        gtk_widget_queue_draw (GTK_WIDGET (throbber));
+
+        g_object_notify (G_OBJECT (throbber), "static-icon-name");
+        g_object_notify (G_OBJECT (throbber), "static-stock-id");
+    }
+
+    g_object_notify (G_OBJECT (throbber), "static-pixbuf");
+    g_object_thaw_notify (G_OBJECT (throbber));
+}
+
+/**
+ * katze_throbber_set_static_stock_id:
+ * @throbber: a #KatzeThrobber
+ * @stock_id: a stock ID or %NULL
+ *
+ * Sets the stock ID of an icon that should provide the static image.
+ *
+ * The static icon name and pixbuf are automatically invalidated.
+ **/
+void
+katze_throbber_set_static_stock_id (KatzeThrobber* throbber,
+                                    const gchar*   stock_id)
+{
+    g_return_if_fail (KATZE_IS_THROBBER (throbber));
+
+    g_object_freeze_notify (G_OBJECT (throbber));
+
+    if (stock_id)
+    {
+        GtkStockItem stock_item;
+        g_return_if_fail (gtk_stock_lookup (stock_id, &stock_item));
+
+        g_object_notify (G_OBJECT (throbber), "static-icon-name");
+        g_object_notify (G_OBJECT (throbber), "static-pixbuf");
+    }
+
+    katze_assign (throbber->static_stock_id, g_strdup (stock_id));
+
+    if (stock_id)
+        icon_theme_changed (throbber);
+
+    g_object_notify (G_OBJECT (throbber), "static-stock-id");
+    g_object_thaw_notify (G_OBJECT (throbber));
+}
+
+/**
+ * katze_throbber_get_icon_size:
+ * @throbber: a #KatzeThrobber
+ *
+ * Retrieves the size of the throbber.
+ *
+ * Return value: the size of the throbber
+ **/
+GtkIconSize
+katze_throbber_get_icon_size (KatzeThrobber* throbber)
+{
+    g_return_val_if_fail (KATZE_IS_THROBBER (throbber), GTK_ICON_SIZE_INVALID);
+
+    return throbber->icon_size;
+}
+
+/**
+ * katze_throbber_get_icon_name:
+ * @throbber: a #KatzeThrobber
+ *
+ * Retrieves the name of the icon providing the animation frames.
+ *
+ * Return value: the name of the icon providing the animation frames, or %NULL
+ **/
+const gchar*
+katze_throbber_get_icon_name (KatzeThrobber* throbber)
+{
+    g_return_val_if_fail (KATZE_IS_THROBBER (throbber), NULL);
+
+    return throbber->icon_name;
+}
+
+/**
+ * katze_throbber_get_pixbuf:
+ * @throbber: a #KatzeThrobber
+ *
+ * Retrieves the #GdkPixbuf providing the animation frames if an icon name
+ * or pixbuf is available. The caller of this function does not own a
+ * reference to the returned pixbuf.
+ *
+ * Return value: the pixbuf providing the animation frames, or %NULL
+ **/
+GdkPixbuf*
+katze_throbber_get_pixbuf (KatzeThrobber* throbber)
+{
+    g_return_val_if_fail (KATZE_IS_THROBBER (throbber), NULL);
+
+    return throbber->pixbuf;
+}
+
+/**
+ * katze_throbber_get_animated:
+ * @throbber: a #KatzeThrobber
+ *
+ * Retrieves the status of the animation, whcih can be animated or static.
+ *
+ * Return value: %TRUE if the throbber is animated
+ **/
+gboolean
+katze_throbber_get_animated (KatzeThrobber* throbber)
+{
+    g_return_val_if_fail (KATZE_IS_THROBBER (throbber), FALSE);
+
+    return throbber->animated;
+}
+
+/**
+ * katze_throbber_get_static_icon_name:
+ * @throbber: a #KatzeThrobber
+ *
+ * Retrieves the name of the icon providing the static image, if an icon name
+ * for the static image was specified.
+ *
+ * Return value: the name of the icon providing the static image, or %NULL
+ **/
+const gchar*
+katze_throbber_get_static_icon_name (KatzeThrobber* throbber)
+{
+    g_return_val_if_fail (KATZE_IS_THROBBER (throbber), NULL);
+
+    return throbber->static_icon_name;
+}
+
+/**
+ * katze_throbber_get_static pixbuf:
+ * @throbber: a #KatzeThrobber
+ *
+ * Retrieves the #GdkPixbuf providing the static image, if an icon name, a
+ * pixbuf or a stock ID for the static image was specified. The caller of this
+ * function does not own a reference to the returned pixbuf.
+ *
+ * Return value: the pixbuf providing the static image, or %NULL
+ **/
+GdkPixbuf*
+katze_throbber_get_static_pixbuf (KatzeThrobber* throbber)
+{
+    g_return_val_if_fail (KATZE_IS_THROBBER (throbber), NULL);
+
+    return throbber->static_pixbuf;
+}
+
+/**
+ * katze_throbber_get_static_stock_id:
+ * @throbber: a #KatzeThrobber
+ *
+ * Retrieves the stock ID of the icon providing the static image, if a
+ * stock ID for the static image was specified.
+ *
+ * Return value: the stock ID of the icon providing the static image, or %NULL
+ **/
+const gchar*
+katze_throbber_get_static_stock_id (KatzeThrobber* throbber)
+{
+    g_return_val_if_fail (KATZE_IS_THROBBER (throbber), NULL);
+
+    return throbber->static_stock_id;
+}
+
+static void
+katze_throbber_realize (GtkWidget* widget)
+{
+    (*GTK_WIDGET_CLASS (katze_throbber_parent_class)->realize) (widget);
+
+    icon_theme_changed (KATZE_THROBBER (widget));
+}
+
+static void
+katze_throbber_unrealize (GtkWidget* widget)
+{
+    if (GTK_WIDGET_CLASS (katze_throbber_parent_class)->unrealize)
+        GTK_WIDGET_CLASS (katze_throbber_parent_class)->unrealize (widget);
+}
+
+static void
+pixbuf_assign_icon (GdkPixbuf**    pixbuf,
+                    const gchar*   icon_name,
+                    KatzeThrobber* throbber)
+{
+    GdkScreen* screen;
+    GtkIconTheme* icon_theme;
+
+    if (*pixbuf)
+        g_object_unref (*pixbuf);
+
+    screen = gtk_widget_get_screen (GTK_WIDGET (throbber));
+    icon_theme = gtk_icon_theme_get_for_screen (screen);
+    *pixbuf = gtk_icon_theme_load_icon (icon_theme,
+                                        icon_name,
+                                        MAX (throbber->width, throbber->height),
+                                        (GtkIconLookupFlags) 0,
+                                        NULL);
+}
+
+static void
+icon_theme_changed (KatzeThrobber* throbber)
+{
+    if (throbber->icon_name)
+        pixbuf_assign_icon (&throbber->pixbuf,
+                            throbber->icon_name, throbber);
+
+    if (throbber->static_icon_name)
+        pixbuf_assign_icon (&throbber->static_pixbuf,
+                            throbber->static_icon_name, throbber);
+    else if (throbber->static_stock_id)
+        katze_object_assign (throbber->static_pixbuf,
+            gtk_widget_render_icon (GTK_WIDGET (throbber),
+                                    throbber->static_stock_id,
+                                    throbber->icon_size,
+                                    NULL));
+
+    g_object_freeze_notify (G_OBJECT (throbber));
+    g_object_notify (G_OBJECT (throbber), "pixbuf");
+    g_object_notify (G_OBJECT (throbber), "static-pixbuf");
+    g_object_thaw_notify (G_OBJECT (throbber));
+
+    gtk_widget_queue_draw (GTK_WIDGET (throbber));
+}
+
+static void
+katze_throbber_map (GtkWidget* widget)
+{
+    (*GTK_WIDGET_CLASS (katze_throbber_parent_class)->map) (widget);
+}
+
+static void
+katze_throbber_unmap (GtkWidget* widget)
+{
+    if (GTK_WIDGET_CLASS (katze_throbber_parent_class)->unmap)
+        GTK_WIDGET_CLASS (katze_throbber_parent_class)->unmap (widget);
+}
+
+static gboolean
+katze_throbber_timeout (KatzeThrobber*  throbber)
+{
+    throbber->index++;
+    gtk_widget_queue_draw (GTK_WIDGET (throbber));
+
+    return throbber->animated;
+}
+
+static void
+katze_throbber_timeout_destroy (KatzeThrobber*  throbber)
+{
+    throbber->index = 0;
+    throbber->timer_id = -1;
+}
+
+static void
+katze_throbber_style_set (GtkWidget* widget,
+                          GtkStyle*  prev_style)
+{
+    if (GTK_WIDGET_CLASS (katze_throbber_parent_class)->style_set)
+        GTK_WIDGET_CLASS (katze_throbber_parent_class)->style_set (widget,
+                                                                   prev_style);
+
+    icon_theme_changed (KATZE_THROBBER (widget));
+}
+
+static void
+katze_throbber_screen_changed (GtkWidget* widget,
+                               GdkScreen* prev_screen)
+{
+    if (GTK_WIDGET_CLASS (katze_throbber_parent_class)->screen_changed)
+        GTK_WIDGET_CLASS (katze_throbber_parent_class)->screen_changed (
+                                                        widget,
+                                                        prev_screen);
+
+    icon_theme_changed (KATZE_THROBBER (widget));
+}
+
+static void
+katze_throbber_size_request (GtkWidget*      widget,
+                             GtkRequisition* requisition)
+{
+    KatzeThrobber* throbber = KATZE_THROBBER (widget);
+
+    requisition->width = throbber->width;
+    requisition->height = throbber->height;
+
+    GTK_WIDGET_CLASS (katze_throbber_parent_class)->size_request (widget,
+                                                                  requisition);
+}
+
+static void
+katze_throbber_aligned_coords (GtkWidget* widget,
+                               gint*      ax,
+                               gint*      ay)
+{
+    gfloat xalign, yalign;
+    gint xpad, ypad;
+
+    gtk_misc_get_alignment (GTK_MISC (widget), &xalign, &yalign);
+    if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+        xalign = 1.0f - xalign;
+    gtk_misc_get_padding (GTK_MISC (widget), &xpad, &ypad);
+
+    *ax = floor (widget->allocation.x + xpad
+        + ((widget->allocation.width - widget->requisition.width) * xalign));
+    *ay = floor (widget->allocation.y + ypad
+        + ((widget->allocation.height - widget->requisition.height) * yalign));
+}
+
+static gboolean
+katze_throbber_expose_event (GtkWidget*      widget,
+                             GdkEventExpose* event)
+{
+    gint ax, ay;
+    KatzeThrobber* throbber = KATZE_THROBBER (widget);
+
+    if (G_UNLIKELY (!throbber->width || !throbber->height))
+        return TRUE;
+
+    if (G_UNLIKELY (!throbber->pixbuf && !throbber->static_pixbuf))
+        if (throbber->animated && !throbber->pixbuf && !throbber->icon_name)
+            return TRUE;
+
+    if (!throbber->animated && (throbber->static_pixbuf
+        || throbber->static_icon_name || throbber->static_stock_id))
+    {
+        if (G_UNLIKELY (!throbber->static_pixbuf && throbber->static_icon_name))
+        {
+            icon_theme_changed (KATZE_THROBBER (widget));
+
+            if (!throbber->static_pixbuf)
+            {
+                g_warning (_("Named icon '%s' couldn't be loaded"),
+                           throbber->static_icon_name);
+                katze_assign (throbber->static_icon_name, NULL);
+                g_object_notify (G_OBJECT (throbber), "static-icon-name");
+                return TRUE;
+            }
+        }
+        else if (G_UNLIKELY (!throbber->static_pixbuf && throbber->static_stock_id))
+        {
+            icon_theme_changed (KATZE_THROBBER (widget));
+
+            if (!throbber->static_pixbuf)
+            {
+                g_warning (_("Stock icon '%s' couldn't be loaded"),
+                           throbber->static_stock_id);
+                katze_assign (throbber->static_stock_id, NULL);
+                g_object_notify (G_OBJECT (throbber), "static-stock-id");
+                return TRUE;
+            }
+        }
+
+        katze_throbber_aligned_coords (widget, &ax, &ay);
+
+        gdk_draw_pixbuf (event->window, NULL, throbber->static_pixbuf,
+                         0, 0, ax, ay,
+                         throbber->width, throbber->height,
+                         GDK_RGB_DITHER_NONE, 0, 0);
+    }
+    else
+    {
+        if (G_UNLIKELY (throbber->icon_name && !throbber->pixbuf))
+        {
+            icon_theme_changed (KATZE_THROBBER (widget));
+
+            if (!throbber->pixbuf)
+            {
+                /* Fallback to a stock icon */
+                katze_assign (throbber->icon_name, g_strdup (GTK_STOCK_EXECUTE));
+                g_object_notify (G_OBJECT (throbber), "icon-name");
+                return TRUE;
+            }
+        }
+
+        gint cols = gdk_pixbuf_get_width (throbber->pixbuf) / throbber->width;
+        gint rows = gdk_pixbuf_get_height (throbber->pixbuf) / throbber->height;
+
+        if (G_UNLIKELY (cols == 1 && cols == rows))
+        {
+            katze_throbber_aligned_coords (widget, &ax, &ay);
+
+            if (throbber->animated)
+                gdk_draw_pixbuf (event->window, NULL, throbber->pixbuf,
+                                 0, 0, ax, ay,
+                                 throbber->width, throbber->height,
+                                 GDK_RGB_DITHER_NONE, 0, 0);
+            return TRUE;
+        }
+
+        if (G_LIKELY (cols > 0 && rows > 0))
+        {
+            gint idx;
+            guint x, y;
+
+            katze_throbber_aligned_coords (widget, &ax, &ay);
+
+            idx = throbber->index % (cols * rows);
+            if (G_LIKELY (throbber->timer_id >= 0))
+                idx = MAX (idx, 1);
+
+            x = (idx % cols) * throbber->width;
+            y = (idx / cols) * throbber->height;
+
+            gdk_draw_pixbuf (event->window, NULL, throbber->pixbuf,
+                             x, y, ax, ay,
+                             throbber->width, throbber->height,
+                             GDK_RGB_DITHER_NONE, 0, 0);
+        }
+        else
+        {
+            g_warning (_("Animation frames are broken"));
+            katze_assign (throbber->icon_name, NULL);
+            katze_object_assign (throbber->pixbuf, NULL);
+
+            g_object_freeze_notify (G_OBJECT (throbber));
+            g_object_notify (G_OBJECT (throbber), "icon-name");
+            g_object_notify (G_OBJECT (throbber), "pixbuf");
+            g_object_thaw_notify (G_OBJECT (throbber));
+        }
+    }
+
+    return TRUE;
+}
diff --git a/lib/katze-throbber.h b/lib/katze-throbber.h
new file mode 100644
index 0000000000000000000000000000000000000000..15ff20f90bcbcae7720a232b1b54f6f1edb9822a
--- /dev/null
+++ b/lib/katze-throbber.h
@@ -0,0 +1,112 @@
+/*  $Id$
+ *
+ *  Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ * 
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * */
+
+#ifndef __KATZE_THROBBER_H__
+#define __KATZE_THROBBER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define KATZE_TYPE_THROBBER \
+    (katze_throbber_get_type ())
+#define KATZE_THROBBER(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), KATZE_TYPE_THROBBER, KatzeThrobber))
+#define KATZE_THROBBER_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), KATZE_TYPE_THROBBER, KatzeThrobberClass))
+#define KATZE_IS_THROBBER(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KATZE_TYPE_THROBBER))
+#define KATZE_IS_THROBBER_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), KATZE_TYPE_THROBBER))
+#define KATZE_THROBBER_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), KATZE_TYPE_THROBBER, KatzeThrobberClass))
+
+typedef struct _KatzeThrobber                KatzeThrobber;
+typedef struct _KatzeThrobberPrivate         KatzeThrobberPrivate;
+typedef struct _KatzeThrobberClass           KatzeThrobberClass;
+
+struct _KatzeThrobberClass
+{
+    GtkMiscClass parent_class;
+
+    /* Padding for future expansion */
+    void (*_katze_reserved1) (void);
+    void (*_katze_reserved2) (void);
+    void (*_katze_reserved3) (void);
+    void (*_katze_reserved4) (void);
+};
+
+GType
+katze_throbber_get_type             (void);
+
+GtkWidget*
+katze_throbber_new                  (void);
+
+void
+katze_throbber_set_icon_size        (KatzeThrobber*   throbber,
+                                     GtkIconSize      icon_size);
+
+void
+katze_throbber_set_icon_name        (KatzeThrobber*   throbber,
+                                     const gchar*     icon_size);
+
+void
+katze_throbber_set_pixbuf           (KatzeThrobber*   throbber,
+                                     GdkPixbuf*       pixbuf);
+
+void
+katze_throbber_set_animated         (KatzeThrobber*   throbber,
+                                     gboolean         animated);
+
+void
+katze_throbber_set_static_icon_name (KatzeThrobber*   throbber,
+                                     const gchar*     icon_name);
+
+void
+katze_throbber_set_static_pixbuf    (KatzeThrobber*   throbber,
+                                     GdkPixbuf*       pixbuf);
+
+void
+katze_throbber_set_static_stock_id  (KatzeThrobber*   throbber,
+                                     const gchar*     stock_id);
+
+GtkIconSize
+katze_throbber_get_icon_size        (KatzeThrobber*   throbber);
+
+const gchar*
+katze_throbber_get_icon_name        (KatzeThrobber*   throbber);
+
+GdkPixbuf*
+katze_throbber_get_pixbuf           (KatzeThrobber*   throbber);
+
+gboolean
+katze_throbber_get_animated         (KatzeThrobber*   throbber);
+
+const gchar*
+katze_throbber_get_static_icon_name (KatzeThrobber    *throbber);
+
+GdkPixbuf*
+katze_throbber_get_static_pixbuf    (KatzeThrobber*   throbber);
+
+const gchar*
+katze_throbber_get_static_stock_id  (KatzeThrobber*   throbber);
+
+G_END_DECLS
+
+#endif /* __KATZE_THROBBER_H__ */
diff --git a/lib/screenshooter-zimagez.c b/lib/screenshooter-zimagez.c
index e4e5fc81d6cad56e2ac2a0b0c3710363f0952058..c9b014f3aa37b35e4717af4ef61119342e1fd6a2 100644
--- a/lib/screenshooter-zimagez.c
+++ b/lib/screenshooter-zimagez.c
@@ -1113,6 +1113,7 @@ void screenshooter_upload_to_zimagez (const gchar *image_path, gchar *last_user)
   ScreenshooterJob *job;
   GtkWidget *dialog;
   GtkWidget *label, *status_label;
+  GtkWidget *hbox, *throbber;
   GtkWidget *main_box, *main_alignment;
 
   g_return_if_fail (image_path != NULL);
@@ -1124,13 +1125,13 @@ void screenshooter_upload_to_zimagez (const gchar *image_path, gchar *last_user)
                                  NULL);
 
   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
-  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG(dialog)->vbox), 12);
+  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 0);
   gtk_window_set_deletable (GTK_WINDOW (dialog), FALSE);
   gtk_window_set_icon_name (GTK_WINDOW (dialog), "gtk-info");
 
   /* Create the main alignment for the dialog */
   main_alignment = gtk_alignment_new (0, 0, 1, 1);
-  gtk_alignment_set_padding (GTK_ALIGNMENT (main_alignment), 6, 0, 6, 6);
+  gtk_alignment_set_padding (GTK_ALIGNMENT (main_alignment), 0, 0, 6, 6);
   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_alignment, TRUE, TRUE, 0);
 
   /* Create the main box for the dialog */
@@ -1138,13 +1139,23 @@ void screenshooter_upload_to_zimagez (const gchar *image_path, gchar *last_user)
   gtk_container_set_border_width (GTK_CONTAINER (main_box), 12);
   gtk_container_add (GTK_CONTAINER (main_alignment), main_box);
 
+  /* Top horizontal box for the throbber */
+  hbox= gtk_hbox_new (FALSE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
+  gtk_container_add (GTK_CONTAINER (main_box), hbox);
+
+  /* Add the throbber */
+  throbber = katze_throbber_new ();
+  katze_throbber_set_animated (KATZE_THROBBER (throbber), TRUE);
+  gtk_box_pack_end (GTK_BOX (hbox), throbber, FALSE, FALSE, 0);
+
   /* Status label*/
   status_label = gtk_label_new ("");
   gtk_label_set_markup (GTK_LABEL (status_label),
                         _("<span weight=\"bold\" stretch=\"semiexpanded\">"
                           "Status</span>"));
   gtk_misc_set_alignment (GTK_MISC (status_label), 0, 0);
-  gtk_container_add (GTK_CONTAINER (main_box), status_label);
+  gtk_box_pack_start (GTK_BOX (hbox), status_label, FALSE, FALSE, 0);
 
   /* Information label */
   label = gtk_label_new ("");
diff --git a/lib/screenshooter-zimagez.h b/lib/screenshooter-zimagez.h
index 9df035c43b4e2336863ab8405b93499cb28af459..0b20cddf72871b3bfa5ce558cc933b72a5f31f52 100644
--- a/lib/screenshooter-zimagez.h
+++ b/lib/screenshooter-zimagez.h
@@ -33,7 +33,7 @@
 #include "screenshooter-utils.h"
 #include "screenshooter-simple-job.h"
 #include "sexy-url-label.h"
-
+#include "katze-throbber.h"
 
 void screenshooter_upload_to_zimagez (const gchar *image_path,
                                       gchar       *last_user);
diff --git a/po/ChangeLog b/po/ChangeLog
index 1da30ec1d580987c9ead2287a2f2d14e673733df..b1501d2f81be67fce410be615eb30e02a2ff285e 100644
--- a/po/ChangeLog
+++ b/po/ChangeLog
@@ -1,3 +1,7 @@
+2009-05-28 Jérôme Guelfucci <jeromeg@xfce.org>
+
+Fix a typo in the French translation.
+
 2009-05-28 Michal Várady <miko.vaji@gmail.com>
 
 	* cs.po: Czech translation updated
diff --git a/po/fr.po b/po/fr.po
index f20da938f7ba9ccf2041c00c87242b6d1799f613..fad10af88d31d46d8d53d90ca17460dd3068a01e 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -345,7 +345,7 @@ msgstr "BBCode pour les forums"
 
 #: ../lib/screenshooter-zimagez.c:1121
 msgid "ZimageZ"
-msgstr "ZimgeZ"
+msgstr "ZimageZ"
 
 #: ../lib/screenshooter-zimagez.c:1144
 msgid "<span weight=\"bold\" stretch=\"semiexpanded\">Status</span>"