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

View File

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

View File

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