Subject: RE: bug#17532: 24.4.50; Options > `set-frame-font' does not work as documented

From: Drew Adams <[email-masked]>
Date: Wed, 21 May 2014 11:03:44 -0700 (PDT)

> > > But that doesn't cover future frames, either.  It only affects the
> > > existing GUI frames, per the doc string (and the code, which see).
> >                        ^^^^^^^^^^^^^^^^^^
> >
> > Where are you getting this?  `C-h f set-frame-font' says clearly:
> >
> >    Also, if FRAME is non-nil, alter the user's Customization settings as
> >    though the font-related attributes of the `default' face had been
> >    "set in this session", so that the font is applied to future frames.
> >
> > One of us seems to be sorely missing something. ;-)
> 
> You are missing the previous sentence of the doc string.

No, I was not missing that previous sentence: 

  "If FRAMES is non-nil, it should be a list of frames to act upon,
  or t meaning all graphical frames."

Where does it say that only existing frames should be affected?
It says that `t' means that it affects all graphical frames.  Nothing
limits that to the existing ones.  "All men are created equal" does
not refer only to the men that existed at the time that sentence
was coined.

> I have now made it say clearly that only the existing frames are
> affected.

Too bad.  Anyway I give up.

> > A face, including face `default', is not something that is frame-specific.
> 
> Faces are _always_ frame-specific in Emacs.  That includes the
> 'default' face.  Thus, changing the 'default' face does not imply the
> change affects all frames, let alone future frames.

That's not my understanding.  And if that were the case then it would
be reflected in the doc.  Node (emacs) `Faces' tells you what a face is, 
and it says NOTHING about it being frame-dependent.  Likewise node `Face Attributes', which tells you what a face is in detail, says nothing about
a face definition being frame-dependent.  Likewise node `Defining Faces'.

And in functions etc.  Function `facep' would then require a second arg
FRAME or would implicitly tell you only that the object was a face for,
say, the selected frame.  

And customizing a face (including `default') would affect only a
particular frame.  And `defface' would provide for specifying the
frame(s) to which that particular face applies.

A face is defined independently of any place it might be displayed,
including any frame.

A face _attribute_ can have different values for a given face on
different frames.  That does not mean that the face itself is
different.  And this overriding of a face's default attribute values
is just that: exceptional.  As the doc says:

  Normally, Emacs uses the face specs of each face to automatically
  calculate its attributes on each frame (*note Defining Faces::).  The
  function `set-face-attribute' can override this calculation by directly
  assigning attributes to a face, either on a specific frame or for all
  frames.  This function is mostly intended for internal usage.

A face's default attributes are what apply to newly created frames.
Changing the default font of a face, in particular, should affect new
frames.  And particularly for face `default'.

What's more, the doc says clearly that a `t' value for `set-face-attribute'
parameter FRAME " sets the attributes for all existing frames, as well
as for newly created frames."  Existing and new go together here, and
the same doc says clearly that they go together the same way for all
of the related `set-face-*' functions - including `set-face-font':

  The following commands and functions mostly provide compatibility
  with old versions of Emacs.  They work by calling `set-face-attribute'.
  Values of `t' and `nil' for their FRAME argument are handled just like
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  `set-face-attribute' and `face-attribute'.  The commands read their
  ^^^^^^^^^^^^^^^^^^^^
  arguments using the minibuffer, if called interactively.

Why you would think that `set-face-font' should not do like this doc
says and should be an exception to the rule that `t' affects newly
created frames as well as existing frames, is beyond me.

And even all of the functions that examine face attributes act similarly.
In fact, it is ONLY the new-frame behavior of `t' that is kept in this
case.  The (same) doc says:

  The following functions examine the attributes of a face.  They
  mostly provide compatibility with old versions of Emacs.  If you don't
  specify FRAME, they refer to the selected frame; `t' refers to the
                                                   ^^^^^^^^^^^^^^^^^
  default data for new frames.
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

And yes, this includes function `face-font': FRAME = `t' means the
default value, which is what affects new frames.

> The very next bullet is about a different method of changing the font,
> so it's not really relevant to what this first bullet describes.

A different method of doing the same thing: changing the font for
new frames!  ALL of the bullets here describe ways of doing that.

> Anyway, I made the changes that clarify the current behavior.  The
> part that seems to say that Customize settings are changed to affect
> the font change on all future frames does not correspond to what
> actually happens.  This could be a code bug or a documentation bug;
> someone who can decipher the Customize-related code in set-frame-font
> will have to look into this, and fix either the doc string or the code
> as appropriate.  For now, I left that part of the doc string
> unaltered.

Anyway, I give up.  I did my part in filing the bug and in trying to
explain what I think the bug is: the doc is pretty much right in
suggesting that new frames are also affected; the product is wrong in
not respecting that.