[libnotify] notification: Add support for getting actions activation token



commit d07785959cbf264881787498187800a564b9ba99
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Mon Apr 25 22:59:57 2022 +0200

    notification: Add support for getting actions activation token
    
    Notification actions can now be activated with an activation token
    containing platform data. So update the notification-spec to include
    latest version of the specification, and expose the activation token
    during an action activation.
    
    Not to change the API, by modifying the type of NotifyActionCallback
    it's just better to provide a function to fetch the activation token
    during activation only, so that this can be retro-compatible.
    
    Reference: https://gitlab.freedesktop.org/xdg/xdg-specs/-/commit/b9a4700

 docs/notification-spec.xml            | 59 +++++++++++++++++++++++++++++++++++
 docs/reference/libnotify-sections.txt |  1 +
 libnotify/notification.c              | 43 +++++++++++++++++++++++++
 libnotify/notification.h              |  2 ++
 tools/notify-send.c                   |  8 +++++
 5 files changed, 113 insertions(+)
---
diff --git a/docs/notification-spec.xml b/docs/notification-spec.xml
index 5f66077..37a7552 100644
--- a/docs/notification-spec.xml
+++ b/docs/notification-spec.xml
@@ -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 --git a/docs/reference/libnotify-sections.txt b/docs/reference/libnotify-sections.txt
index 5aaa2f7..f78a33a 100644
--- a/docs/reference/libnotify-sections.txt
+++ b/docs/reference/libnotify-sections.txt
@@ -27,6 +27,7 @@ notify_notification_clear_hints
 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 --git a/libnotify/notification.c b/libnotify/notification.c
index fef195e..85f9d02 100644
--- a/libnotify/notification.c
+++ b/libnotify/notification.c
@@ -68,6 +68,7 @@ struct _NotifyNotificationPrivate
         char           *app_name;
         char           *summary;
         char           *body;
+        char           *activation_token;
 
         const char     *snap_path;
         const char     *snap_name;
@@ -88,6 +89,7 @@ struct _NotifyNotificationPrivate
         GHashTable     *hints;
 
         gboolean        has_nondefault_actions;
+        gboolean        activating;
         gboolean        updates_pending;
 
         gulong          proxy_signal_handler;
@@ -484,6 +486,7 @@ notify_notification_finalize (GObject *object)
         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) {
@@ -736,8 +739,25 @@ proxy_g_signal_cb (GDBusProxy *proxy,
                                 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);
         }
 }
 
@@ -1351,6 +1371,29 @@ notify_notification_add_action (NotifyNotification  *notification,
         }
 }
 
+/**
+ * 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 --git a/libnotify/notification.h b/libnotify/notification.h
index b232b3b..ffc960f 100644
--- a/libnotify/notification.h
+++ b/libnotify/notification.h
@@ -180,6 +180,8 @@ void                notify_notification_add_action            (NotifyNotificatio
                                                                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 --git a/tools/notify-send.c b/tools/notify-send.c
index 65963ff..88599bf 100644
--- a/tools/notify-send.c
+++ b/tools/notify-send.c
@@ -134,8 +134,16 @@ handle_action (NotifyNotification *notify,
                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);
 }
 


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