all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: emacs-devel@gnu.org
Subject: night-mode?
Date: Fri, 20 Nov 2020 16:25:35 -0500	[thread overview]
Message-ID: <jwvy2ivzq5p.fsf-monnier+emacs@gnu.org> (raw)

Based on previous discussions, I think we should add some way to toggle
the dark/light mode.  I'm not completely sure what the interface should
look like, nor what'd be the better implementation, but see the patch
below for a first cut to add a `night-mode` command, which does
basically the "inverse video" by swapping the foreground and the
background of the default face (and then resetting the background-mode
accordingly, of course).


        Stefan


Along the way I saw a few other issues:

- `frame-set-background-mode` currently doesn't use `color-dark-p`, and
  the code it uses for that uses a different algorithm, AFAICT.

- The only current use of `color-dark-p`, as well as the potential new
  use of it in `frame-set-background-mode` both have an RGB in form
  [0,65535] and need to scale it to p0,1] before calling `color-dark-p`,
  so maybe `color-dark-p` should be changed to accept colors using the
  [0,65535] scale.


diff --git a/lisp/faces.el b/lisp/faces.el
index 7355e1dd0a..a417979547 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -1798,6 +1798,9 @@ color-luminance-dark-limit
 This value was determined experimentally.")
 
 (defun color-dark-p (rgb)
+  ;; FIXME: The only 2 uses of this function I can find both need to
+  ;; (mapcar (lambda (c) (/ c 65535.0)) because they have RGB on
+  ;; [0,65535] instead of [0,1]!
   "Whether RGB is more readable against white than black.
 RGB is a 3-element list (R G B), each component in the range [0,1].
 This predicate can be used both for determining a suitable (black or white)
diff --git a/lisp/frame.el b/lisp/frame.el
index 772ba3d8c4..57ffb8bee9 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -1159,8 +1159,8 @@ frame-background-mode
   :group 'faces
   :set #'(lambda (var value)
 	   (set-default var value)
-	   (mapc 'frame-set-background-mode (frame-list)))
-  :initialize 'custom-initialize-changed
+	   (mapc #'frame-set-background-mode (frame-list)))
+  :initialize #'custom-initialize-changed
   :type '(choice (const dark)
 		 (const light)
 		 (const :tag "automatic" nil)))
@@ -1173,6 +1173,27 @@ frame-background-mode
 
 (defvar inhibit-frame-set-background-mode nil)
 
+(defun frame--current-backround-mode (frame)
+  (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)))
+    (cond (frame-default-bg-mode)
+	  ((equal bg-color "unspecified-fg") ; inverted colors
+	   (if (eq default-bg-mode 'light) 'dark 'light))
+	  ((not (color-values bg-color frame))
+	   default-bg-mode)
+	  ((color-dark-p (mapcar (lambda (c) (/ c 65535.0))
+	                         (color-values bg-color frame)))
+	   'dark)
+	  (t 'light))))
+
 (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
@@ -1181,30 +1202,8 @@ frame-set-background-mode
 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)))
+    (let* ((bg-mode
+	    (frame--current-backround-mode frame))
 	   (display-type
 	    (cond ((null (window-system frame))
 		   (if (tty-display-color-p frame) 'color 'mono))
@@ -1270,6 +1269,18 @@ frame-terminal-default-bg-mode
 	    (intern (downcase bg-resource))))
       (terminal-parameter frame 'background-mode)))
 
+(define-minor-mode night-mode
+  "Use light text on dark background."
+  :global t
+  ;; FIXME: The code below is partly per-frame and partly all-frames :-(
+  (when (eq night-mode
+            (eq 'light (frame--current-backround-mode (selected-frame))))
+    ;; FIXME: Change the face's SPEC instead?
+    (set-face-attribute 'default nil
+                        :foreground (face-attribute 'default :background)
+                        :background (face-attribute 'default :foreground))
+    (frame-set-background-mode (selected-frame))))
+
 \f
 ;;;; Frame configurations
 




             reply	other threads:[~2020-11-20 21:25 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-20 21:25 Stefan Monnier [this message]
2020-11-21  2:36 ` night-mode? Pankaj Jangid
2020-11-21  5:00   ` Modus themes toggle (was: night-mode?) Protesilaos Stavrou
2020-11-21  7:22     ` Modus themes toggle Pankaj Jangid
2020-11-21 19:21 ` night-mode? Juri Linkov
2020-11-21 21:20   ` night-mode? Stefan Monnier
2020-11-22  8:40     ` night-mode? Juri Linkov
2020-11-22 15:09       ` night-mode? Stefan Monnier
2020-11-22 15:16       ` night-mode? Eli Zaretskii
2020-11-22 16:09         ` night-mode? Jean Louis
2020-11-22 19:55           ` night-mode? Stefan Monnier
2020-11-22 16:38         ` night-mode? Arthur Miller
2020-11-22 17:27           ` night-mode? Jean Louis
2020-11-23  7:21             ` night-mode? Arthur Miller
2020-11-23  8:36               ` night-mode? Jean Louis
2020-11-23 17:06                 ` night-mode? Arthur Miller
2020-11-23 19:38                   ` night-mode? Jean Louis
2020-11-24  8:55                     ` night-mode? Arthur Miller
2020-11-24  9:47                       ` night-mode? Jean Louis
     [not found] ` <87r1onmjpx.fsf@gmail.com>
     [not found]   ` <jwvtutiy783.fsf-monnier+emacs@gnu.org>
2020-11-22  0:03     ` night-mode? Caio Henrique

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=jwvy2ivzq5p.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.