Protect ensure_valid_themes() from recursion, which can happen for example

2007-03-15  Chris Wilson  <chris@chris-wilson.co.uk>

	* gtk/gtkicontheme.c (ensure_valid_themes), (rescan_themes),
	(gtk_icon_theme_rescan_if_needed): Protect ensure_valid_themes()
	from recursion, which can happen for example if the app tries to
	reload an icon from within a theme-changed handler. (#418531)


svn path=/trunk/; revision=17523
This commit is contained in:
Chris Wilson 2007-03-15 18:40:16 +00:00 committed by Chris Wilson
parent 47b6f2c2eb
commit 0b1c9b7cc2
2 changed files with 79 additions and 46 deletions

View File

@ -1,3 +1,10 @@
2007-03-15 Chris Wilson <chris@chris-wilson.co.uk>
* gtk/gtkicontheme.c (ensure_valid_themes), (rescan_themes),
(gtk_icon_theme_rescan_if_needed): Protect ensure_valid_themes()
from recursion, which can happen for example if the app tries to
reload an icon from within a theme-changed handler. (#418531)
2007-03-15 Richard Hult <richard@imendio.com>
* gdk/quartz/gdkmain-quartz.c: Add stubs for

View File

@ -73,6 +73,7 @@ struct _GtkIconThemePrivate
guint pixbuf_supports_svg : 1;
guint themes_valid : 1;
guint check_reload : 1;
guint loading_themes : 1;
char *current_theme;
char *fallback_theme;
@ -206,6 +207,7 @@ static void theme_subdir_load (GtkIconTheme *icon_theme,
static void do_theme_change (GtkIconTheme *icon_theme);
static void blow_themes (GtkIconTheme *icon_themes);
static gboolean rescan_themes (GtkIconTheme *icon_themes);
static void icon_data_free (GtkIconData *icon_data);
static void load_icon_data (IconThemeDir *dir,
@ -1176,21 +1178,30 @@ ensure_valid_themes (GtkIconTheme *icon_theme)
GTimeVal tv;
gboolean was_valid = priv->themes_valid;
if (priv->loading_themes)
return;
priv->loading_themes = TRUE;
_gtk_icon_theme_ensure_builtin_cache ();
if (priv->themes_valid)
{
g_get_current_time (&tv);
if (ABS (tv.tv_sec - priv->last_stat_time) > 5)
gtk_icon_theme_rescan_if_needed (icon_theme);
if (ABS (tv.tv_sec - priv->last_stat_time) > 5 &&
rescan_themes (icon_theme))
blow_themes (icon_theme);
}
if (!priv->themes_valid)
{
load_themes (icon_theme);
if (!priv->check_reload && was_valid && priv->screen)
if (was_valid)
{
g_signal_emit (icon_theme, signal_changed, 0);
if (!priv->check_reload && priv->screen)
{
static GdkAtom atom_iconthemes = GDK_NONE;
GdkEvent *event = gdk_event_new (GDK_CLIENT_EVENT);
@ -1207,6 +1218,9 @@ ensure_valid_themes (GtkIconTheme *icon_theme)
gdk_screen_broadcast_client_message (priv->screen, event);
}
}
}
priv->loading_themes = FALSE;
}
/**
@ -1673,21 +1687,9 @@ gtk_icon_theme_get_example_icon_name (GtkIconTheme *icon_theme)
return NULL;
}
/**
* gtk_icon_theme_rescan_if_needed:
* @icon_theme: a #GtkIconTheme
*
* Checks to see if the icon theme has changed; if it has, any
* currently cached information is discarded and will be reloaded
* next time @icon_theme is accessed.
*
* Return value: %TRUE if the icon theme has changed and needed
* to be reloaded.
*
* Since: 2.4
**/
gboolean
gtk_icon_theme_rescan_if_needed (GtkIconTheme *icon_theme)
static gboolean
rescan_themes (GtkIconTheme *icon_theme)
{
GtkIconThemePrivate *priv;
IconThemeDirMtime *dir_mtime;
@ -1696,8 +1698,6 @@ gtk_icon_theme_rescan_if_needed (GtkIconTheme *icon_theme)
struct stat stat_buf;
GTimeVal tv;
g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), FALSE);
priv = icon_theme->priv;
for (d = priv->dir_mtimes; d != NULL; d = d->next)
@ -1716,7 +1716,6 @@ gtk_icon_theme_rescan_if_needed (GtkIconTheme *icon_theme)
(stat_res != 0 || !S_ISDIR (stat_buf.st_mode)))
continue;
do_theme_change (icon_theme);
return TRUE;
}
@ -1726,6 +1725,33 @@ gtk_icon_theme_rescan_if_needed (GtkIconTheme *icon_theme)
return FALSE;
}
/**
* gtk_icon_theme_rescan_if_needed:
* @icon_theme: a #GtkIconTheme
*
* Checks to see if the icon theme has changed; if it has, any
* currently cached information is discarded and will be reloaded
* next time @icon_theme is accessed.
*
* Return value: %TRUE if the icon theme has changed and needed
* to be reloaded.
*
* Since: 2.4
**/
gboolean
gtk_icon_theme_rescan_if_needed (GtkIconTheme *icon_theme)
{
gboolean retval;
g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), FALSE);
retval = rescan_themes (icon_theme);
if (retval)
do_theme_change (icon_theme);
return retval;
}
static void
theme_destroy (IconTheme *theme)
{