Repository: qutebrowser/qutebrowser

Issue:
colors.webpage.prefers_color_scheme_dark breaks with Qt 5.15.2
```
.tox/py38-pyqt515/bin/python3 -m qutebrowser --temp-basedir -s colors.webpage.prefers_color_scheme_dark true ':later 500 jseval matchMedia("(prefers-color-scheme: dark)").matches'
```

This shows "True" on QtWebEngine 5.15.1 and below, but "False" on QtWebEngine 5.15.2.

I suspect the `--force-dark-mode` Chromium flag got removed/renamed between Chromium 80 and 83.


Discussion:
According to `ekpneo` who originally reported this in IRC, passing `--blink-settings=preferredColorScheme=1` instead should work.

Resolving patch:
diff --git a/qutebrowser/browser/webengine/darkmode.py b/qutebrowser/browser/webengine/darkmode.py
--- a/qutebrowser/browser/webengine/darkmode.py
+++ b/qutebrowser/browser/webengine/darkmode.py
@@ -264,6 +264,12 @@ def _variant() -> Variant:
 
 def settings() -> Iterator[Tuple[str, str]]:
     """Get necessary blink settings to configure dark mode for QtWebEngine."""
+    if (qtutils.version_check('5.15.2', compiled=False) and
+            config.val.colors.webpage.prefers_color_scheme_dark):
+        # In future versions of 'blink', (> Qt 5.15.2) the enumeration has
+        # changed and this will need to be set to '0' instead.
+        yield "preferredColorScheme", "1"
+
     if not config.val.colors.webpage.darkmode.enabled:
         return
 
diff --git a/qutebrowser/config/qtargs.py b/qutebrowser/config/qtargs.py
--- a/qutebrowser/config/qtargs.py
+++ b/qutebrowser/config/qtargs.py
@@ -203,12 +203,18 @@ def _qtwebengine_settings_args() -> Iterator[str]:
         }
     }
 
-    referrer_setting = settings['content.headers.referer']
-    if qtutils.version_check('5.14', compiled=False):
+    if (qtutils.version_check('5.14', compiled=False) and
+            not qtutils.version_check('5.15.2', compiled=False)):
+        # In Qt 5.14 to 5.15.1, `--force-dark-mode` is used to set the
+        # preferred colorscheme. In Qt 5.15.2, this is handled by a
+        # blink-setting instead.
         settings['colors.webpage.prefers_color_scheme_dark'] = {
             True: '--force-dark-mode',
             False: None,
         }
+
+    referrer_setting = settings['content.headers.referer']
+    if qtutils.version_check('5.14', compiled=False):
         # Starting with Qt 5.14, this is handled via --enable-features
         referrer_setting['same-domain'] = None
     else:


Test patch:
diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py
--- a/tests/end2end/test_invocations.py
+++ b/tests/end2end/test_invocations.py
@@ -417,3 +417,18 @@ def test_referrer(quteproc_new, server, server2, request, value, expected):
             expected = expected.replace(key, str(val))
 
     assert headers.get('Referer') == expected
+
+
+@pytest.mark.qtwebkit_skip
+@utils.qt514
+def test_preferred_colorscheme(request, quteproc_new):
+    """Make sure the the preferred colorscheme is set."""
+    args = _base_args(request.config) + [
+        '--temp-basedir',
+        '-s', 'colors.webpage.prefers_color_scheme_dark', 'true',
+    ]
+    quteproc_new.start(args)
+
+    quteproc_new.send_cmd(':jseval '
+                          'matchMedia("(prefers-color-scheme: dark)").matches')
+    quteproc_new.wait_for(message='True')
diff --git a/tests/unit/browser/webengine/test_darkmode.py b/tests/unit/browser/webengine/test_darkmode.py
--- a/tests/unit/browser/webengine/test_darkmode.py
+++ b/tests/unit/browser/webengine/test_darkmode.py
@@ -32,6 +32,26 @@ def patch_backend(monkeypatch):
     monkeypatch.setattr(objects, 'backend', usertypes.Backend.QtWebEngine)
 
 
+@pytest.mark.parametrize('qversion, enabled, expected', [
+    # Disabled or nothing set
+    ("5.14", False, []),
+    ("5.15.0", False, []),
+    ("5.15.1", False, []),
+    ("5.15.2", False, []),
+
+    # Enabled in configuration
+    ("5.14", True, []),
+    ("5.15.0", True, []),
+    ("5.15.1", True, []),
+    ("5.15.2", True, [("preferredColorScheme", "1")]),
+])
+@utils.qt514
+def test_colorscheme(config_stub, monkeypatch, qversion, enabled, expected):
+    monkeypatch.setattr(darkmode.qtutils, 'qVersion', lambda: qversion)
+    config_stub.val.colors.webpage.prefers_color_scheme_dark = enabled
+    assert list(darkmode.settings()) == expected
+
+
 @pytest.mark.parametrize('settings, expected', [
     # Disabled
     ({}, []),
diff --git a/tests/unit/config/test_qtargs.py b/tests/unit/config/test_qtargs.py
--- a/tests/unit/config/test_qtargs.py
+++ b/tests/unit/config/test_qtargs.py
@@ -289,20 +289,24 @@ def test_referer(self, config_stub, monkeypatch, parser, qt_version, referer, ar
         else:
             assert arg in args
 
-    @pytest.mark.parametrize('dark, new_qt, added', [
-        (True, True, True),
-        (True, False, False),
-        (False, True, False),
-        (False, False, False),
+    @pytest.mark.parametrize('dark, qt_version, added', [
+        (True, "5.13", False),
+        (True, "5.14", True),
+        (True, "5.15.0", True),
+        (True, "5.15.1", True),
+        (True, "5.15.2", False),
+        (False, "5.13", False),
+        (False, "5.14", False),
+        (False, "5.15.0", False),
+        (False, "5.15.1", False),
+        (False, "5.15.2", False),
     ])
     @utils.qt514
     def test_prefers_color_scheme_dark(self, config_stub, monkeypatch, parser,
-                                       dark, new_qt, added):
+                                       dark, qt_version, added):
         monkeypatch.setattr(qtargs.objects, 'backend',
                             usertypes.Backend.QtWebEngine)
-        monkeypatch.setattr(qtargs.qtutils, 'version_check',
-                            lambda version, exact=False, compiled=True:
-                            new_qt)
+        monkeypatch.setattr(qtargs.qtutils, 'qVersion', lambda: qt_version)
 
         config_stub.val.colors.webpage.prefers_color_scheme_dark = dark