diff --git a/libnotify/notification.c b/libnotify/notification.c index c4f9be5..0b851d5 100644 --- a/libnotify/notification.c +++ b/libnotify/notification.c @@ -94,6 +94,7 @@ struct _NotifyNotificationPrivate enum { SIGNAL_CLOSED, + SIGNAL_REPLIED, LAST_SIGNAL }; @@ -167,6 +168,30 @@ notify_notification_class_init (NotifyNotificationClass *klass) G_TYPE_NONE, 0); + /** + * NotifyNotification::replied: + * @notification: The object which received the signal. + * @text: The reply text the user typed. + * + * Emitted when a notification reply text is submitted. + * + * When the notification server has the "inline-reply" capability, + * adding an action named "inline-reply" will instead of adding + * a button, offer a text field inside the notification popup, + * which when its text is submitted, emits this signal. + */ + signals[SIGNAL_REPLIED] = + g_signal_new ("replied", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + g_object_class_install_property (object_class, PROP_ID, g_param_spec_int ("id", "ID", @@ -610,6 +635,17 @@ proxy_g_signal_cb (GDBusProxy *proxy, } else { pair->cb (notification, (char *) action, pair->user_data); } + } else if (g_strcmp0 (signal_name, "NotificationReplied") == 0 && + g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(us)"))) { + guint32 id; + const char *text; + + g_variant_get (parameters, "(u&s)", &id, &text); + + if (id != notification->priv->id) + return; + + g_signal_emit (notification, signals[SIGNAL_REPLIED], 0, text); } } diff --git a/tests/meson.build b/tests/meson.build index 3efc1a3..0902935 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -5,6 +5,7 @@ test_progs = [ 'default-action', 'multi-actions', 'action-icons', + 'inline-reply', 'image', 'basic', 'error', diff --git a/tests/test-inline-reply.c b/tests/test-inline-reply.c new file mode 100644 index 0000000..530b83d --- /dev/null +++ b/tests/test-inline-reply.c @@ -0,0 +1,89 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * @file tests/test-inline-reply-action.c Unit test: inline reply action + * + * @Copyright (C) 2004 Mike Hearn + * @Copyright (C) 2020 Kai Uwe Broulik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include + +static GMainLoop *loop; + +static void +callback (NotifyNotification *n, + const char *action, + void *user_data) +{ + printf ("action %s invoked, inline-reply probably not supported.\n", action); + + notify_notification_close (n, NULL); + + g_main_loop_quit (loop); +} + +static void +handle_replied (NotifyNotification *n, + const char *text) +{ + printf("repleid\n"); + printf ("inline-reply: %s\n", text); + + notify_notification_close (n, NULL); + + g_main_loop_quit (loop); +} + +int +main () +{ + NotifyNotification *n; + + if (!notify_init ("Inline Reply Action Test")) + exit (1); + + loop = g_main_loop_new (NULL, FALSE); + + n = notify_notification_new ("Matt", "What's up for dinner?", NULL); + notify_notification_set_timeout (n, NOTIFY_EXPIRES_DEFAULT); + notify_notification_add_action (n, + "inline-reply", + "Reply...", + (NotifyActionCallback) callback, + NULL, + NULL); + g_signal_connect (G_OBJECT (n), + "replied", + G_CALLBACK (handle_replied), + NULL); + + + if (!notify_notification_show (n, NULL)) { + fprintf (stderr, "failed to send notification\n"); + return 1; + } + + g_main_loop_run (loop); + + return 0; +}