From a4398ac93d9dc4659a50876e158112d8d1feeca2 Mon Sep 17 00:00:00 2001 From: djcb Date: Sun, 12 Aug 2018 13:46:55 +0300 Subject: [PATCH] mu4e/mu: optimize mark-as-read Since cd649efb6be, 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. --- mu/mu-cmd-server.c | 48 +++++++++++++++++++++++++--------------------- mu4e/mu4e-proc.el | 19 ++++++++++-------- mu4e/mu4e-view.el | 5 +++-- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/mu/mu-cmd-server.c b/mu/mu-cmd-server.c index 3804bf64..be227e52 100644 --- a/mu/mu-cmd-server.c +++ b/mu/mu-cmd-server.c @@ -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); diff --git a/mu4e/mu4e-proc.el b/mu4e/mu4e-proc.el index 34534906..701deb4e 100644 --- a/mu4e/mu4e-proc.el +++ b/mu4e/mu4e-proc.el @@ -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 diff --git a/mu4e/mu4e-view.el b/mu4e/mu4e-view.el index a5f7f070..72f5492c 100644 --- a/mu4e/mu4e-view.el +++ b/mu4e/mu4e-view.el @@ -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))))