Subject: [PATCH] Preserve Window Position with Proced
From: Laurence Warne <[email-masked]>
To: [email-masked]
Date: Wed, 28 Dec 2022 15:55:20 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi,

This patch fixes a minor issue with proced buffers.  Previously, the window
position would be set to the start of the buffer when a proced buffer was
updated and it was not displayed in the selected window.  To reproduce:

(require 'proced)
(setq-default proceed-auto-update-flag t)
(M-x proced)

Move down to the next process, then change to a different window, and wait
a bit.  You should see the point in the proced buffer move back to the
beginning of the buffer. A similar issue occurs when the proced buffer is
not displayed in any window.

This patch addresses this by setting the window point (if applicable)
whenever a proced buffer is updated, and the second issue by not updating a
proced buffer if it is not displayed in any window.

I tried to add a test for this, but for example this:

(ert-deftest proced-update-preserves-point-test ()
  (proced--within-buffer
   'medium
   'user
   (proced--move-to-column "PID")
   (let ((point (window-point))
         (window (split-window)))
     (select-window window)
     (bury-buffer)
     (with-current-buffer "*Proced*"
       (proced-update t t))
     (switch-to-buffer "*Proced*")
     (should (= point (window-point))))))

passes even without this patch (though if I step through it with
edebug-defun it fails as expected).

Thanks, Laurence
From 90bf6675bdf50a0fd3392b7ac4acc56e1e6436c4 Mon Sep 17 00:00:00 2001
From: Laurence Warne <[email-masked]>
Date: Thu, 22 Dec 2022 17:16:08 +0000
Subject: [PATCH] Preserve the window position with proced

Preserve the window position for windows which display a proced buffer,
but are not the selected window when a proced buffer is updated.  Previously,
the window position would be set to the start of the buffer when a
proced buffer was updated and it was not displayed in the selected window.

* lisp/proced.el (proced-auto-update-timer): Only update a given
proced buffer if it is displayed in a window.
(proced-update): Set the window position if the proced buffer is
displayed in a window.
---
 lisp/proced.el | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lisp/proced.el b/lisp/proced.el
index c09ee18a8b..102171bef0 100644
--- a/lisp/proced.el
+++ b/lisp/proced.el
@@ -905,7 +905,8 @@ proced-auto-update-timer
   (unless (seq-filter (lambda (buf)
                         (with-current-buffer buf
                           (when (eq major-mode 'proced-mode)
-                            (if proced-auto-update-flag
+                            (if (and proced-auto-update-flag
+                                     (get-buffer-window buf t))
                                 (proced-update t t))
                             t)))
                       (buffer-list))
@@ -1986,7 +1987,13 @@ proced-update
     ;; done
     (or quiet (input-pending-p)
         (message (if revert "Updating process information...done."
-                   "Updating process display...done.")))))
+                   "Updating process display...done."))))
+  ;; This sets the window point for all windows displaying the Proced buffer
+  ;; which means all windows will have their point set to the most recently
+  ;; visited window displaying the buffer.  Possibly we could save all window
+  ;; points ahead of time, though this is more complicated.
+  (mapc (lambda (win) (set-window-point win (point)))
+        (get-buffer-window-list (current-buffer))))
 
 (defun proced-revert (&rest _args)
   "Reevaluate the process listing based on the currently running processes.
-- 
2.30.2