[evolution] I#9 - Mail notification tweaks
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] I#9 - Mail notification tweaks
- Date: Tue, 5 Jun 2018 15:41:30 +0000 (UTC)
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]