summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <matthiasc@src.gnome.org>2004-07-17 03:55:07 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2004-07-17 03:55:07 +0000
commita5638e82e8f5bef394166fecd997752204299155 (patch)
treecd6d74fceba6a917d1f5b9ffdef1329ce01fd06c
parent1d45cbd83155e4df2bbbf61230ea4f09bb44dde6 (diff)
downloadgdk-pixbuf-a5638e82e8f5bef394166fecd997752204299155.tar.gz
Support named themed window icons.
-rw-r--r--ChangeLog18
-rw-r--r--ChangeLog.pre-2-1018
-rw-r--r--ChangeLog.pre-2-618
-rw-r--r--ChangeLog.pre-2-818
-rw-r--r--docs/reference/ChangeLog5
-rw-r--r--docs/reference/gtk/gtk-sections.txt4
-rw-r--r--gtk/gtkicontheme.c73
-rw-r--r--gtk/gtkicontheme.h2
-rw-r--r--gtk/gtkwindow.c243
-rw-r--r--gtk/gtkwindow.h5
10 files changed, 400 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index aece06a44..a65b6a3e6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Fri Jul 16 23:20:34 2004 Matthias Clasen <maclas@gmx.de>
+
+ Support themed window icons. (#92346, Calum Benson)
+
+ * gtk/gtkicontheme.c (gtk_icon_theme_get_icon_sizes): New
+ function to obtain information about the sizes in which an
+ icon is available.
+
+ * gtk/gtkwindow.h:
+ * gtk/gtkwindow.c (gtk_window_class_init):
+ (gtk_window_set_icon_name):
+ (gtk_window_get_icon_name): Add an "icon_name" property
+ (gtk_window_set_default_icon_name): ...and a default icon name.
+ (icon_list_from_theme):
+ (update_themed_icon): New auxiliary functions to create a
+ list of all available sizes of a themed icon and update the
+ window icon list from it.
+
2004-07-16 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkcombobox.c (gtk_combo_box_scroll_event): Make
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index aece06a44..a65b6a3e6 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,21 @@
+Fri Jul 16 23:20:34 2004 Matthias Clasen <maclas@gmx.de>
+
+ Support themed window icons. (#92346, Calum Benson)
+
+ * gtk/gtkicontheme.c (gtk_icon_theme_get_icon_sizes): New
+ function to obtain information about the sizes in which an
+ icon is available.
+
+ * gtk/gtkwindow.h:
+ * gtk/gtkwindow.c (gtk_window_class_init):
+ (gtk_window_set_icon_name):
+ (gtk_window_get_icon_name): Add an "icon_name" property
+ (gtk_window_set_default_icon_name): ...and a default icon name.
+ (icon_list_from_theme):
+ (update_themed_icon): New auxiliary functions to create a
+ list of all available sizes of a themed icon and update the
+ window icon list from it.
+
2004-07-16 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkcombobox.c (gtk_combo_box_scroll_event): Make
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index aece06a44..a65b6a3e6 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,21 @@
+Fri Jul 16 23:20:34 2004 Matthias Clasen <maclas@gmx.de>
+
+ Support themed window icons. (#92346, Calum Benson)
+
+ * gtk/gtkicontheme.c (gtk_icon_theme_get_icon_sizes): New
+ function to obtain information about the sizes in which an
+ icon is available.
+
+ * gtk/gtkwindow.h:
+ * gtk/gtkwindow.c (gtk_window_class_init):
+ (gtk_window_set_icon_name):
+ (gtk_window_get_icon_name): Add an "icon_name" property
+ (gtk_window_set_default_icon_name): ...and a default icon name.
+ (icon_list_from_theme):
+ (update_themed_icon): New auxiliary functions to create a
+ list of all available sizes of a themed icon and update the
+ window icon list from it.
+
2004-07-16 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkcombobox.c (gtk_combo_box_scroll_event): Make
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index aece06a44..a65b6a3e6 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,21 @@
+Fri Jul 16 23:20:34 2004 Matthias Clasen <maclas@gmx.de>
+
+ Support themed window icons. (#92346, Calum Benson)
+
+ * gtk/gtkicontheme.c (gtk_icon_theme_get_icon_sizes): New
+ function to obtain information about the sizes in which an
+ icon is available.
+
+ * gtk/gtkwindow.h:
+ * gtk/gtkwindow.c (gtk_window_class_init):
+ (gtk_window_set_icon_name):
+ (gtk_window_get_icon_name): Add an "icon_name" property
+ (gtk_window_set_default_icon_name): ...and a default icon name.
+ (icon_list_from_theme):
+ (update_themed_icon): New auxiliary functions to create a
+ list of all available sizes of a themed icon and update the
+ window icon list from it.
+
2004-07-16 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkcombobox.c (gtk_combo_box_scroll_event): Make
diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog
index 96ebbc3b0..43a6ae191 100644
--- a/docs/reference/ChangeLog
+++ b/docs/reference/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jul 16 23:54:18 2004 Matthias Clasen <maclas@gmx.de>
+
+ * gtk/gtk-sections.txt: Add new GtkWindow and GtkIconTheme
+ functions for named themed window icons.
+
2004-07-16 Matthias Clasen <mclasen@redhat.com>
* gtk/gtk-sections.txt:
diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt
index 84d293000..c9ea44a28 100644
--- a/docs/reference/gtk/gtk-sections.txt
+++ b/docs/reference/gtk/gtk-sections.txt
@@ -4559,6 +4559,7 @@ gtk_window_get_frame_dimensions
gtk_window_get_has_frame
gtk_window_get_icon
gtk_window_get_icon_list
+gtk_window_get_icon_name
gtk_window_get_mnemonic_modifier
gtk_window_get_modal
gtk_window_get_position
@@ -4578,9 +4579,11 @@ gtk_window_resize
gtk_window_set_default_icon_list
gtk_window_set_default_icon
gtk_window_set_default_icon_from_file
+gtk_window_set_default_icon_name
gtk_window_set_icon
gtk_window_set_icon_list
gtk_window_set_icon_from_file
+gtk_window_set_icon_name
gtk_window_set_auto_startup_notification
<SUBSECTION Standard>
GTK_WINDOW
@@ -5308,6 +5311,7 @@ gtk_icon_theme_has_icon
gtk_icon_theme_lookup_icon
gtk_icon_theme_load_icon
gtk_icon_theme_list_icons
+gtk_icon_theme_get_icon_sizes
gtk_icon_theme_get_example_icon_name
gtk_icon_theme_rescan_if_needed
gtk_icon_theme_add_builtin_icon
diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c
index c4b30f367..ef04e1c11 100644
--- a/gtk/gtkicontheme.c
+++ b/gtk/gtkicontheme.c
@@ -1295,6 +1295,77 @@ gtk_icon_theme_has_icon (GtkIconTheme *icon_theme,
return FALSE;
}
+static void
+add_size (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ gint **res_p = user_data;
+
+ **res_p = GPOINTER_TO_INT (key);
+
+ *res_p++;
+}
+
+/**
+ * gtk_icon_theme_get_icon_sizes:
+ * @icon_theme: a #GtkIconTheme
+ * @icon_name: the name of an icon
+ *
+ * Returns an array of integers describing the sizes at which
+ * the icon is available without scaling. A size of -1 means
+ * that the icon is available in a scalable format. The array
+ * is zero-terminated.
+ *
+ * Return value: An newly allocated array describing the sizes at
+ * which the icon is available.
+ *
+ * Since: 2.6
+ **/
+gint *
+gtk_icon_theme_get_icon_sizes (GtkIconTheme *icon_theme,
+ const char *icon_name)
+{
+ GList *l, *d;
+ GHashTable *sizes;
+ gint *result;
+ guint suffix;
+
+ GtkIconThemePrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), FALSE);
+
+ priv = icon_theme->priv;
+
+ ensure_valid_themes (icon_theme);
+
+ sizes = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ for (l = priv->themes; l; l = l->next)
+ {
+ IconTheme *theme = l->data;
+ for (d = theme->dirs; d; d = d->next)
+ {
+ IconThemeDir *dir = d->data;
+
+ suffix = GPOINTER_TO_UINT (g_hash_table_lookup (dir->icons, icon_name));
+ if (suffix != ICON_SUFFIX_NONE)
+ {
+ if (suffix == ICON_SUFFIX_SVG)
+ g_hash_table_insert (sizes, GINT_TO_POINTER (-1), NULL);
+ else
+ g_hash_table_insert (sizes, GINT_TO_POINTER (dir->size), NULL);
+ }
+ }
+ }
+
+ result = g_new0 (gint, g_hash_table_size (sizes) + 1);
+
+ g_hash_table_foreach (sizes, add_size, &result);
+ g_hash_table_destroy (sizes);
+
+ return result;
+}
static void
add_key_to_hash (gpointer key,
@@ -2275,7 +2346,7 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info,
*
* Renders an icon previously looked up in an icon theme using
* gtk_icon_theme_lookup_icon(); the size will be based on the size
- * pssed to gtk_icon_theme_lookup_icon(). Note that the resulting
+ * passed to gtk_icon_theme_lookup_icon(). Note that the resulting
* pixbuf may not be exactly this size; an icon theme may have icons
* that differ slightly from their nominal sizes, and in addition GTK+
* will avoid scaling icons that it considers sufficiently close to the
diff --git a/gtk/gtkicontheme.h b/gtk/gtkicontheme.h
index 33bd6625f..c97d7a130 100644
--- a/gtk/gtkicontheme.h
+++ b/gtk/gtkicontheme.h
@@ -116,6 +116,8 @@ void gtk_icon_theme_set_custom_theme (GtkIconTheme
gboolean gtk_icon_theme_has_icon (GtkIconTheme *icon_theme,
const gchar *icon_name);
+gint *gtk_icon_theme_get_icon_sizes (GtkIconTheme *icon_theme,
+ const gchar *icon_name);
GtkIconInfo * gtk_icon_theme_lookup_icon (GtkIconTheme *icon_theme,
const gchar *icon_name,
gint size,
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 9ffe43b7e..a6b9c30bf 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -38,6 +38,7 @@
#include "gtkkeyhash.h"
#include "gtkmain.h"
#include "gtkiconfactory.h"
+#include "gtkicontheme.h"
#include "gtkintl.h"
#include "gtkmarshalers.h"
#include "gtkplug.h"
@@ -70,6 +71,7 @@ enum {
PROP_DEFAULT_HEIGHT,
PROP_DESTROY_WITH_PARENT,
PROP_ICON,
+ PROP_ICON_NAME,
PROP_SCREEN,
PROP_TYPE_HINT,
PROP_SKIP_TASKBAR_HINT,
@@ -91,9 +93,11 @@ typedef struct
GList *icon_list;
GdkPixmap *icon_pixmap;
GdkPixmap *icon_mask;
+ gchar *icon_name;
guint realized : 1;
guint using_default_icon : 1;
guint using_parent_icon : 1;
+ guint using_themed_icon : 1;
} GtkWindowIconInfo;
typedef struct {
@@ -261,6 +265,10 @@ static void gtk_window_set_default_size_internal (GtkWindow *window,
gint height,
gboolean is_geometry);
+static void update_themed_icon (GtkIconTheme *theme,
+ GtkWindow *window);
+static GList *icon_list_from_theme (GtkWidget *widget,
+ const gchar *name);
static void gtk_window_realize_icon (GtkWindow *window);
static void gtk_window_unrealize_icon (GtkWindow *window);
@@ -273,6 +281,7 @@ static GHashTable *mnemonic_hash_table = NULL;
static GtkBinClass *parent_class = NULL;
static guint window_signals[LAST_SIGNAL] = { 0 };
static GList *default_icon_list = NULL;
+static gchar *default_icon_name = NULL;
static guint default_icon_serial = 0;
static gboolean disable_startup_notification = FALSE;
static gboolean sent_startup_notification = FALSE;
@@ -539,6 +548,22 @@ gtk_window_class_init (GtkWindowClass *klass)
GDK_TYPE_PIXBUF,
G_PARAM_READWRITE));
+ /**
+ * GtkWindow:icon-name:
+ *
+ * The :icon-name property specifies the name of the themed icon to
+ * use as the window icon. See #GtkIconTheme for more details.
+ *
+ * Since: 2.6
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_ICON_NAME,
+ g_param_spec_string ("icon_name",
+ P_("Icon Name"),
+ P_("Name of the themed icon for this window"),
+ NULL,
+ G_PARAM_READWRITE));
+
g_object_class_install_property (gobject_class,
PROP_SCREEN,
g_param_spec_object ("screen",
@@ -858,6 +883,9 @@ gtk_window_set_property (GObject *object,
gtk_window_set_icon (window,
g_value_get_object (value));
break;
+ case PROP_ICON_NAME:
+ gtk_window_set_icon_name (window, g_value_get_string (value));
+ break;
case PROP_SCREEN:
gtk_window_set_screen (window, g_value_get_object (value));
break;
@@ -949,6 +977,9 @@ gtk_window_get_property (GObject *object,
case PROP_ICON:
g_value_set_object (value, gtk_window_get_icon (window));
break;
+ case PROP_ICON_NAME:
+ g_value_set_string (value, gtk_window_get_icon_name (window));
+ break;
case PROP_SCREEN:
g_value_set_object (value, window->screen);
break;
@@ -2430,6 +2461,14 @@ get_icon_info (GtkWindow *window)
"gtk-window-icon-info");
}
+static void
+free_icon_info (GtkWindowIconInfo *info)
+{
+ g_free (info->icon_name);
+ g_free (info);
+}
+
+
static GtkWindowIconInfo*
ensure_icon_info (GtkWindow *window)
{
@@ -2443,7 +2482,7 @@ ensure_icon_info (GtkWindow *window)
g_object_set_data_full (G_OBJECT (window),
"gtk-window-icon-info",
info,
- g_free);
+ (GDestroyNotify)free_icon_info);
}
return info;
@@ -2599,13 +2638,50 @@ get_pixmap_and_mask (GdkWindow *window,
}
}
+static GList *
+icon_list_from_theme (GtkWidget *widget,
+ const gchar *name)
+{
+ GList *list;
+
+ GtkIconTheme *icon_theme;
+ GdkPixbuf *icon;
+ gint *sizes;
+ gint i;
+
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
+
+ sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
+ list = NULL;
+
+ for (i = 0; sizes[i]; i++)
+ {
+ /* FIXME
+ * We need an EWMH extension to handle scalable icons
+ * by passing their name to the WM. For now just use a
+ * fixed size of 48.
+ */
+ if (sizes[i] == -1)
+ icon = gtk_icon_theme_load_icon (icon_theme, name,
+ 48, 0, NULL);
+ else
+ icon = gtk_icon_theme_load_icon (icon_theme, name,
+ sizes[i], 0, NULL);
+ if (icon)
+ list = g_list_append (list, icon);
+ }
+
+ return list;
+}
+
+
static void
gtk_window_realize_icon (GtkWindow *window)
{
GtkWidget *widget;
GtkWindowIconInfo *info;
GList *icon_list;
-
+
widget = GTK_WIDGET (window);
g_return_if_fail (widget->window != NULL);
@@ -2626,9 +2702,17 @@ gtk_window_realize_icon (GtkWindow *window)
info->using_default_icon = FALSE;
info->using_parent_icon = FALSE;
+ info->using_themed_icon = FALSE;
icon_list = info->icon_list;
-
+
+ /* Look up themed icon */
+ if (icon_list == NULL && info->icon_name)
+ {
+ icon_list = icon_list_from_theme (widget, info->icon_name);
+ info->using_themed_icon = TRUE;
+ }
+
/* Inherit from transient parent */
if (icon_list == NULL && window->transient_parent)
{
@@ -2644,6 +2728,14 @@ gtk_window_realize_icon (GtkWindow *window)
if (icon_list)
info->using_default_icon = TRUE;
}
+
+ /* Look up themed icon */
+ if (icon_list == NULL && default_icon_name)
+ {
+ icon_list = icon_list_from_theme (widget, default_icon_name);
+ info->using_default_icon = TRUE;
+ info->using_themed_icon = TRUE;
+ }
gdk_window_set_icon_list (widget->window, icon_list);
@@ -2663,6 +2755,18 @@ gtk_window_realize_icon (GtkWindow *window)
info->icon_mask);
info->realized = TRUE;
+
+ if (info->using_themed_icon)
+ {
+ GtkIconTheme *icon_theme;
+
+ g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
+ g_list_free (icon_list);
+
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
+ g_signal_connect (icon_theme, "changed",
+ G_CALLBACK (update_themed_icon), window);
+ }
}
static void
@@ -2687,11 +2791,21 @@ gtk_window_unrealize_icon (GtkWindow *window)
info->icon_pixmap = NULL;
info->icon_mask = NULL;
+ if (info->using_themed_icon)
+ {
+ GtkIconTheme *icon_theme;
+
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
+
+ g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
+ }
+
/* We don't clear the properties on the window, just figure the
* window is going away.
*/
info->realized = FALSE;
+
}
/**
@@ -2826,6 +2940,79 @@ gtk_window_set_icon (GtkWindow *window,
g_list_free (list);
}
+
+static void
+update_themed_icon (GtkIconTheme *icon_theme,
+ GtkWindow *window)
+{
+ g_object_notify (G_OBJECT (window), "icon");
+
+ gtk_window_unrealize_icon (window);
+
+ if (GTK_WIDGET_REALIZED (window))
+ gtk_window_realize_icon (window);
+}
+
+/**
+ * gtk_window_set_icon_name:
+ * @window: a #GtkWindow
+ * @name: the name of the themed icon
+ *
+ * Sets the icon for the window from a named themed icon. See
+ * the docs for #GtkIconTheme for more details.
+ *
+ * Note that this has nothing to do with the WM_ICON_NAME
+ * property which is mentioned in the ICCCM.
+ *
+ * Since: 2.6
+ */
+void
+gtk_window_set_icon_name (GtkWindow *window,
+ const gchar *name)
+{
+ GtkWindowIconInfo *info;
+ gchar *tmp;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+
+ info = ensure_icon_info (window);
+
+ tmp = info->icon_name;
+ info->icon_name = g_strdup (name);
+ g_free (tmp);
+
+ g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
+ g_list_free (info->icon_list);
+
+ update_themed_icon (NULL, window);
+
+ g_object_notify (G_OBJECT (window), "icon_name");
+}
+
+/**
+ * gtk_window_get_icon_name:
+ * @window: a #GtkWindow
+ *
+ * Returns the name of the themed icon for the window,
+ * see gtk_window_set_icon_name().
+ *
+ * Returns: the icon name or %NULL if the window has
+ * no themed icon
+ *
+ * Since: 2.6
+ */
+G_CONST_RETURN gchar *
+gtk_window_get_icon_name (GtkWindow *window)
+{
+ GtkWindowIconInfo *info;
+
+ g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
+
+ info = ensure_icon_info (window);
+
+ return info->icon_name;
+}
+
/**
* gtk_window_get_icon:
* @window: a #GtkWindow
@@ -2986,6 +3173,56 @@ gtk_window_set_default_icon (GdkPixbuf *icon)
}
/**
+ * gtk_window_set_default_icon_name:
+ * @name: the name of the themed icon
+ *
+ * Sets an icon to be used as fallback for windows that haven't
+ * had gtk_window_set_icon_list() called on them from a named
+ * themed icon, see gtk_window_set_icon_name().
+ *
+ * Since: 2.6
+ **/
+void
+gtk_window_set_default_icon_name (const gchar *name)
+{
+ GList *tmp_list;
+ GList *toplevels;
+
+ /* Update serial so we don't used cached pixmaps/masks
+ */
+ default_icon_serial++;
+
+ g_free (default_icon_name);
+ default_icon_name = g_strdup (name);
+
+ g_list_foreach (default_icon_list,
+ (GFunc) g_object_unref, NULL);
+
+ g_list_free (default_icon_list);
+ default_icon_list = NULL;
+
+ /* Update all toplevels */
+ toplevels = gtk_window_list_toplevels ();
+ tmp_list = toplevels;
+ while (tmp_list != NULL)
+ {
+ GtkWindowIconInfo *info;
+ GtkWindow *w = tmp_list->data;
+
+ info = get_icon_info (w);
+ if (info && info->using_default_icon && info->using_themed_icon)
+ {
+ gtk_window_unrealize_icon (w);
+ if (GTK_WIDGET_REALIZED (w))
+ gtk_window_realize_icon (w);
+ }
+
+ tmp_list = tmp_list->next;
+ }
+ g_list_free (toplevels);
+}
+
+/**
* gtk_window_set_default_icon_from_file:
* @filename: location of icon file
* @err: location to store error, or %NULL.
diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h
index bcf6963e0..a52d675c0 100644
--- a/gtk/gtkwindow.h
+++ b/gtk/gtkwindow.h
@@ -257,13 +257,18 @@ void gtk_window_set_icon_list (GtkWindow *window,
GList* gtk_window_get_icon_list (GtkWindow *window);
void gtk_window_set_icon (GtkWindow *window,
GdkPixbuf *icon);
+void gtk_window_set_icon_name (GtkWindow *window,
+ const gchar *name);
gboolean gtk_window_set_icon_from_file (GtkWindow *window,
const gchar *filename,
GError **err);
GdkPixbuf* gtk_window_get_icon (GtkWindow *window);
+G_CONST_RETURN
+gchar *gtk_window_get_icon_name (GtkWindow *window);
void gtk_window_set_default_icon_list (GList *list);
GList* gtk_window_get_default_icon_list (void);
void gtk_window_set_default_icon (GdkPixbuf *icon);
+void gtk_window_set_default_icon_name (const gchar *name);
gboolean gtk_window_set_default_icon_from_file (const gchar *filename,
GError **err);