Subject: Re: bug#73768: 'read-passwd-mode' can clobber user defined mode lines

From: Michael Albinus <[email-masked]>
Date: Fri, 18 Oct 2024 13:02:59 +0200

Michael Albinus <[email-masked]> writes:

Hi Martin,

>> One minor problem exists when using a stand-alone minibuffer frame.
>> Clicking the icons never works because they appear on another frame and
>> when you move the mouse there
>>
>>   (when (minibufferp)
>>
>> fails.  Basically, clicks work now iff the minibuffer window is selected
>> and not if the minibuffer window is active as previously.
>
> I've seen, yes. I have no solution now.

I've modified the patch, this case seems to be covered now.

> There are further problems like
>
> emacs -Q --eval '(read-passwd "PWD: ")'
> i n p u t TAB
> M-: x x x
>
> The inner minibuffer, showing "xxx", toggles its visibility when
> clicking the password icon. I've extended the patch to check for
> read-passwd-mode in local-minor-modes.

This fix is also included in the patch.

Could you pls check whether you see further annoyances? Otherwise, if
you give me a go, I'll push to emacs-30.

>> martin

Best regards, Michael.

diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index 90b58f560c0..557d360bc6a 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -2467,14 +2467,11 @@ read-passwd--hide-password-icon
   :version "30.1"
   :help-echo "mouse-1: Toggle password visibility")

-(defvar read-passwd--mode-line-buffer nil
-  "Buffer to modify `mode-line-format' for showing/hiding passwords.")
-
 (defvar read-passwd--mode-line-icon nil
   "Propertized mode line icon for showing/hiding passwords.")

 (defvar read-passwd--hide-password t
-  "Toggle whether password should be hidden in minubuffer.")
+  "Toggle whether password should be hidden in minibuffer.")

 (defun read-passwd--hide-password ()
   "Make password in minibuffer hidden or visible."
@@ -2497,8 +2494,8 @@ read-passwd-toggle-visibility
     ;; FIXME: In case of a recursive minibuffer, this may select the wrong
     ;; mini-buffer.
     (with-current-buffer (window-buffer win)
-      (setq read-passwd--hide-password (not read-passwd--hide-password))
-      (with-current-buffer read-passwd--mode-line-buffer
+      (when (memq 'read-passwd-mode local-minor-modes)
+        (setq read-passwd--hide-password (not read-passwd--hide-password))
         (setq read-passwd--mode-line-icon
               `(:propertize
                 ,(if icon-preference
@@ -2514,8 +2511,8 @@ read-passwd-toggle-visibility
                      (define-key map [mode-line mouse-1]
                                  #'read-passwd-toggle-visibility)
                      map))))
-        (force-mode-line-update))
-      (read-passwd--hide-password))))
+        (force-mode-line-update 'all)
+        (read-passwd--hide-password)))))

 (defvar read-passwd-map
   ;; BEWARE: `defconst' would purecopy it, breaking the sharing with
@@ -2534,25 +2531,18 @@ read-passwd-mode
   :keymap read-passwd-map
   :version "30.1"

-  (setq read-passwd--hide-password nil
-        ;; Stolen from `eldoc-minibuffer-message'.
-        read-passwd--mode-line-buffer
-        (window-buffer
-         (or (window-in-direction 'above (minibuffer-window))
-	     (minibuffer-selected-window)
-	     (get-largest-window))))
+  (setq read-passwd--hide-password nil)
+  (or global-mode-string (setq global-mode-string '("")))

-  (if read-passwd-mode
-      (with-current-buffer read-passwd--mode-line-buffer
+  (let ((mode-string '(:eval read-passwd--mode-line-icon)))
+    (if read-passwd-mode
         ;; Add `read-passwd--mode-line-icon'.
-        (when (listp mode-line-format)
-          (setq mode-line-format
-                (cons '(:eval read-passwd--mode-line-icon)
-	              mode-line-format))))
-    (with-current-buffer read-passwd--mode-line-buffer
+        (or (member mode-string global-mode-string)
+            (setq global-mode-string
+	          (append global-mode-string (list mode-string))))
       ;; Remove `read-passwd--mode-line-icon'.
-      (when (listp mode-line-format)
-        (setq mode-line-format (cdr mode-line-format)))))
+      (setq global-mode-string
+	    (delete mode-string global-mode-string))))

   (when read-passwd-mode
     (read-passwd-toggle-visibility)))