Subject: RE: bug#52877: [External] : Re: bug#52877: 27.2; Let `use-dialog-box' apply to more than just yes/no questions

From: Drew Adams <[email-masked]>
Date: Sun, 16 Jan 2022 22:13:35 +0000

> > > So it uses a graphical chooser by default, 
> > > no matter whether use-dialog-box is set or not.
> >
> > Exactly.  That's exactly the limitation this
> > enhancement request asks to remove.  Let _users_
> > control whether it uses a graphical chooser
> > or not - exactly what `use-dialog-box' is for.
> >
> > The limitation is that `use-dialog-box' currently
> > is usable only with `yes-or-no' questions.
> 
> We don't provide any non-dialog way of selecting fonts because no one
> has written code to do that.  The dialog we show uses OS APIs, and the
> implementation, beyond popping up the dialog and using the value it
> returns, is not in Emacs.
> 
> So we simply cannot offer the users control of this, since we don't
> have code to find the available fonts relevant to Emacs and display
> them grouped by family, typeface, size, etc., in a useful way.  We use
> the system-provided dialogs instead.
> 
> IOW, this is not a bug.

Let me try again to be clear.

1. This is an enhancement request, NOT a bug report.

2. This is a general request, to do what's suggested
   for at least some commands that prompt for input
   other than yes/no or y/n:

   When the system provides a dialog box for choosing
   the input, let the command test `use-dialog-box',
   and use that dialog box when that var is non-nil,
   but use minibuffer input otherwise.

   Do this when it makes sense for a given command.
   If it truly makes no sense for some particular
   command - e.g., there's no way to get the required
   input except by using a dialog box - then don't
   try to do it for that command.

3. As an _illustration_, and as a possible starting
   point, do this for `menu-set-font' (which could,
   but need not, be renamed to remove "menu").

This code does that.  It uses the current code for
that command only when `use-dialog-box' is non-nil.
It instead uses the minibuffer with completion when
the option is nil.

(defun menu-set-font ()
  "Interactively select a font and make it the default on all frames.
The selected font will be the default on both the existing and future frames."
  (interactive)
  (if use-dialog-box
      (set-frame-font (if (fboundp 'x-select-font)
			  (x-select-font)
			(mouse-select-font))
		      nil t)
    (call-interactively #'set-frame-font-all)))

(defun set-frame-font-all (font)
  "Set the default font to FONT on all existing and future frames.
\(This is `set-frame-font' with `t' as argument FRAMES.)"
  (interactive
   (let* ((completion-ignore-case t)
          (font (completing-read
		 "Font name: "
                 (x-list-fonts "*" nil (selected-frame))
                 nil nil nil nil
                 (frame-parameter nil 'font))))
     (list font)))
  (set-frame-font font nil t))

AFAICT, at least on MS Windows, it just works.  But if
you feel it doesn't work as you'd prefer, feel free to
use other code.

As for whether the simple code I suggested here for
`set-frame-font-all' provides _exactly_ what the use
of the dialog box provides (you mention grouping fonts
"by family, typeface, size, etc., in a useful way"):
that's not very relevant - not definitively limiting.
The doc of the command can make clear what the behavior
is in each case, if they differ: graphic input vs
minibuffer input.

In any case, the point is not this particular code.

The point is not even, more generally, to fix
`menu-set-font' to make it usable also with nil
`use-dialog-box' (using the minibuffer in that case).

The point is more general than `menu-set-font'.  The
point is that there's no good reason to limit the
use of `use-dialog-box' to yes-no questions.

But if you think there is such a reason, which
precludes _any_ use, for _any_ non-yes-or-no command,
to use `use-dialog-box, then please state the reason.

Users should be able to make at least some commands,
which today _always_ use a dialog box, respect
`use-dialog-box', so that if nil they prompt and
accept minibuffer input.