Add qt.workarounds.disable_accessibility setting

This disables accessibility with Qt 6.10.1, which
causes frequent segfaults.

Closes #8797
This commit is contained in:
Florian Bruhin 2025-11-30 17:54:33 +01:00
parent 0570545342
commit 88aa47c377
5 changed files with 98 additions and 1 deletions

View File

@ -15,6 +15,18 @@ breaking changes (such as renamed commands) can happen in minor releases.
// `Fixed` for any bug fixes. // `Fixed` for any bug fixes.
// `Security` to invite users to upgrade in case of vulnerabilities. // `Security` to invite users to upgrade in case of vulnerabilities.
[[v3.6.3]]
v3.6.3 (unreleased)
-------------------
Fixed
~~~~~
- New `qt.workarounds.disable_accessibility` setting, which disables Chromium
accessibility support. By default, is it set to `auto`, which only disables
accessibility on Qt versions with known issues. This works around a bug in Qt
6.10.1 causing frequent segfaults (#8797).
[[v3.6.2]] [[v3.6.2]]
v3.6.2 (2025-11-27) v3.6.2 (2025-11-27)
------------------- -------------------

View File

@ -302,6 +302,7 @@
|<<qt.force_software_rendering,qt.force_software_rendering>>|Force software rendering for QtWebEngine. |<<qt.force_software_rendering,qt.force_software_rendering>>|Force software rendering for QtWebEngine.
|<<qt.highdpi,qt.highdpi>>|Turn on Qt HighDPI scaling. |<<qt.highdpi,qt.highdpi>>|Turn on Qt HighDPI scaling.
|<<qt.workarounds.disable_accelerated_2d_canvas,qt.workarounds.disable_accelerated_2d_canvas>>|Disable accelerated 2d canvas to avoid graphical glitches. |<<qt.workarounds.disable_accelerated_2d_canvas,qt.workarounds.disable_accelerated_2d_canvas>>|Disable accelerated 2d canvas to avoid graphical glitches.
|<<qt.workarounds.disable_accessibility,qt.workarounds.disable_accessibility>>|Disable accessibility to avoid crashes on Qt 6.10.1.
|<<qt.workarounds.disable_hangouts_extension,qt.workarounds.disable_hangouts_extension>>|Disable the Hangouts extension. |<<qt.workarounds.disable_hangouts_extension,qt.workarounds.disable_hangouts_extension>>|Disable the Hangouts extension.
|<<qt.workarounds.locale,qt.workarounds.locale>>|Work around locale parsing issues in QtWebEngine 5.15.3. |<<qt.workarounds.locale,qt.workarounds.locale>>|Work around locale parsing issues in QtWebEngine 5.15.3.
|<<qt.workarounds.remove_service_workers,qt.workarounds.remove_service_workers>>|Delete the QtWebEngine Service Worker directory on every start. |<<qt.workarounds.remove_service_workers,qt.workarounds.remove_service_workers>>|Delete the QtWebEngine Service Worker directory on every start.
@ -3996,6 +3997,24 @@ Valid values:
Default: +pass:[auto]+ Default: +pass:[auto]+
[[qt.workarounds.disable_accessibility]]
=== qt.workarounds.disable_accessibility
Disable accessibility to avoid crashes on Qt 6.10.1.
This setting requires a restart.
This setting is only available with the QtWebEngine backend.
Type: <<types,String>>
Valid values:
* +always+: Disable renderer accessibility
* +auto+: Disable on Qt versions with known issues, enable otherwise
* +never+: Enable renderer accessibility
Default: +pass:[auto]+
[[qt.workarounds.disable_hangouts_extension]] [[qt.workarounds.disable_hangouts_extension]]
=== qt.workarounds.disable_hangouts_extension === qt.workarounds.disable_hangouts_extension
Disable the Hangouts extension. Disable the Hangouts extension.

View File

@ -422,6 +422,19 @@ qt.workarounds.disable_hangouts_extension:
disabled to avoid crashes on Qt 6.5.0 to 6.5.3 if dark mode is enabled, disabled to avoid crashes on Qt 6.5.0 to 6.5.3 if dark mode is enabled,
as well as on Qt 6.6.0. as well as on Qt 6.6.0.
qt.workarounds.disable_accessibility:
type:
name: String
valid_values:
- always: Disable renderer accessibility
- auto: Disable on Qt versions with known issues, enable otherwise
- never: Enable renderer accessibility
default: auto
backend: QtWebEngine
restart: true
desc: >-
Disable accessibility to avoid crashes on Qt 6.10.1.
## auto_save ## auto_save
auto_save.interval: auto_save.interval:

View File

@ -362,6 +362,16 @@ _WEBENGINE_SETTINGS: dict[str, dict[Any, Optional[_SettingValueType]]] = {
and versions.webengine < utils.VersionNumber(6, 8, 2) and versions.webengine < utils.VersionNumber(6, 8, 2)
else None, else None,
}, },
'qt.workarounds.disable_accessibility': {
'always': '--disable-renderer-accessibility',
'never': None,
# WORKAROUND for https://qt-project.atlassian.net/browse/QTBUG-142320
'auto': lambda versions: '--disable-renderer-accessibility'
if machinery.IS_QT6
and versions.webengine
and versions.webengine == utils.VersionNumber(6, 10, 1)
else None,
},
} }

View File

@ -12,7 +12,7 @@ import pytest
from qutebrowser.qt import machinery from qutebrowser.qt import machinery
from qutebrowser import qutebrowser from qutebrowser import qutebrowser
from qutebrowser.config import qtargs, configdata from qutebrowser.config import qtargs, configdata
from qutebrowser.utils import usertypes, version from qutebrowser.utils import usertypes, version, utils
@pytest.fixture @pytest.fixture
@ -52,6 +52,7 @@ def reduce_args(config_stub, version_patcher, monkeypatch):
config_stub.val.scrolling.bar = 'never' config_stub.val.scrolling.bar = 'never'
config_stub.val.qt.chromium.experimental_web_platform_features = 'never' config_stub.val.qt.chromium.experimental_web_platform_features = 'never'
config_stub.val.qt.workarounds.disable_accelerated_2d_canvas = 'never' config_stub.val.qt.workarounds.disable_accelerated_2d_canvas = 'never'
config_stub.val.qt.workarounds.disable_accessibility = 'never'
monkeypatch.setattr(qtargs.utils, 'is_mac', False) monkeypatch.setattr(qtargs.utils, 'is_mac', False)
# Avoid WebRTC pipewire feature # Avoid WebRTC pipewire feature
monkeypatch.setattr(qtargs.utils, 'is_linux', False) monkeypatch.setattr(qtargs.utils, 'is_linux', False)
@ -117,6 +118,14 @@ def test_no_webengine_available(monkeypatch, config_stub, parser, stubs):
assert args == [sys.argv[0]] assert args == [sys.argv[0]]
_XFAIL_FUTURE_QT = (
pytest.mark.xfail(
utils.VersionNumber(6, 11) not in version.WebEngineVersions._CHROMIUM_VERSIONS,
reason="Unknown security patch version for Qt 6.11 so far",
),
)
@pytest.mark.usefixtures('reduce_args') @pytest.mark.usefixtures('reduce_args')
class TestWebEngineArgs: class TestWebEngineArgs:
@ -190,6 +199,40 @@ class TestWebEngineArgs:
args = qtargs.qt_args(parsed) args = qtargs.qt_args(parsed)
assert ('--disable-accelerated-2d-canvas' in args) == has_arg assert ('--disable-accelerated-2d-canvas' in args) == has_arg
@pytest.mark.parametrize(
"qt_version, qt6, value, has_arg",
[
("5.15.2", False, "auto", False),
# 6.8.5 is broken too, but commercial-only
("6.10.0", True, "always", True),
("6.10.0", True, "auto", False),
("6.10.1", True, "auto", True),
("6.10.1", True, "never", False),
("6.10.2", True, "always", True),
("6.10.2", True, "auto", False),
pytest.param("6.11.0", True, "always", True, marks=_XFAIL_FUTURE_QT),
pytest.param("6.11.0", True, "auto", False, marks=_XFAIL_FUTURE_QT),
],
)
def test_disable_accessibility(
self,
parser,
version_patcher,
config_stub,
monkeypatch,
qt_version,
qt6,
value,
has_arg,
):
version_patcher(qt_version)
config_stub.val.qt.workarounds.disable_accessibility = value
monkeypatch.setattr(machinery, 'IS_QT6', qt6)
parsed = parser.parse_args([])
args = qtargs.qt_args(parsed)
assert ('--disable-renderer-accessibility' in args) == has_arg
@pytest.mark.parametrize('flags, args', [ @pytest.mark.parametrize('flags, args', [
([], []), ([], []),
(['--debug-flag', 'chromium'], ['--enable-logging', '--v=1']), (['--debug-flag', 'chromium'], ['--enable-logging', '--v=1']),