Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libnotify for openSUSE:Factory 
checked in at 2022-08-05 19:50:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libnotify (Old)
 and      /work/SRC/openSUSE:Factory/.libnotify.new.1521 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libnotify"

Fri Aug  5 19:50:15 2022 rev:43 rq:992698 version:0.8.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/libnotify/libnotify.changes      2022-05-14 
22:54:44.083183817 +0200
+++ /work/SRC/openSUSE:Factory/.libnotify.new.1521/libnotify.changes    
2022-08-05 19:50:40.417404934 +0200
@@ -1,0 +2,19 @@
+Fri Jul 22 17:31:30 UTC 2022 - Emily Gonyer <emilyyr...@gmail.com>
+
+- Update to version 0.8.1:
+  + Keep version of bindings at 0.7.
+- Changes from version 0.8.0:
+  + Use Desktop Portal Notification when running confined (snap and
+    flatpak).
+  + Now the library acts like a wrapper in such scenario, with some
+    limited.
+  + capabilities, but this will enforce security and user control
+    over the allowed notifications.
+  + notify-send: Handles SIGINT gracefully, closing waiting
+    notification.
+  + Use NotifyClosedReason enum as closed reason return value.
+  + Bump dependency on GLib 2.38.
+  + Various introspection docs improvements and fixes.
+- Use ldconfig_scriptlets macro for post(un) handling.
+
+-------------------------------------------------------------------

Old:
----
  libnotify-0.7.12.tar.xz

New:
----
  libnotify-0.8.1.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libnotify.spec ++++++
--- /var/tmp/diff_new_pack.Bgd2Y4/_old  2022-08-05 19:50:41.921408818 +0200
+++ /var/tmp/diff_new_pack.Bgd2Y4/_new  2022-08-05 19:50:41.925408829 +0200
@@ -17,14 +17,15 @@
 
 
 Name:           libnotify
-Version:        0.7.12
+Version:        0.8.1
 Release:        0
 Summary:        Notifications Library
 License:        LGPL-2.1-or-later
 Group:          Development/Libraries/X11
 URL:            https://galago-project.org/
-Source:         
https://download.gnome.org/sources/libnotify/0.7/%{name}-%{version}.tar.xz
+Source:         
https://download.gnome.org/sources/libnotify/0.8/%{name}-%{version}.tar.xz
 Source99:       baselibs.conf
+
 BuildRequires:  docbook5-xsl-stylesheets
 BuildRequires:  gobject-introspection-devel
 BuildRequires:  gtk-doc
@@ -91,13 +92,11 @@
 %install
 %meson_install
 
-%post -n libnotify4 -p /sbin/ldconfig
-%postun -n libnotify4 -p /sbin/ldconfig
+%ldconfig_scriptlets -n libnotify4
 
 %files -n libnotify4
 %license COPYING
-# README is empty
-%doc AUTHORS NEWS
+%doc AUTHORS NEWS README.md
 %{_libdir}/*.so.*
 
 %files -n typelib-1_0-Notify-0_7

++++++ libnotify-0.7.12.tar.xz -> libnotify-0.8.1.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.12/NEWS new/libnotify-0.8.1/NEWS
--- old/libnotify-0.7.12/NEWS   2022-05-05 18:04:26.352672300 +0200
+++ new/libnotify-0.8.1/NEWS    2022-07-17 15:00:39.000000000 +0200
@@ -1,11 +1,34 @@
-New in 0.7.12
+New in 0.8.1
+============
+
+* Keep version of bindings at 0.7 (#27) [Marco]
+
+Contributors:
+  Marco Trevisan
+
+New in 0.8.0
 ============
 
+* Use Desktop Portal Notification when running confined (snap and flatpak)
+  Now the library acts like a wrapper in such scenario, with some limited
+  capabilities, but this will enforce security and user control over the
+  allowed notifications. [Marco]
+* notify-send: Handles SIGINT gracefully, closing waiting notification [Marco]
+* Use NotifyClosedReason enum as closed reason return value [Marco]
+* Bump dependency on GLib 2.38 [Marco]
+* Various introspection docs improvements and fixes [Marco]
+
+Contributors:
+  Marco Trevisan
+
+New in 0.7.12
+=============
+
 * docs/notify-send: Add --transient option to manpage [Marco]
 * notify-send: Move server capabilities check to a separate function [Marco]
 * notify-send: Add debug message about server not supporting persistence
   [Marco]
-* notification: Include sender-pid hint by default if not provided [Marco] 
+* notification: Include sender-pid hint by default if not provided [Marco]
 * Delete unused notifynotification.xml [Patrick; !25]
 * notification: Bookend calling NotifyActionCallback with temporary ref
   [Logan; #25, !26]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.12/README.md 
new/libnotify-0.8.1/README.md
--- old/libnotify-0.7.12/README.md      2022-05-05 18:04:26.352672300 +0200
+++ new/libnotify-0.8.1/README.md       2022-07-17 15:00:39.000000000 +0200
@@ -7,6 +7,9 @@
 Specification. These notifications can be used to inform the user about an 
event
 or display some form of information without getting in the user's way.
 
+It is also a simple wrapper to send cross-desktop Notifications for sandboxed
+applications using the [XDG Portal Notification API][portal].
+
 ## Notice
 
 For GLib based applications the [GNotification][gnotif] API should be used
@@ -14,3 +17,4 @@
 
 [fdo-spec]: 
https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html
 [gnotif]: https://docs.gtk.org/gio/class.Notification.html
+[portal]: 
https://github.com/flatpak/xdg-desktop-portal/blob/main/data/org.freedesktop.portal.Notification.xml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libnotify-0.7.12/docs/reference/libnotify-sections.txt 
new/libnotify-0.8.1/docs/reference/libnotify-sections.txt
--- old/libnotify-0.7.12/docs/reference/libnotify-sections.txt  2022-05-05 
18:04:26.354672200 +0200
+++ new/libnotify-0.8.1/docs/reference/libnotify-sections.txt   2022-07-17 
15:00:39.000000000 +0200
@@ -4,6 +4,7 @@
 NOTIFY_EXPIRES_NEVER
 <TITLE>NotifyNotification</TITLE>
 NotifyNotification
+NotifyClosedReason
 NotifyUrgency
 NotifyActionCallback
 NOTIFY_ACTION_CALLBACK
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.12/libnotify/internal.h 
new/libnotify-0.8.1/libnotify/internal.h
--- old/libnotify-0.7.12/libnotify/internal.h   2022-05-05 18:04:26.355672400 
+0200
+++ new/libnotify-0.8.1/libnotify/internal.h    2022-07-17 15:00:39.000000000 
+0200
@@ -26,6 +26,10 @@
 #define NOTIFY_DBUS_CORE_INTERFACE "org.freedesktop.Notifications"
 #define NOTIFY_DBUS_CORE_OBJECT    "/org/freedesktop/Notifications"
 
+#define NOTIFY_PORTAL_DBUS_NAME           "org.freedesktop.portal.Desktop"
+#define NOTIFY_PORTAL_DBUS_CORE_INTERFACE "org.freedesktop.portal.Notification"
+#define NOTIFY_PORTAL_DBUS_CORE_OBJECT    "/org/freedesktop/portal/desktop"
+
 G_BEGIN_DECLS
 
 GDBusProxy      * _notify_get_proxy                         (GError **error);
@@ -36,6 +40,14 @@
 gboolean        _notify_notification_has_nondefault_actions (const 
NotifyNotification *n);
 gboolean        _notify_check_spec_version                  (int major, int 
minor);
 
+const char     * _notify_get_snap_name                      (void);
+const char     * _notify_get_snap_path                      (void);
+const char     * _notify_get_snap_app                       (void);
+
+const char     * _notify_get_flatpak_app                    (void);
+
+gboolean        _notify_uses_portal_notifications           (void);
+
 G_END_DECLS
 
 #endif /* _LIBNOTIFY_INTERNAL_H_ */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.12/libnotify/notification.c 
new/libnotify-0.8.1/libnotify/notification.c
--- old/libnotify-0.7.12/libnotify/notification.c       2022-05-05 
18:04:26.356672300 +0200
+++ new/libnotify-0.8.1/libnotify/notification.c        2022-07-17 
15:00:39.000000000 +0200
@@ -53,6 +53,7 @@
 static void     notify_notification_class_init (NotifyNotificationClass 
*klass);
 static void     notify_notification_init       (NotifyNotification *sp);
 static void     notify_notification_finalize   (GObject            *object);
+static void     notify_notification_dispose    (GObject            *object);
 
 typedef struct
 {
@@ -70,12 +71,9 @@
         char           *body;
         char           *activation_token;
 
-        const char     *snap_path;
-        const char     *snap_name;
-        char           *snap_app;
-
         /* NULL to use icon data. Anything else to have server lookup icon */
         char           *icon_name;
+        GdkPixbuf      *icon_pixbuf;
 
         /*
          * -1   = use server default
@@ -83,6 +81,7 @@
          *  > 0 = Number of milliseconds before we timeout
          */
         gint            timeout;
+        guint           portal_timeout_id;
 
         GSList         *actions;
         GHashTable     *action_map;
@@ -154,6 +153,7 @@
         object_class->constructor = notify_notification_constructor;
         object_class->get_property = notify_notification_get_property;
         object_class->set_property = notify_notification_set_property;
+        object_class->dispose = notify_notification_dispose;
         object_class->finalize = notify_notification_finalize;
 
         /**
@@ -238,9 +238,9 @@
                                          g_param_spec_int ("closed-reason",
                                                            "Closed Reason",
                                                            "The reason code 
for why the notification was closed",
-                                                           -1,
+                                                           
NOTIFY_CLOSED_REASON_UNSET,
                                                            G_MAXINT32,
-                                                           -1,
+                                                           
NOTIFY_CLOSED_REASON_UNSET,
                                                            G_PARAM_READABLE
                                                            | 
G_PARAM_STATIC_NAME
                                                            | 
G_PARAM_STATIC_NICK
@@ -357,109 +357,11 @@
 }
 
 static void
-maybe_initialize_snap (NotifyNotification *obj)
-{
-        NotifyNotificationPrivate *priv = obj->priv;
-        gchar *cgroup_contents = NULL;
-
-        priv->snap_path = g_getenv ("SNAP");
-        if (priv->snap_path == NULL)
-                return;
-
-        if (*priv->snap_path == '\0' ||
-            !strchr (priv->snap_path, G_DIR_SEPARATOR)) {
-                priv->snap_path = NULL;
-                return;
-        }
-
-        priv->snap_name = g_getenv ("SNAP_NAME");
-        if (priv->snap_name && *priv->snap_name == '\0') {
-                priv->snap_name = NULL;
-        }
-
-        if (g_file_get_contents ("/proc/self/cgroup", &cgroup_contents,
-                                 NULL, NULL)) {
-                gchar **lines = g_strsplit (cgroup_contents, "\n", -1);
-                gchar *found_snap_name = NULL;
-                gint i;
-
-                for (i = 0; lines[i]; ++i) {
-                        gchar **parts = g_strsplit (lines[i], ":", 3);
-                        gchar *basename;
-                        gchar **ns;
-                        guint ns_length;
-
-                        if (g_strv_length (parts) != 3) {
-                                g_strfreev (parts);
-                                continue;
-                        }
-
-                        basename = g_path_get_basename (parts[2]);
-                        g_strfreev (parts);
-
-                        if (!basename) {
-                                continue;
-                        }
-
-                        ns = g_strsplit (basename, ".", -1);
-                        ns_length = g_strv_length (ns);
-                        g_free (basename);
-
-                        if (ns_length < 2 || !g_str_equal (ns[0], "snap")) {
-                                g_strfreev (ns);
-                                continue;
-                        }
-
-                        if (priv->snap_name == NULL) {
-                                g_free (found_snap_name);
-                                found_snap_name = g_strdup (ns[1]);
-                        }
-
-                        if (ns_length < 3) {
-                                g_strfreev (ns);
-                                continue;
-                        }
-
-                        if (priv->snap_name == NULL) {
-                                priv->snap_name = found_snap_name;
-                                found_snap_name = NULL;
-                        }
-
-                        if (g_str_equal (ns[1], priv->snap_name)) {
-                                priv->snap_app = g_strdup (ns[2]);
-                                g_strfreev (ns);
-                                break;
-                        }
-
-                        g_strfreev (ns);
-                }
-
-                if (priv->snap_name == NULL && found_snap_name != NULL) {
-                        priv->snap_name = found_snap_name;
-                        found_snap_name = NULL;
-                }
-
-                g_strfreev (lines);
-                g_free (found_snap_name);
-        }
-
-        if (priv->snap_app == NULL) {
-                priv->snap_app = g_strdup (priv->snap_name);
-        }
-
-        g_debug ("SNAP path: %s", priv->snap_path);
-        g_debug ("SNAP name: %s", priv->snap_name);
-        g_debug ("SNAP app: %s", priv->snap_app);
-
-        g_free (cgroup_contents);
-}
-
-static void
 notify_notification_init (NotifyNotification *obj)
 {
         obj->priv = g_new0 (NotifyNotificationPrivate, 1);
         obj->priv->timeout = NOTIFY_EXPIRES_DEFAULT;
-        obj->priv->closed_reason = -1;
+        obj->priv->closed_reason = NOTIFY_CLOSED_REASON_UNSET;
         obj->priv->hints = g_hash_table_new_full (g_str_hash,
                                                   g_str_equal,
                                                   g_free,
@@ -469,8 +371,22 @@
                                                        g_str_equal,
                                                        g_free,
                                                        (GDestroyNotify) 
destroy_pair);
+}
+
+static void
+notify_notification_dispose (GObject *object)
+{
+        NotifyNotification        *obj = NOTIFY_NOTIFICATION (object);
+        NotifyNotificationPrivate *priv = obj->priv;
 
-        maybe_initialize_snap (obj);
+        if (priv->portal_timeout_id) {
+                g_source_remove (priv->portal_timeout_id);
+                priv->portal_timeout_id = 0;
+        }
+
+        g_clear_object (&priv->icon_pixbuf);
+
+        G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 static void
@@ -487,7 +403,6 @@
         g_free (priv->body);
         g_free (priv->icon_name);
         g_free (priv->activation_token);
-        g_free (priv->snap_app);
 
         if (priv->actions != NULL) {
                 g_slist_foreach (priv->actions, (GFunc) g_free, NULL);
@@ -510,6 +425,18 @@
         G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+static gboolean
+maybe_warn_portal_unsupported_feature (const char *feature_name)
+{
+        if (!_notify_uses_portal_notifications ()) {
+                return FALSE;
+        }
+
+        g_message ("%s is not available when using Portal Notifications",
+                   feature_name);
+        return TRUE;
+}
+
 /**
  * notify_notification_new:
  * @summary: The required summary text.
@@ -596,7 +523,6 @@
 try_prepend_snap_desktop (NotifyNotification *notification,
                           const gchar        *desktop)
 {
-        NotifyNotificationPrivate *priv = notification->priv;
         gchar *ret = NULL;
 
         /*
@@ -604,11 +530,11 @@
          * ${SNAP_NAME}_; snap .desktop files are in the format
          * ${SNAP_NAME}_desktop_file_name
          */
-        ret = try_prepend_path (desktop, priv->snap_path);
+        ret = try_prepend_path (desktop, _notify_get_snap_path ());
 
-        if (ret == NULL && priv->snap_name != NULL &&
+        if (ret == NULL && _notify_get_snap_name () != NULL &&
             strchr (desktop, G_DIR_SEPARATOR) == NULL) {
-                ret = g_strdup_printf ("%s_%s", priv->snap_name, desktop);
+                ret = g_strdup_printf ("%s_%s", _notify_get_snap_name (), 
desktop);
         }
 
         return ret;
@@ -619,7 +545,7 @@
                   const gchar        *value)
 {
         /* hardcoded paths to icons might be relocated under $SNAP */
-        return try_prepend_path (value, notification->priv->snap_path);
+        return try_prepend_path (value, _notify_get_snap_path ());
 }
 
 
@@ -698,6 +624,80 @@
         return TRUE;
 }
 
+static char *
+get_portal_notification_id (NotifyNotification *notification)
+{
+        char *app_id;
+        char *notification_id;
+
+        g_assert (_notify_uses_portal_notifications ());
+
+        if (_notify_get_snap_name ()) {
+                app_id = g_strdup_printf ("snap.%s_%s",
+                                          _notify_get_snap_name (),
+                                          _notify_get_snap_app ());
+        } else {
+                app_id = g_strdup_printf ("flatpak.%s",
+                                          _notify_get_flatpak_app ());
+        }
+
+        notification_id = g_strdup_printf ("libnotify-%s-%s-%u",
+                                           app_id,
+                                           notify_get_app_name (),
+                                           notification->priv->id);
+
+        g_free (app_id);
+
+        return notification_id;
+}
+
+static gboolean
+activate_action (NotifyNotification *notification,
+                 const gchar        *action)
+{
+        CallbackPair *pair;
+
+        pair = g_hash_table_lookup (notification->priv->action_map, action);
+
+        if (!pair) {
+                return FALSE;
+        }
+
+        /* Some clients have assumed it is safe to unref the
+         * Notification at the end of their NotifyActionCallback
+         * so we add a temporary ref until we're done with it.
+         */
+        g_object_ref (notification);
+
+        notification->priv->activating = TRUE;
+        pair->cb (notification, (char *) action, pair->user_data);
+        notification->priv->activating = FALSE;
+        g_free (notification->priv->activation_token);
+        notification->priv->activation_token = NULL;
+
+        g_object_unref (notification);
+
+        return TRUE;
+}
+
+static gboolean
+close_notification (NotifyNotification *notification,
+                    NotifyClosedReason  reason)
+{
+        if (notification->priv->closed_reason != NOTIFY_CLOSED_REASON_UNSET ||
+            reason == NOTIFY_CLOSED_REASON_UNSET) {
+                return FALSE;
+        }
+
+        g_object_ref (G_OBJECT (notification));
+        notification->priv->closed_reason = reason;
+        g_signal_emit (notification, signals[SIGNAL_CLOSED], 0);
+        notification->priv->id = 0;
+        g_object_unref (G_OBJECT (notification));
+
+        return TRUE;
+}
+
 static void
 proxy_g_signal_cb (GDBusProxy *proxy,
                    const char *sender_name,
@@ -705,8 +705,12 @@
                    GVariant   *parameters,
                    NotifyNotification *notification)
 {
+        const char *interface;
+
         g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
 
+        interface = g_dbus_proxy_get_interface_name (proxy);
+
         if (g_strcmp0 (signal_name, "NotificationClosed") == 0 &&
             g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(uu)"))) {
                 guint32 id, reason;
@@ -715,43 +719,21 @@
                 if (id != notification->priv->id)
                         return;
 
-                g_object_ref (G_OBJECT (notification));
-                notification->priv->closed_reason = reason;
-                g_signal_emit (notification, signals[SIGNAL_CLOSED], 0);
-                notification->priv->id = 0;
-                g_object_unref (G_OBJECT (notification));
+                close_notification (notification, reason);
         } else if (g_strcmp0 (signal_name, "ActionInvoked") == 0 &&
+                   g_str_equal (interface, NOTIFY_DBUS_CORE_INTERFACE) &&
                    g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(us)"))) 
{
                 guint32 id;
                 const char *action;
-                CallbackPair *pair;
 
                 g_variant_get (parameters, "(u&s)", &id, &action);
 
                 if (id != notification->priv->id)
                         return;
 
-                pair = (CallbackPair *) g_hash_table_lookup 
(notification->priv->action_map,
-                                                            action);
-
-                if (pair == NULL) {
-                        if (g_ascii_strcasecmp (action, "default")) {
-                                g_warning ("Received unknown action %s", 
action);
-                        }
-                } else {
-                        /* Some clients have assumed it is safe to unref the
-                         * Notification at the end of their 
NotifyActionCallback
-                         * so we add a temporary ref until we're done with it.
-                         */
-                        g_object_ref (notification);
-
-                        notification->priv->activating = TRUE;
-                        pair->cb (notification, (char *) action, 
pair->user_data);
-                        notification->priv->activating = FALSE;
-                        g_free (notification->priv->activation_token);
-                        notification->priv->activation_token = NULL;
-
-                        g_object_unref (notification);
+                if (!activate_action (notification, action) &&
+                    g_ascii_strcasecmp (action, "default")) {
+                        g_warning ("Received unknown action %s", action);
                 }
         } else if (g_strcmp0 (signal_name, "ActivationToken") == 0 &&
                    g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(us)"))) 
{
@@ -765,7 +747,304 @@
 
                 g_free (notification->priv->activation_token);
                 notification->priv->activation_token = g_strdup 
(activation_token);
+        } else if (g_str_equal (signal_name, "ActionInvoked") &&
+                   g_str_equal (interface, NOTIFY_PORTAL_DBUS_CORE_INTERFACE) 
&&
+                   g_variant_is_of_type (parameters, G_VARIANT_TYPE 
("(ssav)"))) {
+                char *notification_id;
+                const char *id;
+                const char *action;
+                GVariant *parameter;
+
+                g_variant_get (parameters, "(&s&s@av)", &id, &action, 
&parameter);
+                g_variant_unref (parameter);
+
+                notification_id = get_portal_notification_id (notification);
+
+                if (!g_str_equal (notification_id, id)) {
+                        g_free (notification_id);
+                        return;
+                }
+
+                if (!activate_action (notification, action) &&
+                    g_str_equal (action, "default-action") &&
+                    !_notify_get_snap_app ()) {
+                        g_warning ("Received unknown action %s", action);
+                }
+
+                close_notification (notification, 
NOTIFY_CLOSED_REASON_DISMISSED);
+
+                g_free (notification_id);
+        } else {
+                g_debug ("Unhandled signal '%s.%s'", interface, signal_name);
+        }
+}
+
+static gboolean
+remove_portal_notification (GDBusProxy         *proxy,
+                            NotifyNotification *notification,
+                            NotifyClosedReason  reason,
+                            GError            **error)
+{
+        GVariant *ret;
+        gchar *notification_id;
+
+        if (notification->priv->portal_timeout_id) {
+                g_source_remove (notification->priv->portal_timeout_id);
+                notification->priv->portal_timeout_id = 0;
+        }
+
+        notification_id = get_portal_notification_id (notification);
+
+        ret = g_dbus_proxy_call_sync (proxy,
+                                      "RemoveNotification",
+                                      g_variant_new ("(s)", notification_id),
+                                      G_DBUS_CALL_FLAGS_NONE,
+                                      -1,
+                                      NULL,
+                                      error);
+
+        g_free (notification_id);
+
+        if (!ret) {
+                return FALSE;
+        }
+
+        close_notification (notification, reason);
+
+        g_variant_unref (ret);
+
+        return TRUE;
+}
+
+static gboolean
+on_portal_timeout (gpointer data)
+{
+        NotifyNotification *notification = data;
+        GDBusProxy *proxy;
+
+        notification->priv->portal_timeout_id = 0;
+
+        proxy = _notify_get_proxy (NULL);
+        if (proxy == NULL) {
+                return FALSE;
+        }
+
+        remove_portal_notification (proxy, notification,
+                                    NOTIFY_CLOSED_REASON_EXPIRED, NULL);
+        return FALSE;
+}
+
+static GIcon *
+get_notification_gicon (NotifyNotification  *notification,
+                        GError             **error)
+{
+        NotifyNotificationPrivate *priv = notification->priv;
+        GFileInputStream *input;
+        GFile *file = NULL;
+        GIcon *gicon = NULL;
+
+        if (priv->icon_pixbuf) {
+                return G_ICON (g_object_ref (priv->icon_pixbuf));
+        }
+
+        if (!priv->icon_name) {
+                return NULL;
+        }
+
+        if (strstr (priv->icon_name, "://")) {
+                file = g_file_new_for_uri (priv->icon_name);
+        } else if (g_file_test (priv->icon_name, G_FILE_TEST_EXISTS)) {
+                file = g_file_new_for_path (priv->icon_name);
+        } else {
+                gicon = g_themed_icon_new (priv->icon_name);
+        }
+
+        if (!file) {
+                return gicon;
+        }
+
+        input = g_file_read (file, NULL, error);
+
+        if (input) {
+                GByteArray *bytes_array = g_byte_array_new ();
+                guint8 buf[1024];
+
+                while (TRUE) {
+                        gssize read;
+
+                        read = g_input_stream_read (G_INPUT_STREAM (input),
+                                                    buf,
+                                                    G_N_ELEMENTS (buf),
+                                                    NULL, NULL);
+
+                        if (read > 0) {
+                                g_byte_array_append (bytes_array, buf, read);
+                        } else {
+                                if (read < 0) {
+                                        g_byte_array_unref (bytes_array);
+                                        bytes_array = NULL;
+                                }
+
+                                break;
+                        }
+                }
+
+                if (bytes_array && bytes_array->len) {
+                        GBytes *bytes;
+
+                        bytes = g_byte_array_free_to_bytes (bytes_array);
+                        bytes_array = NULL;
+
+                        gicon = g_bytes_icon_new (bytes);
+                } else if (bytes_array) {
+                        g_byte_array_unref (bytes_array);
+                }
         }
+
+        g_clear_object (&input);
+        g_clear_object (&file);
+
+        return gicon;
+}
+
+static gboolean
+add_portal_notification (GDBusProxy         *proxy,
+                         NotifyNotification *notification,
+                         GError            **error)
+{
+        GIcon *icon;
+        GVariant *urgency;
+        GVariant *ret;
+        GVariantBuilder builder;
+        NotifyNotificationPrivate *priv = notification->priv;
+        GError *local_error = NULL;
+        static guint32 portal_notification_count = 0;
+        char *notification_id;
+
+        g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+
+        g_variant_builder_add (&builder, "{sv}", "title",
+                               g_variant_new_string (priv->summary ? 
priv->summary : ""));
+        g_variant_builder_add (&builder, "{sv}", "body",
+                               g_variant_new_string (priv->body ? priv->body : 
""));
+
+        if (g_hash_table_lookup (priv->action_map, "default")) {
+                g_variant_builder_add (&builder, "{sv}", "default-action",
+                                       g_variant_new_string ("default"));
+        } else if (g_hash_table_lookup (priv->action_map, "DEFAULT")) {
+                g_variant_builder_add (&builder, "{sv}", "default-action",
+                                       g_variant_new_string ("DEFAULT"));
+        } else if (_notify_get_snap_app ()) {
+                /* In the snap case we may need to ensure that a default-action
+                 * is set to ensure that we will use the FDO notification 
daemon
+                 * and won't fallback to GTK one, as app-id won't match.
+                 * See: 
https://github.com/flatpak/xdg-desktop-portal/issues/769
+                 */
+                g_variant_builder_add (&builder, "{sv}", "default-action",
+                                       g_variant_new_string 
("snap-fake-default-action"));
+        }
+
+        if (priv->has_nondefault_actions) {
+                GVariantBuilder buttons;
+                GSList *l;
+
+                g_variant_builder_init (&buttons, G_VARIANT_TYPE ("aa{sv}"));
+
+                for (l = priv->actions; l && l->next; l = l->next->next) {
+                        GVariantBuilder button;
+                        const char *action;
+                        const char *label;
+
+                        g_variant_builder_init (&button, 
G_VARIANT_TYPE_VARDICT);
+
+                        action = l->data;
+                        label = l->next->data;
+
+                        g_variant_builder_add (&button, "{sv}", "action",
+                                               g_variant_new_string (action));
+                        g_variant_builder_add (&button, "{sv}", "label",
+                                               g_variant_new_string (label));
+
+                        g_variant_builder_add (&buttons, "@a{sv}",
+                                               g_variant_builder_end 
(&button));
+                }
+
+                g_variant_builder_add (&builder, "{sv}", "buttons",
+                                       g_variant_builder_end (&buttons));
+        }
+
+        urgency = g_hash_table_lookup (notification->priv->hints, "urgency");
+        if (urgency) {
+                switch (g_variant_get_byte (urgency)) {
+                case NOTIFY_URGENCY_LOW:
+                        g_variant_builder_add (&builder, "{sv}", "priority",
+                                               g_variant_new_string ("low"));
+                        break;
+                case NOTIFY_URGENCY_NORMAL:
+                        g_variant_builder_add (&builder, "{sv}", "priority",
+                                               g_variant_new_string 
("normal"));
+                        break;
+                case NOTIFY_URGENCY_CRITICAL:
+                        g_variant_builder_add (&builder, "{sv}", "priority",
+                                               g_variant_new_string 
("urgent"));
+                        break;
+                default:
+                        g_warn_if_reached ();
+                }
+        }
+
+        icon = get_notification_gicon (notification, &local_error);
+        if (icon) {
+                GVariant *serialized_icon = g_icon_serialize (icon);
+
+                g_variant_builder_add (&builder, "{sv}", "icon",
+                                       serialized_icon);
+                g_variant_unref (serialized_icon);
+                g_clear_object (&icon);
+        } else if (local_error) {
+                g_propagate_error (error, local_error);
+                return FALSE;
+        }
+
+        if (!priv->id) {
+                priv->id = ++portal_notification_count;
+        } else if (priv->closed_reason == NOTIFY_CLOSED_REASON_UNSET) {
+                remove_portal_notification (proxy, notification,
+                                            NOTIFY_CLOSED_REASON_UNSET, NULL);
+        }
+
+        notification_id = get_portal_notification_id (notification);
+
+        ret = g_dbus_proxy_call_sync (proxy,
+                                      "AddNotification",
+                                      g_variant_new ("(s@a{sv})",
+                                                     notification_id,
+                                                     g_variant_builder_end 
(&builder)),
+                                      G_DBUS_CALL_FLAGS_NONE,
+                                      -1,
+                                      NULL,
+                                      error);
+
+        if (priv->portal_timeout_id) {
+                g_source_remove (priv->portal_timeout_id);
+                priv->portal_timeout_id = 0;
+        }
+
+        g_free (notification_id);
+
+        if (!ret) {
+                return FALSE;
+        }
+
+        if (priv->timeout > 0) {
+                priv->portal_timeout_id = g_timeout_add (priv->timeout,
+                                                         on_portal_timeout,
+                                                         notification);
+        }
+
+        g_variant_unref (ret);
+
+        return TRUE;
 }
 
 /**
@@ -789,9 +1068,7 @@
         GHashTableIter             iter;
         gpointer                   key, data;
         GVariant                  *result;
-#ifdef GLIB_VERSION_2_32
         GApplication              *application = NULL;
-#endif
 
         g_return_val_if_fail (notification != NULL, FALSE);
         g_return_val_if_fail (NOTIFY_IS_NOTIFICATION (notification), FALSE);
@@ -815,6 +1092,10 @@
                                                                notification);
         }
 
+        if (_notify_uses_portal_notifications ()) {
+                return add_portal_notification (proxy, notification, error);
+        }
+
         g_variant_builder_init (&actions_builder, G_VARIANT_TYPE ("as"));
         for (l = priv->actions; l != NULL; l = l->next) {
                 g_variant_builder_add (&actions_builder, "s", l->data);
@@ -831,13 +1112,13 @@
                                        g_variant_new_int64 (getpid ()));
         }
 
-        if (priv->snap_app &&
+        if (_notify_get_snap_app () &&
             g_hash_table_lookup (priv->hints, "desktop-entry") == NULL) {
                 gchar *snap_desktop;
 
                 snap_desktop = g_strdup_printf ("%s_%s",
-                                                priv->snap_name,
-                                                priv->snap_app);
+                                                _notify_get_snap_name (),
+                                                _notify_get_snap_app ());
 
                 g_debug ("Using desktop entry: %s", snap_desktop);
                 g_variant_builder_add (&hints_builder, "{sv}",
@@ -845,8 +1126,7 @@
                                        g_variant_new_take_string 
(snap_desktop));
         }
 
-#ifdef GLIB_VERSION_2_32
-        if (!priv->snap_app) {
+        if (!_notify_get_snap_app ()) {
                 application = g_application_get_default ();
         }
 
@@ -861,7 +1141,6 @@
                                        g_variant_new_string (application_id));
             }
         }
-#endif
 
         /* TODO: make this nonblocking */
         result = g_dbus_proxy_call_sync (proxy,
@@ -940,6 +1219,10 @@
         g_return_if_fail (notification != NULL);
         g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
 
+        if (maybe_warn_portal_unsupported_feature ("Category")) {
+                return;
+        }
+
         if (category != NULL && category[0] != '\0') {
                 notify_notification_set_hint_string (notification,
                                                      "category",
@@ -1017,11 +1300,18 @@
                 hint_name = "icon_data";
         }
 
+        g_clear_object (&notification->priv->icon_pixbuf);
+
         if (pixbuf == NULL) {
                 notify_notification_set_hint (notification, hint_name, NULL);
                 return;
         }
 
+        if (_notify_uses_portal_notifications ()) {
+                notification->priv->icon_pixbuf = g_object_ref (pixbuf);
+                return;
+        }
+
         g_object_get (pixbuf,
                       "width", &width,
                       "height", &height,
@@ -1078,7 +1368,7 @@
 {
         StringParserFunc parse_func = NULL;
 
-        if (!notification->priv->snap_path)
+        if (!_notify_get_snap_path ())
                 return value;
 
         if (g_strcmp0 (key, "desktop-entry") == 0) {
@@ -1145,6 +1435,10 @@
 {
         g_return_if_fail (NOTIFY_IS_NOTIFICATION (notification));
 
+        if (maybe_warn_portal_unsupported_feature ("App Name")) {
+                return;
+        }
+
         g_free (notification->priv->app_name);
         notification->priv->app_name = g_strdup (app_name);
 
@@ -1385,6 +1679,7 @@
 
 /**
  * notify_notification_get_activation_token:
+ * @notification: The notification.
  *
  * If an an action is currently being activated, return the activation token.
  * This function is intended to be used in a #NotifyActionCallback to get
@@ -1399,11 +1694,9 @@
 notify_notification_get_activation_token (NotifyNotification *notification)
 {
         g_return_val_if_fail (NOTIFY_IS_NOTIFICATION (notification), NULL);
+        g_return_val_if_fail (notification->priv->activating, NULL);
 
-        if (notification->priv->activating)
-                return notification->priv->activation_token;
-
-        return NULL;
+        return notification->priv->activation_token;
 }
 
 gboolean
@@ -1442,6 +1735,12 @@
                 return FALSE;
         }
 
+        if (_notify_uses_portal_notifications ()) {
+                return remove_portal_notification (proxy, notification,
+                                                   
NOTIFY_CLOSED_REASON_API_REQUEST,
+                                                   error);
+        }
+
         /* FIXME: make this nonblocking! */
         result = g_dbus_proxy_call_sync (proxy,
                                          "CloseNotification",
@@ -1466,13 +1765,17 @@
  * Returns the closed reason code for the notification. This is valid only
  * after the "closed" signal is emitted.
  *
- * Returns: The closed reason code.
+ * Since version 0.8.0 the returned value is of type #NotifyClosedReason.
+ *
+ * Returns: An integer representing the closed reason code
+ *  (Since 0.8.0 it's also a #NotifyClosedReason).
  */
 gint
 notify_notification_get_closed_reason (const NotifyNotification *notification)
 {
-        g_return_val_if_fail (notification != NULL, -1);
-        g_return_val_if_fail (NOTIFY_IS_NOTIFICATION (notification), -1);
+        g_return_val_if_fail (notification != NULL, 
NOTIFY_CLOSED_REASON_UNSET);
+        g_return_val_if_fail (NOTIFY_IS_NOTIFICATION (notification),
+                              NOTIFY_CLOSED_REASON_UNSET);
 
         return notification->priv->closed_reason;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.12/libnotify/notification.h 
new/libnotify-0.8.1/libnotify/notification.h
--- old/libnotify-0.7.12/libnotify/notification.h       2022-05-05 
18:04:26.357672200 +0200
+++ new/libnotify-0.8.1/libnotify/notification.h        2022-07-17 
15:00:39.000000000 +0200
@@ -55,6 +55,11 @@
 typedef struct _NotifyNotificationClass NotifyNotificationClass;
 typedef struct _NotifyNotificationPrivate NotifyNotificationPrivate;
 
+/**
+ * NotifyNotification:
+ *
+ * A passive pop-up notification.
+ */
 struct _NotifyNotification
 {
         /*< private >*/
@@ -88,11 +93,34 @@
 
 } NotifyUrgency;
 
+
+/**
+ * NotifyClosedReason:
+ * @NOTIFY_CLOSED_REASON_UNSET: Notification not closed.
+ * @NOTIFY_CLOSED_REASON_EXPIRED: Timeout has expired.
+ * @NOTIFY_CLOSED_REASON_DISMISSED: It has been dismissed by the user.
+ * @NOTIFY_CLOSED_REASON_API_REQUEST: It has been closed by a call to
+ *   notify_notification_close().
+ * @NOTIFY_CLOSED_REASON_UNDEFIEND: Closed by undefined/reserved reasons.
+ *
+ * The reason for which the notification has been closed.
+ *
+ * Since: 0.8.0
+ */
+typedef enum
+{
+        NOTIFY_CLOSED_REASON_UNSET = -1,
+        NOTIFY_CLOSED_REASON_EXPIRED = 1,
+        NOTIFY_CLOSED_REASON_DISMISSED = 2,
+        NOTIFY_CLOSED_REASON_API_REQUEST = 3,
+        NOTIFY_CLOSED_REASON_UNDEFIEND = 4,
+} NotifyClosedReason;
+
 /**
  * NotifyActionCallback:
- * @notification:
- * @action:
- * @user_data:
+ * @notification: a #NotifyActionCallback notification
+ * @action: (transfer none): The activated action name
+ * @user_data: (nullable) (transfer none): User provided data
  *
  * An action callback function.
  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.12/libnotify/notify.c 
new/libnotify-0.8.1/libnotify/notify.c
--- old/libnotify-0.7.12/libnotify/notify.c     2022-05-05 18:04:26.359672300 
+0200
+++ new/libnotify-0.8.1/libnotify/notify.c      2022-07-17 15:00:39.000000000 
+0200
@@ -43,10 +43,14 @@
 
 static gboolean         _initted = FALSE;
 static char            *_app_name = NULL;
+static char            *_snap_name = NULL;
+static char            *_snap_app = NULL;
+static char            *_flatpak_app = NULL;
 static GDBusProxy      *_proxy = NULL;
 static GList           *_active_notifications = NULL;
 static int              _spec_version_major = 0;
 static int              _spec_version_minor = 0;
+static int              _portal_version = 0;
 
 gboolean
 _notify_check_spec_version (int major,
@@ -74,6 +78,26 @@
                 return FALSE;
         }
 
+        if (_notify_uses_portal_notifications ()) {
+                if (ret_name) {
+                        *ret_name = g_strdup ("Portal Notification");
+                }
+
+                if (ret_vendor) {
+                        *ret_vendor = g_strdup ("Freedesktop");
+                }
+
+                if (ret_version) {
+                        *ret_version = g_strdup_printf ("%u", _portal_version);
+                }
+
+                if (ret_spec_version) {
+                        *ret_spec_version = g_strdup ("1.2");
+                }
+
+                return TRUE;
+        }
+
         result = g_dbus_proxy_call_sync (proxy,
                                          "GetServerInformation",
                                          g_variant_new ("()"),
@@ -119,6 +143,18 @@
        return TRUE;
 }
 
+static gboolean
+set_app_name (const char *app_name)
+{
+        g_return_val_if_fail (app_name != NULL, FALSE);
+        g_return_val_if_fail (*app_name != '\0', FALSE);
+
+        g_free (_app_name);
+        _app_name = g_strdup (app_name);
+
+        return TRUE;
+}
+
 
 /**
  * notify_set_app_name:
@@ -130,46 +166,267 @@
 void
 notify_set_app_name (const char *app_name)
 {
-        g_free (_app_name);
-        _app_name = g_strdup (app_name);
+        set_app_name (app_name);
 }
 
 /**
  * notify_init:
- * @app_name: The name of the application initializing libnotify.
+ * @app_name: (nullable): The name of the application initializing libnotify.
  *
  * Initialized libnotify. This must be called before any other functions.
  *
+ * Starting from 0.8, if the provided @app_name is %NULL, libnotify will
+ * try to figure it out from the running application.
+ * Before it was not allowed, and was causing libnotify not to be initialized.
+ *
  * Returns: %TRUE if successful, or %FALSE on error.
  */
 gboolean
 notify_init (const char *app_name)
 {
-        g_return_val_if_fail (app_name != NULL, FALSE);
-        g_return_val_if_fail (*app_name != '\0', FALSE);
-
         if (_initted)
                 return TRUE;
 
-#ifdef GLIB_VERSION_2_32
-        if (app_name == NULL && g_application_get_default ()) {
-                GApplication *application = g_application_get_default ();
+        if (app_name == NULL) {
+                GApplication *application;
 
-                app_name = g_application_get_application_id (application);
-        }
-#endif
+                app_name = _notify_get_snap_app ();
+                if (app_name == NULL) {
+                        app_name = _notify_get_flatpak_app ();
+                }
 
-        notify_set_app_name (app_name);
+                if (app_name == NULL &&
+                    (application = g_application_get_default ())) {
+                        app_name = g_application_get_application_id 
(application);
+                }
+        }
 
-#ifndef GLIB_VERSION_2_36
-        g_type_init ();
-#endif
+        if (!set_app_name (app_name)) {
+                return FALSE;
+        }
 
         _initted = TRUE;
 
         return TRUE;
 }
 
+static void
+_initialize_snap_names (void)
+{
+        gchar *cgroup_contents = NULL;
+        gchar *found_snap_name = NULL;
+        gchar **lines;
+        gint i;
+
+        if (!g_file_get_contents ("/proc/self/cgroup", &cgroup_contents,
+                                  NULL, NULL)) {
+                g_free (cgroup_contents);
+                return;
+        }
+
+        lines = g_strsplit (cgroup_contents, "\n", -1);
+        g_free (cgroup_contents);
+
+        for (i = 0; lines[i]; ++i) {
+                gchar **parts = g_strsplit (lines[i], ":", 3);
+                gchar *basename;
+                gchar **ns;
+                guint ns_length;
+
+                if (g_strv_length (parts) != 3) {
+                        g_strfreev (parts);
+                        continue;
+                }
+
+                basename = g_path_get_basename (parts[2]);
+                g_strfreev (parts);
+
+                if (!basename) {
+                        continue;
+                }
+
+                ns = g_strsplit (basename, ".", -1);
+                ns_length = g_strv_length (ns);
+                g_free (basename);
+
+                if (ns_length < 2 || !g_str_equal (ns[0], "snap")) {
+                        g_strfreev (ns);
+                        continue;
+                }
+
+                if (_snap_name == NULL) {
+                        g_free (found_snap_name);
+                        found_snap_name = g_strdup (ns[1]);
+                }
+
+                if (ns_length < 3) {
+                        g_strfreev (ns);
+                        continue;
+                }
+
+                if (_snap_name == NULL) {
+                        _snap_name = found_snap_name;
+                        found_snap_name = NULL;
+                        g_debug ("SNAP name: %s", _snap_name);
+                }
+
+                if (g_str_equal (ns[1], _snap_name)) {
+                        _snap_app = g_strdup (ns[2]);
+                        g_strfreev (ns);
+                        break;
+                }
+
+                g_strfreev (ns);
+        }
+
+        if (_snap_name == NULL && found_snap_name != NULL) {
+                _snap_name = found_snap_name;
+                found_snap_name = NULL;
+                g_debug ("SNAP name: %s", _snap_name);
+        }
+
+        if (_snap_app == NULL) {
+                _snap_app = g_strdup (_snap_name);
+        }
+
+        g_debug ("SNAP app: %s", _snap_app);
+
+        g_strfreev (lines);
+        g_free (found_snap_name);
+}
+
+const char *
+_notify_get_snap_path (void)
+{
+        static const char *snap_path = NULL;
+        static gsize snap_path_set = FALSE;
+
+        if (g_once_init_enter (&snap_path_set)) {
+                snap_path = g_getenv ("SNAP");
+
+                if (!snap_path || *snap_path == '\0' ||
+                    !strchr (snap_path, G_DIR_SEPARATOR)) {
+                        snap_path = NULL;
+                } else {
+                        g_debug ("SNAP path: %s", snap_path);
+                }
+
+                g_once_init_leave (&snap_path_set, TRUE);
+        }
+
+        return snap_path;
+}
+
+const char *
+_notify_get_snap_name (void)
+{
+        static gsize snap_name_set = FALSE;
+
+        if (g_once_init_enter (&snap_name_set)) {
+                if (!_snap_name) {
+                        const char *snap_name_env = g_getenv ("SNAP_NAME");
+
+                        if (!snap_name_env || *snap_name_env == '\0')
+                                snap_name_env = NULL;
+
+                        _snap_name = g_strdup (snap_name_env);
+                        g_debug ("SNAP name: %s", _snap_name);
+                }
+
+                g_once_init_leave (&snap_name_set, TRUE);
+        }
+
+        return _snap_name;
+}
+
+const char *
+_notify_get_snap_app (void)
+{
+        static gsize snap_app_set = FALSE;
+
+        if (g_once_init_enter (&snap_app_set)) {
+                _initialize_snap_names ();
+                g_once_init_leave (&snap_app_set, TRUE);
+        }
+
+        return _snap_app;
+}
+
+const char *
+_notify_get_flatpak_app (void)
+{
+        static gsize flatpak_app_set = FALSE;
+
+        if (g_once_init_enter (&flatpak_app_set)) {
+                GKeyFile *info = g_key_file_new ();
+
+                if (g_key_file_load_from_file (info, "/.flatpak-info",
+                                               G_KEY_FILE_NONE, NULL)) {
+                        const char *group = "Application";
+
+                        if (g_key_file_has_group (info, "Runtime")) {
+                                group = "Runtime";
+                        }
+
+                        _flatpak_app = g_key_file_get_string (info, group,
+                                                              "name", NULL);
+                }
+
+                g_key_file_free (info);
+                g_once_init_leave (&flatpak_app_set, TRUE);
+        }
+
+        return _flatpak_app;
+}
+
+static gboolean
+_notify_is_running_under_flatpak (void)
+{
+        return !!_notify_get_flatpak_app ();
+}
+
+static gboolean
+_notify_is_running_under_snap (void)
+{
+        return !!_notify_get_snap_app ();
+}
+
+static gboolean
+_notify_is_running_in_sandbox (void)
+{
+        static gsize use_portal = 0;
+        enum {
+                IGNORE_PORTAL = 1,
+                TRY_USE_PORTAL = 2,
+                FORCE_PORTAL = 3
+        };
+
+        if (g_once_init_enter (&use_portal)) {
+                if (G_UNLIKELY (g_getenv ("NOTIFY_IGNORE_PORTAL"))) {
+                        g_once_init_leave (&use_portal, IGNORE_PORTAL);
+                } else if (G_UNLIKELY (g_getenv ("NOTIFY_FORCE_PORTAL"))) {
+                        g_once_init_leave (&use_portal, FORCE_PORTAL);
+                } else {
+                        g_once_init_leave (&use_portal, TRY_USE_PORTAL);
+                }
+        }
+
+        if (use_portal == IGNORE_PORTAL) {
+                return FALSE;
+        }
+
+        return use_portal == FORCE_PORTAL ||
+               _notify_is_running_under_flatpak () ||
+               _notify_is_running_under_snap ();
+}
+
+gboolean
+_notify_uses_portal_notifications (void)
+{
+        return _portal_version != 0;
+}
+
+
 /**
  * notify_get_app_name:
  *
@@ -219,6 +476,15 @@
             _proxy = NULL;
         }
 
+        g_free (_snap_name);
+        _snap_name = NULL;
+
+        g_free (_snap_app);
+        _snap_app = NULL;
+
+        g_free (_flatpak_app);
+        _flatpak_app = NULL;
+
         _initted = FALSE;
 }
 
@@ -235,6 +501,46 @@
         return _initted;
 }
 
+GDBusProxy *
+_get_portal_proxy (GError **error)
+{
+        GError *local_error = NULL;
+        GDBusProxy *proxy;
+        GVariant *res;
+
+        proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                               G_DBUS_PROXY_FLAGS_NONE,
+                                               NULL,
+                                               NOTIFY_PORTAL_DBUS_NAME,
+                                               NOTIFY_PORTAL_DBUS_CORE_OBJECT,
+                                               
NOTIFY_PORTAL_DBUS_CORE_INTERFACE,
+                                               NULL,
+                                               &local_error);
+
+        if (proxy == NULL) {
+                g_debug ("Failed to get portal proxy: %s", 
local_error->message);
+                g_clear_error (&local_error);
+
+                return NULL;
+        }
+
+        res = g_dbus_proxy_get_cached_property (proxy, "version");
+        if (!res) {
+                g_object_unref (proxy);
+                return NULL;
+        }
+
+        _portal_version = g_variant_get_uint32 (res);
+        g_assert (_portal_version > 0);
+
+        g_warning ("Running in confined mode, using Portal notifications. "
+                   "Some features and hints won't be supported");
+
+        g_variant_unref (res);
+
+        return proxy;
+}
+
 /*
  * _notify_get_proxy:
  * @error: (allow-none): a location to store a #GError, or %NULL
@@ -250,6 +556,14 @@
         if (_proxy != NULL)
                 return _proxy;
 
+        if (_notify_is_running_in_sandbox ()) {
+                _proxy = _get_portal_proxy (error);
+
+                if (_proxy != NULL) {
+                        goto out;
+                }
+        }
+
         _proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                                 
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
                                                 NULL,
@@ -258,6 +572,8 @@
                                                 NOTIFY_DBUS_CORE_INTERFACE,
                                                 NULL,
                                                 error);
+
+out:
         if (_proxy == NULL) {
                 return NULL;
         }
@@ -295,6 +611,15 @@
                 return NULL;
         }
 
+        if (_notify_uses_portal_notifications ()) {
+                list = g_list_prepend (list, g_strdup ("actions"));
+                list = g_list_prepend (list, g_strdup ("body"));
+                list = g_list_prepend (list, g_strdup ("body-images"));
+                list = g_list_prepend (list, g_strdup ("icon-static"));
+
+                return list;
+        }
+
         result = g_dbus_proxy_call_sync (proxy,
                                          "GetCapabilities",
                                          g_variant_new ("()"),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.12/meson.build 
new/libnotify-0.8.1/meson.build
--- old/libnotify-0.7.12/meson.build    2022-05-05 18:04:26.360672200 +0200
+++ new/libnotify-0.8.1/meson.build     2022-07-17 15:00:39.000000000 +0200
@@ -1,6 +1,6 @@
 project('libnotify',
   'c',
-  version: '0.7.12',
+  version: '0.8.1',
   meson_version: '>= 0.47.0')
 
 gnome = import('gnome')
@@ -22,8 +22,11 @@
 LT_REVISION=0
 LT_AGE=0
 
+API_VERSION = 7
+
 VERSION_ARRAY = meson.project_version().split('.')
-MODULE_VERSION = '@0@.@1@'.format(VERSION_ARRAY[0], VERSION_ARRAY[1])
+# Minor version is hardcoded until we have a real API break
+MODULE_VERSION = '@0@.@1@'.format(VERSION_ARRAY[0], API_VERSION)
 LIBNAME = meson.project_name().split('lib')[1]
 
 default_includes = include_directories('.')
@@ -36,7 +39,7 @@
 libnotify_deps = []
 extra_deps = []
 
-glib_req_version = '>= 2.26.0'
+glib_req_version = '>= 2.38.0'
 
 gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0')
 glib_dep = dependency('glib-2.0', version: glib_req_version)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.12/tests/test-error.c 
new/libnotify-0.8.1/tests/test-error.c
--- old/libnotify-0.7.12/tests/test-error.c     2022-05-05 18:04:26.363672300 
+0200
+++ new/libnotify-0.8.1/tests/test-error.c      2022-07-17 15:00:39.000000000 
+0200
@@ -29,10 +29,6 @@
 {
         NotifyNotification *n;
 
-#ifndef GLIB_VERSION_2_36
-        g_type_init ();
-#endif
-
         notify_init ("Error Handling");
 
         n = notify_notification_new ("Summary", "Content", NULL);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.12/tests/test-replace.c 
new/libnotify-0.8.1/tests/test-replace.c
--- old/libnotify-0.7.12/tests/test-replace.c   2022-05-05 18:04:26.364672200 
+0200
+++ new/libnotify-0.8.1/tests/test-replace.c    2022-07-17 15:00:39.000000000 
+0200
@@ -28,10 +28,6 @@
         GError             *error;
         error = NULL;
 
-#ifndef GLIB_VERSION_2_36
-        g_type_init ();
-#endif
-
         notify_init ("Replace Test");
 
         n = notify_notification_new ("Summary",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.12/tools/notify-send.c 
new/libnotify-0.8.1/tools/notify-send.c
--- old/libnotify-0.7.12/tools/notify-send.c    2022-05-05 18:04:26.365672300 
+0200
+++ new/libnotify-0.8.1/tools/notify-send.c     2022-07-17 15:00:39.000000000 
+0200
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <glib.h>
+#include <glib-unix.h>
 #include <glib/gprintf.h>
 
 #define N_(x) (x)
@@ -148,6 +149,19 @@
         g_main_loop_quit (loop);
 }
 
+static gboolean
+on_sigint (gpointer data)
+{
+        NotifyNotification *notification = data;
+
+        g_printerr ("Wait cancelled, closing notification\n");
+
+        notify_notification_close (notification, NULL);
+        g_main_loop_quit (loop);
+
+        return FALSE;
+}
+
 static void
 handle_action (NotifyNotification *notify,
                char               *action,
@@ -203,6 +217,10 @@
         static char       **n_text = NULL;
         static char       **hints = NULL;
         static char       **actions = NULL;
+        static char        *server_name = NULL;
+        static char        *server_vendor = NULL;
+        static char        *server_version = NULL;
+        static char        *server_spec_version = NULL;
         static gboolean     print_id = FALSE;
         static gint         notification_id = 0;
         static gboolean     do_version = FALSE;
@@ -265,10 +283,6 @@
 
         setlocale (LC_ALL, "");
 
-#ifndef GLIB_VERSION_2_36
-        g_type_init ();
-#endif
-
         g_set_prgname (argv[0]);
         g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
 
@@ -310,6 +324,18 @@
         if (!notify_init ("notify-send"))
                 exit (1);
 
+        notify_get_server_info (&server_name,
+                                &server_vendor,
+                                &server_version,
+                                &server_spec_version);
+
+        g_debug ("Using sever %s %s, v%s - Supporting Notification Spec %s",
+                 server_name, server_vendor, server_version, 
server_spec_version);
+        g_free (server_name);
+        g_free (server_vendor);
+        g_free (server_version);
+        g_free (server_spec_version);
+
         notify = g_object_new (NOTIFY_TYPE_NOTIFICATION,
                                "summary", summary,
                                "body", body,
@@ -442,6 +468,7 @@
         }
 
         if (wait) {
+                g_unix_signal_add (SIGINT, on_sigint, notify);
                 loop = g_main_loop_new (NULL, FALSE);
                 g_main_loop_run (loop);
                 g_main_loop_unref (loop);

Reply via email to