[evolution] I#9 - Mail notification tweaks



commit 363d0fd04c66a55905ffa5b2c8f40d71786c5c52
Author: Ryan Hendrickson <ryan hendrickson alum mit edu>
Date:   Tue Jun 5 17:40:39 2018 +0200

    I#9 - Mail notification tweaks
    
    Closes https://gitlab.gnome.org/GNOME/evolution/issues/9

 CMakeLists.txt                                     |   8 ++
 config.h.in                                        |   3 +
 src/mail/e-mail-backend.c                          |  44 ++++++
 src/mail/em-event.c                                |  26 ++++
 src/mail/em-event.h                                |  19 ++-
 src/plugins/mail-notification/CMakeLists.txt       |   3 +
 src/plugins/mail-notification/mail-notification.c  | 149 +++++++++++++++------
 .../org-gnome-mail-notification.eplug.xml          |   6 +
 8 files changed, 214 insertions(+), 44 deletions(-)
---
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 37c79f1522..2650a7f6c4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -91,6 +91,7 @@ set(gnome_autoar_minimum_version 0.1.1)
 set(gweather_minimum_version 3.10)
 set(libcanberra_gtk_minimum_version 0.25)
 set(libnotify_minimum_version 0.7)
+set(libunity_minimum_version 7.1.4)
 
 # Load modules from the source tree
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
@@ -588,6 +589,13 @@ set(CERT_UI_LIBS ${MANUAL_NSPR_LIBS})
 pkg_check_modules(LIBNOTIFY libnotify>=${libnotify_minimum_version})
 set(HAVE_LIBNOTIFY ${LIBNOTIFY_FOUND})
 
+# ******************************
+# Libunity
+# ******************************
+
+pkg_check_modules(LIBUNITY unity>=${libunity_minimum_version})
+set(HAVE_LIBUNITY ${LIBUNITY_FOUND})
+
 # ******************************
 # libical tweaks
 # ******************************
diff --git a/config.h.in b/config.h.in
index 4918e99899..75d001de68 100644
--- a/config.h.in
+++ b/config.h.in
@@ -99,6 +99,9 @@
 /* Define if you have libnotify */
 #cmakedefine HAVE_LIBNOTIFY 1
 
+/* Define if you have libunity */
+#cmakedefine HAVE_LIBUNITY 1
+
 /* libical provides ical_set_unknown_token_handling_setting function */
 #cmakedefine HAVE_ICAL_UNKNOWN_TOKEN_HANDLING 1
 
diff --git a/src/mail/e-mail-backend.c b/src/mail/e-mail-backend.c
index b0c5cde4ca..73da7f5e40 100644
--- a/src/mail/e-mail-backend.c
+++ b/src/mail/e-mail-backend.c
@@ -843,6 +843,45 @@ mail_backend_folder_changed_cb (MailFolderCache *folder_cache,
                (EEventTarget *) target);
 }
 
+static void
+mail_backend_folder_unread_updated_cb (MailFolderCache *folder_cache,
+                                       CamelStore *store,
+                                       const gchar *folder_name,
+                                       gint unread_messages,
+                                       EMailBackend *mail_backend)
+{
+       EMEvent *event = em_event_peek ();
+       EMEventTargetFolderUnread *target;
+       gchar *folder_uri;
+       gint folder_type;
+       CamelFolderInfoFlags flags = 0;
+
+       folder_uri = e_mail_folder_uri_build (store, folder_name);
+
+       mail_folder_cache_get_folder_info_flags (
+               folder_cache, store, folder_name, &flags);
+
+       target = em_event_target_new_folder_unread (
+               event, store, folder_uri, unread_messages);
+
+       g_free (folder_uri);
+
+       folder_type = (flags & CAMEL_FOLDER_TYPE_MASK);
+       target->is_inbox = (folder_type == CAMEL_FOLDER_TYPE_INBOX);
+
+       /**
+        * @Event: folder.unread-updated
+        * @Title: Folder unread updated
+        * @Target: EMEventTargetFolder
+        *
+        * folder.unread-updated is emitted whenever the number of unread messages
+        * in a folder changes.
+        */
+       e_event_emit (
+               (EEvent *) event, "folder.unread-updated",
+               (EEventTarget *) target);
+}
+
 static void
 mail_backend_job_started_cb (CamelSession *session,
                              GCancellable *cancellable,
@@ -1260,6 +1299,11 @@ mail_backend_constructed (GObject *object)
                folder_cache, "folder-changed",
                G_CALLBACK (mail_backend_folder_changed_cb), shell_backend);
 
+       g_signal_connect (
+               folder_cache, "folder-unread-updated",
+               G_CALLBACK (mail_backend_folder_unread_updated_cb),
+               shell_backend);
+
        mail_config_init (priv->session);
 
        mail_msg_register_activities (
diff --git a/src/mail/em-event.c b/src/mail/em-event.c
index 9beef05d07..94c9ea1e2c 100644
--- a/src/mail/em-event.c
+++ b/src/mail/em-event.c
@@ -46,6 +46,11 @@ eme_target_free (EEvent *ep,
                g_free (s->msg_sender);
                g_free (s->msg_subject);
                break; }
+       case EM_EVENT_TARGET_FOLDER_UNREAD: {
+               EMEventTargetFolderUnread *s = (EMEventTargetFolderUnread *) t;
+               g_clear_object (&s->store);
+               g_free (s->folder_uri);
+               break; }
        case EM_EVENT_TARGET_MESSAGE: {
                EMEventTargetMessage *s = (EMEventTargetMessage *) t;
 
@@ -133,6 +138,27 @@ em_event_target_new_folder (EMEvent *eme,
        return t;
 }
 
+EMEventTargetFolderUnread *
+em_event_target_new_folder_unread (EMEvent *eme,
+                                   CamelStore *store,
+                                   const gchar *folder_uri,
+                                   guint unread)
+{
+       EMEventTargetFolderUnread *t;
+
+       g_return_val_if_fail (CAMEL_IS_STORE (store), NULL);
+       g_return_val_if_fail (folder_uri != NULL, NULL);
+
+       t = e_event_target_new (
+               &eme->popup, EM_EVENT_TARGET_FOLDER_UNREAD, sizeof (*t));
+
+       t->store = g_object_ref (store);
+       t->folder_uri = g_strdup (folder_uri);
+       t->unread = unread;
+
+       return t;
+}
+
 EMEventTargetComposer *
 em_event_target_new_composer (EMEvent *eme,
                               EMsgComposer *composer,
diff --git a/src/mail/em-event.h b/src/mail/em-event.h
index 842d3507ba..c62ca00d2f 100644
--- a/src/mail/em-event.h
+++ b/src/mail/em-event.h
@@ -56,7 +56,8 @@ enum _em_event_target_t {
        EM_EVENT_TARGET_MESSAGE,
        EM_EVENT_TARGET_COMPOSER,
        EM_EVENT_TARGET_SEND_RECEIVE,
-       EM_EVENT_TARGET_CUSTOM_ICON
+       EM_EVENT_TARGET_CUSTOM_ICON,
+       EM_EVENT_TARGET_FOLDER_UNREAD
 };
 
 /* Flags that describe TARGET_FOLDER */
@@ -101,6 +102,16 @@ struct _EMEventTargetFolder {
        gchar *msg_subject;
 };
 
+typedef struct _EMEventTargetFolderUnread EMEventTargetFolderUnread;
+
+struct _EMEventTargetFolderUnread {
+       EEventTarget target;
+       CamelStore *store;
+       gchar *folder_uri;
+       guint unread;
+       gboolean is_inbox;
+};
+
 typedef struct _EMEventTargetMessage EMEventTargetMessage;
 
 struct _EMEventTargetMessage {
@@ -158,6 +169,12 @@ EMEventTargetFolder *
                                                 const gchar *msg_uid,
                                                 const gchar *msg_sender,
                                                 const gchar *msg_subject);
+EMEventTargetFolderUnread *
+               em_event_target_new_folder_unread
+                                               (EMEvent *emp,
+                                                CamelStore *store,
+                                                const gchar *folder_uri,
+                                                guint32 count_unread_msgs);
 EMEventTargetComposer *
                em_event_target_new_composer    (EMEvent *emp,
                                                 EMsgComposer *composer,
diff --git a/src/plugins/mail-notification/CMakeLists.txt b/src/plugins/mail-notification/CMakeLists.txt
index 203817cb4a..6cb333a420 100644
--- a/src/plugins/mail-notification/CMakeLists.txt
+++ b/src/plugins/mail-notification/CMakeLists.txt
@@ -28,6 +28,7 @@ target_compile_options(org-gnome-mail-notification PUBLIC
        ${EVOLUTION_DATA_SERVER_CFLAGS}
        ${GNOME_PLATFORM_CFLAGS}
        ${LIBNOTIFY_CFLAGS}
+       ${LIBUNITY_CFLAGS}
 )
 
 target_include_directories(org-gnome-mail-notification PUBLIC
@@ -39,6 +40,7 @@ target_include_directories(org-gnome-mail-notification PUBLIC
        ${EVOLUTION_DATA_SERVER_INCLUDE_DIRS}
        ${GNOME_PLATFORM_INCLUDE_DIRS}
        ${LIBNOTIFY_INCLUDE_DIRS}
+       ${LIBUNITY_INCLUDE_DIRS}
 )
 
 target_link_libraries(org-gnome-mail-notification
@@ -47,6 +49,7 @@ target_link_libraries(org-gnome-mail-notification
        ${EVOLUTION_DATA_SERVER_LDFLAGS}
        ${GNOME_PLATFORM_LDFLAGS}
        ${LIBNOTIFY_LDFLAGS}
+       ${LIBUNITY_LDFLAGS}
 )
 
 install(TARGETS org-gnome-mail-notification
diff --git a/src/plugins/mail-notification/mail-notification.c 
b/src/plugins/mail-notification/mail-notification.c
index 7df0359964..ac68e1bb03 100644
--- a/src/plugins/mail-notification/mail-notification.c
+++ b/src/plugins/mail-notification/mail-notification.c
@@ -45,6 +45,10 @@
 #include <libnotify/notify.h>
 #endif
 
+#ifdef HAVE_LIBUNITY
+#include <unity.h>
+#endif
+
 #define CONF_KEY_NOTIFY_ONLY_INBOX     "notify-only-inbox"
 #define CONF_KEY_ENABLED_STATUS                "notify-status-enabled"
 #define CONF_KEY_STATUS_NOTIFICATION   "notify-status-notification"
@@ -260,6 +264,11 @@ enable_dbus (gint enable)
 #ifdef HAVE_LIBNOTIFY
 
 static guint status_count = 0;
+static GHashTable *unread_messages_by_folder = NULL;
+
+#ifdef HAVE_LIBUNITY
+static guint unread_message_count = 0;
+#endif
 
 static NotifyNotification *notify = NULL;
 
@@ -383,60 +392,58 @@ new_notify_status (EMEventTargetFolder *t)
        const gchar *summary;
        const gchar *icon_name;
 
-       if (!status_count) {
-               CamelService *service;
-               const gchar *store_name;
-               gchar *folder_name;
+       status_count += t->new;
 
-               service = CAMEL_SERVICE (t->store);
-               store_name = camel_service_get_display_name (service);
+       text = g_strdup_printf (ngettext (
+               /* Translators: '%d' is the count of mails received. */
+               "You have received %d new message.",
+               "You have received %d new messages.",
+               status_count), status_count);
 
-               folder_name = g_strdup_printf (
-                       "%s/%s", store_name, t->folder_name);
+       if (t->msg_sender) {
+               gchar *tmp, *str;
 
-               status_count = t->new;
+               /* Translators: "From:" is preceding a new mail
+                * sender address, like "From: user example com" */
+               str = g_strdup_printf (_("From: %s"), t->msg_sender);
+               tmp = g_strconcat (text, "\n", str, NULL);
 
-               text = g_strdup_printf (ngettext (
-                       /* Translators: '%d' is the count of mails received. */
-                       "You have received %d new message.",
-                       "You have received %d new messages.",
-                       status_count), status_count);
+               g_free (text);
+               g_free (str);
 
-               g_free (folder_name);
+               text = tmp;
+       }
 
-               if (t->msg_sender) {
-                       gchar *tmp, *str;
+       if (t->msg_subject) {
+               gchar *tmp, *str;
 
-                       /* Translators: "From:" is preceding a new mail
-                        * sender address, like "From: user example com" */
-                       str = g_strdup_printf (_("From: %s"), t->msg_sender);
-                       tmp = g_strconcat (text, "\n", str, NULL);
+               /* Translators: "Subject:" is preceding a new mail
+                * subject, like "Subject: It happened again" */
+               str = g_strdup_printf (_("Subject: %s"), t->msg_subject);
+               tmp = g_strconcat (text, "\n", str, NULL);
 
-                       g_free (text);
-                       g_free (str);
+               g_free (text);
+               g_free (str);
 
-                       text = tmp;
-               }
+               text = tmp;
+       }
 
-               if (t->msg_subject) {
-                       gchar *tmp, *str;
+       if (status_count > 1 && (t->msg_sender || t->msg_subject)) {
+               gchar *tmp, *str;
+               guint additional_messages = status_count - 1;
 
-                       /* Translators: "Subject:" is preceding a new mail
-                        * subject, like "Subject: It happened again" */
-                       str = g_strdup_printf (_("Subject: %s"), t->msg_subject);
-                       tmp = g_strconcat (text, "\n", str, NULL);
+               str = g_strdup_printf (ngettext (
+                       /* Translators: %d is the count of mails received in addition
+                        * to the one displayed in this notification. */
+                       "(and %d more)",
+                       "(and %d more)",
+                       additional_messages), additional_messages);
+               tmp = g_strconcat (text, "\n", str, NULL);
 
-                       g_free (text);
-                       g_free (str);
+               g_free (text);
+               g_free (str);
 
-                       text = tmp;
-               }
-       } else {
-               status_count += t->new;
-               text = g_strdup_printf (ngettext (
-                       "You have received %d new message.",
-                       "You have received %d new messages.",
-                       status_count), status_count);
+               text = tmp;
        }
 
        icon_name = "evolution";
@@ -503,6 +510,41 @@ new_notify_status (EMEventTargetFolder *t)
        g_free (text);
 }
 
+static void
+unread_notify_status (EMEventTargetFolderUnread *t)
+{
+       gpointer lookup;
+       guint old_unread;
+
+       if (unread_messages_by_folder == NULL)
+               unread_messages_by_folder = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+       lookup = g_hash_table_lookup (unread_messages_by_folder, t->folder_uri);
+       old_unread = lookup == NULL ? 0 : GPOINTER_TO_UINT (lookup);
+
+       /* Infer that a message has been read by a decrease in the number of unread
+        * messages in a folder. */
+       if (t->unread < old_unread)
+               remove_notification ();
+
+       if (t->unread != old_unread) {
+               if (t->unread) {
+                       g_hash_table_insert (unread_messages_by_folder, g_strdup (t->folder_uri), 
GUINT_TO_POINTER (t->unread));
+               } else {
+                       g_hash_table_remove (unread_messages_by_folder, t->folder_uri);
+               }
+       }
+
+#ifdef HAVE_LIBUNITY
+       if (t->is_inbox) {
+               UnityLauncherEntry *entry = unity_launcher_entry_get_for_desktop_id 
("org.gnome.Evolution.desktop");
+               unread_message_count += t->unread - old_unread;
+               unity_launcher_entry_set_count (entry, unread_message_count);
+               unity_launcher_entry_set_count_visible (entry, unread_message_count != 0);
+       }
+#endif
+}
+
 static void
 read_notify_status (EMEventTargetMessage *t)
 {
@@ -799,7 +841,7 @@ get_config_widget_sound (void)
 /* -------------------------------------------------------------------  */
 
 static void
-e_mail_notif_open_gnome_notificaiton_settings_cb (GtkWidget *button,
+e_mail_notif_open_gnome_notification_settings_cb (GtkWidget *button,
                                                  gpointer user_data)
 {
 #ifndef G_OS_WIN32
@@ -845,7 +887,7 @@ get_cfg_widget (void)
 
        if (e_util_is_running_gnome ()) {
                widget = gtk_button_new_with_mnemonic ("Open _GNOME Notification settings");
-               g_signal_connect (widget, "clicked", G_CALLBACK 
(e_mail_notif_open_gnome_notificaiton_settings_cb), NULL);
+               g_signal_connect (widget, "clicked", G_CALLBACK 
(e_mail_notif_open_gnome_notification_settings_cb), NULL);
                gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
                gtk_widget_show (widget);
        } else {
@@ -870,6 +912,7 @@ get_cfg_widget (void)
 }
 
 void org_gnome_mail_new_notify (EPlugin *ep, EMEventTargetFolder *t);
+void org_gnome_mail_unread_notify (EPlugin *ep, EMEventTargetFolderUnread *t);
 void org_gnome_mail_read_notify (EPlugin *ep, EMEventTargetMessage *t);
 
 gint e_plugin_lib_enable (EPlugin *ep, gint enable);
@@ -900,6 +943,26 @@ org_gnome_mail_new_notify (EPlugin *ep,
        g_mutex_unlock (&mlock);
 }
 
+void
+org_gnome_mail_unread_notify (EPlugin *ep,
+                              EMEventTargetFolderUnread *t)
+{
+#ifdef HAVE_LIBNOTIFY
+       g_return_if_fail (t != NULL);
+
+       if (!enabled || (!t->is_inbox &&
+               is_part_enabled (CONF_KEY_NOTIFY_ONLY_INBOX)))
+               return;
+
+       g_mutex_lock (&mlock);
+
+       if (is_part_enabled (CONF_KEY_ENABLED_STATUS) || e_util_is_running_gnome ())
+               unread_notify_status (t);
+
+       g_mutex_unlock (&mlock);
+#endif
+}
+
 void
 org_gnome_mail_read_notify (EPlugin *ep,
                             EMEventTargetMessage *t)
diff --git a/src/plugins/mail-notification/org-gnome-mail-notification.eplug.xml 
b/src/plugins/mail-notification/org-gnome-mail-notification.eplug.xml
index 8cc4fd6983..155b2a850e 100644
--- a/src/plugins/mail-notification/org-gnome-mail-notification.eplug.xml
+++ b/src/plugins/mail-notification/org-gnome-mail-notification.eplug.xml
@@ -16,6 +16,12 @@
                        target="folder"/>
                </hook>
 
+               <hook class="org.gnome.evolution.mail.events:1.0">
+                       <event id="folder.unread-updated"
+                       handle="org_gnome_mail_unread_notify"
+                       target="folder"/>
+               </hook>
+
                <hook class="org.gnome.evolution.mail.events:1.0">
                        <event id="message.reading"
                        handle="org_gnome_mail_read_notify"


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