* bug#13278: 24.3.50; Attributes aren't inherited in a copied face across frames
2012-12-31 0:16 ` Katsumi Yamaoka
@ 2012-12-31 3:14 ` Drew Adams
2012-12-31 4:03 ` Chong Yidong
1 sibling, 0 replies; 7+ messages in thread
From: Drew Adams @ 2012-12-31 3:14 UTC (permalink / raw)
To: 'Katsumi Yamaoka', 'Chong Yidong'; +Cc: 13278
>> May I ask why you are trying to use `copy-face' instead of `defface'?
May I ask why `copy-face' is now considered "mostly intended for internal
usage"? Why does it no longer result in a customizable face (according to the
doc)? And is that really true? In what way and by what scenarios?
> I've been using it conveniently since the face feature was introduced
> in Emacs. For example, it's handy when I want a face of which only
> the color differs from the built-in one:
>
> (copy-face 'bold 'orange-bold)
> (set-face-foreground 'orange-bold "Orange")
>
> Of course doing it by defface is not so troublesome, so I can live
> without copy-face.
>
> > As the docstring of `copy-face' indicates, it is mostly intended for
> > internal usage,
>
> Oh, I didn't notice the docstring having changed recently. I must
> close this thread. Thanks anyway.
>
> > and you are likely to screw up the face's customization
> > data if you call it directly. If you give more details about the
> > use-case, that would be good.
Too bad. `copy-face' was intended for users to use, before someone decided
otherwise and to deem it "mostly intended for internal usage". Internal use was
not what `copy-face' was "mostly intended for" originally.
The doc string is the same in Emacs 23, 22, 21, and 20, and no doubt prior too.
It invites users to use `copy-face'. And the only change I see for Emacs 24 is
that you added this:
This function does not copy face customization data, so NEW-FACE
will not be made customizable. Most Lisp code should not call
this function; use `defface' with :inherit instead.
That was NOT true before Emacs 24 - faces created by `copy-face' WERE
customizable. What did users gain by this change? Or was it just a net loss?
And why tell users to use :inherit here? That is something completely
different. A copy does not at all inherit from its source - that's the whole
idea of a copy, and the idea behind `copy-face'.
Searching for some explanation of this mystery change, I naturally looked in
NEWS. I don't find anything there about any change to `copy-face' behavior or
usage guidelines. Searching for `face' turns up nothing about this. Why isn't
this change documented?
FWIW, I have a fair amount of code that uses `copy-face'. Much of it is in
commands that first copy a face to serve as a backup before the command lets a
user change different attributes of the face incrementally. A user needs to be
able to undo all of the resulting changes, which is why such commands back up
the face to be modified, using `copy-face'.
I presume & hope that such code is not now broken. `copy-face' is still used in
the Emacs Lisp sources, so I'm guessing that a use such as this will still work.
I also do simple things like this, for my own use:
(copy-face 'secondary-selection 'query-replace)
In fact, I don't understand why the doc string says that the result is not
customizable - it sure seems to be in the cases I've tried. If you are going to
say things like that then please be specific: Just what about customization is
lost, and under what circumstances? What does not work wrt customization
anymore?
And why should "most Lisp code" not call `copy-face'? What kind of Lisp code
can reasonably call it? Please be specific about the problems or limitations.
Even "internal" Lisp programmers deserve to know what this is about.
This is Emacs, the "extensible, customizable, self-documenting real-time display
editor". It is not enough to say "don't use this - off limits". Please tell
users why, in detail: what happens if they do use it? Under what circumstances
does `copy-face' break face customizability? In what way is it broken?
This bug report points to one area where `copy-face' apparently no longer works
correctly. But that way doesn't seem to be about the new face not being
customizable.
It would be good for the doc to be clear about just what works and what doesn't,
especially since the breakage is apparently new. And of course the change
belongs in NEWS as well.
Do you want me to file a separate bug for this doc problem, or to reopen this
one until it is fixed?
^ permalink raw reply [flat|nested] 7+ messages in thread
* bug#13278: 24.3.50; Attributes aren't inherited in a copied face across frames
2012-12-31 0:16 ` Katsumi Yamaoka
2012-12-31 3:14 ` Drew Adams
@ 2012-12-31 4:03 ` Chong Yidong
1 sibling, 0 replies; 7+ messages in thread
From: Chong Yidong @ 2012-12-31 4:03 UTC (permalink / raw)
To: Katsumi Yamaoka; +Cc: 13278-done
Katsumi Yamaoka <yamaoka@jpl.org> writes:
>> May I ask why you are trying to use `copy-face' instead of `defface'?
>
> I've been using it conveniently since the face feature was introduced
> in Emacs. For example, it's handy when I want a face of which only
> the color differs from the built-in one:
>
> (copy-face 'bold 'orange-bold)
> (set-face-foreground 'orange-bold "Orange")
>
> Of course doing it by defface is not so troublesome, so I can live
> without copy-face.
Here's the basic issue: `copy-face' acts on internal faces (and always
has, IIRC). Internal faces are vectors of face attributes, which are
stored by Emacs in `face-new-frame-defaults' and in per-frame alists.
The key point is that the face spec, which is specified by `defface', is
separate from this. Since `defface' is used for practically all Emacs
faces, the internal faces stored in `face-new-frame-defaults' are
usually empty. The purpose of `face-new-frame-defaults' is to keep
track of the "overriding attributes", for when the user calls
`set-face-attribute', `set-face-foreground', etc.
What `copy-face' does is to create a new entry for the face copy in
`face-new-frame-defaults'; it doesn't touch the face spec (customization
data). When you create a new frame, Emacs combines
`face-new-frame-defaults' with the face spec from the face's
customization data. So a face created with `copy-face', lacking that
customization data, would have a blank appearance.
Note also that `face-new-frame-defaults' overrides the customization
data, so this mechanism inherently doesn't play well with Custom themes.
That's one reason the direct setting of internal faces is
downplayed/deprecated these days: it can lead to surprising effects for
people who don't know what they're doing.
Of course, we could make `copy-face' copy the customization data as
well, if that is more useful. But this would be a backward incompatible
change, and I would have to think about whether it would screw anything
up.
^ permalink raw reply [flat|nested] 7+ messages in thread