[gnome-flashback] notifications: store icon as GIcon
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] notifications: store icon as GIcon
- Date: Fri, 3 Jan 2020 22:38:37 +0000 (UTC)
commit d8e8d704f68c5f7a00dcfd96cd4d125c4148d58e
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Thu Jan 2 22:39:31 2020 +0200
notifications: store icon as GIcon
gnome-flashback/libnotifications/gf-bubble.c | 70 +----
.../libnotifications/nd-notification-box.c | 11 +-
gnome-flashback/libnotifications/nd-notification.c | 310 ++++++++-------------
gnome-flashback/libnotifications/nd-notification.h | 4 +-
4 files changed, 135 insertions(+), 260 deletions(-)
---
diff --git a/gnome-flashback/libnotifications/gf-bubble.c b/gnome-flashback/libnotifications/gf-bubble.c
index 9f85082..289fc2a 100644
--- a/gnome-flashback/libnotifications/gf-bubble.c
+++ b/gnome-flashback/libnotifications/gf-bubble.c
@@ -196,43 +196,6 @@ add_notification_action (GfBubble *bubble,
gtk_widget_show (priv->actions_box);
}
-static GdkPixbuf *
-scale_pixbuf (GdkPixbuf *pixbuf,
- gint max_width,
- gint max_height)
-{
- gint pw;
- gint ph;
- gfloat scale_factor_x;
- gfloat scale_factor_y;
- gfloat scale_factor;
-
- pw = gdk_pixbuf_get_width (pixbuf);
- ph = gdk_pixbuf_get_height (pixbuf);
-
- /* Determine which dimension requires the smallest scale. */
- scale_factor_x = (gfloat) max_width / (gfloat) pw;
- scale_factor_y = (gfloat) max_height / (gfloat) ph;
-
- scale_factor = scale_factor_x;
- if (scale_factor_x > scale_factor_y)
- scale_factor = scale_factor_y;
-
- if (scale_factor < 1.0f)
- {
- gint scale_x;
- gint scale_y;
-
- scale_x = (gint) (pw * scale_factor);
- scale_y = (gint) (ph * scale_factor);
-
- return gdk_pixbuf_scale_simple (pixbuf, scale_x, scale_y,
- GDK_INTERP_BILINEAR);
- }
-
- return g_object_ref (pixbuf);
-}
-
static gboolean
timeout_bubble (gpointer user_data)
{
@@ -292,7 +255,7 @@ update_bubble (GfBubble *bubble)
gchar **actions;
gint i;
gboolean have_actions;
- GdkPixbuf *pixbuf;
+ GIcon *icon;
gboolean have_icon;
priv = gf_bubble_get_instance_private (bubble);
@@ -361,36 +324,17 @@ update_bubble (GfBubble *bubble)
/* Icon */
- pixbuf = nd_notification_load_image (priv->notification, IMAGE_SIZE);
+ icon = nd_notification_get_icon (priv->notification);
have_icon = FALSE;
- if (pixbuf != NULL)
+ if (icon != NULL)
{
- GdkPixbuf *scaled;
-
- scaled = scale_pixbuf (pixbuf, IMAGE_SIZE, IMAGE_SIZE);
- g_object_unref (pixbuf);
+ gtk_image_set_from_gicon (GTK_IMAGE (priv->icon), icon, GTK_ICON_SIZE_DIALOG);
+ gtk_image_set_pixel_size (GTK_IMAGE (priv->icon), IMAGE_SIZE);
- gtk_image_set_from_pixbuf (GTK_IMAGE (priv->icon), scaled);
-
- have_icon = scaled != NULL;
+ have_icon = TRUE;
gtk_widget_set_visible (priv->icon, have_icon);
-
- if (scaled != NULL)
- {
- gint width;
-
- width = gdk_pixbuf_get_width (scaled);
- g_object_unref (scaled);
-
- width = MAX (BODY_X_OFFSET, width);
-
- gtk_widget_set_size_request (priv->icon, width, -1);
- }
- else
- {
- gtk_widget_set_size_request (priv->icon, BODY_X_OFFSET, -1);
- }
+ gtk_widget_set_size_request (priv->icon, BODY_X_OFFSET, -1);
}
if (have_body || have_actions || have_icon)
diff --git a/gnome-flashback/libnotifications/nd-notification-box.c
b/gnome-flashback/libnotifications/nd-notification-box.c
index e250d63..d86daed 100644
--- a/gnome-flashback/libnotifications/nd-notification-box.c
+++ b/gnome-flashback/libnotifications/nd-notification-box.c
@@ -172,7 +172,7 @@ update_notification_box (NdNotificationBox *notification_box)
gboolean have_body;
const char *body;
gboolean have_actions;
- GdkPixbuf *pixbuf;
+ GIcon *icon;
char **actions;
int i;
char *str;
@@ -187,11 +187,10 @@ update_notification_box (NdNotificationBox *notification_box)
have_actions = FALSE;
/* image */
- pixbuf = nd_notification_load_image (notification_box->priv->notification, IMAGE_SIZE);
- if (pixbuf != NULL) {
- gtk_image_set_from_pixbuf (GTK_IMAGE (notification_box->priv->icon), pixbuf);
-
- g_object_unref (G_OBJECT (pixbuf));
+ icon = nd_notification_get_icon (notification_box->priv->notification);
+ if (icon != NULL) {
+ gtk_image_set_from_gicon (GTK_IMAGE (notification_box->priv->icon), icon,
GTK_ICON_SIZE_DIALOG);
+ gtk_image_set_pixel_size (GTK_IMAGE (notification_box->priv->icon), IMAGE_SIZE);
have_icon = TRUE;
}
diff --git a/gnome-flashback/libnotifications/nd-notification.c
b/gnome-flashback/libnotifications/nd-notification.c
index bbf3e1f..3a8daa2 100644
--- a/gnome-flashback/libnotifications/nd-notification.c
+++ b/gnome-flashback/libnotifications/nd-notification.c
@@ -45,7 +45,7 @@ struct _NdNotification {
char *sender;
guint32 id;
char *app_name;
- char *app_icon;
+ GIcon *icon;
char *summary;
char *body;
char **actions;
@@ -193,6 +193,120 @@ parse_markup (const gchar *text,
return TRUE;
}
+static void
+free_pixels (guchar *pixels,
+ gpointer user_data)
+{
+ g_free (pixels);
+}
+
+static GIcon *
+icon_from_data (GVariant *icon_data)
+{
+ gboolean has_alpha;
+ int bits_per_sample;
+ int width;
+ int height;
+ int rowstride;
+ int n_channels;
+ GVariant *data_variant;
+ gsize expected_len;
+ guchar *data;
+ GdkPixbuf *pixbuf;
+
+ g_variant_get (icon_data,
+ "(iiibii@ay)",
+ &width,
+ &height,
+ &rowstride,
+ &has_alpha,
+ &bits_per_sample,
+ &n_channels,
+ &data_variant);
+
+ expected_len = (height - 1) * rowstride + width
+ * ((n_channels * bits_per_sample + 7) / 8);
+
+ if (expected_len != g_variant_get_size (data_variant)) {
+ g_warning ("Expected image data to be of length %" G_GSIZE_FORMAT
+ " but got a " "length of %" G_GSIZE_FORMAT,
+ expected_len,
+ g_variant_get_size (data_variant));
+ return NULL;
+ }
+
+ data = (guchar *) g_memdup (g_variant_get_data (data_variant),
+ g_variant_get_size (data_variant));
+
+ pixbuf = gdk_pixbuf_new_from_data (data,
+ GDK_COLORSPACE_RGB,
+ has_alpha,
+ bits_per_sample,
+ width,
+ height,
+ rowstride,
+ free_pixels,
+ NULL);
+
+ return G_ICON (pixbuf);
+}
+
+static GIcon *
+icon_from_path (const char *path)
+{
+ GFile *file;
+ GIcon *icon;
+
+ if (path == NULL || *path == '\0')
+ return NULL;
+
+ if (g_str_has_prefix (path, "file://"))
+ file = g_file_new_for_uri (path);
+ else if (*path == '/')
+ file = g_file_new_for_path (path);
+ else
+ file = NULL;
+
+ if (file != NULL) {
+ icon = g_file_icon_new (file);
+ g_object_unref (file);
+ } else {
+ icon = g_themed_icon_new (path);
+ }
+
+ return icon;
+}
+
+static void
+update_icon (NdNotification *notification,
+ const gchar *app_icon,
+ GVariant *hints)
+{
+ GIcon *icon;
+ GVariantDict dict;
+ GVariant *image_data;
+ const char *image_path;
+
+ g_variant_dict_init (&dict, hints);
+
+ if (g_variant_dict_lookup (&dict, "image-data", "@(iiibiiay)", &image_data) ||
+ g_variant_dict_lookup (&dict, "image_data", "@(iiibiiay)", &image_data)) {
+ icon = icon_from_data (image_data);
+ } else if (g_variant_dict_lookup (&dict, "image-path", "&s", &image_path) ||
+ g_variant_dict_lookup (&dict, "image_path", "&s", &image_path)) {
+ icon = icon_from_path (image_path);
+ } else if (*app_icon != '\0') {
+ icon = icon_from_path (app_icon);
+ } else if (g_variant_dict_lookup (&dict, "icon_data", "v", &image_data)) {
+ icon = icon_from_data (image_data);
+ } else {
+ icon = NULL;
+ }
+
+ g_clear_object (¬ification->icon);
+ notification->icon = icon;
+}
+
static void
nd_notification_class_init (NdNotificationClass *class)
{
@@ -234,7 +348,7 @@ nd_notification_init (NdNotification *notification)
notification->id = get_next_notification_serial ();
notification->app_name = NULL;
- notification->app_icon = NULL;
+ notification->icon = NULL;
notification->summary = NULL;
notification->body = NULL;
notification->actions = NULL;
@@ -253,7 +367,7 @@ nd_notification_finalize (GObject *object)
g_free (notification->sender);
g_free (notification->app_name);
- g_free (notification->app_icon);
+ g_clear_object (¬ification->icon);
g_free (notification->summary);
g_free (notification->body);
g_strfreev (notification->actions);
@@ -284,8 +398,7 @@ nd_notification_update (NdNotification *notification,
g_free (notification->app_name);
notification->app_name = g_strdup (app_name);
- g_free (notification->app_icon);
- notification->app_icon = g_strdup (app_icon);
+ update_icon (notification, app_icon, hints);
g_free (notification->summary);
notification->summary = g_strdup (summary);
@@ -456,191 +569,10 @@ nd_notification_get_timeout (NdNotification *notification)
return notification->timeout;
}
-static GdkPixbuf *
-scale_pixbuf (GdkPixbuf *pixbuf,
- int max_width,
- int max_height,
- gboolean no_stretch_hint)
-{
- int pw;
- int ph;
- float scale_factor_x = 1.0;
- float scale_factor_y = 1.0;
- float scale_factor = 1.0;
-
- pw = gdk_pixbuf_get_width (pixbuf);
- ph = gdk_pixbuf_get_height (pixbuf);
-
- /* Determine which dimension requires the smallest scale. */
- scale_factor_x = (float) max_width / (float) pw;
- scale_factor_y = (float) max_height / (float) ph;
-
- if (scale_factor_x > scale_factor_y) {
- scale_factor = scale_factor_y;
- } else {
- scale_factor = scale_factor_x;
- }
-
- /* always scale down, allow to disable scaling up */
- if (scale_factor < 1.0f || !no_stretch_hint) {
- int scale_x;
- int scale_y;
-
- scale_x = (int) (pw * scale_factor);
- scale_y = (int) (ph * scale_factor);
- return gdk_pixbuf_scale_simple (pixbuf,
- scale_x,
- scale_y,
- GDK_INTERP_BILINEAR);
- } else {
- return g_object_ref (pixbuf);
- }
-}
-
-static void
-free_pixels (guchar *pixels,
- gpointer user_data)
-{
- g_free (pixels);
-}
-
-static GdkPixbuf *
-_notify_daemon_pixbuf_from_data_hint (GVariant *icon_data,
- int size)
-{
- gboolean has_alpha;
- int bits_per_sample;
- int width;
- int height;
- int rowstride;
- int n_channels;
- GVariant *data_variant;
- gsize expected_len;
- guchar *data;
- GdkPixbuf *pixbuf;
-
- g_variant_get (icon_data,
- "(iiibii@ay)",
- &width,
- &height,
- &rowstride,
- &has_alpha,
- &bits_per_sample,
- &n_channels,
- &data_variant);
-
- expected_len = (height - 1) * rowstride + width
- * ((n_channels * bits_per_sample + 7) / 8);
-
- if (expected_len != g_variant_get_size (data_variant)) {
- g_warning ("Expected image data to be of length %" G_GSIZE_FORMAT
- " but got a " "length of %" G_GSIZE_FORMAT,
- expected_len,
- g_variant_get_size (data_variant));
- return NULL;
- }
-
- data = (guchar *) g_memdup (g_variant_get_data (data_variant),
- g_variant_get_size (data_variant));
-
- pixbuf = gdk_pixbuf_new_from_data (data,
- GDK_COLORSPACE_RGB,
- has_alpha,
- bits_per_sample,
- width,
- height,
- rowstride,
- free_pixels,
- NULL);
- if (pixbuf != NULL && size > 0) {
- GdkPixbuf *scaled;
- scaled = scale_pixbuf (pixbuf, size, size, TRUE);
- g_object_unref (pixbuf);
- pixbuf = scaled;
- }
-
- return pixbuf;
-}
-
-static GdkPixbuf *
-_notify_daemon_pixbuf_from_path (const char *path,
- int size)
+GIcon *
+nd_notification_get_icon (NdNotification *notification)
{
- GFile *file;
- GdkPixbuf *pixbuf = NULL;
-
- file = g_file_new_for_commandline_arg (path);
- if (g_file_is_native (file)) {
- char *realpath;
-
- realpath = g_file_get_path (file);
- pixbuf = gdk_pixbuf_new_from_file_at_size (realpath, size, size, NULL);
- g_free (realpath);
- }
- g_object_unref (file);
-
- if (pixbuf == NULL) {
- /* Load icon theme icon */
- GtkIconTheme *theme;
- GtkIconInfo *icon_info;
-
- theme = gtk_icon_theme_get_default ();
- icon_info = gtk_icon_theme_lookup_icon (theme,
- path,
- size,
- GTK_ICON_LOOKUP_USE_BUILTIN);
-
- if (icon_info != NULL) {
- gint icon_size;
-
- icon_size = MIN (size,
- gtk_icon_info_get_base_size (icon_info));
-
- if (icon_size == 0)
- icon_size = size;
-
- pixbuf = gtk_icon_theme_load_icon (theme,
- path,
- icon_size,
- GTK_ICON_LOOKUP_USE_BUILTIN,
- NULL);
-
- g_object_unref (icon_info);
- }
- }
-
- return pixbuf;
-}
-
-GdkPixbuf *
-nd_notification_load_image (NdNotification *notification,
- int size)
-{
- GVariant *data;
- GdkPixbuf *pixbuf;
-
- pixbuf = NULL;
-
- if ((data = (GVariant *) g_hash_table_lookup (notification->hints, "image-data"))
- || (data = (GVariant *) g_hash_table_lookup (notification->hints, "image_data"))) {
- pixbuf = _notify_daemon_pixbuf_from_data_hint (data, size);
- } else if ((data = (GVariant *) g_hash_table_lookup (notification->hints, "image-path"))
- || (data = (GVariant *) g_hash_table_lookup (notification->hints, "image_path"))) {
- if (g_variant_is_of_type (data, G_VARIANT_TYPE_STRING)) {
- const char *path;
- path = g_variant_get_string (data, NULL);
- pixbuf = _notify_daemon_pixbuf_from_path (path, size);
- } else {
- g_warning ("Expected image_path hint to be of type string");
- }
- } else if (*notification->app_icon != '\0') {
- pixbuf = _notify_daemon_pixbuf_from_path (notification->app_icon, size);
- } else if ((data = (GVariant *) g_hash_table_lookup (notification->hints, "icon_data"))) {
- g_warning("\"icon_data\" hint is deprecated, please use \"image_data\" instead");
- pixbuf = _notify_daemon_pixbuf_from_data_hint (data, size);
- }
-
- return pixbuf;
+ return notification->icon;
}
void
diff --git a/gnome-flashback/libnotifications/nd-notification.h
b/gnome-flashback/libnotifications/nd-notification.h
index 3cf5249..47e9bb0 100644
--- a/gnome-flashback/libnotifications/nd-notification.h
+++ b/gnome-flashback/libnotifications/nd-notification.h
@@ -70,8 +70,8 @@ const char * nd_notification_get_body (NdNotification *notif
char ** nd_notification_get_actions (NdNotification *notification);
GHashTable * nd_notification_get_hints (NdNotification *notification);
-GdkPixbuf * nd_notification_load_image (NdNotification *notification,
- int size);
+GIcon * nd_notification_get_icon (NdNotification *notification);
+
gboolean nd_notification_get_is_resident (NdNotification *notification);
gboolean nd_notification_get_is_transient (NdNotification *notification);
gboolean nd_notification_get_action_icons (NdNotification *notification);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]