mu4e/mu: optimize mark-as-read

Since cd649efb6b, opening an unread message first does a proc-move,
then proc-view.

Reason is that while we get the (:update ... ) from the move, that only
contains a skeleton message; we need the full view get images etc. This
means that we render the message _twice_.

Here we change add a flag for move to _not_ send the (:update ..), so
only the (:view ...) will trigger rendering of the message.
This commit is contained in:
djcb 2018-08-12 13:46:55 +03:00
parent 6e646ea794
commit a4398ac93d
3 changed files with 40 additions and 32 deletions

View File

@ -1055,8 +1055,6 @@ get_checked_path (const char *path)
}
static MuError
index_and_maybe_cleanup (MuIndex *index, const char *path,
gboolean cleanup, gboolean lazy_check, GError **err)
@ -1174,7 +1172,7 @@ get_flags (const char *path, const char *flagstr)
static MuError
do_move (MuStore *store, unsigned docid, MuMsg *msg, const char *maildir,
MuFlags flags, gboolean new_name, GError **err)
MuFlags flags, gboolean new_name, gboolean no_update, GError **err)
{
unsigned rv;
gchar *sexp;
@ -1201,19 +1199,21 @@ do_move (MuStore *store, unsigned docid, MuMsg *msg, const char *maildir,
print_and_clear_g_error (err);
}
sexp = mu_msg_to_sexp (msg, docid, NULL, MU_MSG_OPTION_VERIFY);
/* note, the :move t thing is a hint to the frontend that it
* could remove the particular header */
print_expr ("(:update %s :move %s)", sexp,
different_mdir ? "t" : "nil");
g_free (sexp);
if (!no_update) {
sexp = mu_msg_to_sexp (msg, docid, NULL, MU_MSG_OPTION_VERIFY);
/* note, the :move t thing is a hint to the frontend that it
* could remove the particular header */
print_expr ("(:update %s :move %s)", sexp,
different_mdir ? "t" : "nil");
g_free (sexp);
}
return MU_OK;
}
static MuError
move_docid (MuStore *store, unsigned docid, const char* flagstr,
gboolean new_name, GError **err)
gboolean new_name, gboolean no_update, GError **err)
{
MuMsg *msg;
MuError rv;
@ -1234,7 +1234,8 @@ move_docid (MuStore *store, unsigned docid, const char* flagstr,
goto leave;
}
rv = do_move (store, docid, msg, NULL, flags, new_name, err);
rv = do_move (store, docid, msg, NULL, flags,
new_name, no_update, err);
leave:
if (msg)
@ -1256,12 +1257,13 @@ move_msgid_maybe (ServerContext *ctx, GHashTable *args, GError **err)
{
GSList *docids, *cur;
const char* maildir, *msgid, *flagstr;
gboolean new_name;
gboolean new_name, no_update;
maildir = get_string_from_args (args, "maildir", TRUE, err);
msgid = get_string_from_args (args, "msgid", TRUE, err);
flagstr = get_string_from_args (args, "flags", TRUE, err);
new_name = get_bool_from_args (args, "newname", TRUE, err);
maildir = get_string_from_args (args, "maildir", TRUE, err);
msgid = get_string_from_args (args, "msgid", TRUE, err);
flagstr = get_string_from_args (args, "flags", TRUE, err);
new_name = get_bool_from_args (args, "newname", TRUE, err);
no_update = get_bool_from_args (args, "noupdate", TRUE, err);
/* you cannot use 'maildir' for multiple messages at once */
if (!msgid || !flagstr || maildir)
@ -1275,7 +1277,7 @@ move_msgid_maybe (ServerContext *ctx, GHashTable *args, GError **err)
for (cur = docids; cur; cur = g_slist_next(cur))
if (move_docid (ctx->store, GPOINTER_TO_SIZE(cur->data),
flagstr, new_name, err) != MU_OK)
flagstr, new_name, no_update, err) != MU_OK)
break;
g_slist_free (docids);
@ -1301,16 +1303,17 @@ cmd_move (ServerContext *ctx, GHashTable *args, GError **err)
MuMsg *msg;
MuFlags flags;
const char *maildir, *flagstr;
gboolean new_name;
gboolean new_name, no_update;
/* check if the move is based on the message id; if so, handle
* it in move_msgid_maybe */
if (move_msgid_maybe (ctx, args, err))
return MU_OK;
maildir = get_string_from_args (args, "maildir", TRUE, err);
flagstr = get_string_from_args (args, "flags", TRUE, err);
new_name = get_bool_from_args (args, "newname", TRUE, err);
maildir = get_string_from_args (args, "maildir", TRUE, err);
flagstr = get_string_from_args (args, "flags", TRUE, err);
new_name = get_bool_from_args (args, "newname", TRUE, err);
no_update = get_bool_from_args (args, "noupdate", TRUE, err);
docid = determine_docid (ctx->query, args, err);
if (docid == MU_STORE_INVALID_DOCID ||
@ -1336,7 +1339,8 @@ cmd_move (ServerContext *ctx, GHashTable *args, GError **err)
goto leave;
}
if ((do_move (ctx->store, docid, msg, maildir, flags, new_name, err)
if ((do_move (ctx->store, docid, msg, maildir, flags,
new_name, no_update, err)
!= MU_OK))
print_and_clear_g_error (err);

View File

@ -348,7 +348,7 @@ or an error."
(if skip-dups "true" "false")
(if include-related "true" "false")))
(defun mu4e~proc-move (docid-or-msgid &optional maildir flags)
(defun mu4e~proc-move (docid-or-msgid &optional maildir flags no-update)
"Move message identified by DOCID-OR-MSGID to optional MAILDIR
and optionally setting FLAGS. If MAILDIR is nil, message will be
moved within the same maildir.
@ -374,12 +374,12 @@ The server reports the results for the operation through
`mu4e-update-func'.
If the variable `mu4e-change-filenames-when-moving' is
non-nil, moving to a different maildir generates new names for
non-nil, moving to a different maildir generates new names forq
the target files; this helps certain tools (such as mbsync).
The results are reported through either (:update ... )
or (:error ) sexp, which are handled my `mu4e-update-func' and
`mu4e-error-func', respectively."
Unless NO-UPDATE is non-nil, the results are reported through
either (:update ... ) or (:error ) sexp, which are handled my
`mu4e-update-func' and `mu4e-error-func', respectively."
(unless (or maildir flags)
(mu4e-error "At least one of maildir and flags must be specified"))
(unless (or (not maildir)
@ -396,9 +396,12 @@ or (:error ) sexp, which are handled my `mu4e-update-func' and
(rename
(if (and maildir mu4e-change-filenames-when-moving)
"true" "false")))
(mu4e~proc-send-command "cmd:move %s %s %s %s"
idparam (or flagstr "") (or path "")
(format "newname:%s" rename))))
(mu4e~proc-send-command "cmd:move %s %s %s %s %s"
idparam
(or flagstr "")
(or path "")
(format "newname:%s" rename)
(format "noupdate:%s" (if no-update "true" "false")))))
(defun mu4e~proc-index (path my-addresses cleanup lazy-check)
"Update the message database for filesystem PATH, which should

View File

@ -901,8 +901,9 @@ changes, it triggers a refresh."
;; is a new message
(when (and docid (or (member 'unread flags) (member 'new flags)))
;; mark /all/ messages with this message-id as read, so all copies of
;; this message will be marked as read.
(mu4e~proc-move msgid nil "+S-u-N")
;; this message will be marked as read. We don't want an update thougn,
;; we want a full message, so images etc. work correctly.
(mu4e~proc-move msgid nil "+S-u-N" 'noupdate)
(mu4e~proc-view docid mu4e-view-show-images (mu4e~decrypt-p msg))
t))))