X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkicontheme.c;h=c79826c2adb2079e66357b57e6a4027b6be1e79e;hb=7c2a752b3724ad9ac88b7abfecc63e4e0eb7eb54;hp=f2e9f6c1c0173485bbf9fdb8b3571438b83b1f96;hpb=7690846c3f18ff94c4d1213f722cab102cd7506a;p=~andy%2Fgtk diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c index f2e9f6c1c..c79826c2a 100644 --- a/gtk/gtkicontheme.c +++ b/gtk/gtkicontheme.c @@ -109,7 +109,7 @@ * or stock items, rather than directly, but looking up icons * directly is also simple. The #GtkIconTheme object acts * as a database of all the icons in the current theme. You - * can create new #GtkIconTheme objects, but its much more + * can create new #GtkIconTheme objects, but it's much more * efficient to use the standard icon theme for the #GdkScreen * so that the icon information is shared with other people * looking up icons. In the case where the default screen is @@ -1444,7 +1444,7 @@ ensure_lru_cache_space (GtkIconTheme *icon_theme) g_list_length (priv->info_cache_lru))); priv->info_cache_lru = g_list_delete_link (priv->info_cache_lru, l); - gtk_icon_info_free (icon_info); + g_object_unref (icon_info); } } @@ -1465,7 +1465,7 @@ add_to_lru_cache (GtkIconTheme *icon_theme, ensure_lru_cache_space (icon_theme); /* prepend new info to LRU */ priv->info_cache_lru = g_list_prepend (priv->info_cache_lru, - gtk_icon_info_copy (icon_info)); + g_object_ref (icon_info)); } static void @@ -1500,7 +1500,7 @@ remove_from_lru_cache (GtkIconTheme *icon_theme, g_list_length (priv->info_cache_lru))); priv->info_cache_lru = g_list_remove (priv->info_cache_lru, icon_info); - gtk_icon_info_free (icon_info); + g_object_unref (icon_info); } } @@ -1614,7 +1614,7 @@ choose_icon (GtkIconTheme *icon_theme, icon_info->key.size, icon_info->key.flags, g_hash_table_size (priv->info_cache))); - icon_info = gtk_icon_info_copy (icon_info); + icon_info = g_object_ref (icon_info); remove_from_lru_cache (icon_theme, icon_info); return icon_info; @@ -1778,9 +1778,8 @@ choose_icon (GtkIconTheme *icon_theme, * gtk_icon_info_load_icon(). (gtk_icon_theme_load_icon() * combines these two steps if all you need is the pixbuf.) * - * Return value: a #GtkIconInfo structure containing information - * about the icon, or %NULL if the icon wasn't found. Free with - * gtk_icon_info_free() + * Return value: (transfer full): a #GtkIconInfo object containing information + * about the icon, or %NULL if the icon wasn't found. * * Since: 2.4 */ @@ -1856,9 +1855,8 @@ gtk_icon_theme_lookup_icon (GtkIconTheme *icon_theme, * tries them all in the given order before falling back to * inherited icon themes. * - * Return value: a #GtkIconInfo structure containing information - * about the icon, or %NULL if the icon wasn't found. Free with - * gtk_icon_info_free() + * Return value: (transfer full): a #GtkIconInfo object containing information + * about the icon, or %NULL if the icon wasn't found. * * Since: 2.12 */ @@ -1939,7 +1937,7 @@ gtk_icon_theme_load_icon (GtkIconTheme *icon_theme, } pixbuf = gtk_icon_info_load_icon (icon_info, error); - gtk_icon_info_free (icon_info); + g_object_unref (icon_info); return pixbuf; } @@ -3029,6 +3027,8 @@ icon_info_dup (GtkIconInfo *icon_info) dup->icon_file = g_object_ref (icon_info->icon_file); if (icon_info->loadable) dup->loadable = g_object_ref (icon_info->loadable); + if (icon_info->pixbuf) + dup->pixbuf = g_object_ref (icon_info->pixbuf); for (l = icon_info->emblem_infos; l != NULL; l = l->next) { @@ -3066,7 +3066,7 @@ icon_info_new_builtin (BuiltinIcon *icon) } /** - * gtk_icon_info_copy: + * gtk_icon_info_copy: (skip) * @icon_info: a #GtkIconInfo * * Make a copy of a #GtkIconInfo. @@ -3074,6 +3074,8 @@ icon_info_new_builtin (BuiltinIcon *icon) * Return value: the new GtkIconInfo * * Since: 2.4 + * + * Deprecated: 3.8: Use g_object_ref() **/ GtkIconInfo * gtk_icon_info_copy (GtkIconInfo *icon_info) @@ -3085,12 +3087,14 @@ gtk_icon_info_copy (GtkIconInfo *icon_info) } /** - * gtk_icon_info_free: + * gtk_icon_info_free: (skip) * @icon_info: a #GtkIconInfo * * Free a #GtkIconInfo and associated information * * Since: 2.4 + * + * Deprecated: 3.8: Use g_object_unref() **/ void gtk_icon_info_free (GtkIconInfo *icon_info) @@ -3115,7 +3119,7 @@ gtk_icon_info_finalize (GObject *object) if (icon_info->loadable) g_object_unref (icon_info->loadable); - g_slist_free_full (icon_info->emblem_infos, (GDestroyNotify) gtk_icon_info_free); + g_slist_free_full (icon_info->emblem_infos, (GDestroyNotify) g_object_unref); if (icon_info->pixbuf) g_object_unref (icon_info->pixbuf); if (icon_info->cache_pixbuf) @@ -3507,7 +3511,7 @@ proxy_pixbuf_destroy (guchar *pixels, gpointer data) if (icon_theme != NULL) ensure_in_lru_cache (icon_theme, icon_info); - gtk_icon_info_free (icon_info); + g_object_unref (icon_info); } /** @@ -3574,7 +3578,7 @@ gtk_icon_info_load_icon (GtkIconInfo *icon_info, gdk_pixbuf_get_height (icon_info->pixbuf), gdk_pixbuf_get_rowstride (icon_info->pixbuf), proxy_pixbuf_destroy, - gtk_icon_info_copy (icon_info)); + g_object_ref (icon_info)); return icon_info->proxy_pixbuf; } @@ -3736,7 +3740,7 @@ proxy_symbolic_pixbuf_destroy (guchar *pixels, gpointer data) if (icon_theme != NULL) ensure_in_lru_cache (icon_theme, icon_info); - gtk_icon_info_free (icon_info); + g_object_unref (icon_info); } static GdkPixbuf * @@ -3755,7 +3759,7 @@ symbolic_cache_get_proxy (SymbolicPixbufCache *symbolic_cache, gdk_pixbuf_get_height (symbolic_cache->pixbuf), gdk_pixbuf_get_rowstride (symbolic_cache->pixbuf), proxy_symbolic_pixbuf_destroy, - gtk_icon_info_copy (icon_info)); + g_object_ref (icon_info)); return symbolic_cache->proxy_pixbuf; } @@ -3766,7 +3770,8 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info, const GdkRGBA *success_color, const GdkRGBA *warning_color, const GdkRGBA *error_color, - GError **error) + gboolean use_cache, + GError **error) { GInputStream *stream; GdkPixbuf *pixbuf; @@ -3778,10 +3783,13 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info, gchar *width, *height, *uri; SymbolicPixbufCache *symbolic_cache; - symbolic_cache = symbolic_pixbuf_cache_matches (icon_info->symbolic_pixbuf_cache, - fg, success_color, warning_color, error_color); - if (symbolic_cache) - return symbolic_cache_get_proxy (symbolic_cache, icon_info); + if (use_cache) + { + symbolic_cache = symbolic_pixbuf_cache_matches (icon_info->symbolic_pixbuf_cache, + fg, success_color, warning_color, error_color); + if (symbolic_cache) + return symbolic_cache_get_proxy (symbolic_cache, icon_info); + } /* css_fg can't possibly have failed, otherwise * that would mean we have a broken style */ @@ -3882,11 +3890,16 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info, if (pixbuf != NULL) { - icon_info->symbolic_pixbuf_cache = - symbolic_pixbuf_cache_new (pixbuf, fg, success_color, warning_color, error_color, - icon_info->symbolic_pixbuf_cache); - - return symbolic_cache_get_proxy (icon_info->symbolic_pixbuf_cache, icon_info); + if (use_cache) + { + icon_info->symbolic_pixbuf_cache = + symbolic_pixbuf_cache_new (pixbuf, fg, success_color, warning_color, error_color, + icon_info->symbolic_pixbuf_cache); + g_object_unref (pixbuf); + return symbolic_cache_get_proxy (icon_info->symbolic_pixbuf_cache, icon_info); + } + else + return pixbuf; } return NULL; @@ -3960,6 +3973,7 @@ gtk_icon_info_load_symbolic (GtkIconInfo *icon_info, return _gtk_icon_info_load_symbolic_internal (icon_info, fg, success_color, warning_color, error_color, + TRUE, error); } @@ -4046,9 +4060,332 @@ gtk_icon_info_load_symbolic_for_context (GtkIconInfo *icon_info, return _gtk_icon_info_load_symbolic_internal (icon_info, fgp, success_colorp, warning_colorp, error_colorp, + TRUE, error); } +typedef struct { + gboolean is_symbolic; + GtkIconInfo *dup; + GdkRGBA fg; + gboolean fg_set; + GdkRGBA success_color; + gboolean success_color_set; + GdkRGBA warning_color; + gboolean warning_color_set; + GdkRGBA error_color; + gboolean error_color_set; +} AsyncSymbolicData; + +static void +async_symbolic_data_free (AsyncSymbolicData *data) +{ + if (data->dup) + g_object_unref (data->dup); + g_slice_free (AsyncSymbolicData, data); +} + +static void +async_load_no_symbolic_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GtkIconInfo *icon_info = GTK_ICON_INFO (source_object); + GTask *task = user_data; + GError *error = NULL; + GdkPixbuf *pixbuf; + + pixbuf = gtk_icon_info_load_icon_finish (icon_info, res, &error); + if (pixbuf == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, pixbuf, g_object_unref); + g_object_unref (task); +} + +static void +load_symbolic_icon_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + AsyncSymbolicData *data = task_data; + GError *error; + GdkPixbuf *pixbuf; + + error = NULL; + pixbuf = + _gtk_icon_info_load_symbolic_internal (data->dup, + data->fg_set ? &data->fg : NULL, + data->success_color_set ? &data->success_color : NULL, + data->warning_color_set ? &data->warning_color : NULL, + data->error_color_set ? &data->error_color : NULL, + FALSE, + &error); + if (pixbuf == NULL) + g_task_return_error (task, error); + else + g_task_return_pointer (task, pixbuf, g_object_unref); +} + +/** + * gtk_icon_info_load_symbolic_async: + * @icon_info: a #GtkIconInfo structure from gtk_icon_theme_lookup_icon() + * @fg: a #GdkRGBA representing the foreground color of the icon + * @success_color: (allow-none): a #GdkRGBA representing the warning color + * of the icon or %NULL to use the default color + * @warning_color: (allow-none): a #GdkRGBA representing the warning color + * of the icon or %NULL to use the default color + * @error_color: (allow-none): a #GdkRGBA representing the error color + * of the icon or %NULL to use the default color (allow-none) + * @cancellable: (allow-none): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call when the + * request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously load, render and scale a symbolic icon previously looked up + * from the icon theme using gtk_icon_theme_lookup_icon(). + * + * For more details, see gtk_icon_info_load_symbolic() which is the synchronous + * version of this call. + * + * Since: 3.8 + **/ +void +gtk_icon_info_load_symbolic_async (GtkIconInfo *icon_info, + const GdkRGBA *fg, + const GdkRGBA *success_color, + const GdkRGBA *warning_color, + const GdkRGBA *error_color, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + AsyncSymbolicData *data; + gchar *icon_uri; + SymbolicPixbufCache *symbolic_cache; + GdkPixbuf *pixbuf; + + g_return_if_fail (icon_info != NULL); + g_return_if_fail (fg != NULL); + + task = g_task_new (icon_info, cancellable, callback, user_data); + + data = g_slice_new0 (AsyncSymbolicData); + g_task_set_task_data (task, data, (GDestroyNotify) async_symbolic_data_free); + + icon_uri = NULL; + if (icon_info->icon_file) + icon_uri = g_file_get_uri (icon_info->icon_file); + + data->is_symbolic = (icon_uri != NULL) && (g_str_has_suffix (icon_uri, "-symbolic.svg")); + g_free (icon_uri); + + if (!data->is_symbolic) + { + gtk_icon_info_load_icon_async (icon_info, cancellable, async_load_no_symbolic_cb, g_object_ref (task)); + } + else + { + symbolic_cache = symbolic_pixbuf_cache_matches (icon_info->symbolic_pixbuf_cache, + fg, success_color, warning_color, error_color); + if (symbolic_cache) + { + pixbuf = symbolic_cache_get_proxy (symbolic_cache, icon_info); + g_task_return_pointer (task, pixbuf, g_object_unref); + } + else + { + if (fg) + { + data->fg = *fg; + data->fg_set = TRUE; + } + + if (success_color) + { + data->success_color = *success_color; + data->success_color_set = TRUE; + } + + if (warning_color) + { + data->warning_color = *warning_color; + data->warning_color_set = TRUE; + } + + if (error_color) + { + data->error_color = *error_color; + data->error_color_set = TRUE; + } + + data->dup = icon_info_dup (icon_info); + g_task_run_in_thread (task, load_symbolic_icon_thread); + } + } + g_object_unref (task); +} + +/** + * gtk_icon_info_load_symbolic_finish: + * @icon_info: a #GtkIconInfo structure from gtk_icon_theme_lookup_icon() + * @res: a #GAsyncResult + * @was_symbolic: (out) (allow-none): a #gboolean, returns whether the + * loaded icon was a symbolic one and whether the @fg color was + * applied to it. + * @error: (allow-none): location to store error information on failure, + * or %NULL. + * + * Finishes an async icon load, see gtk_icon_info_load_symbolic_async(). + * + * Return value: (transfer full): the rendered icon; this may be a newly + * created icon or a new reference to an internal icon, so you must + * not modify the icon. Use g_object_unref() to release your reference + * to the icon. + * + * Since: 3.8 + **/ +GdkPixbuf * +gtk_icon_info_load_symbolic_finish (GtkIconInfo *icon_info, + GAsyncResult *result, + gboolean *was_symbolic, + GError **error) +{ + GTask *task = G_TASK (result); + AsyncSymbolicData *data = g_task_get_task_data (task); + SymbolicPixbufCache *symbolic_cache; + GdkPixbuf *pixbuf; + + if (was_symbolic) + *was_symbolic = data->is_symbolic; + + if (data->dup && !g_task_had_error (task)) + { + pixbuf = g_task_propagate_pointer (task, NULL); + + g_assert (pixbuf != NULL); /* we checked for !had_error above */ + + symbolic_cache = symbolic_pixbuf_cache_matches (icon_info->symbolic_pixbuf_cache, + data->fg_set ? &data->fg : NULL, + data->success_color_set ? &data->success_color : NULL, + data->warning_color_set ? &data->warning_color : NULL, + data->error_color_set ? &data->error_color : NULL); + + if (symbolic_cache == NULL) + { + symbolic_cache = icon_info->symbolic_pixbuf_cache = + symbolic_pixbuf_cache_new (pixbuf, + data->fg_set ? &data->fg : NULL, + data->success_color_set ? &data->success_color : NULL, + data->warning_color_set ? &data->warning_color : NULL, + data->error_color_set ? &data->error_color : NULL, + icon_info->symbolic_pixbuf_cache); + } + + g_object_unref (pixbuf); + + return symbolic_cache_get_proxy (symbolic_cache, icon_info); + } + + return g_task_propagate_pointer (task, error); +} + +/** + * gtk_icon_info_load_symbolic_for_context_async: + * @icon_info: a #GtkIconInfo structure from gtk_icon_theme_lookup_icon() + * @context: a #GtkStyleContext + * @cancellable: (allow-none): optional #GCancellable object, + * %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call when the + * request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously load, render and scale a symbolic icon previously looked up + * from the icon theme using gtk_icon_theme_lookup_icon(). + * + * For more details, see gtk_icon_info_load_symbolic_for_context() which is the synchronous + * version of this call. + * + * Since: 3.8 + **/ +void +gtk_icon_info_load_symbolic_for_context_async (GtkIconInfo *icon_info, + GtkStyleContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GdkRGBA *color = NULL; + GdkRGBA fg; + GdkRGBA *fgp; + GdkRGBA success_color; + GdkRGBA *success_colorp; + GdkRGBA warning_color; + GdkRGBA *warning_colorp; + GdkRGBA error_color; + GdkRGBA *error_colorp; + GtkStateFlags state; + + g_return_if_fail (icon_info != NULL); + g_return_if_fail (context != NULL); + + fgp = success_colorp = warning_colorp = error_colorp = NULL; + + state = gtk_style_context_get_state (context); + gtk_style_context_get (context, state, "color", &color, NULL); + if (color) + { + fg = *color; + fgp = &fg; + gdk_rgba_free (color); + } + + if (gtk_style_context_lookup_color (context, "success_color", &success_color)) + success_colorp = &success_color; + + if (gtk_style_context_lookup_color (context, "warning_color", &warning_color)) + warning_colorp = &warning_color; + + if (gtk_style_context_lookup_color (context, "error_color", &error_color)) + error_colorp = &error_color; + + gtk_icon_info_load_symbolic_async (icon_info, + fgp, success_colorp, + warning_colorp, error_colorp, + cancellable, callback, user_data); +} + +/** + * gtk_icon_info_load_symbolic_for_context_finish: + * @icon_info: a #GtkIconInfo structure from gtk_icon_theme_lookup_icon() + * @res: a #GAsyncResult + * @was_symbolic: (out) (allow-none): a #gboolean, returns whether the + * loaded icon was a symbolic one and whether the @fg color was + * applied to it. + * @error: (allow-none): location to store error information on failure, + * or %NULL. + * + * Finishes an async icon load, see gtk_icon_info_load_symbolic_for_context_async(). + * + * Return value: (transfer full): the rendered icon; this may be a newly + * created icon or a new reference to an internal icon, so you must + * not modify the icon. Use g_object_unref() to release your reference + * to the icon. + * + * Since: 3.8 + **/ +GdkPixbuf * +gtk_icon_info_load_symbolic_for_context_finish (GtkIconInfo *icon_info, + GAsyncResult *result, + gboolean *was_symbolic, + GError **error) +{ + return gtk_icon_info_load_symbolic_finish (icon_info, result, was_symbolic, error); +} + static GdkRGBA * color_to_rgba (GdkColor *color, GdkRGBA *rgba) { @@ -4134,6 +4471,7 @@ gtk_icon_info_load_symbolic_for_style (GtkIconInfo *icon_info, return _gtk_icon_info_load_symbolic_internal (icon_info, &fg, success_colorp, warning_colorp, error_colorp, + TRUE, error); } @@ -4496,9 +4834,9 @@ _gtk_icon_theme_check_reload (GdkDisplay *display) * The icon can then be rendered into a pixbuf using * gtk_icon_info_load_icon(). * - * Return value: a #GtkIconInfo structure containing + * Return value: (transfer full): a #GtkIconInfo structure containing * information about the icon, or %NULL if the icon - * wasn't found. Free with gtk_icon_info_free() + * wasn't found. Unref with g_object_unref() * * Since: 2.14 */ @@ -4549,15 +4887,18 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme, { GIcon *base, *emblem; GList *list, *l; - GtkIconInfo *emblem_info; + GtkIconInfo *base_info, *emblem_info; if (GTK_IS_NUMERABLE_ICON (icon)) _gtk_numerable_icon_set_background_icon_size (GTK_NUMERABLE_ICON (icon), size / 2); base = g_emblemed_icon_get_icon (G_EMBLEMED_ICON (icon)); - info = gtk_icon_theme_lookup_by_gicon (icon_theme, base, size, flags); - if (info) + base_info = gtk_icon_theme_lookup_by_gicon (icon_theme, base, size, flags); + if (base_info) { + info = icon_info_dup (base_info); + g_object_unref (base_info); + list = g_emblemed_icon_get_emblems (G_EMBLEMED_ICON (icon)); for (l = list; l; l = l->next) { @@ -4567,9 +4908,11 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme, if (emblem_info) info->emblem_infos = g_slist_prepend (info->emblem_infos, emblem_info); } - } - return info; + return info; + } + else + return NULL; } else if (GDK_IS_PIXBUF (icon)) { @@ -4615,7 +4958,7 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme, * * Creates a #GtkIconInfo for a #GdkPixbuf. * - * Returns: a #GtkIconInfo + * Return value: (transfer full): a #GtkIconInfo * * Since: 2.14 */