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

From: Michael Albinus <[email-masked]>
Date: Sun, 13 Oct 2024 16:19:13 +0200

martin rudalics <[email-masked]> writes:

Hi Martin,

> When in my Emacs with a stand alone minibuffer frame I create a shell
> buffer and there do ssh-add, the following happens:
>
> In the lines below 'wid' stands for the window in direction (nil in the
> rows below because a stand alone minibuffer frame has no window above),
> 'msw' the minibuffer selected window, 'glw' the largest window (nil in
> the first row below because a stand alone minibuffer frame has no
> largest window) and 'sw' the selected window.  'add' and 'remove' stand
> for adding and removing the icon. 'before' and 'after' stand for whether
> we are before or after doing that.  These are followed by the value of
> 'read-passwd--mode-line-buffer' and the first two elements of that
> buffer's mode line string.
>
> wid .. nil .. msw .. #<window 11 on *shell*> .. glw .. nil .. sw .. #<window 8 on  *Minibuf-1*>
> add before .. *shell* .. %e .. mode-line-version
> add after .. *shell* .. (:eval read-passwd--mode-line-icon) .. %e
> wid .. nil .. msw .. nil .. glw .. #<window 6 on .emacs> .. sw .. #<window 11 on *shell*>
> remove before .. .emacs .. %e .. mode-line-version
> remove after .. .emacs .. mode-line-version ..
>
> So the window chosen for adding the icon is the value of calling
> 'minibuffer-selected-window' and everything is OK ('mode-line-version'
> is a private variable of mine, ignore it).  The icon's buffer is *shell*
> and the icon appears correctly.
>
> But when the icon shall be removed, 'minibuffer-selected-window' returns
> nil and the largest window is chosen instead which now happens to show
> my init file .emacs.  ‘read-passwd’ leaves the icon in *shell* and kills
> the mode line of my .emacs file.
>
> The crucial fact is that the selected window changes from the minibuffer
> window to the *shell* window because 'minibuffer-selected-window' is
> specified as
>
>   if (minibuf_level > 0
>       && MINI_WINDOW_P (XWINDOW (selected_window))
>       && WINDOW_LIVE_P (minibuf_selected_window))
>     return minibuf_selected_window;
>
> and *shell* is not a mini window.  So 'minibuffer-selected-window'
> returns nil in the scenario at hand and the largest window of the
> selected window's frame is chosen.  And the selected window obviously
> changes because 'read-string' (and in further consequence read_minibuf)
> restores the window selected before the minibuffer window was selected.
>
> Concludingly, the current version works when 'window-in-direction'
> returns a suitable window and may fail miserably otherwise.

I tried to reproduce your recipe, but I couldn't. Likely, I have a too
simple minded use of different Emacs windows. And a not customized mode
line. Note, that I'm not familiar with the windows machinery in Emacs at
all.

> The attached patch fixes the problem here.  But I still think that the
> icon should appear in the prompt of 'read-passwd' itself.

Please install your patch (you might ask Eli whether it is good for the
emacs-30 branch). And as I said in the other message, the mode line is
the place to give information about the active buffer, including the minibuffer.

Thanks a lot for investigating it!

> martin

Best regards, Michael.