Subject: Re: bug#911: 23.0.60; custom-set-faces causes "New Frame" to fail

From: Chong Yidong <[email-masked]>
Date: Wed, 24 Sep 2008 16:25:39 -0400

> When creating a new frame `frame-set-background-mode' gets called
> which eventually calls `face-spec-recalc'...  which calls
> `face-spec-set-2' two times for the default face background, one time
> for #ffffff and one time for DarkSlateGray.  `face-spec-set-2' calls
> `set-face-attribute', which calls `internal-set-lisp-face-attribute'
> which calls Fmodify_frame_parameters which calls
> `frame-set-background-mode' again.

The Emacs face code strikes again, huh.

> (>= (apply '+ (color-values "DarkSlateGrey"))
>     (* (apply '+ (color-values "white")) .6))
>
> evaluates to nil while
>
> (>= (apply '+ (color-values "#ffffff"))
>     (* (apply '+ (color-values "white")) .6))
>
> evaluates to t.  This means that `bg-mode' never equals `old-bg-mode'
> but continuously alternates between 'light and 'dark, so
> `frame-set-background-mode' will call `face-spec-recalc' thus sending
> Emacs into a nasty loop.
>
> Note that the looping behavior is due to the second call in the dolist
> (that for DarkSlateGrey).  The first call (for #ffffff) terminates.
>
> I'm not sure how to fix this because that looping has no specific entry
> point.

How about defining a variable `frame-set-background-mode-bg-mode'?  If
it's nil, frame-set-background-mode uses the existing calculation to
determine whether it's light or dark; if it's non-nil, it uses that
existing value.  This should prevent the oscillation.