changeset 3704:c143e7f35074

cli (base): better background detection: - ANSI escape code detection is only used on terminals known to be compatible (currently xterm, konsole, and all VTE based ones) - `COLORFGBG` environment variable is used as fallback - if both methods fail, `dark` is used This should avoid problems with incompatible terminals (e.g. on QTerminal, users had to press `[ENTER]` each time). fix 406
author Goffi <goffi@goffi.org>
date Sat, 06 Nov 2021 17:08:50 +0100
parents de133b180941
children 691dbd78981c
files sat_frontends/jp/base.py
diffstat 1 files changed, 56 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/sat_frontends/jp/base.py	Fri Nov 05 18:11:24 2021 +0100
+++ b/sat_frontends/jp/base.py	Sat Nov 06 17:08:50 2021 +0100
@@ -119,33 +119,65 @@
         return config.getConfig(self.sat_conf, section, name, default=default)
 
     def guess_background(self):
-        if not sys.stdin.isatty() or not sys.stdout.isatty():
-            return 'dark'
-        stdin_fd = sys.stdin.fileno()
-        old_settings = termios.tcgetattr(stdin_fd)
+        # cf. https://unix.stackexchange.com/a/245568 (thanks!)
         try:
-            tty.setraw(sys.stdin.fileno())
-            # we request background color
-            sys.stdout.write("\033]11;?\a")
-            sys.stdout.flush()
-            expected = "\033]11;rgb:"
-            for c in expected:
-                ch = sys.stdin.read(1)
-                if ch != c:
-                    # background id is not supported, we default to "dark"
-                    # TODO: log something?
-                    return 'dark'
-            red, green, blue = [int(c, 16)/65535 for c in sys.stdin.read(14).split('/')]
-            # '\a' is the last character
-            sys.stdin.read(1)
-        finally:
-            termios.tcsetattr(stdin_fd, termios.TCSADRAIN, old_settings)
+            # for VTE based terminals
+            vte_version = int(os.getenv("VTE_VERSION", 0))
+        except ValueError:
+            vte_version = 0
+
+        color_fg_bg = os.getenv("COLORFGBG")
 
-        lum = utils.per_luminance(red, green, blue)
-        if lum <= 0.5:
-            return 'dark'
+        if ((sys.stdin.isatty() and sys.stdout.isatty()
+             and (
+                 # XTerm
+                 os.getenv("TERM", "") in {"xterm"}
+                 # Konsole
+                 or os.getenv("KONSOLE_VERSION")
+                 # All VTE based terminals
+                 or vte_version >= 3502
+             ))):
+            # ANSI escape sequence
+            stdin_fd = sys.stdin.fileno()
+            old_settings = termios.tcgetattr(stdin_fd)
+            try:
+                tty.setraw(sys.stdin.fileno())
+                # we request background color
+                sys.stdout.write("\033]11;?\a")
+                sys.stdout.flush()
+                expected = "\033]11;rgb:"
+                for c in expected:
+                    ch = sys.stdin.read(1)
+                    if ch != c:
+                        # background id is not supported, we default to "dark"
+                        # TODO: log something?
+                        return 'dark'
+                red, green, blue = [
+                    int(c, 16)/65535 for c in sys.stdin.read(14).split('/')
+                ]
+                # '\a' is the last character
+                sys.stdin.read(1)
+            finally:
+                termios.tcsetattr(stdin_fd, termios.TCSADRAIN, old_settings)
+
+            lum = utils.per_luminance(red, green, blue)
+            if lum <= 0.5:
+                return 'dark'
+            else:
+                return 'light'
+        elif color_fg_bg:
+            # no luck with ANSI escape sequence, we try COLORFGBG environment variable
+            try:
+                bg = int(color_fg_bg.split(";")[-1])
+            except ValueError:
+                return "dark"
+            if bg in list(range(7)) + [8]:
+                return "dark"
+            else:
+                return "light"
         else:
-            return 'light'
+            # no autodetection method found
+            return "dark"
 
     def set_color_theme(self):
         background = self.get_config('background', default='auto')