From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: night-mode? Date: Fri, 20 Nov 2020 16:25:35 -0500 Message-ID: Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="7898"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Nov 20 22:32:33 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kgE1A-0001zR-UW for ged-emacs-devel@m.gmane-mx.org; Fri, 20 Nov 2020 22:32:33 +0100 Original-Received: from localhost ([::1]:36098 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kgE19-0000uL-SP for ged-emacs-devel@m.gmane-mx.org; Fri, 20 Nov 2020 16:32:31 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:45630) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kgDud-0003ov-NI for emacs-devel@gnu.org; Fri, 20 Nov 2020 16:25:47 -0500 Original-Received: from mailscanner.iro.umontreal.ca ([132.204.25.50]:17931) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kgDuW-0000tX-Es for emacs-devel@gnu.org; Fri, 20 Nov 2020 16:25:46 -0500 Original-Received: from pmg1.iro.umontreal.ca (localhost.localdomain [127.0.0.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 8F79310024D; Fri, 20 Nov 2020 16:25:38 -0500 (EST) Original-Received: from mail01.iro.umontreal.ca (unknown [172.31.2.1]) by pmg1.iro.umontreal.ca (Proxmox) with ESMTP id 7D2521001D2; Fri, 20 Nov 2020 16:25:36 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=iro.umontreal.ca; s=mail; t=1605907536; bh=w3BMDykPrPmoXgXHtCJ2pmOgSJEPp43n9J/4lw2Q7AA=; h=From:To:Subject:Date:From; b=n36kZ6ijVsPyRgtcxDV2OX6EkISNBIcbkNqhu5Xp+U7BcaZm470f2HY8/uesxk5wE wHknfjzBySE8oReklTvKXRi7wKMgrj5lu8GS+XejDlgcorec7VLCNr3LXei8cUhFd4 T6Hx3/jPg7RhSRKT/KQ4wjcNtntQQZWO6ryAQz+FGHx1qQ9GvYW3ZsE0Y4uayaVo8w 3TnoTuLCn1ulP8aq62G1L8sntJ+Aj5RIrhBuz4eggClwIDJfsCfPzfG3Ct1CiecGE4 u2JgFrnT84xmtxl7g9WEvh1mv572x4yKrq73UqNgobj+byzgtW2tiGMSUy6X8gr8Q5 13r4apl+h/vEQ== Original-Received: from alfajor (69-165-136-52.dsl.teksavvy.com [69.165.136.52]) by mail01.iro.umontreal.ca (Postfix) with ESMTPSA id 1F0ED12027A; Fri, 20 Nov 2020 16:25:36 -0500 (EST) Received-SPF: pass client-ip=132.204.25.50; envelope-from=monnier@iro.umontreal.ca; helo=mailscanner.iro.umontreal.ca X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:259504 Archived-At: 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)))) + ;;;; Frame configurations