| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #undef WNCK_DISABLE_DEPRECATED |
| |
| #include <string.h> |
| #include "class-group.h" |
| #include "window.h" |
| #include "private.h" |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| struct _WnckClassGroupPrivate { |
| char *res_class; |
| char *name; |
| GList *windows; |
| |
| GdkPixbuf *icon; |
| GdkPixbuf *mini_icon; |
| }; |
| |
| G_DEFINE_TYPE (WnckClassGroup, wnck_class_group, G_TYPE_OBJECT); |
| #define WNCK_CLASS_GROUP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), WNCK_TYPE_CLASS_GROUP, WnckClassGroupPrivate)) |
| |
| |
| static GHashTable *class_group_hash = NULL; |
| |
| static void wnck_class_group_finalize (GObject *object); |
| |
| enum { |
| NAME_CHANGED, |
| ICON_CHANGED, |
| LAST_SIGNAL |
| }; |
| |
| static guint signals[LAST_SIGNAL] = { 0 }; |
| |
| void |
| _wnck_class_group_shutdown_all (void) |
| { |
| if (class_group_hash != NULL) |
| { |
| g_hash_table_destroy (class_group_hash); |
| class_group_hash = NULL; |
| } |
| } |
| |
| static void |
| wnck_class_group_class_init (WnckClassGroupClass *class) |
| { |
| GObjectClass *gobject_class = G_OBJECT_CLASS (class); |
| |
| g_type_class_add_private (class, sizeof (WnckClassGroupPrivate)); |
| |
| gobject_class->finalize = wnck_class_group_finalize; |
| |
| |
| |
| |
| |
| |
| |
| signals[NAME_CHANGED] = |
| g_signal_new ("name_changed", |
| G_OBJECT_CLASS_TYPE (gobject_class), |
| G_SIGNAL_RUN_LAST, |
| G_STRUCT_OFFSET (WnckClassGroupClass, name_changed), |
| NULL, NULL, NULL, |
| G_TYPE_NONE, 0); |
| |
| |
| |
| |
| |
| |
| signals[ICON_CHANGED] = |
| g_signal_new ("icon_changed", |
| G_OBJECT_CLASS_TYPE (gobject_class), |
| G_SIGNAL_RUN_LAST, |
| G_STRUCT_OFFSET (WnckClassGroupClass, icon_changed), |
| NULL, NULL, NULL, |
| G_TYPE_NONE, 0); |
| } |
| |
| static void |
| wnck_class_group_init (WnckClassGroup *class_group) |
| { |
| class_group->priv = WNCK_CLASS_GROUP_GET_PRIVATE (class_group); |
| } |
| |
| static void |
| wnck_class_group_finalize (GObject *object) |
| { |
| WnckClassGroup *class_group; |
| |
| class_group = WNCK_CLASS_GROUP (object); |
| |
| if (class_group->priv->res_class) |
| g_free (class_group->priv->res_class); |
| class_group->priv->res_class = NULL; |
| |
| if (class_group->priv->name) |
| g_free (class_group->priv->name); |
| class_group->priv->name = NULL; |
| |
| g_list_free (class_group->priv->windows); |
| class_group->priv->windows = NULL; |
| |
| if (class_group->priv->icon) |
| g_object_unref (class_group->priv->icon); |
| class_group->priv->icon = NULL; |
| |
| if (class_group->priv->mini_icon) |
| g_object_unref (class_group->priv->mini_icon); |
| class_group->priv->mini_icon = NULL; |
| |
| G_OBJECT_CLASS (wnck_class_group_parent_class)->finalize (object); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| WnckClassGroup * |
| wnck_class_group_get (const char *id) |
| { |
| if (!class_group_hash) |
| return NULL; |
| else |
| return g_hash_table_lookup (class_group_hash, id ? id : ""); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| WnckClassGroup * |
| _wnck_class_group_create (const char *res_class) |
| { |
| WnckClassGroup *class_group; |
| |
| if (class_group_hash == NULL) |
| class_group_hash = g_hash_table_new_full (g_str_hash, g_str_equal, |
| NULL, g_object_unref); |
| |
| g_return_val_if_fail (g_hash_table_lookup (class_group_hash, res_class ? res_class : "") == NULL, |
| NULL); |
| |
| class_group = g_object_new (WNCK_TYPE_CLASS_GROUP, NULL); |
| |
| class_group->priv->res_class = g_strdup (res_class ? res_class : ""); |
| |
| g_hash_table_insert (class_group_hash, |
| class_group->priv->res_class, class_group); |
| |
| |
| return class_group; |
| } |
| |
| |
| |
| |
| |
| |
| |
| void |
| _wnck_class_group_destroy (WnckClassGroup *class_group) |
| { |
| g_return_if_fail (WNCK_IS_CLASS_GROUP (class_group)); |
| |
| g_hash_table_remove (class_group_hash, class_group->priv->res_class); |
| |
| |
| } |
| |
| static const char * |
| get_name_from_applications (WnckClassGroup *class_group) |
| { |
| const char *first_name; |
| GList *l; |
| |
| |
| |
| |
| |
| first_name = NULL; |
| |
| for (l = class_group->priv->windows; l; l = l->next) |
| { |
| WnckWindow *w; |
| WnckApplication *app; |
| |
| w = WNCK_WINDOW (l->data); |
| app = wnck_window_get_application (w); |
| |
| if (!first_name) |
| { |
| if (app) |
| first_name = wnck_application_get_name (app); |
| } |
| else |
| { |
| if (!app || strcmp (first_name, wnck_application_get_name (app)) != 0) |
| break; |
| } |
| } |
| |
| if (!l) |
| { |
| |
| return first_name; |
| } |
| else |
| return NULL; |
| } |
| |
| static const char * |
| get_name_from_windows (WnckClassGroup *class_group) |
| { |
| const char *first_name; |
| GList *l; |
| |
| |
| |
| |
| |
| first_name = NULL; |
| |
| for (l = class_group->priv->windows; l; l = l->next) |
| { |
| WnckWindow *window; |
| |
| window = WNCK_WINDOW (l->data); |
| |
| if (!first_name) |
| first_name = wnck_window_get_name (window); |
| else |
| if (strcmp (first_name, wnck_window_get_name (window)) != 0) |
| break; |
| } |
| |
| if (!l) |
| { |
| |
| return first_name; |
| } |
| else |
| return NULL; |
| } |
| |
| |
| |
| |
| |
| static void |
| set_name (WnckClassGroup *class_group) |
| { |
| const char *new_name; |
| |
| if (class_group->priv->name) |
| { |
| g_free (class_group->priv->name); |
| class_group->priv->name = NULL; |
| } |
| |
| new_name = get_name_from_applications (class_group); |
| |
| if (!new_name) |
| { |
| new_name = get_name_from_windows (class_group); |
| |
| if (!new_name) |
| new_name = class_group->priv->res_class; |
| } |
| |
| g_assert (new_name != NULL); |
| |
| if (!class_group->priv->name || |
| strcmp (class_group->priv->name, new_name) != 0) |
| { |
| g_free (class_group->priv->name); |
| class_group->priv->name = g_strdup (new_name); |
| |
| g_signal_emit (G_OBJECT (class_group), signals[NAME_CHANGED], 0); |
| } |
| } |
| |
| |
| static void |
| get_icons_from_applications (WnckClassGroup *class_group, GdkPixbuf **icon, GdkPixbuf **mini_icon) |
| { |
| GList *l; |
| |
| *icon = NULL; |
| *mini_icon = NULL; |
| |
| for (l = class_group->priv->windows; l; l = l->next) |
| { |
| WnckWindow *window; |
| WnckApplication *app; |
| |
| window = WNCK_WINDOW (l->data); |
| app = wnck_window_get_application (window); |
| if (app) |
| { |
| *icon = wnck_application_get_icon (app); |
| *mini_icon = wnck_application_get_mini_icon (app); |
| |
| if (*icon && *mini_icon) |
| return; |
| else |
| { |
| *icon = NULL; |
| *mini_icon = NULL; |
| } |
| } |
| } |
| } |
| |
| |
| static void |
| get_icons_from_windows (WnckClassGroup *class_group, GdkPixbuf **icon, GdkPixbuf **mini_icon) |
| { |
| GList *l; |
| |
| *icon = NULL; |
| *mini_icon = NULL; |
| |
| for (l = class_group->priv->windows; l; l = l->next) |
| { |
| WnckWindow *window; |
| |
| window = WNCK_WINDOW (l->data); |
| |
| *icon = wnck_window_get_icon (window); |
| *mini_icon = wnck_window_get_mini_icon (window); |
| |
| if (*icon && *mini_icon) |
| return; |
| else |
| { |
| *icon = NULL; |
| *mini_icon = NULL; |
| } |
| } |
| } |
| |
| |
| |
| |
| static void |
| set_icon (WnckClassGroup *class_group) |
| { |
| GdkPixbuf *icon, *mini_icon; |
| gboolean icons_reffed = FALSE; |
| |
| get_icons_from_applications (class_group, &icon, &mini_icon); |
| |
| if (!icon || !mini_icon) |
| get_icons_from_windows (class_group, &icon, &mini_icon); |
| |
| if (!icon || !mini_icon) |
| { |
| _wnck_get_fallback_icons (&icon, |
| _wnck_get_default_icon_size (), |
| _wnck_get_default_icon_size (), |
| &mini_icon, |
| _wnck_get_default_mini_icon_size (), |
| _wnck_get_default_mini_icon_size ()); |
| icons_reffed = TRUE; |
| } |
| |
| g_assert (icon && mini_icon); |
| |
| if (class_group->priv->icon) |
| g_object_unref (class_group->priv->icon); |
| |
| if (class_group->priv->mini_icon) |
| g_object_unref (class_group->priv->mini_icon); |
| |
| class_group->priv->icon = icon; |
| class_group->priv->mini_icon = mini_icon; |
| |
| if (!icons_reffed) |
| { |
| g_object_ref (class_group->priv->icon); |
| g_object_ref (class_group->priv->mini_icon); |
| } |
| |
| g_signal_emit (G_OBJECT (class_group), signals[ICON_CHANGED], 0); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void |
| _wnck_class_group_add_window (WnckClassGroup *class_group, |
| WnckWindow *window) |
| { |
| |
| g_return_if_fail (WNCK_IS_CLASS_GROUP (class_group)); |
| g_return_if_fail (WNCK_IS_WINDOW (window)); |
| g_return_if_fail (wnck_window_get_class_group (window) == NULL); |
| |
| class_group->priv->windows = g_list_prepend (class_group->priv->windows, |
| window); |
| _wnck_window_set_class_group (window, class_group); |
| |
| set_name (class_group); |
| set_icon (class_group); |
| |
| |
| |
| |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void |
| _wnck_class_group_remove_window (WnckClassGroup *class_group, |
| WnckWindow *window) |
| { |
| g_return_if_fail (WNCK_IS_CLASS_GROUP (class_group)); |
| g_return_if_fail (WNCK_IS_WINDOW (window)); |
| g_return_if_fail (wnck_window_get_class_group (window) == class_group); |
| |
| class_group->priv->windows = g_list_remove (class_group->priv->windows, |
| window); |
| _wnck_window_set_class_group (window, NULL); |
| |
| set_name (class_group); |
| set_icon (class_group); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| GList * |
| wnck_class_group_get_windows (WnckClassGroup *class_group) |
| { |
| g_return_val_if_fail (class_group != NULL, NULL); |
| |
| return class_group->priv->windows; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| const char * |
| wnck_class_group_get_id (WnckClassGroup *class_group) |
| { |
| g_return_val_if_fail (class_group != NULL, NULL); |
| |
| return class_group->priv->res_class; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| const char * |
| wnck_class_group_get_res_class (WnckClassGroup *class_group) |
| { |
| g_return_val_if_fail (class_group != NULL, NULL); |
| |
| return class_group->priv->res_class; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| const char * |
| wnck_class_group_get_name (WnckClassGroup *class_group) |
| { |
| g_return_val_if_fail (class_group != NULL, NULL); |
| |
| return class_group->priv->name; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| GdkPixbuf * |
| wnck_class_group_get_icon (WnckClassGroup *class_group) |
| { |
| g_return_val_if_fail (class_group != NULL, NULL); |
| |
| return class_group->priv->icon; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| GdkPixbuf * |
| wnck_class_group_get_mini_icon (WnckClassGroup *class_group) |
| { |
| g_return_val_if_fail (class_group != NULL, NULL); |
| |
| return class_group->priv->mini_icon; |
| } |