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-05-08 21:52:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libnotify (Old)
 and      /work/SRC/openSUSE:Factory/.libnotify.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libnotify"

Sun May  8 21:52:25 2022 rev:41 rq:975333 version:0.7.11

Changes:
--------
--- /work/SRC/openSUSE:Factory/libnotify/libnotify.changes      2020-04-13 
12:50:03.808562977 +0200
+++ /work/SRC/openSUSE:Factory/.libnotify.new.1538/libnotify.changes    
2022-05-08 21:52:37.527483735 +0200
@@ -1,0 +2,11 @@
+Thu May  5 09:24:05 UTC 2022 - Christophe Giboudeaux <christo...@krop.fr>
+
+- Update to 0.7.11
+  * Fix potential build errors with old glib version we require
+  * notify-send: Add support for boolean hints
+  * notify-send: Support passing any hint value, by parsing
+    variant strings
+  * notify-send: Add explicit option to create transient
+    notifications
+
+-------------------------------------------------------------------

Old:
----
  libnotify-0.7.9.tar.xz

New:
----
  libnotify-0.7.11.tar.xz

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

Other differences:
------------------
++++++ libnotify.spec ++++++
--- /var/tmp/diff_new_pack.jNULJE/_old  2022-05-08 21:52:37.943484259 +0200
+++ /var/tmp/diff_new_pack.jNULJE/_new  2022-05-08 21:52:37.947484264 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package libnotify
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,16 +17,15 @@
 
 
 Name:           libnotify
-Version:        0.7.9
+Version:        0.7.11
 Release:        0
 Summary:        Notifications Library
 License:        LGPL-2.1-or-later
 Group:          Development/Libraries/X11
-URL:            http://galago-project.org/
+URL:            https://galago-project.org/
 Source:         
https://download.gnome.org/sources/libnotify/0.7/%{name}-%{version}.tar.xz
 Source98:       libnotify-rpmlintrc
 Source99:       baselibs.conf
-
 BuildRequires:  docbook5-xsl-stylesheets
 BuildRequires:  gobject-introspection-devel
 BuildRequires:  gtk-doc
@@ -107,7 +106,7 @@
 
 %files tools
 %{_bindir}/notify-send
-%{_mandir}/man1/notify-send.1%{ext_man}
+%{_mandir}/man1/notify-send.1%{?ext_man}
 
 %files devel
 %{_libdir}/*.so

++++++ libnotify-0.7.9.tar.xz -> libnotify-0.7.11.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/.gitlab-ci.yml 
new/libnotify-0.7.11/.gitlab-ci.yml
--- old/libnotify-0.7.9/.gitlab-ci.yml  1970-01-01 01:00:00.000000000 +0100
+++ new/libnotify-0.7.11/.gitlab-ci.yml 2022-04-27 21:05:49.000000000 +0200
@@ -0,0 +1,37 @@
+variables:
+  DEBIAN_FRONTEND: noninteractive
+
+stages:
+  - build
+
+build:ubuntu:
+  stage: build
+  image: ubuntu:devel
+  before_script:
+    - apt-get update &&
+    - apt-get install -q -y --no-install-recommends
+        gobject-introspection
+        gtk-doc-tools
+        libgdk-pixbuf2.0-dev
+        libgirepository1.0-dev
+        libglib2.0-dev
+        libgtk-3-dev
+        libpopt-dev
+        xmlto
+        ninja-build
+        python3-pip
+        python3-setuptools
+        xsltproc
+        docbook-xsl-ns
+    - pip3 install meson
+  script:
+    - meson _build -Ddocbook_docs=enabled
+    - ninja -C _build install
+  artifacts:
+    expose_as: "Build artifacts"
+    paths:
+      - _build/docs/notification-spec.html
+      - _build/docs/reference/html
+      - _build/docs/reference/html/index.html
+      - _build/meson-logs
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/NEWS new/libnotify-0.7.11/NEWS
--- old/libnotify-0.7.9/NEWS    2020-02-26 20:07:28.388563900 +0100
+++ new/libnotify-0.7.11/NEWS   2022-04-27 21:05:49.000000000 +0200
@@ -1,3 +1,33 @@
+New in 0.7.11
+=============
+* Fix potential build errors with old glib version we require
+* notify-send: Add support for boolean hints
+* notify-send: Support passing any hint value, by parsing variant strings
+* notify-send: Add explicit option to create transient notifications
+
+Contributors:
+  Marco Trevisan
+
+New in 0.7.10
+=============
+* notify-send: Support commas in icon filenames [Thorsten; !15]
+* notify-send: Give failing exit code if showing notification fails [Ray, !13]
+* notify-send: Support for replacing an existing notification [Paul; !17]
+* notify-send: Add option to wait until notification has been closed [Ben; !18]
+* notify-send: Add support for notification actions and responses [Ben; !18]
+* notification: Send the application ID when possible [Corentin; !1]
+* notification: Use g_memdup2 when available [Marco; !22]
+* notification: Improve SNAP detection and confined desktop ID [Marco; !23]
+* notification: Add support for getting actions activation token [Marco; !24]
+* notify: Use application ID if any to set the fallback app name [Marco; !18]
+* Build fixes and improvements [Marco; !22]
+* Docs updates [Boris, David; !14, !20]
+
+Contributors:
+  Marco Trevisan, Boris Shtrasman, Matthias Sweertvaegher, Thorsten Wi??mann,
+  Ray Strode, Maximiliano Sandoval R, David King, Corentin No??l, Paul Collins,
+  Matthias Sweertvaegher, Ben Blain
+
 New in 0.7.9
 ============
 * Fixed linking in darwin [Iain, Marco; !5]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/README.md 
new/libnotify-0.7.11/README.md
--- old/libnotify-0.7.9/README.md       1970-01-01 01:00:00.000000000 +0100
+++ new/libnotify-0.7.11/README.md      2022-04-27 21:05:49.000000000 +0200
@@ -0,0 +1,16 @@
+# libnotify
+
+## Description
+
+libnotify is a library for sending desktop notifications to a notification
+daemon, as defined in the [org.freedesktop.Notifications][fdo-spec] Desktop
+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.
+
+## Notice
+
+For GLib based applications the [GNotification][gnotif] API should be used
+instead.
+
+[fdo-spec]: 
https://specifications.freedesktop.org/notification-spec/notification-spec-latest.html
+[gnotif]: https://docs.gtk.org/gio/class.Notification.html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/docs/config.xsl 
new/libnotify-0.7.11/docs/config.xsl
--- old/libnotify-0.7.9/docs/config.xsl 2020-02-26 20:07:28.388563900 +0100
+++ new/libnotify-0.7.11/docs/config.xsl        2022-04-27 21:05:49.000000000 
+0200
@@ -3,4 +3,5 @@
                 xmlns:fo="http://www.w3.org/1999/XSL/Format";
                 version="1.0">
   <xsl:param name="html.stylesheet" select="'docbook.css'"/>
+  <xsl:param name="generate.consistent.ids" select="1"/>
 </xsl:stylesheet>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/docs/notification-spec.xml 
new/libnotify-0.7.11/docs/notification-spec.xml
--- old/libnotify-0.7.9/docs/notification-spec.xml      2020-02-26 
20:07:28.388563900 +0100
+++ new/libnotify-0.7.11/docs/notification-spec.xml     2022-04-27 
21:05:49.000000000 +0200
@@ -1272,6 +1272,65 @@
      </para>
     </note>
    </sect3>
+
+   <sect3 id="signal-activation-token">
+    
<title><literal>org.freedesktop.Notifications.ActivationToken</literal></title>
+    <funcsynopsis>
+     <funcprototype>
+      <funcdef>
+       <function>org.freedesktop.Notifications.ActivationToken</function>
+      </funcdef>
+      <paramdef>UINT32 <parameter>id</parameter></paramdef>
+      <paramdef>STRING <parameter>activation_token</parameter></paramdef>
+     </funcprototype>
+    </funcsynopsis>
+    <para>
+     This signal can be emitted before a <literal>ActionInvoked</literal>
+     signal. It carries an activation token that can be used to activate a
+     toplevel.
+    </para>
+    <table>
+     <title>ActivationToken Parameters</title>
+     <tgroup cols="2">
+      <thead>
+       <row>
+        <entry>Name</entry>
+        <entry>Type</entry>
+        <entry>Description</entry>
+       </row>
+      </thead>
+      <tbody valign="top">
+       <row>
+        <entry><parameter>id</parameter></entry>
+        <entry>UINT32</entry>
+        <entry>
+         The ID of the notification emitting the 
<literal>ActionInvoked</literal>
+         signal.
+        </entry>
+       </row>
+       <row>
+        <entry><parameter>activation_token</parameter></entry>
+        <entry>STRING</entry>
+        <entry>
+         An activation token. This can be either an X11-style startup ID (see
+         <ulink 
url="https://specifications.freedesktop.org/startup-notification-spec/startup-notification-latest.txt";>Startup
 notification protocol</ulink>)
+         or a
+         <ulink 
url="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/tree/main/staging/xdg-activation";>Wayland
 xdg-activation</ulink>
+         token.
+        </entry>
+       </row>
+      </tbody>
+     </tgroup>
+    </table>
+    <note>
+     <para>
+      Clients should not assume the server will generate this signal. Some
+      servers may not support user interaction at all, or may not support
+      the concept of being able to generate an activation token for a
+      notification.
+     </para>
+    </note>
+   </sect3>
   </sect2>
  </sect1>
 </article>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/docs/notify-send.xml 
new/libnotify-0.7.11/docs/notify-send.xml
--- old/libnotify-0.7.9/docs/notify-send.xml    2020-02-26 20:07:28.388563900 
+0100
+++ new/libnotify-0.7.11/docs/notify-send.xml   2022-04-27 21:05:49.000000000 
+0200
@@ -59,6 +59,18 @@
         </listitem>
       </varlistentry>
       <varlistentry>
+        <term><option>-a</option>, 
<option>--app-name</option>=<replaceable>APP_NAME</replaceable></term>
+        <listitem>
+          <para>Specifies the app name for the notification.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>-A</option>, 
<option>--action</option>=[<replaceable>NAME</replaceable>=]<replaceable>Text...</replaceable></term>
+        <listitem>
+          <para>Specifies the actions to display to the user. Implies 
<option>--wait</option> to wait for user input. May be set multiple times. The 
<replaceable>NAME</replaceable> of the action is output to 
<literal>stdout</literal>. If <replaceable>NAME</replaceable> is not specified, 
the numerical index of the option is used (starting with 
<literal>1</literal>).</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
         <term><option>-u</option>, 
<option>--urgency</option>=<replaceable>LEVEL</replaceable></term>
         <listitem>
           <para>Specifies the urgency level (<literal>low</literal>, 
<literal>normal</literal>, <literal>critical</literal>).</para>
@@ -69,11 +81,11 @@
         </term>
         <listitem>
           <para>The duration, in milliseconds, for the notification to appear 
on screen.</para>
-          <para>(Ubuntu's Notify OSD and GNOME Shell both ignore this 
parameter.)</para>
+          <para>Not all implementations use this parameter. GNOME Shell and 
Notify OSD always ignore it, while Plasma ignores it for notifications with the 
critical urgency level.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
-        <term><option>-i</option>, 
<option>--icon</option>=<replaceable>ICON</replaceable>[,<replaceable>ICON</replaceable>???]
+        <term><option>-i</option>, 
<option>--icon</option>=<replaceable>ICON</replaceable>
         </term>
         <listitem>
           <para>Specifies an icon filename or stock icon to display.</para>
@@ -89,7 +101,25 @@
       <varlistentry>
         <term><option>-h</option>, 
<option>--hint</option>=<replaceable>TYPE</replaceable>:<replaceable>NAME</replaceable>:<replaceable>VALUE</replaceable>
 </term>
         <listitem>
-          <para>Specifies basic extra data to pass. Valid types are 
<literal>INT</literal>, <literal>DOUBLE</literal>, <literal>STRING</literal> 
and <literal>BYTE</literal>.</para>
+          <para>Specifies basic extra data to pass. Valid types are 
<literal>BOOLEAN</literal>, <literal>INT</literal>, <literal>DOUBLE</literal>, 
<literal>STRING</literal>, <literal>BYTE</literal> and 
<literal>VARIANT</literal>.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>-p</option>, <option>--print-id</option></term>
+        <listitem>
+          <para>Print the notification ID.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>-r</option>, 
<option>--replace-id</option>=<replaceable>REPLACE_ID</replaceable></term>
+        <listitem>
+          <para>The ID of the notification to replace.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>-w</option>, <option>--wait</option></term>
+          <listitem>
+            <para>Wait for the notification to be closed before exiting. If 
the <option>expire-time</option> is set, it will be used as the maximum waiting 
time.</para>
         </listitem>
       </varlistentry>
     </variablelist>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libnotify-0.7.9/docs/reference/libnotify-sections.txt 
new/libnotify-0.7.11/docs/reference/libnotify-sections.txt
--- old/libnotify-0.7.9/docs/reference/libnotify-sections.txt   2020-02-26 
20:07:28.388563900 +0100
+++ new/libnotify-0.7.11/docs/reference/libnotify-sections.txt  2022-04-27 
21:05:49.000000000 +0200
@@ -27,6 +27,7 @@
 notify_notification_add_action
 notify_notification_clear_actions
 notify_notification_close
+notify_notification_get_activation_token
 notify_notification_get_closed_reason
 <SUBSECTION Standard>
 NotifyNotificationPrivate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/libnotify/meson.build 
new/libnotify-0.7.11/libnotify/meson.build
--- old/libnotify-0.7.9/libnotify/meson.build   2020-02-26 20:07:28.392563800 
+0100
+++ new/libnotify-0.7.11/libnotify/meson.build  2022-04-27 21:05:49.000000000 
+0200
@@ -69,8 +69,9 @@
 )
 
 introspection = get_option('introspection')
-if not introspection.disabled()
-  find_program('g-ir-scanner', required: introspection.enabled())
+g_ir_scanner = find_program('g-ir-scanner', required: introspection.enabled())
+
+if g_ir_scanner.found() and not introspection.disabled()
   gnome.generate_gir(libnotify_lib,
     sources: headers + sources + enum_types,
     namespace: 'Notify',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/libnotify/notification.c 
new/libnotify-0.7.11/libnotify/notification.c
--- old/libnotify-0.7.9/libnotify/notification.c        2020-02-26 
20:07:28.392563800 +0100
+++ new/libnotify-0.7.11/libnotify/notification.c       2022-04-27 
21:05:49.000000000 +0200
@@ -68,6 +68,11 @@
         char           *app_name;
         char           *summary;
         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;
@@ -84,6 +89,7 @@
         GHashTable     *hints;
 
         gboolean        has_nondefault_actions;
+        gboolean        activating;
         gboolean        updates_pending;
 
         gulong          proxy_signal_handler;
@@ -351,6 +357,104 @@
 }
 
 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);
@@ -365,6 +469,8 @@
                                                        g_str_equal,
                                                        g_free,
                                                        (GDestroyNotify) 
destroy_pair);
+
+        maybe_initialize_snap (obj);
 }
 
 static void
@@ -380,6 +486,8 @@
         g_free (priv->summary);
         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);
@@ -431,30 +539,52 @@
 {
         gchar *path_filename;
         gchar *path_ret;
+        gboolean was_uri;
 
         if (!path || *path == '\0')
                 return NULL;
 
+        was_uri = TRUE;
         path_ret = NULL;
         path_filename = g_filename_from_uri (base_path, NULL, NULL);
 
         if (path_filename == NULL) {
+                was_uri = FALSE;
+
                 if (base_path && base_path[0] == G_DIR_SEPARATOR) {
                         path_filename = g_strdup (base_path);
                 } else {
                         path_filename = realpath (base_path, NULL);
+
+                        if (path_filename == NULL) {
+                                /* File path is not existing, but let's check
+                                 * if it's under the base path before giving up
+                                 */
+                                path_filename = g_strdup (base_path);
+                        }
                 }
         }
 
-        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_str_has_prefix (path_filename, path)) {
+                path_ret = g_strdup (path_filename);
+        } else {
+                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_debug ("Nothing found at %s", path_ret);
                 g_free (path_ret);
                 path_ret = NULL;
+        } else if (was_uri) {
+                gchar *uri = g_filename_to_uri (path_ret, NULL, NULL);
+
+                if (uri != NULL) {
+                        g_free (path_ret);
+                        path_ret = uri;
+                }
         }
 
         g_free (path_filename);
@@ -463,33 +593,33 @@
 }
 
 static gchar *
-try_prepend_desktop (const gchar *desktop)
+try_prepend_snap_desktop (NotifyNotification *notification,
+                          const gchar        *desktop)
 {
-        gchar *ret;
+        NotifyNotificationPrivate *priv = notification->priv;
+        gchar *ret = NULL;
 
         /*
          * if it's an absolute path, try prepending $SNAP, otherwise try
-         * $SNAP_NAME_; snap .desktop files are in the format
+         * ${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");
+        ret = try_prepend_path (desktop, priv->snap_path);
 
-                if (snap_name != NULL && snap_name[0] != '\0') {
-                        ret = g_strdup_printf ("%s_%s", snap_name, desktop);
-                }
+        if (ret == NULL && priv->snap_name != NULL &&
+            strchr (desktop, G_DIR_SEPARATOR) == NULL) {
+                ret = g_strdup_printf ("%s_%s", priv->snap_name, desktop);
         }
 
         return ret;
 }
 
 static gchar *
-try_prepend_snap (const gchar *value)
+try_prepend_snap (NotifyNotification *notification,
+                  const gchar        *value)
 {
         /* hardcoded paths to icons might be relocated under $SNAP */
-        return try_prepend_path (value, g_getenv ("SNAP"));
+        return try_prepend_path (value, notification->priv->snap_path);
 }
 
 
@@ -524,7 +654,8 @@
                 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);
+                snapped_icon = try_prepend_snap_desktop (notification,
+                                                         
notification->priv->icon_name);
                 if (snapped_icon != NULL) {
                         g_debug ("Icon updated in snap environment: '%s' -> 
'%s'\n",
                                  notification->priv->icon_name, snapped_icon);
@@ -608,8 +739,25 @@
                                 g_warning ("Received unknown action %s", 
action);
                         }
                 } else {
+                        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;
                 }
+        } else if (g_strcmp0 (signal_name, "ActivationToken") == 0 &&
+                   g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(us)"))) 
{
+                guint32 id;
+                const char *activation_token;
+
+                g_variant_get (parameters, "(u&s)", &id, &activation_token);
+
+                if (id != notification->priv->id)
+                        return;
+
+                g_free (notification->priv->activation_token);
+                notification->priv->activation_token = g_strdup 
(activation_token);
         }
 }
 
@@ -634,6 +782,9 @@
         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);
@@ -668,6 +819,38 @@
                 g_variant_builder_add (&hints_builder, "{sv}", key, data);
         }
 
+        if (priv->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);
+
+                g_debug ("Using desktop entry: %s", snap_desktop);
+                g_variant_builder_add (&hints_builder, "{sv}",
+                                       "desktop-entry",
+                                       g_variant_new_take_string 
(snap_desktop));
+        }
+
+#ifdef GLIB_VERSION_2_32
+        if (!priv->snap_app) {
+                application = g_application_get_default ();
+        }
+
+        if (application != NULL) {
+            GVariant *desktop_entry = g_hash_table_lookup (priv->hints, 
"desktop-entry");
+
+            if (desktop_entry == NULL) {
+                const char *application_id = g_application_get_application_id 
(application);
+
+                g_debug ("Using desktop entry: %s", application_id);
+                g_variant_builder_add (&hints_builder, "{sv}", "desktop-entry",
+                                       g_variant_new_string (application_id));
+            }
+        }
+#endif
+
         /* TODO: make this nonblocking */
         result = g_dbus_proxy_call_sync (proxy,
                                          "Notify",
@@ -855,13 +1038,20 @@
         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));
+typedef gchar * (*StringParserFunc) (NotifyNotification *, const gchar *);
 
-        if (parsed != NULL) {
+static GVariant *
+get_parsed_variant (NotifyNotification *notification,
+                    const char         *key,
+                    GVariant           *variant,
+                    StringParserFunc    str_parser)
+{
+        const char *str = g_variant_get_string (variant, NULL);
+        gchar *parsed = str_parser (notification, str);
+
+        if (parsed != NULL && g_strcmp0 (str, parsed) != 0) {
+                g_debug ("Hint %s updated in snap environment: '%s' -> '%s'\n",
+                         key, str, parsed);
                 g_variant_unref (variant);
                 variant = g_variant_new_take_string (parsed);
         }
@@ -870,18 +1060,28 @@
 }
 
 static GVariant *
-maybe_parse_snap_hint_value (const gchar *key,
+maybe_parse_snap_hint_value (NotifyNotification *notification,
+                             const gchar *key,
                              GVariant    *value)
 {
+        StringParserFunc parse_func = NULL;
+
+        if (!notification->priv->snap_path)
+                return value;
+
         if (g_strcmp0 (key, "desktop-entry") == 0) {
-                value = get_parsed_variant (value, try_prepend_desktop);
+                parse_func = try_prepend_snap_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);
+                parse_func = try_prepend_snap;
+        }
+
+        if (parse_func == NULL) {
+                return value;
         }
 
-        return value;
+        return get_parsed_variant (notification, key, value, parse_func);
 }
 
 /**
@@ -906,7 +1106,7 @@
         g_return_if_fail (key != NULL && *key != '\0');
 
         if (value != NULL) {
-                value = maybe_parse_snap_hint_value (key, value);
+                value = maybe_parse_snap_hint_value (notification, key, value);
                 g_hash_table_insert (notification->priv->hints,
                                     g_strdup (key),
                                     g_variant_ref_sink (value));
@@ -1038,7 +1238,11 @@
 
         g_return_if_fail (value != NULL || len == 0);
 
+#ifdef GLIB_VERSION_2_68
+        value_dup = g_memdup2 (value, len);
+#else
         value_dup = g_memdup (value, len);
+#endif
         notify_notification_set_hint (notification, key,
                                       g_variant_new_from_data (G_VARIANT_TYPE 
("ay"),
                                                                value_dup,
@@ -1167,6 +1371,29 @@
         }
 }
 
+/**
+ * notify_notification_get_activation_token:
+ *
+ * If an an action is currently being activated, return the activation token.
+ * This function is intended to be used in a #NotifyActionCallback to get
+ * the activation token for the activated action, if the notification daemon
+ * supports it.
+ *
+ * Return value: (transfer none): The current activation token, or %NULL if 
none
+ *
+ * Since: 0.7.10
+ */
+const char *
+notify_notification_get_activation_token (NotifyNotification *notification)
+{
+        g_return_val_if_fail (NOTIFY_IS_NOTIFICATION (notification), NULL);
+
+        if (notification->priv->activating)
+                return notification->priv->activation_token;
+
+        return NULL;
+}
+
 gboolean
 _notify_notification_has_nondefault_actions (const NotifyNotification *n)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/libnotify/notification.h 
new/libnotify-0.7.11/libnotify/notification.h
--- old/libnotify-0.7.9/libnotify/notification.h        2020-02-26 
20:07:28.392563800 +0100
+++ new/libnotify-0.7.11/libnotify/notification.h       2022-04-27 
21:05:49.000000000 +0200
@@ -180,6 +180,8 @@
                                                                gpointer        
    user_data,
                                                                GFreeFunc       
    free_func);
 
+const char         *notify_notification_get_activation_token  
(NotifyNotification *notification);
+
 void                notify_notification_clear_actions         
(NotifyNotification *notification);
 gboolean            notify_notification_close                 
(NotifyNotification *notification,
                                                                GError          
  **error);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/libnotify/notify.c 
new/libnotify-0.7.11/libnotify/notify.c
--- old/libnotify-0.7.9/libnotify/notify.c      2020-02-26 20:07:28.392563800 
+0100
+++ new/libnotify-0.7.11/libnotify/notify.c     2022-04-27 21:05:49.000000000 
+0200
@@ -151,9 +151,17 @@
         if (_initted)
                 return TRUE;
 
+#ifdef GLIB_VERSION_2_32
+        if (app_name == NULL && g_application_get_default ()) {
+                GApplication *application = g_application_get_default ();
+
+                app_name = g_application_get_application_id (application);
+        }
+#endif
+
         notify_set_app_name (app_name);
 
-#if !GLIB_CHECK_VERSION (2, 36, 0)
+#ifndef GLIB_VERSION_2_36
         g_type_init ();
 #endif
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/meson.build 
new/libnotify-0.7.11/meson.build
--- old/libnotify-0.7.9/meson.build     2020-02-26 20:07:28.392563800 +0100
+++ new/libnotify-0.7.11/meson.build    2022-04-27 21:05:49.000000000 +0200
@@ -1,6 +1,6 @@
 project('libnotify',
   'c',
-  version: '0.7.9',
+  version: '0.7.11',
   meson_version: '>= 0.47.0')
 
 gnome = import('gnome')
@@ -66,7 +66,7 @@
     '@INPUT@',
   ]
 
-  testrun = run_command(xsltproc, '--nonet', stylesheet)
+  testrun = run_command(xsltproc, '--nonet', stylesheet, check: false)
 
   if testrun.returncode() != 0
     error('DocBook stylesheet for generating man pages not found, you need to 
install docbook-xsl-ns or similar package.')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/tests/test-error.c 
new/libnotify-0.7.11/tests/test-error.c
--- old/libnotify-0.7.9/tests/test-error.c      2020-02-26 20:07:28.396563800 
+0100
+++ new/libnotify-0.7.11/tests/test-error.c     2022-04-27 21:05:49.000000000 
+0200
@@ -29,7 +29,7 @@
 {
         NotifyNotification *n;
 
-#if !GLIB_CHECK_VERSION (2, 36, 0)
+#ifndef GLIB_VERSION_2_36
         g_type_init ();
 #endif
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/tests/test-replace.c 
new/libnotify-0.7.11/tests/test-replace.c
--- old/libnotify-0.7.9/tests/test-replace.c    2020-02-26 20:07:28.396563800 
+0100
+++ new/libnotify-0.7.11/tests/test-replace.c   2022-04-27 21:05:49.000000000 
+0200
@@ -28,7 +28,7 @@
         GError             *error;
         error = NULL;
 
-#if !GLIB_CHECK_VERSION (2, 36, 0)
+#ifndef GLIB_VERSION_2_36
         g_type_init ();
 #endif
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnotify-0.7.9/tools/notify-send.c 
new/libnotify-0.7.11/tools/notify-send.c
--- old/libnotify-0.7.9/tools/notify-send.c     2020-02-26 20:07:28.396563800 
+0100
+++ new/libnotify-0.7.11/tools/notify-send.c    2022-04-27 21:05:49.000000000 
+0200
@@ -32,6 +32,7 @@
 #define GETTEXT_PACKAGE NULL
 
 static NotifyUrgency urgency = NOTIFY_URGENCY_NORMAL;
+static GMainLoop *loop = NULL;
 
 static gboolean
 g_option_arg_urgency_cb (const char *option_name,
@@ -99,6 +100,26 @@
                                                            key,
                                                            (guchar) h_byte);
                 }
+        } else if (g_ascii_strcasecmp (type, "boolean") == 0) {
+                gboolean h_boolean = FALSE;
+
+                if (g_ascii_strcasecmp (value, "true") == 0) {
+                        h_boolean = TRUE;
+                } else if (g_ascii_isdigit (*value)) {
+                        h_boolean = !!g_ascii_strtoull (value, NULL, 10);
+                }
+
+                notify_notification_set_hint (notification, key,
+                                              g_variant_new_boolean 
(h_boolean));
+        } else if (g_ascii_strcasecmp (type, "variant") == 0) {
+                GVariant *variant = g_variant_parse (NULL, value, NULL, NULL, 
NULL);
+
+                if (variant != NULL) {
+                        notify_notification_set_hint (notification, key, 
variant);
+                } else {
+                        conv_error = TRUE;
+                }
+
         } else {
                 *error = g_error_new (G_OPTION_ERROR,
                                       G_OPTION_ERROR_BAD_VALUE,
@@ -120,6 +141,41 @@
         return TRUE;
 }
 
+static void
+handle_closed (NotifyNotification *notify,
+               gpointer            user_data)
+{
+        g_main_loop_quit (loop);
+}
+
+static void
+handle_action (NotifyNotification *notify,
+               char               *action,
+               gpointer            user_data)
+{
+        const char *action_name = user_data;
+        const char *activation_token;
+
+        activation_token = notify_notification_get_activation_token (notify);
+
+        g_printf ("%s\n", action_name);
+
+        if (activation_token) {
+                g_debug ("Activation Token: %s", activation_token);
+        }
+
+        notify_notification_close (notify, NULL);
+}
+
+static gboolean
+on_wait_timeout (gpointer data)
+{
+        fprintf (stderr, "Wait timeout expired\n");
+        g_main_loop_quit (loop);
+
+        return FALSE;
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -128,11 +184,15 @@
         static const char  *type = NULL;
         static char        *app_name = NULL;
         static char        *icon_str = NULL;
-        static char        *icons = NULL;
         static char       **n_text = NULL;
         static char       **hints = NULL;
+        static char       **actions = NULL;
+        static gboolean     print_id = FALSE;
+        static gint         notification_id = 0;
         static gboolean     do_version = FALSE;
-        static gboolean     hint_error = FALSE;
+        static gboolean     hint_error = FALSE, show_error = FALSE;
+        static gboolean     transient = FALSE;
+        static gboolean     wait = FALSE;
         static glong        expire_timeout = NOTIFY_EXPIRES_DEFAULT;
         GOptionContext     *opt_ctx;
         NotifyNotification *notify;
@@ -150,16 +210,32 @@
                   "notification."), N_("TIME")},
                 {"app-name", 'a', 0, G_OPTION_ARG_STRING, &app_name,
                  N_("Specifies the app name for the icon"), N_("APP_NAME")},
-                {"icon", 'i', 0, G_OPTION_ARG_FILENAME, &icons,
+                {"icon", 'i', 0, G_OPTION_ARG_FILENAME, &icon_str,
                  N_("Specifies an icon filename or stock icon to display."),
-                 N_("ICON[,ICON...]")},
+                 N_("ICON")},
                 {"category", 'c', 0, G_OPTION_ARG_FILENAME, &type,
                  N_("Specifies the notification category."),
                  N_("TYPE[,TYPE...]")},
+                {"transient", 'e', 0, G_OPTION_ARG_NONE, &transient,
+                 N_("Create a transient notification"),
+                 NULL},
                 {"hint", 'h', 0, G_OPTION_ARG_FILENAME_ARRAY, &hints,
                  N_
-                 ("Specifies basic extra data to pass. Valid types are int, 
double, string and byte."),
+                 ("Specifies basic extra data to pass. Valid types are 
boolean, int, double, string, byte and variant."),
                  N_("TYPE:NAME:VALUE")},
+                {"print-id", 'p', 0, G_OPTION_ARG_NONE, &print_id,
+                 N_ ("Print the notification ID."), NULL},
+                {"replace-id", 'r', 0, G_OPTION_ARG_INT, &notification_id,
+                 N_ ("The ID of the notification to replace."), 
N_("REPLACE_ID")},
+                {"wait", 'w', 0, G_OPTION_ARG_NONE, &wait,
+                 N_("Wait for the notification to be closed before exiting."),
+                 NULL},
+                {"action", 'A', 0, G_OPTION_ARG_FILENAME_ARRAY, &actions,
+                 N_
+                 ("Specifies the actions to display to the user. Implies 
--wait to wait for user input."
+                 " May be set multiple times. The name of the action is output 
to stdout. If NAME is "
+                 "not specified, the numerical index of the option is used 
(starting with 0)."),
+                 N_("[NAME=]Text...")},
                 {"version", 'v', 0, G_OPTION_ARG_NONE, &do_version,
                  N_("Version of the package."),
                  NULL},
@@ -173,7 +249,7 @@
 
         setlocale (LC_ALL, "");
 
-#if !GLIB_CHECK_VERSION (2, 36, 0)
+#ifndef GLIB_VERSION_2_36
         g_type_init ();
 #endif
 
@@ -215,27 +291,26 @@
                 }
         }
 
-        if (icons != NULL) {
-                char           *c;
-
-                /* XXX */
-                if ((c = strchr (icons, ',')) != NULL)
-                        *c = '\0';
-
-                icon_str = icons;
-        }
-
         if (!notify_init ("notify-send"))
                 exit (1);
 
-        notify = notify_notification_new (summary,
-                                          body,
-                                          icon_str);
+        notify = g_object_new (NOTIFY_TYPE_NOTIFICATION,
+                               "summary", summary,
+                               "body", body,
+                               "icon-name", icon_str,
+                               "id", notification_id,
+                               NULL);
+
         notify_notification_set_category (notify, type);
         notify_notification_set_urgency (notify, urgency);
         notify_notification_set_timeout (notify, expire_timeout);
         notify_notification_set_app_name (notify, app_name);
 
+        if (transient) {
+                notify_notification_set_hint (notify, "transient",
+                                              g_variant_new_boolean (TRUE));
+        }
+
         g_free (body);
 
         /* Set hints */
@@ -263,7 +338,7 @@
 
                                 if (!retval) {
                                         fprintf (stderr, "%s\n", 
error->message);
-                                        g_error_free (error);
+                                        g_clear_error (&error);
                                         hint_error = TRUE;
                                 }
                         }
@@ -274,12 +349,96 @@
                 }
         }
 
-        if (!hint_error)
-                notify_notification_show (notify, NULL);
+        if (actions != NULL) {
+                GList *server_caps = notify_get_server_caps ();
+                gint i = 0;
+                char *action = NULL;
+                gchar **spl = NULL;
+                gboolean have_actions;
+
+                have_actions =
+                        !!g_list_find_custom (server_caps,
+                                              "actions",
+                                              (GCompareFunc) 
g_ascii_strcasecmp);
+                g_list_foreach (server_caps, (GFunc) g_free, NULL);
+                g_list_free (server_caps);
+
+                if (!have_actions) {
+                        g_printerr (N_("Actions are not supported by this "
+                                       "notifications server. "
+                                       "Displaying non-interactively.\n"));
+                        show_error = TRUE;
+                }
+
+                while (have_actions && (action = actions[i++])) {
+                        gchar *name;
+                        const gchar *label;
+
+                        spl = g_strsplit (action, "=", 2);
+
+                        if (g_strv_length (spl) == 1) {
+                                name = g_strdup_printf ("%d", i - 1);
+                                label = g_strstrip (spl[0]);
+                        } else {
+                                name = g_strdup (g_strstrip (spl[0]));
+                                label = g_strstrip (spl[1]);
+                        }
+
+                        if (*label != '\0' && *name != '\0') {
+                                notify_notification_add_action (notify,
+                                                                name,
+                                                                label,
+                                                                handle_action,
+                                                                name,
+                                                                g_free);
+                                wait = TRUE;
+                        }
+
+                        g_strfreev (spl);
+                }
+
+                g_strfreev (actions);
+        }
+
+        if (wait) {
+                g_signal_connect (G_OBJECT (notify),
+                                  "closed",
+                                  G_CALLBACK (handle_closed),
+                                  NULL);
+
+                if (expire_timeout > 0) {
+                        g_timeout_add (expire_timeout, on_wait_timeout, NULL);
+                }
+        }
+
+        if (!hint_error) {
+                retval = notify_notification_show (notify, &error);
+
+                if (!retval) {
+                        fprintf (stderr, "%s\n", error->message);
+                        g_clear_error (&error);
+                        show_error = TRUE;
+                }
+        }
+
+        if (print_id) {
+                g_object_get (notify, "id", &notification_id, NULL);
+                g_printf ("%d\n", notification_id);
+        }
+
+        if (wait) {
+                loop = g_main_loop_new (NULL, FALSE);
+                g_main_loop_run (loop);
+                g_main_loop_unref (loop);
+                loop = NULL;
+        }
 
         g_object_unref (G_OBJECT (notify));
 
         notify_uninit ();
 
-        exit (hint_error);
+        if (hint_error || show_error)
+                exit (1);
+
+        return 0;
 }

Reply via email to