From e6c4ae1f28b0f5b0d50ecd759fb58f7271bb06f8 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 29 Nov 2021 16:03:25 +0100 Subject: [PATCH] calendar-server: Add 'Dismiss' button and application action - add 'Dismiss' button to the notification - introduce org.gnome.Shell.CalendarServer.desktop.in.in to benefit from GNotification API Closes https://gitlab.gnome.org/GNOME/gnome-shell/issues/155 --- data/meson.build | 2 + ...g.gnome.Shell.CalendarServer.desktop.in.in | 9 +++ po/POTFILES.in | 1 + .../gnome-shell-calendar-server.c | 27 +++++-- src/calendar-server/reminder-watcher.c | 78 +++++++++++++++++++ src/calendar-server/reminder-watcher.h | 2 + 6 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 data/org.gnome.Shell.CalendarServer.desktop.in.in diff --git a/data/meson.build b/data/meson.build index 0307613e7..3ec01a5ca 100644 --- a/data/meson.build +++ b/data/meson.build @@ -2,6 +2,7 @@ data_builddir = meson.current_build_dir() desktop_files = [ 'org.gnome.Shell.desktop', + 'org.gnome.Shell.CalendarServer.desktop', 'org.gnome.Shell.Extensions.desktop', ] service_files = [] @@ -15,6 +16,7 @@ desktopconf = configuration_data() # We substitute in bindir so it works as an autostart # file when built in a non-system prefix desktopconf.set('bindir', bindir) +desktopconf.set('libexecdir', libexecdir) desktopconf.set('systemd_hidden', have_systemd ? 'true' : 'false') foreach desktop_file : desktop_files diff --git a/data/org.gnome.Shell.CalendarServer.desktop.in.in b/data/org.gnome.Shell.CalendarServer.desktop.in.in new file mode 100644 index 000000000..088cfa41c --- /dev/null +++ b/data/org.gnome.Shell.CalendarServer.desktop.in.in @@ -0,0 +1,9 @@ +[Desktop Entry] +Type=Application +Name=Reminder Notifications +Icon=appointment-soon +Exec=@libexecdir@/gnome-shell-calendar-server +Terminal=false +Categories= +OnlyShowIn=GNOME +NoDisplay=true diff --git a/po/POTFILES.in b/po/POTFILES.in index cd20a487b..96501b8dc 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -6,6 +6,7 @@ data/50-gnome-shell-system.xml data/org.gnome.Shell.desktop.in.in data/org.gnome.shell.gschema.xml.in data/org.gnome.Shell.Extensions.desktop.in.in +data/org.gnome.Shell.CalendarServer.desktop.in.in data/org.gnome.Shell.PortalHelper.desktop.in.in js/dbusServices/extensions/ui/extension-error-page.ui js/gdm/authPrompt.js diff --git a/src/calendar-server/gnome-shell-calendar-server.c b/src/calendar-server/gnome-shell-calendar-server.c index 41b4bd1d0..67b6fb013 100644 --- a/src/calendar-server/gnome-shell-calendar-server.c +++ b/src/calendar-server/gnome-shell-calendar-server.c @@ -71,11 +71,6 @@ static GDBusNodeInfo *introspection_data = NULL; struct _App; typedef struct _App App; -static gboolean opt_replace = FALSE; -static GOptionEntry opt_entries[] = { - {"replace", 0, 0, G_OPTION_ARG_NONE, &opt_replace, "Replace existing daemon", NULL}, - {NULL } -}; static App *_global_app = NULL; /* ---------------------------------------------------------------------------------------------------- */ @@ -1071,10 +1066,30 @@ stdin_channel_io_func (GIOChannel *source, return FALSE; /* remove source */ } +static void +app_dismiss_reminder_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) +{ + App *app = _global_app; + + g_return_if_fail (app != NULL); + + reminder_watcher_dismiss_by_id (app->reminder_watcher, g_variant_get_string (parameter, NULL)); +} + int main (int argc, char **argv) { + gboolean opt_replace = FALSE; + GOptionEntry opt_entries[] = { + {"replace", 0, 0, G_OPTION_ARG_NONE, &opt_replace, "Replace existing daemon", NULL}, + {NULL } + }; + const GActionEntry action_entries[] = { + { "dismiss-reminder", app_dismiss_reminder_cb, "s" } + }; g_autoptr (GApplication) application = NULL; g_autoptr (GError) error = NULL; GOptionContext *opt_context; @@ -1099,6 +1114,8 @@ main (int argc, } application = g_application_new (BUS_NAME, G_APPLICATION_NON_UNIQUE); + g_action_map_add_action_entries (G_ACTION_MAP (application), action_entries, G_N_ELEMENTS (action_entries), NULL); + g_signal_connect (application, "activate", G_CALLBACK (g_application_hold), NULL); diff --git a/src/calendar-server/reminder-watcher.c b/src/calendar-server/reminder-watcher.c index 9e2061720..360da0611 100644 --- a/src/calendar-server/reminder-watcher.c +++ b/src/calendar-server/reminder-watcher.c @@ -234,6 +234,8 @@ reminder_watcher_notify_display (ReminderWatcher *rw, } #endif + g_notification_add_button_with_target (notification, _("Dismiss"), "app.dismiss-reminder", "s", notif_id); + g_application_send_notification (rw->priv->application, notif_id, notification); g_object_unref (notification); @@ -704,3 +706,79 @@ reminder_watcher_new (GApplication *application, return E_REMINDER_WATCHER (rw); } + +static void +reminder_watcher_dismiss_done_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + + if (!e_reminder_watcher_dismiss_finish (E_REMINDER_WATCHER (source_object), result, &error)) + { + if (!g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_NOT_SUPPORTED)) + print_debug ("Dismiss: Failed with error: %s", error ? error->message : "Unknown error"); + + g_clear_error (&error); + } +} + +static EReminderData * +reminder_watcher_find_by_id (EReminderWatcher *reminder_watcher, + const gchar *id) +{ + EReminderData *res = NULL; + GSList *past, *link; + + past = e_reminder_watcher_dup_past (reminder_watcher); + + for (link = past; link; link = g_slist_next (link)) + { + EReminderData *rd = link->data; + gchar *rd_id; + + rd_id = reminder_watcher_build_notif_id (rd); + + if (g_strcmp0 (rd_id, id) == 0) + { + res = g_steal_pointer (&link->data); + g_free (rd_id); + break; + } + + g_free (rd_id); + } + + g_slist_free_full (past, e_reminder_data_free); + + return res; +} + +void +reminder_watcher_dismiss_by_id (EReminderWatcher *reminder_watcher, + const gchar *id) +{ + EReminderData *rd; + ReminderWatcher *rw; + + g_return_if_fail (IS_REMINDER_WATCHER (reminder_watcher)); + g_return_if_fail (id && *id); + + rw = REMINDER_WATCHER (reminder_watcher); + rd = reminder_watcher_find_by_id (reminder_watcher, id); + + if (rd != NULL) + { + print_debug ("Dismiss: Going to dismiss '%s'", reminder_watcher_get_rd_summary (rd)); + + g_application_withdraw_notification (rw->priv->application, id); + + e_reminder_watcher_dismiss (reminder_watcher, rd, NULL, + reminder_watcher_dismiss_done_cb, NULL); + e_reminder_data_free (rd); + } + else + { + print_debug ("Dismiss: Cannot find reminder '%s'", id); + } +} diff --git a/src/calendar-server/reminder-watcher.h b/src/calendar-server/reminder-watcher.h index f98fadf77..dae2cac65 100644 --- a/src/calendar-server/reminder-watcher.h +++ b/src/calendar-server/reminder-watcher.h @@ -59,6 +59,8 @@ struct _ReminderWatcherClass { GType reminder_watcher_get_type (void) G_GNUC_CONST; EReminderWatcher *reminder_watcher_new (GApplication *application, ESourceRegistry *registry); +void reminder_watcher_dismiss_by_id(EReminderWatcher *reminder_watcher, + const gchar *id); G_END_DECLS