From d7b0001f9650d371040be81abf534b0d4813776f Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Thu, 2 Apr 2026 01:01:26 +0300 Subject: [PATCH] mu4e-draft/headers: resync headers-buf After restoring the window configuration, we could end up pointing at the wrong message. Let's try harder to restore... issue #2902. --- mu4e/mu4e-draft.el | 26 +++++++++++++++++++++++++- mu4e/mu4e-headers.el | 17 +++++------------ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/mu4e/mu4e-draft.el b/mu4e/mu4e-draft.el index fdcfd2a6..547a592e 100644 --- a/mu4e/mu4e-draft.el +++ b/mu4e/mu4e-draft.el @@ -688,7 +688,31 @@ See `set-window-configuration' for further details." (when mu4e--before-draft-window-config ;;(message "RESTORE to %s" mu4e--before-draft-window-config) (set-window-configuration mu4e--before-draft-window-config) - (setq mu4e--before-draft-window-config nil))) + (setq mu4e--before-draft-window-config nil) + ;; After restoring the window configuration, the headers cursor position + ;; may be stale (the headers buffer can change during compose due to + ;; re-indexing or flag updates). Re-sync with the view message. #2902. + (mu4e--compose-post-sync-headers))) + +(declare-function mu4e-get-view-buffer "mu4e-window") +(declare-function mu4e~headers-goto-docid "mu4e-headers") +(declare-function mu4e~headers-highlight "mu4e-headers") + +(defun mu4e--compose-post-sync-headers () + "Sync the headers buffer cursor with the current view message. +After restoring the window configuration, the headers cursor may +point to the wrong message. Navigate to the message that the +view buffer is showing, if any." + (when-let* ((view-buf (mu4e-get-view-buffer)) + (msg (with-current-buffer view-buf + (and (derived-mode-p 'mu4e-view-mode) + (bound-and-true-p mu4e--view-message)))) + (docid (plist-get msg :docid)) + (headers-buf (mu4e-get-headers-buffer))) + (when (buffer-live-p headers-buf) + (with-current-buffer headers-buf + (when (mu4e~headers-goto-docid docid) + (mu4e~headers-highlight docid)))))) (defvar mu4e--draft-activation-frame nil "Frame from which composition was activated. diff --git a/mu4e/mu4e-headers.el b/mu4e/mu4e-headers.el index 408b1206..898d87bc 100644 --- a/mu4e/mu4e-headers.el +++ b/mu4e/mu4e-headers.el @@ -912,18 +912,11 @@ If we're in the message view, temporarily switch." (with-current-buffer buffer (mu4e-thread-unfold-all) (if (or (mu4e~headers-goto-docid docid) - ;; TODO: Is this the best way to find another - ;; relevant docid for a view buffer? - ;; - ;; If you attach a view buffer to another headers - ;; buffer that does not contain the current docid - ;; then `mu4e~headers-goto-docid' returns nil and we - ;; get an error. This "hack" instead gets its - ;; now-changed headers buffer's current message as a - ;; docid - (mu4e~headers-goto-docid - (with-current-buffer buffer - (mu4e-message-field (mu4e-message-at-point) :docid)))) + ;; Docid lookup can fail when the headers buffer was + ;; refreshed (e.g., re-indexing during compose). Fall + ;; back to the stable message-id. #2902. + (mu4e-headers-goto-message-id + (mu4e-message-field msg :message-id))) (progn ,@body) (mu4e-error "Cannot find message in headers buffer")))))))