From: Kevin McCarthy Date: Tue, 7 Jun 2016 22:02:58 +0000 (-0700) Subject: Make extended buffy independent of the sidebar. X-Git-Tag: neomutt-20160822~121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e5c305d7fd54ba6746ee3b87ad85bf683b390a5f;p=neomutt Make extended buffy independent of the sidebar. Add new boolean option $mail_check_stats (default off) and $mail_check_stats_interval. The first turns extended buffy on. The second sets the amount of time in between extended buffy checks (defaulting to 60 seconds). Remove the option $sidebar_refresh_time. Change mutt_buffy_check() to only notify the sidebar to redraw if a mailbox buffy value changes. Remove the #ifdefs around the extended buffy functions. The next patch will merge these functions with the basic functions and pass a parameter instead. Imap is a special case, because it sends out the status in one batch. Change this to perform the comparisons inside cmd_parse_status() and flag the sidebar there. It was previously directly assigning the status counters (unsigned int) to the buffy->new (short). Change this to assign 1/0. --- diff --git a/buffy.c b/buffy.c index 219177409..ffd8f36da 100644 --- a/buffy.c +++ b/buffy.c @@ -45,6 +45,7 @@ #include static time_t BuffyTime = 0; /* last time we started checking for mail */ +static time_t BuffyStatsTime = 0; /* last time we check performed mail_check_stats */ time_t BuffyDoneTime = 0; /* last time we knew for sure how much mail there was. */ static short BuffyCount = 0; /* how many boxes with new mail */ static short BuffyNotify = 0; /* # of unnotified new boxes */ @@ -388,7 +389,6 @@ static int buffy_maildir_hasnew (BUFFY* mailbox) return 0; } -#ifdef USE_SIDEBAR /** * buffy_maildir_update_dir - Update counts for one directory * @mailbox: BUFFY representing a maildir mailbox @@ -451,9 +451,6 @@ buffy_maildir_update_dir (BUFFY *mailbox, const char *dir) void buffy_maildir_update (BUFFY *mailbox) { - if (!option (OPTSIDEBAR)) - return; - mailbox->msg_count = 0; mailbox->msg_unread = 0; mailbox->msg_flagged = 0; @@ -463,12 +460,8 @@ buffy_maildir_update (BUFFY *mailbox) mailbox->new = 1; } buffy_maildir_update_dir (mailbox, "cur"); - - mailbox->sb_last_checked = time (NULL); } -#endif - /* returns 1 if mailbox has new mail */ static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb) { @@ -500,7 +493,6 @@ static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb) return rc; } -#ifdef USE_SIDEBAR /** * buffy_mbox_update - Update messages counts for an mbox mailbox * @mailbox: BUFFY representing an mbox mailbox @@ -515,9 +507,7 @@ buffy_mbox_update (BUFFY *mailbox, struct stat *sb) { CONTEXT *ctx = NULL; - if (!option (OPTSIDEBAR)) - return; - if ((mailbox->sb_last_checked > sb->st_mtime) && (mailbox->msg_count != 0)) + if ((mailbox->stats_last_checked > sb->st_mtime) && (mailbox->msg_count != 0)) return; /* no check necessary */ ctx = mx_open_mailbox (mailbox->path, MUTT_READONLY | MUTT_QUIET | MUTT_NOSORT | MUTT_PEEK, NULL); @@ -526,11 +516,10 @@ buffy_mbox_update (BUFFY *mailbox, struct stat *sb) mailbox->msg_count = ctx->msgcount; mailbox->msg_unread = ctx->unread; mailbox->msg_flagged = ctx->flagged; - mailbox->sb_last_checked = time (NULL); + mailbox->stats_last_checked = time (NULL); mx_close_mailbox (ctx, 0); } } -#endif int mutt_buffy_check (int force) { @@ -538,6 +527,11 @@ int mutt_buffy_check (int force) struct stat sb; struct stat contex_sb; time_t t; + int check_stats = 0; +#ifdef USE_SIDEBAR + short orig_new; + int orig_count, orig_unread, orig_flagged; +#endif sb.st_size=0; contex_sb.st_dev=0; @@ -555,13 +549,20 @@ int mutt_buffy_check (int force) t = time (NULL); if (!force && (t - BuffyTime < BuffyTimeout)) return BuffyCount; - + + if (option (OPTMAILCHECKSTATS) && + (t - BuffyStatsTime >= BuffyCheckStatsInterval)) + { + check_stats = 1; + BuffyStatsTime = t; + } + BuffyTime = t; BuffyCount = 0; BuffyNotify = 0; #ifdef USE_IMAP - BuffyCount += imap_buffy_check (force); + BuffyCount += imap_buffy_check (force, check_stats); #endif /* check device ID and serial number instead of comparing paths */ @@ -572,9 +573,6 @@ int mutt_buffy_check (int force) contex_sb.st_ino=0; } -#ifdef USE_SIDEBAR - int should_refresh = mutt_sb_should_refresh(); -#endif for (tmp = Incoming; tmp; tmp = tmp->next) { if (tmp->magic != MUTT_IMAP) @@ -597,6 +595,13 @@ int mutt_buffy_check (int force) } } +#ifdef USE_SIDEBAR + orig_new = tmp->new; + orig_count = tmp->msg_count; + orig_unread = tmp->msg_unread; + orig_flagged = tmp->msg_flagged; +#endif + /* check to see if the folder is the currently selected folder * before polling */ if (!Context || !Context->path || @@ -608,28 +613,22 @@ int mutt_buffy_check (int force) { case MUTT_MBOX: case MUTT_MMDF: -#ifdef USE_SIDEBAR - if (should_refresh) + if (check_stats) buffy_mbox_update (tmp, &sb); -#endif if (buffy_mbox_hasnew (tmp, &sb) > 0) BuffyCount++; break; case MUTT_MAILDIR: -#ifdef USE_SIDEBAR - if (should_refresh) + if (check_stats) buffy_maildir_update (tmp); -#endif if (buffy_maildir_hasnew (tmp) > 0) BuffyCount++; break; case MUTT_MH: -#ifdef USE_SIDEBAR - if (should_refresh) + if (check_stats) mh_buffy_update (tmp); -#endif mh_buffy(tmp); if (tmp->new) BuffyCount++; @@ -639,18 +638,19 @@ int mutt_buffy_check (int force) else if (option(OPTCHECKMBOXSIZE) && Context && Context->path) tmp->size = (off_t) sb.st_size; /* update the size of current folder */ +#ifdef USE_SIDEBAR + if ((orig_new != tmp->new) || + (orig_count != tmp->msg_count) || + (orig_unread != tmp->msg_unread) || + (orig_flagged != tmp->msg_flagged)) + SidebarNeedsRedraw = 1; +#endif + if (!tmp->new) tmp->notified = 0; else if (!tmp->notified) BuffyNotify++; } -#ifdef USE_SIDEBAR - if (should_refresh) - { - SidebarNeedsRedraw = 1; - mutt_sb_set_update_time(); - } -#endif BuffyDoneTime = BuffyTime; return (BuffyCount); diff --git a/buffy.h b/buffy.h index 7f2f1d542..d3f5454ac 100644 --- a/buffy.h +++ b/buffy.h @@ -35,24 +35,26 @@ typedef struct buffy_t struct buffy_t *prev; #endif short new; /* mailbox has new mail */ -#ifdef USE_SIDEBAR + + /* These next three are only set when OPTMAILCHECKSTATS is set */ int msg_count; /* total number of messages */ int msg_unread; /* number of unread messages */ int msg_flagged; /* number of flagged messages */ + +#ifdef USE_SIDEBAR short is_hidden; /* is hidden from the sidebar */ #endif short notified; /* user has been notified */ short magic; /* mailbox type */ short newly_created; /* mbox or mmdf just popped into existence */ time_t last_visited; /* time of last exit from this mailbox */ -#ifdef USE_SIDEBAR - time_t sb_last_checked; /* time of last buffy check from sidebar */ -#endif + time_t stats_last_checked; /* time of last mail_check_stats calculation */ } BUFFY; WHERE BUFFY *Incoming INITVAL (0); WHERE short BuffyTimeout INITVAL (3); +WHERE short BuffyCheckStatsInterval INITVAL (60); extern time_t BuffyDoneTime; /* last time we knew for sure how much mail there was */ diff --git a/contrib/sample.muttrc-sidebar b/contrib/sample.muttrc-sidebar index 1b5cda7bd..f56e527ec 100644 --- a/contrib/sample.muttrc-sidebar +++ b/contrib/sample.muttrc-sidebar @@ -43,6 +43,10 @@ set sidebar_next_new_wrap = no # Note: Only the first character of this string is used. set sidebar_divider_char = '|' +# Enable extended buffy mode to calculate total, new, and flagged +# message counts for each mailbox. +set mail_check_stats + # Display the Sidebar mailboxes using this format string. set sidebar_format = '%B%?F? [%F]?%* %?N?%N/?%S' diff --git a/doc/manual.xml.head b/doc/manual.xml.head index f30a947b2..57c45f305 100644 --- a/doc/manual.xml.head +++ b/doc/manual.xml.head @@ -8164,11 +8164,6 @@ please have a look at the mixmaster documentation. boolean no - - sidebar_refresh_time - number - 60 - sidebar_short_path boolean diff --git a/globals.h b/globals.h index 05a3e11f7..d2b6124d4 100644 --- a/globals.h +++ b/globals.h @@ -222,7 +222,6 @@ WHERE short ScoreThresholdFlag; #ifdef USE_SIDEBAR WHERE short SidebarWidth; -WHERE short SidebarRefreshTime; WHERE LIST *SidebarWhitelist INITVAL(0); WHERE int SidebarNeedsRedraw INITVAL (0); #endif diff --git a/imap/command.c b/imap/command.c index f73e895dc..c91402422 100644 --- a/imap/command.c +++ b/imap/command.c @@ -900,6 +900,7 @@ static void cmd_parse_status (IMAP_DATA* idata, char* s) IMAP_STATUS *status; unsigned int olduv, oldun; long litlen; + short new = 0; mailbox = imap_next_word (s); @@ -1000,30 +1001,32 @@ static void cmd_parse_status (IMAP_DATA* idata, char* s) if (olduv && olduv == status->uidvalidity) { if (oldun < status->uidnext) - inc->new = status->unseen; + new = (status->unseen > 0); } else if (!olduv && !oldun) /* first check per session, use recent. might need a flag for this. */ - inc->new = status->recent; + new = (status->recent > 0); else - inc->new = status->unseen; + new = (status->unseen > 0); } else - inc->new = status->unseen; + new = (status->unseen > 0); + +#ifdef USE_SIDEBAR + if ((inc->new != new) || + (inc->msg_count != status->messages) || + (inc->msg_unread != status->unseen)) + SidebarNeedsRedraw = 1; +#endif + inc->new = new; + inc->msg_count = status->messages; + inc->msg_unread = status->unseen; if (inc->new) /* force back to keep detecting new mail until the mailbox is opened */ status->uidnext = oldun; -#ifdef USE_SIDEBAR - /* Make the sidebar show the correct numbers */ - if (status->messages) { - inc->msg_count = status->messages; - inc->msg_unread = status->unseen; - } -#endif - FREE (&value); return; } diff --git a/imap/imap.c b/imap/imap.c index 8a73ec9ad..cc31be55e 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -1503,7 +1503,7 @@ static int imap_get_mailbox (const char* path, IMAP_DATA** hidata, char* buf, si /* check for new mail in any subscribed mailboxes. Given a list of mailboxes * rather than called once for each so that it can batch the commands and * save on round trips. Returns number of mailboxes with new mail. */ -int imap_buffy_check (int force) +int imap_buffy_check (int force, int check_stats) { IMAP_DATA* idata; IMAP_DATA* lastdata = NULL; @@ -1525,8 +1525,6 @@ int imap_buffy_check (int force) if (mailbox->magic != MUTT_IMAP) continue; - mailbox->new = 0; - if (imap_get_mailbox (mailbox->path, &idata, name, sizeof (name)) < 0) continue; @@ -1558,12 +1556,12 @@ int imap_buffy_check (int force) lastdata = idata; imap_munge_mbox_name (idata, munged, sizeof (munged), name); - snprintf (command, sizeof (command), -#ifdef USE_SIDEBAR + if (check_stats) + snprintf (command, sizeof (command), "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT MESSAGES)", munged); -#else + else + snprintf (command, sizeof (command), "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT)", munged); -#endif if (imap_exec (idata, command, IMAP_CMD_QUEUE) < 0) { diff --git a/imap/imap.h b/imap/imap.h index 132ae2b9b..693008b10 100644 --- a/imap/imap.h +++ b/imap/imap.h @@ -38,7 +38,7 @@ int imap_delete_mailbox (CONTEXT* idata, IMAP_MBOX mx); int imap_open_mailbox_append (CONTEXT *ctx); int imap_sync_mailbox (CONTEXT *ctx, int expunge, int *index_hint); int imap_close_mailbox (CONTEXT *ctx); -int imap_buffy_check (int force); +int imap_buffy_check (int force, int check_stats); int imap_status (char *path, int queue); int imap_search (CONTEXT* ctx, const pattern_t* pat); int imap_subscribe (char *path, int subscribe); diff --git a/init.h b/init.h index 4b1617af7..47b5647e6 100644 --- a/init.h +++ b/init.h @@ -1409,6 +1409,22 @@ struct option_t MuttVars[] = { ** When \fI$$mark_old\fP is set, Mutt does not consider the mailbox to contain new ** mail if only old messages exist. */ + { "mail_check_stats", DT_BOOL, R_NONE, OPTMAILCHECKSTATS, 0 }, + /* + ** .pp + ** When \fIset\fP, mutt will periodically calculate message + ** statistics of a mailbox while polling for new mail. It will + ** check for unread, flagged, and total message counts. Because + ** this operation is more performance intensive, it defaults to + ** \fIunset\fP, and has a separate option, $$mail_check_stats_interval, to + ** control how often to update these counts. + */ + { "mail_check_stats_interval", DT_NUM, R_NONE, UL &BuffyCheckStatsInterval, 60 }, + /* + ** .pp + ** When $$mail_check_stats is \fIset\fP, this variable configures + ** how often (in seconds) mutt will update message counts. + */ { "mailcap_path", DT_STR, R_NONE, UL &MailcapPath, 0 }, /* ** .pp @@ -2727,7 +2743,9 @@ struct option_t MuttVars[] = { ** * = Can be optionally printed if nonzero ** @ = Only applicable to the current folder ** .pp - ** A useful value for this is "%B%?F? [%F]?%* %?N?%N/?%S". + ** In order to use %S, %N, %F, and %!, $$mail_check_stats must + ** be \fIset\fP. When set, a useful value for this setting is + ** "%B%?F? [%F]?%* %?N?%N/?%S". */ { "sidebar_indent_string", DT_STR, R_BOTH, UL &SidebarIndentString, UL " " }, /* @@ -2753,14 +2771,6 @@ struct option_t MuttVars[] = { ** \fC\fP command is similarly affected, wrapping around to ** the end of the list. */ - { "sidebar_refresh_time", DT_NUM, R_BOTH, UL &SidebarRefreshTime, 60 }, - /* - ** .pp - ** Set sidebar_refresh_time to the minimum number of seconds between refreshes. - ** This will reduced network traffic. - ** .pp - ** \fBNote:\fP Set to 0 to disable refreshing. - */ { "sidebar_short_path", DT_BOOL, R_BOTH, OPTSIDEBARSHORTPATH, 0 }, /* ** .pp diff --git a/mailbox.h b/mailbox.h index bdbfeac29..a0c523877 100644 --- a/mailbox.h +++ b/mailbox.h @@ -25,11 +25,8 @@ #define MUTT_READONLY (1<<2) /* open in read-only mode */ #define MUTT_QUIET (1<<3) /* do not print any messages */ #define MUTT_NEWFOLDER (1<<4) /* create a new folder - same as MUTT_APPEND, but uses - * safe_fopen() for mbox-style folders. - */ -#ifdef USE_SIDEBAR + * safe_fopen() for mbox-style folders. */ #define MUTT_PEEK (1<<5) /* revert atime back after taking a look (if applicable) */ -#endif /* mx_open_new_message() */ #define MUTT_ADD_FROM (1<<0) /* add a From_ line */ diff --git a/mbox.c b/mbox.c index 3d071dc46..b3ee560b2 100644 --- a/mbox.c +++ b/mbox.c @@ -100,9 +100,7 @@ int mmdf_parse_mailbox (CONTEXT *ctx) mutt_perror (ctx->path); return (-1); } -#ifdef USE_SIDEBAR ctx->atime = sb.st_atime; -#endif ctx->mtime = sb.st_mtime; ctx->size = sb.st_size; @@ -254,9 +252,7 @@ int mbox_parse_mailbox (CONTEXT *ctx) ctx->size = sb.st_size; ctx->mtime = sb.st_mtime; -#ifdef USE_SIDEBAR ctx->atime = sb.st_atime; -#endif #ifdef NFS_ATTRIBUTE_HACK if (sb.st_mtime > sb.st_atime) diff --git a/mh.c b/mh.c index 7b04305aa..6d00637af 100644 --- a/mh.c +++ b/mh.c @@ -298,7 +298,6 @@ void mh_buffy(BUFFY *b) mhs_free_sequences (&mhs); } -#ifdef USE_SIDEBAR /** * mh_buffy_update - Update messages counts for an mh mailbox * @mailbox: BUFFY representing a maildir mailbox @@ -315,9 +314,6 @@ mh_buffy_update (BUFFY *mailbox) if (!mailbox) return; - if (!option (OPTSIDEBAR)) - return; - memset (&mhs, 0, sizeof (mhs)); if (mh_read_sequences (&mhs, mailbox->path) < 0) @@ -336,9 +332,7 @@ mh_buffy_update (BUFFY *mailbox) mailbox->msg_flagged++; } mhs_free_sequences (&mhs); - mailbox->sb_last_checked = time (NULL); } -#endif static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt) { diff --git a/mutt.h b/mutt.h index cb386fb49..aa18241ea 100644 --- a/mutt.h +++ b/mutt.h @@ -388,6 +388,7 @@ enum OPTKEEPFLAGGED, OPTMAILCAPSANITIZE, OPTMAILCHECKRECENT, + OPTMAILCHECKSTATS, OPTMAILDIRTRASH, OPTMAILDIRCHECKCUR, OPTMARKERS, @@ -900,9 +901,7 @@ typedef struct _context { char *path; FILE *fp; -#ifdef USE_SIDEBAR time_t atime; -#endif time_t mtime; off_t size; off_t vsize; @@ -937,9 +936,7 @@ typedef struct _context unsigned int quiet : 1; /* inhibit status messages? */ unsigned int collapsed : 1; /* are all threads collapsed? */ unsigned int closing : 1; /* mailbox is being closed */ -#ifdef USE_SIDEBAR unsigned int peekonly : 1; /* just taking a glance, revert atime */ -#endif /* driver hooks */ void *data; /* driver specific data */ diff --git a/mx.c b/mx.c index e05142164..b2397740a 100644 --- a/mx.c +++ b/mx.c @@ -639,10 +639,8 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx) ctx->quiet = 1; if (flags & MUTT_READONLY) ctx->readonly = 1; -#ifdef USE_SIDEBAR if (flags & MUTT_PEEK) ctx->peekonly = 1; -#endif if (flags & (MUTT_APPEND|MUTT_NEWFOLDER)) { @@ -712,26 +710,22 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx) void mx_fastclose_mailbox (CONTEXT *ctx) { int i; + struct utimbuf ut; if(!ctx) return; -#ifdef USE_SIDEBAR /* fix up the times so buffy won't get confused */ - struct utimbuf ut; if (ctx->peekonly && ctx->path && (ctx->mtime > ctx->atime)) { ut.actime = ctx->atime; ut.modtime = ctx->mtime; utime (ctx->path, &ut); } -#endif /* never announce that a mailbox we've just left has new mail. #3290 * XXX: really belongs in mx_close_mailbox, but this is a nice hook point */ -#ifdef USE_SIDEBAR if (!ctx->peekonly) -#endif - mutt_buffy_setnotified(ctx->path); + mutt_buffy_setnotified(ctx->path); if (ctx->mx_ops) ctx->mx_ops->close (ctx); diff --git a/mx.h b/mx.h index 6bc11b435..95d899461 100644 --- a/mx.h +++ b/mx.h @@ -53,9 +53,7 @@ int mbox_check_empty (const char *); void mbox_reset_atime (CONTEXT *, struct stat *); int mh_sync_mailbox (CONTEXT *, int *); -#ifdef USE_SIDEBAR void mh_buffy_update (BUFFY *mailbox); -#endif int mh_check_empty (const char *); int maildir_check_empty (const char *); diff --git a/sidebar.c b/sidebar.c index 5f26bd05f..e363063a9 100644 --- a/sidebar.c +++ b/sidebar.c @@ -30,7 +30,6 @@ /* Previous values for some sidebar config */ static short PreviousSort; /* sidebar_sort_method */ -static time_t LastRefresh; /* Time of last refresh */ /* Keep track of various BUFFYs */ static BUFFY *TopBuffy; /* First mailbox visible in sidebar */ @@ -758,29 +757,6 @@ void mutt_sb_draw (void) draw_sidebar (num_rows, num_cols, div_width); } -/** - * mutt_sb_should_refresh - Check if the sidebar is due to be refreshed - * - * The "sidebar_refresh_time" config option allows the user to limit the frequency - * with which the sidebar is refreshed. - * - * Returns: - * 1 Yes, refresh is due - * 0 No, refresh happened recently - */ -int mutt_sb_should_refresh (void) -{ - if (!option (OPTSIDEBAR)) - return 0; - - if (SidebarRefreshTime == 0) - return 0; - - time_t diff = (time (NULL) - LastRefresh); - - return (diff >= SidebarRefreshTime); -} - /** * mutt_sb_change_mailbox - Change the selected mailbox * @op: Operation code @@ -930,19 +906,6 @@ BUFFY *mutt_sb_set_open_buffy (const char *path) return OpnBuffy; } -/** - * mutt_sb_set_update_time - Note the time that the sidebar was updated - * - * Update the timestamp representing the last sidebar update. If the user - * configures "sidebar_refresh_time", this will help to reduce traffic. - */ -void mutt_sb_set_update_time (void) -{ - /* XXX - should this be public? */ - - LastRefresh = time (NULL); -} - /** * mutt_sb_notify_mailbox - The state of a BUFFY is about to change * diff --git a/sidebar.h b/sidebar.h index f219d5ec1..885f5e64b 100644 --- a/sidebar.h +++ b/sidebar.h @@ -29,7 +29,5 @@ const char * mutt_sb_get_highlight (void); void mutt_sb_notify_mailbox (BUFFY *b, int created); void mutt_sb_set_buffystats (const CONTEXT *ctx); BUFFY * mutt_sb_set_open_buffy (const char *path); -void mutt_sb_set_update_time (void); -int mutt_sb_should_refresh (void); #endif /* SIDEBAR_H */