summaryrefslogtreecommitdiff
path: root/lisp/frame.el
diff options
context:
space:
mode:
authorChong Yidong <cyd@stupidchicken.com>2011-07-03 18:16:07 -0400
committerChong Yidong <cyd@stupidchicken.com>2011-07-03 18:16:07 -0400
commit1485f4c03a3e887f8e60fefb96e5e3d9ca484cf7 (patch)
tree07c3889b6d224dbf2c2fcc647580c2ff548e56dd /lisp/frame.el
parent9fa3dd45482a9fa8084fae495b3a857a216decf2 (diff)
downloademacs-1485f4c03a3e887f8e60fefb96e5e3d9ca484cf7.tar.gz
emacs-1485f4c03a3e887f8e60fefb96e5e3d9ca484cf7.tar.bz2
emacs-1485f4c03a3e887f8e60fefb96e5e3d9ca484cf7.zip
Fix how custom themes handle faces, so the multi-tty/multi-frame case works.
* lisp/custom.el (custom-push-theme): Don't record faces in `changed' theme; this doesn't work correctly for per-frame face settings. (disable-theme): Use face-set-after-frame-default to reset faces. (custom--frame-color-default): New function. * lisp/frame.el (frame-background-mode, frame-set-background-mode): Moved from faces.el. (frame-default-terminal-background): New function. * src/xfaces.c (Finternal_merge_in_global_face): Modify the foreground and background color parameters if they have been changed.
Diffstat (limited to 'lisp/frame.el')
-rw-r--r--lisp/frame.el110
1 files changed, 110 insertions, 0 deletions
diff --git a/lisp/frame.el b/lisp/frame.el
index 3ceec2657e7..d6f82750347 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -847,6 +847,116 @@ If there is no frame by that name, signal an error."
(if frame
(select-frame-set-input-focus frame)
(error "There is no frame named `%s'" name))))
+
+
+;;;; Background mode.
+
+(defcustom frame-background-mode nil
+ "The brightness of the background.
+Set this to the symbol `dark' if your background color is dark,
+`light' if your background is light, or nil (automatic by default)
+if you want Emacs to examine the brightness for you. Don't set this
+variable with `setq'; this won't have the expected effect."
+ :group 'faces
+ :set #'(lambda (var value)
+ (set-default var value)
+ (mapc 'frame-set-background-mode (frame-list)))
+ :initialize 'custom-initialize-changed
+ :type '(choice (const dark)
+ (const light)
+ (const :tag "automatic" nil)))
+
+(declare-function x-get-resource "frame.c"
+ (attribute class &optional component subclass))
+
+(defvar inhibit-frame-set-background-mode nil)
+
+(defun frame-set-background-mode (frame &optional keep-face-specs)
+ "Set up display-dependent faces on FRAME.
+Display-dependent faces are those which have different definitions
+according to the `background-mode' and `display-type' frame parameters.
+
+If optional arg KEEP-FACE-SPECS is non-nil, don't recalculate
+face specs for the new background mode."
+ (unless inhibit-frame-set-background-mode
+ (let* ((frame-default-bg-mode (frame-terminal-default-bg-mode frame))
+ (bg-color (frame-parameter frame 'background-color))
+ (tty-type (tty-type frame))
+ (default-bg-mode
+ (if (or (window-system frame)
+ (and tty-type
+ (string-match "^\\(xterm\\|\\rxvt\\|dtterm\\|eterm\\)"
+ tty-type)))
+ 'light
+ 'dark))
+ (non-default-bg-mode (if (eq default-bg-mode 'light) 'dark 'light))
+ (bg-mode
+ (cond (frame-default-bg-mode)
+ ((equal bg-color "unspecified-fg") ; inverted colors
+ non-default-bg-mode)
+ ((not (color-values bg-color frame))
+ default-bg-mode)
+ ((>= (apply '+ (color-values bg-color frame))
+ ;; Just looking at the screen, colors whose
+ ;; values add up to .6 of the white total
+ ;; still look dark to me.
+ (* (apply '+ (color-values "white" frame)) .6))
+ 'light)
+ (t 'dark)))
+ (display-type
+ (cond ((null (window-system frame))
+ (if (tty-display-color-p frame) 'color 'mono))
+ ((display-color-p frame)
+ 'color)
+ ((x-display-grayscale-p frame)
+ 'grayscale)
+ (t 'mono)))
+ (old-bg-mode
+ (frame-parameter frame 'background-mode))
+ (old-display-type
+ (frame-parameter frame 'display-type)))
+
+ (unless (and (eq bg-mode old-bg-mode) (eq display-type old-display-type))
+ (let ((locally-modified-faces nil)
+ ;; Prevent face-spec-recalc from calling this function
+ ;; again, resulting in a loop (bug#911).
+ (inhibit-frame-set-background-mode t)
+ (params (list (cons 'background-mode bg-mode)
+ (cons 'display-type display-type))))
+ (if keep-face-specs
+ (modify-frame-parameters frame params)
+ ;; If we are recomputing face specs, first collect a list
+ ;; of faces that don't match their face-specs. These are
+ ;; the faces modified on FRAME, and we avoid changing them
+ ;; below. Use a negative list to avoid consing (we assume
+ ;; most faces are unmodified).
+ (dolist (face (face-list))
+ (and (not (get face 'face-override-spec))
+ (not (face-spec-match-p face
+ (face-user-default-spec face)
+ (selected-frame)))
+ (push face locally-modified-faces)))
+ ;; Now change to the new frame parameters
+ (modify-frame-parameters frame params)
+ ;; For all unmodified named faces, choose face specs
+ ;; matching the new frame parameters.
+ (dolist (face (face-list))
+ (unless (memq face locally-modified-faces)
+ (face-spec-recalc face frame)))))))))
+
+(defun frame-terminal-default-bg-mode (frame)
+ "Return the default background mode of FRAME.
+This checks the `frame-background-mode' variable, the X resource
+named \"backgroundMode\" (if FRAME is an X frame), and finally
+the `background-mode' terminal parameter."
+ (or frame-background-mode
+ (let ((bg-resource
+ (and (window-system frame)
+ (x-get-resource "backgroundMode" "BackgroundMode"))))
+ (if bg-resource
+ (intern (downcase bg-resource))))
+ (terminal-parameter frame 'background-mode)))
+
;;;; Frame configurations