Hi all Having not found a satisfactory solution to bug 311512 (new mail notification) by trying to put the notification code into where mail is received by the camel backends, I've looked into a different approach.
I was intrigued by how the mail-notification tool works, since it effectively hangs off the same problematic folder.changed event. Looking at its source code revealed that the author added to code to 'snoop' through the messages, looking for ones that really were newmail (rather than simply 'added to this folder'). So I have replicated this approach, but natively in evolution. The attached patch affects mail-folder-cache.c only, and adds a function to look for new messages comparing their 'received' timestamp with a global timestamp. This enables us to check for messages that are brand new - received since the last new mail arrived. Can anyone comment on this patch - it should resolve nearly all the mail notification problems. The one is doesn't resolve is to do with junk mail - presumably I can just add a test against the messages to see if they are junk. However - that assumes no folder_changed call happens until after the junk-mail filtering has happened. Currently the check has to snoop all messages in the folder. I think in principle I can move the test into folder_changed and snoop through the list of 'uid_added', which should be more efficient. Assuming nobody flags any big pitfalls, I'll look into that soon. Regards Karl
--- mail-folder-cache.h.old 2007-03-02 13:11:50.000000000 +0000 +++ mail-folder-cache.h 2007-03-02 11:49:43.000000000 +0000 @@ -25,6 +25,9 @@ #ifndef _MAIL_FOLDER_CACHE_H #define _MAIL_FOLDER_CACHE_H +/* min no. seconds between newmail notifications */ +#define NOTIFY_THROTTLE 30 + #include <camel/camel-store.h> /* Add a store whose folders should appear in the shell --- mail-folder-cache.c.old 2007-03-02 13:11:42.000000000 +0000 +++ mail-folder-cache.c 2007-03-02 13:14:13.000000000 +0000 @@ -103,7 +103,8 @@ struct _folder_update { char *olduri; int unread; - CamelStore *store; + CamelStore *store; + CamelFolder *folder; }; struct _store_info { @@ -127,10 +128,10 @@ static guint notify_id = 0; static int notify_type = -1; static time_t last_notify = 0; +static time_t last_newmail = 0; static guint notify_idle_id = 0; static gboolean notify_idle_cb (gpointer user_data); - /* Store to storeinfo table, active stores */ static GHashTable *stores = NULL; @@ -191,14 +192,41 @@ notify_type_changed (GConfClient *client notify_type = gconf_client_get_int (client, "/apps/evolution/mail/notify/type", NULL); } +static gboolean +check_brand_new(CamelFolder *folder) +{ + GPtrArray *summary; + int i; + + summary = camel_folder_get_summary(folder); + for (i = 0; i < summary->len; i++) + { + CamelMessageInfo *info = summary->pdata[i]; + +// Check junk here using the flags? + if (((camel_message_info_flags(info) & CAMEL_MESSAGE_SEEN) == 0) && + (camel_message_info_date_received(info) > last_newmail)) + { + camel_folder_free_summary(folder, summary); + time (&last_newmail); + d(printf("brand_new TRUE\n")); + return TRUE; + } + } + + camel_folder_free_summary(folder, summary); + d(printf("brand_new FALSE\n")); + return FALSE; +} + static void real_flush_updates(void *o, void *event_data, void *data) { struct _MailComponent *component; struct _EMFolderTreeModel *model; struct _folder_update *up; - time_t now; - + gboolean brand_new = FALSE; + component = mail_component_peek (); model = mail_component_peek_tree_model (component); @@ -230,7 +258,12 @@ real_flush_updates(void *o, void *event_ /* update unread counts */ em_folder_tree_model_set_unread_count (model, up->store, up->full_name, up->unread); - + + /* Check for brand new mail */ + if (up->new && up->unread > 0) { + brand_new = check_brand_new (up->folder); + } + /* new mail notification */ if (notify_type == -1) { /* need to track the user's new-mail-notification settings... */ @@ -244,13 +277,12 @@ real_flush_updates(void *o, void *event_ notify_type = gconf_client_get_int (gconf, "/apps/evolution/mail/notify/type", NULL); } - time (&now); - if (notify_type != 0 && up->new && notify_idle_id == 0 && (now - last_notify >= 5)) + if (notify_type != 0 && brand_new && notify_idle_id == 0 && (last_newmail - last_notify >= NOTIFY_THROTTLE)) notify_idle_id = g_idle_add_full (G_PRIORITY_LOW, notify_idle_cb, NULL, NULL); if (up->uri) { EMEvent *e = em_event_peek(); - EMEventTargetFolder *t = em_event_target_new_folder(e, up->uri, up->new?EM_EVENT_FOLDER_NEWMAIL:0); + EMEventTargetFolder *t = em_event_target_new_folder(e, up->uri, brand_new?EM_EVENT_FOLDER_NEWMAIL:0); /** @Event: folder.changed * @Title: Folder changed @@ -380,6 +412,7 @@ update_1folder(struct _folder_info *mfi, up->new = new ? 1 : 0; up->store = mfi->store_info->store; up->uri = g_strdup(mfi->uri); + up->folder = folder; camel_object_ref(up->store); e_dlist_addtail(&updates, (EDListNode *)up); flush_updates();
_______________________________________________ Evolution-hackers mailing list Evolution-hackers@gnome.org http://mail.gnome.org/mailman/listinfo/evolution-hackers