[libnotify: 1/2] notification: Handle snap applications



commit 2e8ed8add32410118b61a3a50b6b6c12d3b1b76d
Author: Iain Lane <iainl gnome org>
Date:   Mon Jul 1 18:39:44 2019 +0100

    notification: Handle snap applications
    
    When a non-relocatable application is packaged as a snap, its resources
    will be visible under `${SNAP}`. We can discover these resources by
    probing paths that are given to us and trying the same path under
    `${SNAP}` if the probe fails.
    
    Snap packages have desktop files namespaced by the snap name. This name
    is available inside the snap environment as `${SNAP_NAME}`. Also probe
    desktop files and try this form of mangled name if the referenced
    desktop file is not found.

 libnotify/notification.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)
---
diff --git a/libnotify/notification.c b/libnotify/notification.c
index 88bbf2a..c4f9be5 100644
--- a/libnotify/notification.c
+++ b/libnotify/notification.c
@@ -425,6 +425,74 @@ notify_notification_new (const char *summary,
                              NULL);
 }
 
+static gchar *
+try_prepend_path (const char *base_path,
+                  const char *path)
+{
+        gchar *path_filename;
+        gchar *path_ret;
+
+        if (!path || *path == '\0')
+                return NULL;
+
+        path_ret = NULL;
+        path_filename = g_filename_from_uri (base_path, NULL, NULL);
+
+        if (path_filename == NULL) {
+                if (base_path && base_path[0] == G_DIR_SEPARATOR) {
+                        path_filename = g_strdup (base_path);
+                } else {
+                        path_filename = realpath (base_path, NULL);
+                }
+        }
+
+        g_debug ("Trying to look at file '%s' in the '%s' prefix.",
+                 base_path,
+                 path);
+
+        path_ret = g_build_filename (path, path_filename, NULL);
+
+        if (!g_file_test (path_ret, G_FILE_TEST_EXISTS)) {
+                g_free (path_ret);
+                path_ret = NULL;
+        }
+
+        g_free (path_filename);
+
+        return path_ret;
+}
+
+static gchar *
+try_prepend_desktop (const gchar *desktop)
+{
+        gchar *ret;
+
+        /*
+         * if it's an absolute path, try prepending $SNAP, otherwise try
+         * $SNAP_NAME_; snap .desktop files are in the format
+         * ${SNAP_NAME}_desktop_file_name
+         */
+        ret = try_prepend_path (desktop, g_getenv ("SNAP"));
+
+        if (ret == NULL) {
+                const gchar *snap_name = g_getenv ("SNAP_NAME");
+
+                if (snap_name != NULL && snap_name[0] != '\0') {
+                        ret = g_strdup_printf ("%s_%s", snap_name, desktop);
+                }
+        }
+
+        return ret;
+}
+
+static gchar *
+try_prepend_snap (const gchar *value)
+{
+        /* hardcoded paths to icons might be relocated under $SNAP */
+        return try_prepend_path (value, g_getenv ("SNAP"));
+}
+
+
 static void
 notify_notification_update_internal (NotifyNotification *notification,
                                      const char         *app_name,
@@ -452,9 +520,17 @@ notify_notification_update_internal (NotifyNotification *notification,
         }
 
         if (notification->priv->icon_name != icon) {
+                gchar *snapped_icon;
                 g_free (notification->priv->icon_name);
                 notification->priv->icon_name = (icon != NULL
                                                  && *icon != '\0' ? g_strdup (icon) : NULL);
+                snapped_icon = try_prepend_desktop (notification->priv->icon_name);
+                if (snapped_icon != NULL) {
+                        g_debug ("Icon updated in snap environment: '%s' -> '%s'\n",
+                                 notification->priv->icon_name, snapped_icon);
+                        g_free (notification->priv->icon_name);
+                        notification->priv->icon_name = snapped_icon;
+                }
                 g_object_notify (G_OBJECT (notification), "icon-name");
         }
 
@@ -779,6 +855,35 @@ notify_notification_set_image_from_pixbuf (NotifyNotification *notification,
         notify_notification_set_hint (notification, hint_name, value);
 }
 
+static GVariant *
+get_parsed_variant (GVariant *variant,
+                    gchar    *(*str_parser)(const gchar *))
+{
+        gchar *parsed = str_parser (g_variant_get_string (variant, NULL));
+
+        if (parsed != NULL) {
+                g_variant_unref (variant);
+                variant = g_variant_new_take_string (parsed);
+        }
+
+        return variant;
+}
+
+static GVariant *
+maybe_parse_snap_hint_value (const gchar *key,
+                             GVariant    *value)
+{
+        if (g_strcmp0 (key, "desktop-entry") == 0) {
+                value = get_parsed_variant (value, try_prepend_desktop);
+        } else if (g_strcmp0 (key, "image-path") == 0 ||
+                   g_strcmp0 (key, "image_path") == 0 ||
+                   g_strcmp0 (key, "sound-file") == 0) {
+                value = get_parsed_variant (value, try_prepend_snap);
+        }
+
+        return value;
+}
+
 /**
  * notify_notification_set_hint:
  * @notification: a #NotifyNotification
@@ -801,6 +906,7 @@ notify_notification_set_hint (NotifyNotification *notification,
         g_return_if_fail (key != NULL && *key != '\0');
 
         if (value != NULL) {
+                value = maybe_parse_snap_hint_value (key, value);
                 g_hash_table_insert (notification->priv->hints,
                                     g_strdup (key),
                                     g_variant_ref_sink (value));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]