[gitg] Make gitg work with gtk+ 2.18 again



commit b67f475d53619a67f4869bd5f1026cac045cca43
Author: Jesse van den Kieboom <jesse vandenkieboom epfl ch>
Date:   Mon Jun 7 09:28:37 2010 +0200

    Make gitg work with gtk+ 2.18 again

 configure.ac                  |   19 +-
 gitg/Makefile.am              |    5 +
 gitg/gitg-activatable.c       |   35 ++-
 gitg/gitg-commit-view.c       |    7 +-
 gitg/gitg-repository-dialog.c |  116 ++++++-
 gitg/gitg-repository.ui       |    9 +-
 gitg/gitg-revision-panel.c    |   31 ++-
 gitg/gitg-spinner.c           |  794 +++++++++++++++++++++++++++++++++++++++++
 gitg/gitg-spinner.h           |   99 +++++
 gitg/gitg-stat-view.c         |    1 +
 gitg/gitg-utils.c             |    2 +
 gitg/gitg-window.c            |    2 +
 gitg/gitg-window.ui           |    2 +-
 gitg/gseal-gtk-compat.h       |    2 +
 14 files changed, 1094 insertions(+), 30 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index db0f0ae..e8a45a1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,7 +51,7 @@ PKG_CHECK_EXISTS([gtk+-3.0 >= 2.90],
 			GTK_REQUIRED_VERSION=2.90.0
 		 ],[
 			GTK_REQUIRED=gtk+-2.0
-			GTK_REQUIRED_VERSION=2.20.0
+			GTK_REQUIRED_VERSION=2.18.0
 		 ])
 
 PKG_CHECK_MODULES(GITG, [
@@ -86,15 +86,28 @@ AC_ARG_ENABLE(deprecations,
 
 if test "$enable_deprecations" = "yes"; then
    DISABLE_DEPRECATED_CFLAGS="\
--DGSEAL_ENABLE \
 -DG_DISABLE_DEPRECATED \
 -DGDK_DISABLE_DEPRECATED \
 -DGTK_DISABLE_DEPRECATED \
 -DGDK_PIXBUF_DISABLE_DEPRECATED \
 -DGNOME_DISABLE_DEPRECATED"
-   AC_SUBST(DISABLE_DEPRECATED_CFLAGS)
 fi
 
+if $PKG_CONFIG --atleast-version 2.19.0 $GTK_REQUIRED; then
+	gtkatleast=
+else
+	gtkatleast=no
+fi
+
+AM_CONDITIONAL(BUILD_SPINNER, test "$gtkatleast" = "no")
+if test "$gtkatleast" = "no"; then
+	AC_DEFINE([BUILD_SPINNER],[1],[Whether to use GitgSpinner instead of GtkSpinner])
+else
+	DISABLE_DEPRECATED_CFLAGS="$DISABLE_DEPRECATED_CFLAGS -DGSEAL_ENABLE"
+fi
+
+AC_SUBST(DISABLE_DEPRECATED_CFLAGS)
+
 AC_SUBST(PACKAGE_CFLAGS)
 AC_SUBST(PACKAGE_LIBS)
 
diff --git a/gitg/Makefile.am b/gitg/Makefile.am
index 7ffb604..0cee607 100644
--- a/gitg/Makefile.am
+++ b/gitg/Makefile.am
@@ -63,6 +63,11 @@ gitg_SOURCES = 				\
 	gitg-window.c			\
 	$(NOINST_H_FILES)
 
+if BUILD_SPINNER
+gitg_SOURCES += gitg-spinner.c
+NOINST_H_FILES += gitg-spinner.h
+endif
+
 gitg_LDADD =		\
 	$(GITG_LIBS)	\
 	$(PACKAGE_LIBS) \
diff --git a/gitg/gitg-activatable.c b/gitg/gitg-activatable.c
index 644aaee..690deb3 100644
--- a/gitg/gitg-activatable.c
+++ b/gitg/gitg-activatable.c
@@ -1,6 +1,35 @@
 #include "gitg-activatable.h"
 
-G_DEFINE_INTERFACE (GitgActivatable, gitg_activatable, G_TYPE_INVALID)
+static void gitg_activatable_default_init (GitgActivatableInterface *iface);
+
+GType
+gitg_activatable_get_type ()
+{
+	static GType gitg_activatable_type_id = 0;
+	
+	if (!gitg_activatable_type_id)
+	{
+		static const GTypeInfo g_define_type_info =
+		{
+			sizeof (GitgActivatableInterface),
+			(GBaseInitFunc) gitg_activatable_default_init,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			0,
+			0,
+			NULL
+		};
+		
+		gitg_activatable_type_id = g_type_register_static (G_TYPE_INTERFACE,
+		                                                  "GitgActivatable",
+		                                                  &g_define_type_info,
+		                                                  0);
+	}
+
+	return gitg_activatable_type_id;
+}
 
 /* Default implementation */
 static gchar *
@@ -11,7 +40,7 @@ gitg_activatable_get_id_default (GitgActivatable *panel)
 
 static gboolean
 gitg_activatable_activate_default (GitgActivatable *panel,
-                                      gchar const       *cmd)
+				      gchar const       *cmd)
 {
 	return FALSE;
 }
@@ -40,7 +69,7 @@ gitg_activatable_get_id (GitgActivatable *panel)
 
 gboolean
 gitg_activatable_activate (GitgActivatable *panel,
-                           gchar const     *action)
+			   gchar const     *action)
 {
 	g_return_val_if_fail (GITG_IS_ACTIVATABLE (panel), FALSE);
 
diff --git a/gitg/gitg-commit-view.c b/gitg/gitg-commit-view.c
index f6998b1..7f53deb 100644
--- a/gitg/gitg-commit-view.c
+++ b/gitg/gitg-commit-view.c
@@ -32,6 +32,7 @@
 #include "gitg-preferences.h"
 #include "gitg-data-binding.h"
 #include "gitg-utils.h"
+#include "gseal-gtk-compat.h"
 
 #define GITG_COMMIT_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_COMMIT_VIEW, GitgCommitViewPrivate))
 #define CATEGORY_UNSTAGE_HUNK "CategoryUnstageHunk"
@@ -1677,10 +1678,14 @@ gitg_commit_view_set_repository(GitgCommitView *view, GitgRepository *repository
 	gtk_list_store_clear(view->priv->store_staged);
 
 	if (repository)
+	{
 		view->priv->repository = g_object_ref(repository);
+	}
 
-	if (gtk_widget_get_mapped(GTK_WIDGET(view)))
+	if (gtk_widget_get_mapped (GTK_WIDGET (view)))
+	{
 		initialize_commit(view);
+	}
 
 	g_object_notify(G_OBJECT(view), "repository");
 }
diff --git a/gitg/gitg-repository-dialog.c b/gitg/gitg-repository-dialog.c
index 2d0276a..c1dc6ac 100644
--- a/gitg/gitg-repository-dialog.c
+++ b/gitg/gitg-repository-dialog.c
@@ -28,6 +28,14 @@
 #include "gitg-repository-dialog.h"
 #include "gitg-utils.h"
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef BUILD_SPINNER
+#include "gitg-spinner.h"
+#endif
+
 void on_button_fetch_remote_clicked (GtkButton *button,
                                      GitgRepositoryDialog *dialog);
 
@@ -64,7 +72,8 @@ enum
 	COLUMN_NAME,
 	COLUMN_URL,
 	COLUMN_FETCH,
-	COLUMN_PULSE
+	COLUMN_PULSE,
+	COLUMN_SPINNER
 };
 
 struct _GitgRepositoryDialogPrivate
@@ -93,7 +102,12 @@ typedef struct
 	GitgRepositoryDialog *dialog;
 	GitgRunner *runner;
 	GtkTreeRowReference *reference;
+
+#ifdef BUILD_SPINNER
+	GitgSpinner *spinner;
+#else
 	guint pulse_id;
+#endif
 } FetchInfo;
 
 static void
@@ -110,6 +124,13 @@ fetch_cleanup (FetchInfo *info)
 		                         &iter,
 		                         path);
 
+#ifdef BUILD_SPINNER
+		gtk_list_store_set (info->dialog->priv->list_store_remotes,
+		                    &iter,
+		                    COLUMN_SPINNER, NULL,
+		                    -1);
+#endif
+
 		gtk_list_store_set (info->dialog->priv->list_store_remotes,
 		                    &iter,
 		                    COLUMN_FETCH, FALSE,
@@ -118,7 +139,14 @@ fetch_cleanup (FetchInfo *info)
 		gtk_tree_path_free (path);
 	}
 
+#ifdef BUILD_SPINNER
+	if (info->spinner)
+	{
+		g_object_unref (info->spinner);
+	}
+#else
 	g_source_remove (info->pulse_id);
+#endif
 
 	gtk_tree_row_reference_free (info->reference);
 	g_object_unref (info->runner);
@@ -193,9 +221,10 @@ update_fetch (GitgRepositoryDialog *dialog)
 	{
 		GtkTreePath *path = (GtkTreePath *)item->data;
 		GtkTreeIter iter;
-		gboolean fetch;
 
 		gtk_tree_model_get_iter (model, &iter, path);
+
+		gboolean fetch;
 		gtk_tree_model_get (model, &iter, COLUMN_FETCH, &fetch, -1);
 
 		if (!fetch)
@@ -250,15 +279,35 @@ add_remote (GitgRepositoryDialog *dialog, gchar const *name, gchar const *url, G
 	GtkTreeIter it;
 
 	gtk_list_store_append (dialog->priv->list_store_remotes, iter ? iter : &it);
-	gtk_list_store_set (dialog->priv->list_store_remotes, 
+	gtk_list_store_set (dialog->priv->list_store_remotes,
 	                    iter ? iter : &it,
 	                    COLUMN_NAME, name,
 	                    COLUMN_URL, url,
 	                    COLUMN_FETCH, FALSE,
 	                    COLUMN_PULSE, 0,
+	                    COLUMN_SPINNER, NULL,
 	                    -1);
 }
 
+#ifdef BUILD_SPINNER
+static void
+on_spinner_frame (GitgSpinner *spinner, GdkPixbuf *pixbuf, FetchInfo *info)
+{
+	GtkTreeIter iter;
+	GtkTreePath *path = gtk_tree_row_reference_get_path (info->reference);
+
+	gtk_tree_model_get_iter (GTK_TREE_MODEL (info->dialog->priv->list_store_remotes),
+	                         &iter,
+	                         path);
+
+	gtk_list_store_set (info->dialog->priv->list_store_remotes,
+	                    &iter,
+	                    COLUMN_SPINNER, pixbuf,
+	                    -1);
+
+	gtk_tree_path_free (path);
+}
+#else
 static gboolean
 pulse_row (FetchInfo *info)
 {
@@ -276,7 +325,7 @@ pulse_row (FetchInfo *info)
 	                    COLUMN_FETCH, &fetch,
 	                    COLUMN_PULSE, &pulse,
 	                    -1);
-	
+
 	if (fetch)
 	{
 		gtk_list_store_set (info->dialog->priv->list_store_remotes,
@@ -284,11 +333,12 @@ pulse_row (FetchInfo *info)
 			            COLUMN_PULSE, pulse + 1,
 			            -1);
 	}
-	
+
 	gtk_tree_path_free (path);
 
 	return fetch;
 }
+#endif
 
 static void
 on_fetch_begin_loading (GitgRunner *runner, FetchInfo *info)
@@ -305,6 +355,13 @@ on_fetch_begin_loading (GitgRunner *runner, FetchInfo *info)
 	                    COLUMN_FETCH, TRUE,
 	                    -1);
 
+#ifdef BUILD_SPINNER
+	info->spinner = gitg_spinner_new (GTK_ICON_SIZE_MENU);
+	gitg_spinner_set_screen (info->spinner, gtk_widget_get_screen (GTK_WIDGET (info->dialog)));
+
+	g_signal_connect (info->spinner, "frame", G_CALLBACK (on_spinner_frame), info);
+	gitg_spinner_start (info->spinner);
+#else
 	GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (info->dialog->priv->tree_view_remotes));
 
 	GValue cycle_duration = {0,};
@@ -323,9 +380,9 @@ on_fetch_begin_loading (GitgRunner *runner, FetchInfo *info)
 
 	g_value_unset (&cycle_duration);
 	g_value_unset (&num_steps);
+#endif
 
 	gtk_tree_path_free (path);
-
 	update_fetch (info->dialog);
 }
 
@@ -359,10 +416,10 @@ fetch_remote (GitgRepositoryDialog *dialog, GtkTreeIter *iter)
 	info->reference = gtk_tree_row_reference_new (model, path);
 	info->runner = runner;
 
-	gtk_tree_path_free (path); 
+	gtk_tree_path_free (path);
 
-	g_signal_connect (runner, 
-	                  "begin-loading", 
+	g_signal_connect (runner,
+	                  "begin-loading",
 	                  G_CALLBACK (on_fetch_begin_loading),
 	                  info);
 
@@ -458,6 +515,7 @@ init_properties(GitgRepositoryDialog *dialog)
 	init_remotes(dialog);
 }
 
+#ifndef BUILD_SPINNER
 static void
 fetch_data_spinner_cb (GtkTreeViewColumn    *column,
                        GtkCellRenderer      *cell,
@@ -479,6 +537,7 @@ fetch_data_spinner_cb (GtkTreeViewColumn    *column,
 	              "pulse", pulse,
 	              NULL);
 }
+#endif
 
 static void
 fetch_data_icon_cb (GtkTreeViewColumn    *column,
@@ -487,6 +546,21 @@ fetch_data_icon_cb (GtkTreeViewColumn    *column,
                     GtkTreeIter          *iter,
                     GitgRepositoryDialog *dialog)
 {
+#ifdef BUILD_SPINNER
+	GdkPixbuf *fetch;
+
+	gtk_tree_model_get (model, iter, COLUMN_SPINNER, &fetch, -1);
+
+	if (fetch)
+	{
+		g_object_set (cell, "pixbuf", fetch, NULL);
+		g_object_unref (fetch);
+	}
+	else
+	{
+		g_object_set (cell, "stock-id", GTK_STOCK_NETWORK, NULL);
+	}
+#else
 	gboolean fetch;
 
 	gtk_tree_model_get (model, iter, COLUMN_FETCH, &fetch, -1);
@@ -494,6 +568,7 @@ fetch_data_icon_cb (GtkTreeViewColumn    *column,
 	g_object_set (G_OBJECT (cell),
 	              "visible", !fetch,
 	              NULL);
+#endif
 }
 
 
@@ -526,13 +601,20 @@ create_repository_dialog (GitgWindow *window)
 	repository_dialog->priv->image_fetch_remote = GTK_IMAGE(gtk_builder_get_object(b, "image_fetch_remote"));
 
 	GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (b, "tree_view_remotes_column_name"));
-	GtkCellRenderer *spinner_renderer = GTK_CELL_RENDERER (gtk_builder_get_object (b, "tree_view_remotes_renderer_spinner"));
+
+#ifndef BUILD_SPINNER
+	GtkCellRenderer *spinner_renderer = gtk_cell_renderer_spinner_new ();
+	g_object_set (spinner_renderer, "visible", FALSE, NULL);
+
+	gtk_tree_view_column_pack_start (column, spinner_renderer, FALSE);
+	gtk_cell_layout_reorder (GTK_CELL_LAYOUT (column), spinner_renderer, 1);
 
 	gtk_tree_view_column_set_cell_data_func (column,
 	                                         spinner_renderer,
 	                                         (GtkTreeCellDataFunc)fetch_data_spinner_cb,
 	                                         repository_dialog,
 	                                         NULL);
+#endif
 
 	GtkCellRenderer *icon_renderer = GTK_CELL_RENDERER (gtk_builder_get_object (b, "tree_view_remotes_renderer_icon"));
 	gtk_tree_view_column_set_cell_data_func (column,
@@ -560,10 +642,12 @@ create_repository_dialog (GitgWindow *window)
 }
 
 GitgRepositoryDialog *
-gitg_repository_dialog_present(GitgWindow *window)
+gitg_repository_dialog_present (GitgWindow *window)
 {
 	if (!repository_dialog)
+	{
 		create_repository_dialog(window);
+	}
 
 	gtk_window_set_transient_for(GTK_WINDOW(repository_dialog), GTK_WINDOW (window));
 	gtk_window_present(GTK_WINDOW(repository_dialog));
@@ -581,7 +665,8 @@ gitg_repository_dialog_close (void)
 }
 
 static void
-fetch_remote_cancel (GitgRepositoryDialog *dialog, GtkTreeIter *iter)
+fetch_remote_cancel (GitgRepositoryDialog *dialog,
+                     GtkTreeIter          *iter)
 {
 	GList *item;
 	GtkTreePath *orig;
@@ -608,7 +693,8 @@ fetch_remote_cancel (GitgRepositoryDialog *dialog, GtkTreeIter *iter)
 }
 
 void
-on_button_fetch_remote_clicked (GtkButton *button, GitgRepositoryDialog *dialog)
+on_button_fetch_remote_clicked (GtkButton            *button,
+                                GitgRepositoryDialog *dialog)
 {
 	GtkTreeSelection *selection;
 	GtkTreeModel *model;
@@ -809,9 +895,9 @@ on_remote_name_edited (GtkCellRendererText *renderer,
 	gchar *oldname;
 	gchar *url;
 
-	gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->list_store_remotes), 
+	gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->list_store_remotes),
 	                    &iter,
-	                    COLUMN_NAME, &oldname, 
+	                    COLUMN_NAME, &oldname,
 	                    COLUMN_URL, &url,
 	                    -1);
 
diff --git a/gitg/gitg-repository.ui b/gitg/gitg-repository.ui
index ef8f192..b619954 100644
--- a/gitg/gitg-repository.ui
+++ b/gitg/gitg-repository.ui
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <interface>
-  <requires lib="gtk+" version="2.20"/>
+  <requires lib="gtk+" version="2.18"/>
   <!-- interface-requires gitg 0.2 -->
   <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkListStore" id="list_store_remotes">
@@ -13,6 +13,8 @@
       <column type="gboolean"/>
       <!-- column-name pulse -->
       <column type="gint"/>
+       <!-- column-name spinner -->
+      <column type="GdkPixbuf"/>
     </columns>
   </object>
   <object class="GitgRepositoryDialog" id="dialog_repository">
@@ -58,11 +60,6 @@
                               </object>
                             </child>
                             <child>
-                              <object class="GtkCellRendererSpinner" id="tree_view_remotes_renderer_spinner">
-                                <property name="visible">False</property>
-                              </object>
-                            </child>
-                            <child>
                               <object class="GtkCellRendererText" id="tree_view_remotes_renderer_name">
                                 <property name="editable">True</property>
                                 <signal name="edited" handler="on_remote_name_edited"/>
diff --git a/gitg/gitg-revision-panel.c b/gitg/gitg-revision-panel.c
index 2812a8d..565e186 100644
--- a/gitg/gitg-revision-panel.c
+++ b/gitg/gitg-revision-panel.c
@@ -1,6 +1,35 @@
 #include "gitg-revision-panel.h"
 
-G_DEFINE_INTERFACE (GitgRevisionPanel, gitg_revision_panel, G_TYPE_INVALID)
+static void gitg_revision_panel_default_init (GitgRevisionPanelInterface *iface);
+
+GType
+gitg_revision_panel_get_type ()
+{
+	static GType gitg_revision_panel_type_id = 0;
+	
+	if (!gitg_revision_panel_type_id)
+	{
+		static const GTypeInfo g_define_type_info =
+		{
+			sizeof (GitgRevisionPanelInterface),
+			(GBaseInitFunc) gitg_revision_panel_default_init,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			0,
+			0,
+			NULL
+		};
+		
+		gitg_revision_panel_type_id = g_type_register_static (G_TYPE_INTERFACE,
+		                                                      "GitgRevisionPanel",
+		                                                      &g_define_type_info,
+		                                                      0);
+	}
+
+	return gitg_revision_panel_type_id;
+}
 
 /* Default implementation */
 static void
diff --git a/gitg/gitg-spinner.c b/gitg/gitg-spinner.c
new file mode 100644
index 0000000..912bc24
--- /dev/null
+++ b/gitg/gitg-spinner.c
@@ -0,0 +1,794 @@
+/*
+ * gitg-spinner.c
+ * This file is part of gitg
+ *
+ * Copyright (C) 2009 - Jesse van den kieboom
+ * Copyright (C) 2005 - Paolo Maggi 
+ * Copyright (C) 2002-2004 Marco Pesenti Gritti
+ * Copyright (C) 2004 Christian Persch
+ * Copyright (C) 2000 - Eazel, Inc. 
+ *
+ * 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 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.
+ */
+ 
+/*
+ * This widget was originally written by Andy Hertzfeld <andy eazel com> for
+ * Nautilus. It was then modified by Marco Pesenti Gritti and Christian Persch
+ * for Epiphany.
+ *
+ * Modified by the gitg Team, 2005. See the AUTHORS file for a 
+ * list of people on the gitg Team.
+ * See the ChangeLog files for a list of changes. 
+ *
+ * Modified by the gitg team, 2009.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gitg-spinner.h"
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+/* Spinner cache implementation */
+
+#define GITG_TYPE_SPINNER_CACHE		(gitg_spinner_cache_get_type())
+#define GITG_SPINNER_CACHE(object)		(G_TYPE_CHECK_INSTANCE_CAST((object), GITG_TYPE_SPINNER_CACHE, GitgSpinnerCache))
+#define GITG_SPINNER_CACHE_CLASS(klass) 	(G_TYPE_CHECK_CLASS_CAST((klass), GITG_TYPE_SPINNER_CACHE, GitgSpinnerCacheClass))
+#define GITG_IS_SPINNER_CACHE(object)		(G_TYPE_CHECK_INSTANCE_TYPE((object), GITG_TYPE_SPINNER_CACHE))
+#define GITG_IS_SPINNER_CACHE_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), GITG_TYPE_SPINNER_CACHE))
+#define GITG_SPINNER_CACHE_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), GITG_TYPE_SPINNER_CACHE, GitgSpinnerCacheClass))
+
+typedef struct _GitgSpinnerCache		GitgSpinnerCache;
+typedef struct _GitgSpinnerCacheClass		GitgSpinnerCacheClass;
+typedef struct _GitgSpinnerCachePrivate	GitgSpinnerCachePrivate;
+
+struct _GitgSpinnerCacheClass
+{
+	GObjectClass parent_class;
+};
+
+struct _GitgSpinnerCache
+{
+	GObject parent_object;
+
+	/*< private >*/
+	GitgSpinnerCachePrivate *priv;
+};
+
+#define GITG_SPINNER_CACHE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GITG_TYPE_SPINNER_CACHE, GitgSpinnerCachePrivate))
+
+struct _GitgSpinnerCachePrivate
+{
+	/* Hash table of GdkScreen -> GitgSpinnerCacheData */
+	GHashTable *hash;
+};
+
+typedef struct
+{
+	guint        ref_count;
+	GtkIconSize  size;
+	gint         width;
+	gint         height;
+	GdkPixbuf  **animation_pixbufs;
+	guint        n_animation_pixbufs;
+} GitgSpinnerImages;
+
+#define LAST_ICON_SIZE			GTK_ICON_SIZE_DIALOG + 1
+#define SPINNER_ICON_NAME		"process-working"
+#define SPINNER_FALLBACK_ICON_NAME	"gnome-spinner"
+#define GITG_SPINNER_IMAGES_INVALID	((GitgSpinnerImages *) 0x1)
+
+typedef struct
+{
+	GdkScreen          *screen;
+	GtkIconTheme       *icon_theme;
+	GitgSpinnerImages  *images[LAST_ICON_SIZE];
+} GitgSpinnerCacheData;
+
+static void gitg_spinner_cache_class_init	(GitgSpinnerCacheClass *klass);
+static void gitg_spinner_cache_init		(GitgSpinnerCache      *cache);
+
+static GObjectClass *gitg_spinner_cache_parent_class;
+
+static GType
+gitg_spinner_cache_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0))
+	{
+		const GTypeInfo our_info =
+		{
+			sizeof (GitgSpinnerCacheClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) gitg_spinner_cache_class_init,
+			NULL,
+			NULL,
+			sizeof (GitgSpinnerCache),
+			0,
+			(GInstanceInitFunc) gitg_spinner_cache_init
+		};
+
+		type = g_type_register_static (G_TYPE_OBJECT,
+					       "GitgSpinnerCache",
+					       &our_info, 0);
+	}
+
+	return type;
+}
+
+static GitgSpinnerImages *
+gitg_spinner_images_ref (GitgSpinnerImages *images)
+{
+	g_return_val_if_fail (images != NULL, NULL);
+
+	images->ref_count++;
+
+	return images;
+}
+
+static void
+gitg_spinner_images_unref (GitgSpinnerImages *images)
+{
+	g_return_if_fail (images != NULL);
+
+	images->ref_count--;
+
+	if (images->ref_count == 0)
+	{
+		guint i;
+
+		/* LOG ("Freeing spinner images %p for size %d", images, images->size); */
+
+		for (i = 0; i < images->n_animation_pixbufs; ++i)
+		{
+			g_object_unref (images->animation_pixbufs[i]);
+		}
+
+		g_free (images->animation_pixbufs);
+		g_free (images);
+	}
+}
+
+static void
+gitg_spinner_cache_data_unload (GitgSpinnerCacheData *data)
+{
+	GtkIconSize size;
+	GitgSpinnerImages *images;
+
+	g_return_if_fail (data != NULL);
+
+	/* LOG ("GitgSpinnerDataCache unload for screen %p", data->screen); */
+
+	for (size = GTK_ICON_SIZE_INVALID; size < LAST_ICON_SIZE; ++size)
+	{
+		images = data->images[size];
+		data->images[size] = NULL;
+
+		if (images != NULL && images != GITG_SPINNER_IMAGES_INVALID)
+		{
+			gitg_spinner_images_unref (images);
+		}
+	}
+}
+
+static GdkPixbuf *
+extract_frame (GdkPixbuf *grid_pixbuf,
+	       int x,
+	       int y,
+	       int size)
+{
+	GdkPixbuf *pixbuf;
+
+	if (x + size > gdk_pixbuf_get_width (grid_pixbuf) ||
+	    y + size > gdk_pixbuf_get_height (grid_pixbuf))
+	{
+		return NULL;
+	}
+
+	pixbuf = gdk_pixbuf_new_subpixbuf (grid_pixbuf,
+					   x, y,
+					   size, size);
+	g_return_val_if_fail (pixbuf != NULL, NULL);
+
+	return pixbuf;
+}
+
+static GdkPixbuf *
+scale_to_size (GdkPixbuf *pixbuf,
+	       int dw,
+	       int dh)
+{
+	GdkPixbuf *result;
+	int pw, ph;
+
+	g_return_val_if_fail (pixbuf != NULL, NULL);
+
+	pw = gdk_pixbuf_get_width (pixbuf);
+	ph = gdk_pixbuf_get_height (pixbuf);
+
+	if (pw != dw || ph != dh)
+	{
+		result = gdk_pixbuf_scale_simple (pixbuf, dw, dh,
+						  GDK_INTERP_BILINEAR);
+		g_object_unref (pixbuf);
+		return result;
+	}
+
+	return pixbuf;
+}
+
+static GitgSpinnerImages *
+gitg_spinner_images_load (GdkScreen    *screen,
+                          GtkIconTheme *icon_theme,
+                          GtkIconSize   icon_size)
+{
+	GitgSpinnerImages *images;
+	GdkPixbuf *icon_pixbuf, *pixbuf;
+	GtkIconInfo *icon_info = NULL;
+	int grid_width, grid_height, x, y, requested_size, size, isw, ish, n;
+	const char *icon;
+	GSList *list = NULL, *l;
+
+	/* LOG ("GitgSpinnerCacheData loading for screen %p at size %d", screen, icon_size); */
+
+	/* START_PROFILER ("loading spinner animation") */
+
+	if (screen == NULL)
+		screen = gdk_screen_get_default ();
+
+	if (!gtk_icon_size_lookup_for_settings (gtk_settings_get_for_screen (screen),
+						icon_size, &isw, &ish))
+		goto loser;
+ 
+	requested_size = MAX (ish, isw);
+
+	/* Load the animation. The 'rest icon' is the 0th frame */
+	icon_info = gtk_icon_theme_lookup_icon (icon_theme,
+						SPINNER_ICON_NAME,
+						requested_size, 0);
+
+	if (icon_info == NULL)
+	{
+		g_warning ("Throbber animation not found");
+
+		/* If the icon naming spec compliant name wasn't found, try the old name */
+		icon_info = gtk_icon_theme_lookup_icon (icon_theme,
+							SPINNER_FALLBACK_ICON_NAME,
+						        requested_size, 0);
+		if (icon_info == NULL)
+		{
+			g_warning ("Throbber fallback animation not found either");
+			goto loser;
+	 	}
+	}
+
+	g_assert (icon_info != NULL);
+
+	size = gtk_icon_info_get_base_size (icon_info);
+	icon = gtk_icon_info_get_filename (icon_info);
+
+	if (icon == NULL)
+		goto loser;
+
+	icon_pixbuf = gdk_pixbuf_new_from_file (icon, NULL);
+	gtk_icon_info_free (icon_info);
+	icon_info = NULL;
+
+	if (icon_pixbuf == NULL)
+	{
+		g_warning ("Could not load the spinner file");
+		goto loser;
+	}
+
+	grid_width = gdk_pixbuf_get_width (icon_pixbuf);
+	grid_height = gdk_pixbuf_get_height (icon_pixbuf);
+
+	n = 0;
+	for (y = 0; y < grid_height; y += size)
+	{
+		for (x = 0; x < grid_width ; x += size)
+		{
+			pixbuf = extract_frame (icon_pixbuf, x, y, size);
+
+			if (pixbuf)
+			{
+				list = g_slist_prepend (list, pixbuf);
+				++n;
+			}
+			else
+			{
+				g_warning ("Cannot extract frame (%d, %d) from the grid\n", x, y);
+			}
+		}
+	}
+
+	g_object_unref (icon_pixbuf);
+
+	if (list == NULL)
+		goto loser;
+
+	/* g_assert (n > 0); */
+
+	if (size > requested_size)
+	{
+		for (l = list; l != NULL; l = l->next)
+		{
+			l->data = scale_to_size (l->data, isw, ish);
+		}
+ 	}
+
+	/* Now we've successfully got all the data */
+	images = g_new (GitgSpinnerImages, 1);
+	images->ref_count = 1;
+ 
+	images->size = icon_size;
+	images->width = images->height = requested_size;
+
+	images->n_animation_pixbufs = n;
+	images->animation_pixbufs = g_new (GdkPixbuf *, n);
+
+	for (l = list; l != NULL; l = l->next)
+	{
+		g_assert (l->data != NULL);
+		images->animation_pixbufs[--n] = l->data;
+	}
+	g_assert (n == 0);
+
+	g_slist_free (list);
+
+	/* STOP_PROFILER ("loading spinner animation") */
+	return images;
+ 
+loser:
+	if (icon_info)
+	{
+		gtk_icon_info_free (icon_info);
+ 	}
+
+	g_slist_foreach (list, (GFunc) g_object_unref, NULL);
+
+	/* STOP_PROFILER ("loading spinner animation") */
+
+	return NULL;
+}
+
+static GitgSpinnerCacheData *
+gitg_spinner_cache_data_new (GdkScreen *screen)
+{
+	GitgSpinnerCacheData *data;
+
+	data = g_new0 (GitgSpinnerCacheData, 1);
+
+	data->screen = screen;
+	data->icon_theme = gtk_icon_theme_get_for_screen (screen);
+
+	g_signal_connect_swapped (data->icon_theme,
+				  "changed",
+				  G_CALLBACK (gitg_spinner_cache_data_unload),
+				  data);
+
+	return data;
+}
+
+static void
+gitg_spinner_cache_data_free (GitgSpinnerCacheData *data)
+{
+	g_return_if_fail (data != NULL);
+	g_return_if_fail (data->icon_theme != NULL);
+
+	g_signal_handlers_disconnect_by_func (data->icon_theme,
+					      G_CALLBACK (gitg_spinner_cache_data_unload),
+					      data);
+
+	gitg_spinner_cache_data_unload (data);
+
+	g_free (data);
+}
+
+static GitgSpinnerImages *
+gitg_spinner_cache_get_images (GitgSpinnerCache *cache,
+                               GdkScreen        *screen,
+                               GtkIconSize       icon_size)
+{
+	GitgSpinnerCachePrivate *priv = cache->priv;
+	GitgSpinnerCacheData *data;
+	GitgSpinnerImages *images;
+
+	g_return_val_if_fail (icon_size >= 0 && icon_size < LAST_ICON_SIZE, NULL);
+
+	data = g_hash_table_lookup (priv->hash, screen);
+
+	if (data == NULL)
+	{
+		data = gitg_spinner_cache_data_new (screen);
+
+		/* FIXME: think about what happens when the screen's display is closed later on */
+		g_hash_table_insert (priv->hash, screen, data);
+	}
+
+	images = data->images[icon_size];
+
+	if (images == GITG_SPINNER_IMAGES_INVALID)
+	{
+		/* Load failed, but don't try endlessly again! */
+		return NULL;
+	}
+
+	if (images != NULL)
+	{
+		/* Return cached data */
+		return gitg_spinner_images_ref (images);
+	}
+
+	images = gitg_spinner_images_load (screen, data->icon_theme, icon_size);
+
+	if (images == NULL)
+ 	{
+		/* Mark as failed-to-load */
+		data->images[icon_size] = GITG_SPINNER_IMAGES_INVALID;
+ 
+		return NULL;
+ 	}
+
+	data->images[icon_size] = images;
+
+	return gitg_spinner_images_ref (images);
+}
+
+static void
+gitg_spinner_cache_init (GitgSpinnerCache *cache)
+{
+	GitgSpinnerCachePrivate *priv;
+
+	priv = cache->priv = GITG_SPINNER_CACHE_GET_PRIVATE (cache);
+
+	/* LOG ("GitgSpinnerCache initialising"); */
+
+	priv->hash = g_hash_table_new_full (g_direct_hash,
+					    g_direct_equal,
+					    NULL,
+					    (GDestroyNotify) gitg_spinner_cache_data_free);
+}
+
+static void
+gitg_spinner_cache_finalize (GObject *object)
+{
+	GitgSpinnerCache *cache = GITG_SPINNER_CACHE (object); 
+	GitgSpinnerCachePrivate *priv = cache->priv;
+
+	g_hash_table_destroy (priv->hash);
+
+	/* LOG ("GitgSpinnerCache finalised"); */
+
+	G_OBJECT_CLASS (gitg_spinner_cache_parent_class)->finalize (object);
+}
+
+static void
+gitg_spinner_cache_class_init (GitgSpinnerCacheClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	gitg_spinner_cache_parent_class = g_type_class_peek_parent (klass);
+
+	object_class->finalize = gitg_spinner_cache_finalize;
+
+	g_type_class_add_private (object_class, sizeof (GitgSpinnerCachePrivate));
+}
+
+static GitgSpinnerCache *spinner_cache = NULL;
+
+static GitgSpinnerCache *
+gitg_spinner_cache_ref (void)
+{
+	if (spinner_cache == NULL)
+	{
+		GitgSpinnerCache **cache_ptr;
+
+		spinner_cache = g_object_new (GITG_TYPE_SPINNER_CACHE, NULL);
+		cache_ptr = &spinner_cache;
+		g_object_add_weak_pointer (G_OBJECT (spinner_cache),
+					   (gpointer *) cache_ptr);
+
+		return spinner_cache;
+	}
+
+	return g_object_ref (spinner_cache);
+}
+
+/* Spinner implementation */
+
+#define SPINNER_TIMEOUT 50 /* ms */
+
+#define GITG_SPINNER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GITG_TYPE_SPINNER, GitgSpinnerPrivate))
+
+struct _GitgSpinnerPrivate
+{
+	GdkScreen          *screen;
+	GitgSpinnerCache   *cache;
+	GtkIconSize         size;
+	GitgSpinnerImages  *images;
+	guint               current_image;
+	guint               timeout;
+	guint               timer_task;
+	guint               spinning : 1;
+	guint               need_load : 1;
+};
+
+enum
+{
+	FRAME,
+	NUM_SIGNALS
+};
+
+static guint spinner_signals[NUM_SIGNALS] = {0,};
+
+static void gitg_spinner_class_init	(GitgSpinnerClass *class);
+static void gitg_spinner_init		(GitgSpinner      *spinner);
+
+static GObjectClass *parent_class;
+
+GType
+gitg_spinner_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0))
+	{
+		const GTypeInfo our_info =
+		{
+			sizeof (GitgSpinnerClass),
+			NULL, /* base_init */
+			NULL, /* base_finalize */
+			(GClassInitFunc) gitg_spinner_class_init,
+			NULL,
+			NULL, /* class_data */
+			sizeof (GitgSpinner),
+			0, /* n_preallocs */
+			(GInstanceInitFunc) gitg_spinner_init
+		};
+
+		type = g_type_register_static (G_TYPE_OBJECT,
+					       "GitgSpinner",
+					       &our_info, 0);
+	}
+
+	return type;
+}
+
+static gboolean
+gitg_spinner_load_images (GitgSpinner *spinner)
+{
+	GitgSpinnerPrivate *priv = spinner->priv;
+
+	if (priv->need_load)
+	{
+		priv->images = gitg_spinner_cache_get_images (priv->cache, priv->screen, priv->size);
+
+		priv->current_image = 0; /* 'rest' icon */
+		priv->need_load = FALSE;
+	}
+
+	return priv->images != NULL;
+}
+
+static void
+gitg_spinner_unload_images (GitgSpinner *spinner)
+{
+	GitgSpinnerPrivate *priv = spinner->priv;
+
+	if (priv->images != NULL)
+	{
+		gitg_spinner_images_unref (priv->images);
+		priv->images = NULL;
+	}
+
+	priv->current_image = 0;
+	priv->need_load = TRUE;
+}
+
+static void
+gitg_spinner_init (GitgSpinner *spinner)
+{
+	spinner->priv = GITG_SPINNER_GET_PRIVATE (spinner);
+
+	spinner->priv->cache = gitg_spinner_cache_ref ();
+	spinner->priv->size = GTK_ICON_SIZE_MENU;
+	spinner->priv->timeout = SPINNER_TIMEOUT;
+	spinner->priv->need_load = TRUE;
+}
+
+static gboolean
+bump_spinner_frame_cb (GitgSpinner *spinner)
+{
+	GitgSpinnerPrivate *priv = spinner->priv;
+
+	/* This can happen when we've unloaded the images on a theme
+	 * change, but haven't been in the queued size request yet.
+	 * Just skip this update.
+	 */
+	if (priv->images == NULL)
+	{
+		if (!gitg_spinner_load_images (spinner))
+		{
+			return FALSE;
+		}
+	}
+
+	priv->current_image++;
+
+	if (priv->current_image >= priv->images->n_animation_pixbufs)
+	{
+		/* the 0th frame is the 'rest' icon */
+		priv->current_image = MIN (1, priv->images->n_animation_pixbufs);
+	}
+
+	g_signal_emit (spinner, spinner_signals[FRAME], 0, priv->images->animation_pixbufs[priv->current_image]);
+
+	/* run again */
+	return TRUE;
+}
+
+/**
+ * gitg_spinner_start:
+ * @spinner: a #GitgSpinner
+ *
+ * Start the spinner animation.
+ **/
+void
+gitg_spinner_start (GitgSpinner *spinner)
+{
+	GitgSpinnerPrivate *priv = spinner->priv;
+
+	priv->spinning = TRUE;
+
+	if (priv->timer_task == 0 && gitg_spinner_load_images (spinner))
+	{
+		/* the 0th frame is the 'rest' icon */
+		priv->current_image = MIN (0, priv->images->n_animation_pixbufs);
+
+		priv->timer_task = g_timeout_add_full (G_PRIORITY_LOW,
+						       priv->timeout,
+						       (GSourceFunc) bump_spinner_frame_cb,
+						       spinner,
+						       NULL);
+
+		bump_spinner_frame_cb (spinner);
+	}
+}
+
+static void
+gitg_spinner_remove_update_callback (GitgSpinner *spinner)
+{
+	GitgSpinnerPrivate *priv = spinner->priv;
+
+	if (priv->timer_task != 0)
+	{
+		g_source_remove (priv->timer_task);
+		priv->timer_task = 0;
+	}
+}
+
+/**
+ * gitg_spinner_stop:
+ * @spinner: a #GitgSpinner
+ *
+ * Stop the spinner animation.
+ **/
+void
+gitg_spinner_stop (GitgSpinner *spinner)
+{
+	GitgSpinnerPrivate *priv = spinner->priv;
+
+	priv->spinning = FALSE;
+	priv->current_image = 0;
+
+	if (priv->timer_task != 0)
+	{
+		gitg_spinner_remove_update_callback (spinner);
+	}
+}
+
+void
+gitg_spinner_set_screen (GitgSpinner *spinner, GdkScreen *screen)
+{
+	g_return_if_fail (GITG_IS_SPINNER (spinner));
+	g_return_if_fail (GDK_IS_SCREEN (screen));
+
+	if (spinner->priv->screen != screen)
+	{
+		gitg_spinner_unload_images (spinner);
+
+		if (spinner->priv->screen)
+		{
+			g_object_unref (spinner->priv->screen);
+		}
+
+		spinner->priv->screen = g_object_ref (screen);
+	}
+}
+
+static void
+gitg_spinner_dispose (GObject *object)
+{
+	//GitgSpinner *spinner = GITG_SPINNER (object);
+
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gitg_spinner_finalize (GObject *object)
+{
+	GitgSpinner *spinner = GITG_SPINNER (object);
+
+	gitg_spinner_remove_update_callback (spinner);
+	gitg_spinner_unload_images (spinner);
+
+	g_object_unref (spinner->priv->cache);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gitg_spinner_class_init (GitgSpinnerClass *class)
+{
+	GObjectClass *object_class =  G_OBJECT_CLASS (class);
+
+	parent_class = g_type_class_peek_parent (class);
+
+	object_class->dispose = gitg_spinner_dispose;
+	object_class->finalize = gitg_spinner_finalize;
+
+	spinner_signals[FRAME] =
+   		g_signal_new ("frame",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (GitgSpinnerClass, frame),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__OBJECT,
+			      G_TYPE_NONE,
+			      1,
+			      GDK_TYPE_PIXBUF);
+
+	g_type_class_add_private (object_class, sizeof (GitgSpinnerPrivate));
+}
+
+GitgSpinner *
+gitg_spinner_new (GtkIconSize size)
+{
+	GitgSpinner *spinner = g_object_new (GITG_TYPE_SPINNER, NULL);
+
+	spinner->priv->size = size;
+	return spinner;
+}
+
+GdkPixbuf *
+gitg_spinner_get_pixbuf (GitgSpinner *spinner)
+{
+	g_return_val_if_fail (GITG_IS_SPINNER (spinner), NULL);
+
+	if (spinner->priv->timer_task == 0)
+	{
+		return NULL;
+	}
+
+	return g_object_ref (spinner->priv->images->animation_pixbufs[spinner->priv->current_image]);
+}
diff --git a/gitg/gitg-spinner.h b/gitg/gitg-spinner.h
new file mode 100644
index 0000000..b3d4e44
--- /dev/null
+++ b/gitg/gitg-spinner.h
@@ -0,0 +1,99 @@
+/*
+ * gitg-spinner.h
+ * This file is part of gitg
+ *
+ * Copyright (C) 2009 - Jesse van den Kieboom
+ * Copyright (C) 2005 - Paolo Maggi 
+ * Copyright (C) 2000 - Eazel, Inc. 
+ *
+ * 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 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.
+ */
+ 
+/*
+ * This widget was originally written by Andy Hertzfeld <andy eazel com> for
+ * Nautilus.
+ *
+ * Modified by the gitg Team, 2005. See the AUTHORS file for a 
+ * list of people on the gitg Team.
+ * See the ChangeLog files for a list of changes. 
+ *
+ * Modified by the gitg Team, 2009
+ *
+ * $Id$
+ */
+
+#ifndef __GITG_SPINNER_H__
+#define __GITG_SPINNER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GITG_TYPE_SPINNER		(gitg_spinner_get_type ())
+#define GITG_SPINNER(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GITG_TYPE_SPINNER, GitgSpinner))
+#define GITG_SPINNER_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), GITG_TYPE_SPINNER, GitgSpinnerClass))
+#define GITG_IS_SPINNER(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GITG_TYPE_SPINNER))
+#define GITG_IS_SPINNER_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GITG_TYPE_SPINNER))
+#define GITG_SPINNER_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GITG_TYPE_SPINNER, GitgSpinnerClass))
+
+
+/* Private structure type */
+typedef struct _GitgSpinnerPrivate	GitgSpinnerPrivate;
+
+/*
+ * Main object structure
+ */
+typedef struct _GitgSpinner		GitgSpinner;
+
+struct _GitgSpinner
+{
+	GObject parent;
+
+	/*< private >*/
+	GitgSpinnerPrivate *priv;
+};
+
+/*
+ * Class definition
+ */
+typedef struct _GitgSpinnerClass	GitgSpinnerClass;
+
+struct _GitgSpinnerClass
+{
+	GObjectClass parent_class;
+
+	void (*frame)(GitgSpinner *spinner, GdkPixbuf *pixbuf);
+};
+
+/*
+ * Public methods
+ */
+GType			gitg_spinner_get_type	(void) G_GNUC_CONST;
+
+GitgSpinner	   *gitg_spinner_new		(GtkIconSize  size);
+void 			gitg_spinner_set_screen (GitgSpinner *spinner, 
+										 GdkScreen   *screen);
+void			gitg_spinner_start		(GitgSpinner  *spinner);
+void			gitg_spinner_stop		(GitgSpinner  *spinner);
+
+GdkPixbuf      *gitg_spinner_get_pixbuf (GitgSpinner *spinner);
+
+G_END_DECLS
+
+#endif /* __GITG_SPINNER_H__ */
diff --git a/gitg/gitg-stat-view.c b/gitg/gitg-stat-view.c
index a04f9b2..d9c54cc 100644
--- a/gitg/gitg-stat-view.c
+++ b/gitg/gitg-stat-view.c
@@ -3,6 +3,7 @@
 #include "gitg-utils.h"
 #include <math.h>
 #include <cairo.h>
+#include "gseal-gtk-compat.h"
 
 #define GITG_STAT_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_STAT_VIEW, GitgStatViewPrivate))
 
diff --git a/gitg/gitg-utils.c b/gitg/gitg-utils.c
index 61df5ac..edfe6ae 100644
--- a/gitg/gitg-utils.c
+++ b/gitg/gitg-utils.c
@@ -28,6 +28,8 @@
 #include <string.h>
 #include <math.h>
 
+#include "gseal-gtk-compat.h"
+
 gchar *
 gitg_utils_get_content_type(GFile *file)
 {
diff --git a/gitg/gitg-window.c b/gitg/gitg-window.c
index 25eed6b..a500528 100644
--- a/gitg/gitg-window.c
+++ b/gitg/gitg-window.c
@@ -50,6 +50,8 @@
 #include "gitg-activatable.h"
 #include "gitg-uri.h"
 
+#include "gseal-gtk-compat.h"
+
 #define DYNAMIC_ACTION_DATA_KEY "GitgDynamicActionDataKey"
 #define DYNAMIC_ACTION_DATA_REMOTE_KEY "GitgDynamicActionDataRemoteKey"
 #define DYNAMIC_ACTION_DATA_BRANCH_KEY "GitgDynamicActionDataBranchKey"
diff --git a/gitg/gitg-window.ui b/gitg/gitg-window.ui
index b84e092..842de54 100644
--- a/gitg/gitg-window.ui
+++ b/gitg/gitg-window.ui
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <interface>
-  <!-- interface-requires gtk+ 2.20 -->
+  <!-- interface-requires gtk+ 2.18 -->
   <!-- interface-requires gitg 0.0.6 -->
   <!-- interface-requires sourceview2 0.0 -->
   <!-- interface-naming-policy toplevel-contextual -->
diff --git a/gitg/gseal-gtk-compat.h b/gitg/gseal-gtk-compat.h
index 789174b..8d34e62 100644
--- a/gitg/gseal-gtk-compat.h
+++ b/gitg/gseal-gtk-compat.h
@@ -25,6 +25,8 @@ G_BEGIN_DECLS
 
 #if !GTK_CHECK_VERSION (2, 21, 0)
 #define gdk_drag_context_list_targets(context)		((context)->targets)
+#define gtk_widget_get_mapped(widget)			(GTK_WIDGET_MAPPED ((widget)))
+#define gtk_widget_get_realized(widget)			(GTK_WIDGET_REALIZED ((widget)))
 #endif /* GTK < 2.22.0 */
 
 G_END_DECLS



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