diff --git a/lisp/ghostel.el b/lisp/ghostel.el index 9dc1b2b..1c5e2cc 100644 --- a/lisp/ghostel.el +++ b/lisp/ghostel.el @@ -284,8 +284,7 @@ or backing scale factor." shrinking entirely so CJK and other fallback glyphs render at natural size, potentially making rows slightly taller and cells slightly wider." :type '(float 0.0 1.0) - :local t - :group 'ghostel) + :local t) (defcustom ghostel-kitty-graphics-storage-limit (* 320 1024 1024) ; 320 MiB "Kitty graphics image storage cap, in bytes, per terminal. @@ -5360,18 +5359,21 @@ the rest of Emacs (e.g. a dark terminal inside a light Emacs)." (defun ghostel--face-hex-color (face attr) "Extract hex color string from FACE's ATTR (:foreground or :background). -Falls back to \"#000000\" if the color cannot be resolved." +Falls back to white (for :foreground) or black (for :background)." (or (let ((color (face-attribute face attr nil 'default))) - (when (and (stringp color) (not (string= color "unspecified"))) + (when (and (stringp color) + (not (member color '("unspecified" + "unspecified-fg" + "unspecified-bg")))) (let ((rgb (color-values color))) (if rgb (apply #'format "#%02x%02x%02x" (mapcar (lambda (c) (ash c -8)) rgb)) - ;; Batch mode: color-values returns nil without a display. - ;; If the color is already "#RRGGBB", use it directly. + ;; Batch mode / TTY: color-values returns nil without a + ;; display. If the color is already "#RRGGBB", use it. (and (string-prefix-p "#" color) (= (length color) 7) color))))) - "#000000")) + (if (eq attr :foreground) "#ffffff" "#000000"))) (defun ghostel--apply-palette (term) "Apply colors from `ghostel-color-palette' faces and default fg/bg to TERM." diff --git a/test/ghostel-render-test.el b/test/ghostel-render-test.el index c8f432a..b408b98 100644 --- a/test/ghostel-render-test.el +++ b/test/ghostel-render-test.el @@ -311,6 +311,24 @@ through without cross-call munging.)" (string-prefix-p "#" color) (= (length color) 7))))) +(ert-deftest ghostel-test-face-hex-color-tty-unspecified () + "TTY sentinel colors must not collapse fg and bg to the same hex (#297). +On a Linux framebuffer the `default' face reports \"unspecified-fg\" and +\"unspecified-bg\". If `ghostel--face-hex-color' returned the same +fallback for both, the buffer default face was remapped black-on-black +and typed text was invisible." + (cl-letf (((symbol-function 'face-attribute) + (lambda (_face attr &optional _frame _inherit) + (pcase attr + (:foreground "unspecified-fg") + (:background "unspecified-bg") + (_ 'unspecified))))) + (let ((fg (ghostel--face-hex-color 'ghostel-default :foreground)) + (bg (ghostel--face-hex-color 'ghostel-default :background))) + (should (string-match-p "\\`#[0-9a-fA-F]\\{6\\}\\'" fg)) + (should (string-match-p "\\`#[0-9a-fA-F]\\{6\\}\\'" bg)) + (should-not (string= fg bg))))) + (ert-deftest ghostel-test-hyperlinks () "Test hyperlink keymap and helpers." :tags '(native)