diff options
author | Chong Yidong <cyd@stupidchicken.com> | 2011-07-03 18:16:07 -0400 |
---|---|---|
committer | Chong Yidong <cyd@stupidchicken.com> | 2011-07-03 18:16:07 -0400 |
commit | 1485f4c03a3e887f8e60fefb96e5e3d9ca484cf7 (patch) | |
tree | 07c3889b6d224dbf2c2fcc647580c2ff548e56dd /lisp/frame.el | |
parent | 9fa3dd45482a9fa8084fae495b3a857a216decf2 (diff) | |
download | emacs-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.el | 110 |
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 |