Subject: bug#16434: bug#16694: bugs #16694/#16378: Patches

From: Eli Zaretskii <[email-masked]>
Date: Wed, 23 Apr 2014 18:51:37 +0300

> Date: Sat, 12 Apr 2014 16:57:46 +0200
> From: Matthias Dahl <[email-masked]>
> Cc: [email-masked], [email-masked], [email-masked],
>  [email-masked], [email-masked],
>  [email-masked]
> 
> Hello Eli...
> 
> > Done.
> 
> Thanks.

I'm sorry, but now I see that the fix of this bug caused an adverse
side effect: face attributes that are defined in the X resources are
now overridden by the face defaults.  At least that's what happens on
MS-Windows, where we simulate the X resources in w32reg.c.

Specifically, in Emacs 24.3, the tool bar has its foreground and
background colors set to SystemButtonText and SystemButtonFace,
accordingly, as specified in SYSTEM_DEFAULT_RESOURCES defined by
w32reg.c.  By contrast, in the current pretest, this face has the
default foreground and background colors defined by faces.el:

  (defface tool-bar
    '((default
       :box (:line-width 1 :style released-button)
       :foreground "black")  <<<<<<<<<<<<<<<<<<<<<<<<<<
      (((type x w32 ns) (class color))
       :background "grey75") <<<<<<<<<<<<<<<<<<<<<<<<<<

This is clearly seen if one tries to customize this face in an Emacs
that was started without -Q.

I looked at the code, and it seems that the problem is in
face-spec-recalc, and the doc string explicitly says that it is the
intended behavior:

  (defun face-spec-recalc (face frame)
    "Reset the face attributes of FACE on FRAME according to its specs.
  After the reset, the specs are applied from the following sources in this order:
    X resources (if applicable)
     |
    (theme and user customization)
      or, if nonexistent or does not match the current frame,
    (defface default spec)
     |
    defface override spec"

The code indeed follows the doc string: it first resets the face, then
applies the X resources, and then applies either the theme or the
default face spec:

    (face-spec-reset-face face frame)
    (make-face-x-resource-internal face frame)
    ;; If FACE is customized or themed, set the custom spec from
    ;; `theme-face' records.
    (let ((theme-faces (get face 'theme-face))
	  (no-match-found 0)
	  spec theme-face-applied)
      (if theme-faces
	  (dolist (elt (reverse theme-faces))
	    (setq spec (face-spec-choose (cadr elt) frame no-match-found))
	    (unless (eq spec no-match-found)
	      (face-spec-set-2 face frame spec)
	      (setq theme-face-applied t))))
      ;; If there was a spec applicable to FRAME, that overrides the
      ;; defface spec entirely (rather than inheriting from it).  If
      ;; there was no spec applicable to FRAME, apply the defface spec.
      (unless theme-face-applied
	(setq spec (face-spec-choose (face-default-spec face) frame))
	(face-spec-set-2 face frame spec))
      (setq spec (face-spec-choose (get face 'face-override-spec) frame))
      (face-spec-set-2 face frame spec)))

What happens on Windows is that make-face-x-resource-internal indeed
picks up the colors specified bu w32reg.c, but then face-spec-set-2
resets the colors to what the defface spec says.

Can you or someone else see if setting the colors of the tool-bar face
in the X resources on Unix is similarly overridden?

I don't understand this logic: resources are a kind of customization,
so they should override the default face spec, not the other way
around.  Am I missing something?

This change was done because --reverse-video didn't work, but what
does --reverse-video have to do with X resources and their priority in
determining the face attributes?

Thanks.