Subject: bug#69784: 29.2; Proced auto update should only update visible buffers

From: Rahguzar <[email-masked]>
Date: Fri, 15 Mar 2024 18:52:53 +0100

Hi Eli,

Eli Zaretskii <[email-masked]> writes:

>> From: Rahguzar <[email-masked]>
>> Cc: [email-masked]
>> Date: Thu, 14 Mar 2024 09:54:46 +0100
>>
>> > As a user option, this sounds useful.  So please do send a patch, but
>> > please add such an option, because I can imagine users who'd like
>> > Proced buffers to be always up-to-date, regardless of whether they are
>> > displayed.
>> >
>> > Thanks.
>>
>> What about a special value 'visible' for proced-auto-update-flag instead
>> of a separate option?
>
> Yes, a good idea.
>
>> The only wrinkle might be how to set this value using
>> proced-toggle-auto-update.
>
> Make it cycle through the values?

The patch I have attached does this. I am not entirely satisfied with
with proced-toggle-auto-update so suggestions for improvement are welcome.

>> There is also the slight inconsistency that it makes
>> proced-auto-update-flag not a flag.
>
> Not a catastrophe, IMO.

Thanks,
Rahguzar

>From 0ddf3332cac4e780ae05735a91d98d52fb6fabc3 Mon Sep 17 00:00:00 2001
From: Rahguzar <[email-masked]>
Date: Fri, 15 Mar 2024 18:46:46 +0100
Subject: [PATCH] Allow for only auto updating visible proced buffers
 (bug#69784)

* lisp/proced.el
(proced-auto-update-flag): document 'visible' value and add
it to the custom type.
(proced-auto-update-timer, proced-toggle-auto-update):
take 'visible' value into account.
---
 lisp/proced.el | 46 +++++++++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 15 deletions(-)

diff --git a/lisp/proced.el b/lisp/proced.el
index 3435f1ab8cd..396bf4dc232 100644
--- a/lisp/proced.el
+++ b/lisp/proced.el
@@ -362,9 +362,13 @@ proced-auto-update-interval
   :type 'integer)
 
 (defcustom proced-auto-update-flag nil
-  "Non-nil for auto update of a Proced buffer.
-Can be changed interactively via `proced-toggle-auto-update'."
-  :type 'boolean)
+  "Non-nil means auto update proced buffers.
+Special value `visible' means only update proced buffers that are currently
+displayed in a window.  Can be changed interactively via
+`proced-toggle-auto-update'."
+  :type '(radio (const :tag "Don't auto update" nil)
+                (const :tag "Only update visible proced buffers" visible)
+                (const :tag "Update all proced buffers" t)))
 (make-variable-buffer-local 'proced-auto-update-flag)
 
 (defcustom proced-tree-flag nil
@@ -951,28 +955,40 @@ proced-auto-update-timer
   "Auto-update Proced buffers using `run-at-time'.
 
 If there are no proced buffers, cancel the timer."
-  (unless (seq-filter (lambda (buf)
-                        (with-current-buffer buf
-                          (when (eq major-mode 'proced-mode)
-                            (if proced-auto-update-flag
-                                (proced-update t t))
-                            t)))
-                      (buffer-list))
+  (if-let (buffers (match-buffers '(derived-mode . proced-mode)))
+      (dolist (buf buffers)
+        (when-let ((flag (buffer-local-value 'proced-auto-update-flag buf))
+                   ((or (not (eq flag 'visible))
+                        (get-buffer-window buf 'visible))))
+          (with-current-buffer buf
+            (proced-update t t))))
     (cancel-timer proced-auto-update-timer)
     (setq proced-auto-update-timer nil)))
 
 (defun proced-toggle-auto-update (arg)
   "Change whether this Proced buffer is updated automatically.
 With prefix ARG, update this buffer automatically if ARG is positive,
-otherwise do not update.  Sets the variable `proced-auto-update-flag'.
-The time interval for updates is specified via `proced-auto-update-interval'."
+update the buffer only when the buffer is displayed in a window if ARG is 0,
+otherwise do not update.  Sets the variable `proced-auto-update-flag' by
+cycling between nil, `visible' and t.  The time interval for updates is
+specified via `proced-auto-update-interval'."
   (interactive (list (or current-prefix-arg 'toggle)) proced-mode)
   (setq proced-auto-update-flag
-        (cond ((eq arg 'toggle) (not proced-auto-update-flag))
-              (arg (> (prefix-numeric-value arg) 0))
+        (cond ((eq arg 'toggle)
+               (cond ((not proced-auto-update-flag) 'visible)
+                     ((eq proced-auto-update-flag 'visible) t)
+                     (t nil)))
+              (arg
+               (setq arg (prefix-numeric-value arg))
+               (message "%s" arg)
+               (cond ((> arg 0) t)
+                     ((eq arg 0) 'visible)
+                     (t nil)))
               (t (not proced-auto-update-flag))))
   (message "Proced auto update %s"
-           (if proced-auto-update-flag "enabled" "disabled")))
+           (cond ((eq proced-auto-update-flag 'visible) "enabled (only when buffer is visible)")
+                 (proced-auto-update-flag "enabled (unconditionally)")
+                 (t "disabled"))))
 
 ;;; Mark
 
-- 
2.44.0