diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index b6035614c..bc93293a6 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -28,6 +28,8 @@ Fixed - The version info now includes the Wayland compositor name if wayland-client is available under a different name than `libwayland-client.so` (#8771). +- The list of Chromium extensions in `--version` / `:version` now uses the + correct Chromium data profile, also fixing a crash with Qt 6.10.1 (#8785). [[v3.6.1]] v3.6.1 (2025-11-03) diff --git a/qutebrowser/browser/webengine/webenginesettings.py b/qutebrowser/browser/webengine/webenginesettings.py index 08d52b16c..599111196 100644 --- a/qutebrowser/browser/webengine/webenginesettings.py +++ b/qutebrowser/browser/webengine/webenginesettings.py @@ -458,14 +458,18 @@ def _clear_webengine_permissions_json(): ) +def default_qt_profile() -> QWebEngineProfile: + """Get the default profile from Qt.""" + if machinery.IS_QT6: + return QWebEngineProfile("Default") + else: + return QWebEngineProfile.defaultProfile() + + def _init_default_profile(): """Init the default QWebEngineProfile.""" global default_profile - - if machinery.IS_QT6: - default_profile = QWebEngineProfile("Default") - else: - default_profile = QWebEngineProfile.defaultProfile() + default_profile = default_qt_profile() assert not default_profile.isOffTheRecord() assert parsed_user_agent is None # avoid earlier profile initialization diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index 698843058..0d0598ca5 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -931,12 +931,18 @@ def _webengine_extensions() -> Sequence[str]: lines: list[str] = [] if ( objects.backend == usertypes.Backend.QtWebEngine - and "avoid-chromium-init" not in objects.debug_flags and machinery.IS_QT6 # mypy; TODO early return once Qt 5 is dropped ): - from qutebrowser.qt.webenginecore import QWebEngineProfile - profile = QWebEngineProfile.defaultProfile() - assert profile is not None # mypy + from qutebrowser.browser.webengine import webenginesettings + lines.append("WebExtensions:") + + if webenginesettings.default_profile: + profile = webenginesettings.default_profile + elif "avoid-chromium-init" in objects.debug_flags: + lines[0] += " unknown (avoiding init)" + return lines + else: + profile = webenginesettings.default_qt_profile() try: ext_manager = profile.extensionManager() @@ -945,7 +951,6 @@ def _webengine_extensions() -> Sequence[str]: return [] assert ext_manager is not None # mypy - lines.append("WebExtensions:") if not ext_manager.extensions(): lines[0] += " none" diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py index 5c7b94523..5988ce732 100644 --- a/tests/unit/utils/test_version.py +++ b/tests/unit/utils/test_version.py @@ -1449,11 +1449,9 @@ def test_version_info(params, stubs, monkeypatch, config_stub): monkeypatch.delattr(version, 'qtutils.qWebKitVersion', raising=False) if machinery.IS_QT6: monkeypatch.setattr( - QWebEngineProfile, - "defaultProfile", - lambda: FakeExtensionProfile( - FakeExtensionManager([FakeExtensionInfo("ext1")]) - ), + webenginesettings, + "default_profile", + FakeExtensionProfile(FakeExtensionManager([FakeExtensionInfo("ext1")])), ) substitutions['webextensions'] = ( "\n" @@ -1592,20 +1590,35 @@ class TestOpenGLInfo: class TestWebEngineExtensions: def test_qtwebkit(self, monkeypatch: pytest.MonkeyPatch) -> None: + assert webenginesettings.default_profile is None # -> default_qt_profile() used monkeypatch.setattr(version.objects, "backend", usertypes.Backend.QtWebKit) - monkeypatch.setattr(QWebEngineProfile, "defaultProfile", lambda: 1/0) + monkeypatch.setattr(webenginesettings, "default_qt_profile", lambda: 1 / 0) assert not version._webengine_extensions() def test_avoid_chromium_init(self, monkeypatch: pytest.MonkeyPatch) -> None: + assert webenginesettings.default_profile is None # -> default_qt_profile() used monkeypatch.setattr(version.objects, "backend", usertypes.Backend.QtWebEngine) monkeypatch.setattr(objects, "debug_flags", {"avoid-chromium-init"}) - monkeypatch.setattr(QWebEngineProfile, "defaultProfile", lambda: 1/0) - assert not version._webengine_extensions() + monkeypatch.setattr(webenginesettings, "default_qt_profile", lambda: 1 / 0) + assert version._webengine_extensions() == [ + "WebExtensions: unknown (avoiding init)" + ] def test_no_extension_manager(self, monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.setattr(QWebEngineProfile, "defaultProfile", object) + assert webenginesettings.default_profile is None # -> default_qt_profile() used + monkeypatch.setattr(webenginesettings, "default_qt_profile", object) assert not version._webengine_extensions() + @pytest.mark.parametrize("avoid_init", [True, False]) + def test_preexisting_profile(self, monkeypatch: pytest.MonkeyPatch, avoid_init: bool) -> None: + """Test that we use the pre-existing profile if available.""" + monkeypatch.setattr(webenginesettings, "default_profile", FakeExtensionProfile(FakeExtensionManager([]))) + if avoid_init: + monkeypatch.setattr(objects, "debug_flags", {"avoid-chromium-init"}) + + result = version._webengine_extensions() + assert result == ["WebExtensions: none"] + @pytest.mark.parametrize( "extensions, expected", [ @@ -1666,11 +1679,9 @@ class TestWebEngineExtensions: expected: list[str], ) -> None: monkeypatch.setattr( - QWebEngineProfile, - "defaultProfile", - lambda: FakeExtensionProfile( - FakeExtensionManager(extensions) - ), + webenginesettings, + "default_profile", + FakeExtensionProfile(FakeExtensionManager(extensions)), ) assert version._webengine_extensions() == expected