summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2023-03-17 20:30:13 +0100
committerFlorian Bruhin <me@the-compiler.org>2023-03-17 20:30:13 +0100
commit4793070db3e5afec32470c440a63c6add0450880 (patch)
treed69cba543c311f3e131c76b5cbb9e6006f6fc32c
parent3d56f57e502ffaad40936f19f44083a2b63f0690 (diff)
parent30125a2e2e302b79a168db36cb5b3f18ff50f5bd (diff)
downloadqutebrowser-4793070db3e5afec32470c440a63c6add0450880.tar.gz
qutebrowser-4793070db3e5afec32470c440a63c6add0450880.zip
Merge branch 'qt6-v2' into master-qt6
-rw-r--r--.github/workflows/ci.yml42
-rw-r--r--.pylintrc5
-rw-r--r--MANIFEST.in1
-rw-r--r--README.asciidoc9
-rw-r--r--doc/changelog.asciidoc5
-rw-r--r--doc/contributing.asciidoc69
-rw-r--r--doc/help/commands.asciidoc13
-rw-r--r--doc/help/settings.asciidoc70
-rw-r--r--doc/qutebrowser.1.asciidoc2
-rw-r--r--misc/qutebrowser.spec2
-rw-r--r--misc/requirements/requirements-pyqt-5.12.txt5
-rw-r--r--misc/requirements/requirements-pyqt-5.12.txt-raw4
-rw-r--r--misc/requirements/requirements-pyqt-5.13.txt5
-rw-r--r--misc/requirements/requirements-pyqt-5.13.txt-raw4
-rw-r--r--misc/requirements/requirements-pyqt-5.14.txt5
-rw-r--r--misc/requirements/requirements-pyqt-5.14.txt-raw4
-rw-r--r--misc/requirements/requirements-pyqt-5.15.0.txt5
-rw-r--r--misc/requirements/requirements-pyqt-5.15.0.txt-raw4
-rw-r--r--misc/requirements/requirements-pyqt-5.15.2.txt5
-rw-r--r--misc/requirements/requirements-pyqt-5.15.2.txt-raw4
-rw-r--r--misc/requirements/requirements-pyqt-5.txt7
-rw-r--r--misc/requirements/requirements-pyqt-5.txt-raw2
-rw-r--r--misc/requirements/requirements-pyqt-6.2.txt7
-rw-r--r--misc/requirements/requirements-pyqt-6.2.txt-raw4
-rw-r--r--misc/requirements/requirements-pyqt-6.3.txt7
-rw-r--r--misc/requirements/requirements-pyqt-6.3.txt-raw4
-rw-r--r--misc/requirements/requirements-pyqt-6.4.txt7
-rw-r--r--misc/requirements/requirements-pyqt-6.4.txt-raw4
-rw-r--r--misc/requirements/requirements-pyqt-6.txt7
-rw-r--r--misc/requirements/requirements-pyqt-6.txt-raw4
-rw-r--r--misc/requirements/requirements-qutebrowser.txt-raw2
-rw-r--r--pyrightconfig.json10
-rw-r--r--pytest.ini55
-rw-r--r--qutebrowser/api/config.py2
-rw-r--r--qutebrowser/api/downloads.py2
-rw-r--r--qutebrowser/app.py121
-rw-r--r--qutebrowser/browser/browsertab.py95
-rw-r--r--qutebrowser/browser/commands.py66
-rw-r--r--qutebrowser/browser/downloads.py26
-rw-r--r--qutebrowser/browser/downloadview.py16
-rw-r--r--qutebrowser/browser/eventfilter.py51
-rw-r--r--qutebrowser/browser/greasemonkey.py6
-rw-r--r--qutebrowser/browser/hints.py21
-rw-r--r--qutebrowser/browser/history.py8
-rw-r--r--qutebrowser/browser/inspector.py8
-rw-r--r--qutebrowser/browser/navigate.py28
-rw-r--r--qutebrowser/browser/network/pac.py34
-rw-r--r--qutebrowser/browser/network/proxy.py10
-rw-r--r--qutebrowser/browser/pdfjs.py6
-rw-r--r--qutebrowser/browser/qtnetworkdownloads.py117
-rw-r--r--qutebrowser/browser/qutescheme.py20
-rw-r--r--qutebrowser/browser/shared.py91
-rw-r--r--qutebrowser/browser/signalfilter.py2
-rw-r--r--qutebrowser/browser/urlmarks.py8
-rw-r--r--qutebrowser/browser/webelem.py47
-rw-r--r--qutebrowser/browser/webengine/certificateerror.py42
-rw-r--r--qutebrowser/browser/webengine/darkmode.py188
-rw-r--r--qutebrowser/browser/webengine/interceptor.py92
-rw-r--r--qutebrowser/browser/webengine/notification.py146
-rw-r--r--qutebrowser/browser/webengine/tabhistory.py4
-rw-r--r--qutebrowser/browser/webengine/webenginedownloads.py82
-rw-r--r--qutebrowser/browser/webengine/webengineelem.py13
-rw-r--r--qutebrowser/browser/webengine/webengineinspector.py47
-rw-r--r--qutebrowser/browser/webengine/webenginequtescheme.py24
-rw-r--r--qutebrowser/browser/webengine/webenginesettings.py140
-rw-r--r--qutebrowser/browser/webengine/webenginetab.py357
-rw-r--r--qutebrowser/browser/webengine/webview.py100
-rw-r--r--qutebrowser/browser/webkit/cache.py2
-rw-r--r--qutebrowser/browser/webkit/certificateerror.py27
-rw-r--r--qutebrowser/browser/webkit/cookies.py4
-rw-r--r--qutebrowser/browser/webkit/http.py4
-rw-r--r--qutebrowser/browser/webkit/mhtml.py2
-rw-r--r--qutebrowser/browser/webkit/network/networkmanager.py34
-rw-r--r--qutebrowser/browser/webkit/network/networkreply.py20
-rw-r--r--qutebrowser/browser/webkit/network/webkitqutescheme.py20
-rw-r--r--qutebrowser/browser/webkit/tabhistory.py8
-rw-r--r--qutebrowser/browser/webkit/webkitelem.py15
-rw-r--r--qutebrowser/browser/webkit/webkithistory.py5
-rw-r--r--qutebrowser/browser/webkit/webkitinspector.py11
-rw-r--r--qutebrowser/browser/webkit/webkitsettings.py95
-rw-r--r--qutebrowser/browser/webkit/webkittab.py181
-rw-r--r--qutebrowser/browser/webkit/webpage.py69
-rw-r--r--qutebrowser/browser/webkit/webview.py35
-rw-r--r--qutebrowser/commands/argparser.py2
-rw-r--r--qutebrowser/commands/runners.py6
-rw-r--r--qutebrowser/commands/userscripts.py4
-rw-r--r--qutebrowser/completion/completer.py2
-rw-r--r--qutebrowser/completion/completiondelegate.py86
-rw-r--r--qutebrowser/completion/completionwidget.py26
-rw-r--r--qutebrowser/completion/models/completionmodel.py16
-rw-r--r--qutebrowser/completion/models/filepathcategory.py6
-rw-r--r--qutebrowser/completion/models/histcategory.py4
-rw-r--r--qutebrowser/completion/models/listcategory.py8
-rw-r--r--qutebrowser/completion/models/urlmodel.py2
-rw-r--r--qutebrowser/components/braveadblock.py3
-rw-r--r--qutebrowser/components/hostblock.py2
-rw-r--r--qutebrowser/components/misccommands.py18
-rw-r--r--qutebrowser/components/readlinecommands.py2
-rw-r--r--qutebrowser/components/utils/blockutils.py2
-rw-r--r--qutebrowser/config/config.py9
-rw-r--r--qutebrowser/config/configcommands.py15
-rw-r--r--qutebrowser/config/configdata.py5
-rw-r--r--qutebrowser/config/configdata.yml65
-rw-r--r--qutebrowser/config/configfiles.py83
-rw-r--r--qutebrowser/config/configinit.py4
-rw-r--r--qutebrowser/config/configtypes.py44
-rw-r--r--qutebrowser/config/configutils.py26
-rw-r--r--qutebrowser/config/qtargs.py169
-rw-r--r--qutebrowser/config/stylesheet.py4
-rw-r--r--qutebrowser/config/websettings.py4
-rw-r--r--qutebrowser/extensions/interceptors.py5
-rw-r--r--qutebrowser/extensions/loader.py2
-rw-r--r--qutebrowser/html/warning-sandboxing.html16
-rw-r--r--qutebrowser/html/warning-sessions.html2
-rw-r--r--qutebrowser/html/warning-webkit.html8
-rw-r--r--qutebrowser/javascript/quirks/globalthis.user.js12
-rw-r--r--qutebrowser/javascript/quirks/object_fromentries.user.js46
-rw-r--r--qutebrowser/keyinput/basekeyparser.py62
-rw-r--r--qutebrowser/keyinput/eventfilter.py10
-rw-r--r--qutebrowser/keyinput/keyutils.py483
-rw-r--r--qutebrowser/keyinput/modeman.py24
-rw-r--r--qutebrowser/keyinput/modeparsers.py44
-rw-r--r--qutebrowser/mainwindow/mainwindow.py64
-rw-r--r--qutebrowser/mainwindow/messageview.py10
-rw-r--r--qutebrowser/mainwindow/prompt.py50
-rw-r--r--qutebrowser/mainwindow/statusbar/bar.py8
-rw-r--r--qutebrowser/mainwindow/statusbar/clock.py4
-rw-r--r--qutebrowser/mainwindow/statusbar/command.py12
-rw-r--r--qutebrowser/mainwindow/statusbar/keystring.py2
-rw-r--r--qutebrowser/mainwindow/statusbar/percentage.py4
-rw-r--r--qutebrowser/mainwindow/statusbar/progress.py6
-rw-r--r--qutebrowser/mainwindow/statusbar/searchmatch.py2
-rw-r--r--qutebrowser/mainwindow/statusbar/tabindex.py2
-rw-r--r--qutebrowser/mainwindow/statusbar/textbase.py16
-rw-r--r--qutebrowser/mainwindow/statusbar/url.py2
-rw-r--r--qutebrowser/mainwindow/tabbedbrowser.py32
-rw-r--r--qutebrowser/mainwindow/tabwidget.py154
-rw-r--r--qutebrowser/mainwindow/windowundo.py4
-rw-r--r--qutebrowser/misc/autoupdate.py2
-rw-r--r--qutebrowser/misc/backendproblem.py304
-rw-r--r--qutebrowser/misc/cmdhistory.py2
-rw-r--r--qutebrowser/misc/consolewidget.py16
-rw-r--r--qutebrowser/misc/crashdialog.py24
-rw-r--r--qutebrowser/misc/crashsignal.py8
-rw-r--r--qutebrowser/misc/earlyinit.py89
-rw-r--r--qutebrowser/misc/editor.py4
-rw-r--r--qutebrowser/misc/elf.py51
-rw-r--r--qutebrowser/misc/guiprocess.py24
-rw-r--r--qutebrowser/misc/httpclient.py12
-rw-r--r--qutebrowser/misc/ipc.py54
-rw-r--r--qutebrowser/misc/keyhintwidget.py20
-rw-r--r--qutebrowser/misc/lineparser.py2
-rw-r--r--qutebrowser/misc/miscwidgets.py39
-rw-r--r--qutebrowser/misc/msgbox.py14
-rw-r--r--qutebrowser/misc/pastebin.py2
-rw-r--r--qutebrowser/misc/quitter.py39
-rw-r--r--qutebrowser/misc/savemanager.py2
-rw-r--r--qutebrowser/misc/sessions.py18
-rw-r--r--qutebrowser/misc/sql.py104
-rw-r--r--qutebrowser/misc/throttle.py2
-rw-r--r--qutebrowser/misc/utilcmds.py4
-rw-r--r--qutebrowser/qt.py29
-rw-r--r--qutebrowser/qt/__init__.py0
-rw-r--r--qutebrowser/qt/core.py16
-rw-r--r--qutebrowser/qt/dbus.py16
-rw-r--r--qutebrowser/qt/gui.py18
-rw-r--r--qutebrowser/qt/machinery.py79
-rw-r--r--qutebrowser/qt/network.py16
-rw-r--r--qutebrowser/qt/opengl.py16
-rw-r--r--qutebrowser/qt/printsupport.py16
-rw-r--r--qutebrowser/qt/qml.py16
-rw-r--r--qutebrowser/qt/sip.py31
-rw-r--r--qutebrowser/qt/sql.py16
-rw-r--r--qutebrowser/qt/test.py16
-rw-r--r--qutebrowser/qt/webenginecore.py31
-rw-r--r--qutebrowser/qt/webenginewidgets.py32
-rw-r--r--qutebrowser/qt/webkit.py16
-rw-r--r--qutebrowser/qt/webkitwidgets.py16
-rw-r--r--qutebrowser/qt/widgets.py19
-rw-r--r--qutebrowser/qutebrowser.py4
-rw-r--r--qutebrowser/utils/debug.py108
-rw-r--r--qutebrowser/utils/error.py4
-rw-r--r--qutebrowser/utils/jinja.py4
-rw-r--r--qutebrowser/utils/log.py39
-rw-r--r--qutebrowser/utils/message.py4
-rw-r--r--qutebrowser/utils/objreg.py6
-rw-r--r--qutebrowser/utils/qtutils.py110
-rw-r--r--qutebrowser/utils/standarddir.py48
-rw-r--r--qutebrowser/utils/urlmatch.py2
-rw-r--r--qutebrowser/utils/urlutils.py33
-rw-r--r--qutebrowser/utils/usertypes.py31
-rw-r--r--qutebrowser/utils/utils.py10
-rw-r--r--qutebrowser/utils/version.py220
-rw-r--r--scripts/dev/Makefile-dmg2
-rwxr-xr-xscripts/dev/build_release.py157
-rw-r--r--scripts/dev/changelog_urls.json5
-rw-r--r--scripts/dev/ci/docker/Dockerfile.j218
-rw-r--r--scripts/dev/ci/docker/generate.py7
-rw-r--r--scripts/dev/enums.txt7970
-rw-r--r--scripts/dev/misc_checks.py34
-rw-r--r--scripts/dev/rewrite_enums.py45
-rw-r--r--scripts/dev/rewrite_find_enums.py67
-rw-r--r--scripts/dev/rewrite_find_flags.py83
-rw-r--r--scripts/dev/rewrite_qt_imports.sh22
-rwxr-xr-xscripts/dev/run_vulture.py11
-rw-r--r--scripts/link_pyqt.py19
-rwxr-xr-xscripts/mkvenv.py111
-rwxr-xr-xscripts/testbrowser/testbrowser_webengine.py13
-rw-r--r--tests/conftest.py23
-rw-r--r--tests/end2end/conftest.py17
-rw-r--r--tests/end2end/features/conftest.py18
-rw-r--r--tests/end2end/features/downloads.feature41
-rw-r--r--tests/end2end/features/keyinput.feature2
-rw-r--r--tests/end2end/features/misc.feature7
-rw-r--r--tests/end2end/features/prompts.feature20
-rw-r--r--tests/end2end/features/qutescheme.feature5
-rw-r--r--tests/end2end/features/search.feature10
-rw-r--r--tests/end2end/features/test_downloads_bdd.py9
-rw-r--r--tests/end2end/features/test_editor_bdd.py2
-rw-r--r--tests/end2end/features/test_notifications_bdd.py11
-rw-r--r--tests/end2end/features/test_qutescheme_bdd.py16
-rw-r--r--tests/end2end/fixtures/notificationserver.py18
-rw-r--r--tests/end2end/fixtures/quteprocess.py340
-rw-r--r--tests/end2end/fixtures/test_quteprocess.py15
-rw-r--r--tests/end2end/fixtures/test_testprocess.py4
-rw-r--r--tests/end2end/fixtures/testprocess.py8
-rw-r--r--tests/end2end/fixtures/webserver.py5
-rw-r--r--tests/end2end/fixtures/webserver_sub_ssl.py8
-rw-r--r--tests/end2end/test_dirbrowser.py2
-rw-r--r--tests/end2end/test_invocations.py175
-rw-r--r--tests/helpers/fixtures.py29
-rw-r--r--tests/helpers/messagemock.py2
-rw-r--r--tests/helpers/stubs.py19
-rw-r--r--tests/helpers/test_helper_utils.py11
-rw-r--r--tests/helpers/testutils.py42
-rw-r--r--tests/unit/browser/test_browsertab.py48
-rw-r--r--tests/unit/browser/test_caret.py2
-rw-r--r--tests/unit/browser/test_downloadview.py2
-rw-r--r--tests/unit/browser/test_hints.py2
-rw-r--r--tests/unit/browser/test_history.py10
-rw-r--r--tests/unit/browser/test_inspector.py2
-rw-r--r--tests/unit/browser/test_navigate.py2
-rw-r--r--tests/unit/browser/test_notification.py18
-rw-r--r--tests/unit/browser/test_pdfjs.py4
-rw-r--r--tests/unit/browser/test_qutescheme.py38
-rw-r--r--tests/unit/browser/test_signalfilter.py2
-rw-r--r--tests/unit/browser/test_urlmarks.py2
-rw-r--r--tests/unit/browser/webengine/test_darkmode.py126
-rw-r--r--tests/unit/browser/webengine/test_webengine_cookies.py7
-rw-r--r--tests/unit/browser/webengine/test_webenginedownloads.py8
-rw-r--r--tests/unit/browser/webengine/test_webengineinterceptor.py16
-rw-r--r--tests/unit/browser/webengine/test_webenginesettings.py14
-rw-r--r--tests/unit/browser/webengine/test_webenginetab.py30
-rw-r--r--tests/unit/browser/webengine/test_webview.py75
-rw-r--r--tests/unit/browser/webkit/http/test_http.py2
-rw-r--r--tests/unit/browser/webkit/network/test_filescheme.py4
-rw-r--r--tests/unit/browser/webkit/network/test_networkreply.py22
-rw-r--r--tests/unit/browser/webkit/network/test_pac.py10
-rw-r--r--tests/unit/browser/webkit/test_cache.py4
-rw-r--r--tests/unit/browser/webkit/test_certificateerror.py14
-rw-r--r--tests/unit/browser/webkit/test_cookies.py4
-rw-r--r--tests/unit/browser/webkit/test_tabhistory.py9
-rw-r--r--tests/unit/browser/webkit/test_webkit_view.py (renamed from tests/unit/browser/webkit/test_webview.py)0
-rw-r--r--tests/unit/browser/webkit/test_webkitelem.py6
-rw-r--r--tests/unit/browser/webkit/test_webkitsettings.py2
-rw-r--r--tests/unit/commands/test_argparser.py2
-rw-r--r--tests/unit/commands/test_userscripts.py2
-rw-r--r--tests/unit/completion/test_completer.py2
-rw-r--r--tests/unit/completion/test_completiondelegate.py14
-rw-r--r--tests/unit/completion/test_completionmodel.py2
-rw-r--r--tests/unit/completion/test_completionwidget.py2
-rw-r--r--tests/unit/completion/test_models.py10
-rw-r--r--tests/unit/components/test_blockutils.py2
-rw-r--r--tests/unit/components/test_braveadblock.py9
-rw-r--r--tests/unit/components/test_hostblock.py2
-rw-r--r--tests/unit/components/test_readlinecommands.py2
-rw-r--r--tests/unit/config/test_config.py22
-rw-r--r--tests/unit/config/test_configcommands.py15
-rw-r--r--tests/unit/config/test_configexc.py6
-rw-r--r--tests/unit/config/test_configfiles.py213
-rw-r--r--tests/unit/config/test_configinit.py2
-rw-r--r--tests/unit/config/test_configtypes.py76
-rw-r--r--tests/unit/config/test_configutils.py4
-rw-r--r--tests/unit/config/test_qtargs.py167
-rw-r--r--tests/unit/config/test_qtargs_locale_workaround.py4
-rw-r--r--tests/unit/config/test_stylesheet.py2
-rw-r--r--tests/unit/javascript/conftest.py2
-rw-r--r--tests/unit/javascript/position_caret/test_position_caret.py10
-rw-r--r--tests/unit/javascript/stylesheet/test_stylesheet_js.py4
-rw-r--r--tests/unit/javascript/test_greasemonkey.py2
-rw-r--r--tests/unit/javascript/test_js_execution.py21
-rw-r--r--tests/unit/javascript/test_js_quirks.py43
-rw-r--r--tests/unit/keyinput/conftest.py20
-rw-r--r--tests/unit/keyinput/key_data.py19
-rw-r--r--tests/unit/keyinput/test_basekeyparser.py90
-rw-r--r--tests/unit/keyinput/test_bindingtrie.py30
-rw-r--r--tests/unit/keyinput/test_keyutils.py383
-rw-r--r--tests/unit/keyinput/test_modeman.py20
-rw-r--r--tests/unit/keyinput/test_modeparsers.py38
-rw-r--r--tests/unit/mainwindow/statusbar/test_textbase.py10
-rw-r--r--tests/unit/mainwindow/statusbar/test_url.py27
-rw-r--r--tests/unit/mainwindow/test_messageview.py23
-rw-r--r--tests/unit/mainwindow/test_prompt.py10
-rw-r--r--tests/unit/mainwindow/test_tabwidget.py2
-rw-r--r--tests/unit/misc/test_autoupdate.py2
-rw-r--r--tests/unit/misc/test_editor.py24
-rw-r--r--tests/unit/misc/test_elf.py43
-rw-r--r--tests/unit/misc/test_guiprocess.py10
-rw-r--r--tests/unit/misc/test_ipc.py93
-rw-r--r--tests/unit/misc/test_miscwidgets.py51
-rw-r--r--tests/unit/misc/test_msgbox.py20
-rw-r--r--tests/unit/misc/test_pastebin.py2
-rw-r--r--tests/unit/misc/test_sessions.py4
-rw-r--r--tests/unit/misc/test_sql.py81
-rw-r--r--tests/unit/misc/test_throttle.py4
-rw-r--r--tests/unit/misc/test_utilcmds.py2
-rw-r--r--tests/unit/misc/userscripts/test_qute_lastpass.py2
-rw-r--r--tests/unit/test_app.py2
-rw-r--r--tests/unit/utils/test_debug.py59
-rw-r--r--tests/unit/utils/test_error.py8
-rw-r--r--tests/unit/utils/test_jinja.py2
-rw-r--r--tests/unit/utils/test_log.py6
-rw-r--r--tests/unit/utils/test_qtutils.py151
-rw-r--r--tests/unit/utils/test_standarddir.py29
-rw-r--r--tests/unit/utils/test_urlmatch.py4
-rw-r--r--tests/unit/utils/test_urlutils.py47
-rw-r--r--tests/unit/utils/test_utils.py8
-rw-r--r--tests/unit/utils/test_version.py102
-rw-r--r--tests/unit/utils/usertypes/test_timer.py2
-rw-r--r--tox.ini55
330 files changed, 13958 insertions, 4573 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 69f0dc687..d463df3f0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,7 +21,9 @@ jobs:
include:
- testenv: pylint
- testenv: flake8
- - testenv: mypy
+ # FIXME:qt6 (lint)
+ # - testenv: mypy-pyqt6
+ - testenv: mypy-pyqt5
- testenv: docs
- testenv: vulture
- testenv: misc
@@ -90,11 +92,11 @@ jobs:
image:
- archlinux-webkit
- archlinux-webengine
+ # - archlinux-webengine-qt6 # FIXME:qt6 activate
# - archlinux-webengine-unstable
container:
image: "qutebrowser/ci:${{ matrix.image }}"
env:
- QUTE_BDD_WEBENGINE: "${{ matrix.image != 'archlinux-webkit' }}"
DOCKER: "${{ matrix.image }}"
CI: true
PYTEST_ADDOPTS: "--color=yes"
@@ -119,30 +121,32 @@ jobs:
fail-fast: false
matrix:
include:
- ### PyQt 5.12 (Python 3.7)
- - testenv: py37-pyqt512
- os: ubuntu-20.04
- python: "3.7"
- ### PyQt 5.13 (Python 3.7)
- - testenv: py37-pyqt513
- os: ubuntu-20.04
- python: "3.7"
- ### PyQt 5.14 (Python 3.8)
- - testenv: py38-pyqt514
- os: ubuntu-20.04
- python: "3.8"
- ### PyQt 5.15.0 (Python 3.9)
- - testenv: py39-pyqt5150
+ ### PyQt 5.15.2 (Python 3.9)
+ - testenv: py39-pyqt5152
os: ubuntu-20.04
python: "3.9"
### PyQt 5.15 (Python 3.10, with coverage)
- - testenv: py310-pyqt515-cov
- os: ubuntu-22.04
- python: "3.10"
+ ### PyQt 5.15 (Python 3.9, with coverage)
+ # FIXME:qt6
+ # - testenv: py39-pyqt515-cov
+ # os: ubuntu-22.04
+ # python: "3.10"
### PyQt 5.15 (Python 3.11)
- testenv: py311-pyqt515
os: ubuntu-20.04
python: "3.11-dev"
+ ### PyQt 6.2 (Python 3.9)
+ - testenv: py39-pyqt62
+ os: ubuntu-20.04
+ python: 3.9
+ ### PyQt 6.3 (Python 3.9)
+ - testenv: py39-pyqt63
+ os: ubuntu-20.04
+ python: 3.9
+ ### PyQt 6.4 (Python 3.9)
+ # - testenv: py39-pyqt64
+ # os: ubuntu-20.04
+ # python: 3.9
### macOS Big Sur: PyQt 5.15 (Python 3.9 to match PyInstaller env)
- testenv: py39-pyqt515
os: macos-11
diff --git a/.pylintrc b/.pylintrc
index 225021f38..a018d9fbe 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -60,6 +60,8 @@ disable=locally-disabled,
missing-type-doc,
missing-param-doc,
useless-param-doc,
+ wrong-import-order, # FIXME:qt6 (lint)
+ ungrouped-imports, # FIXME:qt6 (lint)
[BASIC]
function-rgx=[a-z_][a-z0-9_]{2,50}$
@@ -74,7 +76,8 @@ no-docstring-rgx=(^_|^main$)
class-const-naming-style = snake_case
[FORMAT]
-max-line-length=88
+# FIXME:qt6 (lint) down to 88 again once we use black
+max-line-length=190
ignore-long-lines=(<?https?://|file://|^# Copyright 201\d|link:)
expected-line-ending-format=LF
diff --git a/MANIFEST.in b/MANIFEST.in
index 81bf824b7..a2603e147 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -32,6 +32,7 @@ include doc/qutebrowser.1.asciidoc
include doc/changelog.asciidoc
prune qutebrowser/3rdparty
exclude mypy.ini
+exclude pyrightconfig.json
exclude tox.ini
exclude qutebrowser/javascript/.eslintrc.yaml
exclude qutebrowser/javascript/.eslintignore
diff --git a/README.asciidoc b/README.asciidoc
index 651e0948b..4335a871c 100644
--- a/README.asciidoc
+++ b/README.asciidoc
@@ -83,15 +83,14 @@ Requirements
The following software and libraries are required to run qutebrowser:
* https://www.python.org/[Python] 3.7 or newer
-* https://www.qt.io/[Qt] 5.12.0 or newer (5.12 LTS or 5.15 recommended, Qt 6 is
- not supported yet) with the following modules:
+* https://www.qt.io/[Qt], either 6.2.0 or newer, or 5.15.0 or newer, with the following modules:
- QtCore / qtbase
- QtQuick (part of qtbase or qtdeclarative in some distributions)
- QtSQL (part of qtbase in some distributions)
- QtDBus (part of qtbase in some distributions; note that a connection to DBus at
runtime is optional)
- QtOpenGL
- - QtWebEngine, or
+ - QtWebEngine (if using Qt 5, 5.15.2 or newer), or
- alternatively QtWebKit (5.212) - **This is not recommended** due to known security
issues in QtWebKit, you most likely want to use qutebrowser with the
default QtWebEngine backend (based on Chromium) instead. Quoting the
@@ -99,8 +98,8 @@ The following software and libraries are required to run qutebrowser:
_[The latest QtWebKit] release is based on [an] old WebKit revision with known
unpatched vulnerabilities. Please use it carefully and avoid visiting untrusted
websites and using it for transmission of sensitive data._
-* https://www.riverbankcomputing.com/software/pyqt/intro[PyQt] 5.12.0 or newer
- for Python 3
+* https://www.riverbankcomputing.com/software/pyqt/intro[PyQt] 6.2.2 or newer
+ (Qt 6) or 5.15.0 or newer (Qt 5)
* https://palletsprojects.com/p/jinja/[jinja2]
* https://github.com/yaml/pyyaml[PyYAML]
diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc
index e3825de20..209042184 100644
--- a/doc/changelog.asciidoc
+++ b/doc/changelog.asciidoc
@@ -57,9 +57,12 @@ Removed
- Support for Python 3.6 is dropped, as it's been
https://discuss.python.org/t/python-3-6-rides-into-the-sunset/12964[end-of-life upstream]
since December 2021. Python 3.7.0 or newer is now required.
+- Support for Qt/PyQt before 5.15.0 and QtWebEngine before 5.15.2 are now
+ dropped, as older Qt versions are
+ https://endoflife.date/qt[end-of-life upstream] since mid/late 2020
+ (5.13/5.14) and late 2021 (5.12 LTS).
- It's planned to drop support for various legacy platforms and libraries which
are unsupported upstream, such as:
- * Qt before 5.15 LTS (plus adding support for Qt 6.2+)
* The QtWebKit backend
* macOS 10.14 (via Homebrew)
* 32-bit Windows (via Qt)
diff --git a/doc/contributing.asciidoc b/doc/contributing.asciidoc
index 70447d8c5..d99dc41ef 100644
--- a/doc/contributing.asciidoc
+++ b/doc/contributing.asciidoc
@@ -128,6 +128,9 @@ Currently, the following tox environments are available:
- untracked git files
- VCS conflict markers
- common spelling mistakes
+* http://mypy-lang.org/[mypy] for static type checking:
+ - `mypy-pyqt5` run mypy with PyQt5 installed
+ - `mypy-pyqt6` run mypy with PyQt6 installed
The default test suite is run with `tox`; the list of default
environments is obtained with `tox -l`.
@@ -153,7 +156,7 @@ smallest scope which makes sense. Most of the time, this will be line scope.
false-positives, let me know! I'm still tweaking the parameters.
-Running Specific Tests
+Running specific tests
~~~~~~~~~~~~~~~~~~~~~~
While you are developing you often don't want to run the full test
@@ -180,6 +183,15 @@ tox -e py37 -- tests/end2end/features/test_tabs_bdd.py -k undo
tox -e py37-cov -- tests/unit/browser/test_webelem.py
----
+Specifying the backend for tests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Tests automatically pick the backend based on what they manage to import. If
+you have both backends available and you would like the tests to be run with a
+specific one you can set either of a) the environment variable QUTE_TESTS_BACKEND
+, or b) the command line argument --qute-backend, to the desired backend
+(webkit/webengine).
+
Profiling
~~~~~~~~~
@@ -219,7 +231,8 @@ Useful websites
Some resources which might be handy:
-* https://doc.qt.io/qt-5/classes.html[The Qt5 reference]
+* https://doc.qt.io/qt-6/classes.html[The Qt 6 reference]
+* https://doc.qt.io/qt-5/classes.html[The Qt 5 reference]
* https://docs.python.org/3/library/index.html[The Python reference]
* https://httpbin.org/[httpbin, a test service for HTTP requests/responses]
* https://requestbin.com/[RequestBin, a service to inspect HTTP requests]
@@ -274,7 +287,7 @@ Other
Languages] (https://www.rfc-editor.org/errata_search.php?rfc=5646[Errata])
* https://www.w3.org/TR/CSS2/[Cascading Style Sheets Level 2 Revision 1 (CSS
2.1) Specification]
-* https://doc.qt.io/qt-5/stylesheet-reference.html[Qt Style Sheets Reference]
+* https://doc.qt.io/qt-6/stylesheet-reference.html[Qt Style Sheets Reference]
* https://mimesniff.spec.whatwg.org/[MIME Sniffing Standard]
* https://spec.whatwg.org/[WHATWG specifications]
* https://www.w3.org/html/wg/drafts/html/master/Overview.html[HTML 5.1 Nightly]
@@ -353,7 +366,7 @@ All objects can be printed by starting with the `--debug` flag and using the
The registry is mainly used for <<commands,command handlers>>, but it can
also be useful in places where using Qt's
-https://doc.qt.io/qt-5/signalsandslots.html[signals and slots] mechanism would
+https://doc.qt.io/qt-6/signalsandslots.html[signals and slots] mechanism would
be difficult.
Logging
@@ -600,11 +613,14 @@ This is mostly useful for qutebrowser maintainers to work around issues in Qt -
The hierarchy of widgets when QtWebEngine is involved looks like this:
- qutebrowser has a `WebEngineTab` object, which is its abstraction over QtWebKit/QtWebEngine.
-- The `WebEngineTab` has a `_widget` attribute, which is the https://doc.qt.io/qt-5/qwebengineview.html[QWebEngineView]
-- That view has a https://doc.qt.io/qt-5/qwebenginepage.html[QWebEnginePage] for everything which doesn't require rendering.
-- The view also has a layout with exactly one element (which also is its `focusProxy()`)
-- That element is the https://code.qt.io/cgit/qt/qtwebengine.git/tree/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp[RenderWidgetHostViewQtDelegateWidget] (it inherits https://doc.qt.io/qt-5/qquickwidget.html[QQuickWidget]) - also often referred to as RWHV or RWHVQDW. It can be obtained via `sip.cast(tab._widget.focusProxy(), QQuickWidget)`.
-- Calling `rootObject()` on that gives us the https://doc.qt.io/qt-5/qquickitem.html[QQuickItem] where Chromium renders into (?). With it, we can do things like `.setRotation(20)`.
+- The `WebEngineTab` has a `_widget` attribute, which is the https://doc.qt.io/qt-6/qwebengineview.html[QWebEngineView]
+- That view has a https://doc.qt.io/qt-6/qwebenginepage.html[QWebEnginePage] for everything which doesn't require rendering.
+- The view also has a layout with exactly one element (which also is its `focusProxy()`).
+ - Qt 5: That element is the https://code.qt.io/cgit/qt/qtwebengine.git/tree/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp?h=5.15[RenderWidgetHostViewQtDelegateWidget] (it inherits https://doc.qt.io/qt-6/qquickwidget.html[QQuickWidget]) - also often referred to as RWHV or RWHVQDW.
+ It can be obtained via `sip.cast(tab._widget.focusProxy(), QQuickWidget)`.
+ - Qt 6: That element is the https://code.qt.io/cgit/qt/qtwebengine.git/tree/src/webenginewidgets/api/qwebengineview.cpp[WebEngineQuickWidget] (it inherits https://doc.qt.io/qt-6/qquickwidget.html[QQuickWidget]).
+ It can be obtained via `tab._widget.focusProxy()`.
+- Calling `rootObject()` on that gives us the https://doc.qt.io/qt-6/qquickitem.html[QQuickItem] where Chromium renders into (?). With it, we can do things like `.setRotation(20)`.
Style conventions
-----------------
@@ -676,6 +692,41 @@ Return:
- `__magic__` methods
- other methods
- overrides of Qt methods
+* Type hinting: the qutebrowser codebase uses type hints liberally to enable
+ static type checking and autocompletion in editors.
+ - We use http://mypy-lang.org/[mypy] in CI jobs to perform static type
+ checking.
+ - Not all of the codebase is covered by type hints currently. We encourage
+ including type hints on all new code and even adding type hints to
+ existing code if you find yourself working on some that isn't already
+ covered. There are some module specific rules in the mypy config file,
+ `.mypy.ini`, to make type hints strictly required in some areas.
+ - More often than not mypy is correct when it raises issues. But don't be
+ afraid to add `# type: ignore[...]` statements or casts if you need to.
+ As an optional part of the language not all type information from third
+ parties is always correct. Mypy will raise a new issue if it spots an
+ "ignore" statement which is no longer needed because the underlying
+ issue has been resolved.
+ - One area where we have to take particular care is in code that deals
+ with differences between PyQt5 and PyQt6. We try to write most code in a
+ way that will work with either backend but when you need to deal with
+ differences you should use a pattern like:
++
+[source,python]
+----
+if machinery.IS_QT5:
+ ... # do PyQt5 specific implementation
+else:
+ # PyQt6
+ ... # do PyQt6 specific implementation
+----
++
+then you have to https://mypy.readthedocs.io/en/latest/command_line.html#cmdoption-mypy-always-true[tell]
+ mypy to treat `machinery.IS_QT5` as a constant value then run mypy twice to
+ cover both branches. There are a handful of variables in
+ `qutebrowser/qt/machinery.py` that mypy needs to know about. There are tox
+ jobs (`mypy-pyqt5` and `mypy-pyqt6`) that take care of telling mypy to use
+ them as constants.
Checklists
----------
diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc
index 0ba7b15a2..7f0abc71d 100644
--- a/doc/help/commands.asciidoc
+++ b/doc/help/commands.asciidoc
@@ -337,8 +337,13 @@ Remove a key from a dict.
[[config-diff]]
=== config-diff
+Syntax: +:config-diff [*--include-hidden*]+
+
Show all customized options.
+==== optional arguments
+* +*-i*+, +*--include-hidden*+: Also include internal qutebrowser settings.
+
[[config-edit]]
=== config-edit
Syntax: +:config-edit [*--no-source*]+
@@ -821,7 +826,7 @@ Show an error message in the statusbar.
* +'text'+: The text to show.
==== optional arguments
-* +*-r*+, +*--rich*+: Render the given text as https://doc.qt.io/qt-5/richtext-html-subset.html[Qt Rich Text].
+* +*-r*+, +*--rich*+: Render the given text as https://doc.qt.io/qt-6/richtext-html-subset.html[Qt Rich Text].
[[message-info]]
@@ -834,7 +839,7 @@ Show an info message in the statusbar.
* +'text'+: The text to show.
==== optional arguments
-* +*-r*+, +*--rich*+: Render the given text as https://doc.qt.io/qt-5/richtext-html-subset.html[Qt Rich Text].
+* +*-r*+, +*--rich*+: Render the given text as https://doc.qt.io/qt-6/richtext-html-subset.html[Qt Rich Text].
==== count
@@ -850,7 +855,7 @@ Show a warning message in the statusbar.
* +'text'+: The text to show.
==== optional arguments
-* +*-r*+, +*--rich*+: Render the given text as https://doc.qt.io/qt-5/richtext-html-subset.html[Qt Rich Text].
+* +*-r*+, +*--rich*+: Render the given text as https://doc.qt.io/qt-6/richtext-html-subset.html[Qt Rich Text].
[[messages]]
@@ -2176,7 +2181,7 @@ Syntax: +:debug-webaction 'action'+
Execute a webaction.
-Available actions: https://doc.qt.io/archives/qt-5.5/qwebpage.html#WebAction-enum (WebKit) https://doc.qt.io/qt-5/qwebenginepage.html#WebAction-enum (WebEngine)
+Available actions: https://doc.qt.io/archives/qt-5.5/qwebpage.html#WebAction-enum (WebKit) https://doc.qt.io/qt-6/qwebenginepage.html#WebAction-enum (WebEngine)
==== positional arguments
* +'action'+: The action to execute, e.g. MoveToNextChar.
diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc
index 8327ec048..29cde3b0f 100644
--- a/doc/help/settings.asciidoc
+++ b/doc/help/settings.asciidoc
@@ -118,6 +118,7 @@
|<<colors.webpage.darkmode.enabled,colors.webpage.darkmode.enabled>>|Render all web contents using a dark theme.
|<<colors.webpage.darkmode.grayscale.all,colors.webpage.darkmode.grayscale.all>>|Render all colors as grayscale.
|<<colors.webpage.darkmode.grayscale.images,colors.webpage.darkmode.grayscale.images>>|Desaturation factor for images in dark mode.
+|<<colors.webpage.darkmode.increase_text_contrast,colors.webpage.darkmode.increase_text_contrast>>|Increase text contrast by drawing an outline of the uninverted color.
|<<colors.webpage.darkmode.policy.images,colors.webpage.darkmode.policy.images>>|Which images to apply dark mode to.
|<<colors.webpage.darkmode.policy.page,colors.webpage.darkmode.policy.page>>|Which pages to apply dark mode to.
|<<colors.webpage.darkmode.threshold.background,colors.webpage.darkmode.threshold.background>>|Threshold for inverting background elements with dark mode.
@@ -1671,6 +1672,9 @@ Example configurations from Chromium's `chrome://flags`:
- "With selective inversion of everything": Combines the two variants
above.
+- "With increased text contrast": Set
+ `colors.webpage.darkmode.increase_text_contrast` (QtWebEngine 6.3+)
+
This setting requires a restart.
This setting is only available with the QtWebEngine backend.
@@ -1699,14 +1703,26 @@ If set to 0, images are left as-is. If set to 1, images are completely grayscale
This setting requires a restart.
-On QtWebEngine, this setting requires Qt 5.14 or newer.
-
-On QtWebKit, this setting is unavailable.
+This setting is only available with the QtWebEngine backend.
Type: <<types,Float>>
Default: +pass:[0.0]+
+[[colors.webpage.darkmode.increase_text_contrast]]
+=== colors.webpage.darkmode.increase_text_contrast
+Increase text contrast by drawing an outline of the uninverted color.
+
+This setting requires a restart.
+
+On QtWebEngine, this setting requires Qt 6.3 or newer.
+
+On QtWebKit, this setting is unavailable.
+
+Type: <<types,Bool>>
+
+Default: +pass:[false]+
+
[[colors.webpage.darkmode.policy.images]]
=== colors.webpage.darkmode.policy.images
Which images to apply dark mode to.
@@ -1733,9 +1749,7 @@ The underlying Chromium setting has been removed in QtWebEngine 5.15.3, thus thi
This setting requires a restart.
-On QtWebEngine, this setting requires Qt 5.14 or newer.
-
-On QtWebKit, this setting is unavailable.
+This setting is only available with the QtWebEngine backend.
Type: <<types,String>>
@@ -1754,9 +1768,7 @@ Note: This behavior is the opposite of `colors.webpage.darkmode.threshold.text`!
This setting requires a restart.
-On QtWebEngine, this setting requires Qt 5.14 or newer.
-
-On QtWebKit, this setting is unavailable.
+This setting is only available with the QtWebEngine backend.
Type: <<types,Int>>
@@ -1769,9 +1781,7 @@ Text colors with brightness below this threshold will be inverted, and above it
This setting requires a restart.
-On QtWebEngine, this setting requires Qt 5.14 or newer.
-
-On QtWebKit, this setting is unavailable.
+This setting is only available with the QtWebEngine backend.
Type: <<types,Int>>
@@ -1785,9 +1795,7 @@ The "auto" value is broken on QtWebEngine 5.15.2 due to a Qt bug. There, it will
This setting requires a restart.
-On QtWebEngine, this setting requires Qt 5.14 or newer.
-
-On QtWebKit, this setting is unavailable.
+This setting is only available with the QtWebEngine backend.
Type: <<types,String>>
@@ -2274,7 +2282,7 @@ Type: <<types,String>>
Valid values:
- * +always+: Always send the Referer.
+ * +always+: Always send the Referer. With QtWebEngine 6.2+, this value is unavailable and will act like `same-domain`.
* +never+: Never send the Referer. This is not recommended, as some sites may break.
* +same-domain+: Only send the Referer for the same domain. This will still protect your privacy, but shouldn't break any sites. With QtWebEngine, the referer will still be sent for other domains, but with stripped path information.
@@ -2579,8 +2587,6 @@ Allow websites to show notifications.
This setting supports link:configuring{outfilesuffix}#patterns[URL patterns].
-On QtWebEngine, this setting requires Qt 5.13 or newer.
-
Type: <<types,BoolAsk>>
Valid values:
@@ -2595,8 +2601,6 @@ Default: +pass:[ask]+
=== content.notifications.presenter
What notification presenter to use for web notifications.
Note that not all implementations support all features of notifications:
-- With PyQt 5.14, any setting other than `qt` does not support the `click` and
- `close` events, as well as the `tag` option to replace existing notifications.
- The `qt` and `systray` options only support showing one notification at the time
and ignore the `tag` option to replace existing notifications.
- The `herbe` option only supports showing one notification at the time and doesn't
@@ -2604,16 +2608,14 @@ Note that not all implementations support all features of notifications:
- The `messages` option doesn't show icons and doesn't support the `click` and
`close` events.
-On QtWebEngine, this setting requires Qt 5.14 or newer.
-
-On QtWebKit, this setting is unavailable.
+This setting is only available with the QtWebEngine backend.
Type: <<types,String>>
Valid values:
* +auto+: Tries `libnotify`, `systray` and `messages`, uses the first one available without showing error messages.
- * +qt+: Use Qt's native notification presenter, based on a system tray icon. Switching from or to this value requires a restart of qutebrowser. Recommended over `systray` on PyQt 5.14.
+ * +qt+: Use Qt's native notification presenter, based on a system tray icon. Switching from or to this value requires a restart of qutebrowser.
* +libnotify+: Shows messages via DBus in a libnotify-compatible way. If DBus isn't available, falls back to `systray` or `messages`, but shows an error message.
* +systray+: Use a notification presenter based on a systray icon. Falls back to `libnotify` or `messages` if not systray is available. This is a reimplementation of the `qt` setting value, but with the possibility to switch to it at runtime.
* +messages+: Show notifications as qutebrowser messages. Most notification features aren't available.
@@ -2629,9 +2631,7 @@ Note that with the `qt` presenter, origins are never shown.
This setting supports link:configuring{outfilesuffix}#patterns[URL patterns].
-On QtWebEngine, this setting requires Qt 5.14 or newer.
-
-On QtWebKit, this setting is unavailable.
+This setting is only available with the QtWebEngine backend.
Type: <<types,Bool>>
@@ -2684,9 +2684,7 @@ On Windows, if this setting is set to False, the system-wide animation setting i
This setting requires a restart.
-On QtWebEngine, this setting requires Qt 5.14 or newer.
-
-On QtWebKit, this setting is unavailable.
+This setting is only available with the QtWebEngine backend.
Type: <<types,Bool>>
@@ -3635,9 +3633,7 @@ On Linux, disabling this also disables Chromium's MPRIS integration.
This setting requires a restart.
-On QtWebEngine, this setting requires Qt 5.14 or newer.
-
-On QtWebKit, this setting is unavailable.
+This setting is only available with the QtWebEngine backend.
Type: <<types,Bool>>
@@ -3853,7 +3849,7 @@ Alternative process models use less resources, but decrease security and robustn
See the following pages for more details:
- https://www.chromium.org/developers/design-documents/process-models
- - https://doc.qt.io/qt-5/qtwebengine-features.html#process-models
+ - https://doc.qt.io/qt-6/qtwebengine-features.html#process-models
This setting requires a restart.
@@ -3950,7 +3946,7 @@ Default: +pass:[none]+
[[qt.highdpi]]
=== qt.highdpi
Turn on Qt HighDPI scaling.
-This is equivalent to setting QT_AUTO_SCREEN_SCALE_FACTOR=1 or QT_ENABLE_HIGHDPI_SCALING=1 (Qt >= 5.14) in the environment.
+This is equivalent to setting QT_ENABLE_HIGHDPI_SCALING=1 (Qt >= 5.14) in the environment.
It's off by default as it can cause issues with some bitmap fonts. As an alternative to this, it's possible to set font sizes and the `zoom.default` setting.
This setting requires a restart.
@@ -4033,8 +4029,6 @@ Default: +pass:[true]+
=== search.wrap
Wrap around at the top and bottom of the page when advancing through text matches using `:search-next` and `:search-prev`.
-On QtWebEngine, this setting requires Qt 5.14 or newer.
-
Type: <<types,Bool>>
Default: +pass:[true]+
@@ -4809,7 +4803,7 @@ When setting from a string, pass a json-like list, e.g. `["one", "two"]`.
|Proxy|A proxy URL, or `system`/`none`.
|QssColor|A color value supporting gradients.
-A value can be in one of the following formats: * `#RGB`/`#RRGGBB`/`#AARRGGBB`/`#RRRGGGBBB`/`#RRRRGGGGBBBB` * An SVG color name as specified in https://www.w3.org/TR/SVG/types.html#ColorKeywords[the W3C specification]. * transparent (no color) * `rgb(r, g, b)` / `rgba(r, g, b, a)` (values 0-255 or percentages) * `hsv(h, s, v)` / `hsva(h, s, v, a)` (values 0-255, hue 0-359) * A gradient as explained in https://doc.qt.io/qt-5/stylesheet-reference.html#list-of-property-types[the Qt documentation] under ``Gradient''
+A value can be in one of the following formats: * `#RGB`/`#RRGGBB`/`#AARRGGBB`/`#RRRGGGBBB`/`#RRRRGGGGBBBB` * An SVG color name as specified in https://www.w3.org/TR/SVG/types.html#ColorKeywords[the W3C specification]. * transparent (no color) * `rgb(r, g, b)` / `rgba(r, g, b, a)` (values 0-255 or percentages) * `hsv(h, s, v)` / `hsva(h, s, v, a)` (values 0-255, hue 0-359) * A gradient as explained in https://doc.qt.io/qt-6/stylesheet-reference.html#list-of-property-types[the Qt documentation] under ``Gradient''
|QtColor|A color value.
A value can be in one of the following formats: * `#RGB`/`#RRGGBB`/`#AARRGGBB`/`#RRRGGGBBB`/`#RRRRGGGGBBBB` * An SVG color name as specified in https://www.w3.org/TR/SVG/types.html#ColorKeywords[the W3C specification]. * transparent (no color) * `rgb(r, g, b)` / `rgba(r, g, b, a)` (values 0-255 or percentages) * `hsv(h, s, v)` / `hsva(h, s, v, a)` (values 0-255, hue 0-359)
diff --git a/doc/qutebrowser.1.asciidoc b/doc/qutebrowser.1.asciidoc
index 0f8a55680..9dc921acd 100644
--- a/doc/qutebrowser.1.asciidoc
+++ b/doc/qutebrowser.1.asciidoc
@@ -63,7 +63,7 @@ show it.
Which backend to use.
*--desktop-file-name* 'DESKTOP_FILE_NAME'::
- Set the base name of the desktop entry for this application. Used to set the app_id under Wayland. See https://doc.qt.io/qt-5/qguiapplication.html#desktopFileName-prop
+ Set the base name of the desktop entry for this application. Used to set the app_id under Wayland. See https://doc.qt.io/qt-6/qguiapplication.html#desktopFileName-prop
*--untrusted-args*::
Mark all following arguments as untrusted, which enforces that they are URLs/search terms (and not flags or commands)
diff --git a/misc/qutebrowser.spec b/misc/qutebrowser.spec
index e12e9a9b0..467994bab 100644
--- a/misc/qutebrowser.spec
+++ b/misc/qutebrowser.spec
@@ -82,7 +82,7 @@ def get_data_files():
def get_hidden_imports():
- imports = ['PyQt5.QtOpenGL', 'PyQt5._QOpenGLFunctions_2_0']
+ imports = [] if "PYINSTALLER_QT6" in os.environ else ['PyQt5.QtOpenGL']
for info in loader.walk_components():
imports.append(info.name)
return imports
diff --git a/misc/requirements/requirements-pyqt-5.12.txt b/misc/requirements/requirements-pyqt-5.12.txt
deleted file mode 100644
index 3e08c1598..000000000
--- a/misc/requirements/requirements-pyqt-5.12.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# This file is automatically generated by scripts/dev/recompile_requirements.py
-
-PyQt5==5.12.3 # rq.filter: < 5.13
-PyQt5-sip==12.11.1
-PyQtWebEngine==5.12.1 # rq.filter: < 5.13
diff --git a/misc/requirements/requirements-pyqt-5.12.txt-raw b/misc/requirements/requirements-pyqt-5.12.txt-raw
deleted file mode 100644
index f127ba42f..000000000
--- a/misc/requirements/requirements-pyqt-5.12.txt-raw
+++ /dev/null
@@ -1,4 +0,0 @@
-#@ filter: PyQt5 < 5.13
-#@ filter: PyQtWebEngine < 5.13
-PyQt5 >= 5.12, < 5.13
-PyQtWebEngine >= 5.12, < 5.13
diff --git a/misc/requirements/requirements-pyqt-5.13.txt b/misc/requirements/requirements-pyqt-5.13.txt
deleted file mode 100644
index ab5965e73..000000000
--- a/misc/requirements/requirements-pyqt-5.13.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# This file is automatically generated by scripts/dev/recompile_requirements.py
-
-PyQt5==5.13.2 # rq.filter: < 5.14
-PyQt5-sip==12.11.1
-PyQtWebEngine==5.13.2 # rq.filter: < 5.14
diff --git a/misc/requirements/requirements-pyqt-5.13.txt-raw b/misc/requirements/requirements-pyqt-5.13.txt-raw
deleted file mode 100644
index e60db7edb..000000000
--- a/misc/requirements/requirements-pyqt-5.13.txt-raw
+++ /dev/null
@@ -1,4 +0,0 @@
-#@ filter: PyQt5 < 5.14
-#@ filter: PyQtWebEngine < 5.14
-PyQt5 >= 5.13, < 5.14
-PyQtWebEngine >= 5.13, < 5.14
diff --git a/misc/requirements/requirements-pyqt-5.14.txt b/misc/requirements/requirements-pyqt-5.14.txt
deleted file mode 100644
index d7f9af1f9..000000000
--- a/misc/requirements/requirements-pyqt-5.14.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# This file is automatically generated by scripts/dev/recompile_requirements.py
-
-PyQt5==5.14.2 # rq.filter: < 5.15
-PyQt5-sip==12.11.1
-PyQtWebEngine==5.14.0 # rq.filter: < 5.15
diff --git a/misc/requirements/requirements-pyqt-5.14.txt-raw b/misc/requirements/requirements-pyqt-5.14.txt-raw
deleted file mode 100644
index 9dadfc846..000000000
--- a/misc/requirements/requirements-pyqt-5.14.txt-raw
+++ /dev/null
@@ -1,4 +0,0 @@
-#@ filter: PyQt5 < 5.15
-#@ filter: PyQtWebEngine < 5.15
-PyQt5 >= 5.14, < 5.15
-PyQtWebEngine >= 5.14, < 5.15
diff --git a/misc/requirements/requirements-pyqt-5.15.0.txt b/misc/requirements/requirements-pyqt-5.15.0.txt
deleted file mode 100644
index 4022b53af..000000000
--- a/misc/requirements/requirements-pyqt-5.15.0.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-# This file is automatically generated by scripts/dev/recompile_requirements.py
-
-PyQt5==5.15.0 # rq.filter: == 5.15.0
-PyQt5-sip==12.11.1
-PyQtWebEngine==5.15.0 # rq.filter: == 5.15.0
diff --git a/misc/requirements/requirements-pyqt-5.15.0.txt-raw b/misc/requirements/requirements-pyqt-5.15.0.txt-raw
deleted file mode 100644
index 12d6adb7d..000000000
--- a/misc/requirements/requirements-pyqt-5.15.0.txt-raw
+++ /dev/null
@@ -1,4 +0,0 @@
-#@ filter: PyQt5 == 5.15.0
-#@ filter: PyQtWebEngine == 5.15.0
-PyQt5 == 5.15.0
-PyQtWebEngine == 5.15.0
diff --git a/misc/requirements/requirements-pyqt-5.15.2.txt b/misc/requirements/requirements-pyqt-5.15.2.txt
new file mode 100644
index 000000000..986bb42c1
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-5.15.2.txt
@@ -0,0 +1,5 @@
+# This file is automatically generated by scripts/dev/recompile_requirements.py
+
+PyQt5==5.15.2 # rq.filter: == 5.15.2
+PyQt5-sip==12.10.1
+PyQtWebEngine==5.15.2 # rq.filter: == 5.15.2
diff --git a/misc/requirements/requirements-pyqt-5.15.2.txt-raw b/misc/requirements/requirements-pyqt-5.15.2.txt-raw
new file mode 100644
index 000000000..f8475fd8a
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-5.15.2.txt-raw
@@ -0,0 +1,4 @@
+#@ filter: PyQt5 == 5.15.2
+#@ filter: PyQtWebEngine == 5.15.2
+PyQt5 == 5.15.2
+PyQtWebEngine == 5.15.2
diff --git a/misc/requirements/requirements-pyqt-5.txt b/misc/requirements/requirements-pyqt-5.txt
new file mode 100644
index 000000000..1641b4fcd
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-5.txt
@@ -0,0 +1,7 @@
+# This file is automatically generated by scripts/dev/recompile_requirements.py
+
+PyQt5==5.15.6
+PyQt5-Qt5==5.15.2
+PyQt5-sip==12.10.1
+PyQtWebEngine==5.15.5
+PyQtWebEngine-Qt5==5.15.2
diff --git a/misc/requirements/requirements-pyqt-5.txt-raw b/misc/requirements/requirements-pyqt-5.txt-raw
new file mode 100644
index 000000000..9c6afbf16
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-5.txt-raw
@@ -0,0 +1,2 @@
+PyQt5
+PyQtWebEngine
diff --git a/misc/requirements/requirements-pyqt-6.2.txt b/misc/requirements/requirements-pyqt-6.2.txt
new file mode 100644
index 000000000..c41148a06
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-6.2.txt
@@ -0,0 +1,7 @@
+# This file is automatically generated by scripts/dev/recompile_requirements.py
+
+PyQt6==6.2.3
+PyQt6-Qt6==6.2.4
+PyQt6-sip==13.3.1
+PyQt6-WebEngine==6.2.1
+PyQt6-WebEngine-Qt6==6.2.4
diff --git a/misc/requirements/requirements-pyqt-6.2.txt-raw b/misc/requirements/requirements-pyqt-6.2.txt-raw
new file mode 100644
index 000000000..ea182a474
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-6.2.txt-raw
@@ -0,0 +1,4 @@
+PyQt6 >= 6.2, < 6.3
+PyQt6-Qt6 >= 6.2, < 6.3
+PyQt6-WebEngine >= 6.2, < 6.3
+PyQt6-WebEngine-Qt6 >= 6.2, < 6.3
diff --git a/misc/requirements/requirements-pyqt-6.3.txt b/misc/requirements/requirements-pyqt-6.3.txt
new file mode 100644
index 000000000..cdd830e00
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-6.3.txt
@@ -0,0 +1,7 @@
+# This file is automatically generated by scripts/dev/recompile_requirements.py
+
+PyQt6==6.3.1
+PyQt6-Qt6==6.3.1
+PyQt6-sip==13.4.0
+PyQt6-WebEngine==6.3.1
+PyQt6-WebEngine-Qt6==6.3.1
diff --git a/misc/requirements/requirements-pyqt-6.3.txt-raw b/misc/requirements/requirements-pyqt-6.3.txt-raw
new file mode 100644
index 000000000..b4fe4d66e
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-6.3.txt-raw
@@ -0,0 +1,4 @@
+PyQt6 >= 6.3, < 6.4
+PyQt6-Qt6 >= 6.3, < 6.4
+PyQt6-WebEngine >= 6.3, < 6.4
+PyQt6-WebEngine-Qt6 >= 6.3, < 6.4
diff --git a/misc/requirements/requirements-pyqt-6.4.txt b/misc/requirements/requirements-pyqt-6.4.txt
new file mode 100644
index 000000000..91f45c849
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-6.4.txt
@@ -0,0 +1,7 @@
+# This file is automatically generated by scripts/dev/recompile_requirements.py
+
+PyQt6==6.4.0
+PyQt6-Qt6==6.4.1
+PyQt6-sip==13.4.0
+PyQt6-WebEngine==6.4.0
+PyQt6-WebEngine-Qt6==6.4.1
diff --git a/misc/requirements/requirements-pyqt-6.4.txt-raw b/misc/requirements/requirements-pyqt-6.4.txt-raw
new file mode 100644
index 000000000..2de7ab852
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-6.4.txt-raw
@@ -0,0 +1,4 @@
+PyQt6 >= 6.4, < 6.5
+PyQt6-Qt6 >= 6.4, < 6.5
+PyQt6-WebEngine >= 6.4, < 6.5
+PyQt6-WebEngine-Qt6 >= 6.4, < 6.5
diff --git a/misc/requirements/requirements-pyqt-6.txt b/misc/requirements/requirements-pyqt-6.txt
new file mode 100644
index 000000000..cdd830e00
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-6.txt
@@ -0,0 +1,7 @@
+# This file is automatically generated by scripts/dev/recompile_requirements.py
+
+PyQt6==6.3.1
+PyQt6-Qt6==6.3.1
+PyQt6-sip==13.4.0
+PyQt6-WebEngine==6.3.1
+PyQt6-WebEngine-Qt6==6.3.1
diff --git a/misc/requirements/requirements-pyqt-6.txt-raw b/misc/requirements/requirements-pyqt-6.txt-raw
new file mode 100644
index 000000000..68a5db685
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-6.txt-raw
@@ -0,0 +1,4 @@
+PyQt6
+PyQt6-Qt6
+PyQt6-WebEngine
+PyQt6-WebEngine-Qt6
diff --git a/misc/requirements/requirements-qutebrowser.txt-raw b/misc/requirements/requirements-qutebrowser.txt-raw
index ab18a7caa..4c1d32ae7 100644
--- a/misc/requirements/requirements-qutebrowser.txt-raw
+++ b/misc/requirements/requirements-qutebrowser.txt-raw
@@ -2,6 +2,8 @@ Jinja2
PyYAML
## Only used on macOS to make borderless windows resizable
+# Not needed anymore with Qt 6.3, but we can't express that
+# here, and it won't hurt either.
## our recompile_requirements.py can't really deal with
## platform-specific dependencies unfortunately...
# pyobjc-core
diff --git a/pyrightconfig.json b/pyrightconfig.json
new file mode 100644
index 000000000..138687c53
--- /dev/null
+++ b/pyrightconfig.json
@@ -0,0 +1,10 @@
+{
+ "defineConstant": {
+ "USE_PYQT6": false,
+ "USE_PYQT5": true,
+ "USE_PYSIDE2": false,
+ "USE_PYSIDE6": false,
+ "IS_QT5": true,
+ "IS_QT6": false
+ }
+}
diff --git a/pytest.ini b/pytest.ini
index 05e5e3d76..ab46bd391 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -27,7 +27,6 @@ markers =
no_ci: Tests which should not run on CI.
qtwebengine_todo: Features still missing with QtWebEngine
qtwebengine_skip: Tests not applicable with QtWebEngine
- qtwebengine_notifications: Tests which need QtWebEngine notification support
qtwebkit_skip: Tests not applicable with QtWebKit
qtwebengine_flaky: Tests which are flaky (and currently skipped) with QtWebEngine
qtwebengine_mac_xfail: Tests which fail on macOS with QtWebEngine
@@ -35,58 +34,30 @@ markers =
no_invalid_lines: Don't fail on unparsable lines in end2end tests
fake_os: Fake utils.is_* to a fake operating system
unicode_locale: Tests which need a unicode locale to work
- js_headers: Sets JS headers dynamically on QtWebEngine (unsupported on some versions)
qtwebkit_pdf_imageformat_skip: Broken on QtWebKit with PDF image format plugin installed
qtwebkit_openssl3_skip: Broken due to cheroot bug with OpenSSL 3 on QtWebKit
windows_skip: Tests which should be skipped on Windows
+ qt5_only: Tests which should only run with Qt 5
+ qt6_only: Tests which should only run with Qt 6
+ qt5_xfail: Tests which fail with Qt 5
+ qt6_xfail: Tests which fail with Qt 6
qt_log_level_fail = WARNING
qt_log_ignore =
- ^SpellCheck: .*
- ^SetProcessDpiAwareness failed: .*
- ^QWindowsWindow::setGeometry(Dp)?: Unable to set geometry .*
- ^QProcess: Destroyed while process .* is still running\.
- ^"Method "GetAll" with signature "s" on interface "org\.freedesktop\.DBus\.Properties" doesn't exist
- ^"Method \\"GetAll\\" with signature \\"s\\" on interface \\"org\.freedesktop\.DBus\.Properties\\" doesn't exist\\n"
- ^propsReply "Method \\"GetAll\\" with signature \\"s\\" on interface \\"org\.freedesktop\.DBus\.Properties\\" doesn't exist\\n"
- ^nmReply "Method \\"GetDevices\\" with signature \\"\\" on interface \\"org\.freedesktop\.NetworkManager\\" doesn't exist\\n"
- ^"Object path cannot be empty"
- ^virtual void QSslSocketBackendPrivate::transmit\(\) SSL write failed with error: -9805
- ^virtual void QSslSocketBackendPrivate::transmit\(\) SSLRead failed with: -9805
- ^Type conversion already registered from type .*
- ^QNetworkReplyImplPrivate::error: Internal problem, this method must only be called once\.
- ^QWaitCondition: Destroyed while threads are still waiting
- ^QXcbXSettings::QXcbXSettings\(QXcbScreen\*\) Failed to get selection owner for XSETTINGS_S atom
+ # GitHub Actions
^QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to .*
- ^QObject::connect: Cannot connect \(null\)::stateChanged\(QNetworkSession::State\) to QNetworkReplyHttpImpl::_q_networkSessionStateChanged\(QNetworkSession::State\)
- ^QXcbClipboard: Cannot transfer data, no data available
- ^load glyph failed
- ^Error when parsing the netrc file
- ^Image of format '' blocked because it is not considered safe. If you are sure it is safe to do so, you can white-list the format by setting the environment variable QTWEBKIT_IMAGEFORMAT_WHITELIST=
- ^QPainter::end: Painter ended with \d+ saved states
- ^QSslSocket: cannot resolve .*
- ^QSslSocket: cannot call unresolved function .*
- ^Incompatible version of OpenSSL
- ^QQuickWidget::invalidateRenderControl could not make context current
- ^libpng warning: iCCP: known incorrect sRGB profile
- ^inotify_add_watch\(".*"\) failed: "No space left on device"
- ^QSettings::value: Empty key passed
- ^Icon theme ".*" not found
- ^Error receiving trust for a CA certificate
- ^QBackingStore::endPaint\(\) called with active painter.*
- ^QPaintDevice: Cannot destroy paint device that is being painted
- ^DirectWrite: CreateFontFaceFromHDC\(\) failed .*
- ^Attribute Qt::AA_ShareOpenGLContexts must be set before QCoreApplication is created\.
- ^QHttpNetworkConnectionPrivate::_q_hostLookupFinished could not de-queue request, failed to report HostNotFoundError
+ # test_on_focus_changed_issue1484 on macOS
^The available OpenGL surface format was either not version 3\.2 or higher or not a Core Profile.*
+ # tests/unit/mainwindow/test_messageview.py and
+ # tests/unit/mainwindow/statusbar/test_textbase.py::test_resize
+ # on Windows
+ ^QWindowsWindow::setGeometry(Dp)?: Unable to set geometry .*
+ # tests/unit/commands/test_userscripts.py::test_killed_command
+ # on Windows
+ ^QProcess: Destroyed while process .* is still running\.
xfail_strict = true
filterwarnings =
error
default:Test process .* failed to terminate!:UserWarning
- ignore:_SixMetaPathImporter\.exec_module\(\) not found; falling back to load_module\(\):ImportWarning
- ignore:VendorImporter\.find_spec\(\) not found; falling back to find_module\(\):ImportWarning
- ignore:_SixMetaPathImporter\.find_spec\(\) not found; falling back to find_module\(\):ImportWarning
- # https://github.com/ionelmc/python-hunter/issues/97
- ignore:The distutils\.sysconfig module is deprecated, use sysconfig instead:DeprecationWarning
# https://github.com/certifi/python-certifi/issues/170
ignore:path is deprecated\. Use files\(\) instead\. Refer to https.//importlib-resources\.readthedocs\.io/en/latest/using\.html#migrating-from-legacy for migration advice\.:DeprecationWarning:certifi.core
# https://github.com/HypothesisWorks/hypothesis/issues/3309
diff --git a/qutebrowser/api/config.py b/qutebrowser/api/config.py
index 19e2b3c3e..fd0890602 100644
--- a/qutebrowser/api/config.py
+++ b/qutebrowser/api/config.py
@@ -21,7 +21,7 @@
from typing import cast, Any
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.config import config
diff --git a/qutebrowser/api/downloads.py b/qutebrowser/api/downloads.py
index cd33f5709..85f5b8b91 100644
--- a/qutebrowser/api/downloads.py
+++ b/qutebrowser/api/downloads.py
@@ -23,7 +23,7 @@
import io
-from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QUrl
+from qutebrowser.qt.core import QObject, pyqtSignal, pyqtSlot, QUrl
from qutebrowser.browser import downloads, qtnetworkdownloads
from qutebrowser.utils import objreg
diff --git a/qutebrowser/app.py b/qutebrowser/app.py
index f74617133..db7eea608 100644
--- a/qutebrowser/app.py
+++ b/qutebrowser/app.py
@@ -46,9 +46,10 @@ import datetime
import argparse
from typing import Iterable, Optional
-from PyQt5.QtWidgets import QApplication, QWidget
-from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon
-from PyQt5.QtCore import pyqtSlot, QUrl, QObject, QEvent, pyqtSignal, Qt
+from qutebrowser.qt import machinery
+from qutebrowser.qt.widgets import QApplication, QWidget
+from qutebrowser.qt.gui import QDesktopServices, QPixmap, QIcon
+from qutebrowser.qt.core import pyqtSlot, QUrl, QObject, QEvent, pyqtSignal, Qt
import qutebrowser
from qutebrowser.commands import runners
@@ -149,7 +150,6 @@ def init(*, args: argparse.Namespace) -> None:
quitter.instance.shutting_down.connect(QApplication.closeAllWindows)
_init_icon()
- _init_pulseaudio()
loader.init()
loader.load_components()
@@ -195,27 +195,12 @@ def _init_icon():
objects.qapp.setWindowIcon(icon)
-def _init_pulseaudio():
- """Set properties for PulseAudio.
-
- WORKAROUND for https://bugreports.qt.io/browse/QTBUG-85363
-
- Affected Qt versions:
- - Older than 5.11 (which is unsupported)
- - 5.14.0 to 5.15.0 (inclusive)
-
- However, we set this on all versions so that qutebrowser's icon gets picked
- up as well.
- """
- for prop in ['application.name', 'application.icon_name']:
- os.environ['PULSE_PROP_OVERRIDE_' + prop] = 'qutebrowser'
-
-
def _process_args(args):
"""Open startpage etc. and process commandline args."""
if not args.override_restore:
sessions.load_default(args.session)
+ new_window = None
if not sessions.session_manager.did_load:
log.init.debug("Initializing main window...")
private = args.target == 'private-window'
@@ -226,15 +211,17 @@ def _process_args(args):
error.handle_fatal_exc(err, 'Cannot start in private mode',
no_err_windows=args.no_err_windows)
sys.exit(usertypes.Exit.err_init)
- window = mainwindow.MainWindow(private=private)
- if not args.nowindow:
- window.show()
- objects.qapp.setActiveWindow(window)
+
+ new_window = mainwindow.MainWindow(private=private)
process_pos_args(args.command)
_open_startpage()
_open_special_pages(args)
+ if new_window is not None and not args.nowindow:
+ new_window.show()
+ objects.qapp.setActiveWindow(new_window)
+
delta = datetime.datetime.now() - earlyinit.START_TIME
log.init.debug("Init finished after {}s".format(delta.total_seconds()))
@@ -258,26 +245,30 @@ def process_pos_args(args, via_ipc=False, cwd=None, target_arg=None):
if command_target in {'window', 'private-window'}:
command_target = 'tab-silent'
- win_id: Optional[int] = None
+ window: Optional[mainwindow.MainWindow] = None
if via_ipc and (not args or args == ['']):
- win_id = mainwindow.get_window(via_ipc=via_ipc,
- target=new_window_target)
- _open_startpage(win_id)
+ window = mainwindow.get_window(via_ipc=via_ipc, target=new_window_target)
+ _open_startpage(window)
+ window.show()
+ window.maybe_raise()
return
for cmd in args:
if cmd.startswith(':'):
- if win_id is None:
- win_id = mainwindow.get_window(via_ipc=via_ipc,
- target=command_target)
+ if window is None:
+ window = mainwindow.get_window(via_ipc=via_ipc, target=command_target)
+ # FIXME preserving old behavior, but we probably shouldn't be
+ # doing this...
+ # See https://github.com/qutebrowser/qutebrowser/issues/5094
+ window.maybe_raise()
+
log.init.debug("Startup cmd {!r}".format(cmd))
- commandrunner = runners.CommandRunner(win_id)
+ commandrunner = runners.CommandRunner(window.win_id)
commandrunner.run_safely(cmd[1:])
elif not cmd:
log.init.debug("Empty argument")
- win_id = mainwindow.get_window(via_ipc=via_ipc,
- target=new_window_target)
+ window = mainwindow.get_window(via_ipc=via_ipc, target=new_window_target)
else:
if via_ipc and target_arg and target_arg != 'auto':
open_target = target_arg
@@ -291,7 +282,7 @@ def process_pos_args(args, via_ipc=False, cwd=None, target_arg=None):
message.error("Error in startup argument '{}': {}".format(
cmd, e))
else:
- win_id = open_url(url, target=open_target, via_ipc=via_ipc)
+ window = open_url(url, target=open_target, via_ipc=via_ipc)
def open_url(url, target=None, no_raise=False, via_ipc=True):
@@ -304,39 +295,37 @@ def open_url(url, target=None, no_raise=False, via_ipc=True):
via_ipc: Whether the arguments were transmitted over IPC.
Return:
- ID of a window that was used to open URL
+ The MainWindow of a window that was used to open the URL.
"""
target = target or config.val.new_instance_open_target
background = target in {'tab-bg', 'tab-bg-silent'}
- win_id = mainwindow.get_window(via_ipc=via_ipc, target=target,
- no_raise=no_raise)
- tabbed_browser = objreg.get('tabbed-browser', scope='window',
- window=win_id)
+ window = mainwindow.get_window(via_ipc=via_ipc, target=target, no_raise=no_raise)
log.init.debug("About to open URL: {}".format(url.toDisplayString()))
- tabbed_browser.tabopen(url, background=background, related=False)
- return win_id
+ window.tabbed_browser.tabopen(url, background=background, related=False)
+ window.show()
+ window.maybe_raise()
+ return window
-def _open_startpage(win_id=None):
+def _open_startpage(window: Optional[mainwindow.MainWindow] = None) -> None:
"""Open startpage.
The startpage is never opened if the given windows are not empty.
Args:
- win_id: If None, open startpage in all empty windows.
+ window: If None, open startpage in all empty windows.
If set, open the startpage in the given window.
"""
- if win_id is not None:
- window_ids: Iterable[int] = [win_id]
+ if window is not None:
+ windows: Iterable[mainwindow.MainWindow] = [window]
else:
- window_ids = objreg.window_registry
- for cur_win_id in list(window_ids): # Copying as the dict could change
- tabbed_browser = objreg.get('tabbed-browser', scope='window',
- window=cur_win_id)
- if tabbed_browser.widget.count() == 0:
+ windows = objreg.window_registry.values()
+
+ for cur_window in list(windows): # Copying as the dict could change
+ if cur_window.tabbed_browser.widget.count() == 0:
log.init.debug("Opening start pages")
for url in config.val.url.start_pages:
- tabbed_browser.tabopen(url)
+ cur_window.tabbed_browser.tabopen(url)
def _open_special_pages(args):
@@ -369,8 +358,17 @@ def _open_special_pages(args):
'qute://warning/webkit'),
('session-warning-shown',
- qtutils.version_check('5.15', compiled=False),
+ True,
'qute://warning/sessions'),
+
+ ('sandboxing-warning-shown',
+ (
+ hasattr(sys, "frozen") and
+ utils.is_mac and
+ machinery.IS_QT6 and
+ os.environ.get("QTWEBENGINE_DISABLE_SANDBOX") == "1"
+ ),
+ 'qute://warning/sandboxing'),
]
if 'quickstart-done' not in general_sect:
@@ -432,10 +430,10 @@ def on_focus_changed(_old, new):
def open_desktopservices_url(url):
"""Handler to open a URL via QDesktopServices."""
target = config.val.new_instance_open_target
- win_id = mainwindow.get_window(via_ipc=True, target=target)
- tabbed_browser = objreg.get('tabbed-browser', scope='window',
- window=win_id)
- tabbed_browser.tabopen(url)
+ window = mainwindow.get_window(via_ipc=True, target=target)
+ window.tabbed_browser.tabopen(url)
+ window.show()
+ window.maybe_raise()
# This is effectively a @config.change_filter
@@ -563,7 +561,12 @@ class Application(QApplication):
self.launch_time = datetime.datetime.now()
self.focusObjectChanged.connect(self.on_focus_object_changed)
- self.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
+
+ try:
+ self.setAttribute(Qt.ApplicationAttribute.AA_UseHighDpiPixmaps, True)
+ except AttributeError:
+ # default and removed in Qt 6
+ pass
self.new_window.connect(self._on_new_window)
@@ -582,7 +585,7 @@ class Application(QApplication):
def event(self, e):
"""Handle macOS FileOpen events."""
- if e.type() != QEvent.FileOpen:
+ if e.type() != QEvent.Type.FileOpen:
return super().event(e)
url = e.url()
diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py
index 86c373a9a..95851b7f0 100644
--- a/qutebrowser/browser/browsertab.py
+++ b/qutebrowser/browser/browsertab.py
@@ -26,17 +26,17 @@ import dataclasses
from typing import (cast, TYPE_CHECKING, Any, Callable, Iterable, List, Optional,
Sequence, Set, Type, Union, Tuple)
-from PyQt5.QtCore import (pyqtSignal, pyqtSlot, QUrl, QObject, QSizeF, Qt,
+from qutebrowser.qt.core import (pyqtSignal, pyqtSlot, QUrl, QObject, QSizeF, Qt,
QEvent, QPoint, QRect)
-from PyQt5.QtGui import QKeyEvent, QIcon, QPixmap
-from PyQt5.QtWidgets import QWidget, QApplication, QDialog
-from PyQt5.QtPrintSupport import QPrintDialog, QPrinter
-from PyQt5.QtNetwork import QNetworkAccessManager
+from qutebrowser.qt.gui import QKeyEvent, QIcon, QPixmap
+from qutebrowser.qt.widgets import QApplication, QWidget
+from qutebrowser.qt.printsupport import QPrintDialog, QPrinter
+from qutebrowser.qt.network import QNetworkAccessManager
if TYPE_CHECKING:
- from PyQt5.QtWebKit import QWebHistory, QWebHistoryItem
- from PyQt5.QtWebKitWidgets import QWebPage, QWebView
- from PyQt5.QtWebEngineWidgets import (
+ from qutebrowser.qt.webkit import QWebHistory, QWebHistoryItem
+ from qutebrowser.qt.webkitwidgets import QWebPage, QWebView
+ from qutebrowser.qt.webenginewidgets import (
QWebEngineHistory, QWebEngineHistoryItem, QWebEnginePage, QWebEngineView)
from qutebrowser.keyinput import modeman
@@ -153,7 +153,6 @@ class AbstractAction:
"""Attribute ``action`` of AbstractTab for Qt WebActions."""
- action_class: Type[Union['QWebPage', 'QWebEnginePage']]
action_base: Type[Union['QWebPage.WebAction', 'QWebEnginePage.WebAction']]
def __init__(self, tab: 'AbstractTab') -> None:
@@ -170,10 +169,10 @@ class AbstractAction:
def run_string(self, name: str) -> None:
"""Run a webaction based on its name."""
- member = getattr(self.action_class, name, None)
- if not isinstance(member, self.action_base):
- raise WebTabError("{} is not a valid web action!".format(name))
- assert member is not None # for mypy
+ try:
+ member = getattr(self.action_base, name)
+ except AttributeError:
+ raise WebTabError(f"{name} is not a valid web action!")
self._widget.triggerPageAction(member)
def show_source(self, pygments: bool = False) -> None:
@@ -226,13 +225,37 @@ class AbstractAction:
self._tab.dump_async(show_source_cb)
-class AbstractPrinting:
+class AbstractPrinting(QObject):
"""Attribute ``printing`` of AbstractTab for printing the page."""
- def __init__(self, tab: 'AbstractTab') -> None:
+ printing_finished = pyqtSignal(bool)
+ pdf_printing_finished = pyqtSignal(str, bool) # filename, ok
+
+ def __init__(self, tab: 'AbstractTab', parent: QWidget = None) -> None:
+ super().__init__(parent)
self._widget = cast(_WidgetType, None)
self._tab = tab
+ self._dialog: Optional[QPrintDialog] = None
+ self.printing_finished.connect(self._on_printing_finished)
+ self.pdf_printing_finished.connect(self._on_pdf_printing_finished)
+
+ @pyqtSlot(bool)
+ def _on_printing_finished(self, ok: bool) -> None:
+ # Only reporting error here, as the user has feedback from the dialog
+ # (and probably their printer) already.
+ if not ok:
+ message.error("Printing failed!")
+ if self._dialog is not None:
+ self._dialog.deleteLater()
+ self._dialog = None
+
+ @pyqtSlot(str, bool)
+ def _on_pdf_printing_finished(self, path: str, ok: bool) -> None:
+ if ok:
+ message.info(f"Printed to {path}")
+ else:
+ message.error(f"Printing to {path} failed!")
def check_pdf_support(self) -> None:
"""Check whether writing to PDFs is supported.
@@ -250,41 +273,23 @@ class AbstractPrinting:
"""
raise NotImplementedError
- def to_pdf(self, filename: str) -> bool:
+ def to_pdf(self, filename: str) -> None:
"""Print the tab to a PDF with the given filename."""
raise NotImplementedError
- def to_printer(self, printer: QPrinter,
- callback: Callable[[bool], None] = None) -> None:
+ def to_printer(self, printer: QPrinter) -> None:
"""Print the tab.
Args:
printer: The QPrinter to print to.
- callback: Called with a boolean
- (True if printing succeeded, False otherwise)
"""
raise NotImplementedError
def show_dialog(self) -> None:
"""Print with a QPrintDialog."""
- def print_callback(ok: bool) -> None:
- """Called when printing finished."""
- if not ok:
- message.error("Printing failed!")
- diag.deleteLater()
-
- def do_print() -> None:
- """Called when the dialog was closed."""
- self.to_printer(diag.printer(), print_callback)
-
- diag = QPrintDialog(self._tab)
- if utils.is_mac:
- # For some reason we get a segfault when using open() on macOS
- ret = diag.exec()
- if ret == QDialog.Accepted:
- do_print()
- else:
- diag.open(do_print)
+ self._dialog = dialog = QPrintDialog(self._tab)
+ self._dialog.open(lambda: self.to_printer(dialog.printer()))
+ # Gets cleaned up in on_printing_finished
@dataclasses.dataclass
@@ -603,9 +608,9 @@ class AbstractCaret(QObject):
def _follow_enter(self, tab: bool) -> None:
"""Follow a link by faking an enter press."""
if tab:
- self._tab.fake_key_press(Qt.Key_Enter, modifier=Qt.ControlModifier)
+ self._tab.fake_key_press(Qt.Key.Key_Enter, modifier=Qt.KeyboardModifier.ControlModifier)
else:
- self._tab.fake_key_press(Qt.Key_Enter)
+ self._tab.fake_key_press(Qt.Key.Key_Enter)
def follow_selected(self, *, tab: bool = False) -> None:
raise NotImplementedError
@@ -1238,10 +1243,10 @@ class AbstractTab(QWidget):
def fake_key_press(self,
key: Qt.Key,
- modifier: Qt.KeyboardModifier = Qt.NoModifier) -> None:
+ modifier: Qt.KeyboardModifier = Qt.KeyboardModifier.NoModifier) -> None:
"""Send a fake key event to this tab."""
- press_evt = QKeyEvent(QEvent.KeyPress, key, modifier, 0, 0, 0)
- release_evt = QKeyEvent(QEvent.KeyRelease, key, modifier,
+ press_evt = QKeyEvent(QEvent.Type.KeyPress, key, modifier, 0, 0, 0)
+ release_evt = QKeyEvent(QEvent.Type.KeyRelease, key, modifier,
0, 0, 0)
self.send_event(press_evt)
self.send_event(release_evt)
@@ -1315,8 +1320,8 @@ class AbstractTab(QWidget):
def __repr__(self) -> str:
try:
qurl = self.url()
- url = qurl.toDisplayString(
- QUrl.EncodeUnicode) # type: ignore[arg-type]
+ as_unicode = QUrl.ComponentFormattingOption.EncodeUnicode
+ url = qurl.toDisplayString(as_unicode) # type: ignore[arg-type]
except (AttributeError, RuntimeError) as exc:
url = '<{}>'.format(exc.__class__.__name__)
else:
diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py
index f9c4bb8e1..84f217a38 100644
--- a/qutebrowser/browser/commands.py
+++ b/qutebrowser/browser/commands.py
@@ -24,8 +24,8 @@ import shlex
import functools
from typing import cast, Callable, Dict, Union, Optional
-from PyQt5.QtWidgets import QApplication, QTabBar
-from PyQt5.QtCore import Qt, QUrl, QEvent, QUrlQuery
+from qutebrowser.qt.widgets import QApplication, QTabBar
+from qutebrowser.qt.core import Qt, QUrl, QEvent, QUrlQuery
from qutebrowser.commands import userscripts, runners
from qutebrowser.api import cmdutils
@@ -70,9 +70,7 @@ class CommandDispatcher:
raise cmdutils.CommandError("Private windows are unavailable with "
"the single-process process model.")
- new_window = mainwindow.MainWindow(private=private)
- new_window.show()
- return new_window.tabbed_browser
+ return mainwindow.MainWindow(private=private).tabbed_browser
def _count(self) -> int:
"""Convenience method to get the widget count."""
@@ -109,8 +107,15 @@ class CommandDispatcher:
raise cmdutils.CommandError("No WebView available yet!")
return widget
- def _open(self, url, tab=False, background=False, window=False,
- related=False, private=None):
+ def _open(
+ self,
+ url: QUrl,
+ tab: bool = False,
+ background: bool = False,
+ window: bool = False,
+ related: bool = False,
+ private: Optional[bool] = None,
+ ) -> None:
"""Helper function to open a page.
Args:
@@ -123,13 +128,15 @@ class CommandDispatcher:
"""
urlutils.raise_cmdexc_if_invalid(url)
tabbed_browser = self._tabbed_browser
- cmdutils.check_exclusive((tab, background, window, private), 'tbwp')
+ cmdutils.check_exclusive((tab, background, window, private or False), 'tbwp')
if window and private is None:
private = self._tabbed_browser.is_private
if window or private:
+ assert isinstance(private, bool)
tabbed_browser = self._new_tabbed_browser(private)
tabbed_browser.tabopen(url)
+ tabbed_browser.window().show()
elif tab:
tabbed_browser.tabopen(url, background=False, related=related)
elif background:
@@ -192,21 +199,21 @@ class CommandDispatcher:
what's configured in 'tabs.select_on_remove'.
Return:
- QTabBar.SelectLeftTab, QTabBar.SelectRightTab, or None if no change
+ QTabBar.SelectionBehavior.SelectLeftTab, QTabBar.SelectionBehavior.SelectRightTab, or None if no change
should be made.
"""
cmdutils.check_exclusive((prev, next_, opposite), 'pno')
if prev:
- return QTabBar.SelectLeftTab
+ return QTabBar.SelectionBehavior.SelectLeftTab
elif next_:
- return QTabBar.SelectRightTab
+ return QTabBar.SelectionBehavior.SelectRightTab
elif opposite:
conf_selection = config.val.tabs.select_on_remove
- if conf_selection == QTabBar.SelectLeftTab:
- return QTabBar.SelectRightTab
- elif conf_selection == QTabBar.SelectRightTab:
- return QTabBar.SelectLeftTab
- elif conf_selection == QTabBar.SelectPreviousTab:
+ if conf_selection == QTabBar.SelectionBehavior.SelectLeftTab:
+ return QTabBar.SelectionBehavior.SelectRightTab
+ elif conf_selection == QTabBar.SelectionBehavior.SelectRightTab:
+ return QTabBar.SelectionBehavior.SelectLeftTab
+ elif conf_selection == QTabBar.SelectionBehavior.SelectPreviousTab:
raise cmdutils.CommandError(
"-o is not supported with 'tabs.select_on_remove' set to "
"'last-used'!")
@@ -403,14 +410,17 @@ class CommandDispatcher:
except browsertab.WebTabError as e:
raise cmdutils.CommandError(e)
- # The new tab could be in a new tabbed_browser (e.g. because of
- # tabs.tabs_are_windows being set)
if window or private:
new_tabbed_browser = self._new_tabbed_browser(
private=self._tabbed_browser.is_private or private)
else:
new_tabbed_browser = self._tabbed_browser
+
newtab = new_tabbed_browser.tabopen(background=bg)
+ new_tabbed_browser.window().show()
+
+ # The new tab could be in a new tabbed_browser (e.g. because of
+ # tabs.tabs_are_windows being set)
new_tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=newtab.win_id)
idx = new_tabbed_browser.widget.indexOf(newtab)
@@ -498,6 +508,8 @@ class CommandDispatcher:
"The window with id {} is not private".format(win_id))
tabbed_browser.tabopen(self._current_url())
+ tabbed_browser.window().show()
+
if not keep:
self._tabbed_browser.close_tab(self._current_widget(),
add_undo=False,
@@ -706,9 +718,9 @@ class CommandDispatcher:
assert what in ['url', 'pretty-url'], what
if what == 'pretty-url':
- flags = QUrl.RemovePassword | QUrl.DecodeReserved
+ flags = QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.DecodeReserved
else:
- flags = QUrl.RemovePassword | QUrl.FullyEncoded
+ flags = QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded
url = QUrl(self._current_url())
url_query = QUrlQuery()
@@ -1200,7 +1212,7 @@ class CommandDispatcher:
except qtutils.QtValueError:
pass
else:
- env['QUTE_URL'] = url.toString(QUrl.FullyEncoded)
+ env['QUTE_URL'] = url.toString(QUrl.ComponentFormattingOption.FullyEncoded)
try:
runner = userscripts.run_async(
@@ -1330,8 +1342,8 @@ class CommandDispatcher:
current page's url.
"""
if url is None:
- url = self._current_url().toString(QUrl.RemovePassword |
- QUrl.FullyEncoded)
+ url = self._current_url().toString(QUrl.UrlFormattingOption.RemovePassword |
+ QUrl.ComponentFormattingOption.FullyEncoded)
try:
objreg.get('bookmark-manager').delete(url)
except KeyError:
@@ -1774,8 +1786,8 @@ class CommandDispatcher:
raise cmdutils.CommandError(str(e))
for keyinfo in sequence:
- press_event = keyinfo.to_event(QEvent.KeyPress)
- release_event = keyinfo.to_event(QEvent.KeyRelease)
+ press_event = keyinfo.to_event(QEvent.Type.KeyPress)
+ release_event = keyinfo.to_event(QEvent.Type.KeyRelease)
if global_:
window = QApplication.focusWindow()
@@ -1882,9 +1894,9 @@ class CommandDispatcher:
if not window.isFullScreen():
window.state_before_fullscreen = window.windowState()
if enter:
- window.setWindowState(window.windowState() | Qt.WindowFullScreen)
+ window.setWindowState(window.windowState() | Qt.WindowState.WindowFullScreen)
else:
- window.setWindowState(window.windowState() ^ Qt.WindowFullScreen)
+ window.setWindowState(window.windowState() ^ Qt.WindowState.WindowFullScreen)
log.misc.debug('state before fullscreen: {}'.format(
debug.qflags_key(Qt, window.state_before_fullscreen)))
diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py
index 32bfd2693..8ce0ca1b2 100644
--- a/qutebrowser/browser/downloads.py
+++ b/qutebrowser/browser/downloads.py
@@ -30,7 +30,7 @@ import tempfile
import enum
from typing import Any, Dict, IO, List, MutableSequence, Optional, Union
-from PyQt5.QtCore import (pyqtSlot, pyqtSignal, Qt, QObject, QModelIndex,
+from qutebrowser.qt.core import (pyqtSlot, pyqtSignal, Qt, QObject, QModelIndex,
QTimer, QAbstractListModel, QUrl)
from qutebrowser.browser import pdfjs
@@ -45,7 +45,7 @@ class ModelRole(enum.IntEnum):
"""Custom download model roles."""
- item = Qt.UserRole
+ item = Qt.ItemDataRole.UserRole
# Remember the last used directory
@@ -188,7 +188,7 @@ def get_filename_question(*, suggested_filename, url, parent=None):
q.title = "Save file to:"
q.text = "Please enter a location for <b>{}</b>".format(
html.escape(url.toDisplayString()))
- q.url = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ q.url = url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
q.mode = usertypes.PromptMode.download
q.completed.connect(q.deleteLater)
q.default = _path_suggestion(suggested_filename)
@@ -1266,10 +1266,10 @@ class DownloadModel(QAbstractListModel):
idx = self.index(self.rowCount() - 1)
return idx
- def headerData(self, section, orientation, role=Qt.DisplayRole):
+ def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole):
"""Simple constant header."""
- if (section == 0 and orientation == Qt.Horizontal and
- role == Qt.DisplayRole):
+ if (section == 0 and orientation == Qt.Orientation.Horizontal and
+ role == Qt.ItemDataRole.DisplayRole):
return "Downloads"
else:
return ""
@@ -1283,15 +1283,15 @@ class DownloadModel(QAbstractListModel):
return None
item = self[index.row()]
- if role == Qt.DisplayRole:
+ if role == Qt.ItemDataRole.DisplayRole:
data: Any = str(item)
- elif role == Qt.ForegroundRole:
+ elif role == Qt.ItemDataRole.ForegroundRole:
data = item.get_status_color('fg')
- elif role == Qt.BackgroundRole:
+ elif role == Qt.ItemDataRole.BackgroundRole:
data = item.get_status_color('bg')
elif role == ModelRole.item:
data = item
- elif role == Qt.ToolTipRole:
+ elif role == Qt.ItemDataRole.ToolTipRole:
if item.error_msg is None:
data = None
else:
@@ -1303,11 +1303,11 @@ class DownloadModel(QAbstractListModel):
def flags(self, index):
"""Override flags so items aren't selectable.
- The default would be Qt.ItemIsEnabled | Qt.ItemIsSelectable.
+ The default would be Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable.
"""
if not index.isValid():
- return Qt.ItemFlags()
- return Qt.ItemIsEnabled | Qt.ItemNeverHasChildren
+ return Qt.ItemFlag.NoItemFlags
+ return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemNeverHasChildren
def rowCount(self, parent=QModelIndex()):
"""Get count of active downloads."""
diff --git a/qutebrowser/browser/downloadview.py b/qutebrowser/browser/downloadview.py
index 8187a1002..da0763b76 100644
--- a/qutebrowser/browser/downloadview.py
+++ b/qutebrowser/browser/downloadview.py
@@ -22,8 +22,8 @@
import functools
from typing import Callable, MutableSequence, Tuple, Union
-from PyQt5.QtCore import pyqtSlot, QSize, Qt
-from PyQt5.QtWidgets import QListView, QSizePolicy, QMenu, QStyleFactory
+from qutebrowser.qt.core import pyqtSlot, QSize, Qt
+from qutebrowser.qt.widgets import QListView, QSizePolicy, QMenu, QStyleFactory
from qutebrowser.browser import downloads
from qutebrowser.config import stylesheet
@@ -62,11 +62,11 @@ class DownloadView(QListView):
if not utils.is_mac:
self.setStyle(QStyleFactory.create('Fusion'))
stylesheet.set_register(self)
- self.setResizeMode(QListView.Adjust)
- self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
- self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
- self.setFocusPolicy(Qt.NoFocus)
- self.setFlow(QListView.LeftToRight)
+ self.setResizeMode(QListView.ResizeMode.Adjust)
+ self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
+ self.setSizePolicy(QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Fixed)
+ self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
+ self.setFlow(QListView.Flow.LeftToRight)
self.setSpacing(1)
self._menu = None
model.rowsInserted.connect(self._update_geometry)
@@ -74,7 +74,7 @@ class DownloadView(QListView):
model.dataChanged.connect(self._update_geometry)
self.setModel(model)
self.setWrapping(True)
- self.setContextMenuPolicy(Qt.CustomContextMenu)
+ self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.customContextMenuRequested.connect(self.show_context_menu)
self.clicked.connect(self.on_clicked)
diff --git a/qutebrowser/browser/eventfilter.py b/qutebrowser/browser/eventfilter.py
index 0b5fab096..616798f9b 100644
--- a/qutebrowser/browser/eventfilter.py
+++ b/qutebrowser/browser/eventfilter.py
@@ -19,11 +19,11 @@
"""Event handling for a browser tab."""
-from PyQt5.QtCore import QObject, QEvent, Qt, QTimer
+from qutebrowser.qt import machinery
+from qutebrowser.qt.core import QObject, QEvent, Qt, QTimer
from qutebrowser.config import config
-from qutebrowser.utils import message, log, usertypes, qtutils
-from qutebrowser.misc import objects
+from qutebrowser.utils import log, message, usertypes
from qutebrowser.keyinput import modeman
@@ -48,7 +48,7 @@ class ChildEventFilter(QObject):
def eventFilter(self, obj, event):
"""Act on ChildAdded events."""
- if event.type() == QEvent.ChildAdded:
+ if event.type() == QEvent.Type.ChildAdded:
child = event.child()
log.misc.debug("{} got new child {}, installing filter"
.format(obj, child))
@@ -58,7 +58,7 @@ class ChildEventFilter(QObject):
assert obj is self._widget
child.installEventFilter(self._filter)
- elif event.type() == QEvent.ChildRemoved:
+ elif event.type() == QEvent.Type.ChildRemoved:
child = event.child()
log.misc.debug("{}: removed child {}".format(obj, child))
@@ -81,10 +81,9 @@ class TabEventFilter(QObject):
super().__init__(parent)
self._tab = tab
self._handlers = {
- QEvent.MouseButtonPress: self._handle_mouse_press,
- QEvent.MouseButtonRelease: self._handle_mouse_release,
- QEvent.Wheel: self._handle_wheel,
- QEvent.KeyRelease: self._handle_key_release,
+ QEvent.Type.MouseButtonPress: self._handle_mouse_press,
+ QEvent.Type.MouseButtonRelease: self._handle_mouse_release,
+ QEvent.Type.Wheel: self._handle_wheel,
}
self._ignore_wheel_event = False
self._check_insertmode_on_release = False
@@ -99,10 +98,13 @@ class TabEventFilter(QObject):
True if the event should be filtered, False otherwise.
"""
is_rocker_gesture = (config.val.input.mouse.rocker_gestures and
- e.buttons() == Qt.LeftButton | Qt.RightButton)
+ e.buttons() == Qt.MouseButton.LeftButton | Qt.MouseButton.RightButton)
- if e.button() in [Qt.XButton1, Qt.XButton2] or is_rocker_gesture:
- self._mousepress_backforward(e)
+ if e.button() in [Qt.MouseButton.XButton1, Qt.MouseButton.XButton2] or is_rocker_gesture:
+ if not machinery.IS_QT6:
+ self._mousepress_backforward(e)
+ # FIXME:qt6 For some reason, this doesn't filter the action on
+ # Qt 6...
return True
self._ignore_wheel_event = True
@@ -112,7 +114,7 @@ class TabEventFilter(QObject):
log.mouse.warning("Ignoring invalid click at {}".format(pos))
return False
- if e.button() != Qt.NoButton:
+ if e.button() != Qt.MouseButton.NoButton:
self._tab.elements.find_at_pos(pos, self._mousepress_insertmode_cb)
return False
@@ -150,7 +152,7 @@ class TabEventFilter(QObject):
if mode == usertypes.KeyMode.hint:
return True
- elif e.modifiers() & Qt.ControlModifier:
+ elif e.modifiers() & Qt.KeyboardModifier.ControlModifier:
if mode == usertypes.KeyMode.passthrough:
return False
@@ -170,21 +172,6 @@ class TabEventFilter(QObject):
return False
- def _handle_key_release(self, e):
- """Ignore repeated key release events going to the website.
-
- WORKAROUND for https://bugreports.qt.io/browse/QTBUG-77208
-
- Args:
- e: The QKeyEvent.
-
- Return:
- True if the event should be filtered, False otherwise.
- """
- return (e.isAutoRepeat() and
- not qtutils.version_check('5.14', compiled=False) and
- objects.backend == usertypes.Backend.QtWebEngine)
-
def _mousepress_insertmode_cb(self, elem):
"""Check if the clicked element is editable."""
if elem is None:
@@ -240,17 +227,17 @@ class TabEventFilter(QObject):
True if the event should be filtered, False otherwise.
"""
if (not config.val.input.mouse.back_forward_buttons and
- e.button() in [Qt.XButton1, Qt.XButton2]):
+ e.button() in [Qt.MouseButton.XButton1, Qt.MouseButton.XButton2]):
# Back and forward on mice are disabled
return
- if e.button() in [Qt.XButton1, Qt.LeftButton]:
+ if e.button() in [Qt.MouseButton.XButton1, Qt.MouseButton.LeftButton]:
# Back button on mice which have it, or rocker gesture
if self._tab.history.can_go_back():
self._tab.history.back()
else:
message.error("At beginning of history.")
- elif e.button() in [Qt.XButton2, Qt.RightButton]:
+ elif e.button() in [Qt.MouseButton.XButton2, Qt.MouseButton.RightButton]:
# Forward button on mice which have it, or rocker gesture
if self._tab.history.can_go_forward():
self._tab.history.forward()
diff --git a/qutebrowser/browser/greasemonkey.py b/qutebrowser/browser/greasemonkey.py
index a0bff89fd..a0cdf0fcc 100644
--- a/qutebrowser/browser/greasemonkey.py
+++ b/qutebrowser/browser/greasemonkey.py
@@ -29,7 +29,7 @@ import textwrap
import dataclasses
from typing import cast, List, Sequence, Tuple, Optional
-from PyQt5.QtCore import pyqtSignal, QObject, QUrl
+from qutebrowser.qt.core import pyqtSignal, QObject, QUrl
from qutebrowser.utils import (log, standarddir, jinja, objreg, utils,
javascript, urlmatch, version, usertypes, message)
@@ -145,7 +145,7 @@ class GreasemonkeyScript:
def needs_document_end_workaround(self):
"""Check whether to force @run-at document-end.
- This needs to be done on QtWebEngine (since Qt 5.12) for known-broken scripts.
+ This needs to be done on QtWebEngine for known-broken scripts.
On Qt 5.12, accessing the DOM isn't possible with "@run-at
document-start". It was documented to be impossible before, but seems
@@ -270,7 +270,7 @@ class GreasemonkeyMatcher:
def __init__(self, url):
self._url = url
- self._url_string = url.toString(QUrl.FullyEncoded)
+ self._url_string = url.toString(QUrl.ComponentFormattingOption.FullyEncoded)
self.is_greaseable = url.scheme() in self.GREASEABLE_SCHEMES
def _match_pattern(self, pattern):
diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py
index ed933e10c..8fe75f271 100644
--- a/qutebrowser/browser/hints.py
+++ b/qutebrowser/browser/hints.py
@@ -30,8 +30,8 @@ from string import ascii_lowercase
from typing import (TYPE_CHECKING, Callable, Dict, Iterable, Iterator, List, Mapping,
MutableSequence, Optional, Sequence, Set)
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, Qt, QUrl
-from PyQt5.QtWidgets import QLabel
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QObject, Qt, QUrl
+from qutebrowser.qt.widgets import QLabel
from qutebrowser.config import config, configexc
from qutebrowser.keyinput import modeman, modeparsers, basekeyparser
@@ -92,12 +92,12 @@ class HintLabel(QLabel):
self._context = context
self.elem = elem
- self.setTextFormat(Qt.RichText)
+ self.setTextFormat(Qt.TextFormat.RichText)
# Make sure we can style the background via a style sheet, and we don't
# get any extra text indent from Qt.
# The real stylesheet lives in mainwindow.py for performance reasons..
- self.setAttribute(Qt.WA_StyledBackground, True)
+ self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
self.setIndent(0)
self._context.tab.contents_size_changed.connect(self._move_to_elem)
@@ -252,9 +252,9 @@ class HintActions:
sel = (context.target == Target.yank_primary and
utils.supports_selection())
- flags = QUrl.FullyEncoded | QUrl.RemovePassword
+ flags = QUrl.ComponentFormattingOption.FullyEncoded | QUrl.UrlFormattingOption.RemovePassword
if url.scheme() == 'mailto':
- flags |= QUrl.RemoveScheme # type: ignore[operator]
+ flags |= QUrl.UrlFormattingOption.RemoveScheme # type: ignore[operator]
urlstr = url.toString(flags)
new_content = urlstr
@@ -276,14 +276,14 @@ class HintActions:
def run_cmd(self, url: QUrl, context: HintContext) -> None:
"""Run the command based on a hint URL."""
- urlstr = url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ urlstr = url.toString(QUrl.ComponentFormattingOption.FullyEncoded) # type: ignore[arg-type]
args = context.get_args(urlstr)
commandrunner = runners.CommandRunner(self._win_id)
commandrunner.run_safely(' '.join(args))
def preset_cmd_text(self, url: QUrl, context: HintContext) -> None:
"""Preset a commandline text based on a hint URL."""
- flags = QUrl.FullyEncoded
+ flags = QUrl.ComponentFormattingOption.FullyEncoded
urlstr = url.toDisplayString(flags) # type: ignore[arg-type]
args = context.get_args(urlstr)
text = ' '.join(args)
@@ -325,7 +325,7 @@ class HintActions:
cmd = context.args[0]
args = context.args[1:]
- flags = QUrl.FullyEncoded
+ flags = QUrl.ComponentFormattingOption.FullyEncoded
env = {
'QUTE_MODE': 'hints',
@@ -356,7 +356,8 @@ class HintActions:
url: The URL to open as a QUrl.
context: The HintContext to use.
"""
- urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
+ urlstr = url.toString(
+ QUrl.ComponentFormattingOption.FullyEncoded | QUrl.UrlFormattingOption.RemovePassword)
args = context.get_args(urlstr)
commandrunner = runners.CommandRunner(self._win_id)
commandrunner.run_safely('spawn ' + ' '.join(args))
diff --git a/qutebrowser/browser/history.py b/qutebrowser/browser/history.py
index 595bd1c03..fa0e3e173 100644
--- a/qutebrowser/browser/history.py
+++ b/qutebrowser/browser/history.py
@@ -25,8 +25,8 @@ import contextlib
import pathlib
from typing import cast, Mapping, MutableSequence, Optional
-from PyQt5.QtCore import pyqtSlot, QUrl, QObject, pyqtSignal
-from PyQt5.QtWidgets import QProgressDialog, QApplication
+from qutebrowser.qt.core import pyqtSlot, QUrl, QObject, pyqtSignal
+from qutebrowser.qt.widgets import QProgressDialog, QApplication
from qutebrowser.config import config
from qutebrowser.api import cmdutils
@@ -435,10 +435,10 @@ class WebHistory(sql.SqlTable):
}, replace=True)
def _format_url(self, url):
- return url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ return url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
def _format_completion_url(self, url):
- return url.toString(QUrl.RemovePassword)
+ return url.toString(QUrl.UrlFormattingOption.RemovePassword)
@cmdutils.register()
diff --git a/qutebrowser/browser/inspector.py b/qutebrowser/browser/inspector.py
index 0eafa0536..dcf718552 100644
--- a/qutebrowser/browser/inspector.py
+++ b/qutebrowser/browser/inspector.py
@@ -24,9 +24,9 @@ import binascii
import enum
from typing import cast, Optional, Any
-from PyQt5.QtWidgets import QWidget
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent
-from PyQt5.QtGui import QCloseEvent
+from qutebrowser.qt.widgets import QWidget
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QObject, QEvent
+from qutebrowser.qt.gui import QCloseEvent
from qutebrowser.browser import eventfilter
from qutebrowser.config import configfiles, config
@@ -74,7 +74,7 @@ class _EventFilter(QObject):
def eventFilter(self, _obj: QObject, event: QEvent) -> bool:
"""Translate mouse presses to a clicked signal."""
- if event.type() == QEvent.MouseButtonPress:
+ if event.type() == QEvent.Type.MouseButtonPress:
self.clicked.emit()
return False
diff --git a/qutebrowser/browser/navigate.py b/qutebrowser/browser/navigate.py
index 6217c8d00..148f0f6e9 100644
--- a/qutebrowser/browser/navigate.py
+++ b/qutebrowser/browser/navigate.py
@@ -23,7 +23,7 @@ import re
import posixpath
from typing import Optional, Set
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.browser import webelem
from qutebrowser.config import config
@@ -42,24 +42,24 @@ class Error(Exception):
# of information. (host and path use FullyDecoded by default)
_URL_SEGMENTS = [
('host',
- lambda url: url.host(QUrl.FullyEncoded),
- lambda url, host: url.setHost(host, QUrl.StrictMode)),
+ lambda url: url.host(QUrl.ComponentFormattingOption.FullyEncoded),
+ lambda url, host: url.setHost(host, QUrl.ParsingMode.StrictMode)),
('port',
lambda url: str(url.port()) if url.port() > 0 else '',
lambda url, x: url.setPort(int(x))),
('path',
- lambda url: url.path(QUrl.FullyEncoded),
- lambda url, path: url.setPath(path, QUrl.StrictMode)),
+ lambda url: url.path(QUrl.ComponentFormattingOption.FullyEncoded),
+ lambda url, path: url.setPath(path, QUrl.ParsingMode.StrictMode)),
('query',
- lambda url: url.query(QUrl.FullyEncoded),
- lambda url, query: url.setQuery(query, QUrl.StrictMode)),
+ lambda url: url.query(QUrl.ComponentFormattingOption.FullyEncoded),
+ lambda url, query: url.setQuery(query, QUrl.ParsingMode.StrictMode)),
('anchor',
- lambda url: url.fragment(QUrl.FullyEncoded),
- lambda url, fragment: url.setFragment(fragment, QUrl.StrictMode)),
+ lambda url: url.fragment(QUrl.ComponentFormattingOption.FullyEncoded),
+ lambda url, fragment: url.setFragment(fragment, QUrl.ParsingMode.StrictMode)),
]
@@ -130,14 +130,14 @@ def path_up(url, count):
count: The number of levels to go up in the url.
"""
urlutils.ensure_valid(url)
- url = url.adjusted(QUrl.RemoveFragment | QUrl.RemoveQuery)
- path = url.path(QUrl.FullyEncoded)
+ url = url.adjusted(QUrl.UrlFormattingOption.RemoveFragment | QUrl.UrlFormattingOption.RemoveQuery)
+ path = url.path(QUrl.ComponentFormattingOption.FullyEncoded)
if not path or path == '/':
raise Error("Can't go up!")
for _i in range(0, min(count, path.count('/'))):
path = posixpath.join(path, posixpath.pardir)
path = posixpath.normpath(path)
- url.setPath(path, QUrl.StrictMode)
+ url.setPath(path, QUrl.ParsingMode.StrictMode)
return url
@@ -146,7 +146,7 @@ def strip(url, count):
if count != 1:
raise Error("Count is not supported when stripping URL components")
urlutils.ensure_valid(url)
- return url.adjusted(QUrl.RemoveFragment | QUrl.RemoveQuery)
+ return url.adjusted(QUrl.UrlFormattingOption.RemoveFragment | QUrl.UrlFormattingOption.RemoveQuery)
def _find_prevnext(prev, elems):
@@ -219,10 +219,10 @@ def prevnext(*, browsertab, win_id, baseurl, prev=False,
if window:
new_window = mainwindow.MainWindow(
private=cur_tabbed_browser.is_private)
- new_window.show()
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=new_window.win_id)
tabbed_browser.tabopen(url, background=False)
+ new_window.show()
elif tab:
cur_tabbed_browser.tabopen(url, background=background)
else:
diff --git a/qutebrowser/browser/network/pac.py b/qutebrowser/browser/network/pac.py
index be2ec3093..c372c6eea 100644
--- a/qutebrowser/browser/network/pac.py
+++ b/qutebrowser/browser/network/pac.py
@@ -23,11 +23,11 @@ import sys
import functools
from typing import Optional
-from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QUrl
-from PyQt5.QtNetwork import (QNetworkProxy, QNetworkRequest, QHostInfo,
+from qutebrowser.qt.core import QObject, pyqtSignal, pyqtSlot, QUrl
+from qutebrowser.qt.network import (QNetworkProxy, QNetworkRequest, QHostInfo,
QNetworkReply, QNetworkAccessManager,
QHostAddress)
-from PyQt5.QtQml import QJSEngine, QJSValue
+from qutebrowser.qt.qml import QJSEngine, QJSValue
from qutebrowser.utils import log, utils, qtutils, resources
@@ -109,10 +109,10 @@ class _PACContext(QObject):
host: hostname to resolve.
"""
ips = QHostInfo.fromName(host)
- if ips.error() != QHostInfo.NoError or not ips.addresses():
+ if ips.error() != QHostInfo.HostInfoError.NoError or not ips.addresses():
err_f = "Failed to resolve host during PAC evaluation: {}"
log.network.info(err_f.format(host))
- return QJSValue(QJSValue.NullValue)
+ return QJSValue(QJSValue.SpecialValue.NullValue)
else:
return ips.addresses()[0].toString()
@@ -123,7 +123,7 @@ class _PACContext(QObject):
Return the server IP address of the current machine, as a string in
the dot-separated integer format.
"""
- return QHostAddress(QHostAddress.LocalHost).toString()
+ return QHostAddress(QHostAddress.SpecialAddress.LocalHost).toString()
class PACResolver:
@@ -150,17 +150,17 @@ class PACResolver:
if len(config) != 1:
raise ParseProxyError("Invalid number of parameters for " +
"DIRECT")
- return QNetworkProxy(QNetworkProxy.NoProxy)
+ return QNetworkProxy(QNetworkProxy.ProxyType.NoProxy)
elif config[0] == "PROXY":
if len(config) != 2:
raise ParseProxyError("Invalid number of parameters for PROXY")
host, port = PACResolver._parse_proxy_host(config[1])
- return QNetworkProxy(QNetworkProxy.HttpProxy, host, port)
+ return QNetworkProxy(QNetworkProxy.ProxyType.HttpProxy, host, port)
elif config[0] in ["SOCKS", "SOCKS5"]:
if len(config) != 2:
raise ParseProxyError("Invalid number of parameters for SOCKS")
host, port = PACResolver._parse_proxy_host(config[1])
- return QNetworkProxy(QNetworkProxy.Socks5Proxy, host, port)
+ return QNetworkProxy(QNetworkProxy.ProxyType.Socks5Proxy, host, port)
else:
err = "Unknown proxy type: {}"
raise ParseProxyError(err.format(config[0]))
@@ -184,7 +184,7 @@ class PACResolver:
"""
self._engine = QJSEngine()
- self._engine.installExtensions(QJSEngine.ConsoleExtension)
+ self._engine.installExtensions(QJSEngine.Extension.ConsoleExtension)
self._ctx = _PACContext(self._engine)
self._engine.globalObject().setProperty(
@@ -215,12 +215,12 @@ class PACResolver:
qtutils.ensure_valid(query.url())
if from_file:
- string_flags = QUrl.PrettyDecoded
+ string_flags = QUrl.ComponentFormattingOption.PrettyDecoded
else:
- string_flags = QUrl.RemoveUserInfo # type: ignore[assignment]
+ string_flags = QUrl.UrlFormattingOption.RemoveUserInfo # type: ignore[assignment]
if query.url().scheme() == 'https':
- string_flags |= QUrl.RemovePath # type: ignore[assignment]
- string_flags |= QUrl.RemoveQuery # type: ignore[assignment]
+ string_flags |= QUrl.UrlFormattingOption.RemovePath # type: ignore[assignment]
+ string_flags |= QUrl.UrlFormattingOption.RemoveQuery # type: ignore[assignment]
result = self._resolver.call([query.url().toString(string_flags),
query.peerHostName()])
@@ -255,7 +255,7 @@ class PACFetcher(QObject):
# WORKAROUND for a hang when messages are printed, see our
# NetworkAccessManager subclass for details.
self._manager: Optional[QNetworkAccessManager] = QNetworkAccessManager()
- self._manager.setProxy(QNetworkProxy(QNetworkProxy.NoProxy))
+ self._manager.setProxy(QNetworkProxy(QNetworkProxy.ProxyType.NoProxy))
self._pac = None
self._error_message = None
self._reply = None
@@ -275,7 +275,7 @@ class PACFetcher(QObject):
@pyqtSlot()
def _finish(self):
assert self._reply is not None
- if self._reply.error() != QNetworkReply.NoError:
+ if self._reply.error() != QNetworkReply.NetworkError.NoError:
error = "Can't fetch PAC file from URL, error code {}: {}"
self._error_message = error.format(
self._reply.error(), self._reply.errorString())
@@ -337,4 +337,4 @@ class PACFetcher(QObject):
# Later NetworkManager.createRequest will detect this and display
# an error message.
error_host = "pac-resolve-error.qutebrowser.invalid"
- return [QNetworkProxy(QNetworkProxy.HttpProxy, error_host, 9)]
+ return [QNetworkProxy(QNetworkProxy.ProxyType.HttpProxy, error_host, 9)]
diff --git a/qutebrowser/browser/network/proxy.py b/qutebrowser/browser/network/proxy.py
index 2c0187837..3261d0d86 100644
--- a/qutebrowser/browser/network/proxy.py
+++ b/qutebrowser/browser/network/proxy.py
@@ -19,8 +19,8 @@
"""Handling of proxies."""
-from PyQt5.QtCore import QUrl, pyqtSlot
-from PyQt5.QtNetwork import QNetworkProxy, QNetworkProxyFactory
+from qutebrowser.qt.core import QUrl, pyqtSlot
+from qutebrowser.qt.network import QNetworkProxy, QNetworkProxyFactory
from qutebrowser.config import config, configtypes
from qutebrowser.utils import message, usertypes, urlutils, utils
@@ -73,11 +73,11 @@ class ProxyFactory(QNetworkProxyFactory):
return None
def _set_capabilities(self, proxy):
- if proxy.type() == QNetworkProxy.NoProxy:
+ if proxy.type() == QNetworkProxy.ProxyType.NoProxy:
return
capabilities = proxy.capabilities()
- lookup_cap = QNetworkProxy.HostNameLookupCapability
+ lookup_cap = QNetworkProxy.Capability.HostNameLookupCapability
if config.val.content.proxy_dns_requests:
capabilities |= lookup_cap
else:
@@ -97,7 +97,7 @@ class ProxyFactory(QNetworkProxyFactory):
if proxy is configtypes.SYSTEM_PROXY:
# On Linux, use "export http_proxy=socks5://host:port" to manually
# set system proxy.
- # ref. https://doc.qt.io/qt-5/qnetworkproxyfactory.html#systemProxyForQuery
+ # ref. https://doc.qt.io/qt-6/qnetworkproxyfactory.html#systemProxyForQuery
proxies = QNetworkProxyFactory.systemProxyForQuery(query)
elif isinstance(proxy, pac.PACFetcher):
if objects.backend == usertypes.Backend.QtWebEngine:
diff --git a/qutebrowser/browser/pdfjs.py b/qutebrowser/browser/pdfjs.py
index f8b000807..737a9cc87 100644
--- a/qutebrowser/browser/pdfjs.py
+++ b/qutebrowser/browser/pdfjs.py
@@ -22,7 +22,7 @@
import os
-from PyQt5.QtCore import QUrl, QUrlQuery
+from qutebrowser.qt.core import QUrl, QUrlQuery
from qutebrowser.utils import resources, javascript, jinja, standarddir, log
from qutebrowser.config import config
@@ -96,7 +96,7 @@ def _generate_pdfjs_script(filename):
url.setQuery(url_query)
js_url = javascript.to_js(
- url.toString(QUrl.FullyEncoded)) # type: ignore[arg-type]
+ url.toString(QUrl.ComponentFormattingOption.FullyEncoded)) # type: ignore[arg-type]
return jinja.js_environment.from_string("""
document.addEventListener("DOMContentLoaded", function() {
@@ -245,7 +245,7 @@ def get_main_url(filename: str, original_url: QUrl) -> QUrl:
query = QUrlQuery()
query.addQueryItem('filename', filename) # read from our JS
query.addQueryItem('file', '') # to avoid pdfjs opening the default PDF
- urlstr = original_url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ urlstr = original_url.toString(QUrl.ComponentFormattingOption.FullyEncoded) # type: ignore[arg-type]
query.addQueryItem('source', urlstr)
url.setQuery(query)
return url
diff --git a/qutebrowser/browser/qtnetworkdownloads.py b/qutebrowser/browser/qtnetworkdownloads.py
index a720402f5..242565a39 100644
--- a/qutebrowser/browser/qtnetworkdownloads.py
+++ b/qutebrowser/browser/qtnetworkdownloads.py
@@ -26,9 +26,9 @@ import functools
import dataclasses
from typing import Dict, IO, Optional
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QTimer, QUrl
-from PyQt5.QtWidgets import QApplication
-from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, QTimer, QUrl
+from qutebrowser.qt.widgets import QApplication
+from qutebrowser.qt.network import QNetworkRequest, QNetworkReply, QNetworkAccessManager
from qutebrowser.config import config, websettings
from qutebrowser.utils import message, usertypes, log, urlutils, utils, debug, objreg
@@ -62,12 +62,8 @@ class DownloadItem(downloads.AbstractDownloadItem):
As soon as we know the file object, we copy self._buffer over and the next
readyRead will write to the real file object.
- Class attributes:
- _MAX_REDIRECTS: The maximum redirection count.
-
Attributes:
_retry_info: A _RetryInfo instance.
- _redirects: How many time we were redirected already.
_buffer: A BytesIO object to buffer incoming data until we know the
target file.
_read_timer: A Timer which reads the QNetworkReply into self._buffer
@@ -82,7 +78,6 @@ class DownloadItem(downloads.AbstractDownloadItem):
arg 0: The new DownloadItem
"""
- _MAX_REDIRECTS = 10
adopt_download = pyqtSignal(object) # DownloadItem
def __init__(self, reply, manager):
@@ -102,7 +97,6 @@ class DownloadItem(downloads.AbstractDownloadItem):
self._read_timer = usertypes.Timer(self, name='download-read-timer')
self._read_timer.setInterval(500)
self._read_timer.timeout.connect(self._on_read_timer_timeout)
- self._redirects = 0
self._url = reply.url()
self._init_reply(reply)
@@ -123,10 +117,12 @@ class DownloadItem(downloads.AbstractDownloadItem):
if self._reply is None:
log.downloads.debug("Reply gone while dying")
return
+
self._reply.downloadProgress.disconnect()
self._reply.finished.disconnect()
- self._reply.error.disconnect()
+ self._reply.errorOccurred.disconnect()
self._reply.readyRead.disconnect()
+
with log.hide_qt_warning('QNetworkReplyImplPrivate::error: Internal '
'problem, this method must only be called '
'once.'):
@@ -135,11 +131,22 @@ class DownloadItem(downloads.AbstractDownloadItem):
self._reply.deleteLater()
self._reply = None
if self.fileobj is not None:
+ pos = self.fileobj.tell()
+ log.downloads.debug(f"File position at error: {pos}")
try:
self.fileobj.close()
except OSError:
log.downloads.exception("Error while closing file object")
+ if pos == 0:
+ # Emtpy remaining file
+ filename = self._get_open_filename()
+ log.downloads.debug(f"Removing empty file at {filename}")
+ try:
+ os.remove(filename)
+ except OSError:
+ log.downloads.exception("Error while removing empty file")
+
def _init_reply(self, reply):
"""Set a new reply and connect its signals.
@@ -150,11 +157,14 @@ class DownloadItem(downloads.AbstractDownloadItem):
self.successful = False
self._reply = reply
reply.setReadBufferSize(16 * 1024 * 1024) # 16 MB
+
reply.downloadProgress.connect(self.stats.on_download_progress)
reply.finished.connect(self._on_reply_finished)
- reply.error.connect(self._on_reply_error)
+ reply.errorOccurred.connect(self._on_reply_error)
reply.readyRead.connect(self._on_ready_read)
reply.metaDataChanged.connect(self._on_meta_data_changed)
+ reply.redirected.connect(self._on_redirected)
+
self._retry_info = _RetryInfo(request=reply.request(),
manager=reply.manager())
if not self.fileobj:
@@ -162,9 +172,16 @@ class DownloadItem(downloads.AbstractDownloadItem):
# We could have got signals before we connected slots to them.
# Here no signals are connected to the DownloadItem yet, so we use a
# singleShot QTimer to emit them after they are connected.
- if reply.error() != QNetworkReply.NoError:
+ if reply.error() != QNetworkReply.NetworkError.NoError:
QTimer.singleShot(0, lambda: self._die(reply.errorString()))
+ @pyqtSlot(QUrl)
+ def _on_redirected(self, url):
+ if self._reply is None:
+ log.downloads.warning(f"redirected: REPLY GONE -> {url}")
+ else:
+ log.downloads.debug(f"redirected: {self._reply.url()} -> {url}")
+
def _do_cancel(self):
self._read_timer.stop()
if self._reply is not None:
@@ -286,7 +303,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
self.fileobj.write(self._reply.readAll())
if self._autoclose:
self.fileobj.close()
- self.successful = self._reply.error() == QNetworkReply.NoError
+ self.successful = self._reply.error() == QNetworkReply.NetworkError.NoError
self._reply.close()
self._reply.deleteLater()
self._reply = None
@@ -307,9 +324,6 @@ class DownloadItem(downloads.AbstractDownloadItem):
return
self._read_timer.stop()
self.stats.finish()
- is_redirected = self._handle_redirect()
- if is_redirected:
- return
log.downloads.debug("Reply finished, fileobj {}".format(self.fileobj))
if self.fileobj is not None:
# We can do a "delayed" write immediately to empty the buffer and
@@ -334,7 +348,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
@pyqtSlot('QNetworkReply::NetworkError')
def _on_reply_error(self, code):
"""Handle QNetworkReply errors."""
- if code == QNetworkReply.OperationCanceledError:
+ if code == QNetworkReply.NetworkError.OperationCanceledError:
return
if self._reply is None:
@@ -364,48 +378,6 @@ class DownloadItem(downloads.AbstractDownloadItem):
for key, value in self._reply.rawHeaderPairs():
self.raw_headers[bytes(key)] = bytes(value)
- def _handle_redirect(self):
- """Handle an HTTP redirect.
-
- Return:
- True if the download was redirected, False otherwise.
- """
- assert self._reply is not None
- redirect = self._reply.attribute(
- QNetworkRequest.RedirectionTargetAttribute)
- if redirect is None or redirect.isEmpty():
- return False
- new_url = self._reply.url().resolved(redirect)
- new_request = self._reply.request()
- if new_url == new_request.url():
- return False
-
- if self._redirects > self._MAX_REDIRECTS:
- self._die("Maximum redirection count reached!")
- self.delete()
- return True # so on_reply_finished aborts
-
- log.downloads.debug("{}: Handling redirect".format(self))
- self._redirects += 1
- new_request.setUrl(new_url)
-
- old_reply = self._reply
- assert old_reply is not None
- old_reply.finished.disconnect(self._on_reply_finished)
-
- self._read_timer.stop()
- self._reply = None
- if self.fileobj is not None:
- self.fileobj.seek(0)
-
- log.downloads.debug("redirected: {} -> {}".format(
- old_reply.url(), new_request.url()))
- new_reply = old_reply.manager().get(new_request)
- self._init_reply(new_reply)
-
- old_reply.deleteLater()
- return True
-
def _uses_nam(self, nam):
"""Check if this download uses the given QNetworkAccessManager."""
assert self._retry_info is not None
@@ -422,8 +394,17 @@ class DownloadManager(downloads.AbstractDownloadManager):
Attributes:
_networkmanager: A NetworkManager for generic downloads.
+
+ Class attributes:
+ _MAX_REDIRECTS: The maximum redirection count.
"""
+ # Same as many browsers
+ # https://fetch.spec.whatwg.org/#http-redirect-fetch
+ # https://source.chromium.org/chromium/chromium/src/+/main:net/url_request/url_request.h;l=97;drc=3c19a2edb96d3d5b56a7481349a357fdbdf8ecf0
+ # https://stackoverflow.com/questions/9384474/in-chrome-how-many-redirects-are-too-many
+ _MAX_REDIRECTS = 20
+
def __init__(self, parent=None):
super().__init__(parent)
self._networkmanager = networkmanager.NetworkManager(
@@ -447,11 +428,19 @@ class DownloadManager(downloads.AbstractDownloadManager):
return None
req = QNetworkRequest(url)
- user_agent = websettings.user_agent(url)
- req.setHeader(QNetworkRequest.UserAgentHeader, user_agent)
+ user_agent = websettings.user_agent(url)
+ req.setHeader(QNetworkRequest.KnownHeaders.UserAgentHeader, user_agent)
if not cache:
- req.setAttribute(QNetworkRequest.CacheSaveControlAttribute, False)
+ req.setAttribute(QNetworkRequest.Attribute.CacheSaveControlAttribute, False)
+
+ # Needed for Qt 5, default on Qt 6
+ # We don't set this on the QNAM because QtWebKit handles redirects manually.
+ req.setAttribute(
+ QNetworkRequest.Attribute.RedirectPolicyAttribute,
+ QNetworkRequest.RedirectPolicy.NoLessSafeRedirectPolicy,
+ )
+ req.setMaximumRedirectsAllowed(self._MAX_REDIRECTS)
return self.get_request(req, **kwargs)
@@ -511,8 +500,8 @@ class DownloadManager(downloads.AbstractDownloadManager):
"""
# WORKAROUND for Qt corrupting data loaded from cache:
# https://bugreports.qt.io/browse/QTBUG-42757
- request.setAttribute(QNetworkRequest.CacheLoadControlAttribute,
- QNetworkRequest.AlwaysNetwork)
+ request.setAttribute(QNetworkRequest.Attribute.CacheLoadControlAttribute,
+ QNetworkRequest.CacheLoadControl.AlwaysNetwork)
if suggested_fn is None:
suggested_fn = self._get_suggested_filename(request)
diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py
index 6bf9fc5d7..77be4ffda 100644
--- a/qutebrowser/browser/qutescheme.py
+++ b/qutebrowser/browser/qutescheme.py
@@ -34,7 +34,7 @@ import collections
import secrets
from typing import TypeVar, Callable, Dict, List, Optional, Union, Sequence, Tuple
-from PyQt5.QtCore import QUrlQuery, QUrl
+from qutebrowser.qt.core import QUrlQuery, QUrl
import qutebrowser
from qutebrowser.browser import pdfjs, downloads, history
@@ -128,7 +128,9 @@ def data_for_url(url: QUrl) -> Tuple[str, bytes]:
Return:
A (mimetype, data) tuple.
"""
- norm_url = url.adjusted(QUrl.NormalizePathSegments | QUrl.StripTrailingSlash)
+ norm_url = url.adjusted(
+ QUrl.UrlFormattingOption.NormalizePathSegments |
+ QUrl.UrlFormattingOption.StripTrailingSlash)
if norm_url != url:
raise Redirect(norm_url)
@@ -423,8 +425,8 @@ def qute_help(url: QUrl) -> _HandlerRet:
def _qute_settings_set(url: QUrl) -> _HandlerRet:
"""Handler for qute://settings/set."""
query = QUrlQuery(url)
- option = query.queryItemValue('option', QUrl.FullyDecoded)
- value = query.queryItemValue('value', QUrl.FullyDecoded)
+ option = query.queryItemValue('option', QUrl.ComponentFormattingOption.FullyDecoded)
+ value = query.queryItemValue('value', QUrl.ComponentFormattingOption.FullyDecoded)
# https://github.com/qutebrowser/qutebrowser/issues/727
if option == 'content.javascript.enabled' and value == 'false':
@@ -498,10 +500,11 @@ def qute_back(url: QUrl) -> _HandlerRet:
@add_handler('configdiff')
-def qute_configdiff(_url: QUrl) -> _HandlerRet:
+def qute_configdiff(url: QUrl) -> _HandlerRet:
"""Handler for qute://configdiff."""
- data = config.instance.dump_userconfig().encode('utf-8')
- return 'text/plain', data
+ include_hidden = QUrlQuery(url).queryItemValue('include_hidden') == 'true'
+ dump = config.instance.dump_userconfig(include_hidden=include_hidden)
+ return 'text/plain', dump.encode('utf-8')
@add_handler('pastebin-version')
@@ -579,6 +582,9 @@ def qute_warning(url: QUrl) -> _HandlerRet:
title='Qt 5.15 sessions warning',
datadir=standarddir.data(),
sep=os.sep)
+ elif path == '/sandboxing':
+ src = jinja.render('warning-sandboxing.html',
+ title='Qt 6 macOS sandboxing warning')
else:
raise NotFoundError("Invalid warning page {}".format(path))
return 'text/html', src
diff --git a/qutebrowser/browser/shared.py b/qutebrowser/browser/shared.py
index 17718cb93..92ed99584 100644
--- a/qutebrowser/browser/shared.py
+++ b/qutebrowser/browser/shared.py
@@ -27,7 +27,7 @@ import netrc
import tempfile
from typing import Callable, Mapping, List, Optional, Iterable, Iterator
-from PyQt5.QtCore import QUrl, pyqtBoundSignal
+from qutebrowser.qt.core import QUrl, pyqtBoundSignal
from qutebrowser.config import config
from qutebrowser.utils import (usertypes, message, log, objreg, jinja, utils,
@@ -72,7 +72,7 @@ def authentication_required(url, authenticator, abort_on):
else:
msg = '<b>{}</b> needs authentication'.format(
html.escape(url.toDisplayString()))
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
answer = message.ask(title="Authentication required", text=msg,
mode=usertypes.PromptMode.user_pwd,
abort_on=abort_on, url=urlstr)
@@ -95,7 +95,7 @@ def javascript_confirm(url, js_msg, abort_on):
msg = 'From <b>{}</b>:<br/>{}'.format(html.escape(url.toDisplayString()),
_format_msg(js_msg))
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
ans = message.ask('Javascript confirm', msg,
mode=usertypes.PromptMode.yesno,
abort_on=abort_on, url=urlstr)
@@ -112,7 +112,7 @@ def javascript_prompt(url, js_msg, default, abort_on):
msg = '<b>{}</b> asks:<br/>{}'.format(html.escape(url.toDisplayString()),
_format_msg(js_msg))
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
answer = message.ask('Javascript prompt', msg,
mode=usertypes.PromptMode.text,
default=default,
@@ -135,7 +135,7 @@ def javascript_alert(url, js_msg, abort_on):
msg = 'From <b>{}</b>:<br/>{}'.format(html.escape(url.toDisplayString()),
_format_msg(js_msg))
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
message.ask('Javascript alert', msg, mode=usertypes.PromptMode.alert,
abort_on=abort_on, url=urlstr)
@@ -205,13 +205,13 @@ def javascript_log_message(
logger(logstring)
-def ignore_certificate_error(
+def handle_certificate_error(
*,
request_url: QUrl,
first_party_url: QUrl,
error: usertypes.AbstractCertificateErrorWrapper,
abort_on: Iterable[pyqtBoundSignal],
-) -> bool:
+) -> None:
"""Display a certificate error question.
Args:
@@ -219,9 +219,6 @@ def ignore_certificate_error(
first_party_url: The URL of the page we're visiting. Might be an invalid QUrl.
error: A single error.
abort_on: Signals aborting a question.
-
- Return:
- True if the error should be ignored, False otherwise.
"""
conf = config.instance.get('content.tls.certificate_errors', url=request_url)
log.network.debug(f"Certificate error {error!r}, config {conf}")
@@ -234,7 +231,7 @@ def ignore_certificate_error(
first_party_url.isValid() and
not request_url.matches(
first_party_url,
- QUrl.RemoveScheme)) # type: ignore[arg-type]
+ QUrl.UrlFormattingOption.RemoveScheme)) # type: ignore[arg-type]
if conf == 'ask' or conf == 'ask-block-thirdparty' and not is_resource:
err_template = jinja.environment.from_string("""
@@ -263,28 +260,46 @@ def ignore_certificate_error(
is_resource=is_resource,
error=error,
)
-
urlstr = request_url.toString(
- QUrl.RemovePassword | QUrl.FullyEncoded) # type: ignore[arg-type]
- ignore = message.ask(title="Certificate error", text=msg,
- mode=usertypes.PromptMode.yesno, default=False,
- abort_on=abort_on, url=urlstr)
- if ignore is None:
- # prompt aborted
- ignore = False
- return ignore
+ QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded) # type: ignore[arg-type]
+ title = "Certificate error"
+
+ try:
+ error.defer()
+ except usertypes.UndeferrableError:
+ # QtNetwork / QtWebKit and buggy PyQt versions
+ # Show blocking question prompt
+ ignore = message.ask(title=title, text=msg,
+ mode=usertypes.PromptMode.yesno, default=False,
+ abort_on=abort_on, url=urlstr)
+ if ignore:
+ error.accept_certificate()
+ else: # includes None, i.e. prompt aborted
+ error.reject_certificate()
+ else:
+ # Show non-blocking question prompt
+ message.confirm_async(
+ title=title,
+ text=msg,
+ abort_on=abort_on,
+ url=urlstr,
+ yes_action=error.accept_certificate,
+ no_action=error.reject_certificate,
+ cancel_action=error.reject_certificate,
+ )
elif conf == 'load-insecurely':
message.error(f'Certificate error: {error}')
- return True
+ error.accept_certificate()
elif conf == 'block':
- return False
+ error.reject_certificate()
elif conf == 'ask-block-thirdparty' and is_resource:
log.network.error(
f"Certificate error in resource load: {error}\n"
f" request URL: {request_url.toDisplayString()}\n"
f" first party URL: {first_party_url.toDisplayString()}")
- return False
- raise utils.Unreachable(conf, is_resource)
+ error.reject_certificate()
+ else:
+ raise utils.Unreachable(conf, is_resource)
def feature_permission(url, option, msg, yes_action, no_action, abort_on,
@@ -307,7 +322,7 @@ def feature_permission(url, option, msg, yes_action, no_action, abort_on,
config_val = config.instance.get(option, url=url)
if config_val == 'ask':
if url.isValid():
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
text = "Allow the website at <b>{}</b> to {}?".format(
html.escape(url.toDisplayString()), msg)
else:
@@ -345,23 +360,19 @@ def get_tab(win_id, target):
win_id: The window ID to open new tabs in
target: A usertypes.ClickTarget
"""
- if target == usertypes.ClickTarget.tab:
- bg_tab = False
- elif target == usertypes.ClickTarget.tab_bg:
- bg_tab = True
- elif target == usertypes.ClickTarget.window:
- tabbed_browser = objreg.get('tabbed-browser', scope='window',
- window=win_id)
+ tabbed_browser = objreg.get('tabbed-browser', scope='window', window=win_id)
+ if target == usertypes.ClickTarget.window:
window = mainwindow.MainWindow(private=tabbed_browser.is_private)
+ tab = window.tabbed_browser.tabopen(url=None, background=False)
window.show()
- win_id = window.win_id
- bg_tab = False
- else:
- raise ValueError("Invalid ClickTarget {}".format(target))
+ return tab
+ elif target in [usertypes.ClickTarget.tab, usertypes.ClickTarget.tab_bg]:
+ return tabbed_browser.tabopen(
+ url=None,
+ background=target == usertypes.ClickTarget.tab_bg,
+ )
- tabbed_browser = objreg.get('tabbed-browser', scope='window',
- window=win_id)
- return tabbed_browser.tabopen(url=None, background=bg_tab)
+ raise ValueError(f"Invalid ClickTarget {target}")
def get_user_stylesheet(searching=False):
@@ -381,7 +392,7 @@ def get_user_stylesheet(searching=False):
css += '\nhtml > ::-webkit-scrollbar { width: 0px; height: 0px; }'
if (objects.backend == usertypes.Backend.QtWebEngine and
- version.qtwebengine_versions().chromium_major in [69, 73, 80, 87] and
+ version.qtwebengine_versions().chromium_major in [87, 90] and
config.val.colors.webpage.darkmode.enabled and
config.val.colors.webpage.darkmode.policy.images == 'smart' and
config.val.content.site_specific_quirks.enabled and
diff --git a/qutebrowser/browser/signalfilter.py b/qutebrowser/browser/signalfilter.py
index 88ac4a65d..beb91e70a 100644
--- a/qutebrowser/browser/signalfilter.py
+++ b/qutebrowser/browser/signalfilter.py
@@ -21,7 +21,7 @@
import functools
-from PyQt5.QtCore import QObject
+from qutebrowser.qt.core import QObject
from qutebrowser.utils import debug, log, objreg
diff --git a/qutebrowser/browser/urlmarks.py b/qutebrowser/browser/urlmarks.py
index 4e173f293..0d30f7973 100644
--- a/qutebrowser/browser/urlmarks.py
+++ b/qutebrowser/browser/urlmarks.py
@@ -32,7 +32,7 @@ import functools
import collections
from typing import MutableMapping
-from PyQt5.QtCore import pyqtSignal, QUrl, QObject
+from qutebrowser.qt.core import pyqtSignal, QUrl, QObject
from qutebrowser.utils import (message, usertypes, qtutils, urlutils,
standarddir, objreg, log)
@@ -151,7 +151,7 @@ class QuickmarkManager(UrlMarkManager):
if not url.isValid():
urlutils.invalid_url_error(url, "save quickmark")
return
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
message.ask_async(
"Add quickmark:", usertypes.PromptMode.text,
functools.partial(self.quickmark_add, urlstr),
@@ -198,7 +198,7 @@ class QuickmarkManager(UrlMarkManager):
Use a name instead where possible.
"""
qtutils.ensure_valid(url)
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
try:
index = list(self.marks.values()).index(urlstr)
@@ -270,7 +270,7 @@ class BookmarkManager(UrlMarkManager):
errstr = urlutils.get_errstring(url)
raise InvalidUrlError(errstr)
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
if urlstr in self.marks:
if toggle:
diff --git a/qutebrowser/browser/webelem.py b/qutebrowser/browser/webelem.py
index 344292166..672c73fdb 100644
--- a/qutebrowser/browser/webelem.py
+++ b/qutebrowser/browser/webelem.py
@@ -19,11 +19,12 @@
"""Generic web element related code."""
-from typing import cast, TYPE_CHECKING, Iterator, Optional, Set, Union, Dict
+from typing import Iterator, Optional, Set, TYPE_CHECKING, Union, Dict
import collections.abc
-from PyQt5.QtCore import QUrl, Qt, QEvent, QTimer, QRect, QPoint
-from PyQt5.QtGui import QMouseEvent
+from qutebrowser.qt import machinery
+from qutebrowser.qt.core import QUrl, Qt, QEvent, QTimer, QRect, QPointF
+from qutebrowser.qt.gui import QMouseEvent
from qutebrowser.config import config
from qutebrowser.keyinput import modeman
@@ -35,6 +36,11 @@ if TYPE_CHECKING:
JsValueType = Union[int, float, str, None]
+if machinery.IS_QT6:
+ KeybordModifierType = Qt.KeyboardModifier
+else:
+ KeybordModifierType = Union[Qt.KeyboardModifiers, Qt.KeyboardModifier]
+
class Error(Exception):
@@ -317,7 +323,7 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
"""Return True if clicking this element needs user interaction."""
raise NotImplementedError
- def _mouse_pos(self) -> QPoint:
+ def _mouse_pos(self) -> QPointF:
"""Get the position to click/hover."""
# Click the center of the largest square fitting into the top/left
# corner of the rectangle, this will help if part of the <a> element
@@ -331,38 +337,37 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
pos = rect.center()
if pos.x() < 0 or pos.y() < 0:
raise Error("Element position is out of view!")
- return pos
+ return QPointF(pos)
def _move_text_cursor(self) -> None:
"""Move cursor to end after clicking."""
raise NotImplementedError
def _click_fake_event(self, click_target: usertypes.ClickTarget,
- button: Qt.MouseButton = Qt.LeftButton) -> None:
+ button: Qt.MouseButton = Qt.MouseButton.LeftButton) -> None:
"""Send a fake click event to the element."""
pos = self._mouse_pos()
log.webelem.debug("Sending fake click to {!r} at position {} with "
"target {}".format(self, pos, click_target))
- target_modifiers: Dict[usertypes.ClickTarget, Qt.KeyboardModifiers] = {
- usertypes.ClickTarget.normal: cast(Qt.KeyboardModifiers, Qt.NoModifier),
- usertypes.ClickTarget.window: Qt.AltModifier | Qt.ShiftModifier,
- usertypes.ClickTarget.tab: cast(Qt.KeyboardModifiers, Qt.ControlModifier),
- usertypes.ClickTarget.tab_bg:
- cast(Qt.KeyboardModifiers, Qt.ControlModifier),
+ target_modifiers: Dict[usertypes.ClickTarget, KeybordModifierType] = {
+ usertypes.ClickTarget.normal: Qt.KeyboardModifier.NoModifier,
+ usertypes.ClickTarget.window: Qt.KeyboardModifier.AltModifier | Qt.KeyboardModifier.ShiftModifier,
+ usertypes.ClickTarget.tab: Qt.KeyboardModifier.ControlModifier,
+ usertypes.ClickTarget.tab_bg: Qt.KeyboardModifier.ControlModifier,
}
if config.val.tabs.background:
- target_modifiers[usertypes.ClickTarget.tab] |= Qt.ShiftModifier
+ target_modifiers[usertypes.ClickTarget.tab] |= Qt.KeyboardModifier.ShiftModifier
else:
- target_modifiers[usertypes.ClickTarget.tab_bg] |= Qt.ShiftModifier
+ target_modifiers[usertypes.ClickTarget.tab_bg] |= Qt.KeyboardModifier.ShiftModifier
modifiers = target_modifiers[click_target]
events = [
- QMouseEvent(QEvent.MouseMove, pos, Qt.NoButton, Qt.NoButton, Qt.NoModifier),
- QMouseEvent(QEvent.MouseButtonPress, pos, button, button, modifiers),
- QMouseEvent(QEvent.MouseButtonRelease, pos, button, Qt.NoButton, modifiers),
+ QMouseEvent(QEvent.Type.MouseMove, pos, Qt.MouseButton.NoButton, Qt.MouseButton.NoButton, Qt.KeyboardModifier.NoModifier),
+ QMouseEvent(QEvent.Type.MouseButtonPress, pos, button, button, modifiers),
+ QMouseEvent(QEvent.Type.MouseButtonRelease, pos, button, Qt.MouseButton.NoButton, modifiers),
]
for evt in events:
@@ -400,8 +405,8 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
elif click_target == usertypes.ClickTarget.window:
from qutebrowser.mainwindow import mainwindow
window = mainwindow.MainWindow(private=tabbed_browser.is_private)
- window.show()
window.tabbed_browser.tabopen(url)
+ window.show()
else:
raise ValueError("Unknown ClickTarget {}".format(click_target))
@@ -446,11 +451,11 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
def hover(self) -> None:
"""Simulate a mouse hover over the element."""
pos = self._mouse_pos()
- event = QMouseEvent(QEvent.MouseMove, pos, Qt.NoButton, Qt.NoButton,
- Qt.NoModifier)
+ event = QMouseEvent(QEvent.Type.MouseMove, pos, Qt.MouseButton.NoButton, Qt.MouseButton.NoButton,
+ Qt.KeyboardModifier.NoModifier)
self._tab.send_event(event)
def right_click(self) -> None:
"""Simulate a right-click on the element."""
self._click_fake_event(usertypes.ClickTarget.normal,
- button=Qt.RightButton)
+ button=Qt.MouseButton.RightButton)
diff --git a/qutebrowser/browser/webengine/certificateerror.py b/qutebrowser/browser/webengine/certificateerror.py
index 4df7ce8ab..0dbd91ccb 100644
--- a/qutebrowser/browser/webengine/certificateerror.py
+++ b/qutebrowser/browser/webengine/certificateerror.py
@@ -19,27 +19,54 @@
"""Wrapper over a QWebEngineCertificateError."""
-from PyQt5.QtCore import QUrl
-from PyQt5.QtWebEngineWidgets import QWebEngineCertificateError
+from typing import Any
+
+from qutebrowser.qt import machinery
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.webenginecore import QWebEngineCertificateError
from qutebrowser.utils import usertypes, utils, debug
class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
- """A wrapper over a QWebEngineCertificateError."""
+ """A wrapper over a QWebEngineCertificateError.
+
+ Support both Qt 5 and 6.
+ """
def __init__(self, error: QWebEngineCertificateError) -> None:
+ super().__init__()
self._error = error
self.ignore = False
def __str__(self) -> str:
- return self._error.errorDescription()
+ if machinery.IS_QT5:
+ return self._error.errorDescription()
+ else:
+ return self._error.description()
+
+ def _type(self) -> Any: # QWebEngineCertificateError.Type or .Error
+ if machinery.IS_QT5:
+ return self._error.error()
+ else:
+ return self._error.type()
+
+ def reject_certificate(self) -> None:
+ super().reject_certificate()
+ self._error.rejectCertificate()
+
+ def accept_certificate(self) -> None:
+ super().accept_certificate()
+ if machinery.IS_QT5:
+ self._error.ignoreCertificateError()
+ else:
+ self._error.acceptCertificate()
def __repr__(self) -> str:
return utils.get_repr(
self,
- error=debug.qenum_key(QWebEngineCertificateError, self._error.error()),
+ error=debug.qenum_key(QWebEngineCertificateError, self._type()),
string=str(self))
def url(self) -> QUrl:
@@ -47,3 +74,8 @@ class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
def is_overridable(self) -> bool:
return self._error.isOverridable()
+
+ def defer(self) -> None:
+ # WORKAROUND for https://www.riverbankcomputing.com/pipermail/pyqt/2022-April/044585.html
+ # (PyQt 5.15.6, 6.2.3, 6.3.0)
+ raise usertypes.UndeferrableError("PyQt bug")
diff --git a/qutebrowser/browser/webengine/darkmode.py b/qutebrowser/browser/webengine/darkmode.py
index 1c6530b49..4bf6990a0 100644
--- a/qutebrowser/browser/webengine/darkmode.py
+++ b/qutebrowser/browser/webengine/darkmode.py
@@ -21,8 +21,8 @@
Overview of blink setting names based on the Qt version:
-Qt 5.10
--------
+Qt 5.10 (UNSUPPORTED)
+---------------------
First implementation, called "high contrast mode".
@@ -31,16 +31,16 @@ First implementation, called "high contrast mode".
- highContrastContrast (float)
- highContractImagePolicy (kFilterAll/kFilterNone)
-Qt 5.11, 5.12, 5.13
--------------------
+Qt 5.11, 5.12, 5.13 (UNSUPPORTED)
+---------------------------------
New "smart" image policy.
- Mode/Grayscale/Contrast as above
- highContractImagePolicy (kFilterAll/kFilterNone/kFilterSmart [new!])
-Qt 5.14
--------
+Qt 5.14 (UNSUPPORTED)
+---------------------
Renamed to "darkMode".
@@ -54,8 +54,8 @@ Renamed to "darkMode".
- darkModeBackgroundBrightnessThreshold (int) [new!]
- darkModeImageGrayscale (float) [new!]
-Qt 5.15.0 and 5.15.1
---------------------
+Qt 5.15.0 and 5.15.1 (UNSUPPORTED)
+----------------------------------
"darkMode" split into "darkModeEnabled" and "darkModeInversionAlgorithm".
@@ -90,6 +90,17 @@ https://chromium-review.googlesource.com/c/chromium/src/+/2232922
- Now needs to be 0 for dark and 1 for light
(before: 0 no preference / 1 dark / 2 light)
+
+Qt 6.2
+------
+
+No significant changes over 5.15.3
+
+Qt 6.3
+------
+
+- New IncreaseTextContrast:
+https://chromium-review.googlesource.com/c/chromium/src/+/2893236
"""
import os
@@ -111,12 +122,9 @@ class Variant(enum.Enum):
"""A dark mode variant."""
- qt_511_to_513 = enum.auto()
- qt_514 = enum.auto()
- qt_515_0 = enum.auto()
- qt_515_1 = enum.auto()
qt_515_2 = enum.auto()
qt_515_3 = enum.auto()
+ qt_63 = enum.auto()
# Mapping from a colors.webpage.darkmode.algorithm setting value to
@@ -128,9 +136,6 @@ _ALGORITHMS = {
'lightness-hsl': 3, # kInvertLightness
'lightness-cielab': 4, # kInvertLightnessLAB
}
-# kInvertLightnessLAB is not available with Qt < 5.14
-_ALGORITHMS_BEFORE_QT_514 = _ALGORITHMS.copy()
-_ALGORITHMS_BEFORE_QT_514['lightness-cielab'] = _ALGORITHMS['lightness-hsl']
# Qt >= 5.15.3, based on dark_mode_settings.h
_ALGORITHMS_NEW = {
# 0: kSimpleInvertForTesting (not exposed)
@@ -160,6 +165,11 @@ _BOOLS = {
False: 'false',
}
+_INT_BOOLS = {
+ True: '1',
+ False: '0',
+}
+
@dataclasses.dataclass
class _Setting:
@@ -229,40 +239,24 @@ class _Definition:
"""Get a new _Definition object with a changed attribute.
NOTE: This does *not* copy the settings list. Both objects will reference the
- same list.
+ same (immutable) tuple.
"""
new = copy.copy(self)
setattr(new, attr, value)
return new
+ def copy_add_setting(self, setting: _Setting) -> '_Definition':
+ """Get a new _Definition object with an additional setting."""
+ new = copy.copy(self)
+ new._settings = self._settings + (setting,) # pylint: disable=protected-access
+ return new
+
# Our defaults for policy.images are different from Chromium's, so we mark it as
-# mandatory setting - except on Qt 5.15.0 where we don't, so we don't get the
-# workaround warning below if the setting wasn't explicitly customized.
+# mandatory setting.
_DEFINITIONS: MutableMapping[Variant, _Definition] = {
- Variant.qt_515_3: _Definition(
- # Different switch for settings
- _Setting('enabled', 'forceDarkModeEnabled', _BOOLS),
- _Setting('algorithm', 'InversionAlgorithm', _ALGORITHMS_NEW),
-
- _Setting('policy.images', 'ImagePolicy', _IMAGE_POLICIES),
- _Setting('contrast', 'ContrastPercent'),
- _Setting('grayscale.all', 'IsGrayScale', _BOOLS),
-
- _Setting('threshold.text', 'TextBrightnessThreshold'),
- _Setting('threshold.background', 'BackgroundBrightnessThreshold'),
- _Setting('grayscale.images', 'ImageGrayScalePercent'),
-
- mandatory={'enabled', 'policy.images'},
- prefix='',
- switch_names={'enabled': _BLINK_SETTINGS, None: 'dark-mode-settings'},
- ),
-
- # Qt 5.15.1 and 5.15.2 get added below, since there are only minor differences.
-
- Variant.qt_515_0: _Definition(
- # 'policy.images' not mandatory because it's broken
+ Variant.qt_515_2: _Definition(
_Setting('enabled', 'Enabled', _BOOLS),
_Setting('algorithm', 'InversionAlgorithm', _ALGORITHMS),
@@ -275,60 +269,55 @@ _DEFINITIONS: MutableMapping[Variant, _Definition] = {
_Setting('threshold.background', 'BackgroundBrightnessThreshold'),
_Setting('grayscale.images', 'ImageGrayscale'),
- mandatory={'enabled'},
- prefix='darkMode',
+ mandatory={'enabled', 'policy.images'},
+ prefix='forceDarkMode',
),
- Variant.qt_514: _Definition(
- _Setting('algorithm', '', _ALGORITHMS), # new: kInvertLightnessLAB
+ Variant.qt_515_3: _Definition(
+ # Different switch for settings
+ _Setting('enabled', 'forceDarkModeEnabled', _BOOLS),
+ _Setting('algorithm', 'InversionAlgorithm', _ALGORITHMS_NEW),
_Setting('policy.images', 'ImagePolicy', _IMAGE_POLICIES),
- _Setting('contrast', 'Contrast'),
- _Setting('grayscale.all', 'Grayscale', _BOOLS),
+ _Setting('contrast', 'ContrastPercent'),
+ _Setting('grayscale.all', 'IsGrayScale', _BOOLS),
- _Setting('policy.page', 'PagePolicy', _PAGE_POLICIES),
_Setting('threshold.text', 'TextBrightnessThreshold'),
_Setting('threshold.background', 'BackgroundBrightnessThreshold'),
- _Setting('grayscale.images', 'ImageGrayscale'),
-
- mandatory={'algorithm', 'policy.images'},
- prefix='darkMode',
- ),
-
- Variant.qt_511_to_513: _Definition(
- _Setting('algorithm', 'Mode', _ALGORITHMS_BEFORE_QT_514),
-
- _Setting('policy.images', 'ImagePolicy', _IMAGE_POLICIES),
- _Setting('contrast', 'Contrast'),
- _Setting('grayscale.all', 'Grayscale', _BOOLS),
+ _Setting('grayscale.images', 'ImageGrayScalePercent'),
- mandatory={'algorithm', 'policy.images'},
- prefix='highContrast',
+ mandatory={'enabled', 'policy.images'},
+ prefix='',
+ switch_names={'enabled': _BLINK_SETTINGS, None: 'dark-mode-settings'},
),
}
-_DEFINITIONS[Variant.qt_515_1] = (
- _DEFINITIONS[Variant.qt_515_0].copy_with('mandatory', {'enabled', 'policy.images'}))
-_DEFINITIONS[Variant.qt_515_2] = (
- _DEFINITIONS[Variant.qt_515_1].copy_with('prefix', 'forceDarkMode'))
-
-
-_PREFERRED_COLOR_SCHEME_DEFINITIONS = {
- # With older Qt versions, this is passed in qtargs.py as --force-dark-mode
- # instead.
-
- ## Qt 5.15.2
- # 0: no-preference (not exposed)
- (Variant.qt_515_2, "dark"): "1",
- (Variant.qt_515_2, "light"): "2",
- # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-89753
- # Fall back to "light" instead of "no preference" (which was removed from the
- # standard)
- (Variant.qt_515_2, "auto"): "2",
- (Variant.qt_515_2, usertypes.UNSET): "2",
-
- ## Qt >= 5.15.3
- (Variant.qt_515_3, "dark"): "0",
- (Variant.qt_515_3, "light"): "1",
+_DEFINITIONS[Variant.qt_63] = _DEFINITIONS[Variant.qt_515_3].copy_add_setting(
+ _Setting('increase_text_contrast', 'IncreaseTextContrast', _INT_BOOLS),
+)
+
+
+_SettingValType = Union[str, usertypes.Unset]
+_PREFERRED_COLOR_SCHEME_DEFINITIONS: Mapping[Variant, Mapping[_SettingValType, str]] = {
+ Variant.qt_515_2: {
+ # 0: no-preference (not exposed)
+ "dark": "1",
+ "light": "2",
+ # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-89753
+ # Fall back to "light" instead of "no preference" (which was removed from the
+ # standard)
+ "auto": "2",
+ usertypes.UNSET: "2",
+ },
+
+ Variant.qt_515_3: {
+ "dark": "0",
+ "light": "1",
+ },
+
+ Variant.qt_63: {
+ "dark": "0",
+ "light": "1",
+ }
}
@@ -341,7 +330,9 @@ def _variant(versions: version.WebEngineVersions) -> Variant:
except KeyError:
log.init.warning(f"Ignoring invalid QUTE_DARKMODE_VARIANT={env_var}")
- if (versions.webengine == utils.VersionNumber(5, 15, 2) and
+ if versions.webengine >= utils.VersionNumber(6, 3):
+ return Variant.qt_63
+ elif (versions.webengine == utils.VersionNumber(5, 15, 2) and
versions.chromium_major == 87):
# WORKAROUND for Gentoo packaging something newer as 5.15.2...
return Variant.qt_515_3
@@ -349,14 +340,6 @@ def _variant(versions: version.WebEngineVersions) -> Variant:
return Variant.qt_515_3
elif versions.webengine >= utils.VersionNumber(5, 15, 2):
return Variant.qt_515_2
- elif versions.webengine == utils.VersionNumber(5, 15, 1):
- return Variant.qt_515_1
- elif versions.webengine == utils.VersionNumber(5, 15):
- return Variant.qt_515_0
- elif versions.webengine >= utils.VersionNumber(5, 14):
- return Variant.qt_514
- elif versions.webengine >= utils.VersionNumber(5, 11):
- return Variant.qt_511_to_513
raise utils.Unreachable(versions.webengine)
@@ -387,12 +370,11 @@ def settings(
key, val = pair.split('=', maxsplit=1)
result[_BLINK_SETTINGS].append((key, val))
- preferred_color_scheme_key = (
- variant,
- config.instance.get("colors.webpage.preferred_color_scheme", fallback=False),
- )
- if preferred_color_scheme_key in _PREFERRED_COLOR_SCHEME_DEFINITIONS:
- value = _PREFERRED_COLOR_SCHEME_DEFINITIONS[preferred_color_scheme_key]
+ preferred_color_scheme_key = config.instance.get(
+ "colors.webpage.preferred_color_scheme", fallback=False)
+ preferred_color_scheme_defs = _PREFERRED_COLOR_SCHEME_DEFINITIONS[variant]
+ if preferred_color_scheme_key in preferred_color_scheme_defs:
+ value = preferred_color_scheme_defs[preferred_color_scheme_key]
result[_BLINK_SETTINGS].append(("preferredColorScheme", value))
if not config.val.colors.webpage.darkmode.enabled:
@@ -411,14 +393,6 @@ def settings(
if isinstance(value, usertypes.Unset):
continue
- if (setting.option == 'policy.images' and value == 'smart' and
- variant == Variant.qt_515_0):
- # WORKAROUND for
- # https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/304211
- log.init.warning("Ignoring colors.webpage.darkmode.policy.images = smart "
- "because of Qt 5.15.0 bug")
- continue
-
result[switch_name].append(setting.chromium_tuple(value))
return result
diff --git a/qutebrowser/browser/webengine/interceptor.py b/qutebrowser/browser/webengine/interceptor.py
index 0b1040c4d..bd1feaad1 100644
--- a/qutebrowser/browser/webengine/interceptor.py
+++ b/qutebrowser/browser/webengine/interceptor.py
@@ -19,13 +19,13 @@
"""A request interceptor taking care of adblocking and custom headers."""
-from PyQt5.QtCore import QUrl, QByteArray
-from PyQt5.QtWebEngineCore import (QWebEngineUrlRequestInterceptor,
+from qutebrowser.qt.core import QUrl, QByteArray
+from qutebrowser.qt.webenginecore import (QWebEngineUrlRequestInterceptor,
QWebEngineUrlRequestInfo)
from qutebrowser.config import websettings, config
from qutebrowser.browser import shared
-from qutebrowser.utils import utils, log, debug, qtutils
+from qutebrowser.utils import debug, log
from qutebrowser.extensions import interceptors
from qutebrowser.misc import objects
@@ -71,80 +71,71 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor):
# extension ResourceTypes. If a ResourceType is added to Qt, this table
# should be updated too.
self._resource_types = {
- QWebEngineUrlRequestInfo.ResourceTypeMainFrame:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeMainFrame:
interceptors.ResourceType.main_frame,
- QWebEngineUrlRequestInfo.ResourceTypeSubFrame:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeSubFrame:
interceptors.ResourceType.sub_frame,
- QWebEngineUrlRequestInfo.ResourceTypeStylesheet:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeStylesheet:
interceptors.ResourceType.stylesheet,
- QWebEngineUrlRequestInfo.ResourceTypeScript:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeScript:
interceptors.ResourceType.script,
- QWebEngineUrlRequestInfo.ResourceTypeImage:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeImage:
interceptors.ResourceType.image,
- QWebEngineUrlRequestInfo.ResourceTypeFontResource:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeFontResource:
interceptors.ResourceType.font_resource,
- QWebEngineUrlRequestInfo.ResourceTypeSubResource:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeSubResource:
interceptors.ResourceType.sub_resource,
- QWebEngineUrlRequestInfo.ResourceTypeObject:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeObject:
interceptors.ResourceType.object,
- QWebEngineUrlRequestInfo.ResourceTypeMedia:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeMedia:
interceptors.ResourceType.media,
- QWebEngineUrlRequestInfo.ResourceTypeWorker:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeWorker:
interceptors.ResourceType.worker,
- QWebEngineUrlRequestInfo.ResourceTypeSharedWorker:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeSharedWorker:
interceptors.ResourceType.shared_worker,
- QWebEngineUrlRequestInfo.ResourceTypePrefetch:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypePrefetch:
interceptors.ResourceType.prefetch,
- QWebEngineUrlRequestInfo.ResourceTypeFavicon:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeFavicon:
interceptors.ResourceType.favicon,
- QWebEngineUrlRequestInfo.ResourceTypeXhr:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeXhr:
interceptors.ResourceType.xhr,
- QWebEngineUrlRequestInfo.ResourceTypePing:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypePing:
interceptors.ResourceType.ping,
- QWebEngineUrlRequestInfo.ResourceTypeServiceWorker:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeServiceWorker:
interceptors.ResourceType.service_worker,
- QWebEngineUrlRequestInfo.ResourceTypeCspReport:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeCspReport:
interceptors.ResourceType.csp_report,
- QWebEngineUrlRequestInfo.ResourceTypePluginResource:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypePluginResource:
interceptors.ResourceType.plugin_resource,
- QWebEngineUrlRequestInfo.ResourceTypeUnknown:
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeUnknown:
interceptors.ResourceType.unknown,
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeNavigationPreloadMainFrame:
+ interceptors.ResourceType.preload_main_frame,
+ QWebEngineUrlRequestInfo.ResourceType.ResourceTypeNavigationPreloadSubFrame:
+ interceptors.ResourceType.preload_sub_frame,
}
-
- try:
- preload_main_frame = (QWebEngineUrlRequestInfo.
- ResourceTypeNavigationPreloadMainFrame)
- preload_sub_frame = (QWebEngineUrlRequestInfo.
- ResourceTypeNavigationPreloadSubFrame)
- except AttributeError:
- # Added in Qt 5.14
- pass
- else:
- self._resource_types[preload_main_frame] = (
- interceptors.ResourceType.preload_main_frame)
- self._resource_types[preload_sub_frame] = (
- interceptors.ResourceType.preload_sub_frame)
+ new_types = {
+ "WebSocket": interceptors.ResourceType.websocket, # added in Qt 6.4
+ }
+ for qt_name, qb_value in new_types.items():
+ qt_value = getattr(
+ QWebEngineUrlRequestInfo.ResourceType,
+ f"ResourceType{qt_name}",
+ None,
+ )
+ if qt_value is not None:
+ self._resource_types[qt_value] = qb_value
def install(self, profile):
"""Install the interceptor on the given QWebEngineProfile."""
- try:
- # Qt >= 5.13, GUI thread
- profile.setUrlRequestInterceptor(self)
- except AttributeError:
- # Qt 5.12, IO thread
- profile.setRequestInterceptor(self)
-
- # Gets called in the IO thread -> showing crash window will fail
- @utils.prevent_exceptions(None, not qtutils.version_check('5.13'))
+ profile.setUrlRequestInterceptor(self)
+
def interceptRequest(self, info):
"""Handle the given request.
Reimplementing this virtual function and setting the interceptor on a
profile makes it possible to intercept URL requests.
- On Qt < 5.13, this function is executed on the IO thread, and therefore
- running long tasks here will block networking.
-
info contains the information about the URL request and will track
internally whether its members have been altered.
@@ -181,7 +172,7 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor):
info.resourceType())))
resource_type = interceptors.ResourceType.unknown
- is_xhr = info.resourceType() == QWebEngineUrlRequestInfo.ResourceTypeXhr
+ is_xhr = info.resourceType() == QWebEngineUrlRequestInfo.ResourceType.ResourceTypeXhr
if ((url.scheme(), url.host(), url.path()) ==
('qute', 'settings', '/set')):
@@ -214,9 +205,6 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor):
continue
info.setHttpHeader(header, value)
- # Note this is ignored before Qt 5.12.4 and 5.13.1 due to
- # https://bugreports.qt.io/browse/QTBUG-60203 - there, we set the
- # commandline-flag in qtargs.py instead.
if config.cache['content.headers.referer'] == 'never':
info.setHttpHeader(b'Referer', b'')
diff --git a/qutebrowser/browser/webengine/notification.py b/qutebrowser/browser/webengine/notification.py
index d14c7c9fe..8b67570a4 100644
--- a/qutebrowser/browser/webengine/notification.py
+++ b/qutebrowser/browser/webengine/notification.py
@@ -50,23 +50,24 @@ import functools
import subprocess
from typing import Any, List, Dict, Optional, Iterator, Type, TYPE_CHECKING
-from PyQt5.QtCore import (Qt, QObject, QVariant, QMetaType, QByteArray, pyqtSlot,
+from qutebrowser.qt import machinery
+from qutebrowser.qt.core import (Qt, QObject, QVariant, QMetaType, QByteArray, pyqtSlot,
pyqtSignal, QTimer, QProcess, QUrl)
-from PyQt5.QtGui import QImage, QIcon, QPixmap
-from PyQt5.QtDBus import (QDBusConnection, QDBusInterface, QDBus, QDBusServiceWatcher,
+from qutebrowser.qt.gui import QImage, QIcon, QPixmap
+from qutebrowser.qt.dbus import (QDBusConnection, QDBusInterface, QDBus, QDBusServiceWatcher,
QDBusArgument, QDBusMessage, QDBusError)
-from PyQt5.QtWidgets import QSystemTrayIcon
+from qutebrowser.qt.widgets import QSystemTrayIcon
if TYPE_CHECKING:
# putting these behind TYPE_CHECKING also means this module is importable
# on installs that don't have these
- from PyQt5.QtWebEngineCore import QWebEngineNotification
- from PyQt5.QtWebEngineWidgets import QWebEngineProfile
+ from qutebrowser.qt.webenginecore import QWebEngineNotification
+ from qutebrowser.qt.webenginewidgets import QWebEngineProfile
from qutebrowser.config import config
from qutebrowser.misc import objects
from qutebrowser.utils import (
- qtutils, log, utils, debug, message, version, objreg, resources,
+ qtutils, log, utils, debug, message, objreg, resources,
)
from qutebrowser.qt import sip
@@ -74,12 +75,6 @@ from qutebrowser.qt import sip
bridge: Optional['NotificationBridgePresenter'] = None
-def _notifications_supported() -> bool:
- """Check whether the current QtWebEngine version has notification support."""
- versions = version.qtwebengine_versions(avoid_init=True)
- return versions.webengine >= utils.VersionNumber(5, 14)
-
-
def init() -> None:
"""Initialize the DBus notification presenter, if applicable.
@@ -94,9 +89,6 @@ def init() -> None:
# to its usefulness.
return
- if not _notifications_supported():
- return
-
global bridge
bridge = NotificationBridgePresenter()
@@ -140,7 +132,7 @@ class DBusError(Error):
}
def __init__(self, msg: QDBusMessage) -> None:
- assert msg.type() == QDBusMessage.ErrorMessage
+ assert msg.type() == QDBusMessage.MessageType.ErrorMessage
self.error = msg.errorName()
self.error_message = msg.errorMessage()
self.is_fatal = self.error not in self._NON_FATAL_ERRORS
@@ -208,7 +200,6 @@ class NotificationBridgePresenter(QObject):
"""Notification presenter which bridges notifications to an adapter.
Takes care of:
- - Working around bugs in PyQt 5.14
- Storing currently shown notifications, using an ID returned by the adapter.
- Initializing a suitable adapter when the first notification is shown.
- Switching out adapters if the current one emitted its error signal.
@@ -216,7 +207,6 @@ class NotificationBridgePresenter(QObject):
def __init__(self, parent: QObject = None) -> None:
super().__init__(parent)
- assert _notifications_supported()
self._active_notifications: Dict[int, 'QWebEngineNotification'] = {}
self._adapter: Optional[AbstractNotificationAdapter] = None
@@ -280,24 +270,7 @@ class NotificationBridgePresenter(QObject):
def install(self, profile: "QWebEngineProfile") -> None:
"""Set the profile to use this bridge as the presenter."""
- # WORKAROUND for
- # https://www.riverbankcomputing.com/pipermail/pyqt/2020-May/042916.html
- # Fixed in PyQtWebEngine 5.15.0
- # PYQT_WEBENGINE_VERSION was added with PyQtWebEngine 5.13, but if we're here,
- # we already did a version check above.
- from PyQt5.QtWebEngine import PYQT_WEBENGINE_VERSION
- if PYQT_WEBENGINE_VERSION < 0x050F00:
- # PyQtWebEngine unrefs the callback after it's called, for some
- # reason. So we call setNotificationPresenter again to *increase*
- # its refcount to prevent it from getting GC'd. Otherwise, random
- # methods start getting called with the notification as `self`, or
- # segfaults happen, or other badness.
- def _present_and_reset(qt_notification: "QWebEngineNotification") -> None:
- profile.setNotificationPresenter(_present_and_reset)
- self.present(qt_notification)
- profile.setNotificationPresenter(_present_and_reset)
- else:
- profile.setNotificationPresenter(self.present)
+ profile.setNotificationPresenter(self.present)
def present(self, qt_notification: "QWebEngineNotification") -> None:
"""Show a notification using the configured adapter.
@@ -349,18 +322,11 @@ class NotificationBridgePresenter(QObject):
f"Finding notification for tag {new_notification.tag()}, "
f"origin {new_notification.origin()}")
- try:
- for notification_id, notification in sorted(
- self._active_notifications.items(), reverse=True):
- if notification.matches(new_notification):
- log.misc.debug(f"Found match: {notification_id}")
- return notification_id
- except RuntimeError:
- # WORKAROUND for
- # https://www.riverbankcomputing.com/pipermail/pyqt/2020-May/042918.html
- # (also affects .matches)
- log.misc.debug(
- f"Ignoring notification tag {new_notification.tag()!r} due to PyQt bug")
+ for notification_id, notification in sorted(
+ self._active_notifications.items(), reverse=True):
+ if notification.matches(new_notification):
+ log.misc.debug(f"Found match: {notification_id}")
+ return notification_id
log.misc.debug("Did not find match")
return None
@@ -381,13 +347,7 @@ class NotificationBridgePresenter(QObject):
# Notification from a different application
return
- try:
- notification.close()
- except RuntimeError:
- # WORKAROUND for
- # https://www.riverbankcomputing.com/pipermail/pyqt/2020-May/042918.html
- log.misc.debug(f"Ignoring close request for notification {notification_id} "
- "due to PyQt bug")
+ notification.close()
@pyqtSlot(int)
def _on_adapter_clicked(self, notification_id: int) -> None:
@@ -405,21 +365,14 @@ class NotificationBridgePresenter(QObject):
log.misc.debug("Did not find matching notification, ignoring")
return
- try:
- notification.click()
- except RuntimeError:
- # WORKAROUND for
- # https://www.riverbankcomputing.com/pipermail/pyqt/2020-May/042918.html
- log.misc.debug(f"Ignoring click request for notification {notification_id} "
- "due to PyQt bug")
- return
+ notification.click()
self._focus_first_matching_tab(notification)
def _focus_first_matching_tab(self, notification: "QWebEngineNotification") -> None:
for win_id in objreg.window_registry:
tabbedbrowser = objreg.get("tabbed-browser", window=win_id, scope="window")
for idx, tab in enumerate(tabbedbrowser.widgets()):
- if tab.url().matches(notification.origin(), QUrl.RemovePath):
+ if tab.url().matches(notification.origin(), QUrl.UrlFormattingOption.RemovePath):
tabbedbrowser.widget.setCurrentIndex(idx)
return
log.misc.debug(f"No matching tab found for {notification.origin()}")
@@ -514,7 +467,7 @@ class SystrayNotificationAdapter(AbstractNotificationAdapter):
"""Convert a QImage to a QIcon."""
if image.isNull():
return QIcon()
- pixmap = QPixmap.fromImage(image, Qt.NoFormatConversion)
+ pixmap = QPixmap.fromImage(image, Qt.ImageConversionFlag.NoFormatConversion)
assert not pixmap.isNull()
icon = QIcon(pixmap)
assert not icon.isNull()
@@ -665,7 +618,7 @@ class HerbeNotificationAdapter(AbstractNotificationAdapter):
signals, we can't do much - emitting self.error would just go use herbe again,
so there's no point.
"""
- if status == QProcess.CrashExit:
+ if status == QProcess.ExitStatus.CrashExit:
pass
elif code == 0:
self.click_id.emit(pid)
@@ -681,7 +634,7 @@ class HerbeNotificationAdapter(AbstractNotificationAdapter):
@pyqtSlot(QProcess.ProcessError)
def _on_error(self, error: QProcess.ProcessError) -> None:
- if error == QProcess.Crashed:
+ if error == QProcess.ProcessError.Crashed:
return
name = debug.qenum_key(QProcess.ProcessError, error)
raise Error(f'herbe process error: {name}')
@@ -737,7 +690,13 @@ class _ServerCapabilities:
def _as_uint32(x: int) -> QVariant:
"""Convert the given int to an uint32 for DBus."""
variant = QVariant(x)
- successful = variant.convert(QVariant.UInt)
+
+ if machinery.IS_QT5:
+ target_type = QVariant.Type.UInt
+ else: # Qt 6
+ target_type = QMetaType(QMetaType.Type.UInt.value)
+
+ successful = variant.convert(target_type)
assert successful
return variant
@@ -763,7 +722,6 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
def __init__(self, parent: QObject = None) -> None:
super().__init__(parent)
- assert _notifications_supported()
if utils.is_windows:
# The QDBusConnection destructor seems to cause error messages (and
@@ -781,7 +739,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
self._watcher = QDBusServiceWatcher(
self.SERVICE,
bus,
- QDBusServiceWatcher.WatchForUnregistration,
+ QDBusServiceWatcher.WatchModeFlag.WatchForUnregistration,
self,
)
self._watcher.serviceUnregistered.connect(self._on_service_unregistered)
@@ -900,8 +858,8 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
def _get_server_info(self) -> None:
"""Query notification server information and set quirks."""
- reply = self.interface.call(QDBus.BlockWithGui, "GetServerInformation")
- self._verify_message(reply, "ssss", QDBusMessage.ReplyMessage)
+ reply = self.interface.call(QDBus.CallMode.BlockWithGui, "GetServerInformation")
+ self._verify_message(reply, "ssss", QDBusMessage.MessageType.ReplyMessage)
name, vendor, ver, spec_version = reply.arguments()
log.misc.debug(
@@ -945,11 +903,11 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
Raises DBusError if the signature doesn't match.
"""
assert expected_type not in [
- QDBusMessage.ErrorMessage,
- QDBusMessage.InvalidMessage,
+ QDBusMessage.MessageType.ErrorMessage,
+ QDBusMessage.MessageType.InvalidMessage,
], expected_type
- if msg.type() == QDBusMessage.ErrorMessage:
+ if msg.type() == QDBusMessage.MessageType.ErrorMessage:
raise DBusError(msg)
signature = msg.signature()
@@ -997,7 +955,10 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
actions = []
if self._capabilities.actions:
actions = ['default', 'Activate'] # key, name
- return QDBusArgument(actions, QMetaType.QStringList)
+ return QDBusArgument(
+ actions,
+ qtutils.extract_enum_val(QMetaType.Type.QStringList),
+ )
def _get_hints_arg(self, *, origin_url: QUrl, icon: QImage) -> Dict[str, Any]:
"""Get the hints argument for present()."""
@@ -1037,7 +998,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
) -> Any:
"""Wrapper around DBus call to use keyword args."""
return self.interface.call(
- QDBus.BlockWithGui,
+ QDBus.CallMode.BlockWithGui,
"Notify",
appname,
replaces_id,
@@ -1077,7 +1038,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
)
try:
- self._verify_message(reply, "u", QDBusMessage.ReplyMessage)
+ self._verify_message(reply, "u", QDBusMessage.MessageType.ReplyMessage)
except DBusError as e:
if e.is_fatal:
raise
@@ -1097,10 +1058,10 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
bits_per_color = 8
has_alpha = qimage.hasAlphaChannel()
if has_alpha:
- image_format = QImage.Format_RGBA8888
+ image_format = QImage.Format.Format_RGBA8888
channel_count = 4
else:
- image_format = QImage.Format_RGB888
+ image_format = QImage.Format.Format_RGB888
channel_count = 3
qimage.convertTo(image_format)
@@ -1117,14 +1078,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
image_data.add(bits_per_color)
image_data.add(channel_count)
- try:
- size = qimage.sizeInBytes()
- except TypeError:
- # WORKAROUND for
- # https://www.riverbankcomputing.com/pipermail/pyqt/2020-May/042919.html
- # byteCount() is obsolete, but sizeInBytes() is only available with
- # SIP >= 5.3.0.
- size = qimage.byteCount()
+ size = qimage.sizeInBytes()
# Despite the spec not mandating this, many notification daemons mandate that
# the last scanline does not have any padding bytes.
@@ -1166,11 +1120,11 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
def _handle_close(self, msg: QDBusMessage) -> None:
"""Handle NotificationClosed from DBus."""
try:
- self._verify_message(msg, "uu", QDBusMessage.SignalMessage)
+ self._verify_message(msg, "uu", QDBusMessage.MessageType.SignalMessage)
except Error:
if not self._quirks.wrong_closes_type:
raise
- self._verify_message(msg, "ui", QDBusMessage.SignalMessage)
+ self._verify_message(msg, "ui", QDBusMessage.MessageType.SignalMessage)
notification_id, _close_reason = msg.arguments()
self.close_id.emit(notification_id)
@@ -1178,7 +1132,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
@pyqtSlot(QDBusMessage)
def _handle_action(self, msg: QDBusMessage) -> None:
"""Handle ActionInvoked from DBus."""
- self._verify_message(msg, "us", QDBusMessage.SignalMessage)
+ self._verify_message(msg, "us", QDBusMessage.MessageType.SignalMessage)
notification_id, action_key = msg.arguments()
if action_key == "default":
self.click_id.emit(notification_id)
@@ -1187,7 +1141,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
def on_web_closed(self, notification_id: int) -> None:
"""Send CloseNotification if a notification was closed from JS."""
self.interface.call(
- QDBus.NoBlock,
+ QDBus.CallMode.NoBlock,
"CloseNotification",
_as_uint32(notification_id),
)
@@ -1195,10 +1149,10 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
def _fetch_capabilities(self) -> None:
"""Fetch capabilities from the notification server."""
reply = self.interface.call(
- QDBus.BlockWithGui,
+ QDBus.CallMode.BlockWithGui,
"GetCapabilities",
)
- self._verify_message(reply, "as", QDBusMessage.ReplyMessage)
+ self._verify_message(reply, "as", QDBusMessage.MessageType.ReplyMessage)
caplist = reply.arguments()[0]
self._capabilities = _ServerCapabilities.from_list(caplist)
@@ -1225,7 +1179,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
prefix = None
elif self._capabilities.body_markup and self._capabilities.body_hyperlinks:
href = html.escape(
- origin_url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ origin_url.toString(QUrl.ComponentFormattingOption.FullyEncoded) # type: ignore[arg-type]
)
text = html.escape(urlstr, quote=False)
prefix = f'<a href="{href}">{text}</a>'
diff --git a/qutebrowser/browser/webengine/tabhistory.py b/qutebrowser/browser/webengine/tabhistory.py
index ab4b05fe9..6efc6a2aa 100644
--- a/qutebrowser/browser/webengine/tabhistory.py
+++ b/qutebrowser/browser/webengine/tabhistory.py
@@ -19,7 +19,7 @@
"""QWebHistory serializer for QtWebEngine."""
-from PyQt5.QtCore import QByteArray, QDataStream, QIODevice, QUrl
+from qutebrowser.qt.core import QByteArray, QDataStream, QIODevice, QUrl
from qutebrowser.utils import qtutils
@@ -124,7 +124,7 @@ def serialize(items):
segfault!
"""
data = QByteArray()
- stream = QDataStream(data, QIODevice.ReadWrite)
+ stream = QDataStream(data, QIODevice.OpenModeFlag.ReadWrite)
cur_user_data = None
current_idx = None
diff --git a/qutebrowser/browser/webengine/webenginedownloads.py b/qutebrowser/browser/webengine/webenginedownloads.py
index a96f49d6b..2ac3dbdc3 100644
--- a/qutebrowser/browser/webengine/webenginedownloads.py
+++ b/qutebrowser/browser/webengine/webenginedownloads.py
@@ -23,8 +23,9 @@ import re
import os.path
import functools
-from PyQt5.QtCore import pyqtSlot, Qt, QUrl, QObject
-from PyQt5.QtWebEngineWidgets import QWebEngineDownloadItem
+from qutebrowser.qt import machinery
+from qutebrowser.qt.core import pyqtSlot, Qt, QUrl, QObject
+from qutebrowser.qt.webenginecore import QWebEngineDownloadRequest
from qutebrowser.browser import downloads, pdfjs
from qutebrowser.utils import (debug, usertypes, message, log, objreg, urlutils,
@@ -33,19 +34,34 @@ from qutebrowser.utils import (debug, usertypes, message, log, objreg, urlutils,
class DownloadItem(downloads.AbstractDownloadItem):
- """A wrapper over a QWebEngineDownloadItem.
+ """A wrapper over a QWebEngineDownloadRequest.
Attributes:
_qt_item: The wrapped item.
"""
- def __init__(self, qt_item: QWebEngineDownloadItem,
+ def __init__(self, qt_item: QWebEngineDownloadRequest,
manager: downloads.AbstractDownloadManager,
parent: QObject = None) -> None:
super().__init__(manager=manager, parent=manager)
self._qt_item = qt_item
- qt_item.downloadProgress.connect(self.stats.on_download_progress)
- qt_item.stateChanged.connect(self._on_state_changed)
+ if machinery.IS_QT5:
+ qt_item.downloadProgress.connect(self.stats.on_download_progress)
+ else: # Qt 6
+ qt_item.receivedBytesChanged.connect(
+ lambda: self.stats.on_download_progress(
+ qt_item.receivedBytes(),
+ qt_item.totalBytes(),
+ )
+ )
+ qt_item.totalBytesChanged.connect(
+ lambda: self.stats.on_download_progress(
+ qt_item.receivedBytes(),
+ qt_item.totalBytes(),
+ )
+ )
+ qt_item.stateChanged.connect(
+ self._on_state_changed)
# Ensure wrapped qt_item is deleted manually when the wrapper object
# is deleted. See https://github.com/qutebrowser/qutebrowser/issues/3373
@@ -54,19 +70,19 @@ class DownloadItem(downloads.AbstractDownloadItem):
def _is_page_download(self):
"""Check if this item is a page (i.e. mhtml) download."""
return (self._qt_item.savePageFormat() !=
- QWebEngineDownloadItem.UnknownSaveFormat)
+ QWebEngineDownloadRequest.SavePageFormat.UnknownSaveFormat)
- @pyqtSlot(QWebEngineDownloadItem.DownloadState)
+ @pyqtSlot(QWebEngineDownloadRequest.DownloadState)
def _on_state_changed(self, state):
- state_name = debug.qenum_key(QWebEngineDownloadItem, state)
+ state_name = debug.qenum_key(QWebEngineDownloadRequest, state)
log.downloads.debug("State for {!r} changed to {}".format(
self, state_name))
- if state == QWebEngineDownloadItem.DownloadRequested:
+ if state == QWebEngineDownloadRequest.DownloadState.DownloadRequested:
pass
- elif state == QWebEngineDownloadItem.DownloadInProgress:
+ elif state == QWebEngineDownloadRequest.DownloadState.DownloadInProgress:
pass
- elif state == QWebEngineDownloadItem.DownloadCompleted:
+ elif state == QWebEngineDownloadRequest.DownloadState.DownloadCompleted:
log.downloads.debug("Download {} finished".format(self.basename))
if self._is_page_download():
# Same logging as QtWebKit mhtml downloads.
@@ -75,12 +91,12 @@ class DownloadItem(downloads.AbstractDownloadItem):
self.done = True
self.finished.emit()
self.stats.finish()
- elif state == QWebEngineDownloadItem.DownloadCancelled:
+ elif state == QWebEngineDownloadRequest.DownloadState.DownloadCancelled:
self.successful = False
self.done = True
self.cancelled.emit()
self.stats.finish()
- elif state == QWebEngineDownloadItem.DownloadInterrupted:
+ elif state == QWebEngineDownloadRequest.DownloadState.DownloadInterrupted:
self.successful = False
reason = self._qt_item.interruptReasonString()
self._die(reason)
@@ -89,24 +105,28 @@ class DownloadItem(downloads.AbstractDownloadItem):
"{}".format(state_name))
def _do_die(self):
- progress_signal = self._qt_item.downloadProgress
- progress_signal.disconnect()
- if self._qt_item.state() != QWebEngineDownloadItem.DownloadInterrupted:
+ if machinery.IS_QT5:
+ self._qt_item.downloadProgress.disconnect()
+ else: # Qt 6
+ self._qt_item.receivedBytesChanged.disconnect()
+ self._qt_item.totalBytesChanged.disconnect()
+
+ if self._qt_item.state() != QWebEngineDownloadRequest.DownloadState.DownloadInterrupted:
self._qt_item.cancel()
def _do_cancel(self):
state = self._qt_item.state()
- state_name = debug.qenum_key(QWebEngineDownloadItem, state)
- assert state not in [QWebEngineDownloadItem.DownloadCompleted,
- QWebEngineDownloadItem.DownloadCancelled], state_name
+ state_name = debug.qenum_key(QWebEngineDownloadRequest, state)
+ assert state not in [QWebEngineDownloadRequest.DownloadState.DownloadCompleted,
+ QWebEngineDownloadRequest.DownloadState.DownloadCancelled], state_name
self._qt_item.cancel()
def retry(self):
state = self._qt_item.state()
- if state != QWebEngineDownloadItem.DownloadInterrupted:
+ if state != QWebEngineDownloadRequest.DownloadState.DownloadInterrupted:
log.downloads.warning(
"Refusing to retry download in state {}".format(
- debug.qenum_key(QWebEngineDownloadItem, state)))
+ debug.qenum_key(QWebEngineDownloadRequest, state)))
return
self._qt_item.resume()
@@ -131,8 +151,8 @@ class DownloadItem(downloads.AbstractDownloadItem):
def _ensure_can_set_filename(self, filename):
state = self._qt_item.state()
- if state != QWebEngineDownloadItem.DownloadRequested:
- state_name = debug.qenum_key(QWebEngineDownloadItem, state)
+ if state != QWebEngineDownloadRequest.DownloadState.DownloadRequested:
+ state_name = debug.qenum_key(QWebEngineDownloadRequest, state)
raise ValueError("Trying to set filename {} on {!r} which is "
"state {} (not in requested state)!".format(
filename, self, state_name))
@@ -174,12 +194,8 @@ class DownloadItem(downloads.AbstractDownloadItem):
assert self._filename is not None
dirname, basename = os.path.split(self._filename)
- try:
- # Qt 5.14
- self._qt_item.setDownloadDirectory(dirname)
- self._qt_item.setDownloadFileName(basename)
- except AttributeError:
- self._qt_item.setPath(self._filename)
+ self._qt_item.setDownloadDirectory(dirname)
+ self._qt_item.setDownloadFileName(basename)
self._qt_item.accept()
@@ -245,12 +261,12 @@ class DownloadManager(downloads.AbstractDownloadManager):
def install(self, profile):
"""Set up the download manager on a QWebEngineProfile."""
profile.downloadRequested.connect(self.handle_download,
- Qt.DirectConnection)
+ Qt.ConnectionType.DirectConnection)
- @pyqtSlot(QWebEngineDownloadItem)
+ @pyqtSlot(QWebEngineDownloadRequest)
def handle_download(self, qt_item):
"""Start a download coming from a QWebEngineProfile."""
- qt_filename = os.path.basename(qt_item.path()) # FIXME use 5.14 API
+ qt_filename = qt_item.downloadFileName()
mime_type = qt_item.mimeType()
url = qt_item.url()
diff --git a/qutebrowser/browser/webengine/webengineelem.py b/qutebrowser/browser/webengine/webengineelem.py
index 75b7a51ba..2e348055c 100644
--- a/qutebrowser/browser/webengine/webengineelem.py
+++ b/qutebrowser/browser/webengine/webengineelem.py
@@ -22,9 +22,9 @@
from typing import (
TYPE_CHECKING, Any, Callable, Dict, Iterator, Optional, Set, Tuple, Union)
-from PyQt5.QtCore import QRect, QEventLoop
-from PyQt5.QtWidgets import QApplication
-from PyQt5.QtWebEngineWidgets import QWebEngineSettings
+from qutebrowser.qt.core import QRect, QEventLoop
+from qutebrowser.qt.widgets import QApplication
+from qutebrowser.qt.webenginecore import QWebEngineSettings
from qutebrowser.utils import log, javascript, urlutils, usertypes, utils
from qutebrowser.browser import webelem
@@ -231,7 +231,6 @@ class WebEngineElement(webelem.AbstractWebElement):
return url.scheme() not in urlutils.WEBENGINE_SCHEMES
def _click_editable(self, click_target: usertypes.ClickTarget) -> None:
- self._tab.setFocus() # Needed as WORKAROUND on Qt 5.12
# This actually "clicks" the element by calling focus() on it in JS.
self._js_call('focus')
self._move_text_cursor()
@@ -242,7 +241,7 @@ class WebEngineElement(webelem.AbstractWebElement):
view = self._tab._widget
assert view is not None
# pylint: enable=protected-access
- attribute = QWebEngineSettings.JavascriptCanOpenWindows
+ attribute = QWebEngineSettings.WebAttribute.JavascriptCanOpenWindows
could_open_windows = view.settings().testAttribute(attribute)
view.settings().setAttribute(attribute, True)
@@ -251,8 +250,8 @@ class WebEngineElement(webelem.AbstractWebElement):
# This is also used in Qt's tests:
# https://github.com/qt/qtwebengine/commit/5e572e88efa7ba7c2b9138ec19e606d3e345ac90
QApplication.processEvents(
- QEventLoop.ExcludeSocketNotifiers |
- QEventLoop.ExcludeUserInputEvents)
+ QEventLoop.ProcessEventsFlag.ExcludeSocketNotifiers |
+ QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents)
def reset_setting(_arg: Any) -> None:
"""Set the JavascriptCanOpenWindows setting to its old value."""
diff --git a/qutebrowser/browser/webengine/webengineinspector.py b/qutebrowser/browser/webengine/webengineinspector.py
index 58babc70c..67158af1c 100644
--- a/qutebrowser/browser/webengine/webengineinspector.py
+++ b/qutebrowser/browser/webengine/webengineinspector.py
@@ -19,16 +19,17 @@
"""Customized QWebInspector for QtWebEngine."""
-import pathlib
+from typing import Optional
-from PyQt5.QtCore import QLibraryInfo
-from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt import machinery
+from qutebrowser.qt.webenginewidgets import QWebEngineView
+from qutebrowser.qt.webenginecore import QWebEnginePage
+from qutebrowser.qt.widgets import QWidget
from qutebrowser.browser import inspector
-from qutebrowser.browser.webengine import webenginesettings
+from qutebrowser.browser.webengine import webenginesettings, webview
from qutebrowser.misc import miscwidgets
-from qutebrowser.utils import version, usertypes
+from qutebrowser.utils import version, usertypes, qtutils
from qutebrowser.keyinput import modeman
@@ -49,9 +50,14 @@ class WebEngineInspectorView(QWebEngineView):
See WebEngineView.createWindow for details.
"""
- view = self.page().inspectedPage().view()
- assert isinstance(view, QWebEngineView), view
- return view.createWindow(wintype)
+ inspected_page = self.page().inspectedPage()
+ if machinery.IS_QT5:
+ view = inspected_page.view()
+ assert isinstance(view, QWebEngineView), view
+ return view.createWindow(wintype)
+ else: # Qt 6
+ newpage = inspected_page.createWindow(wintype)
+ return webview.WebEngineView.forPage(newpage)
class WebEngineInspector(inspector.AbstractWebInspector):
@@ -65,12 +71,7 @@ class WebEngineInspector(inspector.AbstractWebInspector):
parent: QWidget = None) -> None:
super().__init__(splitter, win_id, parent)
self._check_devtools_resources()
-
- view = WebEngineInspectorView()
- self._settings = webenginesettings.WebEngineSettings(view.settings())
- self._set_widget(view)
- page = view.page()
- page.windowCloseRequested.connect(self._on_window_close_requested)
+ self._settings: Optional[webenginesettings.WebEngineSettings] = None
def _on_window_close_requested(self) -> None:
"""Called when the 'x' was clicked in the devtools."""
@@ -92,7 +93,7 @@ class WebEngineInspector(inspector.AbstractWebInspector):
if dist is None or dist.parsed != version.Distribution.fedora:
return
- data_path = pathlib.Path(QLibraryInfo.location(QLibraryInfo.DataPath))
+ data_path = qtutils.library_path(qtutils.LibraryPath.data)
pak = data_path / 'resources' / 'qtwebengine_devtools_resources.pak'
if not pak.exists():
raise inspector.Error("QtWebEngine devtools resources not found, "
@@ -100,8 +101,22 @@ class WebEngineInspector(inspector.AbstractWebInspector):
"Fedora package.")
def inspect(self, page: QWebEnginePage) -> None:
+ if not self._widget:
+ view = WebEngineInspectorView()
+ inspector_page = QWebEnginePage(
+ page.profile(),
+ self
+ )
+ inspector_page.windowCloseRequested.connect(self._on_window_close_requested)
+ view.setPage(inspector_page)
+ self._settings = webenginesettings.WebEngineSettings(view.settings())
+ self._set_widget(view)
+
inspector_page = self._widget.page()
+ assert inspector_page.profile() == page.profile()
inspector_page.setInspectedPage(page)
+
+ assert self._settings is not None
self._settings.update_for_url(inspector_page.requestedUrl())
def _needs_recreate(self) -> bool:
diff --git a/qutebrowser/browser/webengine/webenginequtescheme.py b/qutebrowser/browser/webengine/webenginequtescheme.py
index 9e073951a..6fb809f6d 100644
--- a/qutebrowser/browser/webengine/webenginequtescheme.py
+++ b/qutebrowser/browser/webengine/webenginequtescheme.py
@@ -19,8 +19,8 @@
"""QtWebEngine specific qute://* handlers and glue code."""
-from PyQt5.QtCore import QBuffer, QIODevice, QUrl
-from PyQt5.QtWebEngineCore import (QWebEngineUrlSchemeHandler,
+from qutebrowser.qt.core import QBuffer, QIODevice, QUrl
+from qutebrowser.qt.webenginecore import (QWebEngineUrlSchemeHandler,
QWebEngineUrlRequestJob,
QWebEngineUrlScheme)
@@ -67,7 +67,7 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
log.network.warning("Blocking malicious request from {} to {}"
.format(initiator.toDisplayString(),
request_url.toDisplayString()))
- job.fail(QWebEngineUrlRequestJob.RequestDenied)
+ job.fail(QWebEngineUrlRequestJob.Error.RequestDenied)
return False
return True
@@ -87,7 +87,7 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
return
if job.requestMethod() != b'GET':
- job.fail(QWebEngineUrlRequestJob.RequestDenied)
+ job.fail(QWebEngineUrlRequestJob.Error.RequestDenied)
return
assert url.scheme() == 'qute'
@@ -98,15 +98,15 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
except qutescheme.Error as e:
errors = {
qutescheme.NotFoundError:
- QWebEngineUrlRequestJob.UrlNotFound,
+ QWebEngineUrlRequestJob.Error.UrlNotFound,
qutescheme.UrlInvalidError:
- QWebEngineUrlRequestJob.UrlInvalid,
+ QWebEngineUrlRequestJob.Error.UrlInvalid,
qutescheme.RequestDeniedError:
- QWebEngineUrlRequestJob.RequestDenied,
+ QWebEngineUrlRequestJob.Error.RequestDenied,
qutescheme.SchemeOSError:
- QWebEngineUrlRequestJob.UrlNotFound,
+ QWebEngineUrlRequestJob.Error.UrlNotFound,
qutescheme.Error:
- QWebEngineUrlRequestJob.RequestFailed,
+ QWebEngineUrlRequestJob.Error.RequestFailed,
}
exctype = type(e)
log.network.error(f"{exctype.__name__} while handling qute://* URL: {e}")
@@ -121,7 +121,7 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
# because that somehow segfaults...
# https://www.riverbankcomputing.com/pipermail/pyqt/2016-September/038075.html
buf = QBuffer(parent=self)
- buf.open(QIODevice.WriteOnly)
+ buf.open(QIODevice.OpenModeFlag.WriteOnly)
buf.write(data)
buf.seek(0)
buf.close()
@@ -138,6 +138,6 @@ def init():
assert not QWebEngineUrlScheme.schemeByName(b'qute').name()
scheme = QWebEngineUrlScheme(b'qute')
scheme.setFlags(
- QWebEngineUrlScheme.LocalScheme |
- QWebEngineUrlScheme.LocalAccessAllowed)
+ QWebEngineUrlScheme.Flag.LocalScheme |
+ QWebEngineUrlScheme.Flag.LocalAccessAllowed)
QWebEngineUrlScheme.registerScheme(scheme)
diff --git a/qutebrowser/browser/webengine/webenginesettings.py b/qutebrowser/browser/webengine/webenginesettings.py
index 1ffb55337..8a8c4766f 100644
--- a/qutebrowser/browser/webengine/webenginesettings.py
+++ b/qutebrowser/browser/webengine/webenginesettings.py
@@ -26,11 +26,13 @@ Module attributes:
import os
import operator
+import pathlib
from typing import cast, Any, List, Optional, Tuple, Union, TYPE_CHECKING
-from PyQt5.QtGui import QFont
-from PyQt5.QtWidgets import QApplication
-from PyQt5.QtWebEngineWidgets import QWebEngineSettings, QWebEngineProfile
+from qutebrowser.qt import machinery
+from qutebrowser.qt.gui import QFont
+from qutebrowser.qt.widgets import QApplication
+from qutebrowser.qt.webenginecore import QWebEngineSettings, QWebEngineProfile
from qutebrowser.browser import history
from qutebrowser.browser.webengine import (spell, webenginequtescheme, cookies,
@@ -110,91 +112,91 @@ class WebEngineSettings(websettings.AbstractSettings):
_ATTRIBUTES = {
'content.xss_auditing':
- Attr(QWebEngineSettings.XSSAuditingEnabled),
+ Attr(QWebEngineSettings.WebAttribute.XSSAuditingEnabled),
'content.images':
- Attr(QWebEngineSettings.AutoLoadImages),
+ Attr(QWebEngineSettings.WebAttribute.AutoLoadImages),
'content.javascript.enabled':
- Attr(QWebEngineSettings.JavascriptEnabled),
+ Attr(QWebEngineSettings.WebAttribute.JavascriptEnabled),
'content.javascript.can_open_tabs_automatically':
- Attr(QWebEngineSettings.JavascriptCanOpenWindows),
+ Attr(QWebEngineSettings.WebAttribute.JavascriptCanOpenWindows),
'content.plugins':
- Attr(QWebEngineSettings.PluginsEnabled),
+ Attr(QWebEngineSettings.WebAttribute.PluginsEnabled),
'content.hyperlink_auditing':
- Attr(QWebEngineSettings.HyperlinkAuditingEnabled),
+ Attr(QWebEngineSettings.WebAttribute.HyperlinkAuditingEnabled),
'content.local_content_can_access_remote_urls':
- Attr(QWebEngineSettings.LocalContentCanAccessRemoteUrls),
+ Attr(QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls),
'content.local_content_can_access_file_urls':
- Attr(QWebEngineSettings.LocalContentCanAccessFileUrls),
+ Attr(QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls),
'content.webgl':
- Attr(QWebEngineSettings.WebGLEnabled),
+ Attr(QWebEngineSettings.WebAttribute.WebGLEnabled),
'content.local_storage':
- Attr(QWebEngineSettings.LocalStorageEnabled),
+ Attr(QWebEngineSettings.WebAttribute.LocalStorageEnabled),
'content.desktop_capture':
- Attr(QWebEngineSettings.ScreenCaptureEnabled,
+ Attr(QWebEngineSettings.WebAttribute.ScreenCaptureEnabled,
converter=lambda val: True if val == 'ask' else val),
# 'ask' is handled via the permission system
'input.spatial_navigation':
- Attr(QWebEngineSettings.SpatialNavigationEnabled),
+ Attr(QWebEngineSettings.WebAttribute.SpatialNavigationEnabled),
'input.links_included_in_focus_chain':
- Attr(QWebEngineSettings.LinksIncludedInFocusChain),
+ Attr(QWebEngineSettings.WebAttribute.LinksIncludedInFocusChain),
'scrolling.smooth':
- Attr(QWebEngineSettings.ScrollAnimatorEnabled),
+ Attr(QWebEngineSettings.WebAttribute.ScrollAnimatorEnabled),
'content.print_element_backgrounds':
- Attr(QWebEngineSettings.PrintElementBackgrounds),
+ Attr(QWebEngineSettings.WebAttribute.PrintElementBackgrounds),
'content.autoplay':
- Attr(QWebEngineSettings.PlaybackRequiresUserGesture,
+ Attr(QWebEngineSettings.WebAttribute.PlaybackRequiresUserGesture,
converter=operator.not_),
'content.dns_prefetch':
- Attr(QWebEngineSettings.DnsPrefetchEnabled),
+ Attr(QWebEngineSettings.WebAttribute.DnsPrefetchEnabled),
'tabs.favicons.show':
- Attr(QWebEngineSettings.AutoLoadIconsForPage,
+ Attr(QWebEngineSettings.WebAttribute.AutoLoadIconsForPage,
converter=lambda val: val != 'never'),
}
_FONT_SIZES = {
'fonts.web.size.minimum':
- QWebEngineSettings.MinimumFontSize,
+ QWebEngineSettings.FontSize.MinimumFontSize,
'fonts.web.size.minimum_logical':
- QWebEngineSettings.MinimumLogicalFontSize,
+ QWebEngineSettings.FontSize.MinimumLogicalFontSize,
'fonts.web.size.default':
- QWebEngineSettings.DefaultFontSize,
+ QWebEngineSettings.FontSize.DefaultFontSize,
'fonts.web.size.default_fixed':
- QWebEngineSettings.DefaultFixedFontSize,
+ QWebEngineSettings.FontSize.DefaultFixedFontSize,
}
_FONT_FAMILIES = {
- 'fonts.web.family.standard': QWebEngineSettings.StandardFont,
- 'fonts.web.family.fixed': QWebEngineSettings.FixedFont,
- 'fonts.web.family.serif': QWebEngineSettings.SerifFont,
- 'fonts.web.family.sans_serif': QWebEngineSettings.SansSerifFont,
- 'fonts.web.family.cursive': QWebEngineSettings.CursiveFont,
- 'fonts.web.family.fantasy': QWebEngineSettings.FantasyFont,
+ 'fonts.web.family.standard': QWebEngineSettings.FontFamily.StandardFont,
+ 'fonts.web.family.fixed': QWebEngineSettings.FontFamily.FixedFont,
+ 'fonts.web.family.serif': QWebEngineSettings.FontFamily.SerifFont,
+ 'fonts.web.family.sans_serif': QWebEngineSettings.FontFamily.SansSerifFont,
+ 'fonts.web.family.cursive': QWebEngineSettings.FontFamily.CursiveFont,
+ 'fonts.web.family.fantasy': QWebEngineSettings.FontFamily.FantasyFont,
}
_UNKNOWN_URL_SCHEME_POLICY = {
'disallow':
- QWebEngineSettings.DisallowUnknownUrlSchemes,
+ QWebEngineSettings.UnknownUrlSchemePolicy.DisallowUnknownUrlSchemes,
'allow-from-user-interaction':
- QWebEngineSettings.AllowUnknownUrlSchemesFromUserInteraction,
+ QWebEngineSettings.UnknownUrlSchemePolicy.AllowUnknownUrlSchemesFromUserInteraction,
'allow-all':
- QWebEngineSettings.AllowAllUnknownUrlSchemes,
+ QWebEngineSettings.UnknownUrlSchemePolicy.AllowAllUnknownUrlSchemes,
}
# Mapping from WebEngineSettings::initDefaults in
# qtwebengine/src/core/web_engine_settings.cpp
_FONT_TO_QFONT = {
- QWebEngineSettings.StandardFont: QFont.Serif,
- QWebEngineSettings.FixedFont: QFont.Monospace,
- QWebEngineSettings.SerifFont: QFont.Serif,
- QWebEngineSettings.SansSerifFont: QFont.SansSerif,
- QWebEngineSettings.CursiveFont: QFont.Cursive,
- QWebEngineSettings.FantasyFont: QFont.Fantasy,
+ QWebEngineSettings.FontFamily.StandardFont: QFont.StyleHint.Serif,
+ QWebEngineSettings.FontFamily.FixedFont: QFont.StyleHint.Monospace,
+ QWebEngineSettings.FontFamily.SerifFont: QFont.StyleHint.Serif,
+ QWebEngineSettings.FontFamily.SansSerifFont: QFont.StyleHint.SansSerif,
+ QWebEngineSettings.FontFamily.CursiveFont: QFont.StyleHint.Cursive,
+ QWebEngineSettings.FontFamily.FantasyFont: QFont.StyleHint.Fantasy,
}
_JS_CLIPBOARD_SETTINGS = {
@@ -256,15 +258,10 @@ class ProfileSetter:
'content.cache.size': self.set_http_cache_size,
'content.cookies.store': self.set_persistent_cookie_policy,
'spellcheck.languages': self.set_dictionary_language,
+ 'content.headers.user_agent': self.set_http_headers,
+ 'content.headers.accept_language': self.set_http_headers,
}
- # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-75884
- # (note this isn't actually fixed properly before Qt 5.15)
- header_bug_fixed = qtutils.version_check('5.15', compiled=False)
- if header_bug_fixed:
- for name in ['user_agent', 'accept_language']:
- self._name_to_method[f'content.headers.{name}'] = self.set_http_headers
-
def update_setting(self, name):
"""Update a setting based on its name."""
try:
@@ -286,15 +283,10 @@ class ProfileSetter:
settings = self._profile.settings()
settings.setAttribute(
- QWebEngineSettings.FullScreenSupportEnabled, True)
+ QWebEngineSettings.WebAttribute.FullScreenSupportEnabled, True)
settings.setAttribute(
- QWebEngineSettings.FocusOnNavigationEnabled, False)
-
- try:
- settings.setAttribute(QWebEngineSettings.PdfViewerEnabled, False)
- except AttributeError:
- # Added in Qt 5.13
- pass
+ QWebEngineSettings.WebAttribute.FocusOnNavigationEnabled, False)
+ settings.setAttribute(QWebEngineSettings.WebAttribute.PdfViewerEnabled, False)
def set_http_headers(self):
"""Set the user agent and accept-language for the given profile.
@@ -326,9 +318,9 @@ class ProfileSetter:
if self._profile.isOffTheRecord():
return
if config.val.content.cookies.store:
- value = QWebEngineProfile.AllowPersistentCookies
+ value = QWebEngineProfile.PersistentCookiesPolicy.AllowPersistentCookies
else:
- value = QWebEngineProfile.NoPersistentCookies
+ value = QWebEngineProfile.PersistentCookiesPolicy.NoPersistentCookies
self._profile.setPersistentCookiesPolicy(value)
def set_dictionary_language(self):
@@ -397,7 +389,11 @@ def _init_default_profile():
"""Init the default QWebEngineProfile."""
global default_profile
- default_profile = QWebEngineProfile.defaultProfile()
+ if machinery.IS_QT6:
+ default_profile = QWebEngineProfile("Default")
+ else:
+ default_profile = QWebEngineProfile.defaultProfile()
+ assert not default_profile.isOffTheRecord()
assert parsed_user_agent is None # avoid earlier profile initialization
non_ua_version = version.qtwebengine_versions(avoid_init=True)
@@ -470,6 +466,7 @@ def _init_site_specific_quirks():
# Needed because Slack adds an error which prevents using it relatively
# aggressively, despite things actually working fine.
# September 2020: Qt 5.12 works, but Qt <= 5.11 shows the error.
+ # FIXME:qt6 Still needed?
# https://github.com/qutebrowser/qutebrowser/issues/4669
("ua-slack", 'https://*.slack.com/*', new_chrome_ua),
]
@@ -489,20 +486,37 @@ def _init_site_specific_quirks():
)
-def _init_devtools_settings():
- """Make sure the devtools always get images/JS permissions."""
- settings: List[Tuple[str, Any]] = [
+def _init_default_settings():
+ """Set permissions required for internal functionality.
+
+ - Make sure the devtools always get images/JS permissions.
+ - On Qt 6, make sure files in the data path can load external resources.
+ """
+ devtools_settings: List[Tuple[str, Any]] = [
('content.javascript.enabled', True),
('content.images', True),
('content.cookies.accept', 'all'),
]
- for setting, value in settings:
+ for setting, value in devtools_settings:
for pattern in ['chrome-devtools://*', 'devtools://*']:
config.instance.set_obj(setting, value,
pattern=urlmatch.UrlPattern(pattern),
hide_userconfig=True)
+ if machinery.IS_QT6:
+ userscripts_settings: List[Tuple[str, Any]] = [
+ ("content.local_content_can_access_remote_urls", True),
+ ("content.local_content_can_access_file_urls", False),
+ ]
+ # https://codereview.qt-project.org/c/qt/qtwebengine/+/375672
+ url = pathlib.Path(standarddir.data(), "userscripts").as_uri()
+ for setting, value in userscripts_settings:
+ config.instance.set_obj(setting,
+ value,
+ pattern=urlmatch.UrlPattern(f"{url}/*"),
+ hide_userconfig=True)
+
def init():
"""Initialize the global QWebSettings."""
@@ -543,7 +557,7 @@ def init():
log.init.debug("Misc initialization...")
_init_site_specific_quirks()
- _init_devtools_settings()
+ _init_default_settings()
def shutdown():
diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py
index 6cd0e7526..6f0ea82f3 100644
--- a/qutebrowser/browser/webengine/webenginetab.py
+++ b/qutebrowser/browser/webengine/webenginetab.py
@@ -26,11 +26,11 @@ import re
import html as html_utils
from typing import cast, Union, Optional
-from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QPoint, QPointF, QTimer, QUrl,
+from qutebrowser.qt.core import (pyqtSignal, pyqtSlot, Qt, QPoint, QPointF, QTimer, QUrl,
QObject)
-from PyQt5.QtNetwork import QAuthenticator
-from PyQt5.QtWebEngineWidgets import (QWebEnginePage, QWebEngineView, QWebEngineScript,
- QWebEngineHistory)
+from qutebrowser.qt.network import QAuthenticator
+from qutebrowser.qt.webenginewidgets import QWebEngineView
+from qutebrowser.qt.webenginecore import QWebEnginePage, QWebEngineScript, QWebEngineHistory
from qutebrowser.config import config
from qutebrowser.browser import browsertab, eventfilter, shared, webelem, greasemonkey
@@ -40,16 +40,16 @@ from qutebrowser.browser.webengine import (webview, webengineelem, tabhistory,
from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils,
resources, message, jinja, debug, version)
-from qutebrowser.qt import sip
+from qutebrowser.qt import sip, machinery
from qutebrowser.misc import objects, miscwidgets
# Mapping worlds from usertypes.JsWorld to QWebEngineScript world IDs.
_JS_WORLD_MAP = {
- usertypes.JsWorld.main: QWebEngineScript.MainWorld,
- usertypes.JsWorld.application: QWebEngineScript.ApplicationWorld,
- usertypes.JsWorld.user: QWebEngineScript.UserWorld,
- usertypes.JsWorld.jseval: QWebEngineScript.UserWorld + 1,
+ usertypes.JsWorld.main: QWebEngineScript.ScriptWorldId.MainWorld,
+ usertypes.JsWorld.application: QWebEngineScript.ScriptWorldId.ApplicationWorld,
+ usertypes.JsWorld.user: QWebEngineScript.ScriptWorldId.UserWorld,
+ usertypes.JsWorld.jseval: QWebEngineScript.ScriptWorldId.UserWorld + 1,
}
@@ -58,23 +58,21 @@ class WebEngineAction(browsertab.AbstractAction):
"""QtWebEngine implementations related to web actions."""
_widget: webview.WebEngineView
-
- action_class = QWebEnginePage
action_base = QWebEnginePage.WebAction
def exit_fullscreen(self):
- self._widget.triggerPageAction(QWebEnginePage.ExitFullScreen)
+ self._widget.triggerPageAction(QWebEnginePage.WebAction.ExitFullScreen)
def save_page(self):
"""Save the current page."""
- self._widget.triggerPageAction(QWebEnginePage.SavePage)
+ self._widget.triggerPageAction(QWebEnginePage.WebAction.SavePage)
def show_source(self, pygments=False):
if pygments:
self._show_source_pygments()
return
- self._widget.triggerPageAction(QWebEnginePage.ViewSource)
+ self._widget.triggerPageAction(QWebEnginePage.WebAction.ViewSource)
class WebEnginePrinting(browsertab.AbstractPrinting):
@@ -83,6 +81,14 @@ class WebEnginePrinting(browsertab.AbstractPrinting):
_widget: webview.WebEngineView
+ def connect_signals(self):
+ """Called from WebEngineTab.connect_signals."""
+ page = self._widget.page()
+ page.pdfPrintingFinished.connect(self.pdf_printing_finished)
+ if machinery.IS_QT6:
+ self._widget.printFinished.connect(self.printing_finished)
+ # Qt 5 uses callbacks instead
+
def check_pdf_support(self):
pass
@@ -93,8 +99,11 @@ class WebEnginePrinting(browsertab.AbstractPrinting):
def to_pdf(self, filename):
self._widget.page().printToPdf(filename)
- def to_printer(self, printer, callback=lambda ok: None):
- self._widget.page().print(printer, callback)
+ def to_printer(self, printer):
+ if machinery.IS_QT5:
+ self._widget.page().print(printer, self.printing_finished.emit)
+ else: # Qt 6
+ self._widget.print(printer)
@dataclasses.dataclass
@@ -159,22 +168,6 @@ class WebEngineSearch(browsertab.AbstractSearch):
def connect_signals(self):
"""Connect the signals necessary for this class to function."""
- # The API necessary to stop wrapping was added in this version
- if not qtutils.version_check("5.14"):
- return
-
- try:
- # pylint: disable=unused-import
- from PyQt5.QtWebEngineCore import QWebEngineFindTextResult
- except ImportError:
- # WORKAROUND for some odd PyQt/packaging bug where the
- # findTextResult signal is available, but QWebEngineFindTextResult
- # is not. Seems to happen on e.g. Gentoo.
- log.webview.warning("Could not import QWebEngineFindTextResult "
- "despite running on Qt 5.14. You might need "
- "to rebuild PyQtWebEngine.")
- return
-
self._widget.page().findTextFinished.connect(self._on_find_finished)
def _find(self, text, flags, callback, caller):
@@ -182,7 +175,7 @@ class WebEngineSearch(browsertab.AbstractSearch):
self.search_displayed = True
self._pending_searches += 1
- def wrapped_callback(found):
+ def wrapped_callback(cb_arg):
"""Wrap the callback to do debug logging."""
self._pending_searches -= 1
if self._pending_searches > 0:
@@ -200,6 +193,11 @@ class WebEngineSearch(browsertab.AbstractSearch):
"widget")
return
+ # bool in Qt 5, QWebEngineFindTextResult in Qt 6
+ # Once we drop Qt 5, we might also want to call callbacks with the
+ # QWebEngineFindTextResult instead of the bool.
+ found = cb_arg if isinstance(cb_arg, bool) else cb_arg.numberOfMatches() > 0
+
found_text = 'found' if found else "didn't find"
if flags:
flag_text = f'with flags {flags}'
@@ -400,6 +398,7 @@ class WebEngineCaret(browsertab.AbstractCaret):
# https://bugreports.qt.io/browse/QTBUG-53134
# Even on Qt 5.10 selectedText() seems to work poorly, see
# https://github.com/qutebrowser/qutebrowser/issues/3523
+ # FIXME:qt6 Reevaluate?
self._tab.run_js_async(javascript.assemble('caret', 'getSelection'),
callback)
@@ -506,7 +505,7 @@ class WebEngineScroller(browsertab.AbstractScroller):
page = widget.page()
page.scrollPositionChanged.connect(self._update_pos)
- def _repeated_key_press(self, key, count=1, modifier=Qt.NoModifier):
+ def _repeated_key_press(self, key, count=1, modifier=Qt.KeyboardModifier.NoModifier):
"""Send count fake key presses to this scroller's WebEngineTab."""
for _ in range(min(count, 1000)):
self._tab.fake_key_press(key, modifier)
@@ -585,28 +584,28 @@ class WebEngineScroller(browsertab.AbstractScroller):
self._tab.run_js_async(js_code)
def up(self, count=1):
- self._repeated_key_press(Qt.Key_Up, count)
+ self._repeated_key_press(Qt.Key.Key_Up, count)
def down(self, count=1):
- self._repeated_key_press(Qt.Key_Down, count)
+ self._repeated_key_press(Qt.Key.Key_Down, count)
def left(self, count=1):
- self._repeated_key_press(Qt.Key_Left, count)
+ self._repeated_key_press(Qt.Key.Key_Left, count)
def right(self, count=1):
- self._repeated_key_press(Qt.Key_Right, count)
+ self._repeated_key_press(Qt.Key.Key_Right, count)
def top(self):
- self._tab.fake_key_press(Qt.Key_Home)
+ self._tab.fake_key_press(Qt.Key.Key_Home)
def bottom(self):
- self._tab.fake_key_press(Qt.Key_End)
+ self._tab.fake_key_press(Qt.Key.Key_End)
def page_up(self, count=1):
- self._repeated_key_press(Qt.Key_PageUp, count)
+ self._repeated_key_press(Qt.Key.Key_PageUp, count)
def page_down(self, count=1):
- self._repeated_key_press(Qt.Key_PageDown, count)
+ self._repeated_key_press(Qt.Key.Key_PageDown, count)
def at_top(self):
return self.pos_px().y() == 0
@@ -650,11 +649,13 @@ class WebEngineHistoryPrivate(browsertab.AbstractHistoryPrivate):
self._tab.load_url(url)
def load_items(self, items):
- webengine_version = version.qtwebengine_versions().webengine
- if webengine_version >= utils.VersionNumber(5, 15):
- self._load_items_workaround(items)
- return
+ self._load_items_workaround(items)
+
+ def _load_items_proper(self, items):
+ """Load session items properly.
+ Currently unused, but should be revived.
+ """
if items:
self._tab.before_load_started.emit(items[-1].url)
@@ -813,7 +814,7 @@ class WebEngineAudio(browsertab.AbstractAudio):
self._overridden = False
# Implements the intended two-second delay specified at
- # https://doc.qt.io/qt-5/qwebenginepage.html#recentlyAudibleChanged
+ # https://doc.qt.io/archives/qt-5.14/qwebenginepage.html#recentlyAudibleChanged
delay_ms = 2000
self._silence_timer = QTimer(self)
self._silence_timer.setSingleShot(True)
@@ -845,15 +846,10 @@ class WebEngineAudio(browsertab.AbstractAudio):
timer.start()
def set_muted(self, muted: bool, override: bool = False) -> None:
- was_muted = self.is_muted()
self._overridden = override
assert self._widget is not None
page = self._widget.page()
page.setAudioMuted(muted)
- if was_muted != muted and qtutils.version_check('5.15'):
- # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-85118
- # so that the tab title at least updates the muted indicator
- self.muted_changed.emit(muted)
def is_muted(self):
page = self._widget.page()
@@ -881,29 +877,26 @@ class _WebEnginePermissions(QObject):
_widget: webview.WebEngineView
- # Using 0 as WORKAROUND for:
- # https://www.riverbankcomputing.com/pipermail/pyqt/2019-July/041903.html
-
_options = {
- 0: 'content.notifications.enabled',
- QWebEnginePage.Geolocation: 'content.geolocation',
- QWebEnginePage.MediaAudioCapture: 'content.media.audio_capture',
- QWebEnginePage.MediaVideoCapture: 'content.media.video_capture',
- QWebEnginePage.MediaAudioVideoCapture: 'content.media.audio_video_capture',
- QWebEnginePage.MouseLock: 'content.mouse_lock',
- QWebEnginePage.DesktopVideoCapture: 'content.desktop_capture',
- QWebEnginePage.DesktopAudioVideoCapture: 'content.desktop_capture',
+ QWebEnginePage.Feature.Notifications: 'content.notifications.enabled',
+ QWebEnginePage.Feature.Geolocation: 'content.geolocation',
+ QWebEnginePage.Feature.MediaAudioCapture: 'content.media.audio_capture',
+ QWebEnginePage.Feature.MediaVideoCapture: 'content.media.video_capture',
+ QWebEnginePage.Feature.MediaAudioVideoCapture: 'content.media.audio_video_capture',
+ QWebEnginePage.Feature.MouseLock: 'content.mouse_lock',
+ QWebEnginePage.Feature.DesktopVideoCapture: 'content.desktop_capture',
+ QWebEnginePage.Feature.DesktopAudioVideoCapture: 'content.desktop_capture',
}
_messages = {
- 0: 'show notifications',
- QWebEnginePage.Geolocation: 'access your location',
- QWebEnginePage.MediaAudioCapture: 'record audio',
- QWebEnginePage.MediaVideoCapture: 'record video',
- QWebEnginePage.MediaAudioVideoCapture: 'record audio/video',
- QWebEnginePage.MouseLock: 'hide your mouse pointer',
- QWebEnginePage.DesktopVideoCapture: 'capture your desktop',
- QWebEnginePage.DesktopAudioVideoCapture: 'capture your desktop and audio',
+ QWebEnginePage.Feature.Notifications: 'show notifications',
+ QWebEnginePage.Feature.Geolocation: 'access your location',
+ QWebEnginePage.Feature.MediaAudioCapture: 'record audio',
+ QWebEnginePage.Feature.MediaVideoCapture: 'record video',
+ QWebEnginePage.Feature.MediaAudioVideoCapture: 'record audio/video',
+ QWebEnginePage.Feature.MouseLock: 'hide your mouse pointer',
+ QWebEnginePage.Feature.DesktopVideoCapture: 'capture your desktop',
+ QWebEnginePage.Feature.DesktopAudioVideoCapture: 'capture your desktop and audio',
}
def __init__(self, tab, parent=None):
@@ -944,22 +937,15 @@ class _WebEnginePermissions(QObject):
page = self._widget.page()
grant_permission = functools.partial(
page.setFeaturePermission, url, feature,
- QWebEnginePage.PermissionGrantedByUser)
+ QWebEnginePage.PermissionPolicy.PermissionGrantedByUser)
deny_permission = functools.partial(
page.setFeaturePermission, url, feature,
- QWebEnginePage.PermissionDeniedByUser)
+ QWebEnginePage.PermissionPolicy.PermissionDeniedByUser)
permission_str = debug.qenum_key(QWebEnginePage, feature)
if not url.isValid():
- # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-85116
- is_qtbug = (qtutils.version_check('5.15.0',
- compiled=False,
- exact=True) and
- self._tab.is_private and
- feature == QWebEnginePage.Notifications)
- logger = log.webview.debug if is_qtbug else log.webview.warning
- logger("Ignoring feature permission {} for invalid URL {}".format(
+ log.webview.warning("Ignoring feature permission {} for invalid URL {}".format(
permission_str, url))
deny_permission()
return
@@ -970,20 +956,8 @@ class _WebEnginePermissions(QObject):
deny_permission()
return
- if (
- feature in [QWebEnginePage.DesktopVideoCapture,
- QWebEnginePage.DesktopAudioVideoCapture] and
- qtutils.version_check('5.13', compiled=False) and
- not qtutils.version_check('5.13.2', compiled=False)
- ):
- # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-78016
- log.webview.warning("Ignoring desktop sharing request due to "
- "crashes in Qt < 5.13.2")
- deny_permission()
- return
-
question = shared.feature_permission(
- url=url.adjusted(QUrl.RemovePath),
+ url=url.adjusted(QUrl.UrlFormattingOption.RemovePath),
option=self._options[feature], msg=self._messages[feature],
yes_action=grant_permission, no_action=deny_permission,
abort_on=[self._tab.abort_questions])
@@ -1010,7 +984,7 @@ class _WebEnginePermissions(QObject):
def _on_quota_requested(self, request):
size = utils.format_size(request.requestedSize())
shared.feature_permission(
- url=request.origin().adjusted(QUrl.RemovePath),
+ url=request.origin().adjusted(QUrl.UrlFormattingOption.RemovePath),
option='content.persistent_storage',
msg='use {} of persistent storage'.format(size),
yes_action=request.accept, no_action=request.reject,
@@ -1019,7 +993,7 @@ class _WebEnginePermissions(QObject):
def _on_register_protocol_handler_requested(self, request):
shared.feature_permission(
- url=request.origin().adjusted(QUrl.RemovePath),
+ url=request.origin().adjusted(QUrl.UrlFormattingOption.RemovePath),
option='content.register_protocol_handler',
msg='open all {} links'.format(request.scheme()),
yes_action=request.accept, no_action=request.reject,
@@ -1032,8 +1006,8 @@ class _Quirk:
filename: str
injection_point: QWebEngineScript.InjectionPoint = (
- QWebEngineScript.DocumentCreation)
- world: QWebEngineScript.ScriptWorldId = QWebEngineScript.MainWorld
+ QWebEngineScript.InjectionPoint.DocumentCreation)
+ world: QWebEngineScript.ScriptWorldId = QWebEngineScript.ScriptWorldId.MainWorld
predicate: bool = True
name: Optional[str] = None
@@ -1074,8 +1048,8 @@ class _WebEngineScripts(QObject):
self._tab.run_js_async(code)
def _inject_js(self, name, js_code, *,
- world=QWebEngineScript.ApplicationWorld,
- injection_point=QWebEngineScript.DocumentCreation,
+ world=QWebEngineScript.ScriptWorldId.ApplicationWorld,
+ injection_point=QWebEngineScript.InjectionPoint.DocumentCreation,
subframes=False):
"""Inject the given script to run early on a page load."""
script = QWebEngineScript()
@@ -1089,9 +1063,13 @@ class _WebEngineScripts(QObject):
def _remove_js(self, name):
"""Remove an early QWebEngineScript."""
scripts = self._widget.page().scripts()
- script = scripts.findScript(f'_qute_{name}')
- if not script.isNull():
- scripts.remove(script)
+ if machinery.IS_QT6:
+ for script in scripts.find(f'_qute_{name}'):
+ scripts.remove(script)
+ else: # Qt 5
+ script = scripts.findScript(f'_qute_{name}')
+ if not script.isNull():
+ scripts.remove(script)
def init(self):
"""Initialize global qutebrowser JavaScript."""
@@ -1184,13 +1162,13 @@ class _WebEngineScripts(QObject):
# Corresponds to "@run-at document-end" which is the default according to
# https://wiki.greasespot.net/Metadata_Block#.40run-at - however,
- # QtWebEngine uses QWebEngineScript.Deferred (@run-at document-idle) as
+ # QtWebEngine uses QWebEngineScript.InjectionPoint.Deferred (@run-at document-idle) as
# default.
#
# NOTE that this needs to be done before setSourceCode, so that
# QtWebEngine's parsing of GreaseMonkey tags will override it if there is a
# @run-at comment.
- new_script.setInjectionPoint(QWebEngineScript.DocumentReady)
+ new_script.setInjectionPoint(QWebEngineScript.InjectionPoint.DocumentReady)
new_script.setSourceCode(script.code())
new_script.setName(script.full_name())
@@ -1199,22 +1177,20 @@ class _WebEngineScripts(QObject):
if script.needs_document_end_workaround():
log.greasemonkey.debug(
f"Forcing @run-at document-end for {script.name}")
- new_script.setInjectionPoint(QWebEngineScript.DocumentReady)
+ new_script.setInjectionPoint(QWebEngineScript.InjectionPoint.DocumentReady)
log.greasemonkey.debug(f'adding script: {new_script.name()}')
page_scripts.insert(new_script)
- def _inject_site_specific_quirks(self):
- """Add site-specific quirk scripts."""
- if not config.val.content.site_specific_quirks.enabled:
- return
-
+ def _get_quirks(self):
+ """Get a list of all available JS quirks."""
versions = version.qtwebengine_versions()
- quirks = [
+ return [
+ # FIXME:qt6 Double check which of those are still required
_Quirk(
'whatsapp_web',
- injection_point=QWebEngineScript.DocumentReady,
- world=QWebEngineScript.ApplicationWorld,
+ injection_point=QWebEngineScript.InjectionPoint.DocumentReady,
+ world=QWebEngineScript.ScriptWorldId.ApplicationWorld,
),
_Quirk('discord'),
_Quirk(
@@ -1222,25 +1198,23 @@ class _WebEngineScripts(QObject):
# will be an UA quirk once we set the JS UA as well
name='ua-googledocs',
),
+
_Quirk(
'string_replaceall',
predicate=versions.webengine < utils.VersionNumber(5, 15, 3),
),
_Quirk(
- 'globalthis',
- predicate=versions.webengine < utils.VersionNumber(5, 13),
- ),
- _Quirk(
- 'object_fromentries',
- predicate=versions.webengine < utils.VersionNumber(5, 13),
- ),
- _Quirk(
'array_at',
- predicate=versions.webengine < utils.VersionNumber(6, 2),
+ predicate=versions.webengine < utils.VersionNumber(6, 3),
),
]
- for quirk in quirks:
+ def _inject_site_specific_quirks(self):
+ """Add site-specific quirk scripts."""
+ if not config.val.content.site_specific_quirks.enabled:
+ return
+
+ for quirk in self._get_quirks():
if not quirk.predicate:
continue
src = resources.read_file(f'javascript/quirks/{quirk.filename}.user.js')
@@ -1297,6 +1271,7 @@ class WebEngineTab(browsertab.AbstractTab):
_widget: QWebEngineView
search: WebEngineSearch
audio: WebEngineAudio
+ printing: WebEnginePrinting
def __init__(self, *, win_id, mode_manager, private, parent=None):
super().__init__(win_id=win_id,
@@ -1311,7 +1286,7 @@ class WebEngineTab(browsertab.AbstractTab):
tab=self, parent=self)
self.zoom = WebEngineZoom(tab=self, parent=self)
self.search = WebEngineSearch(tab=self, parent=self)
- self.printing = WebEnginePrinting(tab=self)
+ self.printing = WebEnginePrinting(tab=self, parent=self)
self.elements = WebEngineElements(tab=self)
self.action = WebEngineAction(tab=self)
self.audio = WebEngineAudio(tab=self, parent=self)
@@ -1327,6 +1302,9 @@ class WebEngineTab(browsertab.AbstractTab):
self._child_event_filter = None
self._saved_zoom = None
self._scripts.init()
+ # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-65223
+ self._needs_qtbug65223_workaround = (
+ version.qtwebengine_versions().webengine < utils.VersionNumber(5, 15, 5))
def _set_widget(self, widget):
# pylint: disable=protected-access
@@ -1384,7 +1362,7 @@ class WebEngineTab(browsertab.AbstractTab):
def run_js_async(self, code, callback=None, *, world=None):
world_id_type = Union[QWebEngineScript.ScriptWorldId, int]
if world is None:
- world_id: world_id_type = QWebEngineScript.ApplicationWorld
+ world_id: world_id_type = QWebEngineScript.ScriptWorldId.ApplicationWorld
elif isinstance(world, int):
world_id = world
if not 0 <= world_id <= qtutils.MAX_WORLD_ID:
@@ -1401,9 +1379,9 @@ class WebEngineTab(browsertab.AbstractTab):
def reload(self, *, force=False):
if force:
- action = QWebEnginePage.ReloadAndBypassCache
+ action = QWebEnginePage.WebAction.ReloadAndBypassCache
else:
- action = QWebEnginePage.Reload
+ action = QWebEnginePage.WebAction.Reload
self._widget.triggerPageAction(action)
def stop(self):
@@ -1412,13 +1390,9 @@ class WebEngineTab(browsertab.AbstractTab):
def title(self):
return self._widget.title()
- def renderer_process_pid(self) -> Optional[int]:
+ def renderer_process_pid(self) -> int:
page = self._widget.page()
- try:
- return page.renderProcessPid()
- except AttributeError:
- # Added in Qt 5.15
- return None
+ return page.renderProcessPid()
def icon(self):
return self._widget.icon()
@@ -1460,7 +1434,7 @@ class WebEngineTab(browsertab.AbstractTab):
title_url = QUrl(url)
title_url.setScheme('')
title_url_str = title_url.toDisplayString(
- QUrl.RemoveScheme) # type: ignore[arg-type]
+ QUrl.UrlFormattingOption.RemoveScheme) # type: ignore[arg-type]
if title == title_url_str.strip('/'):
title = ""
@@ -1477,7 +1451,7 @@ class WebEngineTab(browsertab.AbstractTab):
"""Called when a proxy needs authentication."""
msg = "<b>{}</b> requires a username and password.".format(
html_utils.escape(proxy_host))
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
answer = message.ask(
title="Proxy authentication required", text=msg,
mode=usertypes.PromptMode.user_pwd,
@@ -1526,19 +1500,19 @@ class WebEngineTab(browsertab.AbstractTab):
@pyqtSlot(QWebEnginePage.RenderProcessTerminationStatus, int)
def _on_render_process_terminated(self, status, exitcode):
"""Show an error when the renderer process terminated."""
- if (status == QWebEnginePage.AbnormalTerminationStatus and
+ if (status == QWebEnginePage.RenderProcessTerminationStatus.AbnormalTerminationStatus and
exitcode == 256):
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-58697
- status = QWebEnginePage.CrashedTerminationStatus
+ status = QWebEnginePage.RenderProcessTerminationStatus.CrashedTerminationStatus
status_map = {
- QWebEnginePage.NormalTerminationStatus:
+ QWebEnginePage.RenderProcessTerminationStatus.NormalTerminationStatus:
browsertab.TerminationStatus.normal,
- QWebEnginePage.AbnormalTerminationStatus:
+ QWebEnginePage.RenderProcessTerminationStatus.AbnormalTerminationStatus:
browsertab.TerminationStatus.abnormal,
- QWebEnginePage.CrashedTerminationStatus:
+ QWebEnginePage.RenderProcessTerminationStatus.CrashedTerminationStatus:
browsertab.TerminationStatus.crashed,
- QWebEnginePage.KilledTerminationStatus:
+ QWebEnginePage.RenderProcessTerminationStatus.KilledTerminationStatus:
browsertab.TerminationStatus.killed,
-1:
browsertab.TerminationStatus.unknown,
@@ -1568,24 +1542,25 @@ class WebEngineTab(browsertab.AbstractTab):
@pyqtSlot(int)
def _on_load_progress(self, perc: int) -> None:
- """QtWebEngine-specific loadProgress workarounds.
-
- WORKAROUND for https://bugreports.qt.io/browse/QTBUG-65223
- """
+ """QtWebEngine-specific loadProgress workarounds."""
super()._on_load_progress(perc)
- if (perc == 100 and
- self.load_status() != usertypes.LoadStatus.error):
+ if (
+ self._needs_qtbug65223_workaround and
+ perc == 100 and
+ self.load_status() != usertypes.LoadStatus.error
+ ):
self._update_load_status(ok=True)
@pyqtSlot(bool)
def _on_load_finished(self, ok: bool) -> None:
- """QtWebEngine-specific loadFinished workarounds."""
+ """QtWebEngine-specific loadFinished code."""
super()._on_load_finished(ok)
- if not ok:
- # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-65223
+ if not self._needs_qtbug65223_workaround or not ok:
+ # With the workaround, this should only run with ok=False
self._update_load_status(ok)
+ if not ok:
self.dump_async(functools.partial(
self._error_page_workaround,
self.settings.test_attribute('content.javascript.enabled')))
@@ -1605,7 +1580,7 @@ class WebEngineTab(browsertab.AbstractTab):
log.network.debug("First party URL: {}".format(first_party_url))
if error.is_overridable():
- error.ignore = shared.ignore_certificate_error(
+ shared.handle_certificate_error(
request_url=url,
first_party_url=first_party_url,
error=error,
@@ -1618,28 +1593,6 @@ class WebEngineTab(browsertab.AbstractTab):
log.network.debug("ignore {}, URL {}, requested {}".format(
error.ignore, url, self.url(requested=True)))
- # WORKAROUND for https://codereview.qt-project.org/c/qt/qtwebengine/+/270556
- show_non_overr_cert_error = (
- not error.is_overridable() and (
- # Affected Qt versions:
- # 5.13 before 5.13.2
- # 5.12 before 5.12.6
- # < 5.12 (which is unsupported)
- (qtutils.version_check('5.13') and
- not qtutils.version_check('5.13.2')) or
- (qtutils.version_check('5.12') and
- not qtutils.version_check('5.12.6'))
- )
- )
-
- # We can't really know when to show an error page, as the error might
- # have happened when loading some resource.
- is_resource = (
- first_party_url.isValid() and
- url.matches(first_party_url, QUrl.RemoveScheme))
- if show_non_overr_cert_error and is_resource:
- self._show_error_page(url, str(error))
-
@pyqtSlot()
def _on_print_requested(self):
"""Slot for window.print() in JS."""
@@ -1648,27 +1601,30 @@ class WebEngineTab(browsertab.AbstractTab):
except browsertab.WebTabError as e:
message.error(str(e))
- @pyqtSlot(QUrl)
- def _on_url_changed(self, url: QUrl) -> None:
- """Update settings for the current URL.
-
- Normally this is done below in _on_navigation_request, but we also need
- to do it here as WORKAROUND for
- https://bugreports.qt.io/browse/QTBUG-77137
-
- Since update_for_url() is idempotent, it doesn't matter much if we end
- up doing it twice.
- """
- super()._on_url_changed(url)
- if (url.isValid() and
- qtutils.version_check('5.13') and
- not qtutils.version_check('5.14')):
- self.settings.update_for_url(url)
-
@pyqtSlot(usertypes.NavigationRequest)
def _on_navigation_request(self, navigation):
super()._on_navigation_request(navigation)
+ local_schemes = {"qute", "file"}
+ qtwe_ver = version.qtwebengine_versions().webengine
+ if (
+ navigation.accepted and
+ self.url().scheme().lower() in local_schemes and
+ navigation.url.scheme().lower() not in local_schemes and
+ (navigation.navigation_type ==
+ usertypes.NavigationRequest.Type.link_clicked) and
+ navigation.is_main_frame and
+ (utils.VersionNumber(6, 2) <= qtwe_ver < utils.VersionNumber(6, 2, 5) or
+ utils.VersionNumber(6, 3) <= qtwe_ver < utils.VersionNumber(6, 3, 1))
+ ):
+ # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-103778
+ log.webview.debug(
+ "Working around blocked request from local page "
+ f"{self.url().toDisplayString()}"
+ )
+ navigation.accepted = False
+ self.load_url(navigation.url)
+
if not navigation.accepted or not navigation.is_main_frame:
return
@@ -1721,16 +1677,7 @@ class WebEngineTab(browsertab.AbstractTab):
page.contentsSizeChanged.connect(self.contents_size_changed)
page.navigation_request.connect(self._on_navigation_request)
page.printRequested.connect(self._on_print_requested)
-
- try:
- # pylint: disable=unused-import
- from PyQt5.QtWebEngineWidgets import (
- QWebEngineClientCertificateSelection)
- except ImportError:
- pass
- else:
- page.selectClientCertificate.connect(
- self._on_select_client_certificate)
+ page.selectClientCertificate.connect(self._on_select_client_certificate)
view.titleChanged.connect(self.title_changed)
view.urlChanged.connect(self._on_url_changed)
@@ -1741,12 +1688,7 @@ class WebEngineTab(browsertab.AbstractTab):
page.loadFinished.connect(self._on_history_trigger)
page.loadFinished.connect(self._restore_zoom)
page.loadFinished.connect(self._on_load_finished)
-
- try:
- page.renderProcessPidChanged.connect(self._on_renderer_process_pid_changed)
- except AttributeError:
- # Added in Qt 5.15.0
- pass
+ page.renderProcessPidChanged.connect(self._on_renderer_process_pid_changed)
self.shutting_down.connect(self.abort_questions)
self.load_started.connect(self.abort_questions)
@@ -1754,5 +1696,6 @@ class WebEngineTab(browsertab.AbstractTab):
# pylint: disable=protected-access
self.audio._connect_signals()
self.search.connect_signals()
+ self.printing.connect_signals()
self._permissions.connect_signals()
self._scripts.connect_signals()
diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py
index 4dd1b2a71..66968a954 100644
--- a/qutebrowser/browser/webengine/webview.py
+++ b/qutebrowser/browser/webengine/webview.py
@@ -21,9 +21,11 @@
from typing import List, Iterable
-from PyQt5.QtCore import pyqtSignal, QUrl
-from PyQt5.QtGui import QPalette
-from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
+from qutebrowser.qt import machinery
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QUrl
+from qutebrowser.qt.gui import QPalette
+from qutebrowser.qt.webenginewidgets import QWebEngineView
+from qutebrowser.qt.webenginecore import QWebEnginePage, QWebEngineCertificateError
from qutebrowser.browser import shared
from qutebrowser.browser.webengine import webenginesettings, certificateerror
@@ -32,8 +34,8 @@ from qutebrowser.utils import log, debug, usertypes
_QB_FILESELECTION_MODES = {
- QWebEnginePage.FileSelectOpen: shared.FileSelectionMode.single_file,
- QWebEnginePage.FileSelectOpenMultiple: shared.FileSelectionMode.multiple_files,
+ QWebEnginePage.FileSelectionMode.FileSelectOpen: shared.FileSelectionMode.single_file,
+ QWebEnginePage.FileSelectionMode.FileSelectOpenMultiple: shared.FileSelectionMode.multiple_files,
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-91489
#
# QtWebEngine doesn't expose this value from its internal
@@ -54,7 +56,7 @@ class WebEngineView(QWebEngineView):
self._win_id = win_id
self._tabdata = tabdata
- theme_color = self.style().standardPalette().color(QPalette.Base)
+ theme_color = self.style().standardPalette().color(QPalette.ColorRole.Base)
if private:
assert webenginesettings.private_profile is not None
profile = webenginesettings.private_profile
@@ -106,21 +108,21 @@ class WebEngineView(QWebEngineView):
log.webview.debug("createWindow with type {}, background {}".format(
debug_type, background))
- if wintype == QWebEnginePage.WebBrowserWindow:
+ if wintype == QWebEnginePage.WebWindowType.WebBrowserWindow:
# Shift-Alt-Click
target = usertypes.ClickTarget.window
- elif wintype == QWebEnginePage.WebDialog:
+ elif wintype == QWebEnginePage.WebWindowType.WebDialog:
log.webview.warning("{} requested, but we don't support "
"that!".format(debug_type))
target = usertypes.ClickTarget.tab
- elif wintype == QWebEnginePage.WebBrowserTab:
+ elif wintype == QWebEnginePage.WebWindowType.WebBrowserTab:
# Middle-click / Ctrl-Click with Shift
# FIXME:qtwebengine this also affects target=_blank links...
if background:
target = usertypes.ClickTarget.tab
else:
target = usertypes.ClickTarget.tab_bg
- elif wintype == QWebEnginePage.WebBrowserBackgroundTab:
+ elif wintype == QWebEnginePage.WebWindowType.WebBrowserBackgroundTab:
# Middle-click / Ctrl-Click
if background:
target = usertypes.ClickTarget.tab_bg
@@ -150,8 +152,9 @@ class WebEnginePage(QWebEnginePage):
Signals:
certificate_error: Emitted on certificate errors.
- Needs to be directly connected to a slot setting the
- 'ignore' attribute.
+ Needs to be directly connected to a slot calling
+ .accept_certificate(), .reject_certificate, or
+ .defer().
shutting_down: Emitted when the page is shutting down.
navigation_request: Emitted on acceptNavigationRequest.
"""
@@ -160,12 +163,43 @@ class WebEnginePage(QWebEnginePage):
shutting_down = pyqtSignal()
navigation_request = pyqtSignal(usertypes.NavigationRequest)
+ _JS_LOG_LEVEL_MAPPING = {
+ QWebEnginePage.JavaScriptConsoleMessageLevel.InfoMessageLevel:
+ usertypes.JsLogLevel.info,
+ QWebEnginePage.JavaScriptConsoleMessageLevel.WarningMessageLevel:
+ usertypes.JsLogLevel.warning,
+ QWebEnginePage.JavaScriptConsoleMessageLevel.ErrorMessageLevel:
+ usertypes.JsLogLevel.error,
+ }
+
+ _NAVIGATION_TYPE_MAPPING = {
+ QWebEnginePage.NavigationType.NavigationTypeLinkClicked:
+ usertypes.NavigationRequest.Type.link_clicked,
+ QWebEnginePage.NavigationType.NavigationTypeTyped:
+ usertypes.NavigationRequest.Type.typed,
+ QWebEnginePage.NavigationType.NavigationTypeFormSubmitted:
+ usertypes.NavigationRequest.Type.form_submitted,
+ QWebEnginePage.NavigationType.NavigationTypeBackForward:
+ usertypes.NavigationRequest.Type.back_forward,
+ QWebEnginePage.NavigationType.NavigationTypeReload:
+ usertypes.NavigationRequest.Type.reload,
+ QWebEnginePage.NavigationType.NavigationTypeOther:
+ usertypes.NavigationRequest.Type.other,
+ QWebEnginePage.NavigationType.NavigationTypeRedirect:
+ usertypes.NavigationRequest.Type.redirect,
+ }
+
def __init__(self, *, theme_color, profile, parent=None):
super().__init__(profile, parent)
self._is_shutting_down = False
self._theme_color = theme_color
self._set_bg_color()
config.instance.changed.connect(self._set_bg_color)
+ if machinery.IS_QT6:
+ self.certificateError.connect( # pylint: disable=no-member
+ self._handle_certificate_error
+ )
+ # Qt 5: Overridden method instead of signal
@config.change_filter('colors.webpage.bg')
def _set_bg_color(self):
@@ -178,11 +212,17 @@ class WebEnginePage(QWebEnginePage):
self._is_shutting_down = True
self.shutting_down.emit()
- def certificateError(self, error):
+ @pyqtSlot(QWebEngineCertificateError)
+ def _handle_certificate_error(self, qt_error):
"""Handle certificate errors coming from Qt."""
- error = certificateerror.CertificateErrorWrapper(error)
+ error = certificateerror.CertificateErrorWrapper(qt_error)
self.certificate_error.emit(error)
- return error.ignore
+ # Right now, we never defer accepting, due to a PyQt bug
+ return error.certificate_was_accepted()
+
+ if machinery.IS_QT5:
+ # Overridden method instead of signal
+ certificateError = _handle_certificate_error # noqa: N815
def javaScriptConfirm(self, url, js_msg):
"""Override javaScriptConfirm to use qutebrowser prompts."""
@@ -216,42 +256,16 @@ class WebEnginePage(QWebEnginePage):
def javaScriptConsoleMessage(self, level, msg, line, source):
"""Log javascript messages to qutebrowser's log."""
- level_map = {
- QWebEnginePage.InfoMessageLevel: usertypes.JsLogLevel.info,
- QWebEnginePage.WarningMessageLevel: usertypes.JsLogLevel.warning,
- QWebEnginePage.ErrorMessageLevel: usertypes.JsLogLevel.error,
- }
- shared.javascript_log_message(level_map[level], source, line, msg)
+ shared.javascript_log_message(self._JS_LOG_LEVEL_MAPPING[level], source, line, msg)
def acceptNavigationRequest(self,
url: QUrl,
typ: QWebEnginePage.NavigationType,
is_main_frame: bool) -> bool:
"""Override acceptNavigationRequest to forward it to the tab API."""
- type_map = {
- QWebEnginePage.NavigationTypeLinkClicked:
- usertypes.NavigationRequest.Type.link_clicked,
- QWebEnginePage.NavigationTypeTyped:
- usertypes.NavigationRequest.Type.typed,
- QWebEnginePage.NavigationTypeFormSubmitted:
- usertypes.NavigationRequest.Type.form_submitted,
- QWebEnginePage.NavigationTypeBackForward:
- usertypes.NavigationRequest.Type.back_forward,
- QWebEnginePage.NavigationTypeReload:
- usertypes.NavigationRequest.Type.reloaded,
- QWebEnginePage.NavigationTypeOther:
- usertypes.NavigationRequest.Type.other,
- }
- try:
- type_map[QWebEnginePage.NavigationTypeRedirect] = (
- usertypes.NavigationRequest.Type.redirect)
- except AttributeError:
- # Added in Qt 5.14
- pass
-
navigation = usertypes.NavigationRequest(
url=url,
- navigation_type=type_map.get(
+ navigation_type=self._NAVIGATION_TYPE_MAPPING.get(
typ, usertypes.NavigationRequest.Type.other),
is_main_frame=is_main_frame)
self.navigation_request.emit(navigation)
diff --git a/qutebrowser/browser/webkit/cache.py b/qutebrowser/browser/webkit/cache.py
index 8494a8477..2b5b07c46 100644
--- a/qutebrowser/browser/webkit/cache.py
+++ b/qutebrowser/browser/webkit/cache.py
@@ -22,7 +22,7 @@
from typing import cast
import os.path
-from PyQt5.QtNetwork import QNetworkDiskCache
+from qutebrowser.qt.network import QNetworkDiskCache
from qutebrowser.config import config
from qutebrowser.utils import utils, standarddir
diff --git a/qutebrowser/browser/webkit/certificateerror.py b/qutebrowser/browser/webkit/certificateerror.py
index 09237dae9..553538193 100644
--- a/qutebrowser/browser/webkit/certificateerror.py
+++ b/qutebrowser/browser/webkit/certificateerror.py
@@ -19,19 +19,25 @@
"""A wrapper over a list of QSslErrors."""
-from typing import Sequence
+from typing import Sequence, Optional
-from PyQt5.QtNetwork import QSslError
+from qutebrowser.qt.network import QSslError, QNetworkReply
-from qutebrowser.utils import usertypes, utils, debug, jinja
+from qutebrowser.utils import usertypes, utils, debug, jinja, urlutils
class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
"""A wrapper over a list of QSslErrors."""
- def __init__(self, errors: Sequence[QSslError]) -> None:
+ def __init__(self, reply: QNetworkReply, errors: Sequence[QSslError]) -> None:
+ super().__init__()
+ self._reply = reply
self._errors = tuple(errors) # needs to be hashable
+ try:
+ self._host_tpl: Optional[urlutils.HostTupleType] = urlutils.host_tuple(reply.url())
+ except ValueError:
+ self._host_tpl = None
def __str__(self) -> str:
return '\n'.join(err.errorString() for err in self._errors)
@@ -43,16 +49,25 @@ class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
string=str(self))
def __hash__(self) -> int:
- return hash(self._errors)
+ return hash((self._host_tpl, self._errors))
def __eq__(self, other: object) -> bool:
if not isinstance(other, CertificateErrorWrapper):
return NotImplemented
- return self._errors == other._errors
+ return self._errors == other._errors and self._host_tpl == other._host_tpl
def is_overridable(self) -> bool:
return True
+ def defer(self) -> None:
+ raise usertypes.UndeferrableError("Never deferrable")
+
+ def accept_certificate(self) -> None:
+ super().accept_certificate()
+ self._reply.ignoreSslErrors()
+
+ # Not overriding reject_certificate because that's default in QNetworkReply
+
def html(self):
if len(self._errors) == 1:
return super().html()
diff --git a/qutebrowser/browser/webkit/cookies.py b/qutebrowser/browser/webkit/cookies.py
index 055ef64d8..fed819cee 100644
--- a/qutebrowser/browser/webkit/cookies.py
+++ b/qutebrowser/browser/webkit/cookies.py
@@ -21,8 +21,8 @@
from typing import Sequence
-from PyQt5.QtNetwork import QNetworkCookie, QNetworkCookieJar
-from PyQt5.QtCore import pyqtSignal, QDateTime
+from qutebrowser.qt.network import QNetworkCookie, QNetworkCookieJar
+from qutebrowser.qt.core import pyqtSignal, QDateTime
from qutebrowser.config import config
from qutebrowser.utils import utils, standarddir, objreg, log
diff --git a/qutebrowser/browser/webkit/http.py b/qutebrowser/browser/webkit/http.py
index add0f14b5..580c667c2 100644
--- a/qutebrowser/browser/webkit/http.py
+++ b/qutebrowser/browser/webkit/http.py
@@ -25,7 +25,7 @@ import dataclasses
import os.path
from typing import Type
-from PyQt5.QtNetwork import QNetworkRequest
+from qutebrowser.qt.network import QNetworkRequest
from qutebrowser.utils import log, utils
@@ -191,7 +191,7 @@ def parse_content_type(reply):
A [mimetype, rest] list, or [None, None] if unset.
Rest can be None.
"""
- content_type = reply.header(QNetworkRequest.ContentTypeHeader)
+ content_type = reply.header(QNetworkRequest.KnownHeaders.ContentTypeHeader)
if content_type is None:
return [None, None]
if ';' in content_type:
diff --git a/qutebrowser/browser/webkit/mhtml.py b/qutebrowser/browser/webkit/mhtml.py
index d9f2d484e..56ad4fb4f 100644
--- a/qutebrowser/browser/webkit/mhtml.py
+++ b/qutebrowser/browser/webkit/mhtml.py
@@ -36,7 +36,7 @@ import quopri
import dataclasses
from typing import MutableMapping, Set, Tuple, Callable
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.browser import downloads
from qutebrowser.browser.webkit import webkitelem
diff --git a/qutebrowser/browser/webkit/network/networkmanager.py b/qutebrowser/browser/webkit/network/networkmanager.py
index 83eaabda7..2bc3cad02 100644
--- a/qutebrowser/browser/webkit/network/networkmanager.py
+++ b/qutebrowser/browser/webkit/network/networkmanager.py
@@ -24,8 +24,8 @@ import html
import dataclasses
from typing import TYPE_CHECKING, Dict, MutableMapping, Optional, Set
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QUrl, QByteArray
-from PyQt5.QtNetwork import (QNetworkAccessManager, QNetworkReply, QSslConfiguration,
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, QUrl, QByteArray
+from qutebrowser.qt.network import (QNetworkAccessManager, QNetworkReply, QSslConfiguration,
QNetworkProxy)
from qutebrowser.config import config
@@ -79,7 +79,7 @@ def _is_secure_cipher(cipher):
return False
# OpenSSL should already protect against this in a better way
# elif (('CBC3' in tokens or 'CBC' in tokens) and (cipher.protocol() not in
- # [QSsl.TlsV1_0, QSsl.TlsV1_1, QSsl.TlsV1_2])):
+ # [QSsl.SslProtocol.TlsV1_0, QSsl.SslProtocol.TlsV1_1, QSsl.SslProtocol.TlsV1_2])):
# # https://en.wikipedia.org/wiki/POODLE
# return False
### These things should never happen as those are already filtered out by
@@ -103,8 +103,8 @@ def _is_secure_cipher(cipher):
def init():
"""Disable insecure SSL ciphers on old Qt versions."""
- sslconfig = QSslConfiguration.defaultConfiguration()
- default_ciphers = sslconfig.ciphers()
+ ssl_config = QSslConfiguration.defaultConfiguration()
+ default_ciphers = ssl_config.ciphers()
log.init.vdebug( # type: ignore[attr-defined]
"Default Qt ciphers: {}".format(
', '.join(c.name() for c in default_ciphers)))
@@ -120,7 +120,7 @@ def init():
if bad_ciphers:
log.init.debug("Disabling bad ciphers: {}".format(
', '.join(c.name() for c in bad_ciphers)))
- sslconfig.setCiphers(good_ciphers)
+ ssl_config.setCiphers(good_ciphers)
_SavedErrorsType = MutableMapping[
@@ -239,12 +239,16 @@ class NetworkManager(QNetworkAccessManager):
def shutdown(self):
"""Abort all running requests."""
- self.setNetworkAccessible(QNetworkAccessManager.NotAccessible)
+ try:
+ self.setNetworkAccessible(QNetworkAccessManager.NetworkAccessibility.NotAccessible)
+ except AttributeError:
+ # Qt 5 only, deprecated seemingly without replacement.
+ pass
self.shutting_down.emit()
# No @pyqtSlot here, see
# https://github.com/qutebrowser/qutebrowser/issues/2213
- def on_ssl_errors(self, reply, qt_errors): # noqa: C901 pragma: no mccabe
+ def on_ssl_errors(self, reply, qt_errors):
"""Decide if SSL errors should be ignored or not.
This slot is called on SSL/TLS errors by the self.sslErrors signal.
@@ -253,7 +257,7 @@ class NetworkManager(QNetworkAccessManager):
reply: The QNetworkReply that is encountering the errors.
qt_errors: A list of errors.
"""
- errors = certificateerror.CertificateErrorWrapper(qt_errors)
+ errors = certificateerror.CertificateErrorWrapper(reply, qt_errors)
log.network.debug("Certificate errors: {!r}".format(errors))
try:
host_tpl: Optional[urlutils.HostTupleType] = urlutils.host_tuple(
@@ -281,14 +285,14 @@ class NetworkManager(QNetworkAccessManager):
tab = self._get_tab()
first_party_url = QUrl() if tab is None else tab.data.last_navigation.url
- ignore = shared.ignore_certificate_error(
+ shared.handle_certificate_error(
request_url=reply.url(),
first_party_url=first_party_url,
error=errors,
abort_on=abort_on,
)
- if ignore:
- reply.ignoreSslErrors()
+
+ if errors.certificate_was_accepted():
if host_tpl is not None:
self._accepted_ssl_errors[host_tpl].add(errors)
elif host_tpl is not None:
@@ -406,14 +410,14 @@ class NetworkManager(QNetworkAccessManager):
proxy_error = proxymod.application_factory.get_error()
if proxy_error is not None:
return networkreply.ErrorNetworkReply(
- req, proxy_error, QNetworkReply.UnknownProxyError,
+ req, proxy_error, QNetworkReply.NetworkError.UnknownProxyError,
self)
if not req.url().isValid():
log.network.debug("Ignoring invalid requested URL: {}".format(
req.url().errorString()))
return networkreply.ErrorNetworkReply(
- req, "Invalid request URL", QNetworkReply.HostNotFoundError,
+ req, "Invalid request URL", QNetworkReply.NetworkError.HostNotFoundError,
self)
for header, value in shared.custom_headers(url=req.url()):
@@ -433,7 +437,7 @@ class NetworkManager(QNetworkAccessManager):
interceptors.run(request)
if request.is_blocked:
return networkreply.ErrorNetworkReply(
- req, HOSTBLOCK_ERROR_STRING, QNetworkReply.ContentAccessDenied,
+ req, HOSTBLOCK_ERROR_STRING, QNetworkReply.NetworkError.ContentAccessDenied,
self)
if 'log-requests' in objects.debug_flags:
diff --git a/qutebrowser/browser/webkit/network/networkreply.py b/qutebrowser/browser/webkit/network/networkreply.py
index d5c724d63..4fb7dfea5 100644
--- a/qutebrowser/browser/webkit/network/networkreply.py
+++ b/qutebrowser/browser/webkit/network/networkreply.py
@@ -26,8 +26,8 @@
"""Special network replies.."""
-from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
-from PyQt5.QtCore import pyqtSlot, QIODevice, QByteArray, QTimer
+from qutebrowser.qt.network import QNetworkReply, QNetworkRequest
+from qutebrowser.qt.core import pyqtSlot, QIODevice, QByteArray, QTimer
class FixedDataNetworkReply(QNetworkReply):
@@ -49,13 +49,13 @@ class FixedDataNetworkReply(QNetworkReply):
self.setRequest(request)
self.setUrl(request.url())
- self.setOpenMode(QIODevice.ReadOnly)
+ self.setOpenMode(QIODevice.OpenModeFlag.ReadOnly)
- self.setHeader(QNetworkRequest.ContentTypeHeader, mimeType)
- self.setHeader(QNetworkRequest.ContentLengthHeader,
+ self.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, mimeType)
+ self.setHeader(QNetworkRequest.KnownHeaders.ContentLengthHeader,
QByteArray.number(len(fileData)))
- self.setAttribute(QNetworkRequest.HttpStatusCodeAttribute, 200)
- self.setAttribute(QNetworkRequest.HttpReasonPhraseAttribute, 'OK')
+ self.setAttribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute, 200)
+ self.setAttribute(QNetworkRequest.Attribute.HttpReasonPhraseAttribute, 'OK')
# For some reason, a segfault will be triggered if these lambdas aren't
# there.
# pylint: disable=unnecessary-lambda
@@ -114,9 +114,9 @@ class ErrorNetworkReply(QNetworkReply):
self.setUrl(req.url())
# We don't actually want to read anything, but we still need to open
# the device to avoid getting a warning.
- self.setOpenMode(QIODevice.ReadOnly)
+ self.setOpenMode(QIODevice.OpenModeFlag.ReadOnly)
self.setError(error, errorstring)
- QTimer.singleShot(0, lambda: self.error.emit(error))
+ QTimer.singleShot(0, lambda: self.errorOccurred.emit(error))
QTimer.singleShot(0, lambda: self.finished.emit())
def abort(self):
@@ -143,7 +143,7 @@ class RedirectNetworkReply(QNetworkReply):
def __init__(self, new_url, parent=None):
super().__init__(parent)
- self.setAttribute(QNetworkRequest.RedirectionTargetAttribute, new_url)
+ self.setAttribute(QNetworkRequest.Attribute.RedirectionTargetAttribute, new_url)
QTimer.singleShot(0, lambda: self.finished.emit())
def abort(self):
diff --git a/qutebrowser/browser/webkit/network/webkitqutescheme.py b/qutebrowser/browser/webkit/network/webkitqutescheme.py
index bccdd1acd..0c4da1a84 100644
--- a/qutebrowser/browser/webkit/network/webkitqutescheme.py
+++ b/qutebrowser/browser/webkit/network/webkitqutescheme.py
@@ -19,8 +19,8 @@
"""QtWebKit specific qute://* handlers and glue code."""
-from PyQt5.QtCore import QUrl
-from PyQt5.QtNetwork import QNetworkReply, QNetworkAccessManager
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.network import QNetworkReply, QNetworkAccessManager
from qutebrowser.browser import qutescheme
from qutebrowser.browser.webkit.network import networkreply
@@ -38,10 +38,10 @@ def handler(request, operation, current_url):
Return:
A QNetworkReply.
"""
- if operation != QNetworkAccessManager.GetOperation:
+ if operation != QNetworkAccessManager.Operation.GetOperation:
return networkreply.ErrorNetworkReply(
request, "Unsupported request type",
- QNetworkReply.ContentOperationNotPermittedError)
+ QNetworkReply.NetworkError.ContentOperationNotPermittedError)
url = request.url()
@@ -53,22 +53,22 @@ def handler(request, operation, current_url):
url.toDisplayString()))
return networkreply.ErrorNetworkReply(
request, "Invalid qute://settings request",
- QNetworkReply.ContentAccessDenied)
+ QNetworkReply.NetworkError.ContentAccessDenied)
try:
mimetype, data = qutescheme.data_for_url(url)
except qutescheme.Error as e:
errors = {
qutescheme.NotFoundError:
- QNetworkReply.ContentNotFoundError,
+ QNetworkReply.NetworkError.ContentNotFoundError,
qutescheme.UrlInvalidError:
- QNetworkReply.ContentOperationNotPermittedError,
+ QNetworkReply.NetworkError.ContentOperationNotPermittedError,
qutescheme.RequestDeniedError:
- QNetworkReply.ContentAccessDenied,
+ QNetworkReply.NetworkError.ContentAccessDenied,
qutescheme.SchemeOSError:
- QNetworkReply.ContentNotFoundError,
+ QNetworkReply.NetworkError.ContentNotFoundError,
qutescheme.Error:
- QNetworkReply.InternalServerError,
+ QNetworkReply.NetworkError.InternalServerError,
}
exctype = type(e)
log.misc.error("{} while handling qute://* URL".format(
diff --git a/qutebrowser/browser/webkit/tabhistory.py b/qutebrowser/browser/webkit/tabhistory.py
index a707030d1..183ffc7a9 100644
--- a/qutebrowser/browser/webkit/tabhistory.py
+++ b/qutebrowser/browser/webkit/tabhistory.py
@@ -21,7 +21,7 @@
from typing import Any, List, Mapping
-from PyQt5.QtCore import QByteArray, QDataStream, QIODevice, QUrl
+from qutebrowser.qt.core import QByteArray, QDataStream, QIODevice, QUrl
from qutebrowser.utils import qtutils
@@ -50,10 +50,10 @@ def _serialize_items(items, current_idx, stream):
def _serialize_item(item):
data = {
- 'originalURLString': item.original_url.toString(QUrl.FullyEncoded),
+ 'originalURLString': item.original_url.toString(QUrl.ComponentFormattingOption.FullyEncoded),
'scrollPosition': {'x': 0, 'y': 0},
'title': item.title,
- 'urlString': item.url.toString(QUrl.FullyEncoded),
+ 'urlString': item.url.toString(QUrl.ComponentFormattingOption.FullyEncoded),
}
try:
data['scrollPosition']['x'] = item.user_data['scroll-pos'].x()
@@ -80,7 +80,7 @@ def serialize(items):
segfault!
"""
data = QByteArray()
- stream = QDataStream(data, QIODevice.ReadWrite)
+ stream = QDataStream(data, QIODevice.OpenModeFlag.ReadWrite)
user_data: List[Mapping[str, Any]] = []
current_idx = None
diff --git a/qutebrowser/browser/webkit/webkitelem.py b/qutebrowser/browser/webkit/webkitelem.py
index 5bf96a610..c44f675e7 100644
--- a/qutebrowser/browser/webkit/webkitelem.py
+++ b/qutebrowser/browser/webkit/webkitelem.py
@@ -17,13 +17,16 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+# FIXME:qt6 (lint)
+# pylint: disable=no-name-in-module
+
"""QtWebKit specific part of the web element API."""
from typing import cast, TYPE_CHECKING, Iterator, List, Optional, Set
-from PyQt5.QtCore import QRect, Qt
-from PyQt5.QtWebKit import QWebElement, QWebSettings
-from PyQt5.QtWebKitWidgets import QWebFrame
+from qutebrowser.qt.core import QRect, Qt
+from qutebrowser.qt.webkit import QWebElement, QWebSettings
+from qutebrowser.qt.webkitwidgets import QWebFrame
from qutebrowser.config import config
from qutebrowser.utils import log, utils, javascript, usertypes
@@ -276,7 +279,7 @@ class WebKitElement(webelem.AbstractWebElement):
def _is_hidden_css(self) -> bool:
"""Check if the given element is hidden via CSS."""
attr_values = {
- attr: self._elem.styleProperty(attr, QWebElement.ComputedStyle)
+ attr: self._elem.styleProperty(attr, QWebElement.StyleResolveStrategy.ComputedStyle)
for attr in ['visibility', 'display', 'opacity']
}
invisible = attr_values['visibility'] == 'hidden'
@@ -362,7 +365,7 @@ class WebKitElement(webelem.AbstractWebElement):
def _click_js(self, click_target: usertypes.ClickTarget) -> None:
settings = QWebSettings.globalSettings()
- attribute = QWebSettings.JavascriptCanOpenWindows
+ attribute = QWebSettings.WebAttribute.JavascriptCanOpenWindows
could_open_windows = settings.testAttribute(attribute)
settings.setAttribute(attribute, True)
ok = self._elem.evaluateJavaScript('this.click(); true;')
@@ -372,7 +375,7 @@ class WebKitElement(webelem.AbstractWebElement):
self._click_fake_event(click_target)
def _click_fake_event(self, click_target: usertypes.ClickTarget,
- button: Qt.MouseButton = Qt.LeftButton) -> None:
+ button: Qt.MouseButton = Qt.MouseButton.LeftButton) -> None:
self._tab.data.override_target = click_target
super()._click_fake_event(click_target)
diff --git a/qutebrowser/browser/webkit/webkithistory.py b/qutebrowser/browser/webkit/webkithistory.py
index 6ffe65193..549a4d545 100644
--- a/qutebrowser/browser/webkit/webkithistory.py
+++ b/qutebrowser/browser/webkit/webkithistory.py
@@ -17,11 +17,14 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+# FIXME:qt6 (lint)
+# pylint: disable=no-name-in-module
+
"""QtWebKit specific part of history."""
import functools
-from PyQt5.QtWebKit import QWebHistoryInterface
+from qutebrowser.qt.webkit import QWebHistoryInterface
from qutebrowser.utils import debug
from qutebrowser.misc import debugcachestats
diff --git a/qutebrowser/browser/webkit/webkitinspector.py b/qutebrowser/browser/webkit/webkitinspector.py
index 4d9785cbe..69e1c7e24 100644
--- a/qutebrowser/browser/webkit/webkitinspector.py
+++ b/qutebrowser/browser/webkit/webkitinspector.py
@@ -17,11 +17,14 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+# FIXME:qt6 (lint)
+# pylint: disable=no-name-in-module
+
"""Customized QWebInspector for QtWebKit."""
-from PyQt5.QtWebKit import QWebSettings
-from PyQt5.QtWebKitWidgets import QWebInspector, QWebPage
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt.webkit import QWebSettings
+from qutebrowser.qt.webkitwidgets import QWebInspector, QWebPage
+from qutebrowser.qt.widgets import QWidget
from qutebrowser.browser import inspector
from qutebrowser.misc import miscwidgets
@@ -40,5 +43,5 @@ class WebKitInspector(inspector.AbstractWebInspector):
def inspect(self, page: QWebPage) -> None:
settings = QWebSettings.globalSettings()
- settings.setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
+ settings.setAttribute(QWebSettings.WebAttribute.DeveloperExtrasEnabled, True)
self._widget.setPage(page)
diff --git a/qutebrowser/browser/webkit/webkitsettings.py b/qutebrowser/browser/webkit/webkitsettings.py
index 1348c849b..87dc30327 100644
--- a/qutebrowser/browser/webkit/webkitsettings.py
+++ b/qutebrowser/browser/webkit/webkitsettings.py
@@ -17,6 +17,9 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+# FIXME:qt6 (lint)
+# pylint: disable=no-name-in-module
+
"""Bridge from QWebSettings to our own settings.
Module attributes:
@@ -27,10 +30,10 @@ Module attributes:
from typing import cast
import os.path
-from PyQt5.QtCore import QUrl
-from PyQt5.QtGui import QFont
-from PyQt5.QtWebKit import QWebSettings
-from PyQt5.QtWebKitWidgets import QWebPage
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.gui import QFont
+from qutebrowser.qt.webkit import QWebSettings
+from qutebrowser.qt.webkitwidgets import QWebPage
from qutebrowser.config import config, websettings
from qutebrowser.config.websettings import AttributeInfo as Attr
@@ -50,82 +53,82 @@ class WebKitSettings(websettings.AbstractSettings):
_ATTRIBUTES = {
'content.images':
- Attr(QWebSettings.AutoLoadImages),
+ Attr(QWebSettings.WebAttribute.AutoLoadImages),
'content.javascript.enabled':
- Attr(QWebSettings.JavascriptEnabled),
+ Attr(QWebSettings.WebAttribute.JavascriptEnabled),
'content.javascript.can_open_tabs_automatically':
- Attr(QWebSettings.JavascriptCanOpenWindows),
+ Attr(QWebSettings.WebAttribute.JavascriptCanOpenWindows),
'content.javascript.can_close_tabs':
- Attr(QWebSettings.JavascriptCanCloseWindows),
+ Attr(QWebSettings.WebAttribute.JavascriptCanCloseWindows),
'content.javascript.clipboard':
- Attr(QWebSettings.JavascriptCanAccessClipboard,
+ Attr(QWebSettings.WebAttribute.JavascriptCanAccessClipboard,
converter=lambda val: val != "none"),
'content.plugins':
- Attr(QWebSettings.PluginsEnabled),
+ Attr(QWebSettings.WebAttribute.PluginsEnabled),
'content.webgl':
- Attr(QWebSettings.WebGLEnabled),
+ Attr(QWebSettings.WebAttribute.WebGLEnabled),
'content.hyperlink_auditing':
- Attr(QWebSettings.HyperlinkAuditingEnabled),
+ Attr(QWebSettings.WebAttribute.HyperlinkAuditingEnabled),
'content.local_content_can_access_remote_urls':
- Attr(QWebSettings.LocalContentCanAccessRemoteUrls),
+ Attr(QWebSettings.WebAttribute.LocalContentCanAccessRemoteUrls),
'content.local_content_can_access_file_urls':
- Attr(QWebSettings.LocalContentCanAccessFileUrls),
+ Attr(QWebSettings.WebAttribute.LocalContentCanAccessFileUrls),
'content.dns_prefetch':
- Attr(QWebSettings.DnsPrefetchEnabled),
+ Attr(QWebSettings.WebAttribute.DnsPrefetchEnabled),
'content.frame_flattening':
- Attr(QWebSettings.FrameFlatteningEnabled),
+ Attr(QWebSettings.WebAttribute.FrameFlatteningEnabled),
'content.cache.appcache':
- Attr(QWebSettings.OfflineWebApplicationCacheEnabled),
+ Attr(QWebSettings.WebAttribute.OfflineWebApplicationCacheEnabled),
'content.local_storage':
- Attr(QWebSettings.LocalStorageEnabled,
- QWebSettings.OfflineStorageDatabaseEnabled),
+ Attr(QWebSettings.WebAttribute.LocalStorageEnabled,
+ QWebSettings.WebAttribute.OfflineStorageDatabaseEnabled),
'content.print_element_backgrounds':
- Attr(QWebSettings.PrintElementBackgrounds),
+ Attr(QWebSettings.WebAttribute.PrintElementBackgrounds),
'content.xss_auditing':
- Attr(QWebSettings.XSSAuditingEnabled),
+ Attr(QWebSettings.WebAttribute.XSSAuditingEnabled),
'content.site_specific_quirks.enabled':
- Attr(QWebSettings.SiteSpecificQuirksEnabled),
+ Attr(QWebSettings.WebAttribute.SiteSpecificQuirksEnabled),
'input.spatial_navigation':
- Attr(QWebSettings.SpatialNavigationEnabled),
+ Attr(QWebSettings.WebAttribute.SpatialNavigationEnabled),
'input.links_included_in_focus_chain':
- Attr(QWebSettings.LinksIncludedInFocusChain),
+ Attr(QWebSettings.WebAttribute.LinksIncludedInFocusChain),
'zoom.text_only':
- Attr(QWebSettings.ZoomTextOnly),
+ Attr(QWebSettings.WebAttribute.ZoomTextOnly),
'scrolling.smooth':
- Attr(QWebSettings.ScrollAnimatorEnabled),
+ Attr(QWebSettings.WebAttribute.ScrollAnimatorEnabled),
}
_FONT_SIZES = {
'fonts.web.size.minimum':
- QWebSettings.MinimumFontSize,
+ QWebSettings.FontSize.MinimumFontSize,
'fonts.web.size.minimum_logical':
- QWebSettings.MinimumLogicalFontSize,
+ QWebSettings.FontSize.MinimumLogicalFontSize,
'fonts.web.size.default':
- QWebSettings.DefaultFontSize,
+ QWebSettings.FontSize.DefaultFontSize,
'fonts.web.size.default_fixed':
- QWebSettings.DefaultFixedFontSize,
+ QWebSettings.FontSize.DefaultFixedFontSize,
}
_FONT_FAMILIES = {
- 'fonts.web.family.standard': QWebSettings.StandardFont,
- 'fonts.web.family.fixed': QWebSettings.FixedFont,
- 'fonts.web.family.serif': QWebSettings.SerifFont,
- 'fonts.web.family.sans_serif': QWebSettings.SansSerifFont,
- 'fonts.web.family.cursive': QWebSettings.CursiveFont,
- 'fonts.web.family.fantasy': QWebSettings.FantasyFont,
+ 'fonts.web.family.standard': QWebSettings.FontFamily.StandardFont,
+ 'fonts.web.family.fixed': QWebSettings.FontFamily.FixedFont,
+ 'fonts.web.family.serif': QWebSettings.FontFamily.SerifFont,
+ 'fonts.web.family.sans_serif': QWebSettings.FontFamily.SansSerifFont,
+ 'fonts.web.family.cursive': QWebSettings.FontFamily.CursiveFont,
+ 'fonts.web.family.fantasy': QWebSettings.FontFamily.FantasyFont,
}
# Mapping from QWebSettings::QWebSettings() in
# qtwebkit/Source/WebKit/qt/Api/qwebsettings.cpp
_FONT_TO_QFONT = {
- QWebSettings.StandardFont: QFont.Serif,
- QWebSettings.FixedFont: QFont.Monospace,
- QWebSettings.SerifFont: QFont.Serif,
- QWebSettings.SansSerifFont: QFont.SansSerif,
- QWebSettings.CursiveFont: QFont.Cursive,
- QWebSettings.FantasyFont: QFont.Fantasy,
+ QWebSettings.FontFamily.StandardFont: QFont.StyleHint.Serif,
+ QWebSettings.FontFamily.FixedFont: QFont.StyleHint.Monospace,
+ QWebSettings.FontFamily.SerifFont: QFont.StyleHint.Serif,
+ QWebSettings.FontFamily.SansSerifFont: QFont.StyleHint.SansSerif,
+ QWebSettings.FontFamily.CursiveFont: QFont.StyleHint.Cursive,
+ QWebSettings.FontFamily.FantasyFont: QFont.StyleHint.Fantasy,
}
@@ -139,10 +142,10 @@ def _set_user_stylesheet(settings):
def _set_cookie_accept_policy(settings):
"""Update the content.cookies.accept setting."""
mapping = {
- 'all': QWebSettings.AlwaysAllowThirdPartyCookies,
- 'no-3rdparty': QWebSettings.AlwaysBlockThirdPartyCookies,
- 'never': QWebSettings.AlwaysBlockThirdPartyCookies,
- 'no-unknown-3rdparty': QWebSettings.AllowThirdPartyWithExistingCookies,
+ 'all': QWebSettings.ThirdPartyCookiePolicy.AlwaysAllowThirdPartyCookies,
+ 'no-3rdparty': QWebSettings.ThirdPartyCookiePolicy.AlwaysBlockThirdPartyCookies,
+ 'never': QWebSettings.ThirdPartyCookiePolicy.AlwaysBlockThirdPartyCookies,
+ 'no-unknown-3rdparty': QWebSettings.ThirdPartyCookiePolicy.AllowThirdPartyWithExistingCookies,
}
value = config.val.content.cookies.accept
settings.setThirdPartyCookiePolicy(mapping[value])
diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py
index 0a1ac18f2..0916a0a64 100644
--- a/qutebrowser/browser/webkit/webkittab.py
+++ b/qutebrowser/browser/webkit/webkittab.py
@@ -17,6 +17,9 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+# FIXME:qt6 (lint)
+# pylint: disable=no-name-in-module
+
"""Wrapper over our (QtWebKit) WebView."""
import re
@@ -24,12 +27,12 @@ import functools
import xml.etree.ElementTree
from typing import cast, Iterable, Optional
-from PyQt5.QtCore import pyqtSlot, Qt, QUrl, QPoint, QTimer, QSizeF, QSize
-from PyQt5.QtGui import QIcon
-from PyQt5.QtWidgets import QWidget
-from PyQt5.QtWebKitWidgets import QWebPage, QWebFrame
-from PyQt5.QtWebKit import QWebSettings, QWebHistory, QWebElement
-from PyQt5.QtPrintSupport import QPrinter
+from qutebrowser.qt.core import pyqtSlot, Qt, QUrl, QPoint, QTimer, QSizeF, QSize
+from qutebrowser.qt.gui import QIcon
+from qutebrowser.qt.widgets import QWidget
+from qutebrowser.qt.webkitwidgets import QWebPage, QWebFrame
+from qutebrowser.qt.webkit import QWebSettings, QWebHistory, QWebElement
+from qutebrowser.qt.printsupport import QPrinter
from qutebrowser.browser import browsertab, shared
from qutebrowser.browser.webkit import (webview, webpage, tabhistory, webkitelem,
@@ -44,7 +47,6 @@ class WebKitAction(browsertab.AbstractAction):
"""QtWebKit implementations related to web actions."""
- action_class = QWebPage
action_base = QWebPage.WebAction
_widget: webview.WebView
@@ -67,9 +69,9 @@ class WebKitAction(browsertab.AbstractAction):
"""
new_actions = {
# https://github.com/qtwebkit/qtwebkit/commit/a96d9ef5d24b02d996ad14ff050d0e485c9ddc97
- 'RequestClose': QWebPage.ToggleVideoFullscreen + 1,
+ 'RequestClose': QWebPage.WebAction.ToggleVideoFullscreen + 1,
# https://github.com/qtwebkit/qtwebkit/commit/96b9ba6269a5be44343635a7aaca4a153ea0366b
- 'Unselect': QWebPage.ToggleVideoFullscreen + 2,
+ 'Unselect': QWebPage.WebAction.ToggleVideoFullscreen + 2,
}
if name in new_actions:
self._widget.triggerPageAction(new_actions[name]) # type: ignore[arg-type]
@@ -93,13 +95,14 @@ class WebKitPrinting(browsertab.AbstractPrinting):
def to_pdf(self, filename):
printer = QPrinter()
printer.setOutputFileName(filename)
- self.to_printer(printer)
+ self._widget.print(printer)
+ # Can't find out whether there was an error...
+ self.pdf_printing_finished.emit(filename, True)
- def to_printer(self, printer, callback=None):
+ def to_printer(self, printer):
self._widget.print(printer)
# Can't find out whether there was an error...
- if callback is not None:
- callback(True)
+ self.printing_finished.emit(True)
class WebKitSearch(browsertab.AbstractSearch):
@@ -118,9 +121,9 @@ class WebKitSearch(browsertab.AbstractSearch):
def _args_to_flags(self, reverse, ignore_case):
flags = self._empty_flags()
if self._is_case_sensitive(ignore_case):
- flags |= QWebPage.FindCaseSensitively
+ flags |= QWebPage.FindFlag.FindCaseSensitively
if reverse:
- flags |= QWebPage.FindBackward
+ flags |= QWebPage.FindFlag.FindBackward
return flags
def _call_cb(self, callback, found, text, flags, caller):
@@ -139,7 +142,7 @@ class WebKitSearch(browsertab.AbstractSearch):
# Removing FindWrapsAroundDocument to get the same logging as with
# QtWebEngine
debug_flags = debug.qflags_key(
- QWebPage, flags & ~QWebPage.FindWrapsAroundDocument,
+ QWebPage, flags & ~QWebPage.FindFlag.FindWrapsAroundDocument,
klass=QWebPage.FindFlag)
if debug_flags != '0x0000':
flag_text = 'with flags {}'.format(debug_flags)
@@ -171,7 +174,7 @@ class WebKitSearch(browsertab.AbstractSearch):
# We first clear the marked text, then the highlights
self._widget.findText('')
self._widget.findText(
- '', QWebPage.HighlightAllOccurrences) # type: ignore[arg-type]
+ '', QWebPage.FindFlag.HighlightAllOccurrences) # type: ignore[arg-type]
def search(self, text, *, ignore_case=usertypes.IgnoreCase.never,
reverse=False, result_cb=None):
@@ -192,7 +195,7 @@ class WebKitSearch(browsertab.AbstractSearch):
# to get a mark so we can navigate.
found = self._widget.findText(text, self._flags)
self._widget.findText(text,
- self._flags | QWebPage.HighlightAllOccurrences)
+ self._flags | QWebPage.FindFlag.HighlightAllOccurrences)
self._call_cb(result_cb, found, text, self._flags, 'search')
def next_result(self, *, wrap=False, callback=None):
@@ -202,7 +205,7 @@ class WebKitSearch(browsertab.AbstractSearch):
int(self._flags)) # type: ignore[call-overload]
if wrap:
- flags |= QWebPage.FindWrapsAroundDocument
+ flags |= QWebPage.FindFlag.FindWrapsAroundDocument
found = self._widget.findText(self.text, flags) # type: ignore[arg-type]
self._call_cb(callback, found, self.text, flags, 'next_result')
@@ -213,13 +216,13 @@ class WebKitSearch(browsertab.AbstractSearch):
flags = QWebPage.FindFlags(
int(self._flags)) # type: ignore[call-overload]
- if flags & QWebPage.FindBackward:
- flags &= ~QWebPage.FindBackward
+ if flags & QWebPage.FindFlag.FindBackward:
+ flags &= ~QWebPage.FindFlag.FindBackward
else:
- flags |= QWebPage.FindBackward
+ flags |= QWebPage.FindFlag.FindBackward
if wrap:
- flags |= QWebPage.FindWrapsAroundDocument
+ flags |= QWebPage.FindFlag.FindWrapsAroundDocument
found = self._widget.findText(self.text, flags) # type: ignore[arg-type]
self._call_cb(callback, found, self.text, flags, 'prev_result')
@@ -249,13 +252,13 @@ class WebKitCaret(browsertab.AbstractCaret):
self._selection_state = browsertab.SelectionState.none
self.selection_toggled.emit(self._selection_state)
settings = self._widget.settings()
- settings.setAttribute(QWebSettings.CaretBrowsingEnabled, True)
+ settings.setAttribute(QWebSettings.WebAttribute.CaretBrowsingEnabled, True)
if self._widget.isVisible():
# Sometimes the caret isn't immediately visible, but unfocusing
# and refocusing it fixes that.
self._widget.clearFocus()
- self._widget.setFocus(Qt.OtherFocusReason)
+ self._widget.setFocus(Qt.FocusReason.OtherFocusReason)
# Move the caret to the first element in the viewport if there
# isn't any text which is already selected.
@@ -269,19 +272,19 @@ class WebKitCaret(browsertab.AbstractCaret):
@pyqtSlot(usertypes.KeyMode)
def _on_mode_left(self, _mode):
settings = self._widget.settings()
- if settings.testAttribute(QWebSettings.CaretBrowsingEnabled):
+ if settings.testAttribute(QWebSettings.WebAttribute.CaretBrowsingEnabled):
if (self._selection_state is not browsertab.SelectionState.none and
self._widget.hasSelection()):
# Remove selection if it exists
- self._widget.triggerPageAction(QWebPage.MoveToNextChar)
- settings.setAttribute(QWebSettings.CaretBrowsingEnabled, False)
+ self._widget.triggerPageAction(QWebPage.WebAction.MoveToNextChar)
+ settings.setAttribute(QWebSettings.WebAttribute.CaretBrowsingEnabled, False)
self._selection_state = browsertab.SelectionState.none
def move_to_next_line(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = QWebPage.SelectNextLine
+ act = QWebPage.WebAction.SelectNextLine
else:
- act = QWebPage.MoveToNextLine
+ act = QWebPage.WebAction.MoveToNextLine
for _ in range(count):
self._widget.triggerPageAction(act)
if self._selection_state is browsertab.SelectionState.line:
@@ -289,9 +292,9 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_prev_line(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = QWebPage.SelectPreviousLine
+ act = QWebPage.WebAction.SelectPreviousLine
else:
- act = QWebPage.MoveToPreviousLine
+ act = QWebPage.WebAction.MoveToPreviousLine
for _ in range(count):
self._widget.triggerPageAction(act)
if self._selection_state is browsertab.SelectionState.line:
@@ -299,89 +302,89 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_next_char(self, count=1):
if self._selection_state is browsertab.SelectionState.normal:
- act = QWebPage.SelectNextChar
+ act = QWebPage.WebAction.SelectNextChar
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = QWebPage.MoveToNextChar
+ act = QWebPage.WebAction.MoveToNextChar
for _ in range(count):
self._widget.triggerPageAction(act)
def move_to_prev_char(self, count=1):
if self._selection_state is browsertab.SelectionState.normal:
- act = QWebPage.SelectPreviousChar
+ act = QWebPage.WebAction.SelectPreviousChar
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = QWebPage.MoveToPreviousChar
+ act = QWebPage.WebAction.MoveToPreviousChar
for _ in range(count):
self._widget.triggerPageAction(act)
def move_to_end_of_word(self, count=1):
if self._selection_state is browsertab.SelectionState.normal:
- act = [QWebPage.SelectNextWord]
+ act = [QWebPage.WebAction.SelectNextWord]
if utils.is_windows: # pragma: no cover
- act.append(QWebPage.SelectPreviousChar)
+ act.append(QWebPage.WebAction.SelectPreviousChar)
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = [QWebPage.MoveToNextWord]
+ act = [QWebPage.WebAction.MoveToNextWord]
if utils.is_windows: # pragma: no cover
- act.append(QWebPage.MoveToPreviousChar)
+ act.append(QWebPage.WebAction.MoveToPreviousChar)
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
def move_to_next_word(self, count=1):
if self._selection_state is browsertab.SelectionState.normal:
- act = [QWebPage.SelectNextWord]
+ act = [QWebPage.WebAction.SelectNextWord]
if not utils.is_windows: # pragma: no branch
- act.append(QWebPage.SelectNextChar)
+ act.append(QWebPage.WebAction.SelectNextChar)
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = [QWebPage.MoveToNextWord]
+ act = [QWebPage.WebAction.MoveToNextWord]
if not utils.is_windows: # pragma: no branch
- act.append(QWebPage.MoveToNextChar)
+ act.append(QWebPage.WebAction.MoveToNextChar)
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
def move_to_prev_word(self, count=1):
if self._selection_state is browsertab.SelectionState.normal:
- act = QWebPage.SelectPreviousWord
+ act = QWebPage.WebAction.SelectPreviousWord
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = QWebPage.MoveToPreviousWord
+ act = QWebPage.WebAction.MoveToPreviousWord
for _ in range(count):
self._widget.triggerPageAction(act)
def move_to_start_of_line(self):
if self._selection_state is browsertab.SelectionState.normal:
- act = QWebPage.SelectStartOfLine
+ act = QWebPage.WebAction.SelectStartOfLine
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = QWebPage.MoveToStartOfLine
+ act = QWebPage.WebAction.MoveToStartOfLine
self._widget.triggerPageAction(act)
def move_to_end_of_line(self):
if self._selection_state is browsertab.SelectionState.normal:
- act = QWebPage.SelectEndOfLine
+ act = QWebPage.WebAction.SelectEndOfLine
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = QWebPage.MoveToEndOfLine
+ act = QWebPage.WebAction.MoveToEndOfLine
self._widget.triggerPageAction(act)
def move_to_start_of_next_block(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = [QWebPage.SelectNextLine,
- QWebPage.SelectStartOfBlock]
+ act = [QWebPage.WebAction.SelectNextLine,
+ QWebPage.WebAction.SelectStartOfBlock]
else:
- act = [QWebPage.MoveToNextLine,
- QWebPage.MoveToStartOfBlock]
+ act = [QWebPage.WebAction.MoveToNextLine,
+ QWebPage.WebAction.MoveToStartOfBlock]
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
@@ -390,11 +393,11 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_start_of_prev_block(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = [QWebPage.SelectPreviousLine,
- QWebPage.SelectStartOfBlock]
+ act = [QWebPage.WebAction.SelectPreviousLine,
+ QWebPage.WebAction.SelectStartOfBlock]
else:
- act = [QWebPage.MoveToPreviousLine,
- QWebPage.MoveToStartOfBlock]
+ act = [QWebPage.WebAction.MoveToPreviousLine,
+ QWebPage.WebAction.MoveToStartOfBlock]
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
@@ -403,11 +406,11 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_end_of_next_block(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = [QWebPage.SelectNextLine,
- QWebPage.SelectEndOfBlock]
+ act = [QWebPage.WebAction.SelectNextLine,
+ QWebPage.WebAction.SelectEndOfBlock]
else:
- act = [QWebPage.MoveToNextLine,
- QWebPage.MoveToEndOfBlock]
+ act = [QWebPage.WebAction.MoveToNextLine,
+ QWebPage.WebAction.MoveToEndOfBlock]
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
@@ -416,9 +419,9 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_end_of_prev_block(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = [QWebPage.SelectPreviousLine, QWebPage.SelectEndOfBlock]
+ act = [QWebPage.WebAction.SelectPreviousLine, QWebPage.WebAction.SelectEndOfBlock]
else:
- act = [QWebPage.MoveToPreviousLine, QWebPage.MoveToEndOfBlock]
+ act = [QWebPage.WebAction.MoveToPreviousLine, QWebPage.WebAction.MoveToEndOfBlock]
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
@@ -427,18 +430,18 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_start_of_document(self):
if self._selection_state is not browsertab.SelectionState.none:
- act = QWebPage.SelectStartOfDocument
+ act = QWebPage.WebAction.SelectStartOfDocument
else:
- act = QWebPage.MoveToStartOfDocument
+ act = QWebPage.WebAction.MoveToStartOfDocument
self._widget.triggerPageAction(act)
if self._selection_state is browsertab.SelectionState.line:
self._select_line()
def move_to_end_of_document(self):
if self._selection_state is not browsertab.SelectionState.none:
- act = QWebPage.SelectEndOfDocument
+ act = QWebPage.WebAction.SelectEndOfDocument
else:
- act = QWebPage.MoveToEndOfDocument
+ act = QWebPage.WebAction.MoveToEndOfDocument
self._widget.triggerPageAction(act)
def toggle_selection(self, line=False):
@@ -455,7 +458,7 @@ class WebKitCaret(browsertab.AbstractCaret):
self.selection_toggled.emit(self._selection_state)
def drop_selection(self):
- self._widget.triggerPageAction(QWebPage.MoveToNextChar)
+ self._widget.triggerPageAction(QWebPage.WebAction.MoveToNextChar)
def selection(self, callback):
callback(self._widget.selectedText())
@@ -470,9 +473,9 @@ class WebKitCaret(browsertab.AbstractCaret):
}""")
def _select_line(self):
- self._widget.triggerPageAction(QWebPage.SelectStartOfLine)
+ self._widget.triggerPageAction(QWebPage.WebAction.SelectStartOfLine)
self.reverse_selection()
- self._widget.triggerPageAction(QWebPage.SelectEndOfLine)
+ self._widget.triggerPageAction(QWebPage.WebAction.SelectEndOfLine)
self.reverse_selection()
def _select_line_to_end(self):
@@ -480,11 +483,11 @@ class WebKitCaret(browsertab.AbstractCaret):
# of focus) has to be checked before moving selection
# to the end of line
if self._js_selection_left_to_right():
- self._widget.triggerPageAction(QWebPage.SelectEndOfLine)
+ self._widget.triggerPageAction(QWebPage.WebAction.SelectEndOfLine)
def _select_line_to_start(self):
if not self._js_selection_left_to_right():
- self._widget.triggerPageAction(QWebPage.SelectStartOfLine)
+ self._widget.triggerPageAction(QWebPage.WebAction.SelectStartOfLine)
def _js_selection_left_to_right(self):
"""Return True iff the selection's direction is left to right."""
@@ -497,7 +500,7 @@ class WebKitCaret(browsertab.AbstractCaret):
def _follow_selected(self, *, tab=False):
if QWebSettings.globalSettings().testAttribute(
- QWebSettings.JavascriptEnabled):
+ QWebSettings.WebAttribute.JavascriptEnabled):
if tab:
self._tab.data.override_target = usertypes.ClickTarget.tab
self._tab.run_js_async("""
@@ -599,7 +602,7 @@ class WebKitScroller(browsertab.AbstractScroller):
elif x is None and y == 100:
self.bottom()
else:
- for val, orientation in [(x, Qt.Horizontal), (y, Qt.Vertical)]:
+ for val, orientation in [(x, Qt.Orientation.Horizontal), (y, Qt.Orientation.Vertical)]:
if val is not None:
frame = self._widget.page().mainFrame()
maximum = frame.scrollBarMaximum(orientation)
@@ -624,36 +627,36 @@ class WebKitScroller(browsertab.AbstractScroller):
self._tab.fake_key_press(key)
def up(self, count=1):
- self._key_press(Qt.Key_Up, count, 'scrollBarMinimum', Qt.Vertical)
+ self._key_press(Qt.Key.Key_Up, count, 'scrollBarMinimum', Qt.Orientation.Vertical)
def down(self, count=1):
- self._key_press(Qt.Key_Down, count, 'scrollBarMaximum', Qt.Vertical)
+ self._key_press(Qt.Key.Key_Down, count, 'scrollBarMaximum', Qt.Orientation.Vertical)
def left(self, count=1):
- self._key_press(Qt.Key_Left, count, 'scrollBarMinimum', Qt.Horizontal)
+ self._key_press(Qt.Key.Key_Left, count, 'scrollBarMinimum', Qt.Orientation.Horizontal)
def right(self, count=1):
- self._key_press(Qt.Key_Right, count, 'scrollBarMaximum', Qt.Horizontal)
+ self._key_press(Qt.Key.Key_Right, count, 'scrollBarMaximum', Qt.Orientation.Horizontal)
def top(self):
- self._key_press(Qt.Key_Home)
+ self._key_press(Qt.Key.Key_Home)
def bottom(self):
- self._key_press(Qt.Key_End)
+ self._key_press(Qt.Key.Key_End)
def page_up(self, count=1):
- self._key_press(Qt.Key_PageUp, count, 'scrollBarMinimum', Qt.Vertical)
+ self._key_press(Qt.Key.Key_PageUp, count, 'scrollBarMinimum', Qt.Orientation.Vertical)
def page_down(self, count=1):
- self._key_press(Qt.Key_PageDown, count, 'scrollBarMaximum',
- Qt.Vertical)
+ self._key_press(Qt.Key.Key_PageDown, count, 'scrollBarMaximum',
+ Qt.Orientation.Vertical)
def at_top(self):
return self.pos_px().y() == 0
def at_bottom(self):
frame = self._widget.page().currentFrame()
- return self.pos_px().y() >= frame.scrollBarMaximum(Qt.Vertical)
+ return self.pos_px().y() >= frame.scrollBarMaximum(Qt.Orientation.Vertical)
class WebKitHistoryPrivate(browsertab.AbstractHistoryPrivate):
@@ -882,7 +885,7 @@ class WebKitTab(browsertab.AbstractTab):
tab=self, parent=self)
self.zoom = WebKitZoom(tab=self, parent=self)
self.search = WebKitSearch(tab=self, parent=self)
- self.printing = WebKitPrinting(tab=self)
+ self.printing = WebKitPrinting(tab=self, parent=self)
self.elements = WebKitElements(tab=self)
self.action = WebKitAction(tab=self)
self.audio = WebKitAudio(tab=self, parent=self)
@@ -899,7 +902,7 @@ class WebKitTab(browsertab.AbstractTab):
def _make_private(self, widget):
settings = widget.settings()
- settings.setAttribute(QWebSettings.PrivateBrowsingEnabled, True)
+ settings.setAttribute(QWebSettings.WebAttribute.PrivateBrowsingEnabled, True)
def load_url(self, url):
self._load_url_prepare(url)
@@ -931,9 +934,9 @@ class WebKitTab(browsertab.AbstractTab):
def reload(self, *, force=False):
if force:
- action = QWebPage.ReloadAndBypassCache
+ action = QWebPage.WebAction.ReloadAndBypassCache
else:
- action = QWebPage.Reload
+ action = QWebPage.WebAction.Reload
self._widget.triggerPageAction(action)
def stop(self):
diff --git a/qutebrowser/browser/webkit/webpage.py b/qutebrowser/browser/webkit/webpage.py
index 9c7495478..2dd4551b9 100644
--- a/qutebrowser/browser/webkit/webpage.py
+++ b/qutebrowser/browser/webkit/webpage.py
@@ -17,17 +17,20 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+# FIXME:qt6 (lint)
+# pylint: disable=no-name-in-module
+
"""The main browser widgets."""
import html
import functools
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QUrl, QPoint
-from PyQt5.QtGui import QDesktopServices
-from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
-from PyQt5.QtWidgets import QFileDialog
-from PyQt5.QtPrintSupport import QPrintDialog
-from PyQt5.QtWebKitWidgets import QWebPage, QWebFrame
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, Qt, QUrl, QPoint
+from qutebrowser.qt.gui import QDesktopServices
+from qutebrowser.qt.network import QNetworkReply, QNetworkRequest
+from qutebrowser.qt.widgets import QFileDialog
+from qutebrowser.qt.printsupport import QPrintDialog
+from qutebrowser.qt.webkitwidgets import QWebPage, QWebFrame
from qutebrowser.config import websettings, config
from qutebrowser.browser import pdfjs, shared, downloads, greasemonkey
@@ -67,8 +70,8 @@ class BrowserPage(QWebPage):
self._tabdata = tabdata
self._is_shutting_down = False
self._extension_handlers = {
- QWebPage.ErrorPageExtension: self._handle_errorpage,
- QWebPage.ChooseMultipleFilesExtension: self._handle_multiple_files,
+ QWebPage.Extension.ErrorPageExtension: self._handle_errorpage,
+ QWebPage.Extension.ChooseMultipleFilesExtension: self._handle_multiple_files,
}
self._ignore_load_started = False
self.error_occurred = False
@@ -134,16 +137,16 @@ class BrowserPage(QWebPage):
False if no error page should be displayed, True otherwise.
"""
ignored_errors = [
- (QWebPage.QtNetwork, QNetworkReply.OperationCanceledError),
+ (QWebPage.ErrorDomain.QtNetwork, QNetworkReply.NetworkError.OperationCanceledError),
# "Loading is handled by the media engine"
- (QWebPage.WebKit, 203),
+ (QWebPage.ErrorDomain.WebKit, 203),
# "Frame load interrupted by policy change"
- (QWebPage.WebKit, 102),
+ (QWebPage.ErrorDomain.WebKit, 102),
]
errpage.baseUrl = info.url
urlstr = info.url.toDisplayString()
- if (info.domain, info.error) == (QWebPage.QtNetwork,
- QNetworkReply.ProtocolUnknownError):
+ if (info.domain, info.error) == (QWebPage.ErrorDomain.QtNetwork,
+ QNetworkReply.NetworkError.ProtocolUnknownError):
# For some reason, we get a segfault when we use
# QDesktopServices::openUrl with info.url directly - however it
# works when we construct a copy of it.
@@ -154,7 +157,7 @@ class BrowserPage(QWebPage):
text="URL: <b>{}</b>".format(
html.escape(url.toDisplayString())),
yes_action=functools.partial(QDesktopServices.openUrl, url),
- url=info.url.toString(QUrl.RemovePassword | QUrl.FullyEncoded))
+ url=info.url.toString(QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded))
return True
elif (info.domain, info.error) in ignored_errors:
log.webview.debug("Ignored error on {}: {} (error domain: {}, "
@@ -251,7 +254,7 @@ class BrowserPage(QWebPage):
def on_print_requested(self, frame):
"""Handle printing when requested via javascript."""
printdiag = QPrintDialog()
- printdiag.setAttribute(Qt.WA_DeleteOnClose)
+ printdiag.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
printdiag.open(lambda: frame.print(printdiag.printer()))
def on_download_requested(self, request):
@@ -357,24 +360,24 @@ class BrowserPage(QWebPage):
return
options = {
- QWebPage.Notifications: 'content.notifications.enabled',
- QWebPage.Geolocation: 'content.geolocation',
+ QWebPage.Feature.Notifications: 'content.notifications.enabled',
+ QWebPage.Feature.Geolocation: 'content.geolocation',
}
messages = {
- QWebPage.Notifications: 'show notifications',
- QWebPage.Geolocation: 'access your location',
+ QWebPage.Feature.Notifications: 'show notifications',
+ QWebPage.Feature.Geolocation: 'access your location',
}
yes_action = functools.partial(
self.setFeaturePermission, frame, feature,
- QWebPage.PermissionGrantedByUser)
+ QWebPage.PermissionPolicy.PermissionGrantedByUser)
no_action = functools.partial(
self.setFeaturePermission, frame, feature,
- QWebPage.PermissionDeniedByUser)
+ QWebPage.PermissionPolicy.PermissionDeniedByUser)
- url = frame.url().adjusted(QUrl.RemoveUserInfo | # type: ignore[operator]
- QUrl.RemovePath |
- QUrl.RemoveQuery |
- QUrl.RemoveFragment)
+ url = frame.url().adjusted(QUrl.UrlFormattingOption.RemoveUserInfo | # type: ignore[operator]
+ QUrl.UrlFormattingOption.RemovePath |
+ QUrl.UrlFormattingOption.RemoveQuery |
+ QUrl.UrlFormattingOption.RemoveFragment)
question = shared.feature_permission(
url=url,
option=options[feature], msg=messages[feature],
@@ -507,17 +510,17 @@ class BrowserPage(QWebPage):
and then conditionally opens the URL here or in another tab/window.
"""
type_map = {
- QWebPage.NavigationTypeLinkClicked:
+ QWebPage.NavigationType.NavigationTypeLinkClicked:
usertypes.NavigationRequest.Type.link_clicked,
- QWebPage.NavigationTypeFormSubmitted:
+ QWebPage.NavigationType.NavigationTypeFormSubmitted:
usertypes.NavigationRequest.Type.form_submitted,
- QWebPage.NavigationTypeFormResubmitted:
+ QWebPage.NavigationType.NavigationTypeFormResubmitted:
usertypes.NavigationRequest.Type.form_resubmitted,
- QWebPage.NavigationTypeBackOrForward:
+ QWebPage.NavigationType.NavigationTypeBackOrForward:
usertypes.NavigationRequest.Type.back_forward,
- QWebPage.NavigationTypeReload:
- usertypes.NavigationRequest.Type.reloaded,
- QWebPage.NavigationTypeOther:
+ QWebPage.NavigationType.NavigationTypeReload:
+ usertypes.NavigationRequest.Type.reload,
+ QWebPage.NavigationType.NavigationTypeOther:
usertypes.NavigationRequest.Type.other,
}
is_main_frame = frame is self.mainFrame()
@@ -525,7 +528,7 @@ class BrowserPage(QWebPage):
navigation_type=type_map[typ],
is_main_frame=is_main_frame)
- if navigation.navigation_type == navigation.Type.reloaded:
+ if navigation.navigation_type == navigation.Type.reload:
self.reloading.emit(navigation.url)
self.navigation_request.emit(navigation)
diff --git a/qutebrowser/browser/webkit/webview.py b/qutebrowser/browser/webkit/webview.py
index be087c855..aaeba4033 100644
--- a/qutebrowser/browser/webkit/webview.py
+++ b/qutebrowser/browser/webkit/webview.py
@@ -17,11 +17,14 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+# FIXME:qt6 (lint)
+# pylint: disable=no-name-in-module
+
"""The main browser widgets."""
-from PyQt5.QtCore import pyqtSignal, Qt, QUrl
-from PyQt5.QtWebKit import QWebSettings
-from PyQt5.QtWebKitWidgets import QWebView, QWebPage
+from qutebrowser.qt.core import pyqtSignal, Qt, QUrl
+from qutebrowser.qt.webkit import QWebSettings
+from qutebrowser.qt.webkitwidgets import QWebView, QWebPage
from qutebrowser.config import config, stylesheet
from qutebrowser.keyinput import modeman
@@ -74,15 +77,15 @@ class WebView(QWebView):
tabdata=tab.data, private=private,
parent=self)
page.setVisibilityState(
- QWebPage.VisibilityStateVisible if self.isVisible()
- else QWebPage.VisibilityStateHidden)
+ QWebPage.VisibilityState.VisibilityStateVisible if self.isVisible()
+ else QWebPage.VisibilityState.VisibilityStateHidden)
self.setPage(page)
stylesheet.set_register(self)
def __repr__(self):
- flags = QUrl.EncodeUnicode
+ flags = QUrl.ComponentFormattingOption.EncodeUnicode
urlstr = self.url().toDisplayString(flags) # type: ignore[arg-type]
url = utils.elide(urlstr, 100)
return utils.get_repr(self, tab_id=self._tab_id, url=url)
@@ -107,7 +110,7 @@ class WebView(QWebView):
# quitting it seems.
log.destroy.debug("Shutting down {!r}.".format(self))
settings = self.settings()
- settings.setAttribute(QWebSettings.JavascriptEnabled, False)
+ settings.setAttribute(QWebSettings.WebAttribute.JavascriptEnabled, False)
self.stop()
page = self.page()
assert isinstance(page, webpage.BrowserPage), page
@@ -134,7 +137,7 @@ class WebView(QWebView):
"""
debug_type = debug.qenum_key(QWebPage, wintype)
log.webview.debug("createWindow with type {}".format(debug_type))
- if wintype == QWebPage.WebModalDialog:
+ if wintype == QWebPage.WebWindowType.WebModalDialog:
log.webview.warning("WebModalDialog requested, but we don't "
"support that!")
tabbed_browser = objreg.get('tabbed-browser', scope='window',
@@ -156,12 +159,12 @@ class WebView(QWebView):
e: The QPaintEvent.
"""
frame = self.page().mainFrame()
- new_pos = (frame.scrollBarValue(Qt.Horizontal),
- frame.scrollBarValue(Qt.Vertical))
+ new_pos = (frame.scrollBarValue(Qt.Orientation.Horizontal),
+ frame.scrollBarValue(Qt.Orientation.Vertical))
if self._old_scroll_pos != new_pos:
self._old_scroll_pos = new_pos
- m = (frame.scrollBarMaximum(Qt.Horizontal),
- frame.scrollBarMaximum(Qt.Vertical))
+ m = (frame.scrollBarMaximum(Qt.Orientation.Horizontal),
+ frame.scrollBarMaximum(Qt.Orientation.Vertical))
perc = (round(100 * new_pos[0] / m[0]) if m[0] != 0 else 0,
round(100 * new_pos[1] / m[1]) if m[1] != 0 else 0)
self.scroll_pos = perc
@@ -187,7 +190,7 @@ class WebView(QWebView):
e: The QShowEvent.
"""
super().showEvent(e)
- self.page().setVisibilityState(QWebPage.VisibilityStateVisible)
+ self.page().setVisibilityState(QWebPage.VisibilityState.VisibilityStateVisible)
def hideEvent(self, e):
"""Extend hideEvent to set the page visibility state to hidden.
@@ -196,16 +199,16 @@ class WebView(QWebView):
e: The QHideEvent.
"""
super().hideEvent(e)
- self.page().setVisibilityState(QWebPage.VisibilityStateHidden)
+ self.page().setVisibilityState(QWebPage.VisibilityState.VisibilityStateHidden)
def mousePressEvent(self, e):
"""Set the tabdata ClickTarget on a mousepress.
This is implemented here as we don't need it for QtWebEngine.
"""
- if e.button() == Qt.MidButton or e.modifiers() & Qt.ControlModifier:
+ if e.button() == Qt.MouseButton.MidButton or e.modifiers() & Qt.KeyboardModifier.ControlModifier:
background = config.val.tabs.background
- if e.modifiers() & Qt.ShiftModifier:
+ if e.modifiers() & Qt.KeyboardModifier.ShiftModifier:
background = not background
if background:
target = usertypes.ClickTarget.tab_bg
diff --git a/qutebrowser/commands/argparser.py b/qutebrowser/commands/argparser.py
index 2a11589f9..febfa7812 100644
--- a/qutebrowser/commands/argparser.py
+++ b/qutebrowser/commands/argparser.py
@@ -21,7 +21,7 @@
import argparse
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.commands import cmdexc
from qutebrowser.utils import utils, objreg, log
diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py
index e3cd0cc97..7cf6ab6fa 100644
--- a/qutebrowser/commands/runners.py
+++ b/qutebrowser/commands/runners.py
@@ -24,7 +24,7 @@ import re
import contextlib
from typing import TYPE_CHECKING, Callable, Dict, Iterator, Mapping, MutableMapping
-from PyQt5.QtCore import pyqtSlot, QUrl, QObject
+from qutebrowser.qt.core import pyqtSlot, QUrl, QObject
from qutebrowser.api import cmdutils
from qutebrowser.commands import cmdexc, parser
@@ -55,9 +55,9 @@ def _init_variable_replacements() -> Mapping[str, _ReplacementFunction]:
"""Return a dict from variable replacements to fns processing them."""
replacements: Dict[str, _ReplacementFunction] = {
'url': lambda tb: _url(tb).toString(
- QUrl.FullyEncoded | QUrl.RemovePassword),
+ QUrl.ComponentFormattingOption.FullyEncoded | QUrl.UrlFormattingOption.RemovePassword),
'url:pretty': lambda tb: _url(tb).toString(
- QUrl.DecodeReserved | QUrl.RemovePassword),
+ QUrl.ComponentFormattingOption.DecodeReserved | QUrl.UrlFormattingOption.RemovePassword),
'url:domain': lambda tb: "{}://{}{}".format(
_url(tb).scheme(), _url(tb).host(),
":" + str(_url(tb).port()) if _url(tb).port() != -1 else ""),
diff --git a/qutebrowser/commands/userscripts.py b/qutebrowser/commands/userscripts.py
index c776324ac..17164a23a 100644
--- a/qutebrowser/commands/userscripts.py
+++ b/qutebrowser/commands/userscripts.py
@@ -24,7 +24,7 @@ import os.path
import tempfile
from typing import cast, Any, MutableMapping, Tuple
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QSocketNotifier
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QObject, QSocketNotifier
import qutebrowser
from qutebrowser.utils import message, log, objreg, standarddir, utils
@@ -62,7 +62,7 @@ class _QtFIFOReader(QObject):
# pylint: enable=no-member,useless-suppression
self._fifo = os.fdopen(fd, 'r')
self._notifier = QSocketNotifier(cast(sip.voidptr, fd),
- QSocketNotifier.Read, self)
+ QSocketNotifier.Type.Read, self)
self._notifier.activated.connect(self.read_line)
@pyqtSlot()
diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py
index 34e68fd2a..45c287717 100644
--- a/qutebrowser/completion/completer.py
+++ b/qutebrowser/completion/completer.py
@@ -22,7 +22,7 @@
import dataclasses
from typing import TYPE_CHECKING
-from PyQt5.QtCore import pyqtSlot, QObject, QTimer
+from qutebrowser.qt.core import pyqtSlot, QObject, QTimer
from qutebrowser.config import config
from qutebrowser.commands import parser, cmdexc
diff --git a/qutebrowser/completion/completiondelegate.py b/qutebrowser/completion/completiondelegate.py
index ae02426a5..f6fec39f6 100644
--- a/qutebrowser/completion/completiondelegate.py
+++ b/qutebrowser/completion/completiondelegate.py
@@ -25,9 +25,9 @@ We use this to be able to highlight parts of the text.
import re
import html
-from PyQt5.QtWidgets import QStyle, QStyleOptionViewItem, QStyledItemDelegate
-from PyQt5.QtCore import QRectF, QRegularExpression, QSize, Qt
-from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption,
+from qutebrowser.qt.widgets import QStyle, QStyleOptionViewItem, QStyledItemDelegate
+from qutebrowser.qt.core import QRectF, QRegularExpression, QSize, Qt
+from qutebrowser.qt.gui import (QIcon, QPalette, QTextDocument, QTextOption,
QAbstractTextDocumentLayout, QSyntaxHighlighter,
QTextCharFormat)
@@ -46,7 +46,7 @@ class _Highlighter(QSyntaxHighlighter):
words.sort(key=len, reverse=True)
pat = "|".join(re.escape(word) for word in words)
self._expression = QRegularExpression(
- pat, QRegularExpression.CaseInsensitiveOption
+ pat, QRegularExpression.PatternOption.CaseInsensitiveOption
)
qtutils.ensure_valid(self._expression)
@@ -95,7 +95,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
"""Draw the background of an ItemViewItem."""
assert self._opt is not None
assert self._style is not None
- self._style.drawPrimitive(self._style.PE_PanelItemViewItem, self._opt,
+ self._style.drawPrimitive(QStyle.PrimitiveElement.PE_PanelItemViewItem, self._opt,
self._painter, self._opt.widget)
def _draw_icon(self):
@@ -104,18 +104,18 @@ class CompletionItemDelegate(QStyledItemDelegate):
assert self._style is not None
icon_rect = self._style.subElementRect(
- self._style.SE_ItemViewItemDecoration, self._opt, self._opt.widget)
+ QStyle.SubElement.SE_ItemViewItemDecoration, self._opt, self._opt.widget)
if not icon_rect.isValid():
# The rect seems to be wrong in all kind of ways if no icon should
# be displayed.
return
- mode = QIcon.Normal
- if not self._opt.state & QStyle.State_Enabled:
- mode = QIcon.Disabled
- elif self._opt.state & QStyle.State_Selected:
- mode = QIcon.Selected
- state = QIcon.On if self._opt.state & QStyle.State_Open else QIcon.Off
+ mode = QIcon.Mode.Normal
+ if not self._opt.state & QStyle.StateFlag.State_Enabled:
+ mode = QIcon.Mode.Disabled
+ elif self._opt.state & QStyle.StateFlag.State_Selected:
+ mode = QIcon.Mode.Selected
+ state = QIcon.State.On if self._opt.state & QStyle.StateFlag.State_Open else QIcon.State.Off
self._opt.icon.paint(self._painter, icon_rect,
self._opt.decorationAlignment, mode, state)
@@ -135,9 +135,9 @@ class CompletionItemDelegate(QStyledItemDelegate):
return
text_rect_ = self._style.subElementRect(
- self._style.SE_ItemViewItemText, self._opt, self._opt.widget)
+ QStyle.SubElement.SE_ItemViewItemText, self._opt, self._opt.widget)
qtutils.ensure_valid(text_rect_)
- margin = self._style.pixelMetric(QStyle.PM_FocusFrameHMargin,
+ margin = self._style.pixelMetric(QStyle.PixelMetric.PM_FocusFrameHMargin,
self._opt, self._opt.widget) + 1
# remove width padding
text_rect = text_rect_.adjusted(margin, 0, -margin, 0)
@@ -149,24 +149,24 @@ class CompletionItemDelegate(QStyledItemDelegate):
text_rect.adjust(0, -2, 0, -2)
self._painter.save()
state = self._opt.state
- if state & QStyle.State_Enabled and state & QStyle.State_Active:
- cg = QPalette.Normal
- elif state & QStyle.State_Enabled:
- cg = QPalette.Inactive
+ if state & QStyle.StateFlag.State_Enabled and state & QStyle.StateFlag.State_Active:
+ cg = QPalette.ColorGroup.Normal
+ elif state & QStyle.StateFlag.State_Enabled:
+ cg = QPalette.ColorGroup.Inactive
else:
- cg = QPalette.Disabled
+ cg = QPalette.ColorGroup.Disabled
- if state & QStyle.State_Selected:
+ if state & QStyle.StateFlag.State_Selected:
self._painter.setPen(self._opt.palette.color(
- cg, QPalette.HighlightedText))
+ cg, QPalette.ColorRole.HighlightedText))
# This is a dirty fix for the text jumping by one pixel for
# whatever reason.
text_rect.adjust(0, -1, 0, 0)
else:
- self._painter.setPen(self._opt.palette.color(cg, QPalette.Text))
+ self._painter.setPen(self._opt.palette.color(cg, QPalette.ColorRole.Text))
- if state & QStyle.State_Editing:
- self._painter.setPen(self._opt.palette.color(cg, QPalette.Text))
+ if state & QStyle.StateFlag.State_Editing:
+ self._painter.setPen(self._opt.palette.color(cg, QPalette.ColorRole.Text))
self._painter.drawRect(text_rect_.adjusted(0, 0, -1, -1))
self._painter.translate(text_rect.left(), text_rect.top())
@@ -188,9 +188,9 @@ class CompletionItemDelegate(QStyledItemDelegate):
clip = QRectF(0, 0, rect.width(), rect.height())
self._painter.save()
- if self._opt.state & QStyle.State_Selected:
+ if self._opt.state & QStyle.StateFlag.State_Selected:
color = config.cache['colors.completion.item.selected.fg']
- elif not self._opt.state & QStyle.State_Enabled:
+ elif not self._opt.state & QStyle.StateFlag.State_Enabled:
color = config.cache['colors.completion.category.fg']
else:
colors = config.cache['colors.completion.fg']
@@ -199,7 +199,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
self._painter.setPen(color)
ctx = QAbstractTextDocumentLayout.PaintContext()
- ctx.palette.setColor(QPalette.Text, self._painter.pen().color())
+ ctx.palette.setColor(QPalette.ColorRole.Text, self._painter.pen().color())
if clip.isValid():
self._painter.setClipRect(clip)
ctx.clip = clip
@@ -217,10 +217,10 @@ class CompletionItemDelegate(QStyledItemDelegate):
# qcommonstyle.cpp:viewItemDrawText
# https://github.com/qutebrowser/qutebrowser/issues/118
text_option = QTextOption()
- if self._opt.features & QStyleOptionViewItem.WrapText:
- text_option.setWrapMode(QTextOption.WordWrap)
+ if self._opt.features & QStyleOptionViewItem.ViewItemFeature.WrapText:
+ text_option.setWrapMode(QTextOption.WrapMode.WordWrap)
else:
- text_option.setWrapMode(QTextOption.ManualWrap)
+ text_option.setWrapMode(QTextOption.WrapMode.ManualWrap)
text_option.setTextDirection(self._opt.direction)
text_option.setAlignment(QStyle.visualAlignment(
self._opt.direction, self._opt.displayAlignment))
@@ -238,7 +238,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
pattern = view.pattern
columns_to_filter = index.model().columns_to_filter(index)
if index.column() in columns_to_filter and pattern:
- if self._opt.state & QStyle.State_Selected:
+ if self._opt.state & QStyle.StateFlag.State_Selected:
color = config.val.colors.completion.item.selected.match.fg
else:
color = config.val.colors.completion.match.fg
@@ -255,23 +255,23 @@ class CompletionItemDelegate(QStyledItemDelegate):
assert self._opt is not None
assert self._style is not None
state = self._opt.state
- if not state & QStyle.State_HasFocus:
+ if not state & QStyle.StateFlag.State_HasFocus:
return
o = self._opt
o.rect = self._style.subElementRect(
- self._style.SE_ItemViewItemFocusRect, self._opt, self._opt.widget)
- o.state |= int(QStyle.State_KeyboardFocusChange | QStyle.State_Item)
+ QStyle.SubElement.SE_ItemViewItemFocusRect, self._opt, self._opt.widget)
+ o.state |= QStyle.StateFlag.State_KeyboardFocusChange | QStyle.StateFlag.State_Item
qtutils.ensure_valid(o.rect)
- if state & QStyle.State_Enabled:
- cg = QPalette.Normal
+ if state & QStyle.StateFlag.State_Enabled:
+ cg = QPalette.ColorGroup.Normal
else:
- cg = QPalette.Disabled
- if state & QStyle.State_Selected:
- role = QPalette.Highlight
+ cg = QPalette.ColorGroup.Disabled
+ if state & QStyle.StateFlag.State_Selected:
+ role = QPalette.ColorRole.Highlight
else:
- role = QPalette.Window
+ role = QPalette.ColorRole.Window
o.backgroundColor = self._opt.palette.color(cg, role)
- self._style.drawPrimitive(QStyle.PE_FrameFocusRect, o, self._painter,
+ self._style.drawPrimitive(QStyle.PrimitiveElement.PE_FrameFocusRect, o, self._painter,
self._opt.widget)
def sizeHint(self, option, index):
@@ -287,7 +287,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
Return:
A QSize with the recommended size.
"""
- value = index.data(Qt.SizeHintRole)
+ value = index.data(Qt.ItemDataRole.SizeHintRole)
if value is not None:
return value
self._opt = QStyleOptionViewItem(option)
@@ -298,7 +298,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
assert self._doc is not None
docsize = self._doc.size().toSize()
- size = self._style.sizeFromContents(QStyle.CT_ItemViewItem, self._opt,
+ size = self._style.sizeFromContents(QStyle.ContentsType.CT_ItemViewItem, self._opt,
docsize, self._opt.widget)
qtutils.ensure_valid(size)
return size + QSize(10, 3)
diff --git a/qutebrowser/completion/completionwidget.py b/qutebrowser/completion/completionwidget.py
index de9100a2e..c137f1141 100644
--- a/qutebrowser/completion/completionwidget.py
+++ b/qutebrowser/completion/completionwidget.py
@@ -25,8 +25,8 @@ subclasses to provide completions.
from typing import TYPE_CHECKING, Optional
-from PyQt5.QtWidgets import QTreeView, QSizePolicy, QStyleFactory, QWidget
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QItemSelectionModel, QSize
+from qutebrowser.qt.widgets import QTreeView, QSizePolicy, QStyleFactory, QWidget
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, Qt, QItemSelectionModel, QSize
from qutebrowser.config import config, stylesheet
from qutebrowser.completion import completiondelegate
@@ -127,14 +127,14 @@ class CompletionView(QTreeView):
self.setItemDelegate(self._delegate)
self.setStyle(QStyleFactory.create('Fusion'))
stylesheet.set_register(self)
- self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+ self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
self.setHeaderHidden(True)
self.setAlternatingRowColors(True)
self.setIndentation(0)
self.setItemsExpandable(False)
self.setExpandsOnDoubleClick(False)
self.setAnimated(False)
- self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+ self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
# WORKAROUND
# This is a workaround for weird race conditions with invalid
# item indexes leading to segfaults in Qt.
@@ -277,18 +277,20 @@ class CompletionView(QTreeView):
direction = -1 if upwards else 1
while True:
idx = idx.sibling(idx.row() + direction, 0)
- if not idx.isValid() and upwards:
+
+ if idx.isValid():
+ child = model.index(0, 0, idx)
+ if child.isValid():
+ self.scrollTo(idx) # scroll to ensure the category is visible
+ return child
+ elif upwards:
# wrap around to the first item of the last category
return model.last_item().sibling(0, 0)
- elif not idx.isValid() and not upwards:
+ else:
# wrap around to the first item of the first category
idx = model.first_item()
self.scrollTo(idx.parent())
return idx
- elif idx.isValid() and idx.child(0, 0).isValid():
- # scroll to ensure the category is visible
- self.scrollTo(idx)
- return idx.child(0, 0)
raise utils.Unreachable
@@ -339,8 +341,8 @@ class CompletionView(QTreeView):
selmodel.setCurrentIndex(
idx,
- QItemSelectionModel.ClearAndSelect |
- QItemSelectionModel.Rows)
+ QItemSelectionModel.SelectionFlag.ClearAndSelect |
+ QItemSelectionModel.SelectionFlag.Rows)
# if the last item is focused, try to fetch more
next_idx = self.indexBelow(idx)
diff --git a/qutebrowser/completion/models/completionmodel.py b/qutebrowser/completion/models/completionmodel.py
index 4b8fee299..ea491612a 100644
--- a/qutebrowser/completion/models/completionmodel.py
+++ b/qutebrowser/completion/models/completionmodel.py
@@ -21,7 +21,7 @@
from typing import MutableSequence
-from PyQt5.QtCore import Qt, QModelIndex, QAbstractItemModel
+from qutebrowser.qt.core import Qt, QModelIndex, QAbstractItemModel
from qutebrowser.utils import log, qtutils, utils
from qutebrowser.api import cmdutils
@@ -63,7 +63,7 @@ class CompletionModel(QAbstractItemModel):
"""Add a completion category to the model."""
self._categories.append(cat)
- def data(self, index, role=Qt.DisplayRole):
+ def data(self, index, role=Qt.ItemDataRole.DisplayRole):
"""Return the item data for index.
Override QAbstractItemModel::data.
@@ -74,7 +74,7 @@ class CompletionModel(QAbstractItemModel):
Return: The item data, or None on an invalid index.
"""
- if role != Qt.DisplayRole:
+ if role != Qt.ItemDataRole.DisplayRole:
return None
cat = self._cat_from_idx(index)
if cat:
@@ -94,17 +94,17 @@ class CompletionModel(QAbstractItemModel):
Override QAbstractItemModel::flags.
- Return: The item flags, or Qt.NoItemFlags on error.
+ Return: The item flags, or Qt.ItemFlag.NoItemFlags on error.
"""
if not index.isValid():
- return Qt.NoItemFlags
+ return Qt.ItemFlag.NoItemFlags
if index.parent().isValid():
# item
- return (Qt.ItemIsEnabled | Qt.ItemIsSelectable |
- Qt.ItemNeverHasChildren)
+ return (Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable |
+ Qt.ItemFlag.ItemNeverHasChildren)
else:
# category
- return Qt.NoItemFlags
+ return Qt.ItemFlag.NoItemFlags
def index(self, row, col, parent=QModelIndex()):
"""Get an index into the model.
diff --git a/qutebrowser/completion/models/filepathcategory.py b/qutebrowser/completion/models/filepathcategory.py
index 58d90869a..66bf41ebd 100644
--- a/qutebrowser/completion/models/filepathcategory.py
+++ b/qutebrowser/completion/models/filepathcategory.py
@@ -31,7 +31,7 @@ import os
import os.path
from typing import List, Optional, Iterable
-from PyQt5.QtCore import QAbstractListModel, QModelIndex, QObject, Qt, QUrl
+from qutebrowser.qt.core import QAbstractListModel, QModelIndex, QObject, Qt, QUrl
from qutebrowser.config import config
from qutebrowser.utils import log
@@ -100,9 +100,9 @@ class FilePathCategory(QAbstractListModel):
paths = self._glob(expanded)
self._paths = sorted(self._contract_user(val, path) for path in paths)
- def data(self, index: QModelIndex, role: int = Qt.DisplayRole) -> Optional[str]:
+ def data(self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole) -> Optional[str]:
"""Implement abstract method in QAbstractListModel."""
- if role == Qt.DisplayRole and index.column() == 0:
+ if role == Qt.ItemDataRole.DisplayRole and index.column() == 0:
return self._paths[index.row()]
return None
diff --git a/qutebrowser/completion/models/histcategory.py b/qutebrowser/completion/models/histcategory.py
index 8dd1be838..fa5c5f2aa 100644
--- a/qutebrowser/completion/models/histcategory.py
+++ b/qutebrowser/completion/models/histcategory.py
@@ -21,8 +21,8 @@
from typing import Optional
-from PyQt5.QtSql import QSqlQueryModel
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt.sql import QSqlQueryModel
+from qutebrowser.qt.widgets import QWidget
from qutebrowser.misc import sql
from qutebrowser.utils import debug, message, log
diff --git a/qutebrowser/completion/models/listcategory.py b/qutebrowser/completion/models/listcategory.py
index 352151ebb..e6756c1a3 100644
--- a/qutebrowser/completion/models/listcategory.py
+++ b/qutebrowser/completion/models/listcategory.py
@@ -22,9 +22,9 @@
import re
from typing import Iterable, Tuple
-from PyQt5.QtCore import QSortFilterProxyModel, QRegularExpression
-from PyQt5.QtGui import QStandardItem, QStandardItemModel
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt.core import QSortFilterProxyModel, QRegularExpression
+from qutebrowser.qt.gui import QStandardItem, QStandardItemModel
+from qutebrowser.qt.widgets import QWidget
from qutebrowser.completion.models import util
from qutebrowser.utils import qtutils, log
@@ -66,7 +66,7 @@ class ListCategory(QSortFilterProxyModel):
val = re.sub(r' +', r' ', val) # See #1919
val = re.escape(val)
val = val.replace(r'\ ', '.*')
- rx = QRegularExpression(val, QRegularExpression.CaseInsensitiveOption)
+ rx = QRegularExpression(val, QRegularExpression.PatternOption.CaseInsensitiveOption)
qtutils.ensure_valid(rx)
self.setFilterRegularExpression(rx)
self.invalidate()
diff --git a/qutebrowser/completion/models/urlmodel.py b/qutebrowser/completion/models/urlmodel.py
index 56af1f7c7..f64e0b570 100644
--- a/qutebrowser/completion/models/urlmodel.py
+++ b/qutebrowser/completion/models/urlmodel.py
@@ -21,7 +21,7 @@
from typing import Dict, Sequence
-from PyQt5.QtCore import QAbstractItemModel
+from qutebrowser.qt.core import QAbstractItemModel
from qutebrowser.completion.models import (completionmodel, filepathcategory,
listcategory, histcategory)
diff --git a/qutebrowser/components/braveadblock.py b/qutebrowser/components/braveadblock.py
index 94dfb547c..82a59b482 100644
--- a/qutebrowser/components/braveadblock.py
+++ b/qutebrowser/components/braveadblock.py
@@ -27,7 +27,7 @@ import contextlib
import subprocess
from typing import Optional, IO, Iterator
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.api import (
hook,
@@ -109,6 +109,7 @@ _RESOURCE_TYPE_STRINGS = {
ResourceType.plugin_resource: "other",
ResourceType.preload_main_frame: "other",
ResourceType.preload_sub_frame: "other",
+ ResourceType.websocket: "websocket",
ResourceType.unknown: "other",
None: "",
}
diff --git a/qutebrowser/components/hostblock.py b/qutebrowser/components/hostblock.py
index 191719f10..f364269d6 100644
--- a/qutebrowser/components/hostblock.py
+++ b/qutebrowser/components/hostblock.py
@@ -26,7 +26,7 @@ import logging
import pathlib
from typing import cast, IO, Set
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.api import (
hook,
diff --git a/qutebrowser/components/misccommands.py b/qutebrowser/components/misccommands.py
index 98eb5c8f4..0b3a918d1 100644
--- a/qutebrowser/components/misccommands.py
+++ b/qutebrowser/components/misccommands.py
@@ -34,8 +34,8 @@ try:
except ImportError:
hunter = None
-from PyQt5.QtCore import Qt
-from PyQt5.QtPrintSupport import QPrintPreviewDialog
+from qutebrowser.qt.core import Qt
+from qutebrowser.qt.printsupport import QPrintPreviewDialog
from qutebrowser.api import cmdutils, apitypes, message, config
@@ -81,11 +81,11 @@ def _print_preview(tab: apitypes.Tab) -> None:
tab.printing.check_preview_support()
diag = QPrintPreviewDialog(tab)
- diag.setAttribute(Qt.WA_DeleteOnClose)
+ diag.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
diag.setWindowFlags(
diag.windowFlags() |
- Qt.WindowMaximizeButtonHint |
- Qt.WindowMinimizeButtonHint)
+ Qt.WindowType.WindowMaximizeButtonHint |
+ Qt.WindowType.WindowMinimizeButtonHint)
diag.paintRequested.connect(functools.partial(
tab.printing.to_printer, callback=print_callback))
diag.exec()
@@ -324,7 +324,7 @@ def debug_webaction(tab: apitypes.Tab, action: str, count: int = 1) -> None:
Available actions:
https://doc.qt.io/archives/qt-5.5/qwebpage.html#WebAction-enum (WebKit)
- https://doc.qt.io/qt-5/qwebenginepage.html#WebAction-enum (WebEngine)
+ https://doc.qt.io/qt-6/qwebenginepage.html#WebAction-enum (WebEngine)
Args:
action: The action to execute, e.g. MoveToNextChar.
@@ -365,7 +365,7 @@ def message_error(text: str, rich: bool = False) -> None:
Args:
text: The text to show.
rich: Render the given text as
- https://doc.qt.io/qt-5/richtext-html-subset.html[Qt Rich Text].
+ https://doc.qt.io/qt-6/richtext-html-subset.html[Qt Rich Text].
"""
message.error(text, rich=rich)
@@ -379,7 +379,7 @@ def message_info(text: str, count: int = 1, rich: bool = False) -> None:
text: The text to show.
count: How many times to show the message.
rich: Render the given text as
- https://doc.qt.io/qt-5/richtext-html-subset.html[Qt Rich Text].
+ https://doc.qt.io/qt-6/richtext-html-subset.html[Qt Rich Text].
"""
for _ in range(count):
message.info(text, rich=rich)
@@ -392,7 +392,7 @@ def message_warning(text: str, rich: bool = False) -> None:
Args:
text: The text to show.
rich: Render the given text as
- https://doc.qt.io/qt-5/richtext-html-subset.html[Qt Rich Text].
+ https://doc.qt.io/qt-6/richtext-html-subset.html[Qt Rich Text].
"""
message.warning(text, rich=rich)
diff --git a/qutebrowser/components/readlinecommands.py b/qutebrowser/components/readlinecommands.py
index 37fa92127..f6ee31e84 100644
--- a/qutebrowser/components/readlinecommands.py
+++ b/qutebrowser/components/readlinecommands.py
@@ -22,7 +22,7 @@
import os
from typing import Iterable, Optional, MutableMapping, Any, Callable
-from PyQt5.QtWidgets import QApplication, QLineEdit
+from qutebrowser.qt.widgets import QApplication, QLineEdit
from qutebrowser.api import cmdutils
diff --git a/qutebrowser/components/utils/blockutils.py b/qutebrowser/components/utils/blockutils.py
index 98681a488..828a87952 100644
--- a/qutebrowser/components/utils/blockutils.py
+++ b/qutebrowser/components/utils/blockutils.py
@@ -24,7 +24,7 @@ import os
import functools
from typing import IO, List, Optional
-from PyQt5.QtCore import QUrl, QObject, pyqtSignal
+from qutebrowser.qt.core import QUrl, QObject, pyqtSignal
from qutebrowser.api import downloads, message, config
diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py
index 38c90f3da..cdb360ef1 100644
--- a/qutebrowser/config/config.py
+++ b/qutebrowser/config/config.py
@@ -25,7 +25,7 @@ import functools
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Mapping,
MutableMapping, MutableSequence, Optional, Tuple, cast)
-from PyQt5.QtCore import pyqtSignal, QObject, QUrl
+from qutebrowser.qt.core import pyqtSignal, QObject, QUrl
from qutebrowser.commands import cmdexc, parser
from qutebrowser.config import configdata, configexc, configutils
@@ -560,15 +560,18 @@ class Config(QObject):
log.config.debug("{} was mutated, updating".format(name))
self.set_obj(name, new_value, save_yaml=save_yaml)
- def dump_userconfig(self) -> str:
+ def dump_userconfig(self, *, include_hidden: bool = False) -> str:
"""Get the part of the config which was changed by the user.
+ Args:
+ include_hidden: Include default scoped configs.
+
Return:
The changed config part as string.
"""
lines: List[str] = []
for values in sorted(self, key=lambda v: v.opt.name):
- lines += values.dump()
+ lines += values.dump(include_hidden=include_hidden)
if not lines:
return '<Default configuration>'
diff --git a/qutebrowser/config/configcommands.py b/qutebrowser/config/configcommands.py
index b85031818..4b6c8bb6f 100644
--- a/qutebrowser/config/configcommands.py
+++ b/qutebrowser/config/configcommands.py
@@ -23,7 +23,7 @@ import os.path
import contextlib
from typing import TYPE_CHECKING, Iterator, List, Optional, Any, Tuple
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl, QUrlQuery
from qutebrowser.api import cmdutils
from qutebrowser.completion.models import configmodel
@@ -281,9 +281,18 @@ class ConfigCommands:
@cmdutils.register(instance='config-commands')
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
- def config_diff(self, win_id: int) -> None:
- """Show all customized options."""
+ def config_diff(self, win_id: int, include_hidden: bool = False) -> None:
+ """Show all customized options.
+
+ Args:
+ include_hidden: Also include internal qutebrowser settings.
+ """
url = QUrl('qute://configdiff')
+ if include_hidden:
+ query = QUrlQuery()
+ query.addQueryItem("include_hidden", "true")
+ url.setQuery(query)
+
tabbed_browser = objreg.get('tabbed-browser',
scope='window', window=win_id)
tabbed_browser.load_url(url, newtab=False)
diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py
index ec4efc375..6306437ec 100644
--- a/qutebrowser/config/configdata.py
+++ b/qutebrowser/config/configdata.py
@@ -155,12 +155,13 @@ def _parse_yaml_backends_dict(
# The value associated to the key, and whether we should add that backend
# or not.
+
conditionals = {
True: True,
False: False,
- 'Qt 5.13': qtutils.version_check('5.13'),
- 'Qt 5.14': qtutils.version_check('5.14'),
'Qt 5.15': qtutils.version_check('5.15'),
+ 'Qt 6.2': qtutils.version_check('6.2'),
+ 'Qt 6.3': qtutils.version_check('6.3'),
}
for key in sorted(node.keys()):
if conditionals[node[key]]:
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index d8e1ef16a..a7a8cf005 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -65,9 +65,6 @@ search.incremental:
search.wrap:
type: Bool
default: true
- backend:
- QtWebEngine: Qt 5.14
- QtWebKit: true
desc: >-
Wrap around at the top and bottom of the page when advancing through text
matches using `:search-next` and `:search-prev`.
@@ -275,7 +272,7 @@ qt.chromium.process_model:
See the following pages for more details:
- https://www.chromium.org/developers/design-documents/process-models
- - https://doc.qt.io/qt-5/qtwebengine-features.html#process-models
+ - https://doc.qt.io/qt-6/qtwebengine-features.html#process-models
qt.low_end_device_mode:
renamed: qt.chromium.low_end_device_mode
@@ -337,8 +334,8 @@ qt.highdpi:
desc: >-
Turn on Qt HighDPI scaling.
- This is equivalent to setting QT_AUTO_SCREEN_SCALE_FACTOR=1 or
- QT_ENABLE_HIGHDPI_SCALING=1 (Qt >= 5.14) in the environment.
+ This is equivalent to setting QT_ENABLE_HIGHDPI_SCALING=1 (Qt >= 5.14) in
+ the environment.
It's off by default as it can cause issues with some bitmap fonts.
As an alternative to this, it's possible to set font sizes and the
@@ -577,9 +574,7 @@ content.frame_flattening:
content.prefers_reduced_motion:
default: false
type: Bool
- backend:
- QtWebEngine: Qt 5.14
- QtWebKit: false
+ backend: QtWebEngine
restart: true
desc: >-
Request websites to minimize non-essentials animations and motion.
@@ -611,8 +606,6 @@ content.site_specific_quirks.skip:
- js-whatsapp-web
- js-discord
- js-string-replaceall
- - js-globalthis
- - js-object-fromentries
- js-array-at
- misc-krunker
- misc-mathml-darkmode
@@ -685,7 +678,8 @@ content.headers.referer:
type:
name: String
valid_values:
- - always: "Always send the Referer."
+ - always: "Always send the Referer. With QtWebEngine 6.2+, this value is
+ unavailable and will act like `same-domain`."
- never: "Never send the Referer. This is not recommended, as some sites
may break."
- same-domain: "Only send the Referer for the same domain. This will
@@ -1059,9 +1053,6 @@ content.notifications.enabled:
default: ask
type: BoolAsk
supports_pattern: true
- backend:
- QtWebEngine: Qt 5.13
- QtWebKit: true
desc: Allow websites to show notifications.
content.notifications.presenter:
@@ -1073,7 +1064,6 @@ content.notifications.presenter:
without showing error messages.
- qt: Use Qt's native notification presenter, based on a system tray icon.
Switching from or to this value requires a restart of qutebrowser.
- Recommended over `systray` on PyQt 5.14.
- libnotify: Shows messages via DBus in a libnotify-compatible way. If DBus isn't
available, falls back to `systray` or `messages`, but shows an error
message.
@@ -1085,16 +1075,12 @@ content.notifications.presenter:
aren't available.
- herbe: (experimental!) Show notifications using herbe (github.com/dudik/herbe).
Most notification features aren't available.
- backend:
- QtWebEngine: Qt 5.14
- QtWebKit: false
+ backend: QtWebEngine
desc: >-
What notification presenter to use for web notifications.
Note that not all implementations support all features of notifications:
- - With PyQt 5.14, any setting other than `qt` does not support the `click` and
- `close` events, as well as the `tag` option to replace existing notifications.
- The `qt` and `systray` options only support showing one notification at the time
and ignore the `tag` option to replace existing notifications.
- The `herbe` option only supports showing one notification at the time and doesn't
@@ -1106,9 +1092,7 @@ content.notifications.show_origin:
default: true
type: Bool
supports_pattern: true
- backend:
- QtWebEngine: Qt 5.14
- QtWebKit: false
+ backend: QtWebEngine
desc: >-
Whether to show the origin URL for notifications.
@@ -1901,9 +1885,7 @@ input.spatial_navigation:
input.media_keys:
default: true
type: Bool
- backend:
- QtWebEngine: Qt 5.14
- QtWebKit: false
+ backend: QtWebEngine
restart: true
desc: >-
Whether the underlying Chromium should handle media keys.
@@ -3197,9 +3179,7 @@ colors.webpage.preferred_color_scheme:
The "auto" value is broken on QtWebEngine 5.15.2 due to a Qt bug. There, it will
fall back to "light" unconditionally.
- backend:
- QtWebEngine: Qt 5.14
- QtWebKit: false
+ backend: QtWebEngine
restart: true
## dark mode
@@ -3225,6 +3205,9 @@ colors.webpage.darkmode.enabled:
- "With selective inversion of everything": Combines the two variants
above.
+
+ - "With increased text contrast": Set
+ `colors.webpage.darkmode.increase_text_contrast` (QtWebEngine 6.3+)
restart: true
backend: QtWebEngine
@@ -3296,9 +3279,7 @@ colors.webpage.darkmode.policy.page:
The underlying Chromium setting has been removed in QtWebEngine 5.15.3, thus this
setting is ignored there. Instead, every element is now classified individually.
restart: true
- backend:
- QtWebEngine: Qt 5.14
- QtWebKit: false
+ backend: QtWebEngine
colors.webpage.darkmode.threshold.text:
default: 256
@@ -3313,9 +3294,7 @@ colors.webpage.darkmode.threshold.text:
above it will be left as in the original, non-dark-mode page. Set to 256
to always invert text color or to 0 to never invert text color.
restart: true
- backend:
- QtWebEngine: Qt 5.14
- QtWebKit: false
+ backend: QtWebEngine
colors.webpage.darkmode.threshold.background:
default: 0
@@ -3333,9 +3312,7 @@ colors.webpage.darkmode.threshold.background:
Note: This behavior is the opposite of
`colors.webpage.darkmode.threshold.text`!
restart: true
- backend:
- QtWebEngine: Qt 5.14
- QtWebKit: false
+ backend: QtWebEngine
colors.webpage.darkmode.grayscale.all:
default: false
@@ -3360,8 +3337,16 @@ colors.webpage.darkmode.grayscale.images:
If set to 0, images are left as-is. If set to 1, images are completely
grayscale. Values between 0 and 1 desaturate the colors accordingly.
restart: true
+ backend: QtWebEngine
+
+colors.webpage.darkmode.increase_text_contrast:
+ default: false
+ type: Bool
+ desc: >-
+ Increase text contrast by drawing an outline of the uninverted color.
+ restart: true
backend:
- QtWebEngine: Qt 5.14
+ QtWebEngine: Qt 6.3
QtWebKit: false
# emacs: '
diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py
index 412f88e54..d88e3e91d 100644
--- a/qutebrowser/config/configfiles.py
+++ b/qutebrowser/config/configfiles.py
@@ -33,7 +33,7 @@ from typing import (TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, Mapping,
MutableMapping, Optional, Tuple, cast)
import yaml
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QSettings, qVersion
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QObject, QSettings, qVersion
import qutebrowser
from qutebrowser.config import (configexc, config, configdata, configutils,
@@ -91,6 +91,7 @@ class StateConfig(configparser.ConfigParser):
self.qt_version_changed = False
self.qtwe_version_changed = False
self.qutebrowser_version_changed = VersionChange.unknown
+ self.chromium_version_changed = VersionChange.unknown
self._set_changed_attributes()
for sect in ['general', 'geometry', 'inspector']:
@@ -103,6 +104,7 @@ class StateConfig(configparser.ConfigParser):
('general', 'fooled'),
('general', 'backend-warning-shown'),
('general', 'old-qt-warning-shown'),
+ ('general', 'serviceworker_workaround'),
('geometry', 'inspector'),
]
for sect, key in deleted_keys:
@@ -110,18 +112,40 @@ class StateConfig(configparser.ConfigParser):
self['general']['qt_version'] = qVersion()
self['general']['qtwe_version'] = self._qtwe_version_str()
+ self['general']['chromium_version'] = self._chromium_version_str()
self['general']['version'] = qutebrowser.__version__
- def _qtwe_version_str(self) -> str:
- """Get the QtWebEngine version string.
+ def _has_webengine(self) -> bool:
+ """Check if QtWebEngine is available.
Note that it's too early to use objects.backend here...
"""
try:
- import PyQt5.QtWebEngineWidgets # pylint: disable=unused-import
+ # pylint: disable=unused-import,redefined-outer-name
+ import qutebrowser.qt.webenginewidgets
except ImportError:
+ return False
+ return True
+
+ def _qtwe_versions(self) -> Optional[version.WebEngineVersions]:
+ """Get the QtWebEngine versions."""
+ if not self._has_webengine():
+ return None
+ return version.qtwebengine_versions(avoid_init=True)
+
+ def _qtwe_version_str(self) -> str:
+ """Get the QtWebEngine version string."""
+ versions = self._qtwe_versions()
+ if versions is None:
+ return 'no'
+ return str(versions.webengine)
+
+ def _chromium_version_str(self) -> str:
+ """Get the Chromium major version string."""
+ versions = self._qtwe_versions()
+ if versions is None:
return 'no'
- return str(version.qtwebengine_versions(avoid_init=True).webengine)
+ return str(versions.chromium_major)
def _set_changed_attributes(self) -> None:
"""Set qt_version_changed/qutebrowser_version_changed attributes.
@@ -139,6 +163,11 @@ class StateConfig(configparser.ConfigParser):
old_qtwe_version = self['general'].get('qtwe_version', None)
self.qtwe_version_changed = old_qtwe_version != self._qtwe_version_str()
+ self._set_qutebrowser_changed_attribute()
+ self._set_chromium_changed_attribute()
+
+ def _set_qutebrowser_changed_attribute(self) -> None:
+ """Detect a qutebrowser version change."""
old_qutebrowser_version = self['general'].get('version', None)
if old_qutebrowser_version is None:
return
@@ -162,6 +191,46 @@ class StateConfig(configparser.ConfigParser):
else:
self.qutebrowser_version_changed = VersionChange.major
+ def _set_chromium_changed_attribute(self) -> None:
+ if not self._has_webengine():
+ return
+
+ old_chromium_version_str = self['general'].get('chromium_version', None)
+ if old_chromium_version_str in ['no', None]:
+ old_qtwe_version = self['general'].get('qtwe_version', None)
+ if old_qtwe_version in ['no', None]:
+ return
+
+ try:
+ old_chromium_version = version.WebEngineVersions.from_webengine(
+ old_qtwe_version, source='config').chromium_major
+ except ValueError:
+ log.init.warning(
+ f"Unable to parse old QtWebEngine version {old_qtwe_version}")
+ return
+ else:
+ try:
+ old_chromium_version = int(old_chromium_version_str)
+ except ValueError:
+ log.init.warning(
+ f"Unable to parse old Chromium version {old_chromium_version_str}")
+ return
+
+ new_versions = version.qtwebengine_versions(avoid_init=True)
+ new_chromium_version = new_versions.chromium_major
+
+ if old_chromium_version is None or new_chromium_version is None:
+ return
+
+ if old_chromium_version <= 87 and new_chromium_version >= 90: # Qt 5 -> Qt 6
+ self.chromium_version_changed = VersionChange.major
+ elif old_chromium_version > new_chromium_version:
+ self.chromium_version_changed = VersionChange.downgrade
+ elif old_chromium_version == new_chromium_version:
+ self.chromium_version_changed = VersionChange.equal
+ else:
+ self.chromium_version_changed = VersionChange.minor
+
def init_save_manager(self,
save_manager: 'savemanager.SaveManager') -> None:
"""Make sure the config gets saved properly.
@@ -989,5 +1058,5 @@ def init() -> None:
# https://github.com/qutebrowser/qutebrowser/issues/515
path = os.path.join(standarddir.config(auto=True), 'qsettings')
- for fmt in [QSettings.NativeFormat, QSettings.IniFormat]:
- QSettings.setPath(fmt, QSettings.UserScope, path)
+ for fmt in [QSettings.Format.NativeFormat, QSettings.Format.IniFormat]:
+ QSettings.setPath(fmt, QSettings.Scope.UserScope, path)
diff --git a/qutebrowser/config/configinit.py b/qutebrowser/config/configinit.py
index 15e587ea2..03453dded 100644
--- a/qutebrowser/config/configinit.py
+++ b/qutebrowser/config/configinit.py
@@ -23,7 +23,7 @@ import argparse
import os.path
import sys
-from PyQt5.QtWidgets import QMessageBox
+from qutebrowser.qt.widgets import QMessageBox
from qutebrowser.api import config as configapi
from qutebrowser.config import (config, configdata, configfiles, configtypes,
@@ -135,7 +135,7 @@ def late_init(save_manager: savemanager.SaveManager) -> None:
errbox = msgbox.msgbox(parent=None,
title="Error while reading config",
text=_init_errors.to_html(),
- icon=QMessageBox.Warning,
+ icon=QMessageBox.Icon.Warning,
plain_text=False)
errbox.exec()
diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py
index 12a21aaeb..2b2b572ab 100644
--- a/qutebrowser/config/configtypes.py
+++ b/qutebrowser/config/configtypes.py
@@ -55,10 +55,10 @@ from typing import (Any, Callable, Dict as DictType, Iterable, Iterator,
List as ListType, Optional, Pattern, Sequence, Tuple, Union)
import yaml
-from PyQt5.QtCore import QUrl, Qt
-from PyQt5.QtGui import QColor
-from PyQt5.QtWidgets import QTabWidget, QTabBar
-from PyQt5.QtNetwork import QNetworkProxy
+from qutebrowser.qt.core import QUrl, Qt
+from qutebrowser.qt.gui import QColor
+from qutebrowser.qt.widgets import QTabWidget, QTabBar
+from qutebrowser.qt.network import QNetworkProxy
from qutebrowser.misc import objects, debugcachestats
from qutebrowser.config import configexc, configutils
@@ -1062,9 +1062,9 @@ class ColorSystem(MappingType):
"""The color system to use for color interpolation."""
MAPPING = {
- 'rgb': (QColor.Rgb, "Interpolate in the RGB color system."),
- 'hsv': (QColor.Hsv, "Interpolate in the HSV color system."),
- 'hsl': (QColor.Hsl, "Interpolate in the HSL color system."),
+ 'rgb': (QColor.Spec.Rgb, "Interpolate in the RGB color system."),
+ 'hsv': (QColor.Spec.Hsv, "Interpolate in the HSV color system."),
+ 'hsl': (QColor.Spec.Hsl, "Interpolate in the HSL color system."),
'none': (None, "Don't show a gradient."),
}
@@ -1167,7 +1167,7 @@ class QssColor(BaseType):
* `rgb(r, g, b)` / `rgba(r, g, b, a)` (values 0-255 or percentages)
* `hsv(h, s, v)` / `hsva(h, s, v, a)` (values 0-255, hue 0-359)
* A gradient as explained in
- https://doc.qt.io/qt-5/stylesheet-reference.html#list-of-property-types[the Qt documentation]
+ https://doc.qt.io/qt-6/stylesheet-reference.html#list-of-property-types[the Qt documentation]
under ``Gradient''
"""
@@ -1798,10 +1798,10 @@ class Position(MappingType):
"""The position of the tab bar."""
MAPPING = {
- 'top': (QTabWidget.North, None),
- 'bottom': (QTabWidget.South, None),
- 'left': (QTabWidget.West, None),
- 'right': (QTabWidget.East, None),
+ 'top': (QTabWidget.TabPosition.North, None),
+ 'bottom': (QTabWidget.TabPosition.South, None),
+ 'left': (QTabWidget.TabPosition.West, None),
+ 'right': (QTabWidget.TabPosition.East, None),
}
@@ -1810,9 +1810,9 @@ class TextAlignment(MappingType):
"""Alignment of text."""
MAPPING = {
- 'left': (Qt.AlignLeft, None),
- 'right': (Qt.AlignRight, None),
- 'center': (Qt.AlignCenter, None),
+ 'left': (Qt.AlignmentFlag.AlignLeft, None),
+ 'right': (Qt.AlignmentFlag.AlignRight, None),
+ 'center': (Qt.AlignmentFlag.AlignCenter, None),
}
@@ -1821,10 +1821,10 @@ class ElidePosition(MappingType):
"""Position of ellipsis in truncated text."""
MAPPING = {
- 'left': (Qt.ElideLeft, None),
- 'right': (Qt.ElideRight, None),
- 'middle': (Qt.ElideMiddle, None),
- 'none': (Qt.ElideNone, None),
+ 'left': (Qt.TextElideMode.ElideLeft, None),
+ 'right': (Qt.TextElideMode.ElideRight, None),
+ 'middle': (Qt.TextElideMode.ElideMiddle, None),
+ 'none': (Qt.TextElideMode.ElideNone, None),
}
@@ -1880,17 +1880,17 @@ class SelectOnRemove(MappingType):
MAPPING = {
'prev': (
- QTabBar.SelectLeftTab,
+ QTabBar.SelectionBehavior.SelectLeftTab,
("Select the tab which came before the closed one "
"(left in horizontal, above in vertical)."),
),
'next': (
- QTabBar.SelectRightTab,
+ QTabBar.SelectionBehavior.SelectRightTab,
("Select the tab which came after the closed one "
"(right in horizontal, below in vertical)."),
),
'last-used': (
- QTabBar.SelectPreviousTab,
+ QTabBar.SelectionBehavior.SelectPreviousTab,
"Select the previously selected tab.",
),
}
diff --git a/qutebrowser/config/configutils.py b/qutebrowser/config/configutils.py
index 480bbd85f..c03971077 100644
--- a/qutebrowser/config/configutils.py
+++ b/qutebrowser/config/configutils.py
@@ -28,9 +28,9 @@ from typing import (
TYPE_CHECKING, Any, Dict, Iterator, List, Optional, Sequence, Set, Union,
MutableMapping)
-from PyQt5.QtCore import QUrl
-from PyQt5.QtGui import QFontDatabase
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.gui import QFontDatabase
+from qutebrowser.qt.widgets import QApplication
from qutebrowser.utils import utils, urlmatch, urlutils, usertypes, qtutils
from qutebrowser.config import configexc
@@ -294,7 +294,7 @@ class FontFamilies:
@classmethod
def from_system_default(
cls,
- font_type: QFontDatabase.SystemFont = QFontDatabase.FixedFont,
+ font_type: QFontDatabase.SystemFont = QFontDatabase.SystemFont.FixedFont,
) -> 'FontFamilies':
"""Get a FontFamilies object for the default system font.
@@ -305,25 +305,25 @@ class FontFamilies:
exist:
1) f = QFont()
- f.setStyleHint(QFont.Monospace)
+ f.setStyleHint(QFont.StyleHint.Monospace)
print(f.defaultFamily())
2) f = QFont()
- f.setStyleHint(QFont.TypeWriter)
+ f.setStyleHint(QFont.StyleHint.TypeWriter)
print(f.defaultFamily())
- 3) f = QFontDatabase.systemFont(QFontDatabase.FixedFont)
+ 3) f = QFontDatabase.systemFont(QFontDatabase.SystemFont.FixedFont)
print(f.family())
They yield different results depending on the OS:
- QFont.Monospace | QFont.TypeWriter | QFontDatabase
- ------------------------------------------------------
- Windows: Courier New | Courier New | Courier New
- Linux: DejaVu Sans Mono | DejaVu Sans Mono | monospace
- macOS: Menlo | American Typewriter | Monaco
+ QFont.StyleHint.Monospace | QFont.StyleHint.TypeWriter | QFontDatabase
+ -----------------------------------------------------------------------
+ Win: Courier New | Courier New | Courier New
+ Linux: DejaVu Sans Mono | DejaVu Sans Mono | monospace
+ macOS: Menlo | American Typewriter | Monaco
- Test script: https://p.cmpl.cc/d4dfe573
+ Test script: https://p.cmpl.cc/076835c4
On Linux, it seems like both actually resolve to the same font.
diff --git a/qutebrowser/config/qtargs.py b/qutebrowser/config/qtargs.py
index 9e7f2620d..8b7a85b64 100644
--- a/qutebrowser/config/qtargs.py
+++ b/qutebrowser/config/qtargs.py
@@ -25,7 +25,7 @@ import argparse
import pathlib
from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple
-from PyQt5.QtCore import QLibraryInfo, QLocale
+from qutebrowser.qt.core import QLocale
from qutebrowser.config import config
from qutebrowser.misc import objects
@@ -75,10 +75,15 @@ def qt_args(namespace: argparse.Namespace) -> List[str]:
log.init.debug("QtWebEngine requested, but unavailable...")
return argv
+ versions = version.qtwebengine_versions(avoid_init=True)
+ if versions.webengine >= utils.VersionNumber(6, 4):
+ # https://codereview.qt-project.org/c/qt/qtwebengine/+/376704
+ argv.insert(1, "--webEngineArgs")
+
special_prefixes = (_ENABLE_FEATURES, _DISABLE_FEATURES, _BLINK_SETTINGS)
special_flags = [flag for flag in argv if flag.startswith(special_prefixes)]
argv = [flag for flag in argv if not flag.startswith(special_prefixes)]
- argv += list(_qtwebengine_args(namespace, special_flags))
+ argv += list(_qtwebengine_args(versions, namespace, special_flags))
return argv
@@ -93,6 +98,8 @@ def _qtwebengine_features(
versions: The WebEngineVersions to get flags for.
special_flags: Existing flags passed via the commandline.
"""
+ assert versions.chromium_major is not None
+
enabled_features = []
disabled_features = []
@@ -108,7 +115,7 @@ def _qtwebengine_features(
else:
raise utils.Unreachable(flag)
- if versions.webengine >= utils.VersionNumber(5, 15, 1) and utils.is_linux:
+ if utils.is_linux:
# Enable WebRTC PipeWire for screen capturing on Wayland.
#
# This is disabled in Chromium by default because of the "dialog hell":
@@ -118,7 +125,7 @@ def _qtwebengine_features(
# However, we don't have Chromium's confirmation dialog in qutebrowser,
# so we should only get qutebrowser's permission dialog.
#
- # In theory this would be supported with Qt 5.13 already, but
+ # In theory this would be supported with Qt 5.15.0 already, but
# QtWebEngine only started picking up PipeWire correctly with Qt
# 5.15.1.
#
@@ -143,8 +150,8 @@ def _qtwebengine_features(
if config.val.scrolling.bar == 'overlay':
enabled_features.append('OverlayScrollbar')
- if (versions.webengine >= utils.VersionNumber(5, 14) and
- config.val.content.headers.referer == 'same-domain'):
+ if (config.val.content.headers.referer == 'same-domain' and
+ versions.chromium_major < 89):
# Handling of reduced-referrer-granularity in Chromium 76+
# https://chromium-review.googlesource.com/c/chromium/src/+/1572699
#
@@ -199,7 +206,7 @@ def _webengine_locales_path() -> pathlib.Path:
# not QtWebEngine.
base = pathlib.Path('/app/translations')
else:
- base = pathlib.Path(QLibraryInfo.location(QLibraryInfo.TranslationsPath))
+ base = qtutils.library_path(qtutils.LibraryPath.translations)
return base / 'qtwebengine_locales'
@@ -210,7 +217,7 @@ def _get_lang_override(
"""Get a --lang switch to override Qt's locale handling.
This is needed as a WORKAROUND for https://bugreports.qt.io/browse/QTBUG-91715
- There is no fix yet, but we assume it'll be fixed with QtWebEngine 5.15.4.
+ Fixed with QtWebEngine 5.15.4.
"""
if not config.val.qt.workarounds.locale:
return None
@@ -239,29 +246,15 @@ def _get_lang_override(
def _qtwebengine_args(
+ versions: version.WebEngineVersions,
namespace: argparse.Namespace,
special_flags: Sequence[str],
) -> Iterator[str]:
"""Get the QtWebEngine arguments to use based on the config."""
- versions = version.qtwebengine_versions(avoid_init=True)
-
- qt_514_ver = utils.VersionNumber(5, 14)
- qt_515_ver = utils.VersionNumber(5, 15)
- if qt_514_ver <= versions.webengine < qt_515_ver:
- # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-82105
- yield '--disable-shared-workers'
-
- # WORKAROUND equivalent to
# https://codereview.qt-project.org/c/qt/qtwebengine/+/256786
- # also see:
# https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/265753
- if versions.webengine >= utils.VersionNumber(5, 12, 3):
- if 'stack' in namespace.debug_flags:
- # Only actually available in Qt 5.12.5, but let's save another
- # check, as passing the option won't hurt.
- yield '--enable-in-process-stack-traces'
- elif 'stack' not in namespace.debug_flags:
- yield '--disable-in-process-stack-traces'
+ if 'stack' in namespace.debug_flags:
+ yield '--enable-in-process-stack-traces'
lang_override = _get_lang_override(
webengine_version=versions.webengine,
@@ -294,83 +287,56 @@ def _qtwebengine_args(
if disabled_features:
yield _DISABLE_FEATURES + ','.join(disabled_features)
- yield from _qtwebengine_settings_args(versions)
-
-
-def _qtwebengine_settings_args(versions: version.WebEngineVersions) -> Iterator[str]:
- settings: Dict[str, Dict[Any, Optional[str]]] = {
- 'qt.force_software_rendering': {
- 'software-opengl': None,
- 'qt-quick': None,
- 'chromium': '--disable-gpu',
- 'none': None,
- },
- 'content.canvas_reading': {
- True: None,
- False: '--disable-reading-from-canvas',
- },
- 'content.webrtc_ip_handling_policy': {
- 'all-interfaces': None,
- 'default-public-and-private-interfaces':
- '--force-webrtc-ip-handling-policy='
- 'default_public_and_private_interfaces',
- 'default-public-interface-only':
- '--force-webrtc-ip-handling-policy='
- 'default_public_interface_only',
- 'disable-non-proxied-udp':
- '--force-webrtc-ip-handling-policy='
- 'disable_non_proxied_udp',
- },
- 'qt.chromium.process_model': {
- 'process-per-site-instance': None,
- 'process-per-site': '--process-per-site',
- 'single-process': '--single-process',
- },
- 'qt.chromium.low_end_device_mode': {
- 'auto': None,
- 'always': '--enable-low-end-device-mode',
- 'never': '--disable-low-end-device-mode',
- },
- 'content.headers.referer': {
- 'always': None,
- },
- 'content.prefers_reduced_motion': {
- True: '--force-prefers-reduced-motion',
- False: None,
- },
- 'qt.chromium.sandboxing': {
- 'enable-all': None,
- 'disable-seccomp-bpf': '--disable-seccomp-filter-sandbox',
- 'disable-all': '--no-sandbox',
- }
+ yield from _qtwebengine_settings_args()
+
+
+_WEBENGINE_SETTINGS: Dict[str, Dict[Any, Optional[str]]] = {
+ 'qt.force_software_rendering': {
+ 'software-opengl': None,
+ 'qt-quick': None,
+ 'chromium': '--disable-gpu',
+ 'none': None,
+ },
+ 'content.canvas_reading': {
+ True: None,
+ False: '--disable-reading-from-canvas',
+ },
+ 'content.webrtc_ip_handling_policy': {
+ 'all-interfaces': None,
+ 'default-public-and-private-interfaces':
+ '--force-webrtc-ip-handling-policy='
+ 'default_public_and_private_interfaces',
+ 'default-public-interface-only':
+ '--force-webrtc-ip-handling-policy='
+ 'default_public_interface_only',
+ 'disable-non-proxied-udp':
+ '--force-webrtc-ip-handling-policy='
+ 'disable_non_proxied_udp',
+ },
+ 'qt.chromium.process_model': {
+ 'process-per-site-instance': None,
+ 'process-per-site': '--process-per-site',
+ 'single-process': '--single-process',
+ },
+ 'qt.chromium.low_end_device_mode': {
+ 'auto': None,
+ 'always': '--enable-low-end-device-mode',
+ 'never': '--disable-low-end-device-mode',
+ },
+ 'content.prefers_reduced_motion': {
+ True: '--force-prefers-reduced-motion',
+ False: None,
+ },
+ 'qt.chromium.sandboxing': {
+ 'enable-all': None,
+ 'disable-seccomp-bpf': '--disable-seccomp-filter-sandbox',
+ 'disable-all': '--no-sandbox',
}
- qt_514_ver = utils.VersionNumber(5, 14)
-
- if qt_514_ver <= versions.webengine < utils.VersionNumber(5, 15, 2):
- # 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 in browser/webengine/darkmode.py instead.
- settings['colors.webpage.preferred_color_scheme'] = {
- 'dark': '--force-dark-mode',
- 'light': None,
- 'auto': None,
- }
-
- referrer_setting = settings['content.headers.referer']
- if versions.webengine >= qt_514_ver:
- # Starting with Qt 5.14, this is handled via --enable-features
- referrer_setting['same-domain'] = None
- else:
- referrer_setting['same-domain'] = '--reduced-referrer-granularity'
+}
- # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-60203
- can_override_referer = (
- versions.webengine >= utils.VersionNumber(5, 12, 4) and
- versions.webengine != utils.VersionNumber(5, 13)
- )
- referrer_setting['never'] = None if can_override_referer else '--no-referrers'
- for setting, args in sorted(settings.items()):
+def _qtwebengine_settings_args() -> Iterator[str]:
+ for setting, args in sorted(_WEBENGINE_SETTINGS.items()):
arg = args[config.instance.get(setting)]
if arg is not None:
yield arg
@@ -411,10 +377,7 @@ def init_envvars() -> None:
os.environ['QT_WAYLAND_DISABLE_WINDOWDECORATION'] = '1'
if config.val.qt.highdpi:
- env_var = ('QT_ENABLE_HIGHDPI_SCALING'
- if qtutils.version_check('5.14', compiled=False)
- else 'QT_AUTO_SCREEN_SCALE_FACTOR')
- os.environ[env_var] = '1'
+ os.environ['QT_ENABLE_HIGHDPI_SCALING'] = '1'
for var, val in config.val.qt.environ.items():
if val is None and var in os.environ:
diff --git a/qutebrowser/config/stylesheet.py b/qutebrowser/config/stylesheet.py
index b08d67a3b..8ad873ab5 100644
--- a/qutebrowser/config/stylesheet.py
+++ b/qutebrowser/config/stylesheet.py
@@ -22,8 +22,8 @@
import functools
from typing import Optional, FrozenSet
-from PyQt5.QtCore import pyqtSlot, QObject
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt.core import pyqtSlot, QObject
+from qutebrowser.qt.widgets import QWidget
from qutebrowser.config import config
from qutebrowser.misc import debugcachestats
diff --git a/qutebrowser/config/websettings.py b/qutebrowser/config/websettings.py
index 7a55c5c97..7f59367cb 100644
--- a/qutebrowser/config/websettings.py
+++ b/qutebrowser/config/websettings.py
@@ -25,8 +25,8 @@ import functools
import dataclasses
from typing import Any, Callable, Dict, Optional, Union
-from PyQt5.QtCore import QUrl, pyqtSlot, qVersion
-from PyQt5.QtGui import QFont
+from qutebrowser.qt.core import QUrl, pyqtSlot, qVersion
+from qutebrowser.qt.gui import QFont
import qutebrowser
from qutebrowser.config import config
diff --git a/qutebrowser/extensions/interceptors.py b/qutebrowser/extensions/interceptors.py
index dfafeb7e3..2a9cfb647 100644
--- a/qutebrowser/extensions/interceptors.py
+++ b/qutebrowser/extensions/interceptors.py
@@ -23,14 +23,14 @@ import enum
import dataclasses
from typing import Callable, List, Optional
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
class ResourceType(enum.Enum):
"""Possible request types that can be received.
Currently corresponds to the QWebEngineUrlRequestInfo Enum:
- https://doc.qt.io/qt-5/qwebengineurlrequestinfo.html#ResourceType-enum
+ https://doc.qt.io/qt-6/qwebengineurlrequestinfo.html#ResourceType-enum
"""
main_frame = 0
@@ -54,6 +54,7 @@ class ResourceType(enum.Enum):
# 18 is "preload", deprecated in Chromium
preload_main_frame = 19
preload_sub_frame = 20
+ websocket = 254
unknown = 255
diff --git a/qutebrowser/extensions/loader.py b/qutebrowser/extensions/loader.py
index 793f131c8..073acd44c 100644
--- a/qutebrowser/extensions/loader.py
+++ b/qutebrowser/extensions/loader.py
@@ -27,7 +27,7 @@ import argparse
import dataclasses
from typing import Callable, Iterator, List, Optional, Tuple
-from PyQt5.QtCore import pyqtSlot
+from qutebrowser.qt.core import pyqtSlot
from qutebrowser import components
from qutebrowser.config import config
diff --git a/qutebrowser/html/warning-sandboxing.html b/qutebrowser/html/warning-sandboxing.html
new file mode 100644
index 000000000..186d938e7
--- /dev/null
+++ b/qutebrowser/html/warning-sandboxing.html
@@ -0,0 +1,16 @@
+{% extends "styled.html" %}
+
+{% block content %}
+<h1>{{ title }}</h1>
+<span class="note">Note this warning will only appear once. Use <span class="mono">:open
+qute://warning/sandboxing</span> to show it again at a later time.</span>
+
+<p>
+ Due to a <a href="https://github.com/pyinstaller/pyinstaller/pull/6903">PyInstaller issue</a>,
+ Chromium's <a href="https://chromium.googlesource.com/chromium/src/+/HEAD/docs/design/sandbox_faq.md">sandboxing</a>
+ is currently disabled for macOS builds with Qt 6. This means that there will be no additional layer of protection
+ in case of Chromium security bugs. Thus, it's advised to
+ <b>not use this build in production</b>. Hopefully, this situation will be
+ resolved before the final 3.0.0 release.
+</p>
+{% endblock %}
diff --git a/qutebrowser/html/warning-sessions.html b/qutebrowser/html/warning-sessions.html
index 422b409a9..9c5d459cb 100644
--- a/qutebrowser/html/warning-sessions.html
+++ b/qutebrowser/html/warning-sessions.html
@@ -5,7 +5,7 @@
<span class="note">Note this warning will only appear once. Use <span class="mono">:open
qute://warning/sessions</span> to show it again at a later time.</span>
-<p>You're using qutebrowser with Qt 5.15. While this is the recommended Qt version to use (due to QtWebEngine security updates), qutebrowser only provides partial support for session files.</p>
+<p>You're using qutebrowser with Qt >= 5.15. While this is the recommended Qt version to use (due to QtWebEngine security updates), qutebrowser only provides partial support for session files.</p>
<p>Since Qt doesn't provide an API to load the history of a tab, qutebrowser relies on a reverse-engineered binary serialization format to load tab history from session files. With Qt 5.15, unfortunately that format changed (due to the underlying Chromium upgrade), in a way which makes it impossible for qutebrowser to load tab history from existing session data.</p>
diff --git a/qutebrowser/html/warning-webkit.html b/qutebrowser/html/warning-webkit.html
index f5cf9bf01..e9612ce37 100644
--- a/qutebrowser/html/warning-webkit.html
+++ b/qutebrowser/html/warning-webkit.html
@@ -37,8 +37,7 @@ class="mono">content.cookies.accept</span> setting works on QtWebEngine.</p>
class="mono">qt.force_software_rendering</span> setting added in v1.4.0 should
hopefully help.</p>
-<p><b>Missing support for notifications</b>: With qutebrowser v1.7.0, initial
-notification support was added for Qt 5.13.0.</p>
+<p><b>Missing support for notifications</b>: Supported since qutebrowser v1.7.0.</p>
<p><b>Resource usage</b>: qutebrowser v1.5.0 added the <span
class="mono">qt.chromium.process_model</span> and <span
@@ -51,9 +50,8 @@ any other unsolicited connections at all). Arguably, having to trust Google
also is a smaller issue than having to trust every website you visit because of
heaps of security issues...</p>
-<p><b>Nouveau graphic driver</b>: You can use QtWebEngine with software
-rendering. With Qt 5.13 (~May 2019) it might be possible to run with Nouveau
-without software rendering.</p>
+<p><b>Nouveau graphic driver</b>: Should be handled properly in current versions
+of QtWebEngine.</p>
<p><b>Wayland</b>: It's possible to use QtWebEngine with XWayland. With Qt
5.11.2 or newer, qutebrowser also runs natively with Wayland.</p>
diff --git a/qutebrowser/javascript/quirks/globalthis.user.js b/qutebrowser/javascript/quirks/globalthis.user.js
deleted file mode 100644
index b87a956e5..000000000
--- a/qutebrowser/javascript/quirks/globalthis.user.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// ==UserScript==
-// @include https://www.reddit.com/*
-// @include https://open.spotify.com/*
-// @include https://*.stackexchange.com/*
-// @include https://stackoverflow.com/*
-// @include https://test.qutebrowser.org/*
-// ==/UserScript==
-
-// Polyfill for a failing globalThis with older Qt versions.
-
-"use strict";
-window.globalThis = window;
diff --git a/qutebrowser/javascript/quirks/object_fromentries.user.js b/qutebrowser/javascript/quirks/object_fromentries.user.js
deleted file mode 100644
index 6f6ad8b31..000000000
--- a/qutebrowser/javascript/quirks/object_fromentries.user.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Based on: https://gitlab.com/moongoal/js-polyfill-object.fromentries/-/tree/master
-
-/*
- Copyright 2018 Alfredo Mungo <alfredo.mungo@protonmail.ch>
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- IN THE SOFTWARE.
-*/
-
-"use strict";
-
-if (!Object.fromEntries) {
- Object.defineProperty(Object, "fromEntries", {
- value(entries) {
- if (!entries || !entries[Symbol.iterator]) {
- throw new Error(
- "Object.fromEntries() requires a single iterable argument");
- }
-
- const obj = {};
-
- Object.keys(entries).forEach((key) => {
- const [k, v] = entries[key];
- obj[k] = v;
- });
-
- return obj;
- },
- });
-}
-
diff --git a/qutebrowser/keyinput/basekeyparser.py b/qutebrowser/keyinput/basekeyparser.py
index 4db1d5d76..cdb3948b4 100644
--- a/qutebrowser/keyinput/basekeyparser.py
+++ b/qutebrowser/keyinput/basekeyparser.py
@@ -24,11 +24,11 @@ import types
import dataclasses
from typing import Mapping, MutableMapping, Optional, Sequence
-from PyQt5.QtCore import pyqtSignal, QObject, Qt
-from PyQt5.QtGui import QKeySequence, QKeyEvent
+from qutebrowser.qt.core import QObject, pyqtSignal
+from qutebrowser.qt.gui import QKeySequence, QKeyEvent
from qutebrowser.config import config
-from qutebrowser.utils import usertypes, log, utils
+from qutebrowser.utils import log, usertypes, utils
from qutebrowser.keyinput import keyutils
@@ -42,7 +42,7 @@ class MatchResult:
sequence: keyutils.KeySequence
def __post_init__(self) -> None:
- if self.match_type == QKeySequence.ExactMatch:
+ if self.match_type == QKeySequence.SequenceMatch.ExactMatch:
assert self.command is not None
else:
assert self.command is None
@@ -89,7 +89,7 @@ class BindingTrie:
node.command = command
def __contains__(self, sequence: keyutils.KeySequence) -> bool:
- return self.matches(sequence).match_type == QKeySequence.ExactMatch
+ return self.matches(sequence).match_type == QKeySequence.SequenceMatch.ExactMatch
def __repr__(self) -> str:
return utils.get_repr(self, children=self.children,
@@ -131,20 +131,20 @@ class BindingTrie:
try:
node = node.children[key]
except KeyError:
- return MatchResult(match_type=QKeySequence.NoMatch,
+ return MatchResult(match_type=QKeySequence.SequenceMatch.NoMatch,
command=None,
sequence=sequence)
if node.command is not None:
- return MatchResult(match_type=QKeySequence.ExactMatch,
+ return MatchResult(match_type=QKeySequence.SequenceMatch.ExactMatch,
command=node.command,
sequence=sequence)
elif node.children:
- return MatchResult(match_type=QKeySequence.PartialMatch,
+ return MatchResult(match_type=QKeySequence.SequenceMatch.PartialMatch,
command=None,
sequence=sequence)
else: # This can only happen when there are no bindings at all.
- return MatchResult(match_type=QKeySequence.NoMatch,
+ return MatchResult(match_type=QKeySequence.SequenceMatch.NoMatch,
command=None,
sequence=sequence)
@@ -247,7 +247,7 @@ class BaseKeyParser(QObject):
self._debug_log("Mapped {} -> {}".format(
sequence, mapped))
return self._match_key(mapped)
- return MatchResult(match_type=QKeySequence.NoMatch,
+ return MatchResult(match_type=QKeySequence.SequenceMatch.NoMatch,
command=None,
sequence=sequence)
@@ -284,52 +284,60 @@ class BaseKeyParser(QObject):
Return:
A QKeySequence match.
"""
- key = Qt.Key(e.key())
- txt = str(keyutils.KeyInfo.from_event(e))
- self._debug_log("Got key: 0x{:x} / modifiers: 0x{:x} / text: '{}' / "
- "dry_run {}".format(key, int(e.modifiers()), txt,
- dry_run))
+ try:
+ info = keyutils.KeyInfo.from_event(e)
+ except keyutils.InvalidKeyError as ex:
+ # See https://github.com/qutebrowser/qutebrowser/issues/7047
+ log.keyboard.debug(f"Got invalid key: {ex}")
+ self.clear_keystring()
+ return QKeySequence.SequenceMatch.NoMatch
+
+ self._debug_log(f"Got key: {info!r} (dry_run {dry_run})")
- if keyutils.is_modifier_key(key):
+ if info.is_modifier_key():
self._debug_log("Ignoring, only modifier")
- return QKeySequence.NoMatch
+ return QKeySequence.SequenceMatch.NoMatch
try:
sequence = self._sequence.append_event(e)
except keyutils.KeyParseError as ex:
self._debug_log("{} Aborting keychain.".format(ex))
self.clear_keystring()
- return QKeySequence.NoMatch
+ return QKeySequence.SequenceMatch.NoMatch
result = self._match_key(sequence)
del sequence # Enforce code below to use the modified result.sequence
- if result.match_type == QKeySequence.NoMatch:
+ if result.match_type == QKeySequence.SequenceMatch.NoMatch:
result = self._match_without_modifiers(result.sequence)
- if result.match_type == QKeySequence.NoMatch:
+ if result.match_type == QKeySequence.SequenceMatch.NoMatch:
result = self._match_key_mapping(result.sequence)
- if result.match_type == QKeySequence.NoMatch:
+ if result.match_type == QKeySequence.SequenceMatch.NoMatch:
was_count = self._match_count(result.sequence, dry_run)
if was_count:
- return QKeySequence.ExactMatch
+ return QKeySequence.SequenceMatch.ExactMatch
if dry_run:
return result.match_type
self._sequence = result.sequence
+ self._handle_result(info, result)
+ return result.match_type
- if result.match_type == QKeySequence.ExactMatch:
+ def _handle_result(self, info: keyutils.KeyInfo, result: MatchResult) -> None:
+ """Handle a final MatchResult from handle()."""
+ if result.match_type == QKeySequence.SequenceMatch.ExactMatch:
assert result.command is not None
self._debug_log("Definitive match for '{}'.".format(
result.sequence))
count = int(self._count) if self._count else None
self.clear_keystring()
self.execute(result.command, count)
- elif result.match_type == QKeySequence.PartialMatch:
+ elif result.match_type == QKeySequence.SequenceMatch.PartialMatch:
self._debug_log("No match for '{}' (added {})".format(
- result.sequence, txt))
+ result.sequence, info))
self.keystring_updated.emit(self._count + str(result.sequence))
- elif result.match_type == QKeySequence.NoMatch:
+ elif result.match_type == QKeySequence.SequenceMatch.NoMatch:
self._debug_log("Giving up with '{}', no matches".format(
result.sequence))
self.clear_keystring()
@@ -337,8 +345,6 @@ class BaseKeyParser(QObject):
raise utils.Unreachable("Invalid match value {!r}".format(
result.match_type))
- return result.match_type
-
@config.change_filter('bindings')
def _on_config_changed(self) -> None:
self._read_config()
diff --git a/qutebrowser/keyinput/eventfilter.py b/qutebrowser/keyinput/eventfilter.py
index f0d85b0ec..31ffcc7f9 100644
--- a/qutebrowser/keyinput/eventfilter.py
+++ b/qutebrowser/keyinput/eventfilter.py
@@ -21,8 +21,8 @@
from typing import cast
-from PyQt5.QtCore import pyqtSlot, QObject, QEvent
-from PyQt5.QtGui import QKeyEvent, QWindow
+from qutebrowser.qt.core import pyqtSlot, QObject, QEvent
+from qutebrowser.qt.gui import QKeyEvent, QWindow
from qutebrowser.keyinput import modeman
from qutebrowser.misc import quitter, objects
@@ -43,9 +43,9 @@ class EventFilter(QObject):
super().__init__(parent)
self._activated = True
self._handlers = {
- QEvent.KeyPress: self._handle_key_event,
- QEvent.KeyRelease: self._handle_key_event,
- QEvent.ShortcutOverride: self._handle_key_event,
+ QEvent.Type.KeyPress: self._handle_key_event,
+ QEvent.Type.KeyRelease: self._handle_key_event,
+ QEvent.Type.ShortcutOverride: self._handle_key_event,
}
def install(self) -> None:
diff --git a/qutebrowser/keyinput/keyutils.py b/qutebrowser/keyinput/keyutils.py
index 0362e09f3..9a0deffc5 100644
--- a/qutebrowser/keyinput/keyutils.py
+++ b/qutebrowser/keyinput/keyutils.py
@@ -24,8 +24,8 @@ comes to keys/modifiers. Many places (such as QKeyEvent::key()) don't actually
return a Qt::Key, they return an int.
To make things worse, when talking about a "key", sometimes Qt means a Qt::Key
-member. However, sometimes it means a Qt::Key member ORed with
-Qt.KeyboardModifiers...
+member. However, sometimes it means a Qt::Key member ORed with a
+Qt.KeyboardModifier...
Because of that, _assert_plain_key() and _assert_plain_modifier() make sure we
handle what we actually think we do.
@@ -33,27 +33,52 @@ handle what we actually think we do.
import itertools
import dataclasses
-from typing import cast, overload, Iterable, Iterator, List, Mapping, Optional, Union
+from typing import Iterator, Iterable, List, Mapping, Optional, Union, overload, cast
-from PyQt5.QtCore import Qt, QEvent
-from PyQt5.QtGui import QKeySequence, QKeyEvent
+from qutebrowser.qt import machinery
+from qutebrowser.qt.core import Qt, QEvent
+from qutebrowser.qt.gui import QKeySequence, QKeyEvent
+if machinery.IS_QT6:
+ # FIXME:qt6 (lint) how come pylint isn't picking this up with both backends
+ # installed?
+ from qutebrowser.qt.core import QKeyCombination # pylint: disable=no-name-in-module
+else:
+ QKeyCombination = None # QKeyCombination was added in Qt 6
-from qutebrowser.utils import utils
+from qutebrowser.utils import utils, qtutils, debug
+
+
+class InvalidKeyError(Exception):
+
+ """Raised when a key can't be represented by PyQt.
+
+ WORKAROUND for https://www.riverbankcomputing.com/pipermail/pyqt/2022-April/044607.html
+ Should be fixed in PyQt 6.3.1 (or 6.4.0?).
+ """
# Map Qt::Key values to their Qt::KeyboardModifier value.
_MODIFIER_MAP = {
- Qt.Key_Shift: Qt.ShiftModifier,
- Qt.Key_Control: Qt.ControlModifier,
- Qt.Key_Alt: Qt.AltModifier,
- Qt.Key_Meta: Qt.MetaModifier,
- Qt.Key_AltGr: Qt.GroupSwitchModifier,
- Qt.Key_Mode_switch: Qt.GroupSwitchModifier,
+ Qt.Key.Key_Shift: Qt.KeyboardModifier.ShiftModifier,
+ Qt.Key.Key_Control: Qt.KeyboardModifier.ControlModifier,
+ Qt.Key.Key_Alt: Qt.KeyboardModifier.AltModifier,
+ Qt.Key.Key_Meta: Qt.KeyboardModifier.MetaModifier,
+ Qt.Key.Key_AltGr: Qt.KeyboardModifier.GroupSwitchModifier,
+ Qt.Key.Key_Mode_switch: Qt.KeyboardModifier.GroupSwitchModifier,
}
-_NIL_KEY = Qt.Key(0)
+try:
+ _NIL_KEY: Union[Qt.Key, int] = Qt.Key(0)
+except ValueError:
+ # WORKAROUND for
+ # https://www.riverbankcomputing.com/pipermail/pyqt/2022-April/044607.html
+ _NIL_KEY = 0
-_ModifierType = Union[Qt.KeyboardModifier, Qt.KeyboardModifiers]
+_ModifierType = Qt.KeyboardModifier
+if machinery.IS_QT6:
+ _KeyInfoType = QKeyCombination
+else:
+ _KeyInfoType = int
_SPECIAL_NAMES = {
@@ -63,123 +88,101 @@ _SPECIAL_NAMES = {
# For dead/combining keys, we return the corresponding non-combining
# key, as that's easier to add to the config.
- Qt.Key_Super_L: 'Super L',
- Qt.Key_Super_R: 'Super R',
- Qt.Key_Hyper_L: 'Hyper L',
- Qt.Key_Hyper_R: 'Hyper R',
- Qt.Key_Direction_L: 'Direction L',
- Qt.Key_Direction_R: 'Direction R',
-
- Qt.Key_Shift: 'Shift',
- Qt.Key_Control: 'Control',
- Qt.Key_Meta: 'Meta',
- Qt.Key_Alt: 'Alt',
-
- Qt.Key_AltGr: 'AltGr',
- Qt.Key_Multi_key: 'Multi key',
- Qt.Key_SingleCandidate: 'Single Candidate',
- Qt.Key_Mode_switch: 'Mode switch',
- Qt.Key_Dead_Grave: '`',
- Qt.Key_Dead_Acute: '´',
- Qt.Key_Dead_Circumflex: '^',
- Qt.Key_Dead_Tilde: '~',
- Qt.Key_Dead_Macron: '¯',
- Qt.Key_Dead_Breve: '˘',
- Qt.Key_Dead_Abovedot: '˙',
- Qt.Key_Dead_Diaeresis: '¨',
- Qt.Key_Dead_Abovering: '˚',
- Qt.Key_Dead_Doubleacute: '˝',
- Qt.Key_Dead_Caron: 'ˇ',
- Qt.Key_Dead_Cedilla: '¸',
- Qt.Key_Dead_Ogonek: '˛',
- Qt.Key_Dead_Iota: 'Iota',
- Qt.Key_Dead_Voiced_Sound: 'Voiced Sound',
- Qt.Key_Dead_Semivoiced_Sound: 'Semivoiced Sound',
- Qt.Key_Dead_Belowdot: 'Belowdot',
- Qt.Key_Dead_Hook: 'Hook',
- Qt.Key_Dead_Horn: 'Horn',
-
- Qt.Key_Dead_Stroke: '\u0335', # '̵'
- Qt.Key_Dead_Abovecomma: '\u0313', # '̓'
- Qt.Key_Dead_Abovereversedcomma: '\u0314', # '̔'
- Qt.Key_Dead_Doublegrave: '\u030f', # '̏'
- Qt.Key_Dead_Belowring: '\u0325', # '̥'
- Qt.Key_Dead_Belowmacron: '\u0331', # '̱'
- Qt.Key_Dead_Belowcircumflex: '\u032d', # '̭'
- Qt.Key_Dead_Belowtilde: '\u0330', # '̰'
- Qt.Key_Dead_Belowbreve: '\u032e', # '̮'
- Qt.Key_Dead_Belowdiaeresis: '\u0324', # '̤'
- Qt.Key_Dead_Invertedbreve: '\u0311', # '̑'
- Qt.Key_Dead_Belowcomma: '\u0326', # '̦'
- Qt.Key_Dead_Currency: '¤',
- Qt.Key_Dead_a: 'a',
- Qt.Key_Dead_A: 'A',
- Qt.Key_Dead_e: 'e',
- Qt.Key_Dead_E: 'E',
- Qt.Key_Dead_i: 'i',
- Qt.Key_Dead_I: 'I',
- Qt.Key_Dead_o: 'o',
- Qt.Key_Dead_O: 'O',
- Qt.Key_Dead_u: 'u',
- Qt.Key_Dead_U: 'U',
- Qt.Key_Dead_Small_Schwa: 'ə',
- Qt.Key_Dead_Capital_Schwa: 'Ə',
- Qt.Key_Dead_Greek: 'Greek',
- Qt.Key_Dead_Lowline: '\u0332', # '̲'
- Qt.Key_Dead_Aboveverticalline: '\u030d', # '̍'
- Qt.Key_Dead_Belowverticalline: '\u0329',
- Qt.Key_Dead_Longsolidusoverlay: '\u0338', # '̸'
-
- Qt.Key_Memo: 'Memo',
- Qt.Key_ToDoList: 'To Do List',
- Qt.Key_Calendar: 'Calendar',
- Qt.Key_ContrastAdjust: 'Contrast Adjust',
- Qt.Key_LaunchG: 'Launch (G)',
- Qt.Key_LaunchH: 'Launch (H)',
-
- Qt.Key_MediaLast: 'Media Last',
-
- Qt.Key_unknown: 'Unknown',
+ Qt.Key.Key_Super_L: 'Super L',
+ Qt.Key.Key_Super_R: 'Super R',
+ Qt.Key.Key_Hyper_L: 'Hyper L',
+ Qt.Key.Key_Hyper_R: 'Hyper R',
+ Qt.Key.Key_Direction_L: 'Direction L',
+ Qt.Key.Key_Direction_R: 'Direction R',
+
+ Qt.Key.Key_Shift: 'Shift',
+ Qt.Key.Key_Control: 'Control',
+ Qt.Key.Key_Meta: 'Meta',
+ Qt.Key.Key_Alt: 'Alt',
+ Qt.Key.Key_AltGr: 'AltGr',
+
+ Qt.Key.Key_Multi_key: 'Multi key',
+ Qt.Key.Key_SingleCandidate: 'Single Candidate',
+ Qt.Key.Key_Mode_switch: 'Mode switch',
+
+ Qt.Key.Key_Dead_Grave: '`',
+ Qt.Key.Key_Dead_Acute: '´',
+ Qt.Key.Key_Dead_Circumflex: '^',
+ Qt.Key.Key_Dead_Tilde: '~',
+ Qt.Key.Key_Dead_Macron: '¯',
+ Qt.Key.Key_Dead_Breve: '˘',
+ Qt.Key.Key_Dead_Abovedot: '˙',
+ Qt.Key.Key_Dead_Diaeresis: '¨',
+ Qt.Key.Key_Dead_Abovering: '˚',
+ Qt.Key.Key_Dead_Doubleacute: '˝',
+ Qt.Key.Key_Dead_Caron: 'ˇ',
+ Qt.Key.Key_Dead_Cedilla: '¸',
+ Qt.Key.Key_Dead_Ogonek: '˛',
+ Qt.Key.Key_Dead_Iota: 'Iota',
+ Qt.Key.Key_Dead_Voiced_Sound: 'Voiced Sound',
+ Qt.Key.Key_Dead_Semivoiced_Sound: 'Semivoiced Sound',
+ Qt.Key.Key_Dead_Belowdot: 'Belowdot',
+ Qt.Key.Key_Dead_Hook: 'Hook',
+ Qt.Key.Key_Dead_Horn: 'Horn',
+ Qt.Key.Key_Dead_Stroke: '\u0335', # '̵'
+ Qt.Key.Key_Dead_Abovecomma: '\u0313', # '̓'
+ Qt.Key.Key_Dead_Abovereversedcomma: '\u0314', # '̔'
+ Qt.Key.Key_Dead_Doublegrave: '\u030f', # '̏'
+ Qt.Key.Key_Dead_Belowring: '\u0325', # '̥'
+ Qt.Key.Key_Dead_Belowmacron: '\u0331', # '̱'
+ Qt.Key.Key_Dead_Belowcircumflex: '\u032d', # '̭'
+ Qt.Key.Key_Dead_Belowtilde: '\u0330', # '̰'
+ Qt.Key.Key_Dead_Belowbreve: '\u032e', # '̮'
+ Qt.Key.Key_Dead_Belowdiaeresis: '\u0324', # '̤'
+ Qt.Key.Key_Dead_Invertedbreve: '\u0311', # '̑'
+ Qt.Key.Key_Dead_Belowcomma: '\u0326', # '̦'
+ Qt.Key.Key_Dead_Currency: '¤',
+ Qt.Key.Key_Dead_a: 'a',
+ Qt.Key.Key_Dead_A: 'A',
+ Qt.Key.Key_Dead_e: 'e',
+ Qt.Key.Key_Dead_E: 'E',
+ Qt.Key.Key_Dead_i: 'i',
+ Qt.Key.Key_Dead_I: 'I',
+ Qt.Key.Key_Dead_o: 'o',
+ Qt.Key.Key_Dead_O: 'O',
+ Qt.Key.Key_Dead_u: 'u',
+ Qt.Key.Key_Dead_U: 'U',
+ Qt.Key.Key_Dead_Small_Schwa: 'ə',
+ Qt.Key.Key_Dead_Capital_Schwa: 'Ə',
+ Qt.Key.Key_Dead_Greek: 'Greek',
+ Qt.Key.Key_Dead_Lowline: '\u0332', # '̲'
+ Qt.Key.Key_Dead_Aboveverticalline: '\u030d', # '̍'
+ Qt.Key.Key_Dead_Belowverticalline: '\u0329',
+ Qt.Key.Key_Dead_Longsolidusoverlay: '\u0338', # '̸'
+
+ Qt.Key.Key_MediaLast: 'Media Last',
+
+ Qt.Key.Key_unknown: 'Unknown',
# For some keys, we just want a different name
- Qt.Key_Escape: 'Escape',
+ Qt.Key.Key_Escape: 'Escape',
_NIL_KEY: 'nil',
}
def _assert_plain_key(key: Qt.Key) -> None:
- """Make sure this is a key without KeyboardModifiers mixed in."""
- assert not key & Qt.KeyboardModifierMask, hex(key)
+ """Make sure this is a key without KeyboardModifier mixed in."""
+ key_int = qtutils.extract_enum_val(key)
+ mask = qtutils.extract_enum_val(Qt.KeyboardModifier.KeyboardModifierMask)
+ assert not key_int & mask, hex(key_int)
def _assert_plain_modifier(key: _ModifierType) -> None:
"""Make sure this is a modifier without a key mixed in."""
- mask = Qt.KeyboardModifierMask
- assert not key & ~mask, hex(key)
+ key_int = qtutils.extract_enum_val(key)
+ mask = qtutils.extract_enum_val(Qt.KeyboardModifier.KeyboardModifierMask)
+ assert not key_int & ~mask, hex(key_int)
def _is_printable(key: Qt.Key) -> bool:
_assert_plain_key(key)
- return key <= 0xff and key not in [Qt.Key_Space, _NIL_KEY]
-
-
-def is_special(key: Qt.Key, modifiers: _ModifierType) -> bool:
- """Check whether this key requires special key syntax."""
- _assert_plain_key(key)
- _assert_plain_modifier(modifiers)
- return not (_is_printable(key) and
- modifiers in [Qt.ShiftModifier, Qt.NoModifier])
-
-
-def is_modifier_key(key: Qt.Key) -> bool:
- """Test whether the given key is a modifier.
-
- This only considers keys which are part of Qt::KeyboardModifiers, i.e.
- which would interrupt a key chain like "yY" when handled.
- """
- _assert_plain_key(key)
- return key in _MODIFIER_MAP
+ return key <= 0xff and key not in [Qt.Key.Key_Space, _NIL_KEY]
def _is_surrogate(key: Qt.Key) -> bool:
@@ -248,20 +251,20 @@ def _key_to_string(key: Qt.Key) -> str:
def _modifiers_to_string(modifiers: _ModifierType) -> str:
- """Convert the given Qt::KeyboardModifiers to a string.
+ """Convert the given Qt::KeyboardModifier to a string.
- Handles Qt.GroupSwitchModifier because Qt doesn't handle that as a
+ Handles Qt.KeyboardModifier.GroupSwitchModifier because Qt doesn't handle that as a
modifier.
"""
_assert_plain_modifier(modifiers)
- altgr = cast(Qt.KeyboardModifiers, Qt.GroupSwitchModifier)
+ altgr = Qt.KeyboardModifier.GroupSwitchModifier
if modifiers & altgr:
- modifiers &= ~altgr
+ modifiers &= ~altgr # type: ignore[assignment]
result = 'AltGr+'
else:
result = ''
- result += QKeySequence(modifiers).toString()
+ result += QKeySequence(qtutils.extract_enum_val(modifiers)).toString()
_check_valid_utf8(result, modifiers)
return result
@@ -344,11 +347,29 @@ class KeyInfo:
Attributes:
key: A Qt::Key member.
- modifiers: A Qt::KeyboardModifiers enum value.
+ modifiers: A Qt::KeyboardModifier enum value.
"""
key: Qt.Key
- modifiers: _ModifierType
+ modifiers: _ModifierType = Qt.KeyboardModifier.NoModifier
+
+ def __post_init__(self) -> None:
+ """Run some validation on the key/modifier values."""
+ # This is mainly useful while porting from Qt 5 to 6.
+ # FIXME:qt6 do we want to remove or keep this (and fix the remaining
+ # issues) when done?
+ # assert isinstance(self.key, Qt.Key), self.key
+ # assert isinstance(self.modifiers, Qt.KeyboardModifier), self.modifiers
+ _assert_plain_key(self.key)
+ _assert_plain_modifier(self.modifiers)
+
+ def __repr__(self) -> str:
+ return utils.get_repr(
+ self,
+ key=debug.qenum_key(Qt, self.key, klass=Qt.Key),
+ modifiers=debug.qflags_key(Qt, self.modifiers, klass=Qt.KeyboardModifier),
+ text=str(self),
+ )
@classmethod
def from_event(cls, e: QKeyEvent) -> 'KeyInfo':
@@ -357,11 +378,35 @@ class KeyInfo:
This makes sure that key/modifiers are never mixed and also remaps
UTF-16 surrogates to work around QTBUG-72776.
"""
- key = _remap_unicode(Qt.Key(e.key()), e.text())
- modifiers = e.modifiers()
- _assert_plain_key(key)
- _assert_plain_modifier(modifiers)
- return cls(key, cast(Qt.KeyboardModifier, modifiers))
+ try:
+ key = Qt.Key(e.key())
+ except ValueError as ex:
+ raise InvalidKeyError(str(ex))
+ key = _remap_unicode(key, e.text())
+ modifiers = cast(Qt.KeyboardModifier, e.modifiers())
+ return cls(key, modifiers)
+
+ @classmethod
+ def from_qt(cls, combination: _KeyInfoType) -> 'KeyInfo':
+ """Construct a KeyInfo from a Qt5-style int or Qt6-style QKeyCombination."""
+ if machinery.IS_QT5:
+ assert isinstance(combination, int)
+ key = Qt.Key(
+ int(combination) & ~Qt.KeyboardModifier.KeyboardModifierMask)
+ modifiers = Qt.KeyboardModifier(
+ int(combination) & Qt.KeyboardModifier.KeyboardModifierMask)
+ return cls(key, modifiers)
+ else:
+ # QKeyCombination is now guaranteed to be available here
+ assert isinstance(combination, QKeyCombination)
+ try:
+ key = combination.key()
+ except ValueError as e:
+ raise InvalidKeyError(str(e))
+ return cls(
+ key=key,
+ modifiers=combination.keyboardModifiers(),
+ )
def __str__(self) -> str:
"""Convert this KeyInfo to a meaningful name.
@@ -370,11 +415,11 @@ class KeyInfo:
A name of the key (combination) as a string.
"""
key_string = _key_to_string(self.key)
- modifiers = int(self.modifiers)
+ modifiers = self.modifiers
if self.key in _MODIFIER_MAP:
# Don't return e.g. <Shift+Shift>
- modifiers &= ~_MODIFIER_MAP[self.key]
+ modifiers &= ~_MODIFIER_MAP[self.key] # type: ignore[assignment]
elif _is_printable(self.key):
# "normal" binding
if not key_string: # pragma: no cover
@@ -382,11 +427,11 @@ class KeyInfo:
.format(self.key))
assert len(key_string) == 1, key_string
- if self.modifiers == Qt.ShiftModifier:
- assert not is_special(self.key, self.modifiers)
+ if self.modifiers == Qt.KeyboardModifier.ShiftModifier:
+ assert not self.is_special()
return key_string.upper()
- elif self.modifiers == Qt.NoModifier:
- assert not is_special(self.key, self.modifiers)
+ elif self.modifiers == Qt.KeyboardModifier.NoModifier:
+ assert not self.is_special()
return key_string.lower()
else:
# Use special binding syntax, but <Ctrl-a> instead of <Ctrl-A>
@@ -395,19 +440,19 @@ class KeyInfo:
modifiers = Qt.KeyboardModifier(modifiers)
# "special" binding
- assert is_special(self.key, self.modifiers)
+ assert self.is_special()
modifier_string = _modifiers_to_string(modifiers)
return '<{}{}>'.format(modifier_string, key_string)
def text(self) -> str:
"""Get the text which would be displayed when pressing this key."""
control = {
- Qt.Key_Space: ' ',
- Qt.Key_Tab: '\t',
- Qt.Key_Backspace: '\b',
- Qt.Key_Return: '\r',
- Qt.Key_Enter: '\r',
- Qt.Key_Escape: '\x1b',
+ Qt.Key.Key_Space: ' ',
+ Qt.Key.Key_Tab: '\t',
+ Qt.Key.Key_Backspace: '\b',
+ Qt.Key.Key_Return: '\r',
+ Qt.Key.Key_Enter: '\r',
+ Qt.Key.Key_Escape: '\x1b',
}
if self.key in control:
@@ -416,17 +461,51 @@ class KeyInfo:
return ''
text = QKeySequence(self.key).toString()
- if not self.modifiers & Qt.ShiftModifier:
+ if not self.modifiers & Qt.KeyboardModifier.ShiftModifier:
text = text.lower()
return text
- def to_event(self, typ: QEvent.Type = QEvent.KeyPress) -> QKeyEvent:
+ def to_event(self, typ: QEvent.Type = QEvent.Type.KeyPress) -> QKeyEvent:
"""Get a QKeyEvent from this KeyInfo."""
return QKeyEvent(typ, self.key, self.modifiers, self.text())
- def to_int(self) -> int:
- """Get the key as an integer (with key/modifiers)."""
- return int(self.key) | int(self.modifiers)
+ def to_qt(self) -> _KeyInfoType:
+ """Get something suitable for a QKeySequence."""
+ if machinery.IS_QT5:
+ return int(self.key) | int(self.modifiers)
+ else:
+ try:
+ # FIXME:qt6 We might want to consider only supporting KeyInfo to be
+ # instanciated with a real Qt.Key, not with ints. See __post_init__.
+ key = Qt.Key(self.key)
+ except ValueError as e:
+ # WORKAROUND for
+ # https://www.riverbankcomputing.com/pipermail/pyqt/2022-April/044607.html
+ raise InvalidKeyError(e)
+
+ return QKeyCombination(self.modifiers, key)
+
+ def with_stripped_modifiers(self, modifiers: Qt.KeyboardModifier) -> "KeyInfo":
+ mods = self.modifiers & ~modifiers
+ return KeyInfo(key=self.key, modifiers=mods) # type: ignore[arg-type]
+
+ def is_special(self) -> bool:
+ """Check whether this key requires special key syntax."""
+ return not (
+ _is_printable(self.key) and
+ self.modifiers in [
+ Qt.KeyboardModifier.ShiftModifier,
+ Qt.KeyboardModifier.NoModifier,
+ ]
+ )
+
+ def is_modifier_key(self) -> bool:
+ """Test whether the given key is a modifier.
+
+ This only considers keys which are part of Qt::KeyboardModifier, i.e.
+ which would interrupt a key chain like "yY" when handled.
+ """
+ return self.key in _MODIFIER_MAP
class KeySequence:
@@ -448,21 +527,20 @@ class KeySequence:
_MAX_LEN = 4
- def __init__(self, *keys: int) -> None:
+ def __init__(self, *keys: KeyInfo) -> None:
self._sequences: List[QKeySequence] = []
for sub in utils.chunk(keys, self._MAX_LEN):
- args = [self._convert_key(key) for key in sub]
+ try:
+ args = [info.to_qt() for info in sub]
+ except InvalidKeyError as e:
+ raise KeyParseError(keystr=None, error=f"Got invalid key: {e}")
+
sequence = QKeySequence(*args)
self._sequences.append(sequence)
if keys:
assert self
self._validate()
- def _convert_key(self, key: Union[int, Qt.KeyboardModifiers]) -> int:
- """Convert a single key for QKeySequence."""
- assert isinstance(key, (int, Qt.KeyboardModifiers)), key
- return int(key)
-
def __str__(self) -> str:
parts = []
for info in self:
@@ -471,11 +549,11 @@ class KeySequence:
def __iter__(self) -> Iterator[KeyInfo]:
"""Iterate over KeyInfo objects."""
- for key_and_modifiers in self._iter_keys():
- key = Qt.Key(int(key_and_modifiers) & ~Qt.KeyboardModifierMask)
- modifiers = Qt.KeyboardModifiers(
- int(key_and_modifiers) & Qt.KeyboardModifierMask)
- yield KeyInfo(key=key, modifiers=modifiers)
+ # FIXME:mypy Stubs seem to be unaware that iterating a QKeySequence produces
+ # _KeyInfoType
+ sequences = cast(List[Iterable[_KeyInfoType]], self._sequences)
+ for combination in itertools.chain.from_iterable(sequences):
+ yield KeyInfo.from_qt(combination)
def __repr__(self) -> str:
return utils.get_repr(self, keys=str(self))
@@ -520,21 +598,19 @@ class KeySequence:
...
def __getitem__(self, item: Union[int, slice]) -> Union[KeyInfo, 'KeySequence']:
+ infos = list(self)
if isinstance(item, slice):
- keys = list(self._iter_keys())
- return self.__class__(*keys[item])
+ return self.__class__(*infos[item])
else:
- infos = list(self)
return infos[item]
- def _iter_keys(self) -> Iterator[int]:
- sequences = cast(Iterable[Iterable[int]], self._sequences)
- return itertools.chain.from_iterable(sequences)
-
def _validate(self, keystr: str = None) -> None:
- for info in self:
- if info.key < Qt.Key_Space or info.key >= Qt.Key_unknown:
- raise KeyParseError(keystr, "Got invalid key!")
+ try:
+ for info in self:
+ if info.key < Qt.Key.Key_Space or info.key >= Qt.Key.Key_unknown:
+ raise KeyParseError(keystr, "Got invalid key!")
+ except InvalidKeyError as e:
+ raise KeyParseError(keystr, f"Got invalid key: {e}")
for seq in self._sequences:
if not seq:
@@ -552,12 +628,12 @@ class KeySequence:
if len(self._sequences) > len(other._sequences):
# If we entered more sequences than there are in the config,
# there's no way there can be a match.
- return QKeySequence.NoMatch
+ return QKeySequence.SequenceMatch.NoMatch
for entered, configured in zip(self._sequences, other._sequences):
# If we get NoMatch/PartialMatch in a sequence, we can abort there.
match = entered.matches(configured)
- if match != QKeySequence.ExactMatch:
+ if match != QKeySequence.SequenceMatch.ExactMatch:
return match
# We checked all common sequences and they had an ExactMatch.
@@ -569,33 +645,36 @@ class KeySequence:
# If there's the same amount of sequences configured and entered,
# that's an EqualMatch.
if len(self._sequences) == len(other._sequences):
- return QKeySequence.ExactMatch
+ return QKeySequence.SequenceMatch.ExactMatch
elif len(self._sequences) < len(other._sequences):
- return QKeySequence.PartialMatch
+ return QKeySequence.SequenceMatch.PartialMatch
else:
raise utils.Unreachable("self={!r} other={!r}".format(self, other))
def append_event(self, ev: QKeyEvent) -> 'KeySequence':
"""Create a new KeySequence object with the given QKeyEvent added."""
- key = Qt.Key(ev.key())
+ try:
+ key = Qt.Key(ev.key())
+ except ValueError as e:
+ raise KeyParseError(None, f"Got invalid key: {e}")
_assert_plain_key(key)
- _assert_plain_modifier(ev.modifiers())
+ _assert_plain_modifier(cast(Qt.KeyboardModifier, ev.modifiers()))
key = _remap_unicode(key, ev.text())
- modifiers = int(ev.modifiers())
+ modifiers = ev.modifiers()
if key == _NIL_KEY:
raise KeyParseError(None, "Got nil key!")
- # We always remove Qt.GroupSwitchModifier because QKeySequence has no
+ # We always remove Qt.KeyboardModifier.GroupSwitchModifier because QKeySequence has no
# way to mention that in a binding anyways...
- modifiers &= ~Qt.GroupSwitchModifier
+ modifiers &= ~Qt.KeyboardModifier.GroupSwitchModifier
- # We change Qt.Key_Backtab to Key_Tab here because nobody would
+ # We change Qt.Key.Key_Backtab to Key_Tab here because nobody would
# configure "Shift-Backtab" in their config.
- if modifiers & Qt.ShiftModifier and key == Qt.Key_Backtab:
- key = Qt.Key_Tab
+ if modifiers & Qt.KeyboardModifier.ShiftModifier and key == Qt.Key.Key_Backtab:
+ key = Qt.Key.Key_Tab
# We don't care about a shift modifier with symbols (Shift-: should
# match a : binding even though we typed it with a shift on an
@@ -607,52 +686,52 @@ class KeySequence:
#
# In addition, Shift also *is* relevant when other modifiers are
# involved. Shift-Ctrl-X should not be equivalent to Ctrl-X.
- if (modifiers == Qt.ShiftModifier and
+ shift_modifier = Qt.KeyboardModifier.ShiftModifier
+ if (modifiers == shift_modifier and # type: ignore[comparison-overlap]
_is_printable(key) and
not ev.text().isupper()):
- modifiers = Qt.KeyboardModifiers() # type: ignore[assignment]
+ modifiers = Qt.KeyboardModifier.NoModifier # type: ignore[assignment]
# On macOS, swap Ctrl and Meta back
#
- # We don't use Qt.AA_MacDontSwapCtrlAndMeta because that also affects
+ # We don't use Qt.ApplicationAttribute.AA_MacDontSwapCtrlAndMeta because that also affects
# Qt/QtWebEngine's own shortcuts. However, we do want "Ctrl" and "Meta"
# (or "Cmd") in a key binding name to actually represent what's on the
# keyboard.
if utils.is_mac:
- # FIXME:qt6 Reevaluate the type ignores below
- if modifiers & Qt.ControlModifier and modifiers & Qt.MetaModifier:
+ if modifiers & Qt.KeyboardModifier.ControlModifier and modifiers & Qt.KeyboardModifier.MetaModifier:
pass
- elif modifiers & Qt.ControlModifier:
- modifiers &= ~Qt.ControlModifier
- modifiers |= Qt.MetaModifier # type: ignore[assignment]
- elif modifiers & Qt.MetaModifier:
- modifiers &= ~Qt.MetaModifier
- modifiers |= Qt.ControlModifier # type: ignore[assignment]
+ elif modifiers & Qt.KeyboardModifier.ControlModifier:
+ modifiers &= ~Qt.KeyboardModifier.ControlModifier
+ modifiers |= Qt.KeyboardModifier.MetaModifier
+ elif modifiers & Qt.KeyboardModifier.MetaModifier:
+ modifiers &= ~Qt.KeyboardModifier.MetaModifier
+ modifiers |= Qt.KeyboardModifier.ControlModifier
- keys = list(self._iter_keys())
- keys.append(key | int(modifiers))
+ infos = list(self)
+ infos.append(KeyInfo(key, cast(Qt.KeyboardModifier, modifiers)))
- return self.__class__(*keys)
+ return self.__class__(*infos)
def strip_modifiers(self) -> 'KeySequence':
"""Strip optional modifiers from keys."""
- modifiers = Qt.KeypadModifier
- keys = [key & ~modifiers for key in self._iter_keys()]
- return self.__class__(*keys)
+ modifiers = Qt.KeyboardModifier.KeypadModifier
+ infos = [info.with_stripped_modifiers(modifiers) for info in self]
+ return self.__class__(*infos)
def with_mappings(
self,
mappings: Mapping['KeySequence', 'KeySequence']
) -> 'KeySequence':
"""Get a new KeySequence with the given mappings applied."""
- keys = []
- for key in self._iter_keys():
- key_seq = KeySequence(key)
+ infos: List[KeyInfo] = []
+ for info in self:
+ key_seq = KeySequence(info)
if key_seq in mappings:
- keys += [info.to_int() for info in mappings[key_seq]]
+ infos += mappings[key_seq]
else:
- keys.append(key)
- return self.__class__(*keys)
+ infos.append(info)
+ return self.__class__(*infos)
@classmethod
def parse(cls, keystr: str) -> 'KeySequence':
diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py
index 24c701401..671c2519e 100644
--- a/qutebrowser/keyinput/modeman.py
+++ b/qutebrowser/keyinput/modeman.py
@@ -23,8 +23,8 @@ import functools
import dataclasses
from typing import Mapping, Callable, MutableMapping, Union, Set, cast
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QObject, QEvent
-from PyQt5.QtGui import QKeyEvent
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, Qt, QObject, QEvent
+from qutebrowser.qt.gui import QKeyEvent, QKeySequence
from qutebrowser.commands import runners
from qutebrowser.keyinput import modeparsers, basekeyparser
@@ -51,17 +51,19 @@ class KeyEvent:
press/release.
Attributes:
- key: A Qt.Key member (QKeyEvent::key).
+ key: Usually a Qt.Key member, but could be other ints (QKeyEvent::key).
text: A string (QKeyEvent::text).
"""
- key: Qt.Key
+ # int instead of Qt.Key:
+ # WORKAROUND for https://www.riverbankcomputing.com/pipermail/pyqt/2022-April/044607.html
+ key: int
text: str
@classmethod
def from_event(cls, event: QKeyEvent) -> 'KeyEvent':
"""Initialize a KeyEvent from a QKeyEvent."""
- return cls(Qt.Key(event.key()), event.text())
+ return cls(event.key(), event.text())
class NotInModeError(Exception):
@@ -290,14 +292,14 @@ class ModeManager(QObject):
match = parser.handle(event, dry_run=dry_run)
has_modifier = event.modifiers() not in [
- Qt.NoModifier,
- Qt.ShiftModifier,
+ Qt.KeyboardModifier.NoModifier,
+ Qt.KeyboardModifier.ShiftModifier,
] # type: ignore[comparison-overlap]
is_non_alnum = has_modifier or not event.text().strip()
forward_unbound_keys = config.cache['input.forward_unbound_keys']
- if match:
+ if match != QKeySequence.SequenceMatch.NoMatch:
filter_this = True
elif (parser.passthrough or forward_unbound_keys == 'all' or
(forward_unbound_keys == 'auto' and is_non_alnum)):
@@ -460,9 +462,9 @@ class ModeManager(QObject):
True if event should be filtered, False otherwise.
"""
handlers: Mapping[QEvent.Type, Callable[[QKeyEvent], bool]] = {
- QEvent.KeyPress: self._handle_keypress,
- QEvent.KeyRelease: self._handle_keyrelease,
- QEvent.ShortcutOverride:
+ QEvent.Type.KeyPress: self._handle_keypress,
+ QEvent.Type.KeyRelease: self._handle_keyrelease,
+ QEvent.Type.ShortcutOverride:
functools.partial(self._handle_keypress, dry_run=True),
}
handler = handlers[event.type()]
diff --git a/qutebrowser/keyinput/modeparsers.py b/qutebrowser/keyinput/modeparsers.py
index bd5d4e801..d127a795a 100644
--- a/qutebrowser/keyinput/modeparsers.py
+++ b/qutebrowser/keyinput/modeparsers.py
@@ -27,8 +27,8 @@ import traceback
import enum
from typing import TYPE_CHECKING, Sequence
-from PyQt5.QtCore import pyqtSlot, Qt, QObject
-from PyQt5.QtGui import QKeySequence, QKeyEvent
+from qutebrowser.qt.core import pyqtSlot, Qt, QObject
+from qutebrowser.qt.gui import QKeySequence, QKeyEvent
from qutebrowser.browser import hints
from qutebrowser.commands import cmdexc
@@ -110,11 +110,11 @@ class NormalKeyParser(CommandKeyParser):
if self._inhibited:
self._debug_log("Ignoring key '{}', because the normal mode is "
"currently inhibited.".format(txt))
- return QKeySequence.NoMatch
+ return QKeySequence.SequenceMatch.NoMatch
match = super().handle(e, dry_run=dry_run)
- if match == QKeySequence.PartialMatch and not dry_run:
+ if match == QKeySequence.SequenceMatch.PartialMatch and not dry_run:
timeout = config.val.input.partial_timeout
if timeout != 0:
self._partial_timer.setInterval(timeout)
@@ -178,7 +178,7 @@ class HintKeyParser(basekeyparser.BaseKeyParser):
"""Handle keys for string filtering."""
log.keyboard.debug("Got filter key 0x{:x} text {}".format(
e.key(), e.text()))
- if e.key() == Qt.Key_Backspace:
+ if e.key() == Qt.Key.Key_Backspace:
log.keyboard.debug("Got backspace, mode {}, filtertext '{}', "
"sequence '{}'".format(self._last_press,
self._filtertext,
@@ -186,7 +186,7 @@ class HintKeyParser(basekeyparser.BaseKeyParser):
if self._last_press != LastPress.keystring and self._filtertext:
self._filtertext = self._filtertext[:-1]
self._hintmanager.filter_hints(self._filtertext)
- return QKeySequence.ExactMatch
+ return QKeySequence.SequenceMatch.ExactMatch
elif self._last_press == LastPress.keystring and self._sequence:
self._sequence = self._sequence[:-1]
self.keystring_updated.emit(str(self._sequence))
@@ -195,18 +195,18 @@ class HintKeyParser(basekeyparser.BaseKeyParser):
# in numeric mode after the number has been deleted).
self._hintmanager.filter_hints(self._filtertext)
self._last_press = LastPress.filtertext
- return QKeySequence.ExactMatch
+ return QKeySequence.SequenceMatch.ExactMatch
else:
- return QKeySequence.NoMatch
+ return QKeySequence.SequenceMatch.NoMatch
elif self._hintmanager.current_mode() != 'number':
- return QKeySequence.NoMatch
+ return QKeySequence.SequenceMatch.NoMatch
elif not e.text():
- return QKeySequence.NoMatch
+ return QKeySequence.SequenceMatch.NoMatch
else:
self._filtertext += e.text()
self._hintmanager.filter_hints(self._filtertext)
self._last_press = LastPress.filtertext
- return QKeySequence.ExactMatch
+ return QKeySequence.SequenceMatch.ExactMatch
def handle(self, e: QKeyEvent, *,
dry_run: bool = False) -> QKeySequence.SequenceMatch:
@@ -217,18 +217,18 @@ class HintKeyParser(basekeyparser.BaseKeyParser):
assert not dry_run
if (self._command_parser.handle(e, dry_run=True) !=
- QKeySequence.NoMatch):
+ QKeySequence.SequenceMatch.NoMatch):
log.keyboard.debug("Handling key via command parser")
self.clear_keystring()
return self._command_parser.handle(e)
match = super().handle(e)
- if match == QKeySequence.PartialMatch:
+ if match == QKeySequence.SequenceMatch.PartialMatch:
self._last_press = LastPress.keystring
- elif match == QKeySequence.ExactMatch:
+ elif match == QKeySequence.SequenceMatch.ExactMatch:
self._last_press = LastPress.none
- elif match == QKeySequence.NoMatch:
+ elif match == QKeySequence.SequenceMatch.NoMatch:
# We couldn't find a keychain so we check if it's a special key.
return self._handle_filter_key(e)
else:
@@ -278,12 +278,18 @@ class RegisterKeyParser(CommandKeyParser):
dry_run: bool = False) -> QKeySequence.SequenceMatch:
"""Override to always match the next key and use the register."""
match = super().handle(e, dry_run=dry_run)
- if match or dry_run:
+ if match != QKeySequence.SequenceMatch.NoMatch or dry_run:
return match
- if keyutils.is_special(Qt.Key(e.key()), e.modifiers()):
+ try:
+ info = keyutils.KeyInfo.from_event(e)
+ except keyutils.InvalidKeyError as ex:
+ # See https://github.com/qutebrowser/qutebrowser/issues/7047
+ log.keyboard.debug(f"Got invalid key: {ex}")
+ return QKeySequence.SequenceMatch.NoMatch
+ if info.is_special():
# this is not a proper register key, let it pass and keep going
- return QKeySequence.NoMatch
+ return QKeySequence.SequenceMatch.NoMatch
key = e.text()
@@ -307,4 +313,4 @@ class RegisterKeyParser(CommandKeyParser):
self.request_leave.emit(
self._register_mode, "valid register key", True)
- return QKeySequence.ExactMatch
+ return QKeySequence.SequenceMatch.ExactMatch
diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py
index 51c765551..4b01dadfd 100644
--- a/qutebrowser/mainwindow/mainwindow.py
+++ b/qutebrowser/mainwindow/mainwindow.py
@@ -23,12 +23,12 @@ import binascii
import base64
import itertools
import functools
-from typing import List, MutableSequence, Optional, Tuple, cast
+from typing import List, MutableSequence, Optional, Tuple
-from PyQt5.QtCore import (pyqtBoundSignal, pyqtSlot, QRect, QPoint, QTimer, Qt,
+from qutebrowser.qt.core import (pyqtBoundSignal, pyqtSlot, QRect, QPoint, QTimer, Qt,
QCoreApplication, QEventLoop, QByteArray)
-from PyQt5.QtWidgets import QWidget, QVBoxLayout, QSizePolicy
-from PyQt5.QtGui import QPalette
+from qutebrowser.qt.widgets import QWidget, QVBoxLayout, QSizePolicy
+from qutebrowser.qt.gui import QPalette
from qutebrowser.commands import runners
from qutebrowser.api import cmdutils
@@ -48,7 +48,7 @@ win_id_gen = itertools.count(0)
def get_window(*, via_ipc: bool,
target: str,
- no_raise: bool = False) -> int:
+ no_raise: bool = False) -> "MainWindow":
"""Helper function for app.py to get a window id.
Args:
@@ -58,47 +58,43 @@ def get_window(*, via_ipc: bool,
no_raise: suppress target window raising
Return:
- ID of a window that was used to open URL
+ The MainWindow that was used to open URL
"""
if not via_ipc:
# Initial main window
- return 0
+ return objreg.get("main-window", scope="window", window=0)
window = None
- should_raise = False
# Try to find the existing tab target if opening in a tab
if target not in {'window', 'private-window'}:
window = get_target_window()
- should_raise = target not in {'tab-silent', 'tab-bg-silent'}
+ window.should_raise = target not in {'tab-silent', 'tab-bg-silent'} and not no_raise
is_private = target == 'private-window'
# Otherwise, or if no window was found, create a new one
if window is None:
window = MainWindow(private=is_private)
- window.show()
- should_raise = True
+ window.should_raise = not no_raise
- if should_raise and not no_raise:
- raise_window(window)
-
- return window.win_id
+ return window
def raise_window(window, alert=True):
"""Raise the given MainWindow object."""
- window.setWindowState(window.windowState() & ~Qt.WindowMinimized)
- window.setWindowState(window.windowState() | Qt.WindowActive)
+ window.setWindowState(window.windowState() & ~Qt.WindowState.WindowMinimized)
+ window.setWindowState(window.windowState() | Qt.WindowState.WindowActive)
window.raise_()
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-69568
QCoreApplication.processEvents(
- QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers)
+ QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents | QEventLoop.ProcessEventsFlag.ExcludeSocketNotifiers)
- if not sip.isdeleted(window):
+ if sip.isdeleted(window):
# Could be deleted by the events run above
- window.activateWindow()
+ return
+ window.activateWindow()
if alert:
objects.qapp.alert(window)
@@ -132,6 +128,8 @@ class MainWindow(QWidget):
status: The StatusBar widget.
tabbed_browser: The TabbedBrowser widget.
state_before_fullscreen: window state before activation of fullscreen.
+ should_raise: Whether the window should be raised/activated when maybe_raise()
+ gets called.
_downloadview: The DownloadView widget.
_download_model: The DownloadModel instance.
_vbox: The main QVBoxLayout.
@@ -202,10 +200,10 @@ class MainWindow(QWidget):
from qutebrowser.mainwindow import tabbedbrowser
from qutebrowser.mainwindow.statusbar import bar
- self.setAttribute(Qt.WA_DeleteOnClose)
+ self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
if config.val.window.transparent:
- self.setAttribute(Qt.WA_TranslucentBackground)
- self.palette().setColor(QPalette.Window, Qt.transparent)
+ self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
+ self.palette().setColor(QPalette.ColorRole.Window, Qt.GlobalColor.transparent)
self._overlays: MutableSequence[_OverlayInfoType] = []
self.win_id = next(win_id_gen)
@@ -279,6 +277,8 @@ class MainWindow(QWidget):
self._set_decoration(config.val.window.hide_decoration)
self.state_before_fullscreen = self.windowState()
+ self.should_raise: bool = False
+
stylesheet.set_register(self)
def _init_geometry(self, geometry):
@@ -305,7 +305,7 @@ class MainWindow(QWidget):
if not widget.isVisible():
return
- if widget.sizePolicy().horizontalPolicy() == QSizePolicy.Expanding:
+ if widget.sizePolicy().horizontalPolicy() == QSizePolicy.Policy.Expanding:
width = self.width() - 2 * padding
if widget.hasHeightForWidth():
height = widget.heightForWidth(width)
@@ -564,13 +564,15 @@ class MainWindow(QWidget):
def _set_decoration(self, hidden):
"""Set the visibility of the window decoration via Qt."""
- window_flags = cast(Qt.WindowFlags, Qt.Window)
+ window_flags = Qt.WindowType.Window
refresh_window = self.isVisible()
if hidden:
- window_flags |= Qt.CustomizeWindowHint | Qt.NoDropShadowWindowHint
+ modifiers = Qt.WindowType.CustomizeWindowHint | Qt.WindowType.NoDropShadowWindowHint
+ window_flags |= modifiers # type: ignore[assignment]
self.setWindowFlags(window_flags)
- if utils.is_mac and hidden:
+ if utils.is_mac and hidden and not qtutils.version_check('6.3', compiled=False):
+ # WORKAROUND for https://codereview.qt-project.org/c/qt/qtbase/+/371279
from ctypes import c_void_p
# pylint: disable=import-error
from objc import objc_object
@@ -586,7 +588,7 @@ class MainWindow(QWidget):
if not config.val.content.fullscreen.window:
if on:
self.state_before_fullscreen = self.windowState()
- self.setWindowState(Qt.WindowFullScreen | self.state_before_fullscreen)
+ self.setWindowState(Qt.WindowState.WindowFullScreen | self.state_before_fullscreen)
elif self.isFullScreen():
self.setWindowState(self.state_before_fullscreen)
log.misc.debug('on: {}, state before fullscreen: {}'.format(
@@ -663,6 +665,12 @@ class MainWindow(QWidget):
return True
+ def maybe_raise(self) -> None:
+ """Raise the window if self.should_raise is set."""
+ if self.should_raise:
+ raise_window(self)
+ self.should_raise = False
+
def closeEvent(self, e):
"""Override closeEvent to display a confirmation if needed."""
if crashsignal.crash_handler.is_crashing:
diff --git a/qutebrowser/mainwindow/messageview.py b/qutebrowser/mainwindow/messageview.py
index b3df0211a..d76a8b0e2 100644
--- a/qutebrowser/mainwindow/messageview.py
+++ b/qutebrowser/mainwindow/messageview.py
@@ -21,8 +21,8 @@
from typing import MutableSequence, Optional
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QTimer, Qt
-from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QSizePolicy
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, QTimer, Qt
+from qutebrowser.qt.widgets import QWidget, QVBoxLayout, QLabel, QSizePolicy
from qutebrowser.config import config, stylesheet
from qutebrowser.utils import usertypes, message
@@ -43,7 +43,7 @@ class Message(QLabel):
super().__init__(text, parent)
self.replace = replace
self.level = level
- self.setAttribute(Qt.WA_StyledBackground, True)
+ self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
self.setWordWrap(True)
self.setTextFormat(text_format)
qss = """
@@ -114,7 +114,7 @@ class MessageView(QWidget):
self._vbox = QVBoxLayout(self)
self._vbox.setContentsMargins(0, 0, 0, 0)
self._vbox.setSpacing(0)
- self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+ self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
self._clear_timer = QTimer()
self._clear_timer.timeout.connect(self.clear_messages)
@@ -173,5 +173,5 @@ class MessageView(QWidget):
def mousePressEvent(self, e):
"""Clear messages when they are clicked on."""
- if e.button() in [Qt.LeftButton, Qt.MiddleButton, Qt.RightButton]:
+ if e.button() in [Qt.MouseButton.LeftButton, Qt.MouseButton.MiddleButton, Qt.MouseButton.RightButton]:
self.clear_messages()
diff --git a/qutebrowser/mainwindow/prompt.py b/qutebrowser/mainwindow/prompt.py
index c5acaabda..c1ad82990 100644
--- a/qutebrowser/mainwindow/prompt.py
+++ b/qutebrowser/mainwindow/prompt.py
@@ -26,11 +26,12 @@ import functools
import dataclasses
from typing import Deque, MutableSequence, Optional, cast
-from PyQt5.QtCore import (pyqtSlot, pyqtSignal, Qt, QTimer, QDir, QModelIndex,
+from qutebrowser.qt.core import (pyqtSlot, pyqtSignal, Qt, QTimer, QDir, QModelIndex,
QItemSelectionModel, QObject, QEventLoop)
-from PyQt5.QtWidgets import (QWidget, QGridLayout, QVBoxLayout, QLineEdit,
- QLabel, QFileSystemModel, QTreeView, QSizePolicy,
+from qutebrowser.qt.widgets import (QWidget, QGridLayout, QVBoxLayout, QLineEdit,
+ QLabel, QTreeView, QSizePolicy,
QSpacerItem)
+from qutebrowser.qt.gui import QFileSystemModel
from qutebrowser.browser import downloads
from qutebrowser.config import config, configtypes, configexc, stylesheet
@@ -130,20 +131,12 @@ class PromptQueue(QObject):
"""Cancel all blocking questions.
Quits and removes all running event loops.
-
- Return:
- True if loops needed to be aborted,
- False otherwise.
"""
- log.prompt.debug("Shutting down with loops {}".format(self._loops))
+ log.prompt.debug(f"Shutting down with loops {self._loops}")
self._shutting_down = True
- if self._loops:
- for loop in self._loops:
- loop.quit()
- loop.deleteLater()
- return True
- else:
- return False
+ for loop in self._loops:
+ loop.quit()
+ loop.deleteLater()
@pyqtSlot(usertypes.Question, bool)
def ask_question(self, question, blocking):
@@ -195,9 +188,8 @@ class PromptQueue(QObject):
question.completed.connect(loop.quit)
question.completed.connect(loop.deleteLater)
log.prompt.debug("Starting loop.exec() for {}".format(question))
- flags = cast(QEventLoop.ProcessEventsFlags,
- QEventLoop.ExcludeSocketNotifiers)
- loop.exec(flags)
+ flags = QEventLoop.ProcessEventsFlag.ExcludeSocketNotifiers
+ loop.exec(flags) # type: ignore[arg-type]
log.prompt.debug("Ending loop.exec() for {}".format(question))
log.prompt.debug("Restoring old question {}".format(old_question))
@@ -293,7 +285,7 @@ class PromptContainer(QWidget):
self._prompt: Optional[_BasePrompt] = None
self.setObjectName('PromptContainer')
- self.setAttribute(Qt.WA_StyledBackground, True)
+ self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
stylesheet.set_register(self)
message.global_bridge.prompt_done.connect(self._on_prompt_done)
@@ -504,11 +496,11 @@ class LineEdit(QLineEdit):
background-color: transparent;
}
""")
- self.setAttribute(Qt.WA_MacShowFocusRect, False)
+ self.setAttribute(Qt.WidgetAttribute.WA_MacShowFocusRect, False)
def keyPressEvent(self, e):
"""Override keyPressEvent to paste primary selection on Shift + Ins."""
- if e.key() == Qt.Key_Insert and e.modifiers() == Qt.ShiftModifier:
+ if e.key() == Qt.Key.Key_Insert and e.modifiers() == Qt.KeyboardModifier.ShiftModifier:
try:
text = utils.get_clipboard(selection=True, fallback=True)
except utils.ClipboardError: # pragma: no cover
@@ -549,7 +541,7 @@ class _BasePrompt(QWidget):
# Not doing any HTML escaping here as the text can be formatted
text_label = QLabel(question.text)
text_label.setWordWrap(True)
- text_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
+ text_label.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse)
self._vbox.addWidget(text_label)
def _init_key_label(self):
@@ -584,7 +576,7 @@ class _BasePrompt(QWidget):
self._key_grid.addWidget(key_label, i, 0)
self._key_grid.addWidget(text_label, i, 1)
- spacer = QSpacerItem(0, 0, QSizePolicy.Expanding)
+ spacer = QSpacerItem(0, 0, QSizePolicy.Policy.Expanding)
self._key_grid.addItem(spacer, 0, 2)
self._vbox.addLayout(self._key_grid)
@@ -666,7 +658,7 @@ class FilenamePrompt(_BasePrompt):
self._set_fileview_root(question.default)
if config.val.prompt.filebrowser:
- self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
+ self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
self._to_complete = ''
self._root_index = QModelIndex()
@@ -821,8 +813,8 @@ class FilenamePrompt(_BasePrompt):
selmodel.setCurrentIndex(
idx,
- QItemSelectionModel.ClearAndSelect |
- QItemSelectionModel.Rows)
+ QItemSelectionModel.SelectionFlag.ClearAndSelect |
+ QItemSelectionModel.SelectionFlag.Rows)
self._insert_path(idx, clicked=False)
def _do_completion(self, idx, which):
@@ -845,7 +837,7 @@ class DownloadFilenamePrompt(FilenamePrompt):
def __init__(self, question, parent=None):
super().__init__(question, parent)
self._file_model.setFilter(
- QDir.AllDirs | QDir.Drives | QDir.NoDotAndDotDot)
+ QDir.Filter.AllDirs | QDir.Filter.Drives | QDir.Filter.NoDotAndDotDot)
def accept(self, value=None, save=False):
done = super().accept(value, save)
@@ -890,7 +882,7 @@ class AuthenticationPrompt(_BasePrompt):
password_label = QLabel("Password:", self)
self._password_lineedit = LineEdit(self)
- self._password_lineedit.setEchoMode(QLineEdit.Password)
+ self._password_lineedit.setEchoMode(QLineEdit.EchoMode.Password)
grid = QGridLayout()
grid.addWidget(user_label, 1, 0)
@@ -1025,4 +1017,4 @@ def init():
global prompt_queue
prompt_queue = PromptQueue()
message.global_bridge.ask_question.connect( # type: ignore[call-arg]
- prompt_queue.ask_question, Qt.DirectConnection)
+ prompt_queue.ask_question, Qt.ConnectionType.DirectConnection)
diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py
index 7e5a8ff2c..eb65a0928 100644
--- a/qutebrowser/mainwindow/statusbar/bar.py
+++ b/qutebrowser/mainwindow/statusbar/bar.py
@@ -22,8 +22,8 @@
import enum
import dataclasses
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, pyqtProperty, Qt, QSize, QTimer
-from PyQt5.QtWidgets import QWidget, QHBoxLayout, QStackedLayout, QSizePolicy
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, pyqtProperty, Qt, QSize, QTimer
+from qutebrowser.qt.widgets import QWidget, QHBoxLayout, QStackedLayout, QSizePolicy
from qutebrowser.browser import browsertab
from qutebrowser.config import config, stylesheet
@@ -165,10 +165,10 @@ class StatusBar(QWidget):
def __init__(self, *, win_id, private, parent=None):
super().__init__(parent)
self.setObjectName(self.__class__.__name__)
- self.setAttribute(Qt.WA_StyledBackground)
+ self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground)
stylesheet.set_register(self)
- self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
+ self.setSizePolicy(QSizePolicy.Policy.Ignored, QSizePolicy.Policy.Fixed)
self._win_id = win_id
self._color_flags = ColorFlags()
diff --git a/qutebrowser/mainwindow/statusbar/clock.py b/qutebrowser/mainwindow/statusbar/clock.py
index 20587a5ac..ebab152b7 100644
--- a/qutebrowser/mainwindow/statusbar/clock.py
+++ b/qutebrowser/mainwindow/statusbar/clock.py
@@ -20,7 +20,7 @@
"""Clock displayed in the statusbar."""
from datetime import datetime
-from PyQt5.QtCore import Qt, QTimer
+from qutebrowser.qt.core import Qt, QTimer
from qutebrowser.mainwindow.statusbar import textbase
@@ -32,7 +32,7 @@ class Clock(textbase.TextBase):
UPDATE_DELAY = 500 # ms
def __init__(self, parent=None):
- super().__init__(parent, elidemode=Qt.ElideNone)
+ super().__init__(parent, elidemode=Qt.TextElideMode.ElideNone)
self.format = ""
self.timer = QTimer(self)
diff --git a/qutebrowser/mainwindow/statusbar/command.py b/qutebrowser/mainwindow/statusbar/command.py
index 95076380a..df85d0dfa 100644
--- a/qutebrowser/mainwindow/statusbar/command.py
+++ b/qutebrowser/mainwindow/statusbar/command.py
@@ -21,9 +21,9 @@
from typing import Optional
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QSize
-from PyQt5.QtGui import QKeyEvent
-from PyQt5.QtWidgets import QSizePolicy, QWidget
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, Qt, QSize
+from qutebrowser.qt.gui import QKeyEvent
+from qutebrowser.qt.widgets import QSizePolicy, QWidget
from qutebrowser.keyinput import modeman, modeparsers
from qutebrowser.api import cmdutils
@@ -70,7 +70,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
command_history = objreg.get('command-history')
self.history.history = command_history.data
self.history.changed.connect(command_history.changed)
- self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
+ self.setSizePolicy(QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Ignored)
self.cursorPositionChanged.connect(self.update_completion)
self.textChanged.connect(self.update_completion)
@@ -260,12 +260,12 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
without command_accept to be called.
"""
text = self.text()
- if text in modeparsers.STARTCHARS and e.key() == Qt.Key_Backspace:
+ if text in modeparsers.STARTCHARS and e.key() == Qt.Key.Key_Backspace:
e.accept()
modeman.leave(self._win_id, usertypes.KeyMode.command,
'prefix deleted')
return
- if e.key() == Qt.Key_Return:
+ if e.key() == Qt.Key.Key_Return:
e.ignore()
return
else:
diff --git a/qutebrowser/mainwindow/statusbar/keystring.py b/qutebrowser/mainwindow/statusbar/keystring.py
index 590dbda93..ed8b56318 100644
--- a/qutebrowser/mainwindow/statusbar/keystring.py
+++ b/qutebrowser/mainwindow/statusbar/keystring.py
@@ -19,7 +19,7 @@
"""Keychain string displayed in the statusbar."""
-from PyQt5.QtCore import pyqtSlot
+from qutebrowser.qt.core import pyqtSlot
from qutebrowser.mainwindow.statusbar import textbase
from qutebrowser.utils import usertypes
diff --git a/qutebrowser/mainwindow/statusbar/percentage.py b/qutebrowser/mainwindow/statusbar/percentage.py
index 122a4d4b4..6ecdc4659 100644
--- a/qutebrowser/mainwindow/statusbar/percentage.py
+++ b/qutebrowser/mainwindow/statusbar/percentage.py
@@ -19,7 +19,7 @@
"""Scroll percentage displayed in the statusbar."""
-from PyQt5.QtCore import pyqtSlot, Qt
+from qutebrowser.qt.core import pyqtSlot, Qt
from qutebrowser.mainwindow.statusbar import textbase
from qutebrowser.misc import throttle
@@ -32,7 +32,7 @@ class Percentage(textbase.TextBase):
def __init__(self, parent=None):
"""Constructor. Set percentage to 0%."""
- super().__init__(parent, elidemode=Qt.ElideNone)
+ super().__init__(parent, elidemode=Qt.TextElideMode.ElideNone)
self._strings = self._calc_strings()
self._set_text = throttle.Throttle(self.setText, 100, parent=self)
self.set_perc(0, 0)
diff --git a/qutebrowser/mainwindow/statusbar/progress.py b/qutebrowser/mainwindow/statusbar/progress.py
index 9d56cd03f..f76367b38 100644
--- a/qutebrowser/mainwindow/statusbar/progress.py
+++ b/qutebrowser/mainwindow/statusbar/progress.py
@@ -19,8 +19,8 @@
"""The progress bar in the statusbar."""
-from PyQt5.QtCore import pyqtSlot, QSize
-from PyQt5.QtWidgets import QProgressBar, QSizePolicy
+from qutebrowser.qt.core import pyqtSlot, QSize
+from qutebrowser.qt.widgets import QProgressBar, QSizePolicy
from qutebrowser.config import stylesheet
from qutebrowser.utils import utils, usertypes
@@ -47,7 +47,7 @@ class Progress(QProgressBar):
super().__init__(parent)
stylesheet.set_register(self)
self.enabled = False
- self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+ self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
self.setTextVisible(False)
self.hide()
diff --git a/qutebrowser/mainwindow/statusbar/searchmatch.py b/qutebrowser/mainwindow/statusbar/searchmatch.py
index 61baedf70..7c9a5b05e 100644
--- a/qutebrowser/mainwindow/statusbar/searchmatch.py
+++ b/qutebrowser/mainwindow/statusbar/searchmatch.py
@@ -20,7 +20,7 @@
"""The search match indicator in the statusbar."""
-from PyQt5.QtCore import pyqtSlot
+from qutebrowser.qt.core import pyqtSlot
from qutebrowser.browser import browsertab
from qutebrowser.mainwindow.statusbar import textbase
diff --git a/qutebrowser/mainwindow/statusbar/tabindex.py b/qutebrowser/mainwindow/statusbar/tabindex.py
index 635d3817b..e41501123 100644
--- a/qutebrowser/mainwindow/statusbar/tabindex.py
+++ b/qutebrowser/mainwindow/statusbar/tabindex.py
@@ -19,7 +19,7 @@
"""TabIndex displayed in the statusbar."""
-from PyQt5.QtCore import pyqtSlot
+from qutebrowser.qt.core import pyqtSlot
from qutebrowser.mainwindow.statusbar import textbase
diff --git a/qutebrowser/mainwindow/statusbar/textbase.py b/qutebrowser/mainwindow/statusbar/textbase.py
index cb454b902..9ab4b9753 100644
--- a/qutebrowser/mainwindow/statusbar/textbase.py
+++ b/qutebrowser/mainwindow/statusbar/textbase.py
@@ -19,9 +19,9 @@
"""Base text widgets for statusbar."""
-from PyQt5.QtCore import Qt
-from PyQt5.QtWidgets import QLabel, QSizePolicy
-from PyQt5.QtGui import QPainter
+from qutebrowser.qt.core import Qt
+from qutebrowser.qt.widgets import QLabel, QSizePolicy
+from qutebrowser.qt.gui import QPainter
from qutebrowser.utils import qtutils, utils
@@ -40,9 +40,9 @@ class TextBase(QLabel):
_elided_text: The current elided text.
"""
- def __init__(self, parent=None, elidemode=Qt.ElideRight):
+ def __init__(self, parent=None, elidemode=Qt.TextElideMode.ElideRight):
super().__init__(parent)
- self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
+ self.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Minimum)
self._elidemode = elidemode
self._elided_text = ''
@@ -57,7 +57,7 @@ class TextBase(QLabel):
"""
if self.text():
self._elided_text = self.fontMetrics().elidedText(
- self.text(), self._elidemode, width, Qt.TextShowMnemonic)
+ self.text(), self._elidemode, width, Qt.TextFlag.TextShowMnemonic)
else:
self._elided_text = ''
@@ -68,7 +68,7 @@ class TextBase(QLabel):
txt: The text to set (string).
"""
super().setText(txt)
- if self._elidemode != Qt.ElideNone:
+ if self._elidemode != Qt.TextElideMode.ElideNone:
self._update_elided_text(self.geometry().width())
def resizeEvent(self, e):
@@ -80,7 +80,7 @@ class TextBase(QLabel):
def paintEvent(self, e):
"""Override QLabel::paintEvent to draw elided text."""
- if self._elidemode == Qt.ElideNone:
+ if self._elidemode == Qt.TextElideMode.ElideNone:
super().paintEvent(e)
else:
e.accept()
diff --git a/qutebrowser/mainwindow/statusbar/url.py b/qutebrowser/mainwindow/statusbar/url.py
index a971d76aa..27a2b2133 100644
--- a/qutebrowser/mainwindow/statusbar/url.py
+++ b/qutebrowser/mainwindow/statusbar/url.py
@@ -21,7 +21,7 @@
import enum
-from PyQt5.QtCore import pyqtSlot, pyqtProperty, QUrl
+from qutebrowser.qt.core import pyqtSlot, pyqtProperty, QUrl
from qutebrowser.mainwindow.statusbar import textbase
from qutebrowser.config import stylesheet
diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py
index c623ce809..ca6409ba0 100644
--- a/qutebrowser/mainwindow/tabbedbrowser.py
+++ b/qutebrowser/mainwindow/tabbedbrowser.py
@@ -27,16 +27,16 @@ import dataclasses
from typing import (
Any, Deque, List, Mapping, MutableMapping, MutableSequence, Optional, Tuple)
-from PyQt5.QtWidgets import QSizePolicy, QWidget, QApplication
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QTimer, QUrl, QPoint
+from qutebrowser.qt.widgets import QSizePolicy, QWidget, QApplication
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QTimer, QUrl, QPoint
from qutebrowser.config import config
from qutebrowser.keyinput import modeman
from qutebrowser.mainwindow import tabwidget, mainwindow
from qutebrowser.browser import signalfilter, browsertab, history
-from qutebrowser.utils import (log, usertypes, utils, qtutils, objreg,
+from qutebrowser.utils import (log, usertypes, utils, qtutils,
urlutils, message, jinja, version)
-from qutebrowser.misc import quitter
+from qutebrowser.misc import quitter, objects
@dataclasses.dataclass
@@ -225,11 +225,16 @@ class TabbedBrowser(QWidget):
self.widget.currentChanged.connect(self._on_current_changed)
self.cur_fullscreen_requested.connect(self.widget.tab_bar().maybe_hide)
- self.widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ self.widget.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
- # load_finished instead of load_started as WORKAROUND for
- # https://bugreports.qt.io/browse/QTBUG-65223
- self.cur_load_finished.connect(self._leave_modes_on_load)
+ if (
+ objects.backend == usertypes.Backend.QtWebEngine and
+ version.qtwebengine_versions().webengine < utils.VersionNumber(5, 15, 5)
+ ):
+ # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-65223
+ self.cur_load_finished.connect(self._leave_modes_on_load)
+ else:
+ self.cur_load_started.connect(self._leave_modes_on_load)
# handle mode_override
self.current_tab_changed.connect(lambda tab: self._mode_override(tab.url()))
@@ -634,11 +639,10 @@ class TabbedBrowser(QWidget):
if config.val.tabs.tabs_are_windows and self.widget.count() > 0:
window = mainwindow.MainWindow(private=self.is_private)
+ tab = window.tabbed_browser.tabopen(
+ url=url, background=background, related=related)
window.show()
- tabbed_browser = objreg.get('tabbed-browser', scope='window',
- window=window.win_id)
- return tabbed_browser.tabopen(url=url, background=background,
- related=related)
+ return tab
tab = browsertab.create(win_id=self._win_id,
private=self.is_private,
@@ -1051,7 +1055,7 @@ class TabbedBrowser(QWidget):
"""
# strip the fragment as it may interfere with scrolling
try:
- url = self.current_url().adjusted(QUrl.RemoveFragment)
+ url = self.current_url().adjusted(QUrl.UrlFormattingOption.RemoveFragment)
except qtutils.QtValueError:
# show an error only if the mark is not automatically set
if key != "'":
@@ -1074,7 +1078,7 @@ class TabbedBrowser(QWidget):
"""
try:
# consider urls that differ only in fragment to be identical
- urlkey = self.current_url().adjusted(QUrl.RemoveFragment)
+ urlkey = self.current_url().adjusted(QUrl.UrlFormattingOption.RemoveFragment)
except qtutils.QtValueError:
urlkey = None
diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py
index f5446e963..5e4f519fa 100644
--- a/qutebrowser/mainwindow/tabwidget.py
+++ b/qutebrowser/mainwindow/tabwidget.py
@@ -24,12 +24,12 @@ import contextlib
import dataclasses
from typing import Optional, Dict, Any
-from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QSize, QRect, QPoint,
+from qutebrowser.qt.core import (pyqtSignal, pyqtSlot, Qt, QSize, QRect, QPoint,
QTimer, QUrl)
-from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
+from qutebrowser.qt.widgets import (QTabWidget, QTabBar, QSizePolicy, QProxyStyle,
QStyle, QStylePainter, QStyleOptionTab,
- QStyleFactory)
-from PyQt5.QtGui import QIcon, QPalette, QColor
+ QCommonStyle)
+from qutebrowser.qt.gui import QIcon, QPalette, QColor
from qutebrowser.utils import qtutils, objreg, utils, usertypes, log
from qutebrowser.config import config, stylesheet
@@ -65,7 +65,7 @@ class TabWidget(QTabWidget):
QTimer.singleShot, 0, self.update_tab_titles))
bar.currentChanged.connect(self._on_current_changed)
bar.new_tab_requested.connect(self._on_new_tab_requested)
- self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+ self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
self.setDocumentMode(True)
self.setUsesScrollButtons(True)
bar.setDrawBase(False)
@@ -83,7 +83,8 @@ class TabWidget(QTabWidget):
self.setElideMode(config.val.tabs.title.elide)
tabbar = self.tab_bar()
- tabbar.vertical = position in [QTabWidget.West, QTabWidget.East]
+ tabbar.vertical = position in [
+ QTabWidget.TabPosition.West, QTabWidget.TabPosition.East]
tabbar.setSelectionBehaviorOnRemove(selection_behavior)
tabbar.refresh()
@@ -366,7 +367,7 @@ class TabWidget(QTabWidget):
config.cache['tabs.pinned.shrink'] and
not self.tab_bar().vertical and
tab is not None and tab.data.pinned):
- icon = self.style().standardIcon(QStyle.SP_FileIcon)
+ icon = self.style().standardIcon(QStyle.StandardPixmap.SP_FileIcon)
super().setTabIcon(idx, icon)
@@ -554,8 +555,8 @@ class TabBar(QTabBar):
Also keep track of if we are currently in a drag."""
self.drag_in_progress = True
button = config.val.tabs.close_mouse_button
- if (e.button() == Qt.RightButton and button == 'right' or
- e.button() == Qt.MiddleButton and button == 'middle'):
+ if (e.button() == Qt.MouseButton.RightButton and button == 'right' or
+ e.button() == Qt.MouseButton.MiddleButton and button == 'middle'):
e.accept()
idx = self.tabAt(e.pos())
if idx == -1:
@@ -613,7 +614,7 @@ class TabBar(QTabBar):
def _text_to_width(text):
# Calculate text width taking into account qt mnemonics
- return self.fontMetrics().size(Qt.TextShowMnemonic, text).width()
+ return self.fontMetrics().size(Qt.TextFlag.TextShowMnemonic, text).width()
text_width = min(_text_to_width(text),
_text_to_width(tab_text))
padding = config.cache['tabs.padding']
@@ -714,14 +715,14 @@ class TabBar(QTabBar):
setting += '.selected'
setting += '.odd' if (idx + 1) % 2 else '.even'
- tab.palette.setColor(QPalette.Window,
+ tab.palette.setColor(QPalette.ColorRole.Window,
config.cache[setting + '.bg'])
- tab.palette.setColor(QPalette.WindowText,
+ tab.palette.setColor(QPalette.ColorRole.WindowText,
config.cache[setting + '.fg'])
indicator_color = self.tab_indicator_color(idx)
- tab.palette.setColor(QPalette.Base, indicator_color)
- p.drawControl(QStyle.CE_TabBarTab, tab)
+ tab.palette.setColor(QPalette.ColorRole.Base, indicator_color)
+ p.drawControl(QStyle.ControlElement.CE_TabBarTab, tab)
def tabInserted(self, idx):
"""Update visibility when a tab was inserted."""
@@ -774,7 +775,7 @@ class Layouts:
indicator: QRect
-class TabBarStyle(QCommonStyle):
+class TabBarStyle(QProxyStyle):
"""Qt style used by TabBar to fix some issues with the default one.
@@ -782,45 +783,10 @@ class TabBarStyle(QCommonStyle):
- Remove the focus rectangle Ubuntu draws on tabs.
- Force text to be left-aligned even though Qt has "centered"
hardcoded.
-
- Unfortunately PyQt doesn't support QProxyStyle, so we need to do this the
- hard way...
-
- Based on:
-
- https://stackoverflow.com/a/17294081
- https://code.google.com/p/makehuman/source/browse/trunk/makehuman/lib/qtgui.py
"""
ICON_PADDING = 4
- def __init__(self):
- """Initialize all functions we're not overriding.
-
- This simply calls the corresponding function in self._style.
- """
- self._style = QStyleFactory.create('Fusion')
- for method in ['drawComplexControl', 'drawItemPixmap',
- 'generatedIconPixmap', 'hitTestComplexControl',
- 'itemPixmapRect', 'itemTextRect', 'polish', 'styleHint',
- 'subControlRect', 'unpolish', 'drawItemText',
- 'sizeFromContents', 'drawPrimitive']:
- setattr(self, method, functools.partial(self._fusion_call, method))
- super().__init__()
-
- def _fusion_call(self, method: str, *args: Any) -> Any:
- """Wrap a call to self._style to log RuntimeErrors.
-
- WORKAROUND for https://github.com/qutebrowser/qutebrowser/issues/5124
- """
- target = getattr(self._style, method)
- try:
- return target(*args)
- except RuntimeError:
- info = f"self._style.{method}{args}"
- log.misc.warning(f"Got RuntimeError while calling {info}")
- raise
-
def _draw_indicator(self, layouts, opt, p):
"""Draw the tab indicator.
@@ -843,12 +809,12 @@ class TabBarStyle(QCommonStyle):
p: QPainter
"""
qtutils.ensure_valid(layouts.icon)
- icon_mode = (QIcon.Normal if opt.state & QStyle.State_Enabled
- else QIcon.Disabled)
- icon_state = (QIcon.On if opt.state & QStyle.State_Selected
- else QIcon.Off)
+ icon_mode = (QIcon.Mode.Normal if opt.state & QStyle.StateFlag.State_Enabled
+ else QIcon.Mode.Disabled)
+ icon_state = (QIcon.State.On if opt.state & QStyle.StateFlag.State_Selected
+ else QIcon.State.Off)
icon = opt.icon.pixmap(opt.iconSize, icon_mode, icon_state)
- self._style.drawItemPixmap(p, layouts.icon, Qt.AlignCenter, icon)
+ self.baseStyle().drawItemPixmap(p, layouts.icon, Qt.AlignmentFlag.AlignCenter, icon)
def drawControl(self, element, opt, p, widget=None):
"""Override drawControl to draw odd tabs in a different color.
@@ -862,10 +828,10 @@ class TabBarStyle(QCommonStyle):
p: QPainter
widget: QWidget
"""
- if element not in [QStyle.CE_TabBarTab, QStyle.CE_TabBarTabShape,
- QStyle.CE_TabBarTabLabel]:
+ if element not in [QStyle.ControlElement.CE_TabBarTab, QStyle.ControlElement.CE_TabBarTabShape,
+ QStyle.ControlElement.CE_TabBarTabLabel]:
# Let the real style draw it.
- self._style.drawControl(element, opt, p, widget)
+ self.baseStyle().drawControl(element, opt, p, widget)
return
layouts = self._tab_layout(opt)
@@ -873,28 +839,30 @@ class TabBarStyle(QCommonStyle):
log.misc.warning("Could not get layouts for tab!")
return
- if element == QStyle.CE_TabBarTab:
+ if element == QStyle.ControlElement.CE_TabBarTab:
# We override this so we can control TabBarTabShape/TabBarTabLabel.
- self.drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
- self.drawControl(QStyle.CE_TabBarTabLabel, opt, p, widget)
- elif element == QStyle.CE_TabBarTabShape:
+ self.drawControl(QStyle.ControlElement.CE_TabBarTabShape, opt, p, widget)
+ self.drawControl(QStyle.ControlElement.CE_TabBarTabLabel, opt, p, widget)
+ elif element == QStyle.ControlElement.CE_TabBarTabShape:
p.fillRect(opt.rect, opt.palette.window())
self._draw_indicator(layouts, opt, p)
- # We use super() rather than self._style here because we don't want
+ # We use QCommonStyle rather than self.baseStyle() here because we don't want
# any sophisticated drawing.
- super().drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
- elif element == QStyle.CE_TabBarTabLabel:
+ QCommonStyle.drawControl(self, QStyle.ControlElement.CE_TabBarTabShape, opt, p, widget)
+ elif element == QStyle.ControlElement.CE_TabBarTabLabel:
if not opt.icon.isNull() and layouts.icon.isValid():
self._draw_icon(layouts, opt, p)
alignment = (config.cache['tabs.title.alignment'] |
- Qt.AlignVCenter | Qt.TextHideMnemonic)
- self._style.drawItemText(p,
- layouts.text,
- int(alignment),
- opt.palette,
- bool(opt.state & QStyle.State_Enabled),
- opt.text,
- QPalette.WindowText)
+ Qt.AlignmentFlag.AlignVCenter | Qt.TextFlag.TextHideMnemonic)
+ self.baseStyle().drawItemText(
+ p,
+ layouts.text,
+ int(alignment),
+ opt.palette,
+ bool(opt.state & QStyle.StateFlag.State_Enabled),
+ opt.text,
+ QPalette.ColorRole.WindowText
+ )
else:
raise ValueError("Invalid element {!r}".format(element))
@@ -909,14 +877,14 @@ class TabBarStyle(QCommonStyle):
Return:
An int.
"""
- if metric in [QStyle.PM_TabBarTabShiftHorizontal,
- QStyle.PM_TabBarTabShiftVertical,
- QStyle.PM_TabBarTabHSpace,
- QStyle.PM_TabBarTabVSpace,
- QStyle.PM_TabBarScrollButtonWidth]:
+ if metric in [QStyle.PixelMetric.PM_TabBarTabShiftHorizontal,
+ QStyle.PixelMetric.PM_TabBarTabShiftVertical,
+ QStyle.PixelMetric.PM_TabBarTabHSpace,
+ QStyle.PixelMetric.PM_TabBarTabVSpace,
+ QStyle.PixelMetric.PM_TabBarScrollButtonWidth]:
return 0
else:
- return self._style.pixelMetric(metric, option, widget)
+ return self.baseStyle().pixelMetric(metric, option, widget)
def subElementRect(self, sr, opt, widget=None):
"""Override subElementRect to use our own _tab_layout implementation.
@@ -929,24 +897,24 @@ class TabBarStyle(QCommonStyle):
Return:
A QRect.
"""
- if sr == QStyle.SE_TabBarTabText:
+ if sr == QStyle.SubElement.SE_TabBarTabText:
layouts = self._tab_layout(opt)
if layouts is None:
log.misc.warning("Could not get layouts for tab!")
return QRect()
return layouts.text
- elif sr in [QStyle.SE_TabWidgetTabBar,
- QStyle.SE_TabBarScrollLeftButton]:
+ elif sr in [QStyle.SubElement.SE_TabWidgetTabBar,
+ QStyle.SubElement.SE_TabBarScrollLeftButton]:
# Handling SE_TabBarScrollLeftButton so the left scroll button is
# aligned properly. Otherwise, empty space will be shown after the
# last tab even though the button width is set to 0
#
- # Need to use super() because we also use super() to render
+ # Need to use QCommonStyle here because we also use it to render
# element in drawControl(); otherwise, we may get bit by
# style differences...
- return super().subElementRect(sr, opt, widget)
+ return QCommonStyle.subElementRect(self, sr, opt, widget)
else:
- return self._style.subElementRect(sr, opt, widget)
+ return self.baseStyle().subElementRect(sr, opt, widget)
def _tab_layout(self, opt):
"""Compute the text/icon rect from the opt rect.
@@ -993,7 +961,7 @@ class TabBarStyle(QCommonStyle):
text_rect.adjust(
icon_rect.width() + TabBarStyle.ICON_PADDING, 0, 0, 0)
- text_rect = self._style.visualRect(opt.direction, opt.rect, text_rect)
+ text_rect = self.baseStyle().visualRect(opt.direction, opt.rect, text_rect)
return Layouts(text=text_rect, icon=icon_rect,
indicator=indicator_rect)
@@ -1009,15 +977,15 @@ class TabBarStyle(QCommonStyle):
"""
icon_size = opt.iconSize
if not icon_size.isValid():
- icon_extent = self.pixelMetric(QStyle.PM_SmallIconSize)
+ icon_extent = self.pixelMetric(QStyle.PixelMetric.PM_SmallIconSize)
icon_size = QSize(icon_extent, icon_extent)
- icon_mode = (QIcon.Normal if opt.state & QStyle.State_Enabled
- else QIcon.Disabled)
- icon_state = (QIcon.On if opt.state & QStyle.State_Selected
- else QIcon.Off)
+ icon_mode = (QIcon.Mode.Normal if opt.state & QStyle.StateFlag.State_Enabled
+ else QIcon.Mode.Disabled)
+ icon_state = (QIcon.State.On if opt.state & QStyle.StateFlag.State_Selected
+ else QIcon.State.Off)
# reserve space for favicon when tab bar is vertical (issue #1968)
position = config.cache['tabs.position']
- if (position in [QTabWidget.East, QTabWidget.West] and
+ if (position in [QTabWidget.TabPosition.East, QTabWidget.TabPosition.West] and
config.cache['tabs.favicons.show'] != 'never'):
tab_icon_size = icon_size
else:
@@ -1028,5 +996,5 @@ class TabBarStyle(QCommonStyle):
icon_top = text_rect.center().y() + 1 - tab_icon_size.height() // 2
icon_rect = QRect(QPoint(text_rect.left(), icon_top), tab_icon_size)
- icon_rect = self._style.visualRect(opt.direction, opt.rect, icon_rect)
+ icon_rect = self.baseStyle().visualRect(opt.direction, opt.rect, icon_rect)
return icon_rect
diff --git a/qutebrowser/mainwindow/windowundo.py b/qutebrowser/mainwindow/windowundo.py
index ea7e1a987..80f47aaaa 100644
--- a/qutebrowser/mainwindow/windowundo.py
+++ b/qutebrowser/mainwindow/windowundo.py
@@ -23,7 +23,7 @@ import collections
import dataclasses
from typing import MutableSequence, cast, TYPE_CHECKING
-from PyQt5.QtCore import QObject, QByteArray
+from qutebrowser.qt.core import QObject, QByteArray
from qutebrowser.config import config
from qutebrowser.mainwindow import mainwindow
@@ -83,9 +83,9 @@ class WindowUndoManager(QObject):
private=False,
geometry=entry.geometry,
)
- window.show()
window.tabbed_browser.undo_stack = entry.tab_stack
window.tabbed_browser.undo()
+ window.show()
def init():
diff --git a/qutebrowser/misc/autoupdate.py b/qutebrowser/misc/autoupdate.py
index 73afdde54..ca21181c0 100644
--- a/qutebrowser/misc/autoupdate.py
+++ b/qutebrowser/misc/autoupdate.py
@@ -21,7 +21,7 @@
import json
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QObject, QUrl
from qutebrowser.misc import httpclient
diff --git a/qutebrowser/misc/backendproblem.py b/qutebrowser/misc/backendproblem.py
index 3e14719e0..4c0e184ac 100644
--- a/qutebrowser/misc/backendproblem.py
+++ b/qutebrowser/misc/backendproblem.py
@@ -27,12 +27,12 @@ import enum
import shutil
import argparse
import dataclasses
-from typing import Any, List, Sequence, Tuple, Optional
+from typing import Any, Optional, Sequence, Tuple
-from PyQt5.QtCore import Qt
-from PyQt5.QtWidgets import (QDialog, QPushButton, QHBoxLayout, QVBoxLayout, QLabel,
+from qutebrowser.qt.core import Qt
+from qutebrowser.qt.widgets import (QDialog, QPushButton, QHBoxLayout, QVBoxLayout, QLabel,
QMessageBox, QWidget)
-from PyQt5.QtNetwork import QSslSocket
+from qutebrowser.qt.network import QSslSocket
from qutebrowser.config import config, configfiles
from qutebrowser.utils import (usertypes, version, qtutils, log, utils,
@@ -44,10 +44,10 @@ class _Result(enum.IntEnum):
"""The result code returned by the backend problem dialog."""
- quit = QDialog.Accepted + 1
- restart = QDialog.Accepted + 2
- restart_webkit = QDialog.Accepted + 3
- restart_webengine = QDialog.Accepted + 4
+ quit = QDialog.DialogCode.Accepted + 1
+ restart = QDialog.DialogCode.Accepted + 2
+ restart_webkit = QDialog.DialogCode.Accepted + 3
+ restart_webengine = QDialog.DialogCode.Accepted + 4
@dataclasses.dataclass
@@ -71,27 +71,33 @@ def _other_backend(backend: usertypes.Backend) -> Tuple[usertypes.Backend, str]:
return (other_backend, other_setting)
-def _error_text(because: str, text: str, backend: usertypes.Backend) -> str:
+def _error_text(
+ because: str,
+ text: str,
+ backend: usertypes.Backend,
+ suggest_other_backend: bool = False,
+) -> str:
"""Get an error text for the given information."""
- other_backend, other_setting = _other_backend(backend)
- if other_backend == usertypes.Backend.QtWebKit:
- warning = ("<i>Note that QtWebKit hasn't been updated since "
- "July 2017 (including security updates).</i>")
- suffix = " (not recommended)"
- else:
- warning = ""
- suffix = ""
- return ("<b>Failed to start with the {backend} backend!</b>"
- "<p>qutebrowser tried to start with the {backend} backend but "
- "failed because {because}.</p>{text}"
- "<p><b>Forcing the {other_backend.name} backend{suffix}</b></p>"
- "<p>This forces usage of the {other_backend.name} backend by "
- "setting the <i>backend = '{other_setting}'</i> option "
- "(if you have a <i>config.py</i> file, you'll need to set "
- "this manually). {warning}</p>".format(
- backend=backend.name, because=because, text=text,
- other_backend=other_backend, other_setting=other_setting,
- warning=warning, suffix=suffix))
+ text = (f"<b>Failed to start with the {backend.name} backend!</b>"
+ f"<p>qutebrowser tried to start with the {backend.name} backend but "
+ f"failed because {because}.</p>{text}")
+
+ if suggest_other_backend:
+ other_backend, other_setting = _other_backend(backend)
+ if other_backend == usertypes.Backend.QtWebKit:
+ warning = ("<i>Note that QtWebKit hasn't been updated since "
+ "July 2017 (including security updates).</i>")
+ suffix = " (not recommended)"
+ else:
+ warning = ""
+ suffix = ""
+
+ text += (f"<p><b>Forcing the {other_backend.name} backend{suffix}</b></p>"
+ f"<p>This forces usage of the {other_backend.name} backend by "
+ f"setting the <i>backend = '{other_setting}'</i> option "
+ f"(if you have a <i>config.py</i> file, you'll need to set "
+ f"this manually). {warning}</p>")
+ return text
class _Dialog(QDialog):
@@ -101,17 +107,18 @@ class _Dialog(QDialog):
def __init__(self, *, because: str,
text: str,
backend: usertypes.Backend,
+ suggest_other_backend: bool = True,
buttons: Sequence[_Button] = None,
parent: QWidget = None) -> None:
super().__init__(parent)
vbox = QVBoxLayout(self)
- other_backend, other_setting = _other_backend(backend)
- text = _error_text(because, text, backend)
+ text = _error_text(because, text, backend,
+ suggest_other_backend=suggest_other_backend)
label = QLabel(text)
label.setWordWrap(True)
- label.setTextFormat(Qt.RichText)
+ label.setTextFormat(Qt.TextFormat.RichText)
vbox.addWidget(label)
hbox = QHBoxLayout()
@@ -121,13 +128,15 @@ class _Dialog(QDialog):
quit_button.clicked.connect(lambda: self.done(_Result.quit))
hbox.addWidget(quit_button)
- backend_text = "Force {} backend".format(other_backend.name)
- if other_backend == usertypes.Backend.QtWebKit:
- backend_text += ' (not recommended)'
- backend_button = QPushButton(backend_text)
- backend_button.clicked.connect(functools.partial(
- self._change_setting, 'backend', other_setting))
- hbox.addWidget(backend_button)
+ if suggest_other_backend:
+ other_backend, other_setting = _other_backend(backend)
+ backend_text = "Force {} backend".format(other_backend.name)
+ if other_backend == usertypes.Backend.QtWebKit:
+ backend_text += ' (not recommended)'
+ backend_button = QPushButton(backend_text)
+ backend_button.clicked.connect(functools.partial(
+ self._change_setting, 'backend', other_setting))
+ hbox.addWidget(backend_button)
for button in buttons:
btn = QPushButton(button.text)
@@ -181,7 +190,7 @@ class _BackendProblemChecker:
status = dialog.exec()
self._save_manager.save_all(is_exit=True)
- if status in [_Result.quit, QDialog.Rejected]:
+ if status in [_Result.quit, QDialog.DialogCode.Rejected]:
pass
elif status == _Result.restart_webkit:
quitter.instance.restart(override_args={'backend': 'webkit'})
@@ -194,95 +203,25 @@ class _BackendProblemChecker:
sys.exit(usertypes.Exit.err_init)
- def _xwayland_options(self) -> Tuple[str, List[_Button]]:
- """Get buttons/text for a possible XWayland solution."""
- buttons = []
- text = "<p>You can work around this in one of the following ways:</p>"
-
- if 'DISPLAY' in os.environ:
- # XWayland is available, but QT_QPA_PLATFORM=wayland is set
- buttons.append(
- _Button("Force XWayland", 'qt.force_platform', 'xcb'))
- text += ("<p><b>Force Qt to use XWayland</b></p>"
- "<p>This allows you to use the newer QtWebEngine backend "
- "(based on Chromium). "
- "This sets the <i>qt.force_platform = 'xcb'</i> option "
- "(if you have a <i>config.py</i> file, you'll need to "
- "set this manually).</p>")
- else:
- text += ("<p><b>Set up XWayland</b></p>"
- "<p>This allows you to use the newer QtWebEngine backend "
- "(based on Chromium). ")
-
- return text, buttons
-
- def _handle_wayland_webgl(self) -> None:
- """On older graphic hardware, WebGL on Wayland causes segfaults.
-
- See https://github.com/qutebrowser/qutebrowser/issues/5313
- """
- self._assert_backend(usertypes.Backend.QtWebEngine)
-
- if os.environ.get('QUTE_SKIP_WAYLAND_WEBGL_CHECK'):
- return
-
- platform = objects.qapp.platformName()
- if platform not in ['wayland', 'wayland-egl']:
- return
-
- # Only Qt 5.14 should be affected
- if not qtutils.version_check('5.14', compiled=False):
- return
- if qtutils.version_check('5.15', compiled=False):
- return
-
- # Newer graphic hardware isn't affected
- opengl_info = version.opengl_info()
- if (opengl_info is None or
- opengl_info.gles or
- opengl_info.version is None or
- opengl_info.version >= (4, 3)):
- return
-
- # If WebGL is turned off, we're fine
- if not config.val.content.webgl:
- return
-
- text, buttons = self._xwayland_options()
-
- buttons.append(_Button("Turn off WebGL (recommended)",
- 'content.webgl',
- False))
- text += ("<p><b>Disable WebGL (recommended)</b></p>"
- "This sets the <i>content.webgl = False</i> option "
- "(if you have a <i>config.py</i> file, you'll need to "
- "set this manually).</p>")
-
- self._show_dialog(backend=usertypes.Backend.QtWebEngine,
- because=("of frequent crashes with Qt 5.14 on "
- "Wayland with older graphics hardware"),
- text=text,
- buttons=buttons)
-
def _try_import_backends(self) -> _BackendImports:
"""Check whether backends can be imported and return BackendImports."""
# pylint: disable=unused-import
results = _BackendImports()
try:
- from PyQt5 import QtWebKit
- from PyQt5.QtWebKit import qWebKitVersion
- from PyQt5 import QtWebKitWidgets
+ from qutebrowser.qt import webkit, webkitwidgets
except (ImportError, ValueError) as e:
results.webkit_error = str(e)
+ assert results.webkit_error
else:
if not qtutils.is_new_qtwebkit():
results.webkit_error = "Unsupported legacy QtWebKit found"
try:
- from PyQt5 import QtWebEngineWidgets
+ from qutebrowser.qt import webenginecore, webenginewidgets
except (ImportError, ValueError) as e:
results.webengine_error = str(e)
+ assert results.webengine_error
return results
@@ -294,25 +233,14 @@ class _BackendProblemChecker:
if QSslSocket.supportsSsl():
return
- if qtutils.version_check('5.12.4'):
- version_text = ("If you use OpenSSL 1.0 with a PyQt package from "
- "PyPI (e.g. on Ubuntu 16.04), you will need to "
- "build OpenSSL 1.1 from sources and set "
- "LD_LIBRARY_PATH accordingly.")
- else:
- version_text = ("If you use OpenSSL 1.1 with a PyQt package from "
- "PyPI (e.g. on Archlinux or Debian Stretch), you "
- "need to set LD_LIBRARY_PATH to the path of "
- "OpenSSL 1.0 or use Qt >= 5.12.4.")
-
- text = ("Could not initialize QtNetwork SSL support. {} This only "
- "affects downloads and :adblock-update.".format(version_text))
+ text = ("Could not initialize QtNetwork SSL support. This only "
+ "affects downloads and :adblock-update.")
if fatal:
errbox = msgbox.msgbox(parent=None,
title="SSL error",
text="Could not initialize SSL support.",
- icon=QMessageBox.Critical,
+ icon=QMessageBox.Icon.Critical,
plain_text=False)
errbox.exec()
sys.exit(usertypes.Exit.err_init)
@@ -338,7 +266,7 @@ class _BackendProblemChecker:
errbox = msgbox.msgbox(parent=None,
title="No backend library found!",
text=text,
- icon=QMessageBox.Critical,
+ icon=QMessageBox.Icon.Critical,
plain_text=False)
errbox.exec()
sys.exit(usertypes.Exit.err_init)
@@ -363,26 +291,6 @@ class _BackendProblemChecker:
raise utils.Unreachable
- def _handle_cache_nuking(self) -> None:
- """Nuke the QtWebEngine cache if the Qt version changed.
-
- WORKAROUND for https://bugreports.qt.io/browse/QTBUG-72532
- """
- if not configfiles.state.qt_version_changed:
- return
-
- # Only nuke the cache in cases where we know there are problems.
- # It seems these issues started with Qt 5.12.
- # They should be fixed with Qt 5.12.5:
- # https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/265408
- if qtutils.version_check('5.12.5', compiled=False):
- return
-
- log.init.info("Qt version changed, nuking QtWebEngine cache")
- cache_dir = os.path.join(standarddir.cache(), 'webengine')
- if os.path.exists(cache_dir):
- shutil.rmtree(cache_dir)
-
def _handle_serviceworker_nuking(self) -> None:
"""Nuke the service workers directory if the Qt version changed.
@@ -391,13 +299,7 @@ class _BackendProblemChecker:
https://bugreports.qt.io/browse/QTBUG-82105
https://bugreports.qt.io/browse/QTBUG-93744
"""
- if ('serviceworker_workaround' not in configfiles.state['general'] and
- qtutils.version_check('5.14', compiled=False)):
- # Nuke the service worker directory once for every install with Qt
- # 5.14, given that it seems to cause a variety of segfaults.
- configfiles.state['general']['serviceworker_workaround'] = '514'
- reason = 'Qt 5.14'
- elif configfiles.state.qt_version_changed:
+ if configfiles.state.qt_version_changed:
reason = 'Qt version changed'
elif configfiles.state.qtwe_version_changed:
reason = 'QtWebEngine version changed'
@@ -422,6 +324,93 @@ class _BackendProblemChecker:
shutil.move(service_worker_dir, bak_dir)
+ def _confirm_chromium_version_changes(self) -> None:
+ """Ask if there are Chromium downgrades or a Qt 5 -> 6 upgrade."""
+ versions = version.qtwebengine_versions(avoid_init=True)
+ change = configfiles.state.chromium_version_changed
+ if change == configfiles.VersionChange.major:
+ # FIXME:qt6 Remove this before the release, as it typically should
+ # not concern users?
+ text = (
+ "Chromium/QtWebEngine upgrade detected:<br>"
+ f"You are <b>upgrading to QtWebEngine {versions.webengine}</b> but "
+ "used Qt 5 for the last qutebrowser launch.<br><br>"
+ "Data managed by Chromium will be upgraded. This is a <b>one-way "
+ "operation:</b> If you open qutebrowser with Qt 5 again later, any "
+ "Chromium data will be invalid and discarded.<br><br>"
+ "This affects page data such as cookies, but not data managed by "
+ "qutebrowser, such as your configuration or <tt>:open</tt> history."
+ )
+ elif change == configfiles.VersionChange.downgrade:
+ text = (
+ "Chromium/QtWebEngine downgrade detected:<br>"
+ f"You are <b>downgrading to QtWebEngine {versions.webengine}</b>."
+ "<br><br>"
+ "Data managed by Chromium will be discarded if you continue.<br><br>"
+ "This affects page data such as cookies, but not data managed by "
+ "qutebrowser, such as your configuration or <tt>:open</tt> history."
+ )
+ else:
+ return
+
+ box = msgbox.msgbox(
+ parent=None,
+ title="QtWebEngine version change",
+ text=text,
+ icon=QMessageBox.Icon.Warning,
+ plain_text=False,
+ buttons=QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Abort,
+ )
+ response = box.exec()
+ if response != QMessageBox.StandardButton.Ok:
+ sys.exit(usertypes.Exit.err_init)
+
+ def _check_webengine_version(self) -> None:
+ versions = version.qtwebengine_versions(avoid_init=True)
+ if versions.webengine < utils.VersionNumber(5, 15, 2):
+ text = (
+ "QtWebEngine >= 5.15.2 is required for qutebrowser, but "
+ f"{versions.webengine} is installed.")
+ errbox = msgbox.msgbox(parent=None,
+ title="QtWebEngine too old",
+ text=text,
+ icon=QMessageBox.Icon.Critical,
+ plain_text=False)
+ errbox.exec()
+ sys.exit(usertypes.Exit.err_init)
+
+ def _check_software_rendering(self) -> None:
+ """Avoid crashing software rendering settings.
+
+ WORKAROUND for https://bugreports.qt.io/browse/QTBUG-103372
+ Fixed with QtWebEngine 6.3.1.
+ """
+ self._assert_backend(usertypes.Backend.QtWebEngine)
+ versions = version.qtwebengine_versions(avoid_init=True)
+
+ if versions.webengine != utils.VersionNumber(6, 3):
+ return
+
+ if os.environ.get('QT_QUICK_BACKEND') != 'software':
+ return
+
+ text = ("You can instead force software rendering on the Chromium level (sets "
+ "<tt>qt.force_software_rendering</tt> to <tt>chromium</tt> instead of "
+ "<tt>qt-quick</tt>).")
+
+ button = _Button("Force Chromium software rendering",
+ 'qt.force_software_rendering',
+ 'chromium')
+ self._show_dialog(
+ backend=usertypes.Backend.QtWebEngine,
+ suggest_other_backend=False,
+ because="a Qt 6.3.0 bug causes instant crashes with Qt Quick software rendering",
+ text=text,
+ buttons=[button],
+ )
+
+ raise utils.Unreachable
+
def _assert_backend(self, backend: usertypes.Backend) -> None:
assert objects.backend == backend, objects.backend
@@ -429,10 +418,11 @@ class _BackendProblemChecker:
"""Run all checks."""
self._check_backend_modules()
if objects.backend == usertypes.Backend.QtWebEngine:
+ self._check_webengine_version()
self._handle_ssl_support()
- self._handle_wayland_webgl()
- self._handle_cache_nuking()
self._handle_serviceworker_nuking()
+ self._check_software_rendering()
+ self._confirm_chromium_version_changes()
else:
self._assert_backend(usertypes.Backend.QtWebKit)
self._handle_ssl_support(fatal=True)
diff --git a/qutebrowser/misc/cmdhistory.py b/qutebrowser/misc/cmdhistory.py
index e4218832c..cd880a0fc 100644
--- a/qutebrowser/misc/cmdhistory.py
+++ b/qutebrowser/misc/cmdhistory.py
@@ -21,7 +21,7 @@
from typing import MutableSequence
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, QObject
from qutebrowser.utils import usertypes, log, standarddir, objreg
from qutebrowser.misc import lineparser
diff --git a/qutebrowser/misc/consolewidget.py b/qutebrowser/misc/consolewidget.py
index a826a4ed8..b2c2b4571 100644
--- a/qutebrowser/misc/consolewidget.py
+++ b/qutebrowser/misc/consolewidget.py
@@ -23,9 +23,9 @@ import sys
import code
from typing import MutableSequence
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
-from PyQt5.QtWidgets import QTextEdit, QWidget, QVBoxLayout, QApplication
-from PyQt5.QtGui import QTextCursor
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, Qt
+from qutebrowser.qt.widgets import QTextEdit, QWidget, QVBoxLayout, QApplication
+from qutebrowser.qt.gui import QTextCursor
from qutebrowser.config import stylesheet
from qutebrowser.misc import cmdhistory, miscwidgets
@@ -92,13 +92,13 @@ class ConsoleLineEdit(miscwidgets.CommandLineEdit):
def keyPressEvent(self, e):
"""Override keyPressEvent to handle special keypresses."""
- if e.key() == Qt.Key_Up:
+ if e.key() == Qt.Key.Key_Up:
self.history_prev()
e.accept()
- elif e.key() == Qt.Key_Down:
+ elif e.key() == Qt.Key.Key_Down:
self.history_next()
e.accept()
- elif e.modifiers() & Qt.ControlModifier and e.key() == Qt.Key_C:
+ elif e.modifiers() & Qt.KeyboardModifier.ControlModifier and e.key() == Qt.Key.Key_C:
self.setText('')
e.accept()
else:
@@ -113,7 +113,7 @@ class ConsoleTextEdit(QTextEdit):
super().__init__(parent)
self.setAcceptRichText(False)
self.setReadOnly(True)
- self.setFocusPolicy(Qt.ClickFocus)
+ self.setFocusPolicy(Qt.FocusPolicy.ClickFocus)
def __repr__(self):
return utils.get_repr(self)
@@ -124,7 +124,7 @@ class ConsoleTextEdit(QTextEdit):
We can't use Qt's way to append stuff because that inserts weird
newlines.
"""
- self.moveCursor(QTextCursor.End)
+ self.moveCursor(QTextCursor.MoveOperation.End)
self.insertPlainText(text)
scrollbar = self.verticalScrollBar()
scrollbar.setValue(scrollbar.maximum())
diff --git a/qutebrowser/misc/crashdialog.py b/qutebrowser/misc/crashdialog.py
index 6c92e9fec..b3998cf27 100644
--- a/qutebrowser/misc/crashdialog.py
+++ b/qutebrowser/misc/crashdialog.py
@@ -30,8 +30,8 @@ import datetime
import enum
from typing import List, Tuple
-from PyQt5.QtCore import pyqtSlot, Qt, QSize
-from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton,
+from qutebrowser.qt.core import pyqtSlot, Qt, QSize
+from qutebrowser.qt.widgets import (QDialog, QLabel, QTextEdit, QPushButton,
QVBoxLayout, QHBoxLayout, QCheckBox,
QDialogButtonBox, QMessageBox)
@@ -47,8 +47,8 @@ class Result(enum.IntEnum):
"""The result code returned by the crash dialog."""
- restore = QDialog.Accepted + 1
- no_restore = QDialog.Accepted + 2
+ restore = QDialog.DialogCode.Accepted + 1
+ no_restore = QDialog.DialogCode.Accepted + 2
def parse_fatal_stacktrace(text):
@@ -149,7 +149,7 @@ class _CrashDialog(QDialog):
self._debug_log = QTextEdit()
self._debug_log.setTabChangesFocus(True)
self._debug_log.setAcceptRichText(False)
- self._debug_log.setLineWrapMode(QTextEdit.NoWrap)
+ self._debug_log.setLineWrapMode(QTextEdit.LineWrapMode.NoWrap)
self._debug_log.hide()
self._fold = miscwidgets.DetailFold("Show log", self)
self._fold.toggled.connect(self._debug_log.setVisible)
@@ -165,7 +165,7 @@ class _CrashDialog(QDialog):
def keyPressEvent(self, e):
"""Prevent closing :report dialogs when pressing <Escape>."""
- if config.val.input.escape_quits_reporter or e.key() != Qt.Key_Escape:
+ if config.val.input.escape_quits_reporter or e.key() != Qt.Key.Key_Escape:
super().keyPressEvent(e)
def __repr__(self):
@@ -201,7 +201,7 @@ class _CrashDialog(QDialog):
self._lbl = QLabel()
self._lbl.setWordWrap(True)
self._lbl.setOpenExternalLinks(True)
- self._lbl.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
+ self._lbl.setTextInteractionFlags(Qt.TextInteractionFlag.LinksAccessibleByMouse)
self._vbox.addWidget(self._lbl)
def _init_checkboxes(self):
@@ -215,12 +215,12 @@ class _CrashDialog(QDialog):
self._btn_report = QPushButton("Report")
self._btn_report.setDefault(True)
self._btn_report.clicked.connect(self.on_report_clicked)
- self._btn_box.addButton(self._btn_report, QDialogButtonBox.AcceptRole)
+ self._btn_box.addButton(self._btn_report, QDialogButtonBox.ButtonRole.AcceptRole)
self._btn_cancel = QPushButton("Don't report")
self._btn_cancel.setAutoDefault(False)
self._btn_cancel.clicked.connect(self.finish)
- self._btn_box.addButton(self._btn_cancel, QDialogButtonBox.RejectRole)
+ self._btn_box.addButton(self._btn_cancel, QDialogButtonBox.ButtonRole.RejectRole)
def _init_info_text(self):
"""Add an info text encouraging the user to report crashes."""
@@ -492,7 +492,7 @@ class FatalCrashDialog(_CrashDialog):
def __init__(self, debug, text, parent=None):
super().__init__(debug, parent)
self._log = text
- self.setAttribute(Qt.WA_DeleteOnClose)
+ self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
self._set_crash_info()
self._type, self._func = parse_fatal_stacktrace(self._log)
@@ -557,7 +557,7 @@ class FatalCrashDialog(_CrashDialog):
"spend on developing qutebrowser instead.\n\nPlease "
"help making qutebrowser better by providing more "
"information, or don't report this.",
- icon=QMessageBox.Critical)
+ icon=QMessageBox.Icon.Critical)
else:
super().on_report_clicked()
@@ -574,7 +574,7 @@ class ReportDialog(_CrashDialog):
def __init__(self, pages, cmdhist, qobjects, parent=None):
super().__init__(False, parent)
- self.setAttribute(Qt.WA_DeleteOnClose)
+ self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
self._pages = pages
self._cmdhist = cmdhist
self._qobjects = qobjects
diff --git a/qutebrowser/misc/crashsignal.py b/qutebrowser/misc/crashsignal.py
index a79118044..a0144e26d 100644
--- a/qutebrowser/misc/crashsignal.py
+++ b/qutebrowser/misc/crashsignal.py
@@ -32,9 +32,9 @@ import faulthandler
import dataclasses
from typing import TYPE_CHECKING, Optional, MutableMapping, cast, List
-from PyQt5.QtCore import (pyqtSlot, qInstallMessageHandler, QObject,
+from qutebrowser.qt.core import (pyqtSlot, qInstallMessageHandler, QObject,
QSocketNotifier, QTimer, QUrl)
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt.widgets import QApplication
from qutebrowser.api import cmdutils
from qutebrowser.misc import earlyinit, crashdialog, ipc, objects
@@ -135,7 +135,7 @@ class CrashHandler(QObject):
for tab in tabbed_browser.widgets():
try:
urlstr = tab.url().toString(
- QUrl.RemovePassword | QUrl.FullyEncoded)
+ QUrl.UrlFormattingOption.RemovePassword | QUrl.ComponentFormattingOption.FullyEncoded)
if urlstr:
win_pages.append(urlstr)
except Exception:
@@ -359,7 +359,7 @@ class SignalHandler(QObject):
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
self._notifier = QSocketNotifier(cast(sip.voidptr, read_fd),
- QSocketNotifier.Read,
+ QSocketNotifier.Type.Read,
self)
self._notifier.activated.connect(self.handle_signal_wakeup)
self._orig_wakeup_fd = signal.set_wakeup_fd(write_fd)
diff --git a/qutebrowser/misc/earlyinit.py b/qutebrowser/misc/earlyinit.py
index 286d4f071..ef7814ab1 100644
--- a/qutebrowser/misc/earlyinit.py
+++ b/qutebrowser/misc/earlyinit.py
@@ -78,8 +78,8 @@ def _die(message, exception=None):
message: The message to display.
exception: The exception object if we're handling an exception.
"""
- from PyQt5.QtWidgets import QApplication, QMessageBox
- from PyQt5.QtCore import Qt
+ from qutebrowser.qt.widgets import QApplication, QMessageBox
+ from qutebrowser.qt.core import Qt
if (('--debug' in sys.argv or '--no-err-windows' in sys.argv) and
exception is not None):
print(file=sys.stderr)
@@ -91,9 +91,9 @@ def _die(message, exception=None):
else:
if exception is not None:
message = message.replace('%ERROR%', str(exception))
- msgbox = QMessageBox(QMessageBox.Critical, "qutebrowser: Fatal error!",
+ msgbox = QMessageBox(QMessageBox.Icon.Critical, "qutebrowser: Fatal error!",
message)
- msgbox.setTextFormat(Qt.RichText)
+ msgbox.setTextFormat(Qt.TextFormat.RichText)
msgbox.resize(msgbox.sizeHint())
msgbox.exec()
app.quit()
@@ -138,7 +138,10 @@ def init_faulthandler(fileobj=sys.__stderr__):
def check_pyqt():
"""Check if PyQt core modules (QtCore/QtWidgets) are installed."""
- for name in ['PyQt5.QtCore', 'PyQt5.QtWidgets']:
+ from qutebrowser.qt import machinery
+
+ packages = [f'{machinery.PACKAGE}.QtCore', f'{machinery.PACKAGE}.QtWidgets']
+ for name in packages:
try:
importlib.import_module(name)
except ImportError as e:
@@ -162,10 +165,10 @@ def check_pyqt():
def qt_version(qversion=None, qt_version_str=None):
"""Get a Qt version string based on the runtime/compiled versions."""
if qversion is None:
- from PyQt5.QtCore import qVersion
+ from qutebrowser.qt.core import qVersion
qversion = qVersion()
if qt_version_str is None:
- from PyQt5.QtCore import QT_VERSION_STR
+ from qutebrowser.qt.core import QT_VERSION_STR
qt_version_str = QT_VERSION_STR
if qversion != qt_version_str:
@@ -174,33 +177,38 @@ def qt_version(qversion=None, qt_version_str=None):
return qversion
-def check_qt_version():
- """Check if the Qt version is recent enough."""
- from PyQt5.QtCore import QT_VERSION, PYQT_VERSION, PYQT_VERSION_STR
+def get_qt_version():
+ """Get the Qt version, or None if too old for QLibaryInfo.version()."""
try:
- from PyQt5.QtCore import QVersionNumber, QLibraryInfo
- qt_ver = QLibraryInfo.version().normalized()
- recent_qt_runtime = qt_ver >= QVersionNumber(5, 12) # type: ignore[operator]
+ from qutebrowser.qt.core import QLibraryInfo
+ return QLibraryInfo.version().normalized()
except (ImportError, AttributeError):
- # QVersionNumber was added in Qt 5.6, QLibraryInfo.version() in 5.8
- recent_qt_runtime = False
+ return None
+
- if QT_VERSION < 0x050C00 or PYQT_VERSION < 0x050C00 or not recent_qt_runtime:
- text = ("Fatal error: Qt >= 5.12.0 and PyQt >= 5.12.0 are required, "
+def check_qt_version():
+ """Check if the Qt version is recent enough."""
+ from qutebrowser.qt.core import QT_VERSION, PYQT_VERSION, PYQT_VERSION_STR
+ from qutebrowser.qt.core import QVersionNumber
+ qt_ver = get_qt_version()
+ recent_qt_runtime = qt_ver is not None and qt_ver >= QVersionNumber(5, 15)
+
+ if QT_VERSION < 0x050F00 or PYQT_VERSION < 0x050F00 or not recent_qt_runtime:
+ text = ("Fatal error: Qt >= 5.15.0 and PyQt >= 5.15.0 are required, "
"but Qt {} / PyQt {} is installed.".format(qt_version(),
PYQT_VERSION_STR))
_die(text)
- if qt_ver == QVersionNumber(5, 12, 0):
- from qutebrowser.utils import log
- log.init.warning("Running on Qt 5.12.0. Doing so is unsupported "
- "(newer 5.12.x versions are fine).")
+ if 0x060000 <= PYQT_VERSION < 0x060202:
+ text = ("Fatal error: With Qt 6, PyQt >= 6.2.2 is required, but "
+ "{} is installed.".format(PYQT_VERSION_STR))
+ _die(text)
def check_ssl_support():
"""Check if SSL support is available."""
try:
- from PyQt5.QtNetwork import QSslSocket # pylint: disable=unused-import
+ from qutebrowser.qt.network import QSslSocket # pylint: disable=unused-import
except ImportError:
_die("Fatal error: Your Qt is built without SSL support.")
@@ -232,21 +240,28 @@ def _check_modules(modules):
def check_libraries():
"""Check if all needed Python libraries are installed."""
+ from qutebrowser.qt import machinery
modules = {
'jinja2': _missing_str("jinja2"),
'yaml': _missing_str("PyYAML"),
- 'PyQt5.QtQml': _missing_str("PyQt5.QtQml"),
- 'PyQt5.QtSql': _missing_str("PyQt5.QtSql"),
- 'PyQt5.QtOpenGL': _missing_str("PyQt5.QtOpenGL"),
- 'PyQt5.QtDBus': _missing_str("PyQt5.QtDBus"),
}
+
+ for subpkg in ['QtQml', 'QtOpenGL', 'QtDBus']:
+ package = f'{machinery.PACKAGE}.{subpkg}'
+ modules[package] = _missing_str(package)
+
if sys.version_info < (3, 9):
# Backport required
modules['importlib_resources'] = _missing_str("importlib_resources")
+
if sys.platform.startswith('darwin'):
- # Used for resizable hide_decoration windows on macOS
- modules['objc'] = _missing_str("pyobjc-core")
- modules['AppKit'] = _missing_str("pyobjc-framework-Cocoa")
+ from qutebrowser.qt.core import QVersionNumber
+ qt_ver = get_qt_version()
+ if qt_ver is not None and qt_ver < QVersionNumber(6, 3):
+ # Used for resizable hide_decoration windows on macOS
+ modules['objc'] = _missing_str("pyobjc-core")
+ modules['AppKit'] = _missing_str("pyobjc-framework-Cocoa")
+
_check_modules(modules)
@@ -256,17 +271,17 @@ def configure_pyqt():
Doing this means we can't use the interactive shell anymore (which we don't
anyways), but we can use pdb instead.
"""
- from PyQt5 import QtCore
- QtCore.pyqtRemoveInputHook()
+ from qutebrowser.qt.core import pyqtRemoveInputHook
+ pyqtRemoveInputHook()
+
+ from qutebrowser.qt import sip
try:
- QtCore.pyqt5_enable_new_onexit_scheme(True) # type: ignore[attr-defined]
+ sip.enableoverflowchecking(True)
except AttributeError:
- # Added in PyQt 5.13 somewhere, going to be the default in 5.14
+ # default in PyQt6
+ # FIXME:qt6 solve this in qutebrowser/qt/sip.py equivalent?
pass
- from qutebrowser.qt import sip
- sip.enableoverflowchecking(True)
-
def init_log(args):
"""Initialize logging.
@@ -297,7 +312,7 @@ def webengine_early_import():
error messages in backendproblem.py are accurate.
"""
try:
- from PyQt5 import QtWebEngineWidgets # pylint: disable=unused-import
+ from qutebrowser.qt import webenginewidgets # pylint: disable=unused-import
except ImportError:
pass
diff --git a/qutebrowser/misc/editor.py b/qutebrowser/misc/editor.py
index a4bc1d8ab..1c4c6ca03 100644
--- a/qutebrowser/misc/editor.py
+++ b/qutebrowser/misc/editor.py
@@ -22,7 +22,7 @@
import os
import tempfile
-from PyQt5.QtCore import (pyqtSignal, pyqtSlot, QObject, QProcess,
+from qutebrowser.qt.core import (pyqtSignal, pyqtSlot, QObject, QProcess,
QFileSystemWatcher)
from qutebrowser.config import config
@@ -105,7 +105,7 @@ class ExternalEditor(QObject):
return
log.procs.debug("Editor closed")
- if exitstatus != QProcess.NormalExit:
+ if exitstatus != QProcess.ExitStatus.NormalExit:
# No error/cleanup here, since we already handle this in
# on_proc_error.
return
diff --git a/qutebrowser/misc/elf.py b/qutebrowser/misc/elf.py
index 8fadbcffd..49a88b398 100644
--- a/qutebrowser/misc/elf.py
+++ b/qutebrowser/misc/elf.py
@@ -67,9 +67,8 @@ import mmap
import pathlib
from typing import Any, IO, ClassVar, Dict, Optional, Tuple, cast
-from PyQt5.QtCore import QLibraryInfo
-
-from qutebrowser.utils import log, version
+from qutebrowser.qt import machinery
+from qutebrowser.utils import log, version, qtutils
class ParseError(Exception):
@@ -269,17 +268,46 @@ def _find_versions(data: bytes) -> Versions:
Note that 'data' can actually be a mmap.mmap, but typing doesn't handle that
correctly: https://github.com/python/typeshed/issues/1467
"""
- match = re.search(
- br'\x00QtWebEngine/([0-9.]+) Chrome/([0-9.]+)\x00',
- data,
- )
+ pattern = br'\x00QtWebEngine/([0-9.]+) Chrome/([0-9.]+)\x00'
+ match = re.search(pattern, data)
+ if match is not None:
+ try:
+ return Versions(
+ webengine=match.group(1).decode('ascii'),
+ chromium=match.group(2).decode('ascii'),
+ )
+ except UnicodeDecodeError as e:
+ raise ParseError(e)
+
+ # Here it gets even more crazy: Sometimes, we don't have the full UA in one piece
+ # in the string table somehow (?!). However, Qt 6.2 added a separate
+ # qWebEngineChromiumVersion(), with PyQt wrappers following later. And *that*
+ # apperently stores the full version in the string table separately from the UA.
+ # As we clearly didn't have enough crazy heuristics yet so far, let's hunt for it!
+
+ # We first get the partial Chromium version from the UA:
+ match = re.search(pattern[:-4], data) # without trailing literal \x00
if match is None:
raise ParseError("No match in .rodata")
+ webengine_bytes = match.group(1)
+ partial_chromium_bytes = match.group(2)
+ if b"." not in partial_chromium_bytes or len(partial_chromium_bytes) < 6:
+ # some sanity checking
+ raise ParseError("Inconclusive partial Chromium bytes")
+
+ # And then try to find the *full* string, stored separately, based on the
+ # partial one we got above.
+ pattern = br"\x00(" + re.escape(partial_chromium_bytes) + br"[0-9.]+)\x00"
+ match = re.search(pattern, data)
+ if match is None:
+ raise ParseError("No match in .rodata for full version")
+
+ chromium_bytes = match.group(1)
try:
return Versions(
- webengine=match.group(1).decode('ascii'),
- chromium=match.group(2).decode('ascii'),
+ webengine=webengine_bytes.decode('ascii'),
+ chromium=chromium_bytes.decode('ascii'),
)
except UnicodeDecodeError as e:
raise ParseError(e)
@@ -314,9 +342,10 @@ def parse_webenginecore() -> Optional[Versions]:
# Flatpak has Qt in /usr/lib/x86_64-linux-gnu, but QtWebEngine in /app/lib.
library_path = pathlib.Path("/app/lib")
else:
- library_path = pathlib.Path(QLibraryInfo.location(QLibraryInfo.LibrariesPath))
+ library_path = qtutils.library_path(qtutils.LibraryPath.libraries)
- library_name = sorted(library_path.glob('libQt5WebEngineCore.so*'))
+ suffix = "6" if machinery.IS_QT6 else "5"
+ library_name = sorted(library_path.glob(f'libQt{suffix}WebEngineCore.so*'))
if not library_name:
log.misc.debug(f"No QtWebEngine .so found in {library_path}")
return None
diff --git a/qutebrowser/misc/guiprocess.py b/qutebrowser/misc/guiprocess.py
index 772417023..3a6ab156a 100644
--- a/qutebrowser/misc/guiprocess.py
+++ b/qutebrowser/misc/guiprocess.py
@@ -25,7 +25,7 @@ import shlex
import shutil
from typing import Mapping, Sequence, Dict, Optional
-from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QObject, QProcess,
+from qutebrowser.qt.core import (pyqtSlot, pyqtSignal, QObject, QProcess,
QProcessEnvironment, QByteArray, QUrl, Qt)
from qutebrowser.utils import message, log, utils, usertypes, version
@@ -94,7 +94,7 @@ class ProcessOutcome:
"""
assert self.status is not None, "Process didn't finish yet"
assert self.code is not None
- return self.status == QProcess.NormalExit and self.code == 0
+ return self.status == QProcess.ExitStatus.NormalExit and self.code == 0
def __str__(self) -> str:
if self.running:
@@ -105,12 +105,12 @@ class ProcessOutcome:
assert self.status is not None
assert self.code is not None
- if self.status == QProcess.CrashExit:
+ if self.status == QProcess.ExitStatus.CrashExit:
return f"{self.what.capitalize()} crashed."
elif self.was_successful():
return f"{self.what.capitalize()} exited successfully."
- assert self.status == QProcess.NormalExit
+ assert self.status == QProcess.ExitStatus.NormalExit
# We call this 'status' here as it makes more sense to the user -
# it's actually 'code'.
return f"{self.what.capitalize()} exited with status {self.code}."
@@ -124,7 +124,7 @@ class ProcessOutcome:
return 'running'
elif self.status is None:
return 'not started'
- elif self.status == QProcess.CrashExit:
+ elif self.status == QProcess.ExitStatus.CrashExit:
return 'crashed'
elif self.was_successful():
return 'successful'
@@ -177,7 +177,7 @@ class GUIProcess(QObject):
self.stderr: str = ""
self._cleanup_timer = usertypes.Timer(self, 'process-cleanup')
- self._cleanup_timer.setTimerType(Qt.VeryCoarseTimer)
+ self._cleanup_timer.setTimerType(Qt.TimerType.VeryCoarseTimer)
self._cleanup_timer.setInterval(3600 * 1000) # 1h
self._cleanup_timer.timeout.connect(self._on_cleanup_timer)
self._cleanup_timer.setSingleShot(True)
@@ -254,17 +254,17 @@ class GUIProcess(QObject):
@pyqtSlot(QProcess.ProcessError)
def _on_error(self, error: QProcess.ProcessError) -> None:
"""Show a message if there was an error while spawning."""
- if error == QProcess.Crashed and not utils.is_windows:
+ if error == QProcess.ProcessError.Crashed and not utils.is_windows:
# Already handled via ExitStatus in _on_finished
return
what = f"{self.what} {self.cmd!r}"
error_descriptions = {
- QProcess.FailedToStart: f"{what.capitalize()} failed to start",
- QProcess.Crashed: f"{what.capitalize()} crashed",
- QProcess.Timedout: f"{what.capitalize()} timed out",
- QProcess.WriteError: f"Write error for {what}",
- QProcess.ReadError: f"Read error for {what}",
+ QProcess.ProcessError.FailedToStart: f"{what.capitalize()} failed to start",
+ QProcess.ProcessError.Crashed: f"{what.capitalize()} crashed",
+ QProcess.ProcessError.Timedout: f"{what.capitalize()} timed out",
+ QProcess.ProcessError.WriteError: f"Write error for {what}",
+ QProcess.ProcessError.ReadError: f"Read error for {what}",
}
# We can't get some kind of error code from Qt...
diff --git a/qutebrowser/misc/httpclient.py b/qutebrowser/misc/httpclient.py
index d4a8e7673..da205ae50 100644
--- a/qutebrowser/misc/httpclient.py
+++ b/qutebrowser/misc/httpclient.py
@@ -23,8 +23,8 @@ import functools
import urllib.parse
from typing import MutableMapping
-from PyQt5.QtCore import pyqtSignal, QObject, QTimer
-from PyQt5.QtNetwork import (QNetworkAccessManager, QNetworkRequest,
+from qutebrowser.qt.core import pyqtSignal, QObject, QTimer
+from qutebrowser.qt.network import (QNetworkAccessManager, QNetworkRequest,
QNetworkReply)
from qutebrowser.utils import log
@@ -35,8 +35,8 @@ class HTTPRequest(QNetworkRequest):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
- self.setAttribute(QNetworkRequest.RedirectPolicyAttribute,
- QNetworkRequest.NoLessSafeRedirectPolicy)
+ self.setAttribute(QNetworkRequest.Attribute.RedirectPolicyAttribute,
+ QNetworkRequest.RedirectPolicy.NoLessSafeRedirectPolicy)
class HTTPClient(QObject):
@@ -78,7 +78,7 @@ class HTTPClient(QObject):
data = {}
encoded_data = urllib.parse.urlencode(data).encode('utf-8')
request = HTTPRequest(url)
- request.setHeader(QNetworkRequest.ContentTypeHeader,
+ request.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader,
'application/x-www-form-urlencoded;charset=utf-8')
reply = self._nam.post(request, encoded_data)
self._handle_reply(reply)
@@ -118,7 +118,7 @@ class HTTPClient(QObject):
if timer is not None:
timer.stop()
timer.deleteLater()
- if reply.error() != QNetworkReply.NoError:
+ if reply.error() != QNetworkReply.NetworkError.NoError:
self.error.emit(reply.errorString())
return
try:
diff --git a/qutebrowser/misc/ipc.py b/qutebrowser/misc/ipc.py
index 8c5c05046..c94c67b29 100644
--- a/qutebrowser/misc/ipc.py
+++ b/qutebrowser/misc/ipc.py
@@ -26,11 +26,11 @@ import getpass
import binascii
import hashlib
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, Qt
-from PyQt5.QtNetwork import QLocalSocket, QLocalServer, QAbstractSocket
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QObject, Qt
+from qutebrowser.qt.network import QLocalSocket, QLocalServer, QAbstractSocket
import qutebrowser
-from qutebrowser.utils import log, usertypes, error, standarddir, utils
+from qutebrowser.utils import log, usertypes, error, standarddir, utils, debug
from qutebrowser.qt import sip
@@ -107,12 +107,12 @@ class SocketError(Error):
"""
super().__init__()
self.action = action
- self.code = socket.error()
- self.message = socket.errorString()
+ self.code: QLocalSocket.LocalSocketError = socket.error()
+ self.message: str = socket.errorString()
def __str__(self):
- return "Error while {}: {} (error {})".format(
- self.action, self.message, self.code)
+ return "Error while {}: {} ({})".format(
+ self.action, self.message, debug.qenum_key(QLocalSocket, self.code))
class ListenError(Error):
@@ -131,12 +131,12 @@ class ListenError(Error):
local_server: The QLocalServer which has the error set.
"""
super().__init__()
- self.code = local_server.serverError()
- self.message = local_server.errorString()
+ self.code: QAbstractSocket.SocketError = local_server.serverError()
+ self.message: str = local_server.errorString()
def __str__(self):
- return "Error while listening to IPC server: {} (error {})".format(
- self.message, self.code)
+ return "Error while listening to IPC server: {} ({})".format(
+ self.message, debug.qenum_key(QAbstractSocket, self.code))
class AddressInUseError(ListenError):
@@ -188,7 +188,7 @@ class IPCServer(QObject):
self._atime_timer = usertypes.Timer(self, 'ipc-atime')
self._atime_timer.setInterval(ATIME_INTERVAL)
self._atime_timer.timeout.connect(self.update_atime)
- self._atime_timer.setTimerType(Qt.VeryCoarseTimer)
+ self._atime_timer.setTimerType(Qt.TimerType.VeryCoarseTimer)
self._server = QLocalServer(self)
self._server.newConnection.connect(self.handle_connection)
@@ -204,7 +204,7 @@ class IPCServer(QObject):
# Thus, we only do so on Windows, and handle permissions manually in
# listen() on Linux.
log.ipc.debug("Calling setSocketOptions")
- self._server.setSocketOptions(QLocalServer.UserAccessOption)
+ self._server.setSocketOptions(QLocalServer.SocketOption.UserAccessOption)
else: # pragma: no cover
log.ipc.debug("Not calling setSocketOptions")
@@ -223,7 +223,7 @@ class IPCServer(QObject):
self._remove_server()
ok = self._server.listen(self._socketname)
if not ok:
- if self._server.serverError() == QAbstractSocket.AddressInUseError:
+ if self._server.serverError() == QAbstractSocket.SocketError.AddressInUseError:
raise AddressInUseError(self._server)
raise ListenError(self._server)
@@ -248,7 +248,7 @@ class IPCServer(QObject):
log.ipc.debug("Socket 0x{:x}: error {}: {}".format(
id(self._socket), self._socket.error(),
self._socket.errorString()))
- if err != QLocalSocket.PeerClosedError:
+ if err != QLocalSocket.LocalSocketError.PeerClosedError:
raise SocketError("handling IPC connection", self._socket)
@pyqtSlot()
@@ -273,13 +273,17 @@ class IPCServer(QObject):
if socket.canReadLine():
log.ipc.debug("We can read a line immediately.")
self.on_ready_read()
- socket.error.connect(self.on_error)
+
+ socket.errorOccurred.connect(self.on_error)
+
if socket.error() not in [ # type: ignore[operator]
- QLocalSocket.UnknownSocketError, QLocalSocket.PeerClosedError]:
+ QLocalSocket.LocalSocketError.UnknownSocketError,
+ QLocalSocket.LocalSocketError.PeerClosedError
+ ]:
log.ipc.debug("We got an error immediately.")
self.on_error(socket.error()) # type: ignore[operator]
socket.disconnected.connect(self.on_disconnected)
- if socket.state() == QLocalSocket.UnconnectedState:
+ if socket.state() == QLocalSocket.LocalSocketState.UnconnectedState:
log.ipc.debug("Socket was disconnected immediately.")
self.on_disconnected()
@@ -302,7 +306,7 @@ class IPCServer(QObject):
log.ipc.error("Ignoring invalid IPC data from socket 0x{:x}.".format(
id(self._socket)))
self.got_invalid_data.emit()
- self._socket.error.connect(self.on_error)
+ self._socket.errorOccurred.connect(self.on_error)
self._socket.disconnectFromServer()
def _handle_data(self, data):
@@ -490,18 +494,18 @@ def send_to_running_instance(socketname, command, target_arg, *, socket=None):
log.ipc.debug("Writing: {!r}".format(data))
socket.writeData(data)
socket.waitForBytesWritten(WRITE_TIMEOUT)
- if socket.error() != QLocalSocket.UnknownSocketError:
+ if socket.error() != QLocalSocket.LocalSocketError.UnknownSocketError:
raise SocketError("writing to running instance", socket)
socket.disconnectFromServer()
- if socket.state() != QLocalSocket.UnconnectedState:
+ if socket.state() != QLocalSocket.LocalSocketState.UnconnectedState:
socket.waitForDisconnected(CONNECT_TIMEOUT)
return True
else:
- if socket.error() not in [QLocalSocket.ConnectionRefusedError,
- QLocalSocket.ServerNotFoundError]:
+ if socket.error() not in [QLocalSocket.LocalSocketError.ConnectionRefusedError,
+ QLocalSocket.LocalSocketError.ServerNotFoundError]:
raise SocketError("connecting to running instance", socket)
- log.ipc.debug("No existing instance present (error {})".format(
- socket.error()))
+ log.ipc.debug("No existing instance present ({})".format(
+ debug.qenum_key(QLocalSocket, socket.error())))
return False
diff --git a/qutebrowser/misc/keyhintwidget.py b/qutebrowser/misc/keyhintwidget.py
index c93ce5d4b..cdfed8392 100644
--- a/qutebrowser/misc/keyhintwidget.py
+++ b/qutebrowser/misc/keyhintwidget.py
@@ -27,8 +27,9 @@ It is intended to help discoverability of keybindings.
import html
import re
-from PyQt5.QtWidgets import QLabel, QSizePolicy
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt
+from qutebrowser.qt.widgets import QLabel, QSizePolicy
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, Qt
+from qutebrowser.qt.gui import QKeySequence
from qutebrowser.config import config, stylesheet
from qutebrowser.utils import utils, usertypes
@@ -64,9 +65,9 @@ class KeyHintView(QLabel):
def __init__(self, win_id, parent=None):
super().__init__(parent)
- self.setTextFormat(Qt.RichText)
+ self.setTextFormat(Qt.TextFormat.RichText)
self._win_id = win_id
- self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum)
+ self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum)
self.hide()
self._show_timer = usertypes.Timer(self, 'keyhint_show')
self._show_timer.timeout.connect(self.show)
@@ -109,10 +110,13 @@ class KeyHintView(QLabel):
return cmd and cmd.takes_count()
bindings_dict = config.key_instance.get_bindings_for(mode.name)
- bindings = [(k, v) for (k, v) in sorted(bindings_dict.items())
- if keyutils.KeySequence.parse(prefix).matches(k) and
- not blacklisted(str(k)) and
- (takes_count(v) or not countstr)]
+ bindings = [
+ (k, v)
+ for (k, v) in sorted(bindings_dict.items())
+ if keyutils.KeySequence.parse(prefix).matches(k) != QKeySequence.SequenceMatch.NoMatch
+ and not blacklisted(str(k))
+ and (takes_count(v) or not countstr)
+ ]
if not bindings:
self._show_timer.stop()
diff --git a/qutebrowser/misc/lineparser.py b/qutebrowser/misc/lineparser.py
index fee87354f..a270798b5 100644
--- a/qutebrowser/misc/lineparser.py
+++ b/qutebrowser/misc/lineparser.py
@@ -24,7 +24,7 @@ import os.path
import contextlib
from typing import Sequence
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, QObject
from qutebrowser.utils import log, utils, qtutils
from qutebrowser.config import config
diff --git a/qutebrowser/misc/miscwidgets.py b/qutebrowser/misc/miscwidgets.py
index 4354ed2ab..5d56f7fcf 100644
--- a/qutebrowser/misc/miscwidgets.py
+++ b/qutebrowser/misc/miscwidgets.py
@@ -21,14 +21,13 @@
from typing import Optional
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QSize, QTimer
-from PyQt5.QtWidgets import (QLineEdit, QWidget, QHBoxLayout, QLabel,
- QStyleOption, QStyle, QLayout, QApplication,
- QSplitter)
-from PyQt5.QtGui import QValidator, QPainter, QResizeEvent
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, Qt, QSize, QTimer
+from qutebrowser.qt.widgets import (QLineEdit, QWidget, QHBoxLayout, QLabel,
+ QStyleOption, QStyle, QLayout, QSplitter)
+from qutebrowser.qt.gui import QValidator, QPainter, QResizeEvent
from qutebrowser.config import config, configfiles
-from qutebrowser.utils import utils, log, usertypes
+from qutebrowser.utils import utils, log, usertypes, debug
from qutebrowser.misc import cmdhistory
from qutebrowser.browser import inspector
from qutebrowser.keyinput import keyutils, modeman
@@ -49,11 +48,11 @@ class MinimalLineEditMixin:
"""
)
self.setAttribute( # type: ignore[attr-defined]
- Qt.WA_MacShowFocusRect, False)
+ Qt.WidgetAttribute.WA_MacShowFocusRect, False)
def keyPressEvent(self, e):
"""Override keyPressEvent to paste primary selection on Shift + Ins."""
- if e.key() == Qt.Key_Insert and e.modifiers() == Qt.ShiftModifier:
+ if e.key() == Qt.Key.Key_Insert and e.modifiers() == Qt.KeyboardModifier.ShiftModifier:
try:
text = utils.get_clipboard(selection=True, fallback=True)
except utils.ClipboardError:
@@ -137,9 +136,9 @@ class _CommandValidator(QValidator):
A tuple (status, string, pos) as a QValidator should.
"""
if self.prompt is None or string.startswith(self.prompt):
- return (QValidator.Acceptable, string, pos)
+ return (QValidator.State.Acceptable, string, pos)
else:
- return (QValidator.Invalid, string, pos)
+ return (QValidator.State.Invalid, string, pos)
class DetailFold(QWidget):
@@ -181,7 +180,7 @@ class DetailFold(QWidget):
Args:
e: The QMouseEvent.
"""
- if e.button() == Qt.LeftButton:
+ if e.button() == Qt.MouseButton.LeftButton:
e.accept()
self.toggle()
else:
@@ -219,9 +218,9 @@ class _FoldArrow(QWidget):
opt.initFrom(self)
painter = QPainter(self)
if self._folded:
- elem = QStyle.PE_IndicatorArrowRight
+ elem = QStyle.PrimitiveElement.PE_IndicatorArrowRight
else:
- elem = QStyle.PE_IndicatorArrowDown
+ elem = QStyle.PrimitiveElement.PE_IndicatorArrowDown
self.style().drawPrimitive(elem, opt, painter, self)
def minimumSizeHint(self):
@@ -309,7 +308,7 @@ class FullscreenNotification(QLabel):
if config.val.content.fullscreen.window:
geom = self.parentWidget().geometry()
else:
- geom = QApplication.desktop().screenGeometry(self)
+ geom = self.window().windowHandle().screen().geometry()
self.move((geom.width() - self.sizeHint().width()) // 2, 30)
def set_timeout(self, timeout):
@@ -387,10 +386,10 @@ class InspectorSplitter(QSplitter):
self._inspector_idx = 0
self._main_idx = 1
- self.setOrientation(Qt.Horizontal
+ self.setOrientation(Qt.Orientation.Horizontal
if position in [inspector.Position.left,
inspector.Position.right]
- else Qt.Vertical)
+ else Qt.Orientation.Vertical)
self.insertWidget(self._inspector_idx, inspector_widget)
self._position = position
self._load_preferred_size()
@@ -405,7 +404,7 @@ class InspectorSplitter(QSplitter):
def _load_preferred_size(self) -> None:
"""Load the preferred size of the inspector widget."""
assert self._position is not None
- full = (self.width() if self.orientation() == Qt.Horizontal
+ full = (self.width() if self.orientation() == Qt.Orientation.Horizontal
else self.height())
# If we first open the inspector with a window size of < 300px
@@ -489,7 +488,7 @@ class KeyTesterWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
- self.setAttribute(Qt.WA_DeleteOnClose)
+ self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
self._layout = QHBoxLayout(self)
self._label = QLabel(text="Waiting for keypress...")
self._layout.addWidget(self._label)
@@ -499,8 +498,8 @@ class KeyTesterWidget(QWidget):
lines = [
str(keyutils.KeyInfo.from_event(e)),
'',
- 'key: 0x{:x}'.format(int(e.key())),
- 'modifiers: 0x{:x}'.format(int(e.modifiers())),
+ f"key: {debug.qenum_key(Qt.Key, e.key(), klass=Qt.Key)}",
+ f"modifiers: {debug.qflags_key(Qt.KeyboardModifier, e.modifiers())}",
'text: {!r}'.format(e.text()),
]
self._label.setText('\n'.join(lines))
diff --git a/qutebrowser/misc/msgbox.py b/qutebrowser/misc/msgbox.py
index 4271c2639..45ad2d44a 100644
--- a/qutebrowser/misc/msgbox.py
+++ b/qutebrowser/misc/msgbox.py
@@ -19,8 +19,8 @@
"""Convenience functions to show message boxes."""
-from PyQt5.QtCore import Qt
-from PyQt5.QtWidgets import QMessageBox
+from qutebrowser.qt.core import Qt
+from qutebrowser.qt.widgets import QMessageBox
from qutebrowser.misc import objects
from qutebrowser.utils import log
@@ -34,7 +34,7 @@ class DummyBox:
pass
-def msgbox(parent, title, text, *, icon, buttons=QMessageBox.Ok,
+def msgbox(parent, title, text, *, icon, buttons=QMessageBox.StandardButton.Ok,
on_finished=None, plain_text=None):
"""Display a QMessageBox with the given icon.
@@ -56,15 +56,15 @@ def msgbox(parent, title, text, *, icon, buttons=QMessageBox.Ok,
return DummyBox()
box = QMessageBox(parent)
- box.setAttribute(Qt.WA_DeleteOnClose)
+ box.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
box.setIcon(icon)
box.setStandardButtons(buttons)
if on_finished is not None:
box.finished.connect(on_finished)
if plain_text:
- box.setTextFormat(Qt.PlainText)
+ box.setTextFormat(Qt.TextFormat.PlainText)
elif plain_text is not None:
- box.setTextFormat(Qt.RichText)
+ box.setTextFormat(Qt.TextFormat.RichText)
box.setWindowTitle(title)
box.setText(text)
box.show()
@@ -81,4 +81,4 @@ def information(*args, **kwargs):
Return:
A new QMessageBox.
"""
- return msgbox(*args, icon=QMessageBox.Information, **kwargs)
+ return msgbox(*args, icon=QMessageBox.Icon.Information, **kwargs)
diff --git a/qutebrowser/misc/pastebin.py b/qutebrowser/misc/pastebin.py
index a4e0a196f..afca59d2e 100644
--- a/qutebrowser/misc/pastebin.py
+++ b/qutebrowser/misc/pastebin.py
@@ -21,7 +21,7 @@
import urllib.parse
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QObject, QUrl
class PastebinClient(QObject):
diff --git a/qutebrowser/misc/quitter.py b/qutebrowser/misc/quitter.py
index 905429989..a849aec70 100644
--- a/qutebrowser/misc/quitter.py
+++ b/qutebrowser/misc/quitter.py
@@ -31,7 +31,7 @@ import functools
import subprocess
from typing import Iterable, Mapping, MutableSequence, Sequence, cast
-from PyQt5.QtCore import QObject, pyqtSignal, QTimer
+from qutebrowser.qt.core import QObject, pyqtSignal, QTimer
try:
import hunter
except ImportError:
@@ -221,21 +221,18 @@ class Quitter(QObject):
status, session))
sessions.shutdown(session, last_window=last_window)
-
- if prompt.prompt_queue.shutdown():
- # If shutdown was called while we were asking a question, we're in
- # a still sub-eventloop (which gets quit now) and not in the main
- # one.
- # This means we need to defer the real shutdown to when we're back
- # in the real main event loop, or we'll get a segfault.
- log.destroy.debug("Deferring real shutdown because question was "
- "active.")
- QTimer.singleShot(0, functools.partial(self._shutdown_2, status,
- is_restart=is_restart))
- else:
- # If we have no questions to shut down, we are already in the real
- # event loop, so we can shut down immediately.
- self._shutdown_2(status, is_restart=is_restart)
+ prompt.prompt_queue.shutdown()
+
+ # If shutdown was called while we were asking a question, we're in
+ # a still sub-eventloop (which gets quit now) and not in the main
+ # one.
+ # But there's also other situations where it's problematic to shut down
+ # immediately (e.g. when we're just starting up).
+ # This means we need to defer the real shutdown to when we're back
+ # in the real main event loop, or we'll get a segfault.
+ log.destroy.debug("Deferring shutdown stage 2")
+ QTimer.singleShot(
+ 0, functools.partial(self._shutdown_2, status, is_restart=is_restart))
def _shutdown_2(self, status: int, is_restart: bool) -> None:
"""Second stage of shutdown."""
@@ -282,12 +279,10 @@ def quit_(save: bool = False,
"""
if session is not None and not save:
raise cmdutils.CommandError("Session name given without --save!")
- if save:
- if session is None:
- session = sessions.default
- instance.shutdown(session=session)
- else:
- instance.shutdown()
+ if save and session is None:
+ session = sessions.default
+
+ instance.shutdown(session=session)
@cmdutils.register()
diff --git a/qutebrowser/misc/savemanager.py b/qutebrowser/misc/savemanager.py
index 1b72734cb..ed1b90890 100644
--- a/qutebrowser/misc/savemanager.py
+++ b/qutebrowser/misc/savemanager.py
@@ -23,7 +23,7 @@ import os.path
import collections
from typing import MutableMapping
-from PyQt5.QtCore import pyqtSlot, QObject, QTimer
+from qutebrowser.qt.core import pyqtSlot, QObject, QTimer
from qutebrowser.config import config
from qutebrowser.api import cmdutils
diff --git a/qutebrowser/misc/sessions.py b/qutebrowser/misc/sessions.py
index 67e22c17d..b96764d81 100644
--- a/qutebrowser/misc/sessions.py
+++ b/qutebrowser/misc/sessions.py
@@ -27,11 +27,11 @@ import shutil
import pathlib
from typing import Any, Iterable, MutableMapping, MutableSequence, Optional, Union, cast
-from PyQt5.QtCore import Qt, QUrl, QObject, QPoint, QTimer, QDateTime
+from qutebrowser.qt.core import Qt, QUrl, QObject, QPoint, QTimer, QDateTime
import yaml
from qutebrowser.utils import (standarddir, objreg, qtutils, log, message,
- utils, usertypes, version)
+ utils, usertypes)
from qutebrowser.api import cmdutils
from qutebrowser.config import config, configfiles
from qutebrowser.completion.models import miscmodels
@@ -64,12 +64,7 @@ def init(parent=None):
# WORKAROUND for https://github.com/qutebrowser/qutebrowser/issues/5359
backup_path = base_path / 'before-qt-515'
-
- if objects.backend == usertypes.Backend.QtWebEngine:
- webengine_version = version.qtwebengine_versions().webengine
- do_backup = webengine_version >= utils.VersionNumber(5, 15)
- else:
- do_backup = False
+ do_backup = objects.backend == usertypes.Backend.QtWebEngine
if base_path.exists() and not backup_path.exists() and do_backup:
backup_path.mkdir()
@@ -225,7 +220,7 @@ class SessionManager(QObject):
# QtWebEngine
user_data = None
- data['last_visited'] = item.lastVisited().toString(Qt.ISODate)
+ data['last_visited'] = item.lastVisited().toString(Qt.DateFormat.ISODate)
if tab.history.current_idx() == idx:
pos = tab.scroller.pos_px()
@@ -450,7 +445,7 @@ class SessionManager(QObject):
if histentry.get("last_visited"):
last_visited: Optional[QDateTime] = QDateTime.fromString(
histentry.get("last_visited"),
- Qt.ISODate,
+ Qt.DateFormat.ISODate,
)
else:
last_visited = None
@@ -472,7 +467,6 @@ class SessionManager(QObject):
"""Turn yaml data into windows."""
window = mainwindow.MainWindow(geometry=win['geometry'],
private=win.get('private', None))
- window.show()
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=window.win_id)
tab_to_focus = None
@@ -485,6 +479,8 @@ class SessionManager(QObject):
new_tab.set_pinned(True)
if tab_to_focus is not None:
tabbed_browser.widget.setCurrentIndex(tab_to_focus)
+
+ window.show()
if win.get('active', False):
QTimer.singleShot(0, tabbed_browser.widget.activateWindow)
diff --git a/qutebrowser/misc/sql.py b/qutebrowser/misc/sql.py
index 062da39de..28a97fd77 100644
--- a/qutebrowser/misc/sql.py
+++ b/qutebrowser/misc/sql.py
@@ -19,16 +19,17 @@
"""Provides access to sqlite databases."""
+import enum
import collections
import contextlib
import dataclasses
import types
-from typing import Any, Dict, Iterator, List, Mapping, MutableSequence, Optional, Type
+from typing import Any, Dict, Iterator, List, Mapping, MutableSequence, Optional, Type, Union
-from PyQt5.QtCore import QObject, pyqtSignal
-from PyQt5.QtSql import QSqlDatabase, QSqlError, QSqlQuery
+from qutebrowser.qt.core import QObject, pyqtSignal
+from qutebrowser.qt.sql import QSqlDatabase, QSqlError, QSqlQuery
-from qutebrowser.qt import sip
+from qutebrowser.qt import sip, machinery
from qutebrowser.utils import debug, log
@@ -69,24 +70,45 @@ class UserVersion:
return f'{self.major}.{self.minor}'
-class SqliteErrorCode:
+class SqliteErrorCode(enum.Enum):
+ """Primary error codes as used by sqlite.
- """Error codes as used by sqlite.
-
- See https://sqlite.org/rescode.html - note we only define the codes we use
- in qutebrowser here.
+ See https://sqlite.org/rescode.html
"""
- ERROR = '1' # generic error code
- BUSY = '5' # database is locked
- READONLY = '8' # attempt to write a readonly database
- IOERR = '10' # disk I/O error
- CORRUPT = '11' # database disk image is malformed
- FULL = '13' # database or disk is full
- CANTOPEN = '14' # unable to open database file
- PROTOCOL = '15' # locking protocol error
- CONSTRAINT = '19' # UNIQUE constraint failed
- NOTADB = '26' # file is not a database
+ # pylint: disable=invalid-name
+
+ OK = 0 # Successful result
+ ERROR = 1 # Generic error
+ INTERNAL = 2 # Internal logic error in SQLite
+ PERM = 3 # Access permission denied
+ ABORT = 4 # Callback routine requested an abort
+ BUSY = 5 # The database file is locked
+ LOCKED = 6 # A table in the database is locked
+ NOMEM = 7 # A malloc() failed
+ READONLY = 8 # Attempt to write a readonly database
+ INTERRUPT = 9 # Operation terminated by sqlite3_interrupt()*/
+ IOERR = 10 # Some kind of disk I/O error occurred
+ CORRUPT = 11 # The database disk image is malformed
+ NOTFOUND = 12 # Unknown opcode in sqlite3_file_control()
+ FULL = 13 # Insertion failed because database is full
+ CANTOPEN = 14 # Unable to open the database file
+ PROTOCOL = 15 # Database lock protocol error
+ EMPTY = 16 # Internal use only
+ SCHEMA = 17 # The database schema changed
+ TOOBIG = 18 # String or BLOB exceeds size limit
+ CONSTRAINT = 19 # Abort due to constraint violation
+ MISMATCH = 20 # Data type mismatch
+ MISUSE = 21 # Library used incorrectly
+ NOLFS = 22 # Uses OS features not supported on host
+ AUTH = 23 # Authorization denied
+ FORMAT = 24 # Not used
+ RANGE = 25 # 2nd parameter to sqlite3_bind out of range
+ NOTADB = 26 # File opened that is not a database file
+ NOTICE = 27 # Notifications from sqlite3_log()
+ WARNING = 28 # Warnings from sqlite3_log()
+ ROW = 100 # sqlite3_step() has another row ready
+ DONE = 101 # sqlite3_step() has finished executing
class Error(Exception):
@@ -104,8 +126,7 @@ class Error(Exception):
"""
if self.error is None:
return str(self)
- else:
- return self.error.databaseText()
+ return self.error.databaseText()
class KnownError(Error):
@@ -128,6 +149,14 @@ class BugError(Error):
def raise_sqlite_error(msg: str, error: QSqlError) -> None:
"""Raise either a BugError or KnownError."""
error_code = error.nativeErrorCode()
+ primary_error_code: Union[SqliteErrorCode, str]
+ try:
+ # https://sqlite.org/rescode.html#pve
+ primary_error_code = SqliteErrorCode(int(error_code) & 0xff)
+ except ValueError:
+ # not an int, or unknown error code -> fall back to string
+ primary_error_code = error_code
+
database_text = error.databaseText()
driver_text = error.driverText()
@@ -135,7 +164,7 @@ def raise_sqlite_error(msg: str, error: QSqlError) -> None:
log.sql.debug(f"type: {debug.qenum_key(QSqlError, error.type())}")
log.sql.debug(f"database text: {database_text}")
log.sql.debug(f"driver text: {driver_text}")
- log.sql.debug(f"error code: {error_code}")
+ log.sql.debug(f"error code: {error_code} -> {primary_error_code}")
known_errors = [
SqliteErrorCode.BUSY,
@@ -151,12 +180,12 @@ def raise_sqlite_error(msg: str, error: QSqlError) -> None:
# https://github.com/qutebrowser/qutebrowser/issues/4681
# If the query we built was too long
too_long_err = (
- error_code == SqliteErrorCode.ERROR and
+ primary_error_code == SqliteErrorCode.ERROR and
(database_text.startswith("Expression tree is too large") or
database_text in ["too many SQL variables",
"LIKE or GLOB pattern too complex"]))
- if error_code in known_errors or too_long_err:
+ if primary_error_code in known_errors or too_long_err:
raise KnownError(msg, error)
raise BugError(msg, error)
@@ -299,6 +328,7 @@ class Query:
ok = self.query.prepare(querystr)
self._check_ok('prepare', ok)
self.query.setForwardOnly(forward_only)
+ self._placeholders: List[str] = []
def __iter__(self) -> Iterator[Any]:
if not self.query.isActive():
@@ -319,15 +349,26 @@ class Query:
msg = f'Failed to {step} query "{query}": "{error.text()}"'
raise_sqlite_error(msg, error)
+ def _validate_bound_values(self):
+ """Make sure all placeholders are bound."""
+ qt_bound_values = self.query.boundValues()
+ if machinery.IS_QT5:
+ # Qt 5: Returns a dict
+ values = list(qt_bound_values.values())
+ else:
+ # Qt 6: Returns a list
+ values = qt_bound_values
+
+ if None in values:
+ raise BugError("Missing bound values!")
+
def _bind_values(self, values: Mapping[str, Any]) -> Dict[str, Any]:
+ self._placeholders = list(values)
for key, val in values.items():
self.query.bindValue(f':{key}', val)
- bound_values = self.bound_values()
- if None in bound_values.values():
- raise BugError("Missing bound values!")
-
- return bound_values
+ self._validate_bound_values()
+ return self.bound_values()
def run(self, **values: Any) -> 'Query':
"""Execute the prepared query."""
@@ -378,7 +419,10 @@ class Query:
return rows
def bound_values(self) -> Dict[str, Any]:
- return self.query.boundValues()
+ return {
+ f":{key}": self.query.boundValue(f":{key}")
+ for key in self._placeholders
+ }
class SqlTable(QObject):
diff --git a/qutebrowser/misc/throttle.py b/qutebrowser/misc/throttle.py
index ac565b68d..5e4dd13b2 100644
--- a/qutebrowser/misc/throttle.py
+++ b/qutebrowser/misc/throttle.py
@@ -23,7 +23,7 @@ import dataclasses
import time
from typing import Any, Callable, Mapping, Optional, Sequence
-from PyQt5.QtCore import QObject
+from qutebrowser.qt.core import QObject
from qutebrowser.utils import usertypes
diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py
index 14c02864e..d94b32c26 100644
--- a/qutebrowser/misc/utilcmds.py
+++ b/qutebrowser/misc/utilcmds.py
@@ -27,8 +27,8 @@ import sys
import traceback
from typing import Optional
-from PyQt5.QtCore import QUrl
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.widgets import QApplication
from qutebrowser.browser import qutescheme
from qutebrowser.utils import log, objreg, usertypes, message, debug, utils
diff --git a/qutebrowser/qt.py b/qutebrowser/qt.py
deleted file mode 100644
index 5e0f80538..000000000
--- a/qutebrowser/qt.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
-
-# Copyright 2018-2021 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
-#
-# This file is part of qutebrowser.
-#
-# qutebrowser is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# qutebrowser is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
-
-"""Wrappers around Qt/PyQt code."""
-
-# pylint: disable=unused-import
-
-# While upstream recommends using PyQt5.sip ever since PyQt5 5.11, some distributions
-# still package later versions of PyQt5 with a top-level "sip" rather than "PyQt5.sip".
-try:
- from PyQt5 import sip
-except ImportError:
- import sip # type: ignore[import, no-redef]
diff --git a/qutebrowser/qt/__init__.py b/qutebrowser/qt/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/qutebrowser/qt/__init__.py
diff --git a/qutebrowser/qt/core.py b/qutebrowser/qt/core.py
new file mode 100644
index 000000000..b09459f6f
--- /dev/null
+++ b/qutebrowser/qt/core.py
@@ -0,0 +1,16 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtCore import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtCore import *
+elif machinery.USE_PYQT6:
+ from PyQt6.QtCore import *
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/dbus.py b/qutebrowser/qt/dbus.py
new file mode 100644
index 000000000..6ef8e55f3
--- /dev/null
+++ b/qutebrowser/qt/dbus.py
@@ -0,0 +1,16 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtDBus import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtDBus import *
+elif machinery.USE_PYQT6:
+ from PyQt6.QtDBus import *
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/gui.py b/qutebrowser/qt/gui.py
new file mode 100644
index 000000000..ce4780f42
--- /dev/null
+++ b/qutebrowser/qt/gui.py
@@ -0,0 +1,18 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import,unused-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtGui import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtGui import *
+ from PyQt5.QtWidgets import QFileSystemModel
+ del QOpenGLVersionProfile # moved to QtOpenGL in Qt 6
+elif machinery.USE_PYQT6:
+ from PyQt6.QtGui import *
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/machinery.py b/qutebrowser/qt/machinery.py
new file mode 100644
index 000000000..66a35a855
--- /dev/null
+++ b/qutebrowser/qt/machinery.py
@@ -0,0 +1,79 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring
+# flake8: noqa
+
+import os
+import importlib
+
+
+_WRAPPERS = [
+ "PyQt6",
+ "PyQt5",
+ # Needs more work
+ # "PySide6",
+]
+
+
+class Error(Exception):
+ pass
+
+
+class Unavailable(Error, ImportError):
+
+ """Raised when a module is unavailable with the given wrapper."""
+
+ def __init__(self) -> None:
+ super().__init__(f"Unavailable with {WRAPPER}")
+
+
+class UnknownWrapper(Error):
+ pass
+
+
+def _autoselect_wrapper():
+ for wrapper in _WRAPPERS:
+ try:
+ importlib.import_module(wrapper)
+ except ImportError:
+ # FIXME:qt6 show/log this somewhere?
+ continue
+ return wrapper
+
+ wrappers = ", ".join(_WRAPPERS)
+ raise Error(f"No Qt wrapper found, tried {wrappers}")
+
+
+def _select_wrapper():
+ env_var = "QUTE_QT_WRAPPER"
+ env_wrapper = os.environ.get(env_var)
+ if env_wrapper is None:
+ return _autoselect_wrapper()
+
+ if env_wrapper not in _WRAPPERS:
+ raise Error(f"Unknown wrapper {env_wrapper} set via {env_var}, "
+ f"allowed: {', '.join(_WRAPPERS)}")
+
+ return env_wrapper
+
+
+WRAPPER = _select_wrapper()
+USE_PYQT5 = WRAPPER == "PyQt5"
+USE_PYQT6 = WRAPPER == "PyQt6"
+USE_PYSIDE6 = WRAPPER == "PySide6"
+assert USE_PYQT5 ^ USE_PYQT6 ^ USE_PYSIDE6
+
+IS_QT5 = USE_PYQT5
+IS_QT6 = USE_PYQT6 or USE_PYSIDE6
+IS_PYQT = USE_PYQT5 or USE_PYQT6
+IS_PYSIDE = USE_PYSIDE6
+assert IS_QT5 ^ IS_QT6
+assert IS_PYQT ^ IS_PYSIDE
+
+
+if USE_PYQT5:
+ PACKAGE = "PyQt5"
+elif USE_PYQT6:
+ PACKAGE = "PyQt6"
+elif USE_PYSIDE6:
+ PACKAGE = "PySide6"
diff --git a/qutebrowser/qt/network.py b/qutebrowser/qt/network.py
new file mode 100644
index 000000000..6836d6226
--- /dev/null
+++ b/qutebrowser/qt/network.py
@@ -0,0 +1,16 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtNetwork import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtNetwork import *
+elif machinery.USE_PYQT6:
+ from PyQt6.QtNetwork import *
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/opengl.py b/qutebrowser/qt/opengl.py
new file mode 100644
index 000000000..a04fb9a29
--- /dev/null
+++ b/qutebrowser/qt/opengl.py
@@ -0,0 +1,16 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtOpenGL import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtGui import QOpenGLVersionProfile
+elif machinery.USE_PYQT6:
+ from PyQt6.QtOpenGL import *
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/printsupport.py b/qutebrowser/qt/printsupport.py
new file mode 100644
index 000000000..08a29638e
--- /dev/null
+++ b/qutebrowser/qt/printsupport.py
@@ -0,0 +1,16 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtPrintSupport import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtPrintSupport import *
+elif machinery.USE_PYQT6:
+ from PyQt6.QtPrintSupport import *
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/qml.py b/qutebrowser/qt/qml.py
new file mode 100644
index 000000000..faa82df48
--- /dev/null
+++ b/qutebrowser/qt/qml.py
@@ -0,0 +1,16 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtQml import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtQml import *
+elif machinery.USE_PYQT6:
+ from PyQt6.QtQml import *
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/sip.py b/qutebrowser/qt/sip.py
new file mode 100644
index 000000000..2cfd9c82f
--- /dev/null
+++ b/qutebrowser/qt/sip.py
@@ -0,0 +1,31 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,wildcard-import,unused-wildcard-import,no-else-raise
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+# While upstream recommends using PyQt6.sip ever since PyQt6 5.11, some distributions
+# still package later versions of PyQt6 with a top-level "sip" rather than "PyQt6.sip".
+_VENDORED_SIP = False
+
+if machinery.USE_PYSIDE6:
+ raise machinery.Unavailable()
+elif machinery.USE_PYQT5:
+ try:
+ from PyQt5.sip import *
+ _VENDORED_SIP = True
+ except ImportError:
+ pass
+elif machinery.USE_PYQT6:
+ try:
+ from PyQt6.sip import *
+ _VENDORED_SIP = True
+ except ImportError:
+ pass
+
+else:
+ raise machinery.UnknownWrapper()
+
+if not _VENDORED_SIP:
+ from sip import * # type: ignore[import] # pylint: disable=import-error
diff --git a/qutebrowser/qt/sql.py b/qutebrowser/qt/sql.py
new file mode 100644
index 000000000..a8c46ebb1
--- /dev/null
+++ b/qutebrowser/qt/sql.py
@@ -0,0 +1,16 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtSql import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtSql import *
+elif machinery.USE_PYQT6:
+ from PyQt6.QtSql import *
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/test.py b/qutebrowser/qt/test.py
new file mode 100644
index 000000000..e8e0189d0
--- /dev/null
+++ b/qutebrowser/qt/test.py
@@ -0,0 +1,16 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtTest import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtTest import *
+elif machinery.USE_PYQT6:
+ from PyQt6.QtTest import *
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/webenginecore.py b/qutebrowser/qt/webenginecore.py
new file mode 100644
index 000000000..b1e650d24
--- /dev/null
+++ b/qutebrowser/qt/webenginecore.py
@@ -0,0 +1,31 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import,unused-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtWebEngineCore import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtWebEngineCore import *
+ from PyQt5.QtWebEngineWidgets import (
+ QWebEngineSettings,
+ QWebEngineProfile,
+ QWebEngineDownloadItem as QWebEngineDownloadRequest,
+ QWebEnginePage,
+ QWebEngineCertificateError,
+ QWebEngineScript,
+ QWebEngineHistory,
+ QWebEngineHistoryItem,
+ QWebEngineScriptCollection,
+ QWebEngineClientCertificateSelection,
+ QWebEngineFullScreenRequest,
+ QWebEngineContextMenuData as QWebEngineContextMenuRequest,
+ )
+ from PyQt5.QtWebEngine import PYQT_WEBENGINE_VERSION, PYQT_WEBENGINE_VERSION_STR
+elif machinery.USE_PYQT6:
+ from PyQt6.QtWebEngineCore import *
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/webenginewidgets.py b/qutebrowser/qt/webenginewidgets.py
new file mode 100644
index 000000000..922acf869
--- /dev/null
+++ b/qutebrowser/qt/webenginewidgets.py
@@ -0,0 +1,32 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtWebEngineWidgets import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtWebEngineWidgets import *
+elif machinery.USE_PYQT6:
+ from PyQt6.QtWebEngineWidgets import *
+else:
+ raise machinery.UnknownWrapper()
+
+
+if machinery.IS_QT5:
+ # moved to WebEngineCore in Qt 6
+ del QWebEngineSettings
+ del QWebEngineProfile
+ del QWebEngineDownloadItem
+ del QWebEnginePage
+ del QWebEngineCertificateError
+ del QWebEngineScript
+ del QWebEngineHistory
+ del QWebEngineHistoryItem
+ del QWebEngineScriptCollection
+ del QWebEngineClientCertificateSelection
+ del QWebEngineFullScreenRequest
+ del QWebEngineContextMenuData
diff --git a/qutebrowser/qt/webkit.py b/qutebrowser/qt/webkit.py
new file mode 100644
index 000000000..616560d49
--- /dev/null
+++ b/qutebrowser/qt/webkit.py
@@ -0,0 +1,16 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,wildcard-import,no-else-raise
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ raise machinery.Unavailable()
+elif machinery.USE_PYQT5:
+ from PyQt5.QtWebKit import *
+elif machinery.USE_PYQT6:
+ raise machinery.Unavailable()
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/webkitwidgets.py b/qutebrowser/qt/webkitwidgets.py
new file mode 100644
index 000000000..fc5228b31
--- /dev/null
+++ b/qutebrowser/qt/webkitwidgets.py
@@ -0,0 +1,16 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,wildcard-import,no-else-raise
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ raise machinery.Unavailable()
+elif machinery.USE_PYQT5:
+ from PyQt5.QtWebKitWidgets import *
+elif machinery.USE_PYQT6:
+ raise machinery.Unavailable()
+else:
+ raise machinery.UnknownWrapper()
diff --git a/qutebrowser/qt/widgets.py b/qutebrowser/qt/widgets.py
new file mode 100644
index 000000000..63e46c359
--- /dev/null
+++ b/qutebrowser/qt/widgets.py
@@ -0,0 +1,19 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+# FIXME:qt6 (lint)
+# pylint: disable=missing-module-docstring,import-error,wildcard-import,unused-wildcard-import
+# flake8: noqa
+
+from qutebrowser.qt import machinery
+
+
+if machinery.USE_PYSIDE6:
+ from PySide6.QtWidgets import *
+elif machinery.USE_PYQT5:
+ from PyQt5.QtWidgets import *
+elif machinery.USE_PYQT6:
+ from PyQt6.QtWidgets import *
+else:
+ raise machinery.UnknownWrapper()
+
+if machinery.IS_QT5:
+ del QFileSystemModel # moved to QtGui in Qt 6
diff --git a/qutebrowser/qutebrowser.py b/qutebrowser/qutebrowser.py
index c576c4a06..f1273dee3 100644
--- a/qutebrowser/qutebrowser.py
+++ b/qutebrowser/qutebrowser.py
@@ -52,7 +52,7 @@ except ImportError:
sys.exit(100)
check_python_version()
-import argparse # pylint: disable=wrong-import-order
+import argparse # FIXME:qt6 (lint): disable=wrong-import-order
from qutebrowser.misc import earlyinit
@@ -86,7 +86,7 @@ def get_argparser():
default="org.qutebrowser.qutebrowser",
help="Set the base name of the desktop entry for this "
"application. Used to set the app_id under Wayland. See "
- "https://doc.qt.io/qt-5/qguiapplication.html#desktopFileName-prop")
+ "https://doc.qt.io/qt-6/qguiapplication.html#desktopFileName-prop")
parser.add_argument('--untrusted-args',
action='store_true',
help="Mark all following arguments as untrusted, which "
diff --git a/qutebrowser/utils/debug.py b/qutebrowser/utils/debug.py
index 0fa74f4e7..47cbebb35 100644
--- a/qutebrowser/utils/debug.py
+++ b/qutebrowser/utils/debug.py
@@ -20,6 +20,7 @@
"""Utilities used for debugging."""
import re
+import enum
import inspect
import logging
import functools
@@ -28,7 +29,7 @@ import types
from typing import (
Any, Callable, List, Mapping, MutableSequence, Optional, Sequence, Type, Union)
-from PyQt5.QtCore import Qt, QEvent, QMetaMethod, QObject, pyqtBoundSignal
+from qutebrowser.qt.core import Qt, QEvent, QMetaMethod, QObject, pyqtBoundSignal
from qutebrowser.utils import log, utils, qtutils, objreg
from qutebrowser.misc import objects
@@ -42,8 +43,10 @@ def log_events(klass: Type[QObject]) -> Type[QObject]:
@functools.wraps(old_event)
def new_event(self: Any, e: QEvent) -> bool:
"""Wrapper for event() which logs events."""
- log.misc.debug("Event in {}: {}".format(utils.qualname(klass),
- qenum_key(QEvent, e.type())))
+ # Passing klass as a WORKAROUND because with PyQt6, QEvent.type() returns int:
+ # https://www.riverbankcomputing.com/pipermail/pyqt/2022-April/044583.html
+ log.misc.debug("Event in {}: {}".format(
+ utils.qualname(klass), qenum_key(QEvent, e.type(), klass=QEvent.Type)))
return old_event(self, e)
klass.event = new_event # type: ignore[assignment]
@@ -70,7 +73,7 @@ def log_signals(obj: QObject) -> QObject:
for i in range(metaobj.methodCount()):
meta_method = metaobj.method(i)
qtutils.ensure_valid(meta_method)
- if meta_method.methodType() == QMetaMethod.Signal:
+ if meta_method.methodType() == QMetaMethod.MethodType.Signal:
name = meta_method.name().data().decode('ascii')
if name != 'destroyed':
signal = getattr(obj, name)
@@ -99,16 +102,62 @@ def log_signals(obj: QObject) -> QObject:
_EnumValueType = Union[sip.simplewrapper, int]
-def qenum_key(base: Type[_EnumValueType],
- value: _EnumValueType,
- add_base: bool = False,
- klass: Type[_EnumValueType] = None) -> str:
+def _qenum_key_python(
+ value: _EnumValueType,
+ klass: Type[_EnumValueType],
+) -> Optional[str]:
+ """New-style PyQt6: Try getting value from Python enum."""
+ if isinstance(value, enum.Enum) and value.name:
+ return value.name
+
+ # We got an int with klass passed: Try asking Python enum for member
+ if issubclass(klass, enum.Enum):
+ try:
+ assert isinstance(value, int)
+ name = klass(value).name
+ if name is not None and name != str(value):
+ return name
+ except ValueError:
+ pass
+
+ return None
+
+
+def _qenum_key_qt(
+ base: Type[_EnumValueType],
+ value: _EnumValueType,
+ klass: Type[_EnumValueType],
+) -> Optional[str]:
+ # On PyQt5, or PyQt6 with int passed: Try to ask Qt's introspection.
+ # However, not every Qt enum value has a staticMetaObject
+ try:
+ meta_obj = base.staticMetaObject # type: ignore[union-attr]
+ idx = meta_obj.indexOfEnumerator(klass.__name__)
+ meta_enum = meta_obj.enumerator(idx)
+ key = meta_enum.valueToKey(int(value)) # type: ignore[arg-type]
+ if key is not None:
+ return key
+ except AttributeError:
+ pass
+
+ # PyQt5: Try finding value match in class
+ for name, obj in vars(base).items():
+ if isinstance(obj, klass) and obj == value:
+ return name
+
+ return None
+
+
+def qenum_key(
+ base: Type[_EnumValueType],
+ value: _EnumValueType,
+ klass: Type[_EnumValueType] = None,
+) -> str:
"""Convert a Qt Enum value to its key as a string.
Args:
base: The object the enum is in, e.g. QFrame.
value: The value to get.
- add_base: Whether the base should be added to the printed name.
klass: The enum class the value belongs to.
If None, the class will be auto-guessed.
@@ -120,44 +169,33 @@ def qenum_key(base: Type[_EnumValueType],
klass = value.__class__
if klass == int:
raise TypeError("Can't guess enum class of an int!")
+ assert klass is not None
- try:
- meta_obj = base.staticMetaObject # type: ignore[union-attr]
- idx = meta_obj.indexOfEnumerator(klass.__name__)
- meta_enum = meta_obj.enumerator(idx)
- ret = meta_enum.valueToKey(int(value)) # type: ignore[arg-type]
- except AttributeError:
- ret = None
+ name = _qenum_key_python(value=value, klass=klass)
+ if name is not None:
+ return name
- if ret is None:
- for name, obj in vars(base).items():
- if isinstance(obj, klass) and obj == value:
- ret = name
- break
- else:
- ret = '0x{:04x}'.format(int(value)) # type: ignore[arg-type]
+ name = _qenum_key_qt(base=base, value=value, klass=klass)
+ if name is not None:
+ return name
- if add_base and hasattr(base, '__name__'):
- return '.'.join([base.__name__, ret])
- else:
- return ret
+ # Last resort fallback: Hex value
+ return '0x{:04x}'.format(int(value)) # type: ignore[arg-type]
def qflags_key(base: Type[_EnumValueType],
value: _EnumValueType,
- add_base: bool = False,
klass: Type[_EnumValueType] = None) -> str:
"""Convert a Qt QFlags value to its keys as string.
- Note: Passing a combined value (such as Qt.AlignCenter) will get the names
- for the individual bits (e.g. Qt.AlignVCenter | Qt.AlignHCenter). FIXME
+ Note: Passing a combined value (such as Qt.AlignmentFlag.AlignCenter) will get the names
+ for the individual bits (e.g. Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignHCenter). FIXME
https://github.com/qutebrowser/qutebrowser/issues/42
Args:
base: The object the flags are in, e.g. QtCore.Qt
value: The value to get.
- add_base: Whether the base should be added to the printed names.
klass: The flags class the value belongs to.
If None, the class will be auto-guessed.
@@ -173,12 +211,12 @@ def qflags_key(base: Type[_EnumValueType],
raise TypeError("Can't guess enum class of an int!")
if not value:
- return qenum_key(base, value, add_base, klass)
+ return qenum_key(base, value, klass)
bits = []
names = []
mask = 0x01
- value = int(value) # type: ignore[arg-type]
+ value = qtutils.extract_enum_val(value)
while mask <= value:
if value & mask:
bits.append(mask)
@@ -187,7 +225,7 @@ def qflags_key(base: Type[_EnumValueType],
# We have to re-convert to an enum type here or we'll sometimes get an
# empty string back.
enum_value = klass(bit) # type: ignore[call-arg]
- names.append(qenum_key(base, enum_value, add_base))
+ names.append(qenum_key(base, enum_value, klass))
return '|'.join(names)
@@ -327,7 +365,7 @@ def _get_pyqt_objects(lines: MutableSequence[str],
obj: QObject,
depth: int = 0) -> None:
"""Recursive method for get_all_objects to get Qt objects."""
- for kid in obj.findChildren(QObject, '', Qt.FindDirectChildrenOnly):
+ for kid in obj.findChildren(QObject, '', Qt.FindChildOption.FindDirectChildrenOnly):
lines.append(' ' * depth + repr(kid))
_get_pyqt_objects(lines, kid, depth + 1)
diff --git a/qutebrowser/utils/error.py b/qutebrowser/utils/error.py
index a5889f977..3a155a4fe 100644
--- a/qutebrowser/utils/error.py
+++ b/qutebrowser/utils/error.py
@@ -19,7 +19,7 @@
"""Tools related to error printing/displaying."""
-from PyQt5.QtWidgets import QMessageBox
+from qutebrowser.qt.widgets import QMessageBox
from qutebrowser.utils import log, utils
@@ -70,5 +70,5 @@ def handle_fatal_exc(exc: BaseException,
msg_text = str(exc)
if post_text:
msg_text += '\n\n{}'.format(post_text)
- msgbox = QMessageBox(QMessageBox.Critical, title, msg_text)
+ msgbox = QMessageBox(QMessageBox.Icon.Critical, title, msg_text)
msgbox.exec()
diff --git a/qutebrowser/utils/jinja.py b/qutebrowser/utils/jinja.py
index a44a0235e..5775b317b 100644
--- a/qutebrowser/utils/jinja.py
+++ b/qutebrowser/utils/jinja.py
@@ -29,7 +29,7 @@ from typing import Any, Callable, FrozenSet, Iterator, List, Set, Tuple
import jinja2
import jinja2.nodes
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.utils import utils, urlutils, log, qtutils, resources
from qutebrowser.misc import debugcachestats
@@ -114,7 +114,7 @@ class Environment(jinja2.Environment):
url = QUrl('qute://resource')
url.setPath('/' + path)
urlutils.ensure_valid(url)
- urlstr = url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ urlstr = url.toString(QUrl.ComponentFormattingOption.FullyEncoded) # type: ignore[arg-type]
return urlstr
def _data_url(self, path: str) -> str:
diff --git a/qutebrowser/utils/log.py b/qutebrowser/utils/log.py
index db72e1a21..040e75f16 100644
--- a/qutebrowser/utils/log.py
+++ b/qutebrowser/utils/log.py
@@ -35,7 +35,7 @@ import argparse
from typing import (TYPE_CHECKING, Any, Iterator, Mapping, MutableSequence,
Optional, Set, Tuple, Union)
-from PyQt5 import QtCore
+from qutebrowser.qt import core as qtcore
# Optional imports
try:
import colorama
@@ -211,13 +211,13 @@ def init_log(args: argparse.Namespace) -> None:
root.setLevel(logging.NOTSET)
logging.captureWarnings(True)
_init_py_warnings()
- QtCore.qInstallMessageHandler(qt_message_handler)
+ qtcore.qInstallMessageHandler(qt_message_handler)
_log_inited = True
-@QtCore.pyqtSlot()
+@qtcore.pyqtSlot()
def shutdown_log() -> None:
- QtCore.qInstallMessageHandler(None)
+ qtcore.qInstallMessageHandler(None)
def _init_py_warnings() -> None:
@@ -236,11 +236,11 @@ def _init_py_warnings() -> None:
@contextlib.contextmanager
def disable_qt_msghandler() -> Iterator[None]:
"""Contextmanager which temporarily disables the Qt message handler."""
- old_handler = QtCore.qInstallMessageHandler(None)
+ old_handler = qtcore.qInstallMessageHandler(None)
try:
yield
finally:
- QtCore.qInstallMessageHandler(old_handler)
+ qtcore.qInstallMessageHandler(old_handler)
@contextlib.contextmanager
@@ -378,8 +378,8 @@ def change_console_formatter(level: int) -> None:
assert isinstance(old_formatter, JSONFormatter), old_formatter
-def qt_message_handler(msg_type: QtCore.QtMsgType,
- context: QtCore.QMessageLogContext,
+def qt_message_handler(msg_type: qtcore.QtMsgType,
+ context: qtcore.QMessageLogContext,
msg: str) -> None:
"""Qt message handler to redirect qWarning etc. to the logging system.
@@ -392,18 +392,12 @@ def qt_message_handler(msg_type: QtCore.QtMsgType,
# Note we map critical to ERROR as it's actually "just" an error, and fatal
# to critical.
qt_to_logging = {
- QtCore.QtDebugMsg: logging.DEBUG,
- QtCore.QtWarningMsg: logging.WARNING,
- QtCore.QtCriticalMsg: logging.ERROR,
- QtCore.QtFatalMsg: logging.CRITICAL,
+ qtcore.QtMsgType.QtDebugMsg: logging.DEBUG,
+ qtcore.QtMsgType.QtWarningMsg: logging.WARNING,
+ qtcore.QtMsgType.QtCriticalMsg: logging.ERROR,
+ qtcore.QtMsgType.QtFatalMsg: logging.CRITICAL,
+ qtcore.QtMsgType.QtInfoMsg: logging.INFO,
}
- try:
- qt_to_logging[QtCore.QtInfoMsg] = logging.INFO
- except AttributeError:
- # Added in Qt 5.5.
- # While we don't support Qt < 5.5 anymore, logging still needs to work so that
- # the Qt version warning in earlyinit.py does.
- pass
# Change levels of some well-known messages to debug so they don't get
# shown to the user.
@@ -468,6 +462,8 @@ def qt_message_handler(msg_type: QtCore.QtMsgType,
# https://bugreports.qt.io/browse/QTBUG-76391
"Attribute Qt::AA_ShareOpenGLContexts must be set before "
"QCoreApplication is created.",
+ # Qt 6.4 beta 1: https://bugreports.qt.io/browse/QTBUG-104741
+ "GL format 0 is not supported",
]
# not using utils.is_mac here, because we can't be sure we can successfully
# import the utils module here.
@@ -483,6 +479,11 @@ def qt_message_handler(msg_type: QtCore.QtMsgType,
if any(msg.strip().startswith(pattern) for pattern in suppressed_msgs):
level = logging.DEBUG
+ elif context.category == "qt.webenginecontext" and (
+ msg.strip().startswith("GL Type: ") or # Qt 6.3
+ msg.strip().startswith("GLImplementation:") # Qt 6.2
+ ):
+ level = logging.DEBUG
else:
level = qt_to_logging[msg_type]
diff --git a/qutebrowser/utils/message.py b/qutebrowser/utils/message.py
index a3da893dc..10183afee 100644
--- a/qutebrowser/utils/message.py
+++ b/qutebrowser/utils/message.py
@@ -27,7 +27,7 @@ import dataclasses
import traceback
from typing import Any, Callable, Iterable, List, Union, Optional
-from PyQt5.QtCore import pyqtSignal, pyqtBoundSignal, QObject
+from qutebrowser.qt.core import pyqtSignal, pyqtBoundSignal, QObject
from qutebrowser.utils import usertypes, log
@@ -241,7 +241,7 @@ class GlobalMessageBridge(QObject):
arg 1: Whether to block (True) or ask async (False).
IMPORTANT: Slots need to be connected to this signal via
- a Qt.DirectConnection!
+ a Qt.ConnectionType.DirectConnection!
mode_left: Emitted when a keymode was left in any window.
"""
diff --git a/qutebrowser/utils/objreg.py b/qutebrowser/utils/objreg.py
index 78d862ab4..58ac18b16 100644
--- a/qutebrowser/utils/objreg.py
+++ b/qutebrowser/utils/objreg.py
@@ -25,9 +25,9 @@ import functools
from typing import (TYPE_CHECKING, Any, Callable, MutableMapping, MutableSequence,
Optional, Sequence, Union)
-from PyQt5.QtCore import QObject, QTimer
-from PyQt5.QtWidgets import QApplication
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt.core import QObject, QTimer
+from qutebrowser.qt.widgets import QApplication
+from qutebrowser.qt.widgets import QWidget
from qutebrowser.utils import log, usertypes, utils
if TYPE_CHECKING:
diff --git a/qutebrowser/utils/qtutils.py b/qutebrowser/utils/qtutils.py
index ff8983c50..0ecc4cba6 100644
--- a/qutebrowser/utils/qtutils.py
+++ b/qutebrowser/utils/qtutils.py
@@ -29,22 +29,25 @@ Module attributes:
import io
+import enum
+import pathlib
import operator
import contextlib
from typing import (Any, AnyStr, TYPE_CHECKING, BinaryIO, IO, Iterator,
Optional, Union, Tuple, cast)
-from PyQt5.QtCore import (qVersion, QEventLoop, QDataStream, QByteArray,
+from qutebrowser.qt import machinery, sip
+from qutebrowser.qt.core import (qVersion, QEventLoop, QDataStream, QByteArray,
QIODevice, QFileDevice, QSaveFile, QT_VERSION_STR,
- PYQT_VERSION_STR, QObject, QUrl)
-from PyQt5.QtGui import QColor
+ PYQT_VERSION_STR, QObject, QUrl, QLibraryInfo)
+from qutebrowser.qt.gui import QColor
try:
- from PyQt5.QtWebKit import qWebKitVersion
+ from qutebrowser.qt.webkit import qWebKitVersion
except ImportError: # pragma: no cover
qWebKitVersion = None # type: ignore[assignment] # noqa: N816
if TYPE_CHECKING:
- from PyQt5.QtWebKit import QWebHistory
- from PyQt5.QtWebEngineWidgets import QWebEngineHistory
+ from qutebrowser.qt.webkit import QWebHistory
+ from qutebrowser.qt.webenginewidgets import QWebEngineHistory
from qutebrowser.misc import objects
from qutebrowser.utils import usertypes, utils
@@ -173,14 +176,14 @@ def ensure_valid(obj: Validatable) -> None:
def check_qdatastream(stream: QDataStream) -> None:
"""Check the status of a QDataStream and raise OSError if it's not ok."""
status_to_str = {
- QDataStream.Ok: "The data stream is operating normally.",
- QDataStream.ReadPastEnd: ("The data stream has read past the end of "
+ QDataStream.Status.Ok: "The data stream is operating normally.",
+ QDataStream.Status.ReadPastEnd: ("The data stream has read past the end of "
"the data in the underlying device."),
- QDataStream.ReadCorruptData: "The data stream has read corrupt data.",
- QDataStream.WriteFailed: ("The data stream cannot write to the "
+ QDataStream.Status.ReadCorruptData: "The data stream has read corrupt data.",
+ QDataStream.Status.WriteFailed: ("The data stream cannot write to the "
"underlying device."),
}
- if stream.status() != QDataStream.Ok:
+ if stream.status() != QDataStream.Status.Ok:
raise OSError(status_to_str[stream.status()])
@@ -196,14 +199,14 @@ _QtSerializableType = Union[
def serialize(obj: _QtSerializableType) -> QByteArray:
"""Serialize an object into a QByteArray."""
data = QByteArray()
- stream = QDataStream(data, QIODevice.WriteOnly)
+ stream = QDataStream(data, QIODevice.OpenModeFlag.WriteOnly)
serialize_stream(stream, obj)
return data
def deserialize(data: QByteArray, obj: _QtSerializableType) -> None:
"""Deserialize an object from a QByteArray."""
- stream = QDataStream(data, QIODevice.ReadOnly)
+ stream = QDataStream(data, QIODevice.OpenModeFlag.ReadOnly)
deserialize_stream(stream, obj)
@@ -233,7 +236,7 @@ def savefile_open(
f = QSaveFile(filename)
cancelled = False
try:
- open_ok = f.open(QIODevice.WriteOnly)
+ open_ok = f.open(QIODevice.OpenModeFlag.WriteOnly)
if not open_ok:
raise QtOSError(f)
@@ -302,7 +305,7 @@ class PyQIODevice(io.BufferedIOBase):
# contextlib.closing is only generic in Python 3.9+
def open(
self,
- mode: QIODevice.OpenMode,
+ mode: QIODevice.OpenModeFlag,
) -> contextlib.closing: # type: ignore[type-arg]
"""Open the underlying device and ensure opening succeeded.
@@ -367,7 +370,7 @@ class PyQIODevice(io.BufferedIOBase):
self._check_readable()
if size is None or size < 0:
- qt_size = 0 # no maximum size
+ qt_size = None # no maximum size
elif size == 0:
return b''
else:
@@ -375,7 +378,10 @@ class PyQIODevice(io.BufferedIOBase):
buf: Union[QByteArray, bytes, None] = None
if self.dev.canReadLine():
- buf = self.dev.readLine(qt_size)
+ if qt_size is None:
+ buf = self.dev.readLine()
+ else:
+ buf = self.dev.readLine(qt_size)
elif size is None or size < 0:
buf = self.dev.readAll()
else:
@@ -450,6 +456,12 @@ class QtValueError(ValueError):
super().__init__(err)
+if machinery.IS_QT6:
+ _ProcessEventFlagType = QEventLoop.ProcessEventsFlag
+else:
+ _ProcessEventFlagType = QEventLoop.ProcessEventsFlags
+
+
class EventLoop(QEventLoop):
"""A thin wrapper around QEventLoop.
@@ -463,8 +475,9 @@ class EventLoop(QEventLoop):
def exec(
self,
- flags: QEventLoop.ProcessEventsFlags =
- cast(QEventLoop.ProcessEventsFlags, QEventLoop.AllEvents)
+ flags: _ProcessEventFlagType = (
+ QEventLoop.ProcessEventsFlag.AllEvents # type: ignore[assignment]
+ ),
) -> int:
"""Override exec_ to raise an exception when re-running."""
if self._executing:
@@ -503,7 +516,7 @@ def interpolate_color(
start: QColor,
end: QColor,
percent: int,
- colorspace: Optional[QColor.Spec] = QColor.Rgb
+ colorspace: Optional[QColor.Spec] = QColor.Spec.Rgb
) -> QColor:
"""Get an interpolated color value.
@@ -528,17 +541,17 @@ def interpolate_color(
return QColor(*start.getRgb())
out = QColor()
- if colorspace == QColor.Rgb:
+ if colorspace == QColor.Spec.Rgb:
r1, g1, b1, a1 = start.getRgb()
r2, g2, b2, a2 = end.getRgb()
components = _get_color_percentage(r1, g1, b1, a1, r2, g2, b2, a2, percent)
out.setRgb(*components)
- elif colorspace == QColor.Hsv:
+ elif colorspace == QColor.Spec.Hsv:
h1, s1, v1, a1 = start.getHsv()
h2, s2, v2, a2 = end.getHsv()
components = _get_color_percentage(h1, s1, v1, a1, h2, s2, v2, a2, percent)
out.setHsv(*components)
- elif colorspace == QColor.Hsl:
+ elif colorspace == QColor.Spec.Hsl:
h1, s1, l1, a1 = start.getHsl()
h2, s2, l2, a2 = end.getHsl()
components = _get_color_percentage(h1, s1, l1, a1, h2, s2, l2, a2, percent)
@@ -548,3 +561,54 @@ def interpolate_color(
out = out.convertTo(start.spec())
ensure_valid(out)
return out
+
+
+class LibraryPath(enum.Enum):
+
+ """A path to be passed to QLibraryInfo.
+
+ Should mirror QLibraryPath (Qt 5) and QLibraryLocation (Qt 6).
+ Values are the respective Qt names.
+ """
+
+ prefix = "PrefixPath"
+ documentation = "DocumentationPath"
+ headers = "HeadersPath"
+ libraries = "LibrariesPath"
+ library_executables = "LibraryExecutablesPath"
+ binaries = "BinariesPath"
+ plugins = "PluginsPath"
+ qml2_imports = "Qml2ImportsPath"
+ arch_data = "ArchDataPath"
+ data = "DataPath"
+ translations = "TranslationsPath"
+ examples = "ExamplesPath"
+ tests = "TestsPath"
+ settings = "SettingsPath"
+
+
+def library_path(which: LibraryPath) -> pathlib.Path:
+ """Wrapper around QLibraryInfo.path / .location."""
+ if machinery.IS_QT6:
+ val = getattr(QLibraryInfo.LibraryPath, which.value)
+ ret = QLibraryInfo.path(val)
+ else:
+ # Qt 5
+ val = getattr(QLibraryInfo.LibraryLocation, which.value)
+ ret = QLibraryInfo.location(val)
+ assert ret
+ return pathlib.Path(ret)
+
+
+def extract_enum_val(val: Union[sip.simplewrapper, int, enum.Enum]) -> int:
+ """Extract an int value from a Qt enum value.
+
+ For Qt 5, enum values are basically Python integers.
+ For Qt 6, they are usually enum.Enum instances, with the value set to the
+ integer.
+ """
+ if isinstance(val, enum.Enum):
+ return val.value
+ elif isinstance(val, sip.simplewrapper):
+ return int(val) # type: ignore[call-overload]
+ return val
diff --git a/qutebrowser/utils/standarddir.py b/qutebrowser/utils/standarddir.py
index 60d14dc79..b54e28d17 100644
--- a/qutebrowser/utils/standarddir.py
+++ b/qutebrowser/utils/standarddir.py
@@ -27,8 +27,8 @@ import enum
import argparse
from typing import Iterator, Optional
-from PyQt5.QtCore import QStandardPaths
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt.core import QStandardPaths
+from qutebrowser.qt.widgets import QApplication
from qutebrowser.utils import log, debug, utils, version
@@ -77,12 +77,12 @@ def _unset_organization() -> Iterator[None]:
def _init_config(args: Optional[argparse.Namespace]) -> None:
"""Initialize the location for configs."""
- typ = QStandardPaths.ConfigLocation
+ typ = QStandardPaths.StandardLocation.ConfigLocation
path = _from_args(typ, args)
if path is None:
if utils.is_windows:
app_data_path = _writable_location(
- QStandardPaths.AppDataLocation)
+ QStandardPaths.StandardLocation.AppDataLocation)
path = os.path.join(app_data_path, 'config')
else:
path = _writable_location(typ)
@@ -128,7 +128,7 @@ def config_py() -> str:
def _init_data(args: Optional[argparse.Namespace]) -> None:
"""Initialize the location for data."""
- typ = QStandardPaths.AppDataLocation
+ typ = QStandardPaths.StandardLocation.AppDataLocation
path = _from_args(typ, args)
if path is None:
if utils.is_windows:
@@ -136,7 +136,7 @@ def _init_data(args: Optional[argparse.Namespace]) -> None:
path = os.path.join(app_data_path, 'data')
elif sys.platform.startswith('haiku'):
# HaikuOS returns an empty value for AppDataLocation
- config_path = _writable_location(QStandardPaths.ConfigLocation)
+ config_path = _writable_location(QStandardPaths.StandardLocation.ConfigLocation)
path = os.path.join(config_path, 'data')
else:
path = _writable_location(typ)
@@ -169,12 +169,12 @@ def data(system: bool = False) -> str:
def _init_cache(args: Optional[argparse.Namespace]) -> None:
"""Initialize the location for the cache."""
- typ = QStandardPaths.CacheLocation
+ typ = QStandardPaths.StandardLocation.CacheLocation
path = _from_args(typ, args)
if path is None:
if utils.is_windows:
# Local, not Roaming!
- data_path = _writable_location(QStandardPaths.AppLocalDataLocation)
+ data_path = _writable_location(QStandardPaths.StandardLocation.AppLocalDataLocation)
path = os.path.join(data_path, 'cache')
else:
path = _writable_location(typ)
@@ -193,7 +193,7 @@ def _init_download(args: Optional[argparse.Namespace]) -> None:
Note this is only the default directory as found by Qt.
Therefore, we also don't create it.
"""
- typ = QStandardPaths.DownloadLocation
+ typ = QStandardPaths.StandardLocation.DownloadLocation
path = _from_args(typ, args)
if path is None:
path = _writable_location(typ)
@@ -208,9 +208,9 @@ def _init_runtime(args: Optional[argparse.Namespace]) -> None:
"""Initialize location for runtime data."""
if utils.is_mac or utils.is_windows:
# RuntimeLocation is a weird path on macOS and Windows.
- typ = QStandardPaths.TempLocation
+ typ = QStandardPaths.StandardLocation.TempLocation
else:
- typ = QStandardPaths.RuntimeLocation
+ typ = QStandardPaths.StandardLocation.RuntimeLocation
path = _from_args(typ, args)
if path is None:
@@ -218,10 +218,10 @@ def _init_runtime(args: Optional[argparse.Namespace]) -> None:
path = _writable_location(typ)
except EmptyValueError:
# Fall back to TempLocation when RuntimeLocation is misconfigured
- if typ == QStandardPaths.TempLocation:
+ if typ == QStandardPaths.StandardLocation.TempLocation:
raise
path = _writable_location( # pragma: no cover
- QStandardPaths.TempLocation)
+ QStandardPaths.StandardLocation.TempLocation)
# This is generic, but per-user.
# _writable_location makes sure we have a qutebrowser-specific subdir.
@@ -263,10 +263,10 @@ def _writable_location(typ: QStandardPaths.StandardLocation) -> str:
# Types we are sure we handle correctly below.
assert typ in [
- QStandardPaths.ConfigLocation, QStandardPaths.AppLocalDataLocation,
- QStandardPaths.CacheLocation, QStandardPaths.DownloadLocation,
- QStandardPaths.RuntimeLocation, QStandardPaths.TempLocation,
- QStandardPaths.AppDataLocation], typ_str
+ QStandardPaths.StandardLocation.ConfigLocation, QStandardPaths.StandardLocation.AppLocalDataLocation,
+ QStandardPaths.StandardLocation.CacheLocation, QStandardPaths.StandardLocation.DownloadLocation,
+ QStandardPaths.StandardLocation.RuntimeLocation, QStandardPaths.StandardLocation.TempLocation,
+ QStandardPaths.StandardLocation.AppDataLocation], typ_str
with _unset_organization():
path = QStandardPaths.writableLocation(typ)
@@ -281,7 +281,7 @@ def _writable_location(typ: QStandardPaths.StandardLocation) -> str:
# Add the application name to the given path if needed.
# This is in order for this to work without a QApplication (and thus
# QStandardsPaths not knowing the application name).
- if (typ != QStandardPaths.DownloadLocation and
+ if (typ != QStandardPaths.StandardLocation.DownloadLocation and
path.split(os.sep)[-1] != APPNAME):
path = os.path.join(path, APPNAME)
@@ -298,12 +298,12 @@ def _from_args(
The overridden path, or None if there is no override.
"""
basedir_suffix = {
- QStandardPaths.ConfigLocation: 'config',
- QStandardPaths.AppDataLocation: 'data',
- QStandardPaths.AppLocalDataLocation: 'data',
- QStandardPaths.CacheLocation: 'cache',
- QStandardPaths.DownloadLocation: 'download',
- QStandardPaths.RuntimeLocation: 'runtime',
+ QStandardPaths.StandardLocation.ConfigLocation: 'config',
+ QStandardPaths.StandardLocation.AppDataLocation: 'data',
+ QStandardPaths.StandardLocation.AppLocalDataLocation: 'data',
+ QStandardPaths.StandardLocation.CacheLocation: 'cache',
+ QStandardPaths.StandardLocation.DownloadLocation: 'download',
+ QStandardPaths.StandardLocation.RuntimeLocation: 'runtime',
}
if getattr(args, 'basedir', None) is None:
diff --git a/qutebrowser/utils/urlmatch.py b/qutebrowser/utils/urlmatch.py
index f14c2083d..81127d986 100644
--- a/qutebrowser/utils/urlmatch.py
+++ b/qutebrowser/utils/urlmatch.py
@@ -34,7 +34,7 @@ import fnmatch
import urllib.parse
from typing import Any, Optional, Tuple
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.utils import utils, qtutils
diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py
index cfba2c1d8..58862925e 100644
--- a/qutebrowser/utils/urlutils.py
+++ b/qutebrowser/utils/urlutils.py
@@ -28,8 +28,8 @@ import urllib.parse
import mimetypes
from typing import Optional, Tuple, Union, Iterable
-from PyQt5.QtCore import QUrl
-from PyQt5.QtNetwork import QHostInfo, QHostAddress, QNetworkProxy
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.network import QHostInfo, QHostAddress, QNetworkProxy
from qutebrowser.api import cmdutils
from qutebrowser.config import config
@@ -493,6 +493,19 @@ def same_domain(url1: QUrl, url2: QUrl) -> bool:
if url1.port() != url2.port():
return False
+ # QUrl.topLevelDomain() got removed in Qt 6:
+ # https://bugreports.qt.io/browse/QTBUG-80308
+ #
+ # However, we should never land here if we are on Qt 6:
+ #
+ # On QtWebEngine, we don't have a QNetworkAccessManager attached to a tab
+ # (all tab-specific downloads happen via the QtWebEngine network stack).
+ # Thus, ensure_valid(url2) above will raise InvalidUrlError, which is
+ # handled in NetworkManager.
+ #
+ # There are no other callers of same_domain, and url2 will only be ever valid when
+ # we use a NetworkManager from QtWebKit. However, QtWebKit is Qt 5 only.
+
suffix1 = url1.topLevelDomain()
suffix2 = url2.topLevelDomain()
if not suffix1:
@@ -522,7 +535,7 @@ def file_url(path: str) -> str:
path: The absolute path to the local file
"""
url = QUrl.fromLocalFile(path)
- return url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ return url.toString(QUrl.ComponentFormattingOption.FullyEncoded) # type: ignore[arg-type]
def data_url(mimetype: str, data: bytes) -> QUrl:
@@ -544,11 +557,11 @@ def safe_display_string(qurl: QUrl) -> str:
"""
ensure_valid(qurl)
- host = qurl.host(QUrl.FullyEncoded)
+ host = qurl.host(QUrl.ComponentFormattingOption.FullyEncoded)
assert '..' not in host, qurl # https://bugreports.qt.io/browse/QTBUG-60364
for part in host.split('.'):
- url_host = qurl.host(QUrl.FullyDecoded)
+ url_host = qurl.host(QUrl.ComponentFormattingOption.FullyDecoded)
if part.startswith('xn--') and host != url_host:
return '({}) {}'.format(host, qurl.toDisplayString())
@@ -581,10 +594,10 @@ def proxy_from_url(url: QUrl) -> Union[QNetworkProxy, pac.PACFetcher]:
return fetcher
types = {
- 'http': QNetworkProxy.HttpProxy,
- 'socks': QNetworkProxy.Socks5Proxy,
- 'socks5': QNetworkProxy.Socks5Proxy,
- 'direct': QNetworkProxy.NoProxy,
+ 'http': QNetworkProxy.ProxyType.HttpProxy,
+ 'socks': QNetworkProxy.ProxyType.Socks5Proxy,
+ 'socks5': QNetworkProxy.ProxyType.Socks5Proxy,
+ 'direct': QNetworkProxy.ProxyType.NoProxy,
}
if scheme not in types:
raise InvalidProxyTypeError(scheme)
@@ -613,7 +626,7 @@ def parse_javascript_url(url: QUrl) -> str:
raise Error("URL contains unexpected components: {}"
.format(url.authority()))
- urlstr = url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ urlstr = url.toString(QUrl.ComponentFormattingOption.FullyEncoded) # type: ignore[arg-type]
urlstr = urllib.parse.unquote(urlstr)
code = urlstr[len('javascript:'):]
diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py
index 56c29899d..aadda000b 100644
--- a/qutebrowser/utils/usertypes.py
+++ b/qutebrowser/utils/usertypes.py
@@ -25,8 +25,8 @@ import enum
import dataclasses
from typing import Optional, Sequence, TypeVar, Union
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QTimer
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QObject, QTimer
+from qutebrowser.qt.core import QUrl
from qutebrowser.utils import log, qtutils, utils
@@ -481,10 +481,18 @@ class Timer(QTimer):
super().start()
+class UndeferrableError(Exception):
+
+ """An AbstractCertificateErrorWrapper isn't deferrable."""
+
+
class AbstractCertificateErrorWrapper:
"""A wrapper over an SSL/certificate error."""
+ def __init__(self) -> None:
+ self._certificate_accepted: Optional[bool] = None
+
def __str__(self) -> str:
raise NotImplementedError
@@ -497,6 +505,23 @@ class AbstractCertificateErrorWrapper:
def html(self) -> str:
return f'<p>{html.escape(str(self))}</p>'
+ def accept_certificate(self) -> None:
+ self._certificate_accepted = True
+
+ def reject_certificate(self) -> None:
+ self._certificate_accepted = False
+
+ def defer(self) -> None:
+ raise NotImplementedError
+
+ def certificate_was_accepted(self) -> bool:
+ """Check whether the certificate was accepted by the user."""
+ if not self.is_overridable():
+ return False
+ if self._certificate_accepted is None:
+ raise ValueError("No decision taken yet")
+ return self._certificate_accepted
+
@dataclasses.dataclass
class NavigationRequest:
@@ -521,7 +546,7 @@ class NavigationRequest:
#: Navigation initiated by a history action.
back_forward = 5
#: Navigation initiated by refreshing the page.
- reloaded = 6
+ reload = 6
#: Navigation triggered automatically by page content or remote server
#: (QtWebEngine >= 5.14 only)
redirect = 7
diff --git a/qutebrowser/utils/utils.py b/qutebrowser/utils/utils.py
index 0c5074e3e..bd2746337 100644
--- a/qutebrowser/utils/utils.py
+++ b/qutebrowser/utils/utils.py
@@ -45,9 +45,9 @@ except ImportError: # pragma: no cover
"""Empty stub at runtime."""
-from PyQt5.QtCore import QUrl, QVersionNumber, QRect, QPoint
-from PyQt5.QtGui import QClipboard, QDesktopServices
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt.core import QUrl, QVersionNumber, QRect, QPoint
+from qutebrowser.qt.gui import QClipboard, QDesktopServices
+from qutebrowser.qt.widgets import QApplication
import yaml
try:
@@ -536,7 +536,7 @@ def set_clipboard(data: str, selection: bool = False) -> None:
log.misc.debug("Setting fake {}: {}".format(what, json.dumps(data)))
fake_clipboard = data
else:
- mode = QClipboard.Selection if selection else QClipboard.Clipboard
+ mode = QClipboard.Mode.Selection if selection else QClipboard.Mode.Clipboard
QApplication.clipboard().setText(data, mode=mode)
@@ -562,7 +562,7 @@ def get_clipboard(selection: bool = False, fallback: bool = False) -> str:
data = fake_clipboard
fake_clipboard = None
else:
- mode = QClipboard.Selection if selection else QClipboard.Clipboard
+ mode = QClipboard.Mode.Selection if selection else QClipboard.Mode.Clipboard
data = QApplication.clipboard().text(mode=mode)
target = "Primary selection" if selection else "Clipboard"
diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py
index e49d9bc42..d1bb7d495 100644
--- a/qutebrowser/utils/version.py
+++ b/qutebrowser/utils/version.py
@@ -26,7 +26,6 @@ import os.path
import platform
import subprocess
import importlib
-import collections
import pathlib
import configparser
import enum
@@ -37,26 +36,27 @@ import dataclasses
from typing import (Mapping, Optional, Sequence, Tuple, ClassVar, Dict, cast,
TYPE_CHECKING)
-
-from PyQt5.QtCore import PYQT_VERSION_STR, QLibraryInfo, qVersion
-from PyQt5.QtNetwork import QSslSocket
-from PyQt5.QtGui import (QOpenGLContext, QOpenGLVersionProfile,
- QOffscreenSurface)
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt import machinery
+from qutebrowser.qt.core import PYQT_VERSION_STR
+from qutebrowser.qt.network import QSslSocket
+from qutebrowser.qt.gui import QOpenGLContext, QOffscreenSurface
+from qutebrowser.qt.opengl import QOpenGLVersionProfile
+from qutebrowser.qt.widgets import QApplication
try:
- from PyQt5.QtWebKit import qWebKitVersion
+ from qutebrowser.qt.webkit import qWebKitVersion
except ImportError: # pragma: no cover
qWebKitVersion = None # type: ignore[assignment] # noqa: N816
try:
- from PyQt5.QtWebEngine import PYQT_WEBENGINE_VERSION_STR
+ from qutebrowser.qt.webenginecore import PYQT_WEBENGINE_VERSION_STR
except ImportError: # pragma: no cover
- # Added in PyQt 5.13
+ # QtWebKit
PYQT_WEBENGINE_VERSION_STR = None # type: ignore[assignment]
import qutebrowser
-from qutebrowser.utils import log, utils, standarddir, usertypes, message, resources
+from qutebrowser.utils import (log, utils, standarddir, usertypes, message, resources,
+ qtutils)
from qutebrowser.misc import objects, earlyinit, sql, httpclient, pastebin, elf
from qutebrowser.browser import pdfjs
from qutebrowser.config import config
@@ -393,23 +393,36 @@ class ModuleInfo:
return text
-MODULE_INFO: Mapping[str, ModuleInfo] = collections.OrderedDict([
- # FIXME: Mypy doesn't understand this. See https://github.com/python/mypy/issues/9706
- (name, ModuleInfo(name, *args)) # type: ignore[arg-type, misc]
- for (name, *args) in
- [
+def _create_module_info() -> Dict[str, ModuleInfo]:
+ packages = [
('sip', ['SIP_VERSION_STR']),
('colorama', ['VERSION', '__version__']),
('jinja2', ['__version__']),
('pygments', ['__version__']),
('yaml', ['__version__']),
('adblock', ['__version__'], "0.3.2"),
- ('PyQt5.QtWebEngineWidgets', []),
- ('PyQt5.QtWebEngine', ['PYQT_WEBENGINE_VERSION_STR']),
- ('PyQt5.QtWebKitWidgets', []),
('objc', ['__version__']),
]
-])
+
+ if machinery.IS_QT5:
+ packages += [
+ ('PyQt5.QtWebEngineWidgets', []),
+ ('PyQt5.QtWebEngine', ['PYQT_WEBENGINE_VERSION_STR']),
+ ('PyQt5.QtWebKitWidgets', []),
+ ]
+ elif machinery.IS_QT6:
+ packages.append(('PyQt6.QtWebEngineCore', ['PYQT_WEBENGINE_VERSION_STR']))
+ else:
+ raise utils.Unreachable()
+
+ # Mypy doesn't understand this. See https://github.com/python/mypy/issues/9706
+ return {
+ name: ModuleInfo(name, *args) # type: ignore[arg-type, misc]
+ for (name, *args) in packages
+ }
+
+
+MODULE_INFO: Mapping[str, ModuleInfo] = _create_module_info()
def _module_versions() -> Sequence[str]:
@@ -520,11 +533,17 @@ def _get_pyqt_webengine_qt_version() -> Optional[str]:
log.misc.debug("Neither importlib.metadata nor backport available")
return None
- for suffix in ['Qt5', 'Qt']:
+ names = (
+ ['PyQt6-WebEngine-Qt6']
+ if machinery.IS_QT6 else
+ ['PyQtWebEngine-Qt5', 'PyQtWebEngine-Qt']
+ )
+
+ for name in names:
try:
- return importlib_metadata.version(f'PyQtWebEngine-{suffix}')
+ return importlib_metadata.version(name)
except importlib_metadata.PackageNotFoundError:
- log.misc.debug(f"PyQtWebEngine-{suffix} not found")
+ log.misc.debug(f"{name} not found")
return None
@@ -540,46 +559,68 @@ class WebEngineVersions:
chromium_major: Optional[int] = dataclasses.field(init=False)
_CHROMIUM_VERSIONS: ClassVar[Dict[utils.VersionNumber, str]] = {
+ # ====== UNSUPPORTED =====
+
# Qt 5.12: Chromium 69
# (LTS) 69.0.3497.128 (~2018-09-11)
- # 5.12.0: Security fixes up to 70.0.3538.102 (~2018-10-24)
- # 5.12.1: Security fixes up to 71.0.3578.94 (2018-12-12)
- # 5.12.2: Security fixes up to 72.0.3626.121 (2019-03-01)
- # 5.12.3: Security fixes up to 73.0.3683.75 (2019-03-12)
- # 5.12.4: Security fixes up to 74.0.3729.157 (2019-05-14)
- # 5.12.5: Security fixes up to 76.0.3809.87 (2019-07-30)
- # 5.12.6: Security fixes up to 77.0.3865.120 (~2019-09-10)
- # 5.12.7: Security fixes up to 79.0.3945.130 (2020-01-16)
- # 5.12.8: Security fixes up to 80.0.3987.149 (2020-03-18)
- # 5.12.9: Security fixes up to 83.0.4103.97 (2020-06-03)
# 5.12.10: Security fixes up to 86.0.4240.75 (2020-10-06)
- utils.VersionNumber(5, 12): '69.0.3497.128',
# Qt 5.13: Chromium 73
# 73.0.3683.105 (~2019-02-28)
- # 5.13.0: Security fixes up to 74.0.3729.157 (2019-05-14)
- # 5.13.1: Security fixes up to 76.0.3809.87 (2019-07-30)
# 5.13.2: Security fixes up to 77.0.3865.120 (2019-10-10)
- utils.VersionNumber(5, 13): '73.0.3683.105',
# Qt 5.14: Chromium 77
# 77.0.3865.129 (~2019-10-10)
- # 5.14.0: Security fixes up to 77.0.3865.129 (~2019-09-10)
- # 5.14.1: Security fixes up to 79.0.3945.117 (2020-01-07)
# 5.14.2: Security fixes up to 80.0.3987.132 (2020-03-03)
- utils.VersionNumber(5, 14): '77.0.3865.129',
# Qt 5.15: Chromium 80
# 80.0.3987.163 (2020-04-02)
# 5.15.0: Security fixes up to 81.0.4044.138 (2020-05-05)
# 5.15.1: Security fixes up to 85.0.4183.83 (2020-08-25)
- # 5.15.2: Updated to 83.0.4103.122 (~2020-06-24)
- # Security fixes up to 86.0.4240.183 (2020-11-02)
- # 5.15.3: Updated to 87.0.4280.144 (~2020-12-02)
- # Security fixes up to 88.0.4324.150 (2021-02-04)
- utils.VersionNumber(5, 15): '80.0.3987.163',
+
+ # ====== SUPPORTED =====
+
+ # Qt 5.15.2: Chromium 83
+ # 83.0.4103.122 (~2020-06-24)
+ # 5.15.2: Security fixes up to 86.0.4240.183 (2020-11-02)
utils.VersionNumber(5, 15, 2): '83.0.4103.122',
- utils.VersionNumber(5, 15, 3): '87.0.4280.144',
+
+ # Qt 5.15.3: Chromium 87
+ # 87.0.4280.144 (~2020-12-02)
+ # 5.15.3: Security fixes up to 88.0.4324.150 (2021-02-04)
+ # 5.15.4: Security fixes up to ???
+ # 5.15.5: Security fixes up to ???
+ # 5.15.6: Security fixes up to ???
+ # 5.15.7: Security fixes up to 94.0.4606.61 (2021-09-24)
+ # 5.15.8: Security fixes up to 96.0.4664.110 (2021-12-13)
+ # 5.15.9: Security fixes up to 98.0.4758.102 (2022-02-14)
+ # 5.15.10: Security fixes up to ???
+ # 5.15.11: Security fixes up to ???
+ utils.VersionNumber(5, 15): '87.0.4280.144', # >= 5.15.3
+
+ # Qt 6.2: Chromium 90
+ # 90.0.4430.228 (2021-06-22)
+ # 6.2.0: Security fixes up to 93.0.4577.63 (2021-08-31)
+ # 6.2.1: Security fixes up to 94.0.4606.61 (2021-09-24)
+ # 6.2.2: Security fixes up to 96.0.4664.45 (2021-11-15)
+ # 6.2.3: Security fixes up to 96.0.4664.45 (2021-11-15)
+ # 6.2.4: Security fixes up to 98.0.4758.102 (2022-02-14)
+ # 6.2.5: Security fixes up to ???
+ # 6.2.6: Security fixes up to ???
+ utils.VersionNumber(6, 2): '90.0.4430.228',
+
+ # Qt 6.3: Chromium 94
+ # 94.0.4606.126 (2021-11-17)
+ # 6.3.0: Security fixes up to 99.0.4844.84 (2022-03-25)
+ # 6.3.1: Security fixes up to 101.0.4951.64 (2022-05-10)
+ # 6.3.2: Security fixes up to 104.0.5112.81 (2022-08-01)
+ utils.VersionNumber(6, 3): '94.0.4606.126',
+
+ # Qt 6.4: Chromium 102
+ # 102.0.5005.177 (~2022-05-24)
+ # 6.4.0: Security fixes up to 104.0.5112.102 (2022-08-16)
+ # 6.4.1: Security fixes up to 107.0.5304.88 (2022-10-27)
+ utils.VersionNumber(6, 4): '102.0.5005.177',
}
def __post_init__(self) -> None:
@@ -640,10 +681,9 @@ class WebEngineVersions:
return chromium_version
# 5.15 patch versions change their QtWebEngine version, but no changes are
- # expected after 5.15.3.
- v5_15_3 = utils.VersionNumber(5, 15, 3)
- if v5_15_3 <= pyqt_webengine_version < utils.VersionNumber(6):
- minor_version = v5_15_3
+ # expected after 5.15.3 and 5.15.[01] are unsupported.
+ if pyqt_webengine_version == utils.VersionNumber(5, 15, 2):
+ minor_version = pyqt_webengine_version
else:
# e.g. 5.14.2 -> 5.14
minor_version = pyqt_webengine_version.strip_patch()
@@ -651,7 +691,25 @@ class WebEngineVersions:
return cls._CHROMIUM_VERSIONS.get(minor_version)
@classmethod
- def from_importlib(cls, pyqt_webengine_qt_version: str) -> 'WebEngineVersions':
+ def from_api(cls, qtwe_version: str, chromium_version: str) -> 'WebEngineVersions':
+ """Get the versions based on the exact versions.
+
+ This is called if we have proper APIs to get the versions easily
+ (Qt 6.2 with PyQt 6.3.1+).
+ """
+ parsed = utils.VersionNumber.parse(qtwe_version)
+ return cls(
+ webengine=parsed,
+ chromium=chromium_version,
+ source='api',
+ )
+
+ @classmethod
+ def from_webengine(
+ cls,
+ pyqt_webengine_qt_version: str,
+ source: str,
+ ) -> 'WebEngineVersions':
"""Get the versions based on the PyQtWebEngine version.
This is called if we don't want to fully initialize QtWebEngine (so
@@ -662,11 +720,11 @@ class WebEngineVersions:
return cls(
webengine=parsed,
chromium=cls._infer_chromium_version(parsed),
- source='importlib',
+ source=source,
)
@classmethod
- def from_pyqt(cls, pyqt_webengine_version: str) -> 'WebEngineVersions':
+ def from_pyqt(cls, pyqt_webengine_version: str, source: str = "PyQt") -> 'WebEngineVersions':
"""Get the versions based on the PyQtWebEngine version.
This is the "last resort" if we don't want to fully initialize QtWebEngine (so
@@ -707,19 +765,6 @@ class WebEngineVersions:
return cls(
webengine=parsed,
chromium=cls._infer_chromium_version(parsed),
- source='PyQt',
- )
-
- @classmethod
- def from_qt(cls, qt_version: str, *, source: str = 'Qt') -> 'WebEngineVersions':
- """Get the versions based on the Qt version.
-
- This is called if we don't have PYQT_WEBENGINE_VERSION, i.e. with PyQt 5.12.
- """
- parsed = utils.VersionNumber.parse(qt_version)
- return cls(
- webengine=parsed,
- chromium=cls._infer_chromium_version(parsed),
source=source,
)
@@ -743,6 +788,24 @@ def qtwebengine_versions(*, avoid_init: bool = False) -> WebEngineVersions:
- https://www.chromium.org/developers/calendar
- https://chromereleases.googleblog.com/
"""
+ override = os.environ.get('QUTE_QTWEBENGINE_VERSION_OVERRIDE')
+ if override is not None:
+ return WebEngineVersions.from_pyqt(override, source='override')
+
+ if machinery.IS_QT6:
+ try:
+ from qutebrowser.qt.webenginecore import (
+ qWebEngineVersion,
+ qWebEngineChromiumVersion,
+ )
+ except ImportError:
+ pass # Needs QtWebEngine 6.2+ with PyQtWebEngine 6.3.1+
+ else:
+ return WebEngineVersions.from_api(
+ qtwe_version=qWebEngineVersion(),
+ chromium_version=qWebEngineChromiumVersion(),
+ )
+
from qutebrowser.browser.webengine import webenginesettings
if webenginesettings.parsed_user_agent is None and not avoid_init:
@@ -751,22 +814,17 @@ def qtwebengine_versions(*, avoid_init: bool = False) -> WebEngineVersions:
if webenginesettings.parsed_user_agent is not None:
return WebEngineVersions.from_ua(webenginesettings.parsed_user_agent)
- override = os.environ.get('QUTE_QTWEBENGINE_VERSION_OVERRIDE')
- if override is not None:
- return WebEngineVersions.from_qt(override, source='override')
-
versions = elf.parse_webenginecore()
if versions is not None:
return WebEngineVersions.from_elf(versions)
pyqt_webengine_qt_version = _get_pyqt_webengine_qt_version()
if pyqt_webengine_qt_version is not None:
- return WebEngineVersions.from_importlib(pyqt_webengine_qt_version)
-
- if PYQT_WEBENGINE_VERSION_STR is not None:
- return WebEngineVersions.from_pyqt(PYQT_WEBENGINE_VERSION_STR)
+ return WebEngineVersions.from_webengine(
+ pyqt_webengine_qt_version, source='importlib')
- return WebEngineVersions.from_qt(qVersion()) # type: ignore[unreachable]
+ assert PYQT_WEBENGINE_VERSION_STR is not None
+ return WebEngineVersions.from_pyqt(PYQT_WEBENGINE_VERSION_STR)
def _backend() -> str:
@@ -849,8 +907,8 @@ def version_info() -> str:
"Imported from {}".format(importpath),
"Using Python from {}".format(sys.executable),
"Qt library executable path: {}, data path: {}".format(
- QLibraryInfo.location(QLibraryInfo.LibraryExecutablesPath),
- QLibraryInfo.location(QLibraryInfo.DataPath)
+ qtutils.library_path(qtutils.LibraryPath.library_executables),
+ qtutils.library_path(qtutils.LibraryPath.data),
)
]
@@ -973,7 +1031,13 @@ def opengl_info() -> Optional[OpenGLInfo]: # pragma: no cover
vp.setVersion(2, 0)
try:
- vf = ctx.versionFunctions(vp)
+ if machinery.IS_QT5:
+ vf = ctx.versionFunctions(vp)
+ else:
+ # Qt 6
+ # FIXME:qt6 (lint)
+ from qutebrowser.qt.opengl import QOpenGLVersionFunctionsFactory
+ vf = QOpenGLVersionFunctionsFactory.get(vp, ctx)
except ImportError as e:
log.init.debug("Importing version functions failed: {}".format(e))
return None
diff --git a/scripts/dev/Makefile-dmg b/scripts/dev/Makefile-dmg
index 8749ce632..48743967d 100644
--- a/scripts/dev/Makefile-dmg
+++ b/scripts/dev/Makefile-dmg
@@ -24,7 +24,7 @@ SOURCE_DIR ?= .
SOURCE_FILES ?= dist/qutebrowser.app LICENSE
TEMPLATE_DMG ?= template.dmg
-TEMPLATE_SIZE ?= 500m
+TEMPLATE_SIZE ?= 750m
################################################################################
# DMG building. No editing should be needed beyond this point.
diff --git a/scripts/dev/build_release.py b/scripts/dev/build_release.py
index 18658f920..3ac48ad55 100755
--- a/scripts/dev/build_release.py
+++ b/scripts/dev/build_release.py
@@ -48,6 +48,10 @@ from scripts import utils
from scripts.dev import update_3rdparty, misc_checks
+IS_MACOS = sys.platform == 'darwin'
+IS_WINDOWS = os.name == 'nt'
+
+
@dataclasses.dataclass
class Artifact:
@@ -134,43 +138,65 @@ def _smoke_test_run(
return subprocess.run(argv, check=True, capture_output=True)
-def smoke_test(executable: pathlib.Path, debug: bool) -> None:
+def smoke_test(executable: pathlib.Path, debug: bool, qt6: bool) -> None:
"""Try starting the given qutebrowser executable."""
stdout_whitelist = []
stderr_whitelist = [
# PyInstaller debug output
r'\[.*\] PyInstaller Bootloader .*',
r'\[.*\] LOADER: .*',
-
- # https://github.com/qutebrowser/qutebrowser/issues/4919
- (r'objc\[.*\]: .* One of the two will be used\. '
- r'Which one is undefined\.'),
- (r'QCoreApplication::applicationDirPath: Please instantiate the '
- r'QApplication object first'),
- (r'\[.*:ERROR:mach_port_broker.mm\(48\)\] bootstrap_look_up '
- r'org\.chromium\.Chromium\.rohitfork\.1: Permission denied \(1100\)'),
- (r'\[.*:ERROR:mach_port_broker.mm\(43\)\] bootstrap_look_up: '
- r'Unknown service name \(1102\)'),
-
- (r'[0-9:]* WARNING: The available OpenGL surface format was either not '
- r'version 3\.2 or higher or not a Core Profile\.'),
- r'Chromium on macOS will fall back to software rendering in this case\.',
- r'Hardware acceleration and features such as WebGL will not be available\.',
- r'Unable to create basic Accelerated OpenGL renderer\.',
- r'Core Image is now using the software OpenGL renderer\. This will be slow\.',
-
- # Windows N:
- # https://github.com/microsoft/playwright/issues/2901
- (r'\[.*:ERROR:dxva_video_decode_accelerator_win.cc\(\d+\)\] '
- r'DXVAVDA fatal error: could not LoadLibrary: .*: The specified '
- r'module could not be found. \(0x7E\)'),
-
- # https://github.com/qutebrowser/qutebrowser/issues/3719
- '[0-9:]* ERROR: Load error: ERR_FILE_NOT_FOUND',
-
- # macOS 11
- (r'[0-9:]* WARNING: Failed to load libssl/libcrypto\.'),
]
+ if IS_MACOS:
+ stderr_whitelist.extend([
+ # macOS on Qt 5.15
+ # https://github.com/qutebrowser/qutebrowser/issues/4919
+ (r'objc\[.*\]: .* One of the two will be used\. '
+ r'Which one is undefined\.'),
+ (r'QCoreApplication::applicationDirPath: Please instantiate the '
+ r'QApplication object first'),
+ (r'\[.*:ERROR:mach_port_broker.mm\(48\)\] bootstrap_look_up '
+ r'org\.chromium\.Chromium\.rohitfork\.1: Permission denied \(1100\)'),
+ (r'\[.*:ERROR:mach_port_broker.mm\(43\)\] bootstrap_look_up: '
+ r'Unknown service name \(1102\)'),
+
+ # macOS on Qt 5.15
+ (r'[0-9:]* WARNING: The available OpenGL surface format was either not '
+ r'version 3\.2 or higher or not a Core Profile\.'),
+ r'Chromium on macOS will fall back to software rendering in this case\.',
+ r'Hardware acceleration and features such as WebGL will not be available\.',
+ r'Unable to create basic Accelerated OpenGL renderer\.',
+ r'Core Image is now using the software OpenGL renderer\. This will be slow\.',
+
+ # https://github.com/qutebrowser/qutebrowser/issues/3719
+ '[0-9:]* ERROR: Load error: ERR_FILE_NOT_FOUND',
+
+ # macOS 11
+ (r'[0-9:]* WARNING: Failed to load libssl/libcrypto\.'),
+ ])
+ if qt6:
+ stderr_whitelist.extend([
+ # FIXME:qt6 Qt 6.3 on macOS
+ r'[0-9:]* WARNING: Incompatible version of OpenSSL',
+ r'[0-9:]* WARNING: Qt WebEngine resources not found at .*',
+ (r'[0-9:]* WARNING: Installed Qt WebEngine locales directory not found at '
+ r'location /qtwebengine_locales\. Trying application directory\.\.\.'),
+
+ # https://github.com/pyinstaller/pyinstaller/pull/6903
+ r"[0-9:]* INFO: Sandboxing disabled by user\.",
+
+ # macOS?
+ (r'\[.*:ERROR:command_buffer_proxy_impl.cc\([0-9]*\)\] '
+ r'ContextResult::kTransientFailure: Failed to send '
+ r'GpuControl\.CreateCommandBuffer\.'),
+ ])
+ elif IS_WINDOWS:
+ stderr_whitelist.extend([
+ # Windows N:
+ # https://github.com/microsoft/playwright/issues/2901
+ (r'\[.*:ERROR:dxva_video_decode_accelerator_win.cc\(\d+\)\] '
+ r'DXVAVDA fatal error: could not LoadLibrary: .*: The specified '
+ r'module could not be found. \(0x7E\)'),
+ ])
proc = _smoke_test_run(executable)
if debug:
@@ -233,23 +259,19 @@ def verify_windows_exe(exe_path: pathlib.Path) -> None:
assert pe.verify_checksum()
-def patch_mac_app() -> None:
+def patch_mac_app(qt6: bool) -> None:
"""Patch .app to save some space and make it signable."""
dist_path = pathlib.Path('dist')
+ ver = '6' if qt6 else '5'
app_path = dist_path / 'qutebrowser.app'
contents_path = app_path / 'Contents'
macos_path = contents_path / 'MacOS'
resources_path = contents_path / 'Resources'
- pyqt_path = macos_path / 'PyQt5'
+ pyqt_path = macos_path / f'PyQt{ver}'
# Replace some duplicate files by symlinks
- framework_path = pyqt_path / 'Qt5' / 'lib' / 'QtWebEngineCore.framework'
-
- core_lib = framework_path / 'Versions' / '5' / 'QtWebEngineCore'
- core_lib.unlink()
- core_target = pathlib.Path(*[os.pardir] * 7, 'MacOS', 'QtWebEngineCore')
- core_lib.symlink_to(core_target)
+ framework_path = pyqt_path / f'Qt{ver}' / 'lib' / 'QtWebEngineCore.framework'
framework_resource_path = framework_path / 'Resources'
for file_path in framework_resource_path.iterdir():
@@ -260,6 +282,16 @@ def patch_mac_app() -> None:
file_path.unlink()
file_path.symlink_to(target)
+ if qt6:
+ # Symlinking QtWebEngineCore.framework does not seem to work with Qt 6.
+ # Also, the symlinking/moving before signing doesn't seem to be required.
+ return
+
+ core_lib = framework_path / 'Versions' / '5' / 'QtWebEngineCore'
+ core_lib.unlink()
+ core_target = pathlib.Path(*[os.pardir] * 7, 'MacOS', 'QtWebEngineCore')
+ core_lib.symlink_to(core_target)
+
# Move stuff around to make things signable on macOS
# See https://github.com/pyinstaller/pyinstaller/issues/6612
pyqt_path_dest = resources_path / pyqt_path.name
@@ -303,6 +335,7 @@ def _mac_bin_path(base: pathlib.Path) -> pathlib.Path:
def build_mac(
*,
gh_token: Optional[str],
+ qt6: bool,
skip_packaging: bool,
debug: bool,
) -> List[Artifact]:
@@ -317,21 +350,20 @@ def build_mac(
shutil.rmtree(d, ignore_errors=True)
utils.print_title("Updating 3rdparty content")
- # FIXME:qt6 Use modern PDF.js version here
- update_3rdparty.run(ace=False, pdfjs=True, legacy_pdfjs=True, fancy_dmg=False,
+ update_3rdparty.run(ace=False, pdfjs=True, legacy_pdfjs=not qt6, fancy_dmg=False,
gh_token=gh_token)
utils.print_title("Building .app via pyinstaller")
- call_tox('pyinstaller-64bit', '-r', debug=debug)
+ call_tox(f'pyinstaller-64bit{"-qt6" if qt6 else ""}', '-r', debug=debug)
utils.print_title("Patching .app")
- patch_mac_app()
+ patch_mac_app(qt6=qt6)
utils.print_title("Re-signing .app")
sign_mac_app()
dist_path = pathlib.Path("dist")
utils.print_title("Running pre-dmg smoke test")
- smoke_test(_mac_bin_path(dist_path), debug=debug)
+ smoke_test(_mac_bin_path(dist_path), debug=debug, qt6=qt6)
if skip_packaging:
return []
@@ -341,6 +373,7 @@ def build_mac(
subprocess.run(['make', '-f', dmg_makefile_path], check=True)
suffix = "-debug" if debug else ""
+ suffix += "-qt6" if qt6 else ""
dmg_path = dist_path / f'qutebrowser-{qutebrowser.__version__}{suffix}.dmg'
pathlib.Path('qutebrowser.dmg').rename(dmg_path)
@@ -352,7 +385,7 @@ def build_mac(
subprocess.run(['hdiutil', 'attach', dmg_path,
'-mountpoint', tmp_path], check=True)
try:
- smoke_test(_mac_bin_path(tmp_path), debug=debug)
+ smoke_test(_mac_bin_path(tmp_path), debug=debug, qt6=qt6)
finally:
print("Waiting 10s for dmg to be detachable...")
time.sleep(10)
@@ -391,6 +424,7 @@ def _get_windows_python_path(x64: bool) -> pathlib.Path:
def _build_windows_single(
*, x64: bool,
+ qt6: bool,
skip_packaging: bool,
debug: bool,
) -> List[Artifact]:
@@ -404,12 +438,11 @@ def _build_windows_single(
_maybe_remove(out_path)
python = _get_windows_python_path(x64=x64)
- call_tox(
- f'pyinstaller-{"64bit" if x64 else "32bit"}',
- '-r',
- python=python,
- debug=debug,
- )
+ suffix = "64bit" if x64 else "32bit"
+ if qt6:
+ # FIXME:qt6 does this regress 391623d5ec983ecfc4512c7305c4b7a293ac3872?
+ suffix += "-qt6"
+ call_tox(f'pyinstaller-{suffix}', '-r', python=python, debug=debug)
out_pyinstaller = dist_path / "qutebrowser"
shutil.move(out_pyinstaller, out_path)
@@ -419,7 +452,7 @@ def _build_windows_single(
verify_windows_exe(exe_path)
utils.print_title(f"Running {human_arch} smoke test")
- smoke_test(exe_path, debug=debug)
+ smoke_test(exe_path, debug=debug, qt6=qt6)
if skip_packaging:
return []
@@ -432,6 +465,7 @@ def _build_windows_single(
desc_arch=human_arch,
desc_suffix='' if x64 else ' (only for 32-bit Windows!)',
debug=debug,
+ qt6=qt6,
)
@@ -440,12 +474,12 @@ def build_windows(
skip_packaging: bool,
only_32bit: bool,
only_64bit: bool,
+ qt6: bool,
debug: bool,
) -> List[Artifact]:
"""Build windows executables/setups."""
utils.print_title("Updating 3rdparty content")
- # FIXME:qt6 Use modern PDF.js version here
- update_3rdparty.run(nsis=True, ace=False, pdfjs=True, legacy_pdfjs=True,
+ update_3rdparty.run(nsis=True, ace=False, pdfjs=True, legacy_pdfjs=not qt6,
fancy_dmg=False, gh_token=gh_token)
utils.print_title("Building Windows binaries")
@@ -461,12 +495,14 @@ def build_windows(
x64=True,
skip_packaging=skip_packaging,
debug=debug,
+ qt6=qt6,
)
- if not only_64bit:
+ if not only_64bit and not qt6:
artifacts += _build_windows_single(
x64=False,
skip_packaging=skip_packaging,
debug=debug,
+ qt6=qt6,
)
return artifacts
@@ -480,6 +516,7 @@ def _package_windows_single(
desc_suffix: str,
filename_arch: str,
debug: bool,
+ qt6: bool,
) -> List[Artifact]:
"""Build the given installer/zip for windows."""
artifacts = []
@@ -497,6 +534,8 @@ def _package_windows_single(
]
if debug:
name_parts.append('debug')
+ if qt6:
+ name_parts.append('qt6')
name = '-'.join(name_parts) + '.exe'
artifacts.append(Artifact(
@@ -515,6 +554,8 @@ def _package_windows_single(
]
if debug:
zip_name_parts.append('debug')
+ if qt6:
+ zip_name_parts.append('qt6')
zip_name = '-'.join(zip_name_parts) + '.zip'
zip_path = dist_path / zip_name
@@ -699,6 +740,8 @@ def main() -> None:
help="Skip Windows 32 bit build.", dest='only_64bit')
parser.add_argument('--debug', action='store_true', required=False,
help="Build a debug build.")
+ parser.add_argument('--qt6', action='store_true', required=False,
+ help="Build against PyQt6")
args = parser.parse_args()
utils.change_cwd()
@@ -721,18 +764,20 @@ def main() -> None:
else:
run_asciidoc2html()
- if os.name == 'nt':
+ if IS_WINDOWS:
artifacts = build_windows(
gh_token=gh_token,
skip_packaging=args.skip_packaging,
only_32bit=args.only_32bit,
only_64bit=args.only_64bit,
+ qt6=args.qt6,
debug=args.debug,
)
- elif sys.platform == 'darwin':
+ elif IS_MACOS:
artifacts = build_mac(
gh_token=gh_token,
skip_packaging=args.skip_packaging,
+ qt6=args.qt6,
debug=args.debug,
)
else:
diff --git a/scripts/dev/changelog_urls.json b/scripts/dev/changelog_urls.json
index 144723772..1946017b3 100644
--- a/scripts/dev/changelog_urls.json
+++ b/scripts/dev/changelog_urls.json
@@ -103,6 +103,11 @@
"PyQt5-sip": "https://www.riverbankcomputing.com/news",
"PyQt5-stubs": "https://github.com/python-qt-tools/PyQt5-stubs/blob/master/CHANGELOG.md",
"sip": "https://www.riverbankcomputing.com/news",
+ "PyQt6": "https://www.riverbankcomputing.com/news",
+ "PyQt6-Qt6": "https://www.riverbankcomputing.com/news",
+ "PyQt6-WebEngine": "https://www.riverbankcomputing.com/news",
+ "PyQt6-WebEngine-Qt6": "https://www.riverbankcomputing.com/news",
+ "PyQt6-sip": "https://www.riverbankcomputing.com/news",
"Pygments": "https://pygments.org/docs/changelog/",
"vulture": "https://github.com/jendrikseipp/vulture/blob/main/CHANGELOG.md",
"distlib": "https://github.com/pypa/distlib/blob/master/CHANGES.rst",
diff --git a/scripts/dev/ci/docker/Dockerfile.j2 b/scripts/dev/ci/docker/Dockerfile.j2
index 48e7c6de0..0ca7d330d 100644
--- a/scripts/dev/ci/docker/Dockerfile.j2
+++ b/scripts/dev/ci/docker/Dockerfile.j2
@@ -9,10 +9,19 @@ RUN pacman -Su --noconfirm \
git \
python-tox \
python-distlib \
+ {% if qt6 %}
+ qt6-base \
+ qt6-declarative \
+ {% if webengine %}
+ qt6-webengine python-pyqt6-webengine \
+ {% else %}{{ 1/0 }}{% endif %}
+ python-pyqt6 \
+ {% else %}
qt5-base \
qt5-declarative \
{% if webengine %}
qt5-webengine python-pyqtwebengine \
+ {% endif %}
python-pyqt5 \
{% endif %}
xorg-xinit \
@@ -28,10 +37,15 @@ RUN pacman -U --noconfirm \
https://archive.archlinux.org/packages/p/python-pyqt5/python-pyqt5-5.15.7-2-x86_64.pkg.tar.zst
{% endif %}
+{% if qt6 %}
+ {% set pyqt_module = 'PyQt6' %}
+{% else %}
+ {% set pyqt_module = 'PyQt5' %}
+{% endif %}
{% if webengine %}
-RUN python3 -c "from PyQt5 import QtWebEngineCore, QtWebEngineWidgets"
+ RUN python3 -c "from {{ pyqt_module }} import QtWebEngineCore, QtWebEngineWidgets"
{% else %}
-RUN python3 -c "from PyQt5 import QtWebKit, QtWebKitWidgets"
+ RUN python3 -c "from {{ pyqt_module }} import QtWebKit, QtWebKitWidgets"
{% endif %}
RUN useradd user -u 1001 && \
diff --git a/scripts/dev/ci/docker/generate.py b/scripts/dev/ci/docker/generate.py
index 34619a668..763a04ecf 100644
--- a/scripts/dev/ci/docker/generate.py
+++ b/scripts/dev/ci/docker/generate.py
@@ -31,9 +31,10 @@ def main():
image = sys.argv[1]
config = {
- 'archlinux-webkit': {'webengine': False, 'unstable': False},
- 'archlinux-webengine': {'webengine': True, 'unstable': False},
- 'archlinux-webengine-unstable': {'webengine': True, 'unstable': True},
+ 'archlinux-webkit': {'webengine': False, 'unstable': False, 'qt6': False},
+ 'archlinux-webengine': {'webengine': True, 'unstable': False, 'qt6': False},
+ 'archlinux-webengine-qt6': {'webengine': True, 'unstable': False, 'qt6': True},
+ 'archlinux-webengine-unstable': {'webengine': True, 'unstable': True, 'qt6': False},
}[image]
with open('Dockerfile', 'w') as f:
diff --git a/scripts/dev/enums.txt b/scripts/dev/enums.txt
new file mode 100644
index 000000000..356a8a647
--- /dev/null
+++ b/scripts/dev/enums.txt
@@ -0,0 +1,7970 @@
+Qt.Round Qt.HighDpiScaleFactorRoundingPolicy.Round
+Qt.Ceil Qt.HighDpiScaleFactorRoundingPolicy.Ceil
+Qt.Floor Qt.HighDpiScaleFactorRoundingPolicy.Floor
+Qt.RoundPreferFloor Qt.HighDpiScaleFactorRoundingPolicy.RoundPreferFloor
+Qt.PassThrough Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
+Qt.ChecksumIso3309 Qt.ChecksumType.ChecksumIso3309
+Qt.ChecksumItuV41 Qt.ChecksumType.ChecksumItuV41
+Qt.EnterKeyDefault Qt.EnterKeyType.EnterKeyDefault
+Qt.EnterKeyReturn Qt.EnterKeyType.EnterKeyReturn
+Qt.EnterKeyDone Qt.EnterKeyType.EnterKeyDone
+Qt.EnterKeyGo Qt.EnterKeyType.EnterKeyGo
+Qt.EnterKeySend Qt.EnterKeyType.EnterKeySend
+Qt.EnterKeySearch Qt.EnterKeyType.EnterKeySearch
+Qt.EnterKeyNext Qt.EnterKeyType.EnterKeyNext
+Qt.EnterKeyPrevious Qt.EnterKeyType.EnterKeyPrevious
+Qt.ReplaceSelection Qt.ItemSelectionOperation.ReplaceSelection
+Qt.AddToSelection Qt.ItemSelectionOperation.AddToSelection
+Qt.NoTabFocus Qt.TabFocusBehavior.NoTabFocus
+Qt.TabFocusTextControls Qt.TabFocusBehavior.TabFocusTextControls
+Qt.TabFocusListControls Qt.TabFocusBehavior.TabFocusListControls
+Qt.TabFocusAllControls Qt.TabFocusBehavior.TabFocusAllControls
+Qt.MouseEventCreatedDoubleClick Qt.MouseEventFlag.MouseEventCreatedDoubleClick
+Qt.MouseEventNotSynthesized Qt.MouseEventSource.MouseEventNotSynthesized
+Qt.MouseEventSynthesizedBySystem Qt.MouseEventSource.MouseEventSynthesizedBySystem
+Qt.MouseEventSynthesizedByQt Qt.MouseEventSource.MouseEventSynthesizedByQt
+Qt.MouseEventSynthesizedByApplication Qt.MouseEventSource.MouseEventSynthesizedByApplication
+Qt.ScrollBegin Qt.ScrollPhase.ScrollBegin
+Qt.ScrollUpdate Qt.ScrollPhase.ScrollUpdate
+Qt.ScrollEnd Qt.ScrollPhase.ScrollEnd
+Qt.NoScrollPhase Qt.ScrollPhase.NoScrollPhase
+Qt.ScrollMomentum Qt.ScrollPhase.ScrollMomentum
+Qt.BeginNativeGesture Qt.NativeGestureType.BeginNativeGesture
+Qt.EndNativeGesture Qt.NativeGestureType.EndNativeGesture
+Qt.PanNativeGesture Qt.NativeGestureType.PanNativeGesture
+Qt.ZoomNativeGesture Qt.NativeGestureType.ZoomNativeGesture
+Qt.SmartZoomNativeGesture Qt.NativeGestureType.SmartZoomNativeGesture
+Qt.RotateNativeGesture Qt.NativeGestureType.RotateNativeGesture
+Qt.SwipeNativeGesture Qt.NativeGestureType.SwipeNativeGesture
+Qt.TopEdge Qt.Edge.TopEdge
+Qt.LeftEdge Qt.Edge.LeftEdge
+Qt.RightEdge Qt.Edge.RightEdge
+Qt.BottomEdge Qt.Edge.BottomEdge
+Qt.ApplicationSuspended Qt.ApplicationState.ApplicationSuspended
+Qt.ApplicationHidden Qt.ApplicationState.ApplicationHidden
+Qt.ApplicationInactive Qt.ApplicationState.ApplicationInactive
+Qt.ApplicationActive Qt.ApplicationState.ApplicationActive
+Qt.ExactHit Qt.HitTestAccuracy.ExactHit
+Qt.FuzzyHit Qt.HitTestAccuracy.FuzzyHit
+Qt.WhiteSpaceNormal Qt.WhiteSpaceMode.WhiteSpaceNormal
+Qt.WhiteSpacePre Qt.WhiteSpaceMode.WhiteSpacePre
+Qt.WhiteSpaceNoWrap Qt.WhiteSpaceMode.WhiteSpaceNoWrap
+Qt.WhiteSpaceModeUndefined Qt.WhiteSpaceMode.WhiteSpaceModeUndefined
+Qt.FindDirectChildrenOnly Qt.FindChildOption.FindDirectChildrenOnly
+Qt.FindChildrenRecursively Qt.FindChildOption.FindChildrenRecursively
+Qt.PrimaryOrientation Qt.ScreenOrientation.PrimaryOrientation
+Qt.PortraitOrientation Qt.ScreenOrientation.PortraitOrientation
+Qt.LandscapeOrientation Qt.ScreenOrientation.LandscapeOrientation
+Qt.InvertedPortraitOrientation Qt.ScreenOrientation.InvertedPortraitOrientation
+Qt.InvertedLandscapeOrientation Qt.ScreenOrientation.InvertedLandscapeOrientation
+Qt.LogicalMoveStyle Qt.CursorMoveStyle.LogicalMoveStyle
+Qt.VisualMoveStyle Qt.CursorMoveStyle.VisualMoveStyle
+Qt.NavigationModeNone Qt.NavigationMode.NavigationModeNone
+Qt.NavigationModeKeypadTabOrder Qt.NavigationMode.NavigationModeKeypadTabOrder
+Qt.NavigationModeKeypadDirectional Qt.NavigationMode.NavigationModeKeypadDirectional
+Qt.NavigationModeCursorAuto Qt.NavigationMode.NavigationModeCursorAuto
+Qt.NavigationModeCursorForceVisible Qt.NavigationMode.NavigationModeCursorForceVisible
+Qt.DontStartGestureOnChildren Qt.GestureFlag.DontStartGestureOnChildren
+Qt.ReceivePartialGestures Qt.GestureFlag.ReceivePartialGestures
+Qt.IgnoredGesturesPropagateToParent Qt.GestureFlag.IgnoredGesturesPropagateToParent
+Qt.TapGesture Qt.GestureType.TapGesture
+Qt.TapAndHoldGesture Qt.GestureType.TapAndHoldGesture
+Qt.PanGesture Qt.GestureType.PanGesture
+Qt.PinchGesture Qt.GestureType.PinchGesture
+Qt.SwipeGesture Qt.GestureType.SwipeGesture
+Qt.CustomGesture Qt.GestureType.CustomGesture
+Qt.GestureStarted Qt.GestureState.GestureStarted
+Qt.GestureUpdated Qt.GestureState.GestureUpdated
+Qt.GestureFinished Qt.GestureState.GestureFinished
+Qt.GestureCanceled Qt.GestureState.GestureCanceled
+Qt.TouchPointPressed Qt.TouchPointState.TouchPointPressed
+Qt.TouchPointMoved Qt.TouchPointState.TouchPointMoved
+Qt.TouchPointStationary Qt.TouchPointState.TouchPointStationary
+Qt.TouchPointReleased Qt.TouchPointState.TouchPointReleased
+Qt.DeviceCoordinates Qt.CoordinateSystem.DeviceCoordinates
+Qt.LogicalCoordinates Qt.CoordinateSystem.LogicalCoordinates
+Qt.AnchorLeft Qt.AnchorPoint.AnchorLeft
+Qt.AnchorHorizontalCenter Qt.AnchorPoint.AnchorHorizontalCenter
+Qt.AnchorRight Qt.AnchorPoint.AnchorRight
+Qt.AnchorTop Qt.AnchorPoint.AnchorTop
+Qt.AnchorVerticalCenter Qt.AnchorPoint.AnchorVerticalCenter
+Qt.AnchorBottom Qt.AnchorPoint.AnchorBottom
+Qt.ImhNone Qt.InputMethodHint.ImhNone
+Qt.ImhHiddenText Qt.InputMethodHint.ImhHiddenText
+Qt.ImhNoAutoUppercase Qt.InputMethodHint.ImhNoAutoUppercase
+Qt.ImhPreferNumbers Qt.InputMethodHint.ImhPreferNumbers
+Qt.ImhPreferUppercase Qt.InputMethodHint.ImhPreferUppercase
+Qt.ImhPreferLowercase Qt.InputMethodHint.ImhPreferLowercase
+Qt.ImhNoPredictiveText Qt.InputMethodHint.ImhNoPredictiveText
+Qt.ImhDigitsOnly Qt.InputMethodHint.ImhDigitsOnly
+Qt.ImhFormattedNumbersOnly Qt.InputMethodHint.ImhFormattedNumbersOnly
+Qt.ImhUppercaseOnly Qt.InputMethodHint.ImhUppercaseOnly
+Qt.ImhLowercaseOnly Qt.InputMethodHint.ImhLowercaseOnly
+Qt.ImhDialableCharactersOnly Qt.InputMethodHint.ImhDialableCharactersOnly
+Qt.ImhEmailCharactersOnly Qt.InputMethodHint.ImhEmailCharactersOnly
+Qt.ImhUrlCharactersOnly Qt.InputMethodHint.ImhUrlCharactersOnly
+Qt.ImhExclusiveInputMask Qt.InputMethodHint.ImhExclusiveInputMask
+Qt.ImhSensitiveData Qt.InputMethodHint.ImhSensitiveData
+Qt.ImhDate Qt.InputMethodHint.ImhDate
+Qt.ImhTime Qt.InputMethodHint.ImhTime
+Qt.ImhPreferLatin Qt.InputMethodHint.ImhPreferLatin
+Qt.ImhLatinOnly Qt.InputMethodHint.ImhLatinOnly
+Qt.ImhMultiLine Qt.InputMethodHint.ImhMultiLine
+Qt.ImhNoEditMenu Qt.InputMethodHint.ImhNoEditMenu
+Qt.ImhNoTextHandles Qt.InputMethodHint.ImhNoTextHandles
+Qt.StretchTile Qt.TileRule.StretchTile
+Qt.RepeatTile Qt.TileRule.RepeatTile
+Qt.RoundTile Qt.TileRule.RoundTile
+Qt.NoSection Qt.WindowFrameSection.NoSection
+Qt.LeftSection Qt.WindowFrameSection.LeftSection
+Qt.TopLeftSection Qt.WindowFrameSection.TopLeftSection
+Qt.TopSection Qt.WindowFrameSection.TopSection
+Qt.TopRightSection Qt.WindowFrameSection.TopRightSection
+Qt.RightSection Qt.WindowFrameSection.RightSection
+Qt.BottomRightSection Qt.WindowFrameSection.BottomRightSection
+Qt.BottomSection Qt.WindowFrameSection.BottomSection
+Qt.BottomLeftSection Qt.WindowFrameSection.BottomLeftSection
+Qt.TitleBarArea Qt.WindowFrameSection.TitleBarArea
+Qt.MinimumSize Qt.SizeHint.MinimumSize
+Qt.PreferredSize Qt.SizeHint.PreferredSize
+Qt.MaximumSize Qt.SizeHint.MaximumSize
+Qt.MinimumDescent Qt.SizeHint.MinimumDescent
+Qt.AbsoluteSize Qt.SizeMode.AbsoluteSize
+Qt.RelativeSize Qt.SizeMode.RelativeSize
+Qt.HighEventPriority Qt.EventPriority.HighEventPriority
+Qt.NormalEventPriority Qt.EventPriority.NormalEventPriority
+Qt.LowEventPriority Qt.EventPriority.LowEventPriority
+Qt.XAxis Qt.Axis.XAxis
+Qt.YAxis Qt.Axis.YAxis
+Qt.ZAxis Qt.Axis.ZAxis
+Qt.MaskInColor Qt.MaskMode.MaskInColor
+Qt.MaskOutColor Qt.MaskMode.MaskOutColor
+Qt.NoTextInteraction Qt.TextInteractionFlag.NoTextInteraction
+Qt.TextSelectableByMouse Qt.TextInteractionFlag.TextSelectableByMouse
+Qt.TextSelectableByKeyboard Qt.TextInteractionFlag.TextSelectableByKeyboard
+Qt.LinksAccessibleByMouse Qt.TextInteractionFlag.LinksAccessibleByMouse
+Qt.LinksAccessibleByKeyboard Qt.TextInteractionFlag.LinksAccessibleByKeyboard
+Qt.TextEditable Qt.TextInteractionFlag.TextEditable
+Qt.TextEditorInteraction Qt.TextInteractionFlag.TextEditorInteraction
+Qt.TextBrowserInteraction Qt.TextInteractionFlag.TextBrowserInteraction
+Qt.ContainsItemShape Qt.ItemSelectionMode.ContainsItemShape
+Qt.IntersectsItemShape Qt.ItemSelectionMode.IntersectsItemShape
+Qt.ContainsItemBoundingRect Qt.ItemSelectionMode.ContainsItemBoundingRect
+Qt.IntersectsItemBoundingRect Qt.ItemSelectionMode.IntersectsItemBoundingRect
+Qt.AA_ImmediateWidgetCreation Qt.ApplicationAttribute.AA_ImmediateWidgetCreation
+Qt.AA_MSWindowsUseDirect3DByDefault Qt.ApplicationAttribute.AA_MSWindowsUseDirect3DByDefault
+Qt.AA_DontShowIconsInMenus Qt.ApplicationAttribute.AA_DontShowIconsInMenus
+Qt.AA_NativeWindows Qt.ApplicationAttribute.AA_NativeWindows
+Qt.AA_DontCreateNativeWidgetSiblings Qt.ApplicationAttribute.AA_DontCreateNativeWidgetSiblings
+Qt.AA_MacPluginApplication Qt.ApplicationAttribute.AA_MacPluginApplication
+Qt.AA_DontUseNativeMenuBar Qt.ApplicationAttribute.AA_DontUseNativeMenuBar
+Qt.AA_MacDontSwapCtrlAndMeta Qt.ApplicationAttribute.AA_MacDontSwapCtrlAndMeta
+Qt.AA_X11InitThreads Qt.ApplicationAttribute.AA_X11InitThreads
+Qt.AA_Use96Dpi Qt.ApplicationAttribute.AA_Use96Dpi
+Qt.AA_SynthesizeTouchForUnhandledMouseEvents Qt.ApplicationAttribute.AA_SynthesizeTouchForUnhandledMouseEvents
+Qt.AA_SynthesizeMouseForUnhandledTouchEvents Qt.ApplicationAttribute.AA_SynthesizeMouseForUnhandledTouchEvents
+Qt.AA_UseHighDpiPixmaps Qt.ApplicationAttribute.AA_UseHighDpiPixmaps
+Qt.AA_ForceRasterWidgets Qt.ApplicationAttribute.AA_ForceRasterWidgets
+Qt.AA_UseDesktopOpenGL Qt.ApplicationAttribute.AA_UseDesktopOpenGL
+Qt.AA_UseOpenGLES Qt.ApplicationAttribute.AA_UseOpenGLES
+Qt.AA_UseSoftwareOpenGL Qt.ApplicationAttribute.AA_UseSoftwareOpenGL
+Qt.AA_ShareOpenGLContexts Qt.ApplicationAttribute.AA_ShareOpenGLContexts
+Qt.AA_SetPalette Qt.ApplicationAttribute.AA_SetPalette
+Qt.AA_EnableHighDpiScaling Qt.ApplicationAttribute.AA_EnableHighDpiScaling
+Qt.AA_DisableHighDpiScaling Qt.ApplicationAttribute.AA_DisableHighDpiScaling
+Qt.AA_PluginApplication Qt.ApplicationAttribute.AA_PluginApplication
+Qt.AA_UseStyleSheetPropagationInWidgetStyles Qt.ApplicationAttribute.AA_UseStyleSheetPropagationInWidgetStyles
+Qt.AA_DontUseNativeDialogs Qt.ApplicationAttribute.AA_DontUseNativeDialogs
+Qt.AA_SynthesizeMouseForUnhandledTabletEvents Qt.ApplicationAttribute.AA_SynthesizeMouseForUnhandledTabletEvents
+Qt.AA_CompressHighFrequencyEvents Qt.ApplicationAttribute.AA_CompressHighFrequencyEvents
+Qt.AA_DontCheckOpenGLContextThreadAffinity Qt.ApplicationAttribute.AA_DontCheckOpenGLContextThreadAffinity
+Qt.AA_DisableShaderDiskCache Qt.ApplicationAttribute.AA_DisableShaderDiskCache
+Qt.AA_DontShowShortcutsInContextMenus Qt.ApplicationAttribute.AA_DontShowShortcutsInContextMenus
+Qt.AA_CompressTabletEvents Qt.ApplicationAttribute.AA_CompressTabletEvents
+Qt.AA_DisableWindowContextHelpButton Qt.ApplicationAttribute.AA_DisableWindowContextHelpButton
+Qt.AA_DisableSessionManager Qt.ApplicationAttribute.AA_DisableSessionManager
+Qt.AA_DisableNativeVirtualKeyboard Qt.ApplicationAttribute.AA_DisableNativeVirtualKeyboard
+Qt.NonModal Qt.WindowModality.NonModal
+Qt.WindowModal Qt.WindowModality.WindowModal
+Qt.ApplicationModal Qt.WindowModality.ApplicationModal
+Qt.MatchExactly Qt.MatchFlag.MatchExactly
+Qt.MatchFixedString Qt.MatchFlag.MatchFixedString
+Qt.MatchContains Qt.MatchFlag.MatchContains
+Qt.MatchStartsWith Qt.MatchFlag.MatchStartsWith
+Qt.MatchEndsWith Qt.MatchFlag.MatchEndsWith
+Qt.MatchRegExp Qt.MatchFlag.MatchRegExp
+Qt.MatchWildcard Qt.MatchFlag.MatchWildcard
+Qt.MatchCaseSensitive Qt.MatchFlag.MatchCaseSensitive
+Qt.MatchWrap Qt.MatchFlag.MatchWrap
+Qt.MatchRecursive Qt.MatchFlag.MatchRecursive
+Qt.MatchRegularExpression Qt.MatchFlag.MatchRegularExpression
+Qt.NoItemFlags Qt.ItemFlag.NoItemFlags
+Qt.ItemIsSelectable Qt.ItemFlag.ItemIsSelectable
+Qt.ItemIsEditable Qt.ItemFlag.ItemIsEditable
+Qt.ItemIsDragEnabled Qt.ItemFlag.ItemIsDragEnabled
+Qt.ItemIsDropEnabled Qt.ItemFlag.ItemIsDropEnabled
+Qt.ItemIsUserCheckable Qt.ItemFlag.ItemIsUserCheckable
+Qt.ItemIsEnabled Qt.ItemFlag.ItemIsEnabled
+Qt.ItemIsTristate Qt.ItemFlag.ItemIsTristate
+Qt.ItemNeverHasChildren Qt.ItemFlag.ItemNeverHasChildren
+Qt.ItemIsUserTristate Qt.ItemFlag.ItemIsUserTristate
+Qt.ItemIsAutoTristate Qt.ItemFlag.ItemIsAutoTristate
+Qt.DisplayRole Qt.ItemDataRole.DisplayRole
+Qt.DecorationRole Qt.ItemDataRole.DecorationRole
+Qt.EditRole Qt.ItemDataRole.EditRole
+Qt.ToolTipRole Qt.ItemDataRole.ToolTipRole
+Qt.StatusTipRole Qt.ItemDataRole.StatusTipRole
+Qt.WhatsThisRole Qt.ItemDataRole.WhatsThisRole
+Qt.FontRole Qt.ItemDataRole.FontRole
+Qt.TextAlignmentRole Qt.ItemDataRole.TextAlignmentRole
+Qt.BackgroundRole Qt.ItemDataRole.BackgroundRole
+Qt.BackgroundColorRole Qt.ItemDataRole.BackgroundColorRole
+Qt.ForegroundRole Qt.ItemDataRole.ForegroundRole
+Qt.TextColorRole Qt.ItemDataRole.TextColorRole
+Qt.CheckStateRole Qt.ItemDataRole.CheckStateRole
+Qt.AccessibleTextRole Qt.ItemDataRole.AccessibleTextRole
+Qt.AccessibleDescriptionRole Qt.ItemDataRole.AccessibleDescriptionRole
+Qt.SizeHintRole Qt.ItemDataRole.SizeHintRole
+Qt.InitialSortOrderRole Qt.ItemDataRole.InitialSortOrderRole
+Qt.UserRole Qt.ItemDataRole.UserRole
+Qt.Unchecked Qt.CheckState.Unchecked
+Qt.PartiallyChecked Qt.CheckState.PartiallyChecked
+Qt.Checked Qt.CheckState.Checked
+Qt.CopyAction Qt.DropAction.CopyAction
+Qt.MoveAction Qt.DropAction.MoveAction
+Qt.LinkAction Qt.DropAction.LinkAction
+Qt.ActionMask Qt.DropAction.ActionMask
+Qt.TargetMoveAction Qt.DropAction.TargetMoveAction
+Qt.IgnoreAction Qt.DropAction.IgnoreAction
+Qt.LeftToRight Qt.LayoutDirection.LeftToRight
+Qt.RightToLeft Qt.LayoutDirection.RightToLeft
+Qt.LayoutDirectionAuto Qt.LayoutDirection.LayoutDirectionAuto
+Qt.ToolButtonIconOnly Qt.ToolButtonStyle.ToolButtonIconOnly
+Qt.ToolButtonTextOnly Qt.ToolButtonStyle.ToolButtonTextOnly
+Qt.ToolButtonTextBesideIcon Qt.ToolButtonStyle.ToolButtonTextBesideIcon
+Qt.ToolButtonTextUnderIcon Qt.ToolButtonStyle.ToolButtonTextUnderIcon
+Qt.ToolButtonFollowStyle Qt.ToolButtonStyle.ToolButtonFollowStyle
+Qt.ImMicroFocus Qt.InputMethodQuery.ImMicroFocus
+Qt.ImFont Qt.InputMethodQuery.ImFont
+Qt.ImCursorPosition Qt.InputMethodQuery.ImCursorPosition
+Qt.ImSurroundingText Qt.InputMethodQuery.ImSurroundingText
+Qt.ImCurrentSelection Qt.InputMethodQuery.ImCurrentSelection
+Qt.ImMaximumTextLength Qt.InputMethodQuery.ImMaximumTextLength
+Qt.ImAnchorPosition Qt.InputMethodQuery.ImAnchorPosition
+Qt.ImEnabled Qt.InputMethodQuery.ImEnabled
+Qt.ImCursorRectangle Qt.InputMethodQuery.ImCursorRectangle
+Qt.ImHints Qt.InputMethodQuery.ImHints
+Qt.ImPreferredLanguage Qt.InputMethodQuery.ImPreferredLanguage
+Qt.ImPlatformData Qt.InputMethodQuery.ImPlatformData
+Qt.ImQueryInput Qt.InputMethodQuery.ImQueryInput
+Qt.ImQueryAll Qt.InputMethodQuery.ImQueryAll
+Qt.ImAbsolutePosition Qt.InputMethodQuery.ImAbsolutePosition
+Qt.ImTextBeforeCursor Qt.InputMethodQuery.ImTextBeforeCursor
+Qt.ImTextAfterCursor Qt.InputMethodQuery.ImTextAfterCursor
+Qt.ImEnterKeyType Qt.InputMethodQuery.ImEnterKeyType
+Qt.ImAnchorRectangle Qt.InputMethodQuery.ImAnchorRectangle
+Qt.ImInputItemClipRectangle Qt.InputMethodQuery.ImInputItemClipRectangle
+Qt.NoContextMenu Qt.ContextMenuPolicy.NoContextMenu
+Qt.PreventContextMenu Qt.ContextMenuPolicy.PreventContextMenu
+Qt.DefaultContextMenu Qt.ContextMenuPolicy.DefaultContextMenu
+Qt.ActionsContextMenu Qt.ContextMenuPolicy.ActionsContextMenu
+Qt.CustomContextMenu Qt.ContextMenuPolicy.CustomContextMenu
+Qt.MouseFocusReason Qt.FocusReason.MouseFocusReason
+Qt.TabFocusReason Qt.FocusReason.TabFocusReason
+Qt.BacktabFocusReason Qt.FocusReason.BacktabFocusReason
+Qt.ActiveWindowFocusReason Qt.FocusReason.ActiveWindowFocusReason
+Qt.PopupFocusReason Qt.FocusReason.PopupFocusReason
+Qt.ShortcutFocusReason Qt.FocusReason.ShortcutFocusReason
+Qt.MenuBarFocusReason Qt.FocusReason.MenuBarFocusReason
+Qt.OtherFocusReason Qt.FocusReason.OtherFocusReason
+Qt.NoFocusReason Qt.FocusReason.NoFocusReason
+Qt.FastTransformation Qt.TransformationMode.FastTransformation
+Qt.SmoothTransformation Qt.TransformationMode.SmoothTransformation
+Qt.NoClip Qt.ClipOperation.NoClip
+Qt.ReplaceClip Qt.ClipOperation.ReplaceClip
+Qt.IntersectClip Qt.ClipOperation.IntersectClip
+Qt.OddEvenFill Qt.FillRule.OddEvenFill
+Qt.WindingFill Qt.FillRule.WindingFill
+Qt.WidgetShortcut Qt.ShortcutContext.WidgetShortcut
+Qt.WindowShortcut Qt.ShortcutContext.WindowShortcut
+Qt.ApplicationShortcut Qt.ShortcutContext.ApplicationShortcut
+Qt.WidgetWithChildrenShortcut Qt.ShortcutContext.WidgetWithChildrenShortcut
+Qt.AutoConnection Qt.ConnectionType.AutoConnection
+Qt.DirectConnection Qt.ConnectionType.DirectConnection
+Qt.QueuedConnection Qt.ConnectionType.QueuedConnection
+Qt.BlockingQueuedConnection Qt.ConnectionType.BlockingQueuedConnection
+Qt.UniqueConnection Qt.ConnectionType.UniqueConnection
+Qt.TopLeftCorner Qt.Corner.TopLeftCorner
+Qt.TopRightCorner Qt.Corner.TopRightCorner
+Qt.BottomLeftCorner Qt.Corner.BottomLeftCorner
+Qt.BottomRightCorner Qt.Corner.BottomRightCorner
+Qt.CaseInsensitive Qt.CaseSensitivity.CaseInsensitive
+Qt.CaseSensitive Qt.CaseSensitivity.CaseSensitive
+Qt.ScrollBarAsNeeded Qt.ScrollBarPolicy.ScrollBarAsNeeded
+Qt.ScrollBarAlwaysOff Qt.ScrollBarPolicy.ScrollBarAlwaysOff
+Qt.ScrollBarAlwaysOn Qt.ScrollBarPolicy.ScrollBarAlwaysOn
+Qt.Monday Qt.DayOfWeek.Monday
+Qt.Tuesday Qt.DayOfWeek.Tuesday
+Qt.Wednesday Qt.DayOfWeek.Wednesday
+Qt.Thursday Qt.DayOfWeek.Thursday
+Qt.Friday Qt.DayOfWeek.Friday
+Qt.Saturday Qt.DayOfWeek.Saturday
+Qt.Sunday Qt.DayOfWeek.Sunday
+Qt.LocalTime Qt.TimeSpec.LocalTime
+Qt.UTC Qt.TimeSpec.UTC
+Qt.OffsetFromUTC Qt.TimeSpec.OffsetFromUTC
+Qt.TimeZone Qt.TimeSpec.TimeZone
+Qt.TextDate Qt.DateFormat.TextDate
+Qt.ISODate Qt.DateFormat.ISODate
+Qt.ISODateWithMs Qt.DateFormat.ISODateWithMs
+Qt.LocalDate Qt.DateFormat.LocalDate
+Qt.SystemLocaleDate Qt.DateFormat.SystemLocaleDate
+Qt.LocaleDate Qt.DateFormat.LocaleDate
+Qt.SystemLocaleShortDate Qt.DateFormat.SystemLocaleShortDate
+Qt.SystemLocaleLongDate Qt.DateFormat.SystemLocaleLongDate
+Qt.DefaultLocaleShortDate Qt.DateFormat.DefaultLocaleShortDate
+Qt.DefaultLocaleLongDate Qt.DateFormat.DefaultLocaleLongDate
+Qt.RFC2822Date Qt.DateFormat.RFC2822Date
+Qt.LeftToolBarArea Qt.ToolBarArea.LeftToolBarArea
+Qt.RightToolBarArea Qt.ToolBarArea.RightToolBarArea
+Qt.TopToolBarArea Qt.ToolBarArea.TopToolBarArea
+Qt.BottomToolBarArea Qt.ToolBarArea.BottomToolBarArea
+Qt.ToolBarArea_Mask Qt.ToolBarArea.ToolBarArea_Mask
+Qt.AllToolBarAreas Qt.ToolBarArea.AllToolBarAreas
+Qt.NoToolBarArea Qt.ToolBarArea.NoToolBarArea
+Qt.PreciseTimer Qt.TimerType.PreciseTimer
+Qt.CoarseTimer Qt.TimerType.CoarseTimer
+Qt.VeryCoarseTimer Qt.TimerType.VeryCoarseTimer
+Qt.LeftDockWidgetArea Qt.DockWidgetArea.LeftDockWidgetArea
+Qt.RightDockWidgetArea Qt.DockWidgetArea.RightDockWidgetArea
+Qt.TopDockWidgetArea Qt.DockWidgetArea.TopDockWidgetArea
+Qt.BottomDockWidgetArea Qt.DockWidgetArea.BottomDockWidgetArea
+Qt.DockWidgetArea_Mask Qt.DockWidgetArea.DockWidgetArea_Mask
+Qt.AllDockWidgetAreas Qt.DockWidgetArea.AllDockWidgetAreas
+Qt.NoDockWidgetArea Qt.DockWidgetArea.NoDockWidgetArea
+Qt.IgnoreAspectRatio Qt.AspectRatioMode.IgnoreAspectRatio
+Qt.KeepAspectRatio Qt.AspectRatioMode.KeepAspectRatio
+Qt.KeepAspectRatioByExpanding Qt.AspectRatioMode.KeepAspectRatioByExpanding
+Qt.PlainText Qt.TextFormat.PlainText
+Qt.RichText Qt.TextFormat.RichText
+Qt.AutoText Qt.TextFormat.AutoText
+Qt.MarkdownText Qt.TextFormat.MarkdownText
+Qt.ArrowCursor Qt.CursorShape.ArrowCursor
+Qt.UpArrowCursor Qt.CursorShape.UpArrowCursor
+Qt.CrossCursor Qt.CursorShape.CrossCursor
+Qt.WaitCursor Qt.CursorShape.WaitCursor
+Qt.IBeamCursor Qt.CursorShape.IBeamCursor
+Qt.SizeVerCursor Qt.CursorShape.SizeVerCursor
+Qt.SizeHorCursor Qt.CursorShape.SizeHorCursor
+Qt.SizeBDiagCursor Qt.CursorShape.SizeBDiagCursor
+Qt.SizeFDiagCursor Qt.CursorShape.SizeFDiagCursor
+Qt.SizeAllCursor Qt.CursorShape.SizeAllCursor
+Qt.BlankCursor Qt.CursorShape.BlankCursor
+Qt.SplitVCursor Qt.CursorShape.SplitVCursor
+Qt.SplitHCursor Qt.CursorShape.SplitHCursor
+Qt.PointingHandCursor Qt.CursorShape.PointingHandCursor
+Qt.ForbiddenCursor Qt.CursorShape.ForbiddenCursor
+Qt.OpenHandCursor Qt.CursorShape.OpenHandCursor
+Qt.ClosedHandCursor Qt.CursorShape.ClosedHandCursor
+Qt.WhatsThisCursor Qt.CursorShape.WhatsThisCursor
+Qt.BusyCursor Qt.CursorShape.BusyCursor
+Qt.LastCursor Qt.CursorShape.LastCursor
+Qt.BitmapCursor Qt.CursorShape.BitmapCursor
+Qt.CustomCursor Qt.CursorShape.CustomCursor
+Qt.DragCopyCursor Qt.CursorShape.DragCopyCursor
+Qt.DragMoveCursor Qt.CursorShape.DragMoveCursor
+Qt.DragLinkCursor Qt.CursorShape.DragLinkCursor
+Qt.UI_General Qt.UIEffect.UI_General
+Qt.UI_AnimateMenu Qt.UIEffect.UI_AnimateMenu
+Qt.UI_FadeMenu Qt.UIEffect.UI_FadeMenu
+Qt.UI_AnimateCombo Qt.UIEffect.UI_AnimateCombo
+Qt.UI_AnimateTooltip Qt.UIEffect.UI_AnimateTooltip
+Qt.UI_FadeTooltip Qt.UIEffect.UI_FadeTooltip
+Qt.UI_AnimateToolBox Qt.UIEffect.UI_AnimateToolBox
+Qt.NoBrush Qt.BrushStyle.NoBrush
+Qt.SolidPattern Qt.BrushStyle.SolidPattern
+Qt.Dense1Pattern Qt.BrushStyle.Dense1Pattern
+Qt.Dense2Pattern Qt.BrushStyle.Dense2Pattern
+Qt.Dense3Pattern Qt.BrushStyle.Dense3Pattern
+Qt.Dense4Pattern Qt.BrushStyle.Dense4Pattern
+Qt.Dense5Pattern Qt.BrushStyle.Dense5Pattern
+Qt.Dense6Pattern Qt.BrushStyle.Dense6Pattern
+Qt.Dense7Pattern Qt.BrushStyle.Dense7Pattern
+Qt.HorPattern Qt.BrushStyle.HorPattern
+Qt.VerPattern Qt.BrushStyle.VerPattern
+Qt.CrossPattern Qt.BrushStyle.CrossPattern
+Qt.BDiagPattern Qt.BrushStyle.BDiagPattern
+Qt.FDiagPattern Qt.BrushStyle.FDiagPattern
+Qt.DiagCrossPattern Qt.BrushStyle.DiagCrossPattern
+Qt.LinearGradientPattern Qt.BrushStyle.LinearGradientPattern
+Qt.RadialGradientPattern Qt.BrushStyle.RadialGradientPattern
+Qt.ConicalGradientPattern Qt.BrushStyle.ConicalGradientPattern
+Qt.TexturePattern Qt.BrushStyle.TexturePattern
+Qt.MiterJoin Qt.PenJoinStyle.MiterJoin
+Qt.BevelJoin Qt.PenJoinStyle.BevelJoin
+Qt.RoundJoin Qt.PenJoinStyle.RoundJoin
+Qt.MPenJoinStyle Qt.PenJoinStyle.MPenJoinStyle
+Qt.SvgMiterJoin Qt.PenJoinStyle.SvgMiterJoin
+Qt.FlatCap Qt.PenCapStyle.FlatCap
+Qt.SquareCap Qt.PenCapStyle.SquareCap
+Qt.RoundCap Qt.PenCapStyle.RoundCap
+Qt.MPenCapStyle Qt.PenCapStyle.MPenCapStyle
+Qt.NoPen Qt.PenStyle.NoPen
+Qt.SolidLine Qt.PenStyle.SolidLine
+Qt.DashLine Qt.PenStyle.DashLine
+Qt.DotLine Qt.PenStyle.DotLine
+Qt.DashDotLine Qt.PenStyle.DashDotLine
+Qt.DashDotDotLine Qt.PenStyle.DashDotDotLine
+Qt.CustomDashLine Qt.PenStyle.CustomDashLine
+Qt.MPenStyle Qt.PenStyle.MPenStyle
+Qt.NoArrow Qt.ArrowType.NoArrow
+Qt.UpArrow Qt.ArrowType.UpArrow
+Qt.DownArrow Qt.ArrowType.DownArrow
+Qt.LeftArrow Qt.ArrowType.LeftArrow
+Qt.RightArrow Qt.ArrowType.RightArrow
+Qt.Key_Escape Qt.Key.Key_Escape
+Qt.Key_Tab Qt.Key.Key_Tab
+Qt.Key_Backtab Qt.Key.Key_Backtab
+Qt.Key_Backspace Qt.Key.Key_Backspace
+Qt.Key_Return Qt.Key.Key_Return
+Qt.Key_Enter Qt.Key.Key_Enter
+Qt.Key_Insert Qt.Key.Key_Insert
+Qt.Key_Delete Qt.Key.Key_Delete
+Qt.Key_Pause Qt.Key.Key_Pause
+Qt.Key_Print Qt.Key.Key_Print
+Qt.Key_SysReq Qt.Key.Key_SysReq
+Qt.Key_Clear Qt.Key.Key_Clear
+Qt.Key_Home Qt.Key.Key_Home
+Qt.Key_End Qt.Key.Key_End
+Qt.Key_Left Qt.Key.Key_Left
+Qt.Key_Up Qt.Key.Key_Up
+Qt.Key_Right Qt.Key.Key_Right
+Qt.Key_Down Qt.Key.Key_Down
+Qt.Key_PageUp Qt.Key.Key_PageUp
+Qt.Key_PageDown Qt.Key.Key_PageDown
+Qt.Key_Shift Qt.Key.Key_Shift
+Qt.Key_Control Qt.Key.Key_Control
+Qt.Key_Meta Qt.Key.Key_Meta
+Qt.Key_Alt Qt.Key.Key_Alt
+Qt.Key_CapsLock Qt.Key.Key_CapsLock
+Qt.Key_NumLock Qt.Key.Key_NumLock
+Qt.Key_ScrollLock Qt.Key.Key_ScrollLock
+Qt.Key_F1 Qt.Key.Key_F1
+Qt.Key_F2 Qt.Key.Key_F2
+Qt.Key_F3 Qt.Key.Key_F3
+Qt.Key_F4 Qt.Key.Key_F4
+Qt.Key_F5 Qt.Key.Key_F5
+Qt.Key_F6 Qt.Key.Key_F6
+Qt.Key_F7 Qt.Key.Key_F7
+Qt.Key_F8 Qt.Key.Key_F8
+Qt.Key_F9 Qt.Key.Key_F9
+Qt.Key_F10 Qt.Key.Key_F10
+Qt.Key_F11 Qt.Key.Key_F11
+Qt.Key_F12 Qt.Key.Key_F12
+Qt.Key_F13 Qt.Key.Key_F13
+Qt.Key_F14 Qt.Key.Key_F14
+Qt.Key_F15 Qt.Key.Key_F15
+Qt.Key_F16 Qt.Key.Key_F16
+Qt.Key_F17 Qt.Key.Key_F17
+Qt.Key_F18 Qt.Key.Key_F18
+Qt.Key_F19 Qt.Key.Key_F19
+Qt.Key_F20 Qt.Key.Key_F20
+Qt.Key_F21 Qt.Key.Key_F21
+Qt.Key_F22 Qt.Key.Key_F22
+Qt.Key_F23 Qt.Key.Key_F23
+Qt.Key_F24 Qt.Key.Key_F24
+Qt.Key_F25 Qt.Key.Key_F25
+Qt.Key_F26 Qt.Key.Key_F26
+Qt.Key_F27 Qt.Key.Key_F27
+Qt.Key_F28 Qt.Key.Key_F28
+Qt.Key_F29 Qt.Key.Key_F29
+Qt.Key_F30 Qt.Key.Key_F30
+Qt.Key_F31 Qt.Key.Key_F31
+Qt.Key_F32 Qt.Key.Key_F32
+Qt.Key_F33 Qt.Key.Key_F33
+Qt.Key_F34 Qt.Key.Key_F34
+Qt.Key_F35 Qt.Key.Key_F35
+Qt.Key_Super_L Qt.Key.Key_Super_L
+Qt.Key_Super_R Qt.Key.Key_Super_R
+Qt.Key_Menu Qt.Key.Key_Menu
+Qt.Key_Hyper_L Qt.Key.Key_Hyper_L
+Qt.Key_Hyper_R Qt.Key.Key_Hyper_R
+Qt.Key_Help Qt.Key.Key_Help
+Qt.Key_Direction_L Qt.Key.Key_Direction_L
+Qt.Key_Direction_R Qt.Key.Key_Direction_R
+Qt.Key_Space Qt.Key.Key_Space
+Qt.Key_Any Qt.Key.Key_Any
+Qt.Key_Exclam Qt.Key.Key_Exclam
+Qt.Key_QuoteDbl Qt.Key.Key_QuoteDbl
+Qt.Key_NumberSign Qt.Key.Key_NumberSign
+Qt.Key_Dollar Qt.Key.Key_Dollar
+Qt.Key_Percent Qt.Key.Key_Percent
+Qt.Key_Ampersand Qt.Key.Key_Ampersand
+Qt.Key_Apostrophe Qt.Key.Key_Apostrophe
+Qt.Key_ParenLeft Qt.Key.Key_ParenLeft
+Qt.Key_ParenRight Qt.Key.Key_ParenRight
+Qt.Key_Asterisk Qt.Key.Key_Asterisk
+Qt.Key_Plus Qt.Key.Key_Plus
+Qt.Key_Comma Qt.Key.Key_Comma
+Qt.Key_Minus Qt.Key.Key_Minus
+Qt.Key_Period Qt.Key.Key_Period
+Qt.Key_Slash Qt.Key.Key_Slash
+Qt.Key_0 Qt.Key.Key_0
+Qt.Key_1 Qt.Key.Key_1
+Qt.Key_2 Qt.Key.Key_2
+Qt.Key_3 Qt.Key.Key_3
+Qt.Key_4 Qt.Key.Key_4
+Qt.Key_5 Qt.Key.Key_5
+Qt.Key_6 Qt.Key.Key_6
+Qt.Key_7 Qt.Key.Key_7
+Qt.Key_8 Qt.Key.Key_8
+Qt.Key_9 Qt.Key.Key_9
+Qt.Key_Colon Qt.Key.Key_Colon
+Qt.Key_Semicolon Qt.Key.Key_Semicolon
+Qt.Key_Less Qt.Key.Key_Less
+Qt.Key_Equal Qt.Key.Key_Equal
+Qt.Key_Greater Qt.Key.Key_Greater
+Qt.Key_Question Qt.Key.Key_Question
+Qt.Key_At Qt.Key.Key_At
+Qt.Key_A Qt.Key.Key_A
+Qt.Key_B Qt.Key.Key_B
+Qt.Key_C Qt.Key.Key_C
+Qt.Key_D Qt.Key.Key_D
+Qt.Key_E Qt.Key.Key_E
+Qt.Key_F Qt.Key.Key_F
+Qt.Key_G Qt.Key.Key_G
+Qt.Key_H Qt.Key.Key_H
+Qt.Key_I Qt.Key.Key_I
+Qt.Key_J Qt.Key.Key_J
+Qt.Key_K Qt.Key.Key_K
+Qt.Key_L Qt.Key.Key_L
+Qt.Key_M Qt.Key.Key_M
+Qt.Key_N Qt.Key.Key_N
+Qt.Key_O Qt.Key.Key_O
+Qt.Key_P Qt.Key.Key_P
+Qt.Key_Q Qt.Key.Key_Q
+Qt.Key_R Qt.Key.Key_R
+Qt.Key_S Qt.Key.Key_S
+Qt.Key_T Qt.Key.Key_T
+Qt.Key_U Qt.Key.Key_U
+Qt.Key_V Qt.Key.Key_V
+Qt.Key_W Qt.Key.Key_W
+Qt.Key_X Qt.Key.Key_X
+Qt.Key_Y Qt.Key.Key_Y
+Qt.Key_Z Qt.Key.Key_Z
+Qt.Key_BracketLeft Qt.Key.Key_BracketLeft
+Qt.Key_Backslash Qt.Key.Key_Backslash
+Qt.Key_BracketRight Qt.Key.Key_BracketRight
+Qt.Key_AsciiCircum Qt.Key.Key_AsciiCircum
+Qt.Key_Underscore Qt.Key.Key_Underscore
+Qt.Key_QuoteLeft Qt.Key.Key_QuoteLeft
+Qt.Key_BraceLeft Qt.Key.Key_BraceLeft
+Qt.Key_Bar Qt.Key.Key_Bar
+Qt.Key_BraceRight Qt.Key.Key_BraceRight
+Qt.Key_AsciiTilde Qt.Key.Key_AsciiTilde
+Qt.Key_nobreakspace Qt.Key.Key_nobreakspace
+Qt.Key_exclamdown Qt.Key.Key_exclamdown
+Qt.Key_cent Qt.Key.Key_cent
+Qt.Key_sterling Qt.Key.Key_sterling
+Qt.Key_currency Qt.Key.Key_currency
+Qt.Key_yen Qt.Key.Key_yen
+Qt.Key_brokenbar Qt.Key.Key_brokenbar
+Qt.Key_section Qt.Key.Key_section
+Qt.Key_diaeresis Qt.Key.Key_diaeresis
+Qt.Key_copyright Qt.Key.Key_copyright
+Qt.Key_ordfeminine Qt.Key.Key_ordfeminine
+Qt.Key_guillemotleft Qt.Key.Key_guillemotleft
+Qt.Key_notsign Qt.Key.Key_notsign
+Qt.Key_hyphen Qt.Key.Key_hyphen
+Qt.Key_registered Qt.Key.Key_registered
+Qt.Key_macron Qt.Key.Key_macron
+Qt.Key_degree Qt.Key.Key_degree
+Qt.Key_plusminus Qt.Key.Key_plusminus
+Qt.Key_twosuperior Qt.Key.Key_twosuperior
+Qt.Key_threesuperior Qt.Key.Key_threesuperior
+Qt.Key_acute Qt.Key.Key_acute
+Qt.Key_mu Qt.Key.Key_mu
+Qt.Key_paragraph Qt.Key.Key_paragraph
+Qt.Key_periodcentered Qt.Key.Key_periodcentered
+Qt.Key_cedilla Qt.Key.Key_cedilla
+Qt.Key_onesuperior Qt.Key.Key_onesuperior
+Qt.Key_masculine Qt.Key.Key_masculine
+Qt.Key_guillemotright Qt.Key.Key_guillemotright
+Qt.Key_onequarter Qt.Key.Key_onequarter
+Qt.Key_onehalf Qt.Key.Key_onehalf
+Qt.Key_threequarters Qt.Key.Key_threequarters
+Qt.Key_questiondown Qt.Key.Key_questiondown
+Qt.Key_Agrave Qt.Key.Key_Agrave
+Qt.Key_Aacute Qt.Key.Key_Aacute
+Qt.Key_Acircumflex Qt.Key.Key_Acircumflex
+Qt.Key_Atilde Qt.Key.Key_Atilde
+Qt.Key_Adiaeresis Qt.Key.Key_Adiaeresis
+Qt.Key_Aring Qt.Key.Key_Aring
+Qt.Key_AE Qt.Key.Key_AE
+Qt.Key_Ccedilla Qt.Key.Key_Ccedilla
+Qt.Key_Egrave Qt.Key.Key_Egrave
+Qt.Key_Eacute Qt.Key.Key_Eacute
+Qt.Key_Ecircumflex Qt.Key.Key_Ecircumflex
+Qt.Key_Ediaeresis Qt.Key.Key_Ediaeresis
+Qt.Key_Igrave Qt.Key.Key_Igrave
+Qt.Key_Iacute Qt.Key.Key_Iacute
+Qt.Key_Icircumflex Qt.Key.Key_Icircumflex
+Qt.Key_Idiaeresis Qt.Key.Key_Idiaeresis
+Qt.Key_ETH Qt.Key.Key_ETH
+Qt.Key_Ntilde Qt.Key.Key_Ntilde
+Qt.Key_Ograve Qt.Key.Key_Ograve
+Qt.Key_Oacute Qt.Key.Key_Oacute
+Qt.Key_Ocircumflex Qt.Key.Key_Ocircumflex
+Qt.Key_Otilde Qt.Key.Key_Otilde
+Qt.Key_Odiaeresis Qt.Key.Key_Odiaeresis
+Qt.Key_multiply Qt.Key.Key_multiply
+Qt.Key_Ooblique Qt.Key.Key_Ooblique
+Qt.Key_Ugrave Qt.Key.Key_Ugrave
+Qt.Key_Uacute Qt.Key.Key_Uacute
+Qt.Key_Ucircumflex Qt.Key.Key_Ucircumflex
+Qt.Key_Udiaeresis Qt.Key.Key_Udiaeresis
+Qt.Key_Yacute Qt.Key.Key_Yacute
+Qt.Key_THORN Qt.Key.Key_THORN
+Qt.Key_ssharp Qt.Key.Key_ssharp
+Qt.Key_division Qt.Key.Key_division
+Qt.Key_ydiaeresis Qt.Key.Key_ydiaeresis
+Qt.Key_AltGr Qt.Key.Key_AltGr
+Qt.Key_Multi_key Qt.Key.Key_Multi_key
+Qt.Key_Codeinput Qt.Key.Key_Codeinput
+Qt.Key_SingleCandidate Qt.Key.Key_SingleCandidate
+Qt.Key_MultipleCandidate Qt.Key.Key_MultipleCandidate
+Qt.Key_PreviousCandidate Qt.Key.Key_PreviousCandidate
+Qt.Key_Mode_switch Qt.Key.Key_Mode_switch
+Qt.Key_Kanji Qt.Key.Key_Kanji
+Qt.Key_Muhenkan Qt.Key.Key_Muhenkan
+Qt.Key_Henkan Qt.Key.Key_Henkan
+Qt.Key_Romaji Qt.Key.Key_Romaji
+Qt.Key_Hiragana Qt.Key.Key_Hiragana
+Qt.Key_Katakana Qt.Key.Key_Katakana
+Qt.Key_Hiragana_Katakana Qt.Key.Key_Hiragana_Katakana
+Qt.Key_Zenkaku Qt.Key.Key_Zenkaku
+Qt.Key_Hankaku Qt.Key.Key_Hankaku
+Qt.Key_Zenkaku_Hankaku Qt.Key.Key_Zenkaku_Hankaku
+Qt.Key_Touroku Qt.Key.Key_Touroku
+Qt.Key_Massyo Qt.Key.Key_Massyo
+Qt.Key_Kana_Lock Qt.Key.Key_Kana_Lock
+Qt.Key_Kana_Shift Qt.Key.Key_Kana_Shift
+Qt.Key_Eisu_Shift Qt.Key.Key_Eisu_Shift
+Qt.Key_Eisu_toggle Qt.Key.Key_Eisu_toggle
+Qt.Key_Hangul Qt.Key.Key_Hangul
+Qt.Key_Hangul_Start Qt.Key.Key_Hangul_Start
+Qt.Key_Hangul_End Qt.Key.Key_Hangul_End
+Qt.Key_Hangul_Hanja Qt.Key.Key_Hangul_Hanja
+Qt.Key_Hangul_Jamo Qt.Key.Key_Hangul_Jamo
+Qt.Key_Hangul_Romaja Qt.Key.Key_Hangul_Romaja
+Qt.Key_Hangul_Jeonja Qt.Key.Key_Hangul_Jeonja
+Qt.Key_Hangul_Banja Qt.Key.Key_Hangul_Banja
+Qt.Key_Hangul_PreHanja Qt.Key.Key_Hangul_PreHanja
+Qt.Key_Hangul_PostHanja Qt.Key.Key_Hangul_PostHanja
+Qt.Key_Hangul_Special Qt.Key.Key_Hangul_Special
+Qt.Key_Dead_Grave Qt.Key.Key_Dead_Grave
+Qt.Key_Dead_Acute Qt.Key.Key_Dead_Acute
+Qt.Key_Dead_Circumflex Qt.Key.Key_Dead_Circumflex
+Qt.Key_Dead_Tilde Qt.Key.Key_Dead_Tilde
+Qt.Key_Dead_Macron Qt.Key.Key_Dead_Macron
+Qt.Key_Dead_Breve Qt.Key.Key_Dead_Breve
+Qt.Key_Dead_Abovedot Qt.Key.Key_Dead_Abovedot
+Qt.Key_Dead_Diaeresis Qt.Key.Key_Dead_Diaeresis
+Qt.Key_Dead_Abovering Qt.Key.Key_Dead_Abovering
+Qt.Key_Dead_Doubleacute Qt.Key.Key_Dead_Doubleacute
+Qt.Key_Dead_Caron Qt.Key.Key_Dead_Caron
+Qt.Key_Dead_Cedilla Qt.Key.Key_Dead_Cedilla
+Qt.Key_Dead_Ogonek Qt.Key.Key_Dead_Ogonek
+Qt.Key_Dead_Iota Qt.Key.Key_Dead_Iota
+Qt.Key_Dead_Voiced_Sound Qt.Key.Key_Dead_Voiced_Sound
+Qt.Key_Dead_Semivoiced_Sound Qt.Key.Key_Dead_Semivoiced_Sound
+Qt.Key_Dead_Belowdot Qt.Key.Key_Dead_Belowdot
+Qt.Key_Dead_Hook Qt.Key.Key_Dead_Hook
+Qt.Key_Dead_Horn Qt.Key.Key_Dead_Horn
+Qt.Key_Back Qt.Key.Key_Back
+Qt.Key_Forward Qt.Key.Key_Forward
+Qt.Key_Stop Qt.Key.Key_Stop
+Qt.Key_Refresh Qt.Key.Key_Refresh
+Qt.Key_VolumeDown Qt.Key.Key_VolumeDown
+Qt.Key_VolumeMute Qt.Key.Key_VolumeMute
+Qt.Key_VolumeUp Qt.Key.Key_VolumeUp
+Qt.Key_BassBoost Qt.Key.Key_BassBoost
+Qt.Key_BassUp Qt.Key.Key_BassUp
+Qt.Key_BassDown Qt.Key.Key_BassDown
+Qt.Key_TrebleUp Qt.Key.Key_TrebleUp
+Qt.Key_TrebleDown Qt.Key.Key_TrebleDown
+Qt.Key_MediaPlay Qt.Key.Key_MediaPlay
+Qt.Key_MediaStop Qt.Key.Key_MediaStop
+Qt.Key_MediaPrevious Qt.Key.Key_MediaPrevious
+Qt.Key_MediaNext Qt.Key.Key_MediaNext
+Qt.Key_MediaRecord Qt.Key.Key_MediaRecord
+Qt.Key_HomePage Qt.Key.Key_HomePage
+Qt.Key_Favorites Qt.Key.Key_Favorites
+Qt.Key_Search Qt.Key.Key_Search
+Qt.Key_Standby Qt.Key.Key_Standby
+Qt.Key_OpenUrl Qt.Key.Key_OpenUrl
+Qt.Key_LaunchMail Qt.Key.Key_LaunchMail
+Qt.Key_LaunchMedia Qt.Key.Key_LaunchMedia
+Qt.Key_Launch0 Qt.Key.Key_Launch0
+Qt.Key_Launch1 Qt.Key.Key_Launch1
+Qt.Key_Launch2 Qt.Key.Key_Launch2
+Qt.Key_Launch3 Qt.Key.Key_Launch3
+Qt.Key_Launch4 Qt.Key.Key_Launch4
+Qt.Key_Launch5 Qt.Key.Key_Launch5
+Qt.Key_Launch6 Qt.Key.Key_Launch6
+Qt.Key_Launch7 Qt.Key.Key_Launch7
+Qt.Key_Launch8 Qt.Key.Key_Launch8
+Qt.Key_Launch9 Qt.Key.Key_Launch9
+Qt.Key_LaunchA Qt.Key.Key_LaunchA
+Qt.Key_LaunchB Qt.Key.Key_LaunchB
+Qt.Key_LaunchC Qt.Key.Key_LaunchC
+Qt.Key_LaunchD Qt.Key.Key_LaunchD
+Qt.Key_LaunchE Qt.Key.Key_LaunchE
+Qt.Key_LaunchF Qt.Key.Key_LaunchF
+Qt.Key_MediaLast Qt.Key.Key_MediaLast
+Qt.Key_Select Qt.Key.Key_Select
+Qt.Key_Yes Qt.Key.Key_Yes
+Qt.Key_No Qt.Key.Key_No
+Qt.Key_Context1 Qt.Key.Key_Context1
+Qt.Key_Context2 Qt.Key.Key_Context2
+Qt.Key_Context3 Qt.Key.Key_Context3
+Qt.Key_Context4 Qt.Key.Key_Context4
+Qt.Key_Call Qt.Key.Key_Call
+Qt.Key_Hangup Qt.Key.Key_Hangup
+Qt.Key_Flip Qt.Key.Key_Flip
+Qt.Key_unknown Qt.Key.Key_unknown
+Qt.Key_Execute Qt.Key.Key_Execute
+Qt.Key_Printer Qt.Key.Key_Printer
+Qt.Key_Play Qt.Key.Key_Play
+Qt.Key_Sleep Qt.Key.Key_Sleep
+Qt.Key_Zoom Qt.Key.Key_Zoom
+Qt.Key_Cancel Qt.Key.Key_Cancel
+Qt.Key_MonBrightnessUp Qt.Key.Key_MonBrightnessUp
+Qt.Key_MonBrightnessDown Qt.Key.Key_MonBrightnessDown
+Qt.Key_KeyboardLightOnOff Qt.Key.Key_KeyboardLightOnOff
+Qt.Key_KeyboardBrightnessUp Qt.Key.Key_KeyboardBrightnessUp
+Qt.Key_KeyboardBrightnessDown Qt.Key.Key_KeyboardBrightnessDown
+Qt.Key_PowerOff Qt.Key.Key_PowerOff
+Qt.Key_WakeUp Qt.Key.Key_WakeUp
+Qt.Key_Eject Qt.Key.Key_Eject
+Qt.Key_ScreenSaver Qt.Key.Key_ScreenSaver
+Qt.Key_WWW Qt.Key.Key_WWW
+Qt.Key_Memo Qt.Key.Key_Memo
+Qt.Key_LightBulb Qt.Key.Key_LightBulb
+Qt.Key_Shop Qt.Key.Key_Shop
+Qt.Key_History Qt.Key.Key_History
+Qt.Key_AddFavorite Qt.Key.Key_AddFavorite
+Qt.Key_HotLinks Qt.Key.Key_HotLinks
+Qt.Key_BrightnessAdjust Qt.Key.Key_BrightnessAdjust
+Qt.Key_Finance Qt.Key.Key_Finance
+Qt.Key_Community Qt.Key.Key_Community
+Qt.Key_AudioRewind Qt.Key.Key_AudioRewind
+Qt.Key_BackForward Qt.Key.Key_BackForward
+Qt.Key_ApplicationLeft Qt.Key.Key_ApplicationLeft
+Qt.Key_ApplicationRight Qt.Key.Key_ApplicationRight
+Qt.Key_Book Qt.Key.Key_Book
+Qt.Key_CD Qt.Key.Key_CD
+Qt.Key_Calculator Qt.Key.Key_Calculator
+Qt.Key_ToDoList Qt.Key.Key_ToDoList
+Qt.Key_ClearGrab Qt.Key.Key_ClearGrab
+Qt.Key_Close Qt.Key.Key_Close
+Qt.Key_Copy Qt.Key.Key_Copy
+Qt.Key_Cut Qt.Key.Key_Cut
+Qt.Key_Display Qt.Key.Key_Display
+Qt.Key_DOS Qt.Key.Key_DOS
+Qt.Key_Documents Qt.Key.Key_Documents
+Qt.Key_Excel Qt.Key.Key_Excel
+Qt.Key_Explorer Qt.Key.Key_Explorer
+Qt.Key_Game Qt.Key.Key_Game
+Qt.Key_Go Qt.Key.Key_Go
+Qt.Key_iTouch Qt.Key.Key_iTouch
+Qt.Key_LogOff Qt.Key.Key_LogOff
+Qt.Key_Market Qt.Key.Key_Market
+Qt.Key_Meeting Qt.Key.Key_Meeting
+Qt.Key_MenuKB Qt.Key.Key_MenuKB
+Qt.Key_MenuPB Qt.Key.Key_MenuPB
+Qt.Key_MySites Qt.Key.Key_MySites
+Qt.Key_News Qt.Key.Key_News
+Qt.Key_OfficeHome Qt.Key.Key_OfficeHome
+Qt.Key_Option Qt.Key.Key_Option
+Qt.Key_Paste Qt.Key.Key_Paste
+Qt.Key_Phone Qt.Key.Key_Phone
+Qt.Key_Calendar Qt.Key.Key_Calendar
+Qt.Key_Reply Qt.Key.Key_Reply
+Qt.Key_Reload Qt.Key.Key_Reload
+Qt.Key_RotateWindows Qt.Key.Key_RotateWindows
+Qt.Key_RotationPB Qt.Key.Key_RotationPB
+Qt.Key_RotationKB Qt.Key.Key_RotationKB
+Qt.Key_Save Qt.Key.Key_Save
+Qt.Key_Send Qt.Key.Key_Send
+Qt.Key_Spell Qt.Key.Key_Spell
+Qt.Key_SplitScreen Qt.Key.Key_SplitScreen
+Qt.Key_Support Qt.Key.Key_Support
+Qt.Key_TaskPane Qt.Key.Key_TaskPane
+Qt.Key_Terminal Qt.Key.Key_Terminal
+Qt.Key_Tools Qt.Key.Key_Tools
+Qt.Key_Travel Qt.Key.Key_Travel
+Qt.Key_Video Qt.Key.Key_Video
+Qt.Key_Word Qt.Key.Key_Word
+Qt.Key_Xfer Qt.Key.Key_Xfer
+Qt.Key_ZoomIn Qt.Key.Key_ZoomIn
+Qt.Key_ZoomOut Qt.Key.Key_ZoomOut
+Qt.Key_Away Qt.Key.Key_Away
+Qt.Key_Messenger Qt.Key.Key_Messenger
+Qt.Key_WebCam Qt.Key.Key_WebCam
+Qt.Key_MailForward Qt.Key.Key_MailForward
+Qt.Key_Pictures Qt.Key.Key_Pictures
+Qt.Key_Music Qt.Key.Key_Music
+Qt.Key_Battery Qt.Key.Key_Battery
+Qt.Key_Bluetooth Qt.Key.Key_Bluetooth
+Qt.Key_WLAN Qt.Key.Key_WLAN
+Qt.Key_UWB Qt.Key.Key_UWB
+Qt.Key_AudioForward Qt.Key.Key_AudioForward
+Qt.Key_AudioRepeat Qt.Key.Key_AudioRepeat
+Qt.Key_AudioRandomPlay Qt.Key.Key_AudioRandomPlay
+Qt.Key_Subtitle Qt.Key.Key_Subtitle
+Qt.Key_AudioCycleTrack Qt.Key.Key_AudioCycleTrack
+Qt.Key_Time Qt.Key.Key_Time
+Qt.Key_Hibernate Qt.Key.Key_Hibernate
+Qt.Key_View Qt.Key.Key_View
+Qt.Key_TopMenu Qt.Key.Key_TopMenu
+Qt.Key_PowerDown Qt.Key.Key_PowerDown
+Qt.Key_Suspend Qt.Key.Key_Suspend
+Qt.Key_ContrastAdjust Qt.Key.Key_ContrastAdjust
+Qt.Key_MediaPause Qt.Key.Key_MediaPause
+Qt.Key_MediaTogglePlayPause Qt.Key.Key_MediaTogglePlayPause
+Qt.Key_LaunchG Qt.Key.Key_LaunchG
+Qt.Key_LaunchH Qt.Key.Key_LaunchH
+Qt.Key_ToggleCallHangup Qt.Key.Key_ToggleCallHangup
+Qt.Key_VoiceDial Qt.Key.Key_VoiceDial
+Qt.Key_LastNumberRedial Qt.Key.Key_LastNumberRedial
+Qt.Key_Camera Qt.Key.Key_Camera
+Qt.Key_CameraFocus Qt.Key.Key_CameraFocus
+Qt.Key_TouchpadToggle Qt.Key.Key_TouchpadToggle
+Qt.Key_TouchpadOn Qt.Key.Key_TouchpadOn
+Qt.Key_TouchpadOff Qt.Key.Key_TouchpadOff
+Qt.Key_MicMute Qt.Key.Key_MicMute
+Qt.Key_Red Qt.Key.Key_Red
+Qt.Key_Green Qt.Key.Key_Green
+Qt.Key_Yellow Qt.Key.Key_Yellow
+Qt.Key_Blue Qt.Key.Key_Blue
+Qt.Key_ChannelUp Qt.Key.Key_ChannelUp
+Qt.Key_ChannelDown Qt.Key.Key_ChannelDown
+Qt.Key_Guide Qt.Key.Key_Guide
+Qt.Key_Info Qt.Key.Key_Info
+Qt.Key_Settings Qt.Key.Key_Settings
+Qt.Key_Exit Qt.Key.Key_Exit
+Qt.Key_MicVolumeUp Qt.Key.Key_MicVolumeUp
+Qt.Key_MicVolumeDown Qt.Key.Key_MicVolumeDown
+Qt.Key_New Qt.Key.Key_New
+Qt.Key_Open Qt.Key.Key_Open
+Qt.Key_Find Qt.Key.Key_Find
+Qt.Key_Undo Qt.Key.Key_Undo
+Qt.Key_Redo Qt.Key.Key_Redo
+Qt.Key_Dead_Stroke Qt.Key.Key_Dead_Stroke
+Qt.Key_Dead_Abovecomma Qt.Key.Key_Dead_Abovecomma
+Qt.Key_Dead_Abovereversedcomma Qt.Key.Key_Dead_Abovereversedcomma
+Qt.Key_Dead_Doublegrave Qt.Key.Key_Dead_Doublegrave
+Qt.Key_Dead_Belowring Qt.Key.Key_Dead_Belowring
+Qt.Key_Dead_Belowmacron Qt.Key.Key_Dead_Belowmacron
+Qt.Key_Dead_Belowcircumflex Qt.Key.Key_Dead_Belowcircumflex
+Qt.Key_Dead_Belowtilde Qt.Key.Key_Dead_Belowtilde
+Qt.Key_Dead_Belowbreve Qt.Key.Key_Dead_Belowbreve
+Qt.Key_Dead_Belowdiaeresis Qt.Key.Key_Dead_Belowdiaeresis
+Qt.Key_Dead_Invertedbreve Qt.Key.Key_Dead_Invertedbreve
+Qt.Key_Dead_Belowcomma Qt.Key.Key_Dead_Belowcomma
+Qt.Key_Dead_Currency Qt.Key.Key_Dead_Currency
+Qt.Key_Dead_a Qt.Key.Key_Dead_a
+Qt.Key_Dead_A Qt.Key.Key_Dead_A
+Qt.Key_Dead_e Qt.Key.Key_Dead_e
+Qt.Key_Dead_E Qt.Key.Key_Dead_E
+Qt.Key_Dead_i Qt.Key.Key_Dead_i
+Qt.Key_Dead_I Qt.Key.Key_Dead_I
+Qt.Key_Dead_o Qt.Key.Key_Dead_o
+Qt.Key_Dead_O Qt.Key.Key_Dead_O
+Qt.Key_Dead_u Qt.Key.Key_Dead_u
+Qt.Key_Dead_U Qt.Key.Key_Dead_U
+Qt.Key_Dead_Small_Schwa Qt.Key.Key_Dead_Small_Schwa
+Qt.Key_Dead_Capital_Schwa Qt.Key.Key_Dead_Capital_Schwa
+Qt.Key_Dead_Greek Qt.Key.Key_Dead_Greek
+Qt.Key_Dead_Lowline Qt.Key.Key_Dead_Lowline
+Qt.Key_Dead_Aboveverticalline Qt.Key.Key_Dead_Aboveverticalline
+Qt.Key_Dead_Belowverticalline Qt.Key.Key_Dead_Belowverticalline
+Qt.Key_Dead_Longsolidusoverlay Qt.Key.Key_Dead_Longsolidusoverlay
+Qt.TransparentMode Qt.BGMode.TransparentMode
+Qt.OpaqueMode Qt.BGMode.OpaqueMode
+Qt.AutoColor Qt.ImageConversionFlag.AutoColor
+Qt.ColorOnly Qt.ImageConversionFlag.ColorOnly
+Qt.MonoOnly Qt.ImageConversionFlag.MonoOnly
+Qt.ThresholdAlphaDither Qt.ImageConversionFlag.ThresholdAlphaDither
+Qt.OrderedAlphaDither Qt.ImageConversionFlag.OrderedAlphaDither
+Qt.DiffuseAlphaDither Qt.ImageConversionFlag.DiffuseAlphaDither
+Qt.DiffuseDither Qt.ImageConversionFlag.DiffuseDither
+Qt.OrderedDither Qt.ImageConversionFlag.OrderedDither
+Qt.ThresholdDither Qt.ImageConversionFlag.ThresholdDither
+Qt.AutoDither Qt.ImageConversionFlag.AutoDither
+Qt.PreferDither Qt.ImageConversionFlag.PreferDither
+Qt.AvoidDither Qt.ImageConversionFlag.AvoidDither
+Qt.NoOpaqueDetection Qt.ImageConversionFlag.NoOpaqueDetection
+Qt.NoFormatConversion Qt.ImageConversionFlag.NoFormatConversion
+Qt.WA_Disabled Qt.WidgetAttribute.WA_Disabled
+Qt.WA_UnderMouse Qt.WidgetAttribute.WA_UnderMouse
+Qt.WA_MouseTracking Qt.WidgetAttribute.WA_MouseTracking
+Qt.WA_OpaquePaintEvent Qt.WidgetAttribute.WA_OpaquePaintEvent
+Qt.WA_StaticContents Qt.WidgetAttribute.WA_StaticContents
+Qt.WA_LaidOut Qt.WidgetAttribute.WA_LaidOut
+Qt.WA_PaintOnScreen Qt.WidgetAttribute.WA_PaintOnScreen
+Qt.WA_NoSystemBackground Qt.WidgetAttribute.WA_NoSystemBackground
+Qt.WA_UpdatesDisabled Qt.WidgetAttribute.WA_UpdatesDisabled
+Qt.WA_Mapped Qt.WidgetAttribute.WA_Mapped
+Qt.WA_MacNoClickThrough Qt.WidgetAttribute.WA_MacNoClickThrough
+Qt.WA_InputMethodEnabled Qt.WidgetAttribute.WA_InputMethodEnabled
+Qt.WA_WState_Visible Qt.WidgetAttribute.WA_WState_Visible
+Qt.WA_WState_Hidden Qt.WidgetAttribute.WA_WState_Hidden
+Qt.WA_ForceDisabled Qt.WidgetAttribute.WA_ForceDisabled
+Qt.WA_KeyCompression Qt.WidgetAttribute.WA_KeyCompression
+Qt.WA_PendingMoveEvent Qt.WidgetAttribute.WA_PendingMoveEvent
+Qt.WA_PendingResizeEvent Qt.WidgetAttribute.WA_PendingResizeEvent
+Qt.WA_SetPalette Qt.WidgetAttribute.WA_SetPalette
+Qt.WA_SetFont Qt.WidgetAttribute.WA_SetFont
+Qt.WA_SetCursor Qt.WidgetAttribute.WA_SetCursor
+Qt.WA_NoChildEventsFromChildren Qt.WidgetAttribute.WA_NoChildEventsFromChildren
+Qt.WA_WindowModified Qt.WidgetAttribute.WA_WindowModified
+Qt.WA_Resized Qt.WidgetAttribute.WA_Resized
+Qt.WA_Moved Qt.WidgetAttribute.WA_Moved
+Qt.WA_PendingUpdate Qt.WidgetAttribute.WA_PendingUpdate
+Qt.WA_InvalidSize Qt.WidgetAttribute.WA_InvalidSize
+Qt.WA_MacMetalStyle Qt.WidgetAttribute.WA_MacMetalStyle
+Qt.WA_CustomWhatsThis Qt.WidgetAttribute.WA_CustomWhatsThis
+Qt.WA_LayoutOnEntireRect Qt.WidgetAttribute.WA_LayoutOnEntireRect
+Qt.WA_OutsideWSRange Qt.WidgetAttribute.WA_OutsideWSRange
+Qt.WA_GrabbedShortcut Qt.WidgetAttribute.WA_GrabbedShortcut
+Qt.WA_TransparentForMouseEvents Qt.WidgetAttribute.WA_TransparentForMouseEvents
+Qt.WA_PaintUnclipped Qt.WidgetAttribute.WA_PaintUnclipped
+Qt.WA_SetWindowIcon Qt.WidgetAttribute.WA_SetWindowIcon
+Qt.WA_NoMouseReplay Qt.WidgetAttribute.WA_NoMouseReplay
+Qt.WA_DeleteOnClose Qt.WidgetAttribute.WA_DeleteOnClose
+Qt.WA_RightToLeft Qt.WidgetAttribute.WA_RightToLeft
+Qt.WA_SetLayoutDirection Qt.WidgetAttribute.WA_SetLayoutDirection
+Qt.WA_NoChildEventsForParent Qt.WidgetAttribute.WA_NoChildEventsForParent
+Qt.WA_ForceUpdatesDisabled Qt.WidgetAttribute.WA_ForceUpdatesDisabled
+Qt.WA_WState_Created Qt.WidgetAttribute.WA_WState_Created
+Qt.WA_WState_CompressKeys Qt.WidgetAttribute.WA_WState_CompressKeys
+Qt.WA_WState_InPaintEvent Qt.WidgetAttribute.WA_WState_InPaintEvent
+Qt.WA_WState_Reparented Qt.WidgetAttribute.WA_WState_Reparented
+Qt.WA_WState_ConfigPending Qt.WidgetAttribute.WA_WState_ConfigPending
+Qt.WA_WState_Polished Qt.WidgetAttribute.WA_WState_Polished
+Qt.WA_WState_OwnSizePolicy Qt.WidgetAttribute.WA_WState_OwnSizePolicy
+Qt.WA_WState_ExplicitShowHide Qt.WidgetAttribute.WA_WState_ExplicitShowHide
+Qt.WA_MouseNoMask Qt.WidgetAttribute.WA_MouseNoMask
+Qt.WA_GroupLeader Qt.WidgetAttribute.WA_GroupLeader
+Qt.WA_NoMousePropagation Qt.WidgetAttribute.WA_NoMousePropagation
+Qt.WA_Hover Qt.WidgetAttribute.WA_Hover
+Qt.WA_InputMethodTransparent Qt.WidgetAttribute.WA_InputMethodTransparent
+Qt.WA_QuitOnClose Qt.WidgetAttribute.WA_QuitOnClose
+Qt.WA_KeyboardFocusChange Qt.WidgetAttribute.WA_KeyboardFocusChange
+Qt.WA_AcceptDrops Qt.WidgetAttribute.WA_AcceptDrops
+Qt.WA_WindowPropagation Qt.WidgetAttribute.WA_WindowPropagation
+Qt.WA_NoX11EventCompression Qt.WidgetAttribute.WA_NoX11EventCompression
+Qt.WA_TintedBackground Qt.WidgetAttribute.WA_TintedBackground
+Qt.WA_X11OpenGLOverlay Qt.WidgetAttribute.WA_X11OpenGLOverlay
+Qt.WA_AttributeCount Qt.WidgetAttribute.WA_AttributeCount
+Qt.WA_AlwaysShowToolTips Qt.WidgetAttribute.WA_AlwaysShowToolTips
+Qt.WA_MacOpaqueSizeGrip Qt.WidgetAttribute.WA_MacOpaqueSizeGrip
+Qt.WA_SetStyle Qt.WidgetAttribute.WA_SetStyle
+Qt.WA_MacBrushedMetal Qt.WidgetAttribute.WA_MacBrushedMetal
+Qt.WA_SetLocale Qt.WidgetAttribute.WA_SetLocale
+Qt.WA_MacShowFocusRect Qt.WidgetAttribute.WA_MacShowFocusRect
+Qt.WA_MacNormalSize Qt.WidgetAttribute.WA_MacNormalSize
+Qt.WA_MacSmallSize Qt.WidgetAttribute.WA_MacSmallSize
+Qt.WA_MacMiniSize Qt.WidgetAttribute.WA_MacMiniSize
+Qt.WA_LayoutUsesWidgetRect Qt.WidgetAttribute.WA_LayoutUsesWidgetRect
+Qt.WA_StyledBackground Qt.WidgetAttribute.WA_StyledBackground
+Qt.WA_MSWindowsUseDirect3D Qt.WidgetAttribute.WA_MSWindowsUseDirect3D
+Qt.WA_MacAlwaysShowToolWindow Qt.WidgetAttribute.WA_MacAlwaysShowToolWindow
+Qt.WA_StyleSheet Qt.WidgetAttribute.WA_StyleSheet
+Qt.WA_ShowWithoutActivating Qt.WidgetAttribute.WA_ShowWithoutActivating
+Qt.WA_NativeWindow Qt.WidgetAttribute.WA_NativeWindow
+Qt.WA_DontCreateNativeAncestors Qt.WidgetAttribute.WA_DontCreateNativeAncestors
+Qt.WA_MacVariableSize Qt.WidgetAttribute.WA_MacVariableSize
+Qt.WA_DontShowOnScreen Qt.WidgetAttribute.WA_DontShowOnScreen
+Qt.WA_X11NetWmWindowTypeDesktop Qt.WidgetAttribute.WA_X11NetWmWindowTypeDesktop
+Qt.WA_X11NetWmWindowTypeDock Qt.WidgetAttribute.WA_X11NetWmWindowTypeDock
+Qt.WA_X11NetWmWindowTypeToolBar Qt.WidgetAttribute.WA_X11NetWmWindowTypeToolBar
+Qt.WA_X11NetWmWindowTypeMenu Qt.WidgetAttribute.WA_X11NetWmWindowTypeMenu
+Qt.WA_X11NetWmWindowTypeUtility Qt.WidgetAttribute.WA_X11NetWmWindowTypeUtility
+Qt.WA_X11NetWmWindowTypeSplash Qt.WidgetAttribute.WA_X11NetWmWindowTypeSplash
+Qt.WA_X11NetWmWindowTypeDialog Qt.WidgetAttribute.WA_X11NetWmWindowTypeDialog
+Qt.WA_X11NetWmWindowTypeDropDownMenu Qt.WidgetAttribute.WA_X11NetWmWindowTypeDropDownMenu
+Qt.WA_X11NetWmWindowTypePopupMenu Qt.WidgetAttribute.WA_X11NetWmWindowTypePopupMenu
+Qt.WA_X11NetWmWindowTypeToolTip Qt.WidgetAttribute.WA_X11NetWmWindowTypeToolTip
+Qt.WA_X11NetWmWindowTypeNotification Qt.WidgetAttribute.WA_X11NetWmWindowTypeNotification
+Qt.WA_X11NetWmWindowTypeCombo Qt.WidgetAttribute.WA_X11NetWmWindowTypeCombo
+Qt.WA_X11NetWmWindowTypeDND Qt.WidgetAttribute.WA_X11NetWmWindowTypeDND
+Qt.WA_MacFrameworkScaled Qt.WidgetAttribute.WA_MacFrameworkScaled
+Qt.WA_TranslucentBackground Qt.WidgetAttribute.WA_TranslucentBackground
+Qt.WA_AcceptTouchEvents Qt.WidgetAttribute.WA_AcceptTouchEvents
+Qt.WA_TouchPadAcceptSingleTouchEvents Qt.WidgetAttribute.WA_TouchPadAcceptSingleTouchEvents
+Qt.WA_X11DoNotAcceptFocus Qt.WidgetAttribute.WA_X11DoNotAcceptFocus
+Qt.WA_MacNoShadow Qt.WidgetAttribute.WA_MacNoShadow
+Qt.WA_AlwaysStackOnTop Qt.WidgetAttribute.WA_AlwaysStackOnTop
+Qt.WA_TabletTracking Qt.WidgetAttribute.WA_TabletTracking
+Qt.WA_ContentsMarginsRespectsSafeArea Qt.WidgetAttribute.WA_ContentsMarginsRespectsSafeArea
+Qt.WA_StyleSheetTarget Qt.WidgetAttribute.WA_StyleSheetTarget
+Qt.WindowNoState Qt.WindowState.WindowNoState
+Qt.WindowMinimized Qt.WindowState.WindowMinimized
+Qt.WindowMaximized Qt.WindowState.WindowMaximized
+Qt.WindowFullScreen Qt.WindowState.WindowFullScreen
+Qt.WindowActive Qt.WindowState.WindowActive
+Qt.Widget Qt.WindowType.Widget
+Qt.Window Qt.WindowType.Window
+Qt.Dialog Qt.WindowType.Dialog
+Qt.Sheet Qt.WindowType.Sheet
+Qt.Drawer Qt.WindowType.Drawer
+Qt.Popup Qt.WindowType.Popup
+Qt.Tool Qt.WindowType.Tool
+Qt.ToolTip Qt.WindowType.ToolTip
+Qt.SplashScreen Qt.WindowType.SplashScreen
+Qt.Desktop Qt.WindowType.Desktop
+Qt.SubWindow Qt.WindowType.SubWindow
+Qt.WindowType_Mask Qt.WindowType.WindowType_Mask
+Qt.MSWindowsFixedSizeDialogHint Qt.WindowType.MSWindowsFixedSizeDialogHint
+Qt.MSWindowsOwnDC Qt.WindowType.MSWindowsOwnDC
+Qt.X11BypassWindowManagerHint Qt.WindowType.X11BypassWindowManagerHint
+Qt.FramelessWindowHint Qt.WindowType.FramelessWindowHint
+Qt.CustomizeWindowHint Qt.WindowType.CustomizeWindowHint
+Qt.WindowTitleHint Qt.WindowType.WindowTitleHint
+Qt.WindowSystemMenuHint Qt.WindowType.WindowSystemMenuHint
+Qt.WindowMinimizeButtonHint Qt.WindowType.WindowMinimizeButtonHint
+Qt.WindowMaximizeButtonHint Qt.WindowType.WindowMaximizeButtonHint
+Qt.WindowMinMaxButtonsHint Qt.WindowType.WindowMinMaxButtonsHint
+Qt.WindowContextHelpButtonHint Qt.WindowType.WindowContextHelpButtonHint
+Qt.WindowShadeButtonHint Qt.WindowType.WindowShadeButtonHint
+Qt.WindowStaysOnTopHint Qt.WindowType.WindowStaysOnTopHint
+Qt.WindowStaysOnBottomHint Qt.WindowType.WindowStaysOnBottomHint
+Qt.WindowCloseButtonHint Qt.WindowType.WindowCloseButtonHint
+Qt.MacWindowToolBarButtonHint Qt.WindowType.MacWindowToolBarButtonHint
+Qt.BypassGraphicsProxyWidget Qt.WindowType.BypassGraphicsProxyWidget
+Qt.WindowTransparentForInput Qt.WindowType.WindowTransparentForInput
+Qt.WindowOverridesSystemGestures Qt.WindowType.WindowOverridesSystemGestures
+Qt.WindowDoesNotAcceptFocus Qt.WindowType.WindowDoesNotAcceptFocus
+Qt.NoDropShadowWindowHint Qt.WindowType.NoDropShadowWindowHint
+Qt.WindowFullscreenButtonHint Qt.WindowType.WindowFullscreenButtonHint
+Qt.ForeignWindow Qt.WindowType.ForeignWindow
+Qt.BypassWindowManagerHint Qt.WindowType.BypassWindowManagerHint
+Qt.CoverWindow Qt.WindowType.CoverWindow
+Qt.MaximizeUsingFullscreenGeometryHint Qt.WindowType.MaximizeUsingFullscreenGeometryHint
+Qt.ElideLeft Qt.TextElideMode.ElideLeft
+Qt.ElideRight Qt.TextElideMode.ElideRight
+Qt.ElideMiddle Qt.TextElideMode.ElideMiddle
+Qt.ElideNone Qt.TextElideMode.ElideNone
+Qt.TextSingleLine Qt.TextFlag.TextSingleLine
+Qt.TextDontClip Qt.TextFlag.TextDontClip
+Qt.TextExpandTabs Qt.TextFlag.TextExpandTabs
+Qt.TextShowMnemonic Qt.TextFlag.TextShowMnemonic
+Qt.TextWordWrap Qt.TextFlag.TextWordWrap
+Qt.TextWrapAnywhere Qt.TextFlag.TextWrapAnywhere
+Qt.TextDontPrint Qt.TextFlag.TextDontPrint
+Qt.TextIncludeTrailingSpaces Qt.TextFlag.TextIncludeTrailingSpaces
+Qt.TextHideMnemonic Qt.TextFlag.TextHideMnemonic
+Qt.TextJustificationForced Qt.TextFlag.TextJustificationForced
+Qt.AlignLeft Qt.AlignmentFlag.AlignLeft
+Qt.AlignLeading Qt.AlignmentFlag.AlignLeading
+Qt.AlignRight Qt.AlignmentFlag.AlignRight
+Qt.AlignTrailing Qt.AlignmentFlag.AlignTrailing
+Qt.AlignHCenter Qt.AlignmentFlag.AlignHCenter
+Qt.AlignJustify Qt.AlignmentFlag.AlignJustify
+Qt.AlignAbsolute Qt.AlignmentFlag.AlignAbsolute
+Qt.AlignHorizontal_Mask Qt.AlignmentFlag.AlignHorizontal_Mask
+Qt.AlignTop Qt.AlignmentFlag.AlignTop
+Qt.AlignBottom Qt.AlignmentFlag.AlignBottom
+Qt.AlignVCenter Qt.AlignmentFlag.AlignVCenter
+Qt.AlignVertical_Mask Qt.AlignmentFlag.AlignVertical_Mask
+Qt.AlignCenter Qt.AlignmentFlag.AlignCenter
+Qt.AlignBaseline Qt.AlignmentFlag.AlignBaseline
+Qt.AscendingOrder Qt.SortOrder.AscendingOrder
+Qt.DescendingOrder Qt.SortOrder.DescendingOrder
+Qt.NoFocus Qt.FocusPolicy.NoFocus
+Qt.TabFocus Qt.FocusPolicy.TabFocus
+Qt.ClickFocus Qt.FocusPolicy.ClickFocus
+Qt.StrongFocus Qt.FocusPolicy.StrongFocus
+Qt.WheelFocus Qt.FocusPolicy.WheelFocus
+Qt.Horizontal Qt.Orientation.Horizontal
+Qt.Vertical Qt.Orientation.Vertical
+Qt.NoButton Qt.MouseButton.NoButton
+Qt.AllButtons Qt.MouseButton.AllButtons
+Qt.LeftButton Qt.MouseButton.LeftButton
+Qt.RightButton Qt.MouseButton.RightButton
+Qt.MidButton Qt.MouseButton.MidButton
+Qt.MiddleButton Qt.MouseButton.MiddleButton
+Qt.XButton1 Qt.MouseButton.XButton1
+Qt.XButton2 Qt.MouseButton.XButton2
+Qt.BackButton Qt.MouseButton.BackButton
+Qt.ExtraButton1 Qt.MouseButton.ExtraButton1
+Qt.ForwardButton Qt.MouseButton.ForwardButton
+Qt.ExtraButton2 Qt.MouseButton.ExtraButton2
+Qt.TaskButton Qt.MouseButton.TaskButton
+Qt.ExtraButton3 Qt.MouseButton.ExtraButton3
+Qt.ExtraButton4 Qt.MouseButton.ExtraButton4
+Qt.ExtraButton5 Qt.MouseButton.ExtraButton5
+Qt.ExtraButton6 Qt.MouseButton.ExtraButton6
+Qt.ExtraButton7 Qt.MouseButton.ExtraButton7
+Qt.ExtraButton8 Qt.MouseButton.ExtraButton8
+Qt.ExtraButton9 Qt.MouseButton.ExtraButton9
+Qt.ExtraButton10 Qt.MouseButton.ExtraButton10
+Qt.ExtraButton11 Qt.MouseButton.ExtraButton11
+Qt.ExtraButton12 Qt.MouseButton.ExtraButton12
+Qt.ExtraButton13 Qt.MouseButton.ExtraButton13
+Qt.ExtraButton14 Qt.MouseButton.ExtraButton14
+Qt.ExtraButton15 Qt.MouseButton.ExtraButton15
+Qt.ExtraButton16 Qt.MouseButton.ExtraButton16
+Qt.ExtraButton17 Qt.MouseButton.ExtraButton17
+Qt.ExtraButton18 Qt.MouseButton.ExtraButton18
+Qt.ExtraButton19 Qt.MouseButton.ExtraButton19
+Qt.ExtraButton20 Qt.MouseButton.ExtraButton20
+Qt.ExtraButton21 Qt.MouseButton.ExtraButton21
+Qt.ExtraButton22 Qt.MouseButton.ExtraButton22
+Qt.ExtraButton23 Qt.MouseButton.ExtraButton23
+Qt.ExtraButton24 Qt.MouseButton.ExtraButton24
+Qt.META Qt.Modifier.META
+Qt.SHIFT Qt.Modifier.SHIFT
+Qt.CTRL Qt.Modifier.CTRL
+Qt.ALT Qt.Modifier.ALT
+Qt.MODIFIER_MASK Qt.Modifier.MODIFIER_MASK
+Qt.UNICODE_ACCEL Qt.Modifier.UNICODE_ACCEL
+Qt.NoModifier Qt.KeyboardModifier.NoModifier
+Qt.ShiftModifier Qt.KeyboardModifier.ShiftModifier
+Qt.ControlModifier Qt.KeyboardModifier.ControlModifier
+Qt.AltModifier Qt.KeyboardModifier.AltModifier
+Qt.MetaModifier Qt.KeyboardModifier.MetaModifier
+Qt.KeypadModifier Qt.KeyboardModifier.KeypadModifier
+Qt.GroupSwitchModifier Qt.KeyboardModifier.GroupSwitchModifier
+Qt.KeyboardModifierMask Qt.KeyboardModifier.KeyboardModifierMask
+Qt.color0 Qt.GlobalColor.color0
+Qt.color1 Qt.GlobalColor.color1
+Qt.black Qt.GlobalColor.black
+Qt.white Qt.GlobalColor.white
+Qt.darkGray Qt.GlobalColor.darkGray
+Qt.gray Qt.GlobalColor.gray
+Qt.lightGray Qt.GlobalColor.lightGray
+Qt.red Qt.GlobalColor.red
+Qt.green Qt.GlobalColor.green
+Qt.blue Qt.GlobalColor.blue
+Qt.cyan Qt.GlobalColor.cyan
+Qt.magenta Qt.GlobalColor.magenta
+Qt.yellow Qt.GlobalColor.yellow
+Qt.darkRed Qt.GlobalColor.darkRed
+Qt.darkGreen Qt.GlobalColor.darkGreen
+Qt.darkBlue Qt.GlobalColor.darkBlue
+Qt.darkCyan Qt.GlobalColor.darkCyan
+Qt.darkMagenta Qt.GlobalColor.darkMagenta
+Qt.darkYellow Qt.GlobalColor.darkYellow
+Qt.transparent Qt.GlobalColor.transparent
+QAbstractAnimation.KeepWhenStopped QAbstractAnimation.DeletionPolicy.KeepWhenStopped
+QAbstractAnimation.DeleteWhenStopped QAbstractAnimation.DeletionPolicy.DeleteWhenStopped
+QAbstractAnimation.Stopped QAbstractAnimation.State.Stopped
+QAbstractAnimation.Paused QAbstractAnimation.State.Paused
+QAbstractAnimation.Running QAbstractAnimation.State.Running
+QAbstractAnimation.Forward QAbstractAnimation.Direction.Forward
+QAbstractAnimation.Backward QAbstractAnimation.Direction.Backward
+QAbstractItemModel.NoOption QAbstractItemModel.CheckIndexOption.NoOption
+QAbstractItemModel.IndexIsValid QAbstractItemModel.CheckIndexOption.IndexIsValid
+QAbstractItemModel.DoNotUseParent QAbstractItemModel.CheckIndexOption.DoNotUseParent
+QAbstractItemModel.ParentIsInvalid QAbstractItemModel.CheckIndexOption.ParentIsInvalid
+QAbstractItemModel.NoLayoutChangeHint QAbstractItemModel.LayoutChangeHint.NoLayoutChangeHint
+QAbstractItemModel.VerticalSortHint QAbstractItemModel.LayoutChangeHint.VerticalSortHint
+QAbstractItemModel.HorizontalSortHint QAbstractItemModel.LayoutChangeHint.HorizontalSortHint
+QAbstractTransition.ExternalTransition QAbstractTransition.TransitionType.ExternalTransition
+QAbstractTransition.InternalTransition QAbstractTransition.TransitionType.InternalTransition
+QIODevice.NotOpen QIODevice.OpenModeFlag.NotOpen
+QIODevice.ReadOnly QIODevice.OpenModeFlag.ReadOnly
+QIODevice.WriteOnly QIODevice.OpenModeFlag.WriteOnly
+QIODevice.ReadWrite QIODevice.OpenModeFlag.ReadWrite
+QIODevice.Append QIODevice.OpenModeFlag.Append
+QIODevice.Truncate QIODevice.OpenModeFlag.Truncate
+QIODevice.Text QIODevice.OpenModeFlag.Text
+QIODevice.Unbuffered QIODevice.OpenModeFlag.Unbuffered
+QIODevice.NewOnly QIODevice.OpenModeFlag.NewOnly
+QIODevice.ExistingOnly QIODevice.OpenModeFlag.ExistingOnly
+QByteArray.Ok QByteArray.Base64DecodingStatus.Ok
+QByteArray.IllegalInputLength QByteArray.Base64DecodingStatus.IllegalInputLength
+QByteArray.IllegalCharacter QByteArray.Base64DecodingStatus.IllegalCharacter
+QByteArray.IllegalPadding QByteArray.Base64DecodingStatus.IllegalPadding
+QByteArray.Base64Encoding QByteArray.Base64Option.Base64Encoding
+QByteArray.Base64UrlEncoding QByteArray.Base64Option.Base64UrlEncoding
+QByteArray.KeepTrailingEquals QByteArray.Base64Option.KeepTrailingEquals
+QByteArray.OmitTrailingEquals QByteArray.Base64Option.OmitTrailingEquals
+QByteArray.IgnoreBase64DecodingErrors QByteArray.Base64Option.IgnoreBase64DecodingErrors
+QByteArray.AbortOnBase64DecodingErrors QByteArray.Base64Option.AbortOnBase64DecodingErrors
+QCalendar.Gregorian QCalendar.System.Gregorian
+QCalendar.Julian QCalendar.System.Julian
+QCalendar.Milankovic QCalendar.System.Milankovic
+QCalendar.Jalali QCalendar.System.Jalali
+QCalendar.IslamicCivil QCalendar.System.IslamicCivil
+QCborError.UnknownError QCborError.Code.UnknownError
+QCborError.AdvancePastEnd QCborError.Code.AdvancePastEnd
+QCborError.InputOutputError QCborError.Code.InputOutputError
+QCborError.GarbageAtEnd QCborError.Code.GarbageAtEnd
+QCborError.EndOfFile QCborError.Code.EndOfFile
+QCborError.UnexpectedBreak QCborError.Code.UnexpectedBreak
+QCborError.UnknownType QCborError.Code.UnknownType
+QCborError.IllegalType QCborError.Code.IllegalType
+QCborError.IllegalNumber QCborError.Code.IllegalNumber
+QCborError.IllegalSimpleType QCborError.Code.IllegalSimpleType
+QCborError.InvalidUtf8String QCborError.Code.InvalidUtf8String
+QCborError.DataTooLarge QCborError.Code.DataTooLarge
+QCborError.NestingTooDeep QCborError.Code.NestingTooDeep
+QCborError.UnsupportedType QCborError.Code.UnsupportedType
+QCborError.NoError QCborError.Code.NoError
+QCborStreamReader.EndOfString QCborStreamReader.StringResultCode.EndOfString
+QCborStreamReader.Ok QCborStreamReader.StringResultCode.Ok
+QCborStreamReader.Error QCborStreamReader.StringResultCode.Error
+QCborStreamReader.UnsignedInteger QCborStreamReader.Type.UnsignedInteger
+QCborStreamReader.NegativeInteger QCborStreamReader.Type.NegativeInteger
+QCborStreamReader.ByteString QCborStreamReader.Type.ByteString
+QCborStreamReader.ByteArray QCborStreamReader.Type.ByteArray
+QCborStreamReader.TextString QCborStreamReader.Type.TextString
+QCborStreamReader.String QCborStreamReader.Type.String
+QCborStreamReader.Array QCborStreamReader.Type.Array
+QCborStreamReader.Map QCborStreamReader.Type.Map
+QCborStreamReader.Tag QCborStreamReader.Type.Tag
+QCborStreamReader.SimpleType QCborStreamReader.Type.SimpleType
+QCborStreamReader.HalfFloat QCborStreamReader.Type.HalfFloat
+QCborStreamReader.Float16 QCborStreamReader.Type.Float16
+QCborStreamReader.Float QCborStreamReader.Type.Float
+QCborStreamReader.Double QCborStreamReader.Type.Double
+QCborStreamReader.Invalid QCborStreamReader.Type.Invalid
+QCommandLineOption.HiddenFromHelp QCommandLineOption.Flag.HiddenFromHelp
+QCommandLineOption.ShortOptionStyle QCommandLineOption.Flag.ShortOptionStyle
+QCommandLineParser.ParseAsOptions QCommandLineParser.OptionsAfterPositionalArgumentsMode.ParseAsOptions
+QCommandLineParser.ParseAsPositionalArguments QCommandLineParser.OptionsAfterPositionalArgumentsMode.ParseAsPositionalArguments
+QCommandLineParser.ParseAsCompactedShortOptions QCommandLineParser.SingleDashWordOptionMode.ParseAsCompactedShortOptions
+QCommandLineParser.ParseAsLongOptions QCommandLineParser.SingleDashWordOptionMode.ParseAsLongOptions
+QEvent.None_ QEvent.Type.None_
+QEvent.Timer QEvent.Type.Timer
+QEvent.MouseButtonPress QEvent.Type.MouseButtonPress
+QEvent.MouseButtonRelease QEvent.Type.MouseButtonRelease
+QEvent.MouseButtonDblClick QEvent.Type.MouseButtonDblClick
+QEvent.MouseMove QEvent.Type.MouseMove
+QEvent.KeyPress QEvent.Type.KeyPress
+QEvent.KeyRelease QEvent.Type.KeyRelease
+QEvent.FocusIn QEvent.Type.FocusIn
+QEvent.FocusOut QEvent.Type.FocusOut
+QEvent.Enter QEvent.Type.Enter
+QEvent.Leave QEvent.Type.Leave
+QEvent.Paint QEvent.Type.Paint
+QEvent.Move QEvent.Type.Move
+QEvent.Resize QEvent.Type.Resize
+QEvent.Show QEvent.Type.Show
+QEvent.Hide QEvent.Type.Hide
+QEvent.Close QEvent.Type.Close
+QEvent.ParentChange QEvent.Type.ParentChange
+QEvent.ParentAboutToChange QEvent.Type.ParentAboutToChange
+QEvent.ThreadChange QEvent.Type.ThreadChange
+QEvent.WindowActivate QEvent.Type.WindowActivate
+QEvent.WindowDeactivate QEvent.Type.WindowDeactivate
+QEvent.ShowToParent QEvent.Type.ShowToParent
+QEvent.HideToParent QEvent.Type.HideToParent
+QEvent.Wheel QEvent.Type.Wheel
+QEvent.WindowTitleChange QEvent.Type.WindowTitleChange
+QEvent.WindowIconChange QEvent.Type.WindowIconChange
+QEvent.ApplicationWindowIconChange QEvent.Type.ApplicationWindowIconChange
+QEvent.ApplicationFontChange QEvent.Type.ApplicationFontChange
+QEvent.ApplicationLayoutDirectionChange QEvent.Type.ApplicationLayoutDirectionChange
+QEvent.ApplicationPaletteChange QEvent.Type.ApplicationPaletteChange
+QEvent.PaletteChange QEvent.Type.PaletteChange
+QEvent.Clipboard QEvent.Type.Clipboard
+QEvent.MetaCall QEvent.Type.MetaCall
+QEvent.SockAct QEvent.Type.SockAct
+QEvent.WinEventAct QEvent.Type.WinEventAct
+QEvent.DeferredDelete QEvent.Type.DeferredDelete
+QEvent.DragEnter QEvent.Type.DragEnter
+QEvent.DragMove QEvent.Type.DragMove
+QEvent.DragLeave QEvent.Type.DragLeave
+QEvent.Drop QEvent.Type.Drop
+QEvent.ChildAdded QEvent.Type.ChildAdded
+QEvent.ChildPolished QEvent.Type.ChildPolished
+QEvent.ChildRemoved QEvent.Type.ChildRemoved
+QEvent.PolishRequest QEvent.Type.PolishRequest
+QEvent.Polish QEvent.Type.Polish
+QEvent.LayoutRequest QEvent.Type.LayoutRequest
+QEvent.UpdateRequest QEvent.Type.UpdateRequest
+QEvent.UpdateLater QEvent.Type.UpdateLater
+QEvent.ContextMenu QEvent.Type.ContextMenu
+QEvent.InputMethod QEvent.Type.InputMethod
+QEvent.TabletMove QEvent.Type.TabletMove
+QEvent.LocaleChange QEvent.Type.LocaleChange
+QEvent.LanguageChange QEvent.Type.LanguageChange
+QEvent.LayoutDirectionChange QEvent.Type.LayoutDirectionChange
+QEvent.TabletPress QEvent.Type.TabletPress
+QEvent.TabletRelease QEvent.Type.TabletRelease
+QEvent.OkRequest QEvent.Type.OkRequest
+QEvent.IconDrag QEvent.Type.IconDrag
+QEvent.FontChange QEvent.Type.FontChange
+QEvent.EnabledChange QEvent.Type.EnabledChange
+QEvent.ActivationChange QEvent.Type.ActivationChange
+QEvent.StyleChange QEvent.Type.StyleChange
+QEvent.IconTextChange QEvent.Type.IconTextChange
+QEvent.ModifiedChange QEvent.Type.ModifiedChange
+QEvent.MouseTrackingChange QEvent.Type.MouseTrackingChange
+QEvent.WindowBlocked QEvent.Type.WindowBlocked
+QEvent.WindowUnblocked QEvent.Type.WindowUnblocked
+QEvent.WindowStateChange QEvent.Type.WindowStateChange
+QEvent.ToolTip QEvent.Type.ToolTip
+QEvent.WhatsThis QEvent.Type.WhatsThis
+QEvent.StatusTip QEvent.Type.StatusTip
+QEvent.ActionChanged QEvent.Type.ActionChanged
+QEvent.ActionAdded QEvent.Type.ActionAdded
+QEvent.ActionRemoved QEvent.Type.ActionRemoved
+QEvent.FileOpen QEvent.Type.FileOpen
+QEvent.Shortcut QEvent.Type.Shortcut
+QEvent.ShortcutOverride QEvent.Type.ShortcutOverride
+QEvent.WhatsThisClicked QEvent.Type.WhatsThisClicked
+QEvent.ToolBarChange QEvent.Type.ToolBarChange
+QEvent.ApplicationActivate QEvent.Type.ApplicationActivate
+QEvent.ApplicationActivated QEvent.Type.ApplicationActivated
+QEvent.ApplicationDeactivate QEvent.Type.ApplicationDeactivate
+QEvent.ApplicationDeactivated QEvent.Type.ApplicationDeactivated
+QEvent.QueryWhatsThis QEvent.Type.QueryWhatsThis
+QEvent.EnterWhatsThisMode QEvent.Type.EnterWhatsThisMode
+QEvent.LeaveWhatsThisMode QEvent.Type.LeaveWhatsThisMode
+QEvent.ZOrderChange QEvent.Type.ZOrderChange
+QEvent.HoverEnter QEvent.Type.HoverEnter
+QEvent.HoverLeave QEvent.Type.HoverLeave
+QEvent.HoverMove QEvent.Type.HoverMove
+QEvent.GraphicsSceneMouseMove QEvent.Type.GraphicsSceneMouseMove
+QEvent.GraphicsSceneMousePress QEvent.Type.GraphicsSceneMousePress
+QEvent.GraphicsSceneMouseRelease QEvent.Type.GraphicsSceneMouseRelease
+QEvent.GraphicsSceneMouseDoubleClick QEvent.Type.GraphicsSceneMouseDoubleClick
+QEvent.GraphicsSceneContextMenu QEvent.Type.GraphicsSceneContextMenu
+QEvent.GraphicsSceneHoverEnter QEvent.Type.GraphicsSceneHoverEnter
+QEvent.GraphicsSceneHoverMove QEvent.Type.GraphicsSceneHoverMove
+QEvent.GraphicsSceneHoverLeave QEvent.Type.GraphicsSceneHoverLeave
+QEvent.GraphicsSceneHelp QEvent.Type.GraphicsSceneHelp
+QEvent.GraphicsSceneDragEnter QEvent.Type.GraphicsSceneDragEnter
+QEvent.GraphicsSceneDragMove QEvent.Type.GraphicsSceneDragMove
+QEvent.GraphicsSceneDragLeave QEvent.Type.GraphicsSceneDragLeave
+QEvent.GraphicsSceneDrop QEvent.Type.GraphicsSceneDrop
+QEvent.GraphicsSceneWheel QEvent.Type.GraphicsSceneWheel
+QEvent.GraphicsSceneResize QEvent.Type.GraphicsSceneResize
+QEvent.GraphicsSceneMove QEvent.Type.GraphicsSceneMove
+QEvent.KeyboardLayoutChange QEvent.Type.KeyboardLayoutChange
+QEvent.DynamicPropertyChange QEvent.Type.DynamicPropertyChange
+QEvent.TabletEnterProximity QEvent.Type.TabletEnterProximity
+QEvent.TabletLeaveProximity QEvent.Type.TabletLeaveProximity
+QEvent.NonClientAreaMouseMove QEvent.Type.NonClientAreaMouseMove
+QEvent.NonClientAreaMouseButtonPress QEvent.Type.NonClientAreaMouseButtonPress
+QEvent.NonClientAreaMouseButtonRelease QEvent.Type.NonClientAreaMouseButtonRelease
+QEvent.NonClientAreaMouseButtonDblClick QEvent.Type.NonClientAreaMouseButtonDblClick
+QEvent.MacSizeChange QEvent.Type.MacSizeChange
+QEvent.ContentsRectChange QEvent.Type.ContentsRectChange
+QEvent.CursorChange QEvent.Type.CursorChange
+QEvent.ToolTipChange QEvent.Type.ToolTipChange
+QEvent.GrabMouse QEvent.Type.GrabMouse
+QEvent.UngrabMouse QEvent.Type.UngrabMouse
+QEvent.GrabKeyboard QEvent.Type.GrabKeyboard
+QEvent.UngrabKeyboard QEvent.Type.UngrabKeyboard
+QEvent.StateMachineSignal QEvent.Type.StateMachineSignal
+QEvent.StateMachineWrapped QEvent.Type.StateMachineWrapped
+QEvent.TouchBegin QEvent.Type.TouchBegin
+QEvent.TouchUpdate QEvent.Type.TouchUpdate
+QEvent.TouchEnd QEvent.Type.TouchEnd
+QEvent.RequestSoftwareInputPanel QEvent.Type.RequestSoftwareInputPanel
+QEvent.CloseSoftwareInputPanel QEvent.Type.CloseSoftwareInputPanel
+QEvent.WinIdChange QEvent.Type.WinIdChange
+QEvent.Gesture QEvent.Type.Gesture
+QEvent.GestureOverride QEvent.Type.GestureOverride
+QEvent.FocusAboutToChange QEvent.Type.FocusAboutToChange
+QEvent.ScrollPrepare QEvent.Type.ScrollPrepare
+QEvent.Scroll QEvent.Type.Scroll
+QEvent.Expose QEvent.Type.Expose
+QEvent.InputMethodQuery QEvent.Type.InputMethodQuery
+QEvent.OrientationChange QEvent.Type.OrientationChange
+QEvent.TouchCancel QEvent.Type.TouchCancel
+QEvent.PlatformPanel QEvent.Type.PlatformPanel
+QEvent.ApplicationStateChange QEvent.Type.ApplicationStateChange
+QEvent.ReadOnlyChange QEvent.Type.ReadOnlyChange
+QEvent.PlatformSurface QEvent.Type.PlatformSurface
+QEvent.TabletTrackingChange QEvent.Type.TabletTrackingChange
+QEvent.User QEvent.Type.User
+QEvent.MaxUser QEvent.Type.MaxUser
+QCryptographicHash.Md4 QCryptographicHash.Algorithm.Md4
+QCryptographicHash.Md5 QCryptographicHash.Algorithm.Md5
+QCryptographicHash.Sha1 QCryptographicHash.Algorithm.Sha1
+QCryptographicHash.Sha224 QCryptographicHash.Algorithm.Sha224
+QCryptographicHash.Sha256 QCryptographicHash.Algorithm.Sha256
+QCryptographicHash.Sha384 QCryptographicHash.Algorithm.Sha384
+QCryptographicHash.Sha512 QCryptographicHash.Algorithm.Sha512
+QCryptographicHash.Sha3_224 QCryptographicHash.Algorithm.Sha3_224
+QCryptographicHash.Sha3_256 QCryptographicHash.Algorithm.Sha3_256
+QCryptographicHash.Sha3_384 QCryptographicHash.Algorithm.Sha3_384
+QCryptographicHash.Sha3_512 QCryptographicHash.Algorithm.Sha3_512
+QCryptographicHash.Keccak_224 QCryptographicHash.Algorithm.Keccak_224
+QCryptographicHash.Keccak_256 QCryptographicHash.Algorithm.Keccak_256
+QCryptographicHash.Keccak_384 QCryptographicHash.Algorithm.Keccak_384
+QCryptographicHash.Keccak_512 QCryptographicHash.Algorithm.Keccak_512
+QDataStream.SinglePrecision QDataStream.FloatingPointPrecision.SinglePrecision
+QDataStream.DoublePrecision QDataStream.FloatingPointPrecision.DoublePrecision
+QDataStream.Ok QDataStream.Status.Ok
+QDataStream.ReadPastEnd QDataStream.Status.ReadPastEnd
+QDataStream.ReadCorruptData QDataStream.Status.ReadCorruptData
+QDataStream.WriteFailed QDataStream.Status.WriteFailed
+QDataStream.BigEndian QDataStream.ByteOrder.BigEndian
+QDataStream.LittleEndian QDataStream.ByteOrder.LittleEndian
+QDataStream.Qt_1_0 QDataStream.Version.Qt_1_0
+QDataStream.Qt_2_0 QDataStream.Version.Qt_2_0
+QDataStream.Qt_2_1 QDataStream.Version.Qt_2_1
+QDataStream.Qt_3_0 QDataStream.Version.Qt_3_0
+QDataStream.Qt_3_1 QDataStream.Version.Qt_3_1
+QDataStream.Qt_3_3 QDataStream.Version.Qt_3_3
+QDataStream.Qt_4_0 QDataStream.Version.Qt_4_0
+QDataStream.Qt_4_1 QDataStream.Version.Qt_4_1
+QDataStream.Qt_4_2 QDataStream.Version.Qt_4_2
+QDataStream.Qt_4_3 QDataStream.Version.Qt_4_3
+QDataStream.Qt_4_4 QDataStream.Version.Qt_4_4
+QDataStream.Qt_4_5 QDataStream.Version.Qt_4_5
+QDataStream.Qt_4_6 QDataStream.Version.Qt_4_6
+QDataStream.Qt_4_7 QDataStream.Version.Qt_4_7
+QDataStream.Qt_4_8 QDataStream.Version.Qt_4_8
+QDataStream.Qt_4_9 QDataStream.Version.Qt_4_9
+QDataStream.Qt_5_0 QDataStream.Version.Qt_5_0
+QDataStream.Qt_5_1 QDataStream.Version.Qt_5_1
+QDataStream.Qt_5_2 QDataStream.Version.Qt_5_2
+QDataStream.Qt_5_3 QDataStream.Version.Qt_5_3
+QDataStream.Qt_5_4 QDataStream.Version.Qt_5_4
+QDataStream.Qt_5_5 QDataStream.Version.Qt_5_5
+QDataStream.Qt_5_6 QDataStream.Version.Qt_5_6
+QDataStream.Qt_5_7 QDataStream.Version.Qt_5_7
+QDataStream.Qt_5_8 QDataStream.Version.Qt_5_8
+QDataStream.Qt_5_9 QDataStream.Version.Qt_5_9
+QDataStream.Qt_5_10 QDataStream.Version.Qt_5_10
+QDataStream.Qt_5_11 QDataStream.Version.Qt_5_11
+QDataStream.Qt_5_12 QDataStream.Version.Qt_5_12
+QDataStream.Qt_5_13 QDataStream.Version.Qt_5_13
+QDataStream.Qt_5_14 QDataStream.Version.Qt_5_14
+QDataStream.Qt_5_15 QDataStream.Version.Qt_5_15
+QDate.DateFormat QDate.MonthNameType.DateFormat
+QDate.StandaloneFormat QDate.MonthNameType.StandaloneFormat
+QDateTime.First QDateTime.YearRange.First
+QDateTime.Last QDateTime.YearRange.Last
+QDeadlineTimer.Forever QDeadlineTimer.ForeverConstant.Forever
+QDir.Name QDir.SortFlag.Name
+QDir.Time QDir.SortFlag.Time
+QDir.Size QDir.SortFlag.Size
+QDir.Unsorted QDir.SortFlag.Unsorted
+QDir.SortByMask QDir.SortFlag.SortByMask
+QDir.DirsFirst QDir.SortFlag.DirsFirst
+QDir.Reversed QDir.SortFlag.Reversed
+QDir.IgnoreCase QDir.SortFlag.IgnoreCase
+QDir.DirsLast QDir.SortFlag.DirsLast
+QDir.LocaleAware QDir.SortFlag.LocaleAware
+QDir.Type QDir.SortFlag.Type
+QDir.NoSort QDir.SortFlag.NoSort
+QDir.Dirs QDir.Filter.Dirs
+QDir.Files QDir.Filter.Files
+QDir.Drives QDir.Filter.Drives
+QDir.NoSymLinks QDir.Filter.NoSymLinks
+QDir.AllEntries QDir.Filter.AllEntries
+QDir.TypeMask QDir.Filter.TypeMask
+QDir.Readable QDir.Filter.Readable
+QDir.Writable QDir.Filter.Writable
+QDir.Executable QDir.Filter.Executable
+QDir.PermissionMask QDir.Filter.PermissionMask
+QDir.Modified QDir.Filter.Modified
+QDir.Hidden QDir.Filter.Hidden
+QDir.System QDir.Filter.System
+QDir.AccessMask QDir.Filter.AccessMask
+QDir.AllDirs QDir.Filter.AllDirs
+QDir.CaseSensitive QDir.Filter.CaseSensitive
+QDir.NoDotAndDotDot QDir.Filter.NoDotAndDotDot
+QDir.NoFilter QDir.Filter.NoFilter
+QDir.NoDot QDir.Filter.NoDot
+QDir.NoDotDot QDir.Filter.NoDotDot
+QDirIterator.NoIteratorFlags QDirIterator.IteratorFlag.NoIteratorFlags
+QDirIterator.FollowSymlinks QDirIterator.IteratorFlag.FollowSymlinks
+QDirIterator.Subdirectories QDirIterator.IteratorFlag.Subdirectories
+QEasingCurve.Linear QEasingCurve.Type.Linear
+QEasingCurve.InQuad QEasingCurve.Type.InQuad
+QEasingCurve.OutQuad QEasingCurve.Type.OutQuad
+QEasingCurve.InOutQuad QEasingCurve.Type.InOutQuad
+QEasingCurve.OutInQuad QEasingCurve.Type.OutInQuad
+QEasingCurve.InCubic QEasingCurve.Type.InCubic
+QEasingCurve.OutCubic QEasingCurve.Type.OutCubic
+QEasingCurve.InOutCubic QEasingCurve.Type.InOutCubic
+QEasingCurve.OutInCubic QEasingCurve.Type.OutInCubic
+QEasingCurve.InQuart QEasingCurve.Type.InQuart
+QEasingCurve.OutQuart QEasingCurve.Type.OutQuart
+QEasingCurve.InOutQuart QEasingCurve.Type.InOutQuart
+QEasingCurve.OutInQuart QEasingCurve.Type.OutInQuart
+QEasingCurve.InQuint QEasingCurve.Type.InQuint
+QEasingCurve.OutQuint QEasingCurve.Type.OutQuint
+QEasingCurve.InOutQuint QEasingCurve.Type.InOutQuint
+QEasingCurve.OutInQuint QEasingCurve.Type.OutInQuint
+QEasingCurve.InSine QEasingCurve.Type.InSine
+QEasingCurve.OutSine QEasingCurve.Type.OutSine
+QEasingCurve.InOutSine QEasingCurve.Type.InOutSine
+QEasingCurve.OutInSine QEasingCurve.Type.OutInSine
+QEasingCurve.InExpo QEasingCurve.Type.InExpo
+QEasingCurve.OutExpo QEasingCurve.Type.OutExpo
+QEasingCurve.InOutExpo QEasingCurve.Type.InOutExpo
+QEasingCurve.OutInExpo QEasingCurve.Type.OutInExpo
+QEasingCurve.InCirc QEasingCurve.Type.InCirc
+QEasingCurve.OutCirc QEasingCurve.Type.OutCirc
+QEasingCurve.InOutCirc QEasingCurve.Type.InOutCirc
+QEasingCurve.OutInCirc QEasingCurve.Type.OutInCirc
+QEasingCurve.InElastic QEasingCurve.Type.InElastic
+QEasingCurve.OutElastic QEasingCurve.Type.OutElastic
+QEasingCurve.InOutElastic QEasingCurve.Type.InOutElastic
+QEasingCurve.OutInElastic QEasingCurve.Type.OutInElastic
+QEasingCurve.InBack QEasingCurve.Type.InBack
+QEasingCurve.OutBack QEasingCurve.Type.OutBack
+QEasingCurve.InOutBack QEasingCurve.Type.InOutBack
+QEasingCurve.OutInBack QEasingCurve.Type.OutInBack
+QEasingCurve.InBounce QEasingCurve.Type.InBounce
+QEasingCurve.OutBounce QEasingCurve.Type.OutBounce
+QEasingCurve.InOutBounce QEasingCurve.Type.InOutBounce
+QEasingCurve.OutInBounce QEasingCurve.Type.OutInBounce
+QEasingCurve.InCurve QEasingCurve.Type.InCurve
+QEasingCurve.OutCurve QEasingCurve.Type.OutCurve
+QEasingCurve.SineCurve QEasingCurve.Type.SineCurve
+QEasingCurve.CosineCurve QEasingCurve.Type.CosineCurve
+QEasingCurve.BezierSpline QEasingCurve.Type.BezierSpline
+QEasingCurve.TCBSpline QEasingCurve.Type.TCBSpline
+QEasingCurve.Custom QEasingCurve.Type.Custom
+QElapsedTimer.SystemTime QElapsedTimer.ClockType.SystemTime
+QElapsedTimer.MonotonicClock QElapsedTimer.ClockType.MonotonicClock
+QElapsedTimer.TickCounter QElapsedTimer.ClockType.TickCounter
+QElapsedTimer.MachAbsoluteTime QElapsedTimer.ClockType.MachAbsoluteTime
+QElapsedTimer.PerformanceCounter QElapsedTimer.ClockType.PerformanceCounter
+QEventLoop.AllEvents QEventLoop.ProcessEventsFlag.AllEvents
+QEventLoop.ExcludeUserInputEvents QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents
+QEventLoop.ExcludeSocketNotifiers QEventLoop.ProcessEventsFlag.ExcludeSocketNotifiers
+QEventLoop.WaitForMoreEvents QEventLoop.ProcessEventsFlag.WaitForMoreEvents
+QEventLoop.X11ExcludeTimers QEventLoop.ProcessEventsFlag.X11ExcludeTimers
+QFileDevice.FileAccessTime QFileDevice.FileTime.FileAccessTime
+QFileDevice.FileBirthTime QFileDevice.FileTime.FileBirthTime
+QFileDevice.FileMetadataChangeTime QFileDevice.FileTime.FileMetadataChangeTime
+QFileDevice.FileModificationTime QFileDevice.FileTime.FileModificationTime
+QFileDevice.NoOptions QFileDevice.MemoryMapFlags.NoOptions
+QFileDevice.MapPrivateOption QFileDevice.MemoryMapFlags.MapPrivateOption
+QFileDevice.AutoCloseHandle QFileDevice.FileHandleFlag.AutoCloseHandle
+QFileDevice.DontCloseHandle QFileDevice.FileHandleFlag.DontCloseHandle
+QFileDevice.ReadOwner QFileDevice.Permission.ReadOwner
+QFileDevice.WriteOwner QFileDevice.Permission.WriteOwner
+QFileDevice.ExeOwner QFileDevice.Permission.ExeOwner
+QFileDevice.ReadUser QFileDevice.Permission.ReadUser
+QFileDevice.WriteUser QFileDevice.Permission.WriteUser
+QFileDevice.ExeUser QFileDevice.Permission.ExeUser
+QFileDevice.ReadGroup QFileDevice.Permission.ReadGroup
+QFileDevice.WriteGroup QFileDevice.Permission.WriteGroup
+QFileDevice.ExeGroup QFileDevice.Permission.ExeGroup
+QFileDevice.ReadOther QFileDevice.Permission.ReadOther
+QFileDevice.WriteOther QFileDevice.Permission.WriteOther
+QFileDevice.ExeOther QFileDevice.Permission.ExeOther
+QFileDevice.NoError QFileDevice.FileError.NoError
+QFileDevice.ReadError QFileDevice.FileError.ReadError
+QFileDevice.WriteError QFileDevice.FileError.WriteError
+QFileDevice.FatalError QFileDevice.FileError.FatalError
+QFileDevice.ResourceError QFileDevice.FileError.ResourceError
+QFileDevice.OpenError QFileDevice.FileError.OpenError
+QFileDevice.AbortError QFileDevice.FileError.AbortError
+QFileDevice.TimeOutError QFileDevice.FileError.TimeOutError
+QFileDevice.UnspecifiedError QFileDevice.FileError.UnspecifiedError
+QFileDevice.RemoveError QFileDevice.FileError.RemoveError
+QFileDevice.RenameError QFileDevice.FileError.RenameError
+QFileDevice.PositionError QFileDevice.FileError.PositionError
+QFileDevice.ResizeError QFileDevice.FileError.ResizeError
+QFileDevice.PermissionsError QFileDevice.FileError.PermissionsError
+QFileDevice.CopyError QFileDevice.FileError.CopyError
+QHistoryState.ShallowHistory QHistoryState.HistoryType.ShallowHistory
+QHistoryState.DeepHistory QHistoryState.HistoryType.DeepHistory
+QItemSelectionModel.NoUpdate QItemSelectionModel.SelectionFlag.NoUpdate
+QItemSelectionModel.Clear QItemSelectionModel.SelectionFlag.Clear
+QItemSelectionModel.Select QItemSelectionModel.SelectionFlag.Select
+QItemSelectionModel.Deselect QItemSelectionModel.SelectionFlag.Deselect
+QItemSelectionModel.Toggle QItemSelectionModel.SelectionFlag.Toggle
+QItemSelectionModel.Current QItemSelectionModel.SelectionFlag.Current
+QItemSelectionModel.Rows QItemSelectionModel.SelectionFlag.Rows
+QItemSelectionModel.Columns QItemSelectionModel.SelectionFlag.Columns
+QItemSelectionModel.SelectCurrent QItemSelectionModel.SelectionFlag.SelectCurrent
+QItemSelectionModel.ToggleCurrent QItemSelectionModel.SelectionFlag.ToggleCurrent
+QItemSelectionModel.ClearAndSelect QItemSelectionModel.SelectionFlag.ClearAndSelect
+QJsonParseError.NoError QJsonParseError.ParseError.NoError
+QJsonParseError.UnterminatedObject QJsonParseError.ParseError.UnterminatedObject
+QJsonParseError.MissingNameSeparator QJsonParseError.ParseError.MissingNameSeparator
+QJsonParseError.UnterminatedArray QJsonParseError.ParseError.UnterminatedArray
+QJsonParseError.MissingValueSeparator QJsonParseError.ParseError.MissingValueSeparator
+QJsonParseError.IllegalValue QJsonParseError.ParseError.IllegalValue
+QJsonParseError.TerminationByNumber QJsonParseError.ParseError.TerminationByNumber
+QJsonParseError.IllegalNumber QJsonParseError.ParseError.IllegalNumber
+QJsonParseError.IllegalEscapeSequence QJsonParseError.ParseError.IllegalEscapeSequence
+QJsonParseError.IllegalUTF8String QJsonParseError.ParseError.IllegalUTF8String
+QJsonParseError.UnterminatedString QJsonParseError.ParseError.UnterminatedString
+QJsonParseError.MissingObject QJsonParseError.ParseError.MissingObject
+QJsonParseError.DeepNesting QJsonParseError.ParseError.DeepNesting
+QJsonParseError.DocumentTooLarge QJsonParseError.ParseError.DocumentTooLarge
+QJsonParseError.GarbageAtEnd QJsonParseError.ParseError.GarbageAtEnd
+QJsonParseError.error QJsonParseError.ParseError.error
+QJsonDocument.Indented QJsonDocument.JsonFormat.Indented
+QJsonDocument.Compact QJsonDocument.JsonFormat.Compact
+QJsonDocument.Validate QJsonDocument.DataValidation.Validate
+QJsonDocument.BypassValidation QJsonDocument.DataValidation.BypassValidation
+QJsonValue.Null QJsonValue.Type.Null
+QJsonValue.Bool QJsonValue.Type.Bool
+QJsonValue.Double QJsonValue.Type.Double
+QJsonValue.String QJsonValue.Type.String
+QJsonValue.Array QJsonValue.Type.Array
+QJsonValue.Object QJsonValue.Type.Object
+QJsonValue.Undefined QJsonValue.Type.Undefined
+QLibrary.ResolveAllSymbolsHint QLibrary.LoadHint.ResolveAllSymbolsHint
+QLibrary.ExportExternalSymbolsHint QLibrary.LoadHint.ExportExternalSymbolsHint
+QLibrary.LoadArchiveMemberHint QLibrary.LoadHint.LoadArchiveMemberHint
+QLibrary.PreventUnloadHint QLibrary.LoadHint.PreventUnloadHint
+QLibrary.DeepBindHint QLibrary.LoadHint.DeepBindHint
+QLibraryInfo.PrefixPath QLibraryInfo.LibraryLocation.PrefixPath
+QLibraryInfo.DocumentationPath QLibraryInfo.LibraryLocation.DocumentationPath
+QLibraryInfo.HeadersPath QLibraryInfo.LibraryLocation.HeadersPath
+QLibraryInfo.LibrariesPath QLibraryInfo.LibraryLocation.LibrariesPath
+QLibraryInfo.BinariesPath QLibraryInfo.LibraryLocation.BinariesPath
+QLibraryInfo.PluginsPath QLibraryInfo.LibraryLocation.PluginsPath
+QLibraryInfo.DataPath QLibraryInfo.LibraryLocation.DataPath
+QLibraryInfo.TranslationsPath QLibraryInfo.LibraryLocation.TranslationsPath
+QLibraryInfo.SettingsPath QLibraryInfo.LibraryLocation.SettingsPath
+QLibraryInfo.ExamplesPath QLibraryInfo.LibraryLocation.ExamplesPath
+QLibraryInfo.ImportsPath QLibraryInfo.LibraryLocation.ImportsPath
+QLibraryInfo.TestsPath QLibraryInfo.LibraryLocation.TestsPath
+QLibraryInfo.LibraryExecutablesPath QLibraryInfo.LibraryLocation.LibraryExecutablesPath
+QLibraryInfo.Qml2ImportsPath QLibraryInfo.LibraryLocation.Qml2ImportsPath
+QLibraryInfo.ArchDataPath QLibraryInfo.LibraryLocation.ArchDataPath
+QLineF.NoIntersection QLineF.IntersectType.NoIntersection
+QLineF.BoundedIntersection QLineF.IntersectType.BoundedIntersection
+QLineF.UnboundedIntersection QLineF.IntersectType.UnboundedIntersection
+QLocale.DataSizeIecFormat QLocale.DataSizeFormat.DataSizeIecFormat
+QLocale.DataSizeTraditionalFormat QLocale.DataSizeFormat.DataSizeTraditionalFormat
+QLocale.DataSizeSIFormat QLocale.DataSizeFormat.DataSizeSIFormat
+QLocale.FloatingPointShortest QLocale.FloatingPointPrecisionOption.FloatingPointShortest
+QLocale.StandardQuotation QLocale.QuotationStyle.StandardQuotation
+QLocale.AlternateQuotation QLocale.QuotationStyle.AlternateQuotation
+QLocale.CurrencyIsoCode QLocale.CurrencySymbolFormat.CurrencyIsoCode
+QLocale.CurrencySymbol QLocale.CurrencySymbolFormat.CurrencySymbol
+QLocale.CurrencyDisplayName QLocale.CurrencySymbolFormat.CurrencyDisplayName
+QLocale.AnyScript QLocale.Script.AnyScript
+QLocale.ArabicScript QLocale.Script.ArabicScript
+QLocale.CyrillicScript QLocale.Script.CyrillicScript
+QLocale.DeseretScript QLocale.Script.DeseretScript
+QLocale.GurmukhiScript QLocale.Script.GurmukhiScript
+QLocale.SimplifiedHanScript QLocale.Script.SimplifiedHanScript
+QLocale.TraditionalHanScript QLocale.Script.TraditionalHanScript
+QLocale.LatinScript QLocale.Script.LatinScript
+QLocale.MongolianScript QLocale.Script.MongolianScript
+QLocale.TifinaghScript QLocale.Script.TifinaghScript
+QLocale.SimplifiedChineseScript QLocale.Script.SimplifiedChineseScript
+QLocale.TraditionalChineseScript QLocale.Script.TraditionalChineseScript
+QLocale.ArmenianScript QLocale.Script.ArmenianScript
+QLocale.BengaliScript QLocale.Script.BengaliScript
+QLocale.CherokeeScript QLocale.Script.CherokeeScript
+QLocale.DevanagariScript QLocale.Script.DevanagariScript
+QLocale.EthiopicScript QLocale.Script.EthiopicScript
+QLocale.GeorgianScript QLocale.Script.GeorgianScript
+QLocale.GreekScript QLocale.Script.GreekScript
+QLocale.GujaratiScript QLocale.Script.GujaratiScript
+QLocale.HebrewScript QLocale.Script.HebrewScript
+QLocale.JapaneseScript QLocale.Script.JapaneseScript
+QLocale.KhmerScript QLocale.Script.KhmerScript
+QLocale.KannadaScript QLocale.Script.KannadaScript
+QLocale.KoreanScript QLocale.Script.KoreanScript
+QLocale.LaoScript QLocale.Script.LaoScript
+QLocale.MalayalamScript QLocale.Script.MalayalamScript
+QLocale.MyanmarScript QLocale.Script.MyanmarScript
+QLocale.OriyaScript QLocale.Script.OriyaScript
+QLocale.TamilScript QLocale.Script.TamilScript
+QLocale.TeluguScript QLocale.Script.TeluguScript
+QLocale.ThaanaScript QLocale.Script.ThaanaScript
+QLocale.ThaiScript QLocale.Script.ThaiScript
+QLocale.TibetanScript QLocale.Script.TibetanScript
+QLocale.SinhalaScript QLocale.Script.SinhalaScript
+QLocale.SyriacScript QLocale.Script.SyriacScript
+QLocale.YiScript QLocale.Script.YiScript
+QLocale.VaiScript QLocale.Script.VaiScript
+QLocale.AvestanScript QLocale.Script.AvestanScript
+QLocale.BalineseScript QLocale.Script.BalineseScript
+QLocale.BamumScript QLocale.Script.BamumScript
+QLocale.BatakScript QLocale.Script.BatakScript
+QLocale.BopomofoScript QLocale.Script.BopomofoScript
+QLocale.BrahmiScript QLocale.Script.BrahmiScript
+QLocale.BugineseScript QLocale.Script.BugineseScript
+QLocale.BuhidScript QLocale.Script.BuhidScript
+QLocale.CanadianAboriginalScript QLocale.Script.CanadianAboriginalScript
+QLocale.CarianScript QLocale.Script.CarianScript
+QLocale.ChakmaScript QLocale.Script.ChakmaScript
+QLocale.ChamScript QLocale.Script.ChamScript
+QLocale.CopticScript QLocale.Script.CopticScript
+QLocale.CypriotScript QLocale.Script.CypriotScript
+QLocale.EgyptianHieroglyphsScript QLocale.Script.EgyptianHieroglyphsScript
+QLocale.FraserScript QLocale.Script.FraserScript
+QLocale.GlagoliticScript QLocale.Script.GlagoliticScript
+QLocale.GothicScript QLocale.Script.GothicScript
+QLocale.HanScript QLocale.Script.HanScript
+QLocale.HangulScript QLocale.Script.HangulScript
+QLocale.HanunooScript QLocale.Script.HanunooScript
+QLocale.ImperialAramaicScript QLocale.Script.ImperialAramaicScript
+QLocale.InscriptionalPahlaviScript QLocale.Script.InscriptionalPahlaviScript
+QLocale.InscriptionalParthianScript QLocale.Script.InscriptionalParthianScript
+QLocale.JavaneseScript QLocale.Script.JavaneseScript
+QLocale.KaithiScript QLocale.Script.KaithiScript
+QLocale.KatakanaScript QLocale.Script.KatakanaScript
+QLocale.KayahLiScript QLocale.Script.KayahLiScript
+QLocale.KharoshthiScript QLocale.Script.KharoshthiScript
+QLocale.LannaScript QLocale.Script.LannaScript
+QLocale.LepchaScript QLocale.Script.LepchaScript
+QLocale.LimbuScript QLocale.Script.LimbuScript
+QLocale.LinearBScript QLocale.Script.LinearBScript
+QLocale.LycianScript QLocale.Script.LycianScript
+QLocale.LydianScript QLocale.Script.LydianScript
+QLocale.MandaeanScript QLocale.Script.MandaeanScript
+QLocale.MeiteiMayekScript QLocale.Script.MeiteiMayekScript
+QLocale.MeroiticScript QLocale.Script.MeroiticScript
+QLocale.MeroiticCursiveScript QLocale.Script.MeroiticCursiveScript
+QLocale.NkoScript QLocale.Script.NkoScript
+QLocale.NewTaiLueScript QLocale.Script.NewTaiLueScript
+QLocale.OghamScript QLocale.Script.OghamScript
+QLocale.OlChikiScript QLocale.Script.OlChikiScript
+QLocale.OldItalicScript QLocale.Script.OldItalicScript
+QLocale.OldPersianScript QLocale.Script.OldPersianScript
+QLocale.OldSouthArabianScript QLocale.Script.OldSouthArabianScript
+QLocale.OrkhonScript QLocale.Script.OrkhonScript
+QLocale.OsmanyaScript QLocale.Script.OsmanyaScript
+QLocale.PhagsPaScript QLocale.Script.PhagsPaScript
+QLocale.PhoenicianScript QLocale.Script.PhoenicianScript
+QLocale.PollardPhoneticScript QLocale.Script.PollardPhoneticScript
+QLocale.RejangScript QLocale.Script.RejangScript
+QLocale.RunicScript QLocale.Script.RunicScript
+QLocale.SamaritanScript QLocale.Script.SamaritanScript
+QLocale.SaurashtraScript QLocale.Script.SaurashtraScript
+QLocale.SharadaScript QLocale.Script.SharadaScript
+QLocale.ShavianScript QLocale.Script.ShavianScript
+QLocale.SoraSompengScript QLocale.Script.SoraSompengScript
+QLocale.CuneiformScript QLocale.Script.CuneiformScript
+QLocale.SundaneseScript QLocale.Script.SundaneseScript
+QLocale.SylotiNagriScript QLocale.Script.SylotiNagriScript
+QLocale.TagalogScript QLocale.Script.TagalogScript
+QLocale.TagbanwaScript QLocale.Script.TagbanwaScript
+QLocale.TaiLeScript QLocale.Script.TaiLeScript
+QLocale.TaiVietScript QLocale.Script.TaiVietScript
+QLocale.TakriScript QLocale.Script.TakriScript
+QLocale.UgariticScript QLocale.Script.UgariticScript
+QLocale.BrailleScript QLocale.Script.BrailleScript
+QLocale.HiraganaScript QLocale.Script.HiraganaScript
+QLocale.CaucasianAlbanianScript QLocale.Script.CaucasianAlbanianScript
+QLocale.BassaVahScript QLocale.Script.BassaVahScript
+QLocale.DuployanScript QLocale.Script.DuployanScript
+QLocale.ElbasanScript QLocale.Script.ElbasanScript
+QLocale.GranthaScript QLocale.Script.GranthaScript
+QLocale.PahawhHmongScript QLocale.Script.PahawhHmongScript
+QLocale.KhojkiScript QLocale.Script.KhojkiScript
+QLocale.LinearAScript QLocale.Script.LinearAScript
+QLocale.MahajaniScript QLocale.Script.MahajaniScript
+QLocale.ManichaeanScript QLocale.Script.ManichaeanScript
+QLocale.MendeKikakuiScript QLocale.Script.MendeKikakuiScript
+QLocale.ModiScript QLocale.Script.ModiScript
+QLocale.MroScript QLocale.Script.MroScript
+QLocale.OldNorthArabianScript QLocale.Script.OldNorthArabianScript
+QLocale.NabataeanScript QLocale.Script.NabataeanScript
+QLocale.PalmyreneScript QLocale.Script.PalmyreneScript
+QLocale.PauCinHauScript QLocale.Script.PauCinHauScript
+QLocale.OldPermicScript QLocale.Script.OldPermicScript
+QLocale.PsalterPahlaviScript QLocale.Script.PsalterPahlaviScript
+QLocale.SiddhamScript QLocale.Script.SiddhamScript
+QLocale.KhudawadiScript QLocale.Script.KhudawadiScript
+QLocale.TirhutaScript QLocale.Script.TirhutaScript
+QLocale.VarangKshitiScript QLocale.Script.VarangKshitiScript
+QLocale.AhomScript QLocale.Script.AhomScript
+QLocale.AnatolianHieroglyphsScript QLocale.Script.AnatolianHieroglyphsScript
+QLocale.HatranScript QLocale.Script.HatranScript
+QLocale.MultaniScript QLocale.Script.MultaniScript
+QLocale.OldHungarianScript QLocale.Script.OldHungarianScript
+QLocale.SignWritingScript QLocale.Script.SignWritingScript
+QLocale.AdlamScript QLocale.Script.AdlamScript
+QLocale.BhaiksukiScript QLocale.Script.BhaiksukiScript
+QLocale.MarchenScript QLocale.Script.MarchenScript
+QLocale.NewaScript QLocale.Script.NewaScript
+QLocale.OsageScript QLocale.Script.OsageScript
+QLocale.TangutScript QLocale.Script.TangutScript
+QLocale.HanWithBopomofoScript QLocale.Script.HanWithBopomofoScript
+QLocale.JamoScript QLocale.Script.JamoScript
+QLocale.MetricSystem QLocale.MeasurementSystem.MetricSystem
+QLocale.ImperialSystem QLocale.MeasurementSystem.ImperialSystem
+QLocale.ImperialUSSystem QLocale.MeasurementSystem.ImperialUSSystem
+QLocale.ImperialUKSystem QLocale.MeasurementSystem.ImperialUKSystem
+QLocale.LongFormat QLocale.FormatType.LongFormat
+QLocale.ShortFormat QLocale.FormatType.ShortFormat
+QLocale.NarrowFormat QLocale.FormatType.NarrowFormat
+QLocale.OmitGroupSeparator QLocale.NumberOption.OmitGroupSeparator
+QLocale.RejectGroupSeparator QLocale.NumberOption.RejectGroupSeparator
+QLocale.DefaultNumberOptions QLocale.NumberOption.DefaultNumberOptions
+QLocale.OmitLeadingZeroInExponent QLocale.NumberOption.OmitLeadingZeroInExponent
+QLocale.RejectLeadingZeroInExponent QLocale.NumberOption.RejectLeadingZeroInExponent
+QLocale.IncludeTrailingZeroesAfterDot QLocale.NumberOption.IncludeTrailingZeroesAfterDot
+QLocale.RejectTrailingZeroesAfterDot QLocale.NumberOption.RejectTrailingZeroesAfterDot
+QLocale.AnyCountry QLocale.Country.AnyCountry
+QLocale.Afghanistan QLocale.Country.Afghanistan
+QLocale.Albania QLocale.Country.Albania
+QLocale.Algeria QLocale.Country.Algeria
+QLocale.AmericanSamoa QLocale.Country.AmericanSamoa
+QLocale.Andorra QLocale.Country.Andorra
+QLocale.Angola QLocale.Country.Angola
+QLocale.Anguilla QLocale.Country.Anguilla
+QLocale.Antarctica QLocale.Country.Antarctica
+QLocale.AntiguaAndBarbuda QLocale.Country.AntiguaAndBarbuda
+QLocale.Argentina QLocale.Country.Argentina
+QLocale.Armenia QLocale.Country.Armenia
+QLocale.Aruba QLocale.Country.Aruba
+QLocale.Australia QLocale.Country.Australia
+QLocale.Austria QLocale.Country.Austria
+QLocale.Azerbaijan QLocale.Country.Azerbaijan
+QLocale.Bahamas QLocale.Country.Bahamas
+QLocale.Bahrain QLocale.Country.Bahrain
+QLocale.Bangladesh QLocale.Country.Bangladesh
+QLocale.Barbados QLocale.Country.Barbados
+QLocale.Belarus QLocale.Country.Belarus
+QLocale.Belgium QLocale.Country.Belgium
+QLocale.Belize QLocale.Country.Belize
+QLocale.Benin QLocale.Country.Benin
+QLocale.Bermuda QLocale.Country.Bermuda
+QLocale.Bhutan QLocale.Country.Bhutan
+QLocale.Bolivia QLocale.Country.Bolivia
+QLocale.BosniaAndHerzegowina QLocale.Country.BosniaAndHerzegowina
+QLocale.Botswana QLocale.Country.Botswana
+QLocale.BouvetIsland QLocale.Country.BouvetIsland
+QLocale.Brazil QLocale.Country.Brazil
+QLocale.BritishIndianOceanTerritory QLocale.Country.BritishIndianOceanTerritory
+QLocale.Bulgaria QLocale.Country.Bulgaria
+QLocale.BurkinaFaso QLocale.Country.BurkinaFaso
+QLocale.Burundi QLocale.Country.Burundi
+QLocale.Cambodia QLocale.Country.Cambodia
+QLocale.Cameroon QLocale.Country.Cameroon
+QLocale.Canada QLocale.Country.Canada
+QLocale.CapeVerde QLocale.Country.CapeVerde
+QLocale.CaymanIslands QLocale.Country.CaymanIslands
+QLocale.CentralAfricanRepublic QLocale.Country.CentralAfricanRepublic
+QLocale.Chad QLocale.Country.Chad
+QLocale.Chile QLocale.Country.Chile
+QLocale.China QLocale.Country.China
+QLocale.ChristmasIsland QLocale.Country.ChristmasIsland
+QLocale.CocosIslands QLocale.Country.CocosIslands
+QLocale.Colombia QLocale.Country.Colombia
+QLocale.Comoros QLocale.Country.Comoros
+QLocale.DemocraticRepublicOfCongo QLocale.Country.DemocraticRepublicOfCongo
+QLocale.PeoplesRepublicOfCongo QLocale.Country.PeoplesRepublicOfCongo
+QLocale.CookIslands QLocale.Country.CookIslands
+QLocale.CostaRica QLocale.Country.CostaRica
+QLocale.IvoryCoast QLocale.Country.IvoryCoast
+QLocale.Croatia QLocale.Country.Croatia
+QLocale.Cuba QLocale.Country.Cuba
+QLocale.Cyprus QLocale.Country.Cyprus
+QLocale.CzechRepublic QLocale.Country.CzechRepublic
+QLocale.Denmark QLocale.Country.Denmark
+QLocale.Djibouti QLocale.Country.Djibouti
+QLocale.Dominica QLocale.Country.Dominica
+QLocale.DominicanRepublic QLocale.Country.DominicanRepublic
+QLocale.EastTimor QLocale.Country.EastTimor
+QLocale.Ecuador QLocale.Country.Ecuador
+QLocale.Egypt QLocale.Country.Egypt
+QLocale.ElSalvador QLocale.Country.ElSalvador
+QLocale.EquatorialGuinea QLocale.Country.EquatorialGuinea
+QLocale.Eritrea QLocale.Country.Eritrea
+QLocale.Estonia QLocale.Country.Estonia
+QLocale.Ethiopia QLocale.Country.Ethiopia
+QLocale.FalklandIslands QLocale.Country.FalklandIslands
+QLocale.FaroeIslands QLocale.Country.FaroeIslands
+QLocale.Finland QLocale.Country.Finland
+QLocale.France QLocale.Country.France
+QLocale.FrenchGuiana QLocale.Country.FrenchGuiana
+QLocale.FrenchPolynesia QLocale.Country.FrenchPolynesia
+QLocale.FrenchSouthernTerritories QLocale.Country.FrenchSouthernTerritories
+QLocale.Gabon QLocale.Country.Gabon
+QLocale.Gambia QLocale.Country.Gambia
+QLocale.Georgia QLocale.Country.Georgia
+QLocale.Germany QLocale.Country.Germany
+QLocale.Ghana QLocale.Country.Ghana
+QLocale.Gibraltar QLocale.Country.Gibraltar
+QLocale.Greece QLocale.Country.Greece
+QLocale.Greenland QLocale.Country.Greenland
+QLocale.Grenada QLocale.Country.Grenada
+QLocale.Guadeloupe QLocale.Country.Guadeloupe
+QLocale.Guam QLocale.Country.Guam
+QLocale.Guatemala QLocale.Country.Guatemala
+QLocale.Guinea QLocale.Country.Guinea
+QLocale.GuineaBissau QLocale.Country.GuineaBissau
+QLocale.Guyana QLocale.Country.Guyana
+QLocale.Haiti QLocale.Country.Haiti
+QLocale.HeardAndMcDonaldIslands QLocale.Country.HeardAndMcDonaldIslands
+QLocale.Honduras QLocale.Country.Honduras
+QLocale.HongKong QLocale.Country.HongKong
+QLocale.Hungary QLocale.Country.Hungary
+QLocale.Iceland QLocale.Country.Iceland
+QLocale.India QLocale.Country.India
+QLocale.Indonesia QLocale.Country.Indonesia
+QLocale.Iran QLocale.Country.Iran
+QLocale.Iraq QLocale.Country.Iraq
+QLocale.Ireland QLocale.Country.Ireland
+QLocale.Israel QLocale.Country.Israel
+QLocale.Italy QLocale.Country.Italy
+QLocale.Jamaica QLocale.Country.Jamaica
+QLocale.Japan QLocale.Country.Japan
+QLocale.Jordan QLocale.Country.Jordan
+QLocale.Kazakhstan QLocale.Country.Kazakhstan
+QLocale.Kenya QLocale.Country.Kenya
+QLocale.Kiribati QLocale.Country.Kiribati
+QLocale.DemocraticRepublicOfKorea QLocale.Country.DemocraticRepublicOfKorea
+QLocale.RepublicOfKorea QLocale.Country.RepublicOfKorea
+QLocale.Kuwait QLocale.Country.Kuwait
+QLocale.Kyrgyzstan QLocale.Country.Kyrgyzstan
+QLocale.Latvia QLocale.Country.Latvia
+QLocale.Lebanon QLocale.Country.Lebanon
+QLocale.Lesotho QLocale.Country.Lesotho
+QLocale.Liberia QLocale.Country.Liberia
+QLocale.Liechtenstein QLocale.Country.Liechtenstein
+QLocale.Lithuania QLocale.Country.Lithuania
+QLocale.Luxembourg QLocale.Country.Luxembourg
+QLocale.Macau QLocale.Country.Macau
+QLocale.Macedonia QLocale.Country.Macedonia
+QLocale.Madagascar QLocale.Country.Madagascar
+QLocale.Malawi QLocale.Country.Malawi
+QLocale.Malaysia QLocale.Country.Malaysia
+QLocale.Maldives QLocale.Country.Maldives
+QLocale.Mali QLocale.Country.Mali
+QLocale.Malta QLocale.Country.Malta
+QLocale.MarshallIslands QLocale.Country.MarshallIslands
+QLocale.Martinique QLocale.Country.Martinique
+QLocale.Mauritania QLocale.Country.Mauritania
+QLocale.Mauritius QLocale.Country.Mauritius
+QLocale.Mayotte QLocale.Country.Mayotte
+QLocale.Mexico QLocale.Country.Mexico
+QLocale.Micronesia QLocale.Country.Micronesia
+QLocale.Moldova QLocale.Country.Moldova
+QLocale.Monaco QLocale.Country.Monaco
+QLocale.Mongolia QLocale.Country.Mongolia
+QLocale.Montserrat QLocale.Country.Montserrat
+QLocale.Morocco QLocale.Country.Morocco
+QLocale.Mozambique QLocale.Country.Mozambique
+QLocale.Myanmar QLocale.Country.Myanmar
+QLocale.Namibia QLocale.Country.Namibia
+QLocale.NauruCountry QLocale.Country.NauruCountry
+QLocale.Nepal QLocale.Country.Nepal
+QLocale.Netherlands QLocale.Country.Netherlands
+QLocale.NewCaledonia QLocale.Country.NewCaledonia
+QLocale.NewZealand QLocale.Country.NewZealand
+QLocale.Nicaragua QLocale.Country.Nicaragua
+QLocale.Niger QLocale.Country.Niger
+QLocale.Nigeria QLocale.Country.Nigeria
+QLocale.Niue QLocale.Country.Niue
+QLocale.NorfolkIsland QLocale.Country.NorfolkIsland
+QLocale.NorthernMarianaIslands QLocale.Country.NorthernMarianaIslands
+QLocale.Norway QLocale.Country.Norway
+QLocale.Oman QLocale.Country.Oman
+QLocale.Pakistan QLocale.Country.Pakistan
+QLocale.Palau QLocale.Country.Palau
+QLocale.Panama QLocale.Country.Panama
+QLocale.PapuaNewGuinea QLocale.Country.PapuaNewGuinea
+QLocale.Paraguay QLocale.Country.Paraguay
+QLocale.Peru QLocale.Country.Peru
+QLocale.Philippines QLocale.Country.Philippines
+QLocale.Pitcairn QLocale.Country.Pitcairn
+QLocale.Poland QLocale.Country.Poland
+QLocale.Portugal QLocale.Country.Portugal
+QLocale.PuertoRico QLocale.Country.PuertoRico
+QLocale.Qatar QLocale.Country.Qatar
+QLocale.Reunion QLocale.Country.Reunion
+QLocale.Romania QLocale.Country.Romania
+QLocale.RussianFederation QLocale.Country.RussianFederation
+QLocale.Rwanda QLocale.Country.Rwanda
+QLocale.SaintKittsAndNevis QLocale.Country.SaintKittsAndNevis
+QLocale.Samoa QLocale.Country.Samoa
+QLocale.SanMarino QLocale.Country.SanMarino
+QLocale.SaoTomeAndPrincipe QLocale.Country.SaoTomeAndPrincipe
+QLocale.SaudiArabia QLocale.Country.SaudiArabia
+QLocale.Senegal QLocale.Country.Senegal
+QLocale.Seychelles QLocale.Country.Seychelles
+QLocale.SierraLeone QLocale.Country.SierraLeone
+QLocale.Singapore QLocale.Country.Singapore
+QLocale.Slovakia QLocale.Country.Slovakia
+QLocale.Slovenia QLocale.Country.Slovenia
+QLocale.SolomonIslands QLocale.Country.SolomonIslands
+QLocale.Somalia QLocale.Country.Somalia
+QLocale.SouthAfrica QLocale.Country.SouthAfrica
+QLocale.SouthGeorgiaAndTheSouthSandwichIslands QLocale.Country.SouthGeorgiaAndTheSouthSandwichIslands
+QLocale.Spain QLocale.Country.Spain
+QLocale.SriLanka QLocale.Country.SriLanka
+QLocale.Sudan QLocale.Country.Sudan
+QLocale.Suriname QLocale.Country.Suriname
+QLocale.SvalbardAndJanMayenIslands QLocale.Country.SvalbardAndJanMayenIslands
+QLocale.Swaziland QLocale.Country.Swaziland
+QLocale.Sweden QLocale.Country.Sweden
+QLocale.Switzerland QLocale.Country.Switzerland
+QLocale.SyrianArabRepublic QLocale.Country.SyrianArabRepublic
+QLocale.Taiwan QLocale.Country.Taiwan
+QLocale.Tajikistan QLocale.Country.Tajikistan
+QLocale.Tanzania QLocale.Country.Tanzania
+QLocale.Thailand QLocale.Country.Thailand
+QLocale.Togo QLocale.Country.Togo
+QLocale.Tokelau QLocale.Country.Tokelau
+QLocale.TrinidadAndTobago QLocale.Country.TrinidadAndTobago
+QLocale.Tunisia QLocale.Country.Tunisia
+QLocale.Turkey QLocale.Country.Turkey
+QLocale.Turkmenistan QLocale.Country.Turkmenistan
+QLocale.TurksAndCaicosIslands QLocale.Country.TurksAndCaicosIslands
+QLocale.Tuvalu QLocale.Country.Tuvalu
+QLocale.Uganda QLocale.Country.Uganda
+QLocale.Ukraine QLocale.Country.Ukraine
+QLocale.UnitedArabEmirates QLocale.Country.UnitedArabEmirates
+QLocale.UnitedKingdom QLocale.Country.UnitedKingdom
+QLocale.UnitedStates QLocale.Country.UnitedStates
+QLocale.UnitedStatesMinorOutlyingIslands QLocale.Country.UnitedStatesMinorOutlyingIslands
+QLocale.Uruguay QLocale.Country.Uruguay
+QLocale.Uzbekistan QLocale.Country.Uzbekistan
+QLocale.Vanuatu QLocale.Country.Vanuatu
+QLocale.VaticanCityState QLocale.Country.VaticanCityState
+QLocale.Venezuela QLocale.Country.Venezuela
+QLocale.BritishVirginIslands QLocale.Country.BritishVirginIslands
+QLocale.WallisAndFutunaIslands QLocale.Country.WallisAndFutunaIslands
+QLocale.WesternSahara QLocale.Country.WesternSahara
+QLocale.Yemen QLocale.Country.Yemen
+QLocale.Zambia QLocale.Country.Zambia
+QLocale.Zimbabwe QLocale.Country.Zimbabwe
+QLocale.Montenegro QLocale.Country.Montenegro
+QLocale.Serbia QLocale.Country.Serbia
+QLocale.SaintBarthelemy QLocale.Country.SaintBarthelemy
+QLocale.SaintMartin QLocale.Country.SaintMartin
+QLocale.LatinAmericaAndTheCaribbean QLocale.Country.LatinAmericaAndTheCaribbean
+QLocale.LastCountry QLocale.Country.LastCountry
+QLocale.Brunei QLocale.Country.Brunei
+QLocale.CongoKinshasa QLocale.Country.CongoKinshasa
+QLocale.CongoBrazzaville QLocale.Country.CongoBrazzaville
+QLocale.Fiji QLocale.Country.Fiji
+QLocale.Guernsey QLocale.Country.Guernsey
+QLocale.NorthKorea QLocale.Country.NorthKorea
+QLocale.SouthKorea QLocale.Country.SouthKorea
+QLocale.Laos QLocale.Country.Laos
+QLocale.Libya QLocale.Country.Libya
+QLocale.CuraSao QLocale.Country.CuraSao
+QLocale.PalestinianTerritories QLocale.Country.PalestinianTerritories
+QLocale.Russia QLocale.Country.Russia
+QLocale.SaintLucia QLocale.Country.SaintLucia
+QLocale.SaintVincentAndTheGrenadines QLocale.Country.SaintVincentAndTheGrenadines
+QLocale.SaintHelena QLocale.Country.SaintHelena
+QLocale.SaintPierreAndMiquelon QLocale.Country.SaintPierreAndMiquelon
+QLocale.Syria QLocale.Country.Syria
+QLocale.Tonga QLocale.Country.Tonga
+QLocale.Vietnam QLocale.Country.Vietnam
+QLocale.UnitedStatesVirginIslands QLocale.Country.UnitedStatesVirginIslands
+QLocale.CanaryIslands QLocale.Country.CanaryIslands
+QLocale.ClippertonIsland QLocale.Country.ClippertonIsland
+QLocale.AscensionIsland QLocale.Country.AscensionIsland
+QLocale.AlandIslands QLocale.Country.AlandIslands
+QLocale.DiegoGarcia QLocale.Country.DiegoGarcia
+QLocale.CeutaAndMelilla QLocale.Country.CeutaAndMelilla
+QLocale.IsleOfMan QLocale.Country.IsleOfMan
+QLocale.Jersey QLocale.Country.Jersey
+QLocale.TristanDaCunha QLocale.Country.TristanDaCunha
+QLocale.SouthSudan QLocale.Country.SouthSudan
+QLocale.Bonaire QLocale.Country.Bonaire
+QLocale.SintMaarten QLocale.Country.SintMaarten
+QLocale.Kosovo QLocale.Country.Kosovo
+QLocale.TokelauCountry QLocale.Country.TokelauCountry
+QLocale.TuvaluCountry QLocale.Country.TuvaluCountry
+QLocale.EuropeanUnion QLocale.Country.EuropeanUnion
+QLocale.OutlyingOceania QLocale.Country.OutlyingOceania
+QLocale.LatinAmerica QLocale.Country.LatinAmerica
+QLocale.World QLocale.Country.World
+QLocale.Europe QLocale.Country.Europe
+QLocale.C QLocale.Language.C
+QLocale.Abkhazian QLocale.Language.Abkhazian
+QLocale.Afan QLocale.Language.Afan
+QLocale.Afar QLocale.Language.Afar
+QLocale.Afrikaans QLocale.Language.Afrikaans
+QLocale.Albanian QLocale.Language.Albanian
+QLocale.Amharic QLocale.Language.Amharic
+QLocale.Arabic QLocale.Language.Arabic
+QLocale.Armenian QLocale.Language.Armenian
+QLocale.Assamese QLocale.Language.Assamese
+QLocale.Aymara QLocale.Language.Aymara
+QLocale.Azerbaijani QLocale.Language.Azerbaijani
+QLocale.Bashkir QLocale.Language.Bashkir
+QLocale.Basque QLocale.Language.Basque
+QLocale.Bengali QLocale.Language.Bengali
+QLocale.Bhutani QLocale.Language.Bhutani
+QLocale.Bihari QLocale.Language.Bihari
+QLocale.Bislama QLocale.Language.Bislama
+QLocale.Breton QLocale.Language.Breton
+QLocale.Bulgarian QLocale.Language.Bulgarian
+QLocale.Burmese QLocale.Language.Burmese
+QLocale.Byelorussian QLocale.Language.Byelorussian
+QLocale.Cambodian QLocale.Language.Cambodian
+QLocale.Catalan QLocale.Language.Catalan
+QLocale.Chinese QLocale.Language.Chinese
+QLocale.Corsican QLocale.Language.Corsican
+QLocale.Croatian QLocale.Language.Croatian
+QLocale.Czech QLocale.Language.Czech
+QLocale.Danish QLocale.Language.Danish
+QLocale.Dutch QLocale.Language.Dutch
+QLocale.English QLocale.Language.English
+QLocale.Esperanto QLocale.Language.Esperanto
+QLocale.Estonian QLocale.Language.Estonian
+QLocale.Faroese QLocale.Language.Faroese
+QLocale.Finnish QLocale.Language.Finnish
+QLocale.French QLocale.Language.French
+QLocale.Frisian QLocale.Language.Frisian
+QLocale.Gaelic QLocale.Language.Gaelic
+QLocale.Galician QLocale.Language.Galician
+QLocale.Georgian QLocale.Language.Georgian
+QLocale.German QLocale.Language.German
+QLocale.Greek QLocale.Language.Greek
+QLocale.Greenlandic QLocale.Language.Greenlandic
+QLocale.Guarani QLocale.Language.Guarani
+QLocale.Gujarati QLocale.Language.Gujarati
+QLocale.Hausa QLocale.Language.Hausa
+QLocale.Hebrew QLocale.Language.Hebrew
+QLocale.Hindi QLocale.Language.Hindi
+QLocale.Hungarian QLocale.Language.Hungarian
+QLocale.Icelandic QLocale.Language.Icelandic
+QLocale.Indonesian QLocale.Language.Indonesian
+QLocale.Interlingua QLocale.Language.Interlingua
+QLocale.Interlingue QLocale.Language.Interlingue
+QLocale.Inuktitut QLocale.Language.Inuktitut
+QLocale.Inupiak QLocale.Language.Inupiak
+QLocale.Irish QLocale.Language.Irish
+QLocale.Italian QLocale.Language.Italian
+QLocale.Japanese QLocale.Language.Japanese
+QLocale.Javanese QLocale.Language.Javanese
+QLocale.Kannada QLocale.Language.Kannada
+QLocale.Kashmiri QLocale.Language.Kashmiri
+QLocale.Kazakh QLocale.Language.Kazakh
+QLocale.Kinyarwanda QLocale.Language.Kinyarwanda
+QLocale.Kirghiz QLocale.Language.Kirghiz
+QLocale.Korean QLocale.Language.Korean
+QLocale.Kurdish QLocale.Language.Kurdish
+QLocale.Kurundi QLocale.Language.Kurundi
+QLocale.Latin QLocale.Language.Latin
+QLocale.Latvian QLocale.Language.Latvian
+QLocale.Lingala QLocale.Language.Lingala
+QLocale.Lithuanian QLocale.Language.Lithuanian
+QLocale.Macedonian QLocale.Language.Macedonian
+QLocale.Malagasy QLocale.Language.Malagasy
+QLocale.Malay QLocale.Language.Malay
+QLocale.Malayalam QLocale.Language.Malayalam
+QLocale.Maltese QLocale.Language.Maltese
+QLocale.Maori QLocale.Language.Maori
+QLocale.Marathi QLocale.Language.Marathi
+QLocale.Moldavian QLocale.Language.Moldavian
+QLocale.Mongolian QLocale.Language.Mongolian
+QLocale.NauruLanguage QLocale.Language.NauruLanguage
+QLocale.Nepali QLocale.Language.Nepali
+QLocale.Norwegian QLocale.Language.Norwegian
+QLocale.Occitan QLocale.Language.Occitan
+QLocale.Oriya QLocale.Language.Oriya
+QLocale.Pashto QLocale.Language.Pashto
+QLocale.Persian QLocale.Language.Persian
+QLocale.Polish QLocale.Language.Polish
+QLocale.Portuguese QLocale.Language.Portuguese
+QLocale.Punjabi QLocale.Language.Punjabi
+QLocale.Quechua QLocale.Language.Quechua
+QLocale.RhaetoRomance QLocale.Language.RhaetoRomance
+QLocale.Romanian QLocale.Language.Romanian
+QLocale.Russian QLocale.Language.Russian
+QLocale.Samoan QLocale.Language.Samoan
+QLocale.Sanskrit QLocale.Language.Sanskrit
+QLocale.Serbian QLocale.Language.Serbian
+QLocale.SerboCroatian QLocale.Language.SerboCroatian
+QLocale.Shona QLocale.Language.Shona
+QLocale.Sindhi QLocale.Language.Sindhi
+QLocale.Slovak QLocale.Language.Slovak
+QLocale.Slovenian QLocale.Language.Slovenian
+QLocale.Somali QLocale.Language.Somali
+QLocale.Spanish QLocale.Language.Spanish
+QLocale.Sundanese QLocale.Language.Sundanese
+QLocale.Swahili QLocale.Language.Swahili
+QLocale.Swedish QLocale.Language.Swedish
+QLocale.Tagalog QLocale.Language.Tagalog
+QLocale.Tajik QLocale.Language.Tajik
+QLocale.Tamil QLocale.Language.Tamil
+QLocale.Tatar QLocale.Language.Tatar
+QLocale.Telugu QLocale.Language.Telugu
+QLocale.Thai QLocale.Language.Thai
+QLocale.Tibetan QLocale.Language.Tibetan
+QLocale.Tigrinya QLocale.Language.Tigrinya
+QLocale.Tsonga QLocale.Language.Tsonga
+QLocale.Turkish QLocale.Language.Turkish
+QLocale.Turkmen QLocale.Language.Turkmen
+QLocale.Twi QLocale.Language.Twi
+QLocale.Uigur QLocale.Language.Uigur
+QLocale.Ukrainian QLocale.Language.Ukrainian
+QLocale.Urdu QLocale.Language.Urdu
+QLocale.Uzbek QLocale.Language.Uzbek
+QLocale.Vietnamese QLocale.Language.Vietnamese
+QLocale.Volapuk QLocale.Language.Volapuk
+QLocale.Welsh QLocale.Language.Welsh
+QLocale.Wolof QLocale.Language.Wolof
+QLocale.Xhosa QLocale.Language.Xhosa
+QLocale.Yiddish QLocale.Language.Yiddish
+QLocale.Yoruba QLocale.Language.Yoruba
+QLocale.Zhuang QLocale.Language.Zhuang
+QLocale.Zulu QLocale.Language.Zulu
+QLocale.Bosnian QLocale.Language.Bosnian
+QLocale.Divehi QLocale.Language.Divehi
+QLocale.Manx QLocale.Language.Manx
+QLocale.Cornish QLocale.Language.Cornish
+QLocale.LastLanguage QLocale.Language.LastLanguage
+QLocale.NorwegianBokmal QLocale.Language.NorwegianBokmal
+QLocale.NorwegianNynorsk QLocale.Language.NorwegianNynorsk
+QLocale.Akan QLocale.Language.Akan
+QLocale.Konkani QLocale.Language.Konkani
+QLocale.Ga QLocale.Language.Ga
+QLocale.Igbo QLocale.Language.Igbo
+QLocale.Kamba QLocale.Language.Kamba
+QLocale.Syriac QLocale.Language.Syriac
+QLocale.Blin QLocale.Language.Blin
+QLocale.Geez QLocale.Language.Geez
+QLocale.Koro QLocale.Language.Koro
+QLocale.Sidamo QLocale.Language.Sidamo
+QLocale.Atsam QLocale.Language.Atsam
+QLocale.Tigre QLocale.Language.Tigre
+QLocale.Jju QLocale.Language.Jju
+QLocale.Friulian QLocale.Language.Friulian
+QLocale.Venda QLocale.Language.Venda
+QLocale.Ewe QLocale.Language.Ewe
+QLocale.Walamo QLocale.Language.Walamo
+QLocale.Hawaiian QLocale.Language.Hawaiian
+QLocale.Tyap QLocale.Language.Tyap
+QLocale.Chewa QLocale.Language.Chewa
+QLocale.Filipino QLocale.Language.Filipino
+QLocale.SwissGerman QLocale.Language.SwissGerman
+QLocale.SichuanYi QLocale.Language.SichuanYi
+QLocale.Kpelle QLocale.Language.Kpelle
+QLocale.LowGerman QLocale.Language.LowGerman
+QLocale.SouthNdebele QLocale.Language.SouthNdebele
+QLocale.NorthernSotho QLocale.Language.NorthernSotho
+QLocale.NorthernSami QLocale.Language.NorthernSami
+QLocale.Taroko QLocale.Language.Taroko
+QLocale.Gusii QLocale.Language.Gusii
+QLocale.Taita QLocale.Language.Taita
+QLocale.Fulah QLocale.Language.Fulah
+QLocale.Kikuyu QLocale.Language.Kikuyu
+QLocale.Samburu QLocale.Language.Samburu
+QLocale.Sena QLocale.Language.Sena
+QLocale.NorthNdebele QLocale.Language.NorthNdebele
+QLocale.Rombo QLocale.Language.Rombo
+QLocale.Tachelhit QLocale.Language.Tachelhit
+QLocale.Kabyle QLocale.Language.Kabyle
+QLocale.Nyankole QLocale.Language.Nyankole
+QLocale.Bena QLocale.Language.Bena
+QLocale.Vunjo QLocale.Language.Vunjo
+QLocale.Bambara QLocale.Language.Bambara
+QLocale.Embu QLocale.Language.Embu
+QLocale.Cherokee QLocale.Language.Cherokee
+QLocale.Morisyen QLocale.Language.Morisyen
+QLocale.Makonde QLocale.Language.Makonde
+QLocale.Langi QLocale.Language.Langi
+QLocale.Ganda QLocale.Language.Ganda
+QLocale.Bemba QLocale.Language.Bemba
+QLocale.Kabuverdianu QLocale.Language.Kabuverdianu
+QLocale.Meru QLocale.Language.Meru
+QLocale.Kalenjin QLocale.Language.Kalenjin
+QLocale.Nama QLocale.Language.Nama
+QLocale.Machame QLocale.Language.Machame
+QLocale.Colognian QLocale.Language.Colognian
+QLocale.Masai QLocale.Language.Masai
+QLocale.Soga QLocale.Language.Soga
+QLocale.Luyia QLocale.Language.Luyia
+QLocale.Asu QLocale.Language.Asu
+QLocale.Teso QLocale.Language.Teso
+QLocale.Saho QLocale.Language.Saho
+QLocale.KoyraChiini QLocale.Language.KoyraChiini
+QLocale.Rwa QLocale.Language.Rwa
+QLocale.Luo QLocale.Language.Luo
+QLocale.Chiga QLocale.Language.Chiga
+QLocale.CentralMoroccoTamazight QLocale.Language.CentralMoroccoTamazight
+QLocale.KoyraboroSenni QLocale.Language.KoyraboroSenni
+QLocale.Shambala QLocale.Language.Shambala
+QLocale.AnyLanguage QLocale.Language.AnyLanguage
+QLocale.Rundi QLocale.Language.Rundi
+QLocale.Bodo QLocale.Language.Bodo
+QLocale.Aghem QLocale.Language.Aghem
+QLocale.Basaa QLocale.Language.Basaa
+QLocale.Zarma QLocale.Language.Zarma
+QLocale.Duala QLocale.Language.Duala
+QLocale.JolaFonyi QLocale.Language.JolaFonyi
+QLocale.Ewondo QLocale.Language.Ewondo
+QLocale.Bafia QLocale.Language.Bafia
+QLocale.LubaKatanga QLocale.Language.LubaKatanga
+QLocale.MakhuwaMeetto QLocale.Language.MakhuwaMeetto
+QLocale.Mundang QLocale.Language.Mundang
+QLocale.Kwasio QLocale.Language.Kwasio
+QLocale.Nuer QLocale.Language.Nuer
+QLocale.Sakha QLocale.Language.Sakha
+QLocale.Sangu QLocale.Language.Sangu
+QLocale.CongoSwahili QLocale.Language.CongoSwahili
+QLocale.Tasawaq QLocale.Language.Tasawaq
+QLocale.Vai QLocale.Language.Vai
+QLocale.Walser QLocale.Language.Walser
+QLocale.Yangben QLocale.Language.Yangben
+QLocale.Oromo QLocale.Language.Oromo
+QLocale.Dzongkha QLocale.Language.Dzongkha
+QLocale.Belarusian QLocale.Language.Belarusian
+QLocale.Khmer QLocale.Language.Khmer
+QLocale.Fijian QLocale.Language.Fijian
+QLocale.WesternFrisian QLocale.Language.WesternFrisian
+QLocale.Lao QLocale.Language.Lao
+QLocale.Marshallese QLocale.Language.Marshallese
+QLocale.Romansh QLocale.Language.Romansh
+QLocale.Sango QLocale.Language.Sango
+QLocale.Ossetic QLocale.Language.Ossetic
+QLocale.SouthernSotho QLocale.Language.SouthernSotho
+QLocale.Tswana QLocale.Language.Tswana
+QLocale.Sinhala QLocale.Language.Sinhala
+QLocale.Swati QLocale.Language.Swati
+QLocale.Sardinian QLocale.Language.Sardinian
+QLocale.Tongan QLocale.Language.Tongan
+QLocale.Tahitian QLocale.Language.Tahitian
+QLocale.Nyanja QLocale.Language.Nyanja
+QLocale.Avaric QLocale.Language.Avaric
+QLocale.Chamorro QLocale.Language.Chamorro
+QLocale.Chechen QLocale.Language.Chechen
+QLocale.Church QLocale.Language.Church
+QLocale.Chuvash QLocale.Language.Chuvash
+QLocale.Cree QLocale.Language.Cree
+QLocale.Haitian QLocale.Language.Haitian
+QLocale.Herero QLocale.Language.Herero
+QLocale.HiriMotu QLocale.Language.HiriMotu
+QLocale.Kanuri QLocale.Language.Kanuri
+QLocale.Komi QLocale.Language.Komi
+QLocale.Kongo QLocale.Language.Kongo
+QLocale.Kwanyama QLocale.Language.Kwanyama
+QLocale.Limburgish QLocale.Language.Limburgish
+QLocale.Luxembourgish QLocale.Language.Luxembourgish
+QLocale.Navaho QLocale.Language.Navaho
+QLocale.Ndonga QLocale.Language.Ndonga
+QLocale.Ojibwa QLocale.Language.Ojibwa
+QLocale.Pali QLocale.Language.Pali
+QLocale.Walloon QLocale.Language.Walloon
+QLocale.Avestan QLocale.Language.Avestan
+QLocale.Asturian QLocale.Language.Asturian
+QLocale.Ngomba QLocale.Language.Ngomba
+QLocale.Kako QLocale.Language.Kako
+QLocale.Meta QLocale.Language.Meta
+QLocale.Ngiemboon QLocale.Language.Ngiemboon
+QLocale.Uighur QLocale.Language.Uighur
+QLocale.Aragonese QLocale.Language.Aragonese
+QLocale.Akkadian QLocale.Language.Akkadian
+QLocale.AncientEgyptian QLocale.Language.AncientEgyptian
+QLocale.AncientGreek QLocale.Language.AncientGreek
+QLocale.Aramaic QLocale.Language.Aramaic
+QLocale.Balinese QLocale.Language.Balinese
+QLocale.Bamun QLocale.Language.Bamun
+QLocale.BatakToba QLocale.Language.BatakToba
+QLocale.Buginese QLocale.Language.Buginese
+QLocale.Buhid QLocale.Language.Buhid
+QLocale.Carian QLocale.Language.Carian
+QLocale.Chakma QLocale.Language.Chakma
+QLocale.ClassicalMandaic QLocale.Language.ClassicalMandaic
+QLocale.Coptic QLocale.Language.Coptic
+QLocale.Dogri QLocale.Language.Dogri
+QLocale.EasternCham QLocale.Language.EasternCham
+QLocale.EasternKayah QLocale.Language.EasternKayah
+QLocale.Etruscan QLocale.Language.Etruscan
+QLocale.Gothic QLocale.Language.Gothic
+QLocale.Hanunoo QLocale.Language.Hanunoo
+QLocale.Ingush QLocale.Language.Ingush
+QLocale.LargeFloweryMiao QLocale.Language.LargeFloweryMiao
+QLocale.Lepcha QLocale.Language.Lepcha
+QLocale.Limbu QLocale.Language.Limbu
+QLocale.Lisu QLocale.Language.Lisu
+QLocale.Lu QLocale.Language.Lu
+QLocale.Lycian QLocale.Language.Lycian
+QLocale.Lydian QLocale.Language.Lydian
+QLocale.Mandingo QLocale.Language.Mandingo
+QLocale.Manipuri QLocale.Language.Manipuri
+QLocale.Meroitic QLocale.Language.Meroitic
+QLocale.NorthernThai QLocale.Language.NorthernThai
+QLocale.OldIrish QLocale.Language.OldIrish
+QLocale.OldNorse QLocale.Language.OldNorse
+QLocale.OldPersian QLocale.Language.OldPersian
+QLocale.OldTurkish QLocale.Language.OldTurkish
+QLocale.Pahlavi QLocale.Language.Pahlavi
+QLocale.Parthian QLocale.Language.Parthian
+QLocale.Phoenician QLocale.Language.Phoenician
+QLocale.PrakritLanguage QLocale.Language.PrakritLanguage
+QLocale.Rejang QLocale.Language.Rejang
+QLocale.Sabaean QLocale.Language.Sabaean
+QLocale.Samaritan QLocale.Language.Samaritan
+QLocale.Santali QLocale.Language.Santali
+QLocale.Saurashtra QLocale.Language.Saurashtra
+QLocale.Sora QLocale.Language.Sora
+QLocale.Sylheti QLocale.Language.Sylheti
+QLocale.Tagbanwa QLocale.Language.Tagbanwa
+QLocale.TaiDam QLocale.Language.TaiDam
+QLocale.TaiNua QLocale.Language.TaiNua
+QLocale.Ugaritic QLocale.Language.Ugaritic
+QLocale.Akoose QLocale.Language.Akoose
+QLocale.Lakota QLocale.Language.Lakota
+QLocale.StandardMoroccanTamazight QLocale.Language.StandardMoroccanTamazight
+QLocale.Mapuche QLocale.Language.Mapuche
+QLocale.CentralKurdish QLocale.Language.CentralKurdish
+QLocale.LowerSorbian QLocale.Language.LowerSorbian
+QLocale.UpperSorbian QLocale.Language.UpperSorbian
+QLocale.Kenyang QLocale.Language.Kenyang
+QLocale.Mohawk QLocale.Language.Mohawk
+QLocale.Nko QLocale.Language.Nko
+QLocale.Prussian QLocale.Language.Prussian
+QLocale.Kiche QLocale.Language.Kiche
+QLocale.SouthernSami QLocale.Language.SouthernSami
+QLocale.LuleSami QLocale.Language.LuleSami
+QLocale.InariSami QLocale.Language.InariSami
+QLocale.SkoltSami QLocale.Language.SkoltSami
+QLocale.Warlpiri QLocale.Language.Warlpiri
+QLocale.ManichaeanMiddlePersian QLocale.Language.ManichaeanMiddlePersian
+QLocale.Mende QLocale.Language.Mende
+QLocale.AncientNorthArabian QLocale.Language.AncientNorthArabian
+QLocale.LinearA QLocale.Language.LinearA
+QLocale.HmongNjua QLocale.Language.HmongNjua
+QLocale.Ho QLocale.Language.Ho
+QLocale.Lezghian QLocale.Language.Lezghian
+QLocale.Bassa QLocale.Language.Bassa
+QLocale.Mono QLocale.Language.Mono
+QLocale.TedimChin QLocale.Language.TedimChin
+QLocale.Maithili QLocale.Language.Maithili
+QLocale.Ahom QLocale.Language.Ahom
+QLocale.AmericanSignLanguage QLocale.Language.AmericanSignLanguage
+QLocale.ArdhamagadhiPrakrit QLocale.Language.ArdhamagadhiPrakrit
+QLocale.Bhojpuri QLocale.Language.Bhojpuri
+QLocale.HieroglyphicLuwian QLocale.Language.HieroglyphicLuwian
+QLocale.LiteraryChinese QLocale.Language.LiteraryChinese
+QLocale.Mazanderani QLocale.Language.Mazanderani
+QLocale.Mru QLocale.Language.Mru
+QLocale.Newari QLocale.Language.Newari
+QLocale.NorthernLuri QLocale.Language.NorthernLuri
+QLocale.Palauan QLocale.Language.Palauan
+QLocale.Papiamento QLocale.Language.Papiamento
+QLocale.Saraiki QLocale.Language.Saraiki
+QLocale.TokelauLanguage QLocale.Language.TokelauLanguage
+QLocale.TokPisin QLocale.Language.TokPisin
+QLocale.TuvaluLanguage QLocale.Language.TuvaluLanguage
+QLocale.UncodedLanguages QLocale.Language.UncodedLanguages
+QLocale.Cantonese QLocale.Language.Cantonese
+QLocale.Osage QLocale.Language.Osage
+QLocale.Tangut QLocale.Language.Tangut
+QLocale.Ido QLocale.Language.Ido
+QLocale.Lojban QLocale.Language.Lojban
+QLocale.Sicilian QLocale.Language.Sicilian
+QLocale.SouthernKurdish QLocale.Language.SouthernKurdish
+QLocale.WesternBalochi QLocale.Language.WesternBalochi
+QLocale.Cebuano QLocale.Language.Cebuano
+QLocale.Erzya QLocale.Language.Erzya
+QLocale.Chickasaw QLocale.Language.Chickasaw
+QLocale.Muscogee QLocale.Language.Muscogee
+QLocale.Silesian QLocale.Language.Silesian
+QLockFile.NoError QLockFile.LockError.NoError
+QLockFile.LockFailedError QLockFile.LockError.LockFailedError
+QLockFile.PermissionError QLockFile.LockError.PermissionError
+QLockFile.UnknownError QLockFile.LockError.UnknownError
+QMetaMethod.Method QMetaMethod.MethodType.Method
+QMetaMethod.Signal QMetaMethod.MethodType.Signal
+QMetaMethod.Slot QMetaMethod.MethodType.Slot
+QMetaMethod.Constructor QMetaMethod.MethodType.Constructor
+QMetaMethod.Private QMetaMethod.Access.Private
+QMetaMethod.Protected QMetaMethod.Access.Protected
+QMetaMethod.Public QMetaMethod.Access.Public
+QMetaType.NeedsConstruction QMetaType.TypeFlag.NeedsConstruction
+QMetaType.NeedsDestruction QMetaType.TypeFlag.NeedsDestruction
+QMetaType.MovableType QMetaType.TypeFlag.MovableType
+QMetaType.PointerToQObject QMetaType.TypeFlag.PointerToQObject
+QMetaType.IsEnumeration QMetaType.TypeFlag.IsEnumeration
+QMetaType.UnknownType QMetaType.Type.UnknownType
+QMetaType.Void QMetaType.Type.Void
+QMetaType.Bool QMetaType.Type.Bool
+QMetaType.Int QMetaType.Type.Int
+QMetaType.UInt QMetaType.Type.UInt
+QMetaType.LongLong QMetaType.Type.LongLong
+QMetaType.ULongLong QMetaType.Type.ULongLong
+QMetaType.Double QMetaType.Type.Double
+QMetaType.QChar QMetaType.Type.QChar
+QMetaType.QVariantMap QMetaType.Type.QVariantMap
+QMetaType.QVariantList QMetaType.Type.QVariantList
+QMetaType.QVariantHash QMetaType.Type.QVariantHash
+QMetaType.QString QMetaType.Type.QString
+QMetaType.QStringList QMetaType.Type.QStringList
+QMetaType.QByteArray QMetaType.Type.QByteArray
+QMetaType.QBitArray QMetaType.Type.QBitArray
+QMetaType.QDate QMetaType.Type.QDate
+QMetaType.QTime QMetaType.Type.QTime
+QMetaType.QDateTime QMetaType.Type.QDateTime
+QMetaType.QUrl QMetaType.Type.QUrl
+QMetaType.QLocale QMetaType.Type.QLocale
+QMetaType.QRect QMetaType.Type.QRect
+QMetaType.QRectF QMetaType.Type.QRectF
+QMetaType.QSize QMetaType.Type.QSize
+QMetaType.QSizeF QMetaType.Type.QSizeF
+QMetaType.QLine QMetaType.Type.QLine
+QMetaType.QLineF QMetaType.Type.QLineF
+QMetaType.QPoint QMetaType.Type.QPoint
+QMetaType.QPointF QMetaType.Type.QPointF
+QMetaType.QRegExp QMetaType.Type.QRegExp
+QMetaType.LastCoreType QMetaType.Type.LastCoreType
+QMetaType.FirstGuiType QMetaType.Type.FirstGuiType
+QMetaType.QFont QMetaType.Type.QFont
+QMetaType.QPixmap QMetaType.Type.QPixmap
+QMetaType.QBrush QMetaType.Type.QBrush
+QMetaType.QColor QMetaType.Type.QColor
+QMetaType.QPalette QMetaType.Type.QPalette
+QMetaType.QIcon QMetaType.Type.QIcon
+QMetaType.QImage QMetaType.Type.QImage
+QMetaType.QPolygon QMetaType.Type.QPolygon
+QMetaType.QRegion QMetaType.Type.QRegion
+QMetaType.QBitmap QMetaType.Type.QBitmap
+QMetaType.QCursor QMetaType.Type.QCursor
+QMetaType.QSizePolicy QMetaType.Type.QSizePolicy
+QMetaType.QKeySequence QMetaType.Type.QKeySequence
+QMetaType.QPen QMetaType.Type.QPen
+QMetaType.QTextLength QMetaType.Type.QTextLength
+QMetaType.QTextFormat QMetaType.Type.QTextFormat
+QMetaType.QMatrix QMetaType.Type.QMatrix
+QMetaType.QTransform QMetaType.Type.QTransform
+QMetaType.VoidStar QMetaType.Type.VoidStar
+QMetaType.Long QMetaType.Type.Long
+QMetaType.Short QMetaType.Type.Short
+QMetaType.Char QMetaType.Type.Char
+QMetaType.ULong QMetaType.Type.ULong
+QMetaType.UShort QMetaType.Type.UShort
+QMetaType.UChar QMetaType.Type.UChar
+QMetaType.Float QMetaType.Type.Float
+QMetaType.QObjectStar QMetaType.Type.QObjectStar
+QMetaType.QMatrix4x4 QMetaType.Type.QMatrix4x4
+QMetaType.QVector2D QMetaType.Type.QVector2D
+QMetaType.QVector3D QMetaType.Type.QVector3D
+QMetaType.QVector4D QMetaType.Type.QVector4D
+QMetaType.QQuaternion QMetaType.Type.QQuaternion
+QMetaType.QEasingCurve QMetaType.Type.QEasingCurve
+QMetaType.QVariant QMetaType.Type.QVariant
+QMetaType.QUuid QMetaType.Type.QUuid
+QMetaType.QModelIndex QMetaType.Type.QModelIndex
+QMetaType.QPolygonF QMetaType.Type.QPolygonF
+QMetaType.SChar QMetaType.Type.SChar
+QMetaType.QRegularExpression QMetaType.Type.QRegularExpression
+QMetaType.QJsonValue QMetaType.Type.QJsonValue
+QMetaType.QJsonObject QMetaType.Type.QJsonObject
+QMetaType.QJsonArray QMetaType.Type.QJsonArray
+QMetaType.QJsonDocument QMetaType.Type.QJsonDocument
+QMetaType.QByteArrayList QMetaType.Type.QByteArrayList
+QMetaType.QPersistentModelIndex QMetaType.Type.QPersistentModelIndex
+QMetaType.QCborSimpleType QMetaType.Type.QCborSimpleType
+QMetaType.QCborValue QMetaType.Type.QCborValue
+QMetaType.QCborArray QMetaType.Type.QCborArray
+QMetaType.QCborMap QMetaType.Type.QCborMap
+QMetaType.QColorSpace QMetaType.Type.QColorSpace
+QMetaType.User QMetaType.Type.User
+QMimeDatabase.MatchDefault QMimeDatabase.MatchMode.MatchDefault
+QMimeDatabase.MatchExtension QMimeDatabase.MatchMode.MatchExtension
+QMimeDatabase.MatchContent QMimeDatabase.MatchMode.MatchContent
+QMutex.NonRecursive QMutex.RecursionMode.NonRecursive
+QMutex.Recursive QMutex.RecursionMode.Recursive
+QOperatingSystemVersion.Unknown QOperatingSystemVersion.OSType.Unknown
+QOperatingSystemVersion.Windows QOperatingSystemVersion.OSType.Windows
+QOperatingSystemVersion.MacOS QOperatingSystemVersion.OSType.MacOS
+QOperatingSystemVersion.IOS QOperatingSystemVersion.OSType.IOS
+QOperatingSystemVersion.TvOS QOperatingSystemVersion.OSType.TvOS
+QOperatingSystemVersion.WatchOS QOperatingSystemVersion.OSType.WatchOS
+QOperatingSystemVersion.Android QOperatingSystemVersion.OSType.Android
+QProcess.ManagedInputChannel QProcess.InputChannelMode.ManagedInputChannel
+QProcess.ForwardedInputChannel QProcess.InputChannelMode.ForwardedInputChannel
+QProcess.SeparateChannels QProcess.ProcessChannelMode.SeparateChannels
+QProcess.MergedChannels QProcess.ProcessChannelMode.MergedChannels
+QProcess.ForwardedChannels QProcess.ProcessChannelMode.ForwardedChannels
+QProcess.ForwardedOutputChannel QProcess.ProcessChannelMode.ForwardedOutputChannel
+QProcess.ForwardedErrorChannel QProcess.ProcessChannelMode.ForwardedErrorChannel
+QProcess.StandardOutput QProcess.ProcessChannel.StandardOutput
+QProcess.StandardError QProcess.ProcessChannel.StandardError
+QProcess.NotRunning QProcess.ProcessState.NotRunning
+QProcess.Starting QProcess.ProcessState.Starting
+QProcess.Running QProcess.ProcessState.Running
+QProcess.FailedToStart QProcess.ProcessError.FailedToStart
+QProcess.Crashed QProcess.ProcessError.Crashed
+QProcess.Timedout QProcess.ProcessError.Timedout
+QProcess.ReadError QProcess.ProcessError.ReadError
+QProcess.WriteError QProcess.ProcessError.WriteError
+QProcess.UnknownError QProcess.ProcessError.UnknownError
+QProcess.NormalExit QProcess.ExitStatus.NormalExit
+QProcess.CrashExit QProcess.ExitStatus.CrashExit
+QReadWriteLock.NonRecursive QReadWriteLock.RecursionMode.NonRecursive
+QReadWriteLock.Recursive QReadWriteLock.RecursionMode.Recursive
+QRegExp.CaretAtZero QRegExp.CaretMode.CaretAtZero
+QRegExp.CaretAtOffset QRegExp.CaretMode.CaretAtOffset
+QRegExp.CaretWontMatch QRegExp.CaretMode.CaretWontMatch
+QRegExp.RegExp QRegExp.PatternSyntax.RegExp
+QRegExp.RegExp2 QRegExp.PatternSyntax.RegExp2
+QRegExp.Wildcard QRegExp.PatternSyntax.Wildcard
+QRegExp.FixedString QRegExp.PatternSyntax.FixedString
+QRegExp.WildcardUnix QRegExp.PatternSyntax.WildcardUnix
+QRegExp.W3CXmlSchema11 QRegExp.PatternSyntax.W3CXmlSchema11
+QRegularExpression.NoMatchOption QRegularExpression.MatchOption.NoMatchOption
+QRegularExpression.AnchoredMatchOption QRegularExpression.MatchOption.AnchoredMatchOption
+QRegularExpression.DontCheckSubjectStringMatchOption QRegularExpression.MatchOption.DontCheckSubjectStringMatchOption
+QRegularExpression.NormalMatch QRegularExpression.MatchType.NormalMatch
+QRegularExpression.PartialPreferCompleteMatch QRegularExpression.MatchType.PartialPreferCompleteMatch
+QRegularExpression.PartialPreferFirstMatch QRegularExpression.MatchType.PartialPreferFirstMatch
+QRegularExpression.NoMatch QRegularExpression.MatchType.NoMatch
+QRegularExpression.NoPatternOption QRegularExpression.PatternOption.NoPatternOption
+QRegularExpression.CaseInsensitiveOption QRegularExpression.PatternOption.CaseInsensitiveOption
+QRegularExpression.DotMatchesEverythingOption QRegularExpression.PatternOption.DotMatchesEverythingOption
+QRegularExpression.MultilineOption QRegularExpression.PatternOption.MultilineOption
+QRegularExpression.ExtendedPatternSyntaxOption QRegularExpression.PatternOption.ExtendedPatternSyntaxOption
+QRegularExpression.InvertedGreedinessOption QRegularExpression.PatternOption.InvertedGreedinessOption
+QRegularExpression.DontCaptureOption QRegularExpression.PatternOption.DontCaptureOption
+QRegularExpression.UseUnicodePropertiesOption QRegularExpression.PatternOption.UseUnicodePropertiesOption
+QRegularExpression.OptimizeOnFirstUsageOption QRegularExpression.PatternOption.OptimizeOnFirstUsageOption
+QRegularExpression.DontAutomaticallyOptimizeOption QRegularExpression.PatternOption.DontAutomaticallyOptimizeOption
+QResource.NoCompression QResource.Compression.NoCompression
+QResource.ZlibCompression QResource.Compression.ZlibCompression
+QResource.ZstdCompression QResource.Compression.ZstdCompression
+QSettings.UserScope QSettings.Scope.UserScope
+QSettings.SystemScope QSettings.Scope.SystemScope
+QSettings.NativeFormat QSettings.Format.NativeFormat
+QSettings.IniFormat QSettings.Format.IniFormat
+QSettings.InvalidFormat QSettings.Format.InvalidFormat
+QSettings.NoError QSettings.Status.NoError
+QSettings.AccessError QSettings.Status.AccessError
+QSettings.FormatError QSettings.Status.FormatError
+QSharedMemory.NoError QSharedMemory.SharedMemoryError.NoError
+QSharedMemory.PermissionDenied QSharedMemory.SharedMemoryError.PermissionDenied
+QSharedMemory.InvalidSize QSharedMemory.SharedMemoryError.InvalidSize
+QSharedMemory.KeyError QSharedMemory.SharedMemoryError.KeyError
+QSharedMemory.AlreadyExists QSharedMemory.SharedMemoryError.AlreadyExists
+QSharedMemory.NotFound QSharedMemory.SharedMemoryError.NotFound
+QSharedMemory.LockError QSharedMemory.SharedMemoryError.LockError
+QSharedMemory.OutOfResources QSharedMemory.SharedMemoryError.OutOfResources
+QSharedMemory.UnknownError QSharedMemory.SharedMemoryError.UnknownError
+QSharedMemory.ReadOnly QSharedMemory.AccessMode.ReadOnly
+QSharedMemory.ReadWrite QSharedMemory.AccessMode.ReadWrite
+QSocketNotifier.Read QSocketNotifier.Type.Read
+QSocketNotifier.Write QSocketNotifier.Type.Write
+QSocketNotifier.Exception QSocketNotifier.Type.Exception
+QStandardPaths.LocateFile QStandardPaths.LocateOption.LocateFile
+QStandardPaths.LocateDirectory QStandardPaths.LocateOption.LocateDirectory
+QStandardPaths.DesktopLocation QStandardPaths.StandardLocation.DesktopLocation
+QStandardPaths.DocumentsLocation QStandardPaths.StandardLocation.DocumentsLocation
+QStandardPaths.FontsLocation QStandardPaths.StandardLocation.FontsLocation
+QStandardPaths.ApplicationsLocation QStandardPaths.StandardLocation.ApplicationsLocation
+QStandardPaths.MusicLocation QStandardPaths.StandardLocation.MusicLocation
+QStandardPaths.MoviesLocation QStandardPaths.StandardLocation.MoviesLocation
+QStandardPaths.PicturesLocation QStandardPaths.StandardLocation.PicturesLocation
+QStandardPaths.TempLocation QStandardPaths.StandardLocation.TempLocation
+QStandardPaths.HomeLocation QStandardPaths.StandardLocation.HomeLocation
+QStandardPaths.DataLocation QStandardPaths.StandardLocation.DataLocation
+QStandardPaths.CacheLocation QStandardPaths.StandardLocation.CacheLocation
+QStandardPaths.GenericDataLocation QStandardPaths.StandardLocation.GenericDataLocation
+QStandardPaths.RuntimeLocation QStandardPaths.StandardLocation.RuntimeLocation
+QStandardPaths.ConfigLocation QStandardPaths.StandardLocation.ConfigLocation
+QStandardPaths.DownloadLocation QStandardPaths.StandardLocation.DownloadLocation
+QStandardPaths.GenericCacheLocation QStandardPaths.StandardLocation.GenericCacheLocation
+QStandardPaths.GenericConfigLocation QStandardPaths.StandardLocation.GenericConfigLocation
+QStandardPaths.AppDataLocation QStandardPaths.StandardLocation.AppDataLocation
+QStandardPaths.AppLocalDataLocation QStandardPaths.StandardLocation.AppLocalDataLocation
+QStandardPaths.AppConfigLocation QStandardPaths.StandardLocation.AppConfigLocation
+QState.DontRestoreProperties QState.RestorePolicy.DontRestoreProperties
+QState.RestoreProperties QState.RestorePolicy.RestoreProperties
+QState.ExclusiveStates QState.ChildMode.ExclusiveStates
+QState.ParallelStates QState.ChildMode.ParallelStates
+QStateMachine.NoError QStateMachine.Error.NoError
+QStateMachine.NoInitialStateError QStateMachine.Error.NoInitialStateError
+QStateMachine.NoDefaultStateInHistoryStateError QStateMachine.Error.NoDefaultStateInHistoryStateError
+QStateMachine.NoCommonAncestorForTransitionError QStateMachine.Error.NoCommonAncestorForTransitionError
+QStateMachine.StateMachineChildModeSetToParallelError QStateMachine.Error.StateMachineChildModeSetToParallelError
+QStateMachine.NormalPriority QStateMachine.EventPriority.NormalPriority
+QStateMachine.HighPriority QStateMachine.EventPriority.HighPriority
+QSystemSemaphore.NoError QSystemSemaphore.SystemSemaphoreError.NoError
+QSystemSemaphore.PermissionDenied QSystemSemaphore.SystemSemaphoreError.PermissionDenied
+QSystemSemaphore.KeyError QSystemSemaphore.SystemSemaphoreError.KeyError
+QSystemSemaphore.AlreadyExists QSystemSemaphore.SystemSemaphoreError.AlreadyExists
+QSystemSemaphore.NotFound QSystemSemaphore.SystemSemaphoreError.NotFound
+QSystemSemaphore.OutOfResources QSystemSemaphore.SystemSemaphoreError.OutOfResources
+QSystemSemaphore.UnknownError QSystemSemaphore.SystemSemaphoreError.UnknownError
+QSystemSemaphore.Open QSystemSemaphore.AccessMode.Open
+QSystemSemaphore.Create QSystemSemaphore.AccessMode.Create
+QTextBoundaryFinder.Grapheme QTextBoundaryFinder.BoundaryType.Grapheme
+QTextBoundaryFinder.Word QTextBoundaryFinder.BoundaryType.Word
+QTextBoundaryFinder.Line QTextBoundaryFinder.BoundaryType.Line
+QTextBoundaryFinder.Sentence QTextBoundaryFinder.BoundaryType.Sentence
+QTextBoundaryFinder.NotAtBoundary QTextBoundaryFinder.BoundaryReason.NotAtBoundary
+QTextBoundaryFinder.SoftHyphen QTextBoundaryFinder.BoundaryReason.SoftHyphen
+QTextBoundaryFinder.BreakOpportunity QTextBoundaryFinder.BoundaryReason.BreakOpportunity
+QTextBoundaryFinder.StartOfItem QTextBoundaryFinder.BoundaryReason.StartOfItem
+QTextBoundaryFinder.EndOfItem QTextBoundaryFinder.BoundaryReason.EndOfItem
+QTextBoundaryFinder.MandatoryBreak QTextBoundaryFinder.BoundaryReason.MandatoryBreak
+QTextCodec.DefaultConversion QTextCodec.ConversionFlag.DefaultConversion
+QTextCodec.ConvertInvalidToNull QTextCodec.ConversionFlag.ConvertInvalidToNull
+QTextCodec.IgnoreHeader QTextCodec.ConversionFlag.IgnoreHeader
+QTextStream.Ok QTextStream.Status.Ok
+QTextStream.ReadPastEnd QTextStream.Status.ReadPastEnd
+QTextStream.ReadCorruptData QTextStream.Status.ReadCorruptData
+QTextStream.WriteFailed QTextStream.Status.WriteFailed
+QTextStream.ShowBase QTextStream.NumberFlag.ShowBase
+QTextStream.ForcePoint QTextStream.NumberFlag.ForcePoint
+QTextStream.ForceSign QTextStream.NumberFlag.ForceSign
+QTextStream.UppercaseBase QTextStream.NumberFlag.UppercaseBase
+QTextStream.UppercaseDigits QTextStream.NumberFlag.UppercaseDigits
+QTextStream.AlignLeft QTextStream.FieldAlignment.AlignLeft
+QTextStream.AlignRight QTextStream.FieldAlignment.AlignRight
+QTextStream.AlignCenter QTextStream.FieldAlignment.AlignCenter
+QTextStream.AlignAccountingStyle QTextStream.FieldAlignment.AlignAccountingStyle
+QTextStream.SmartNotation QTextStream.RealNumberNotation.SmartNotation
+QTextStream.FixedNotation QTextStream.RealNumberNotation.FixedNotation
+QTextStream.ScientificNotation QTextStream.RealNumberNotation.ScientificNotation
+QThread.IdlePriority QThread.Priority.IdlePriority
+QThread.LowestPriority QThread.Priority.LowestPriority
+QThread.LowPriority QThread.Priority.LowPriority
+QThread.NormalPriority QThread.Priority.NormalPriority
+QThread.HighPriority QThread.Priority.HighPriority
+QThread.HighestPriority QThread.Priority.HighestPriority
+QThread.TimeCriticalPriority QThread.Priority.TimeCriticalPriority
+QThread.InheritPriority QThread.Priority.InheritPriority
+QTimeLine.NotRunning QTimeLine.State.NotRunning
+QTimeLine.Paused QTimeLine.State.Paused
+QTimeLine.Running QTimeLine.State.Running
+QTimeLine.Forward QTimeLine.Direction.Forward
+QTimeLine.Backward QTimeLine.Direction.Backward
+QTimeLine.EaseInCurve QTimeLine.CurveShape.EaseInCurve
+QTimeLine.EaseOutCurve QTimeLine.CurveShape.EaseOutCurve
+QTimeLine.EaseInOutCurve QTimeLine.CurveShape.EaseInOutCurve
+QTimeLine.LinearCurve QTimeLine.CurveShape.LinearCurve
+QTimeLine.SineCurve QTimeLine.CurveShape.SineCurve
+QTimeLine.CosineCurve QTimeLine.CurveShape.CosineCurve
+QTimeZone.DefaultName QTimeZone.NameType.DefaultName
+QTimeZone.LongName QTimeZone.NameType.LongName
+QTimeZone.ShortName QTimeZone.NameType.ShortName
+QTimeZone.OffsetName QTimeZone.NameType.OffsetName
+QTimeZone.StandardTime QTimeZone.TimeType.StandardTime
+QTimeZone.DaylightTime QTimeZone.TimeType.DaylightTime
+QTimeZone.GenericTime QTimeZone.TimeType.GenericTime
+QUrl.DefaultResolution QUrl.UserInputResolutionOption.DefaultResolution
+QUrl.AssumeLocalFile QUrl.UserInputResolutionOption.AssumeLocalFile
+QUrl.PrettyDecoded QUrl.ComponentFormattingOption.PrettyDecoded
+QUrl.EncodeSpaces QUrl.ComponentFormattingOption.EncodeSpaces
+QUrl.EncodeUnicode QUrl.ComponentFormattingOption.EncodeUnicode
+QUrl.EncodeDelimiters QUrl.ComponentFormattingOption.EncodeDelimiters
+QUrl.EncodeReserved QUrl.ComponentFormattingOption.EncodeReserved
+QUrl.DecodeReserved QUrl.ComponentFormattingOption.DecodeReserved
+QUrl.FullyEncoded QUrl.ComponentFormattingOption.FullyEncoded
+QUrl.FullyDecoded QUrl.ComponentFormattingOption.FullyDecoded
+QUrl.None_ QUrl.UrlFormattingOption.None_
+QUrl.RemoveScheme QUrl.UrlFormattingOption.RemoveScheme
+QUrl.RemovePassword QUrl.UrlFormattingOption.RemovePassword
+QUrl.RemoveUserInfo QUrl.UrlFormattingOption.RemoveUserInfo
+QUrl.RemovePort QUrl.UrlFormattingOption.RemovePort
+QUrl.RemoveAuthority QUrl.UrlFormattingOption.RemoveAuthority
+QUrl.RemovePath QUrl.UrlFormattingOption.RemovePath
+QUrl.RemoveQuery QUrl.UrlFormattingOption.RemoveQuery
+QUrl.RemoveFragment QUrl.UrlFormattingOption.RemoveFragment
+QUrl.PreferLocalFile QUrl.UrlFormattingOption.PreferLocalFile
+QUrl.StripTrailingSlash QUrl.UrlFormattingOption.StripTrailingSlash
+QUrl.RemoveFilename QUrl.UrlFormattingOption.RemoveFilename
+QUrl.NormalizePathSegments QUrl.UrlFormattingOption.NormalizePathSegments
+QUrl.TolerantMode QUrl.ParsingMode.TolerantMode
+QUrl.StrictMode QUrl.ParsingMode.StrictMode
+QUrl.DecodedMode QUrl.ParsingMode.DecodedMode
+QUuid.WithBraces QUuid.StringFormat.WithBraces
+QUuid.WithoutBraces QUuid.StringFormat.WithoutBraces
+QUuid.Id128 QUuid.StringFormat.Id128
+QUuid.VerUnknown QUuid.Version.VerUnknown
+QUuid.Time QUuid.Version.Time
+QUuid.EmbeddedPOSIX QUuid.Version.EmbeddedPOSIX
+QUuid.Md5 QUuid.Version.Md5
+QUuid.Name QUuid.Version.Name
+QUuid.Random QUuid.Version.Random
+QUuid.Sha1 QUuid.Version.Sha1
+QUuid.VarUnknown QUuid.Variant.VarUnknown
+QUuid.NCS QUuid.Variant.NCS
+QUuid.DCE QUuid.Variant.DCE
+QUuid.Microsoft QUuid.Variant.Microsoft
+QUuid.Reserved QUuid.Variant.Reserved
+QVariant.Invalid QVariant.Type.Invalid
+QVariant.Bool QVariant.Type.Bool
+QVariant.Int QVariant.Type.Int
+QVariant.UInt QVariant.Type.UInt
+QVariant.LongLong QVariant.Type.LongLong
+QVariant.ULongLong QVariant.Type.ULongLong
+QVariant.Double QVariant.Type.Double
+QVariant.Char QVariant.Type.Char
+QVariant.Map QVariant.Type.Map
+QVariant.List QVariant.Type.List
+QVariant.String QVariant.Type.String
+QVariant.StringList QVariant.Type.StringList
+QVariant.ByteArray QVariant.Type.ByteArray
+QVariant.BitArray QVariant.Type.BitArray
+QVariant.Date QVariant.Type.Date
+QVariant.Time QVariant.Type.Time
+QVariant.DateTime QVariant.Type.DateTime
+QVariant.Url QVariant.Type.Url
+QVariant.Locale QVariant.Type.Locale
+QVariant.Rect QVariant.Type.Rect
+QVariant.RectF QVariant.Type.RectF
+QVariant.Size QVariant.Type.Size
+QVariant.SizeF QVariant.Type.SizeF
+QVariant.Line QVariant.Type.Line
+QVariant.LineF QVariant.Type.LineF
+QVariant.Point QVariant.Type.Point
+QVariant.PointF QVariant.Type.PointF
+QVariant.RegExp QVariant.Type.RegExp
+QVariant.Font QVariant.Type.Font
+QVariant.Pixmap QVariant.Type.Pixmap
+QVariant.Brush QVariant.Type.Brush
+QVariant.Color QVariant.Type.Color
+QVariant.Palette QVariant.Type.Palette
+QVariant.Icon QVariant.Type.Icon
+QVariant.Image QVariant.Type.Image
+QVariant.Polygon QVariant.Type.Polygon
+QVariant.Region QVariant.Type.Region
+QVariant.Bitmap QVariant.Type.Bitmap
+QVariant.Cursor QVariant.Type.Cursor
+QVariant.SizePolicy QVariant.Type.SizePolicy
+QVariant.KeySequence QVariant.Type.KeySequence
+QVariant.Pen QVariant.Type.Pen
+QVariant.TextLength QVariant.Type.TextLength
+QVariant.TextFormat QVariant.Type.TextFormat
+QVariant.Matrix QVariant.Type.Matrix
+QVariant.Transform QVariant.Type.Transform
+QVariant.Hash QVariant.Type.Hash
+QVariant.Matrix4x4 QVariant.Type.Matrix4x4
+QVariant.Vector2D QVariant.Type.Vector2D
+QVariant.Vector3D QVariant.Type.Vector3D
+QVariant.Vector4D QVariant.Type.Vector4D
+QVariant.Quaternion QVariant.Type.Quaternion
+QVariant.EasingCurve QVariant.Type.EasingCurve
+QVariant.Uuid QVariant.Type.Uuid
+QVariant.ModelIndex QVariant.Type.ModelIndex
+QVariant.PolygonF QVariant.Type.PolygonF
+QVariant.RegularExpression QVariant.Type.RegularExpression
+QVariant.PersistentModelIndex QVariant.Type.PersistentModelIndex
+QVariant.UserType QVariant.Type.UserType
+QXmlStreamReader.NoError QXmlStreamReader.Error.NoError
+QXmlStreamReader.UnexpectedElementError QXmlStreamReader.Error.UnexpectedElementError
+QXmlStreamReader.CustomError QXmlStreamReader.Error.CustomError
+QXmlStreamReader.NotWellFormedError QXmlStreamReader.Error.NotWellFormedError
+QXmlStreamReader.PrematureEndOfDocumentError QXmlStreamReader.Error.PrematureEndOfDocumentError
+QXmlStreamReader.ErrorOnUnexpectedElement QXmlStreamReader.ReadElementTextBehaviour.ErrorOnUnexpectedElement
+QXmlStreamReader.IncludeChildElements QXmlStreamReader.ReadElementTextBehaviour.IncludeChildElements
+QXmlStreamReader.SkipChildElements QXmlStreamReader.ReadElementTextBehaviour.SkipChildElements
+QXmlStreamReader.NoToken QXmlStreamReader.TokenType.NoToken
+QXmlStreamReader.Invalid QXmlStreamReader.TokenType.Invalid
+QXmlStreamReader.StartDocument QXmlStreamReader.TokenType.StartDocument
+QXmlStreamReader.EndDocument QXmlStreamReader.TokenType.EndDocument
+QXmlStreamReader.StartElement QXmlStreamReader.TokenType.StartElement
+QXmlStreamReader.EndElement QXmlStreamReader.TokenType.EndElement
+QXmlStreamReader.Characters QXmlStreamReader.TokenType.Characters
+QXmlStreamReader.Comment QXmlStreamReader.TokenType.Comment
+QXmlStreamReader.DTD QXmlStreamReader.TokenType.DTD
+QXmlStreamReader.EntityReference QXmlStreamReader.TokenType.EntityReference
+QXmlStreamReader.ProcessingInstruction QXmlStreamReader.TokenType.ProcessingInstruction
+QSysInfo.BigEndian QSysInfo.Endian.BigEndian
+QSysInfo.LittleEndian QSysInfo.Endian.LittleEndian
+QSysInfo.ByteOrder QSysInfo.Endian.ByteOrder
+QSysInfo.WordSize QSysInfo.Sizes.WordSize
+QByteArray.decodingStatus QByteArray.Base64DecodingStatus.decodingStatus
+QDBus.NoBlock QDBus.CallMode.NoBlock
+QDBus.Block QDBus.CallMode.Block
+QDBus.BlockWithGui QDBus.CallMode.BlockWithGui
+QDBus.AutoDetect QDBus.CallMode.AutoDetect
+QDBusConnection.UnixFileDescriptorPassing QDBusConnection.ConnectionCapability.UnixFileDescriptorPassing
+QDBusConnection.UnregisterNode QDBusConnection.UnregisterMode.UnregisterNode
+QDBusConnection.UnregisterTree QDBusConnection.UnregisterMode.UnregisterTree
+QDBusConnection.ExportAdaptors QDBusConnection.RegisterOption.ExportAdaptors
+QDBusConnection.ExportScriptableSlots QDBusConnection.RegisterOption.ExportScriptableSlots
+QDBusConnection.ExportScriptableSignals QDBusConnection.RegisterOption.ExportScriptableSignals
+QDBusConnection.ExportScriptableProperties QDBusConnection.RegisterOption.ExportScriptableProperties
+QDBusConnection.ExportScriptableInvokables QDBusConnection.RegisterOption.ExportScriptableInvokables
+QDBusConnection.ExportScriptableContents QDBusConnection.RegisterOption.ExportScriptableContents
+QDBusConnection.ExportNonScriptableSlots QDBusConnection.RegisterOption.ExportNonScriptableSlots
+QDBusConnection.ExportNonScriptableSignals QDBusConnection.RegisterOption.ExportNonScriptableSignals
+QDBusConnection.ExportNonScriptableProperties QDBusConnection.RegisterOption.ExportNonScriptableProperties
+QDBusConnection.ExportNonScriptableInvokables QDBusConnection.RegisterOption.ExportNonScriptableInvokables
+QDBusConnection.ExportNonScriptableContents QDBusConnection.RegisterOption.ExportNonScriptableContents
+QDBusConnection.ExportAllSlots QDBusConnection.RegisterOption.ExportAllSlots
+QDBusConnection.ExportAllSignals QDBusConnection.RegisterOption.ExportAllSignals
+QDBusConnection.ExportAllProperties QDBusConnection.RegisterOption.ExportAllProperties
+QDBusConnection.ExportAllInvokables QDBusConnection.RegisterOption.ExportAllInvokables
+QDBusConnection.ExportAllContents QDBusConnection.RegisterOption.ExportAllContents
+QDBusConnection.ExportAllSignal QDBusConnection.RegisterOption.ExportAllSignal
+QDBusConnection.ExportChildObjects QDBusConnection.RegisterOption.ExportChildObjects
+QDBusConnection.SessionBus QDBusConnection.BusType.SessionBus
+QDBusConnection.SystemBus QDBusConnection.BusType.SystemBus
+QDBusConnection.ActivationBus QDBusConnection.BusType.ActivationBus
+QDBusConnectionInterface.ServiceNotRegistered QDBusConnectionInterface.RegisterServiceReply.ServiceNotRegistered
+QDBusConnectionInterface.ServiceRegistered QDBusConnectionInterface.RegisterServiceReply.ServiceRegistered
+QDBusConnectionInterface.ServiceQueued QDBusConnectionInterface.RegisterServiceReply.ServiceQueued
+QDBusConnectionInterface.DontAllowReplacement QDBusConnectionInterface.ServiceReplacementOptions.DontAllowReplacement
+QDBusConnectionInterface.AllowReplacement QDBusConnectionInterface.ServiceReplacementOptions.AllowReplacement
+QDBusConnectionInterface.DontQueueService QDBusConnectionInterface.ServiceQueueOptions.DontQueueService
+QDBusConnectionInterface.QueueService QDBusConnectionInterface.ServiceQueueOptions.QueueService
+QDBusConnectionInterface.ReplaceExistingService QDBusConnectionInterface.ServiceQueueOptions.ReplaceExistingService
+QDBusError.NoError QDBusError.ErrorType.NoError
+QDBusError.Other QDBusError.ErrorType.Other
+QDBusError.Failed QDBusError.ErrorType.Failed
+QDBusError.NoMemory QDBusError.ErrorType.NoMemory
+QDBusError.ServiceUnknown QDBusError.ErrorType.ServiceUnknown
+QDBusError.NoReply QDBusError.ErrorType.NoReply
+QDBusError.BadAddress QDBusError.ErrorType.BadAddress
+QDBusError.NotSupported QDBusError.ErrorType.NotSupported
+QDBusError.LimitsExceeded QDBusError.ErrorType.LimitsExceeded
+QDBusError.AccessDenied QDBusError.ErrorType.AccessDenied
+QDBusError.NoServer QDBusError.ErrorType.NoServer
+QDBusError.Timeout QDBusError.ErrorType.Timeout
+QDBusError.NoNetwork QDBusError.ErrorType.NoNetwork
+QDBusError.AddressInUse QDBusError.ErrorType.AddressInUse
+QDBusError.Disconnected QDBusError.ErrorType.Disconnected
+QDBusError.InvalidArgs QDBusError.ErrorType.InvalidArgs
+QDBusError.UnknownMethod QDBusError.ErrorType.UnknownMethod
+QDBusError.TimedOut QDBusError.ErrorType.TimedOut
+QDBusError.InvalidSignature QDBusError.ErrorType.InvalidSignature
+QDBusError.UnknownInterface QDBusError.ErrorType.UnknownInterface
+QDBusError.InternalError QDBusError.ErrorType.InternalError
+QDBusError.UnknownObject QDBusError.ErrorType.UnknownObject
+QDBusError.InvalidService QDBusError.ErrorType.InvalidService
+QDBusError.InvalidObjectPath QDBusError.ErrorType.InvalidObjectPath
+QDBusError.InvalidInterface QDBusError.ErrorType.InvalidInterface
+QDBusError.InvalidMember QDBusError.ErrorType.InvalidMember
+QDBusError.UnknownProperty QDBusError.ErrorType.UnknownProperty
+QDBusError.PropertyReadOnly QDBusError.ErrorType.PropertyReadOnly
+QDBusMessage.InvalidMessage QDBusMessage.MessageType.InvalidMessage
+QDBusMessage.MethodCallMessage QDBusMessage.MessageType.MethodCallMessage
+QDBusMessage.ReplyMessage QDBusMessage.MessageType.ReplyMessage
+QDBusMessage.ErrorMessage QDBusMessage.MessageType.ErrorMessage
+QDBusMessage.SignalMessage QDBusMessage.MessageType.SignalMessage
+QDBusServiceWatcher.WatchForRegistration QDBusServiceWatcher.WatchModeFlag.WatchForRegistration
+QDBusServiceWatcher.WatchForUnregistration QDBusServiceWatcher.WatchModeFlag.WatchForUnregistration
+QDBusServiceWatcher.WatchForOwnerChange QDBusServiceWatcher.WatchModeFlag.WatchForOwnerChange
+QDesignerFormWindowInterface.EditFeature QDesignerFormWindowInterface.FeatureFlag.EditFeature
+QDesignerFormWindowInterface.GridFeature QDesignerFormWindowInterface.FeatureFlag.GridFeature
+QDesignerFormWindowInterface.TabOrderFeature QDesignerFormWindowInterface.FeatureFlag.TabOrderFeature
+QDesignerFormWindowInterface.DefaultFeature QDesignerFormWindowInterface.FeatureFlag.DefaultFeature
+QDesignerFormWindowCursorInterface.MoveAnchor QDesignerFormWindowCursorInterface.MoveMode.MoveAnchor
+QDesignerFormWindowCursorInterface.KeepAnchor QDesignerFormWindowCursorInterface.MoveMode.KeepAnchor
+QDesignerFormWindowCursorInterface.NoMove QDesignerFormWindowCursorInterface.MoveOperation.NoMove
+QDesignerFormWindowCursorInterface.Start QDesignerFormWindowCursorInterface.MoveOperation.Start
+QDesignerFormWindowCursorInterface.End QDesignerFormWindowCursorInterface.MoveOperation.End
+QDesignerFormWindowCursorInterface.Next QDesignerFormWindowCursorInterface.MoveOperation.Next
+QDesignerFormWindowCursorInterface.Prev QDesignerFormWindowCursorInterface.MoveOperation.Prev
+QDesignerFormWindowCursorInterface.Left QDesignerFormWindowCursorInterface.MoveOperation.Left
+QDesignerFormWindowCursorInterface.Right QDesignerFormWindowCursorInterface.MoveOperation.Right
+QDesignerFormWindowCursorInterface.Up QDesignerFormWindowCursorInterface.MoveOperation.Up
+QDesignerFormWindowCursorInterface.Down QDesignerFormWindowCursorInterface.MoveOperation.Down
+QDesignerFormWindowManagerInterface.StyledPreviewActionGroup QDesignerFormWindowManagerInterface.ActionGroup.StyledPreviewActionGroup
+QDesignerFormWindowManagerInterface.CutAction QDesignerFormWindowManagerInterface.Action.CutAction
+QDesignerFormWindowManagerInterface.CopyAction QDesignerFormWindowManagerInterface.Action.CopyAction
+QDesignerFormWindowManagerInterface.PasteAction QDesignerFormWindowManagerInterface.Action.PasteAction
+QDesignerFormWindowManagerInterface.DeleteAction QDesignerFormWindowManagerInterface.Action.DeleteAction
+QDesignerFormWindowManagerInterface.SelectAllAction QDesignerFormWindowManagerInterface.Action.SelectAllAction
+QDesignerFormWindowManagerInterface.LowerAction QDesignerFormWindowManagerInterface.Action.LowerAction
+QDesignerFormWindowManagerInterface.RaiseAction QDesignerFormWindowManagerInterface.Action.RaiseAction
+QDesignerFormWindowManagerInterface.UndoAction QDesignerFormWindowManagerInterface.Action.UndoAction
+QDesignerFormWindowManagerInterface.RedoAction QDesignerFormWindowManagerInterface.Action.RedoAction
+QDesignerFormWindowManagerInterface.HorizontalLayoutAction QDesignerFormWindowManagerInterface.Action.HorizontalLayoutAction
+QDesignerFormWindowManagerInterface.VerticalLayoutAction QDesignerFormWindowManagerInterface.Action.VerticalLayoutAction
+QDesignerFormWindowManagerInterface.SplitHorizontalAction QDesignerFormWindowManagerInterface.Action.SplitHorizontalAction
+QDesignerFormWindowManagerInterface.SplitVerticalAction QDesignerFormWindowManagerInterface.Action.SplitVerticalAction
+QDesignerFormWindowManagerInterface.GridLayoutAction QDesignerFormWindowManagerInterface.Action.GridLayoutAction
+QDesignerFormWindowManagerInterface.FormLayoutAction QDesignerFormWindowManagerInterface.Action.FormLayoutAction
+QDesignerFormWindowManagerInterface.BreakLayoutAction QDesignerFormWindowManagerInterface.Action.BreakLayoutAction
+QDesignerFormWindowManagerInterface.AdjustSizeAction QDesignerFormWindowManagerInterface.Action.AdjustSizeAction
+QDesignerFormWindowManagerInterface.SimplifyLayoutAction QDesignerFormWindowManagerInterface.Action.SimplifyLayoutAction
+QDesignerFormWindowManagerInterface.DefaultPreviewAction QDesignerFormWindowManagerInterface.Action.DefaultPreviewAction
+QDesignerFormWindowManagerInterface.FormWindowSettingsDialogAction QDesignerFormWindowManagerInterface.Action.FormWindowSettingsDialogAction
+QPaintDevice.PdmWidth QPaintDevice.PaintDeviceMetric.PdmWidth
+QPaintDevice.PdmHeight QPaintDevice.PaintDeviceMetric.PdmHeight
+QPaintDevice.PdmWidthMM QPaintDevice.PaintDeviceMetric.PdmWidthMM
+QPaintDevice.PdmHeightMM QPaintDevice.PaintDeviceMetric.PdmHeightMM
+QPaintDevice.PdmNumColors QPaintDevice.PaintDeviceMetric.PdmNumColors
+QPaintDevice.PdmDepth QPaintDevice.PaintDeviceMetric.PdmDepth
+QPaintDevice.PdmDpiX QPaintDevice.PaintDeviceMetric.PdmDpiX
+QPaintDevice.PdmDpiY QPaintDevice.PaintDeviceMetric.PdmDpiY
+QPaintDevice.PdmPhysicalDpiX QPaintDevice.PaintDeviceMetric.PdmPhysicalDpiX
+QPaintDevice.PdmPhysicalDpiY QPaintDevice.PaintDeviceMetric.PdmPhysicalDpiY
+QPaintDevice.PdmDevicePixelRatio QPaintDevice.PaintDeviceMetric.PdmDevicePixelRatio
+QPaintDevice.PdmDevicePixelRatioScaled QPaintDevice.PaintDeviceMetric.PdmDevicePixelRatioScaled
+QColor.HexRgb QColor.NameFormat.HexRgb
+QColor.HexArgb QColor.NameFormat.HexArgb
+QColor.Invalid QColor.Spec.Invalid
+QColor.Rgb QColor.Spec.Rgb
+QColor.Hsv QColor.Spec.Hsv
+QColor.Cmyk QColor.Spec.Cmyk
+QColor.Hsl QColor.Spec.Hsl
+QColor.ExtendedRgb QColor.Spec.ExtendedRgb
+QGradient.WarmFlame QGradient.Preset.WarmFlame
+QGradient.NightFade QGradient.Preset.NightFade
+QGradient.SpringWarmth QGradient.Preset.SpringWarmth
+QGradient.JuicyPeach QGradient.Preset.JuicyPeach
+QGradient.YoungPassion QGradient.Preset.YoungPassion
+QGradient.LadyLips QGradient.Preset.LadyLips
+QGradient.SunnyMorning QGradient.Preset.SunnyMorning
+QGradient.RainyAshville QGradient.Preset.RainyAshville
+QGradient.FrozenDreams QGradient.Preset.FrozenDreams
+QGradient.WinterNeva QGradient.Preset.WinterNeva
+QGradient.DustyGrass QGradient.Preset.DustyGrass
+QGradient.TemptingAzure QGradient.Preset.TemptingAzure
+QGradient.HeavyRain QGradient.Preset.HeavyRain
+QGradient.AmyCrisp QGradient.Preset.AmyCrisp
+QGradient.MeanFruit QGradient.Preset.MeanFruit
+QGradient.DeepBlue QGradient.Preset.DeepBlue
+QGradient.RipeMalinka QGradient.Preset.RipeMalinka
+QGradient.CloudyKnoxville QGradient.Preset.CloudyKnoxville
+QGradient.MalibuBeach QGradient.Preset.MalibuBeach
+QGradient.NewLife QGradient.Preset.NewLife
+QGradient.TrueSunset QGradient.Preset.TrueSunset
+QGradient.MorpheusDen QGradient.Preset.MorpheusDen
+QGradient.RareWind QGradient.Preset.RareWind
+QGradient.NearMoon QGradient.Preset.NearMoon
+QGradient.WildApple QGradient.Preset.WildApple
+QGradient.SaintPetersburg QGradient.Preset.SaintPetersburg
+QGradient.PlumPlate QGradient.Preset.PlumPlate
+QGradient.EverlastingSky QGradient.Preset.EverlastingSky
+QGradient.HappyFisher QGradient.Preset.HappyFisher
+QGradient.Blessing QGradient.Preset.Blessing
+QGradient.SharpeyeEagle QGradient.Preset.SharpeyeEagle
+QGradient.LadogaBottom QGradient.Preset.LadogaBottom
+QGradient.LemonGate QGradient.Preset.LemonGate
+QGradient.ItmeoBranding QGradient.Preset.ItmeoBranding
+QGradient.ZeusMiracle QGradient.Preset.ZeusMiracle
+QGradient.OldHat QGradient.Preset.OldHat
+QGradient.StarWine QGradient.Preset.StarWine
+QGradient.HappyAcid QGradient.Preset.HappyAcid
+QGradient.AwesomePine QGradient.Preset.AwesomePine
+QGradient.NewYork QGradient.Preset.NewYork
+QGradient.ShyRainbow QGradient.Preset.ShyRainbow
+QGradient.MixedHopes QGradient.Preset.MixedHopes
+QGradient.FlyHigh QGradient.Preset.FlyHigh
+QGradient.StrongBliss QGradient.Preset.StrongBliss
+QGradient.FreshMilk QGradient.Preset.FreshMilk
+QGradient.SnowAgain QGradient.Preset.SnowAgain
+QGradient.FebruaryInk QGradient.Preset.FebruaryInk
+QGradient.KindSteel QGradient.Preset.KindSteel
+QGradient.SoftGrass QGradient.Preset.SoftGrass
+QGradient.GrownEarly QGradient.Preset.GrownEarly
+QGradient.SharpBlues QGradient.Preset.SharpBlues
+QGradient.ShadyWater QGradient.Preset.ShadyWater
+QGradient.DirtyBeauty QGradient.Preset.DirtyBeauty
+QGradient.GreatWhale QGradient.Preset.GreatWhale
+QGradient.TeenNotebook QGradient.Preset.TeenNotebook
+QGradient.PoliteRumors QGradient.Preset.PoliteRumors
+QGradient.SweetPeriod QGradient.Preset.SweetPeriod
+QGradient.WideMatrix QGradient.Preset.WideMatrix
+QGradient.SoftCherish QGradient.Preset.SoftCherish
+QGradient.RedSalvation QGradient.Preset.RedSalvation
+QGradient.BurningSpring QGradient.Preset.BurningSpring
+QGradient.NightParty QGradient.Preset.NightParty
+QGradient.SkyGlider QGradient.Preset.SkyGlider
+QGradient.HeavenPeach QGradient.Preset.HeavenPeach
+QGradient.PurpleDivision QGradient.Preset.PurpleDivision
+QGradient.AquaSplash QGradient.Preset.AquaSplash
+QGradient.SpikyNaga QGradient.Preset.SpikyNaga
+QGradient.LoveKiss QGradient.Preset.LoveKiss
+QGradient.CleanMirror QGradient.Preset.CleanMirror
+QGradient.PremiumDark QGradient.Preset.PremiumDark
+QGradient.ColdEvening QGradient.Preset.ColdEvening
+QGradient.CochitiLake QGradient.Preset.CochitiLake
+QGradient.SummerGames QGradient.Preset.SummerGames
+QGradient.PassionateBed QGradient.Preset.PassionateBed
+QGradient.MountainRock QGradient.Preset.MountainRock
+QGradient.DesertHump QGradient.Preset.DesertHump
+QGradient.JungleDay QGradient.Preset.JungleDay
+QGradient.PhoenixStart QGradient.Preset.PhoenixStart
+QGradient.OctoberSilence QGradient.Preset.OctoberSilence
+QGradient.FarawayRiver QGradient.Preset.FarawayRiver
+QGradient.AlchemistLab QGradient.Preset.AlchemistLab
+QGradient.OverSun QGradient.Preset.OverSun
+QGradient.PremiumWhite QGradient.Preset.PremiumWhite
+QGradient.MarsParty QGradient.Preset.MarsParty
+QGradient.EternalConstance QGradient.Preset.EternalConstance
+QGradient.JapanBlush QGradient.Preset.JapanBlush
+QGradient.SmilingRain QGradient.Preset.SmilingRain
+QGradient.CloudyApple QGradient.Preset.CloudyApple
+QGradient.BigMango QGradient.Preset.BigMango
+QGradient.HealthyWater QGradient.Preset.HealthyWater
+QGradient.AmourAmour QGradient.Preset.AmourAmour
+QGradient.RiskyConcrete QGradient.Preset.RiskyConcrete
+QGradient.StrongStick QGradient.Preset.StrongStick
+QGradient.ViciousStance QGradient.Preset.ViciousStance
+QGradient.PaloAlto QGradient.Preset.PaloAlto
+QGradient.HappyMemories QGradient.Preset.HappyMemories
+QGradient.MidnightBloom QGradient.Preset.MidnightBloom
+QGradient.Crystalline QGradient.Preset.Crystalline
+QGradient.PartyBliss QGradient.Preset.PartyBliss
+QGradient.ConfidentCloud QGradient.Preset.ConfidentCloud
+QGradient.LeCocktail QGradient.Preset.LeCocktail
+QGradient.RiverCity QGradient.Preset.RiverCity
+QGradient.FrozenBerry QGradient.Preset.FrozenBerry
+QGradient.ChildCare QGradient.Preset.ChildCare
+QGradient.FlyingLemon QGradient.Preset.FlyingLemon
+QGradient.NewRetrowave QGradient.Preset.NewRetrowave
+QGradient.HiddenJaguar QGradient.Preset.HiddenJaguar
+QGradient.AboveTheSky QGradient.Preset.AboveTheSky
+QGradient.Nega QGradient.Preset.Nega
+QGradient.DenseWater QGradient.Preset.DenseWater
+QGradient.Seashore QGradient.Preset.Seashore
+QGradient.MarbleWall QGradient.Preset.MarbleWall
+QGradient.CheerfulCaramel QGradient.Preset.CheerfulCaramel
+QGradient.NightSky QGradient.Preset.NightSky
+QGradient.MagicLake QGradient.Preset.MagicLake
+QGradient.YoungGrass QGradient.Preset.YoungGrass
+QGradient.ColorfulPeach QGradient.Preset.ColorfulPeach
+QGradient.GentleCare QGradient.Preset.GentleCare
+QGradient.PlumBath QGradient.Preset.PlumBath
+QGradient.HappyUnicorn QGradient.Preset.HappyUnicorn
+QGradient.AfricanField QGradient.Preset.AfricanField
+QGradient.SolidStone QGradient.Preset.SolidStone
+QGradient.OrangeJuice QGradient.Preset.OrangeJuice
+QGradient.GlassWater QGradient.Preset.GlassWater
+QGradient.NorthMiracle QGradient.Preset.NorthMiracle
+QGradient.FruitBlend QGradient.Preset.FruitBlend
+QGradient.MillenniumPine QGradient.Preset.MillenniumPine
+QGradient.HighFlight QGradient.Preset.HighFlight
+QGradient.MoleHall QGradient.Preset.MoleHall
+QGradient.SpaceShift QGradient.Preset.SpaceShift
+QGradient.ForestInei QGradient.Preset.ForestInei
+QGradient.RoyalGarden QGradient.Preset.RoyalGarden
+QGradient.RichMetal QGradient.Preset.RichMetal
+QGradient.JuicyCake QGradient.Preset.JuicyCake
+QGradient.SmartIndigo QGradient.Preset.SmartIndigo
+QGradient.SandStrike QGradient.Preset.SandStrike
+QGradient.NorseBeauty QGradient.Preset.NorseBeauty
+QGradient.AquaGuidance QGradient.Preset.AquaGuidance
+QGradient.SunVeggie QGradient.Preset.SunVeggie
+QGradient.SeaLord QGradient.Preset.SeaLord
+QGradient.BlackSea QGradient.Preset.BlackSea
+QGradient.GrassShampoo QGradient.Preset.GrassShampoo
+QGradient.LandingAircraft QGradient.Preset.LandingAircraft
+QGradient.WitchDance QGradient.Preset.WitchDance
+QGradient.SleeplessNight QGradient.Preset.SleeplessNight
+QGradient.AngelCare QGradient.Preset.AngelCare
+QGradient.CrystalRiver QGradient.Preset.CrystalRiver
+QGradient.SoftLipstick QGradient.Preset.SoftLipstick
+QGradient.SaltMountain QGradient.Preset.SaltMountain
+QGradient.PerfectWhite QGradient.Preset.PerfectWhite
+QGradient.FreshOasis QGradient.Preset.FreshOasis
+QGradient.StrictNovember QGradient.Preset.StrictNovember
+QGradient.MorningSalad QGradient.Preset.MorningSalad
+QGradient.DeepRelief QGradient.Preset.DeepRelief
+QGradient.SeaStrike QGradient.Preset.SeaStrike
+QGradient.NightCall QGradient.Preset.NightCall
+QGradient.SupremeSky QGradient.Preset.SupremeSky
+QGradient.LightBlue QGradient.Preset.LightBlue
+QGradient.MindCrawl QGradient.Preset.MindCrawl
+QGradient.LilyMeadow QGradient.Preset.LilyMeadow
+QGradient.SugarLollipop QGradient.Preset.SugarLollipop
+QGradient.SweetDessert QGradient.Preset.SweetDessert
+QGradient.MagicRay QGradient.Preset.MagicRay
+QGradient.TeenParty QGradient.Preset.TeenParty
+QGradient.FrozenHeat QGradient.Preset.FrozenHeat
+QGradient.GagarinView QGradient.Preset.GagarinView
+QGradient.FabledSunset QGradient.Preset.FabledSunset
+QGradient.PerfectBlue QGradient.Preset.PerfectBlue
+QGradient.NumPresets QGradient.Preset.NumPresets
+QGradient.PadSpread QGradient.Spread.PadSpread
+QGradient.ReflectSpread QGradient.Spread.ReflectSpread
+QGradient.RepeatSpread QGradient.Spread.RepeatSpread
+QGradient.LinearGradient QGradient.Type.LinearGradient
+QGradient.RadialGradient QGradient.Type.RadialGradient
+QGradient.ConicalGradient QGradient.Type.ConicalGradient
+QGradient.NoGradient QGradient.Type.NoGradient
+QGradient.LogicalMode QGradient.CoordinateMode.LogicalMode
+QGradient.StretchToDeviceMode QGradient.CoordinateMode.StretchToDeviceMode
+QGradient.ObjectBoundingMode QGradient.CoordinateMode.ObjectBoundingMode
+QGradient.ObjectMode QGradient.CoordinateMode.ObjectMode
+QClipboard.Clipboard QClipboard.Mode.Clipboard
+QClipboard.Selection QClipboard.Mode.Selection
+QClipboard.FindBuffer QClipboard.Mode.FindBuffer
+QColorSpace.Custom QColorSpace.TransferFunction.Custom
+QColorSpace.Linear QColorSpace.TransferFunction.Linear
+QColorSpace.Gamma QColorSpace.TransferFunction.Gamma
+QColorSpace.SRgb QColorSpace.TransferFunction.SRgb
+QColorSpace.ProPhotoRgb QColorSpace.TransferFunction.ProPhotoRgb
+QColorSpace.Custom QColorSpace.Primaries.Custom
+QColorSpace.SRgb QColorSpace.Primaries.SRgb
+QColorSpace.AdobeRgb QColorSpace.Primaries.AdobeRgb
+QColorSpace.DciP3D65 QColorSpace.Primaries.DciP3D65
+QColorSpace.ProPhotoRgb QColorSpace.Primaries.ProPhotoRgb
+QColorSpace.SRgb QColorSpace.NamedColorSpace.SRgb
+QColorSpace.SRgbLinear QColorSpace.NamedColorSpace.SRgbLinear
+QColorSpace.AdobeRgb QColorSpace.NamedColorSpace.AdobeRgb
+QColorSpace.DisplayP3 QColorSpace.NamedColorSpace.DisplayP3
+QColorSpace.ProPhotoRgb QColorSpace.NamedColorSpace.ProPhotoRgb
+QTabletEvent.UnknownPointer QTabletEvent.PointerType.UnknownPointer
+QTabletEvent.Pen QTabletEvent.PointerType.Pen
+QTabletEvent.Cursor QTabletEvent.PointerType.Cursor
+QTabletEvent.Eraser QTabletEvent.PointerType.Eraser
+QTabletEvent.NoDevice QTabletEvent.TabletDevice.NoDevice
+QTabletEvent.Puck QTabletEvent.TabletDevice.Puck
+QTabletEvent.Stylus QTabletEvent.TabletDevice.Stylus
+QTabletEvent.Airbrush QTabletEvent.TabletDevice.Airbrush
+QTabletEvent.FourDMouse QTabletEvent.TabletDevice.FourDMouse
+QTabletEvent.XFreeEraser QTabletEvent.TabletDevice.XFreeEraser
+QTabletEvent.RotationStylus QTabletEvent.TabletDevice.RotationStylus
+QContextMenuEvent.Mouse QContextMenuEvent.Reason.Mouse
+QContextMenuEvent.Keyboard QContextMenuEvent.Reason.Keyboard
+QContextMenuEvent.Other QContextMenuEvent.Reason.Other
+QInputMethodEvent.TextFormat QInputMethodEvent.AttributeType.TextFormat
+QInputMethodEvent.Cursor QInputMethodEvent.AttributeType.Cursor
+QInputMethodEvent.Language QInputMethodEvent.AttributeType.Language
+QInputMethodEvent.Ruby QInputMethodEvent.AttributeType.Ruby
+QInputMethodEvent.Selection QInputMethodEvent.AttributeType.Selection
+QScrollEvent.ScrollStarted QScrollEvent.ScrollState.ScrollStarted
+QScrollEvent.ScrollUpdated QScrollEvent.ScrollState.ScrollUpdated
+QScrollEvent.ScrollFinished QScrollEvent.ScrollState.ScrollFinished
+QPlatformSurfaceEvent.SurfaceCreated QPlatformSurfaceEvent.SurfaceEventType.SurfaceCreated
+QPlatformSurfaceEvent.SurfaceAboutToBeDestroyed QPlatformSurfaceEvent.SurfaceEventType.SurfaceAboutToBeDestroyed
+QFont.PreferDefaultHinting QFont.HintingPreference.PreferDefaultHinting
+QFont.PreferNoHinting QFont.HintingPreference.PreferNoHinting
+QFont.PreferVerticalHinting QFont.HintingPreference.PreferVerticalHinting
+QFont.PreferFullHinting QFont.HintingPreference.PreferFullHinting
+QFont.PercentageSpacing QFont.SpacingType.PercentageSpacing
+QFont.AbsoluteSpacing QFont.SpacingType.AbsoluteSpacing
+QFont.MixedCase QFont.Capitalization.MixedCase
+QFont.AllUppercase QFont.Capitalization.AllUppercase
+QFont.AllLowercase QFont.Capitalization.AllLowercase
+QFont.SmallCaps QFont.Capitalization.SmallCaps
+QFont.Capitalize QFont.Capitalization.Capitalize
+QFont.AnyStretch QFont.Stretch.AnyStretch
+QFont.UltraCondensed QFont.Stretch.UltraCondensed
+QFont.ExtraCondensed QFont.Stretch.ExtraCondensed
+QFont.Condensed QFont.Stretch.Condensed
+QFont.SemiCondensed QFont.Stretch.SemiCondensed
+QFont.Unstretched QFont.Stretch.Unstretched
+QFont.SemiExpanded QFont.Stretch.SemiExpanded
+QFont.Expanded QFont.Stretch.Expanded
+QFont.ExtraExpanded QFont.Stretch.ExtraExpanded
+QFont.UltraExpanded QFont.Stretch.UltraExpanded
+QFont.StyleNormal QFont.Style.StyleNormal
+QFont.StyleItalic QFont.Style.StyleItalic
+QFont.StyleOblique QFont.Style.StyleOblique
+QFont.Thin QFont.Weight.Thin
+QFont.ExtraLight QFont.Weight.ExtraLight
+QFont.Light QFont.Weight.Light
+QFont.Normal QFont.Weight.Normal
+QFont.Medium QFont.Weight.Medium
+QFont.DemiBold QFont.Weight.DemiBold
+QFont.Bold QFont.Weight.Bold
+QFont.ExtraBold QFont.Weight.ExtraBold
+QFont.Black QFont.Weight.Black
+QFont.PreferDefault QFont.StyleStrategy.PreferDefault
+QFont.PreferBitmap QFont.StyleStrategy.PreferBitmap
+QFont.PreferDevice QFont.StyleStrategy.PreferDevice
+QFont.PreferOutline QFont.StyleStrategy.PreferOutline
+QFont.ForceOutline QFont.StyleStrategy.ForceOutline
+QFont.PreferMatch QFont.StyleStrategy.PreferMatch
+QFont.PreferQuality QFont.StyleStrategy.PreferQuality
+QFont.PreferAntialias QFont.StyleStrategy.PreferAntialias
+QFont.NoAntialias QFont.StyleStrategy.NoAntialias
+QFont.NoSubpixelAntialias QFont.StyleStrategy.NoSubpixelAntialias
+QFont.OpenGLCompatible QFont.StyleStrategy.OpenGLCompatible
+QFont.NoFontMerging QFont.StyleStrategy.NoFontMerging
+QFont.ForceIntegerMetrics QFont.StyleStrategy.ForceIntegerMetrics
+QFont.PreferNoShaping QFont.StyleStrategy.PreferNoShaping
+QFont.Helvetica QFont.StyleHint.Helvetica
+QFont.SansSerif QFont.StyleHint.SansSerif
+QFont.Times QFont.StyleHint.Times
+QFont.Serif QFont.StyleHint.Serif
+QFont.Courier QFont.StyleHint.Courier
+QFont.TypeWriter QFont.StyleHint.TypeWriter
+QFont.OldEnglish QFont.StyleHint.OldEnglish
+QFont.Decorative QFont.StyleHint.Decorative
+QFont.System QFont.StyleHint.System
+QFont.AnyStyle QFont.StyleHint.AnyStyle
+QFont.Cursive QFont.StyleHint.Cursive
+QFont.Monospace QFont.StyleHint.Monospace
+QFont.Fantasy QFont.StyleHint.Fantasy
+QFontDatabase.GeneralFont QFontDatabase.SystemFont.GeneralFont
+QFontDatabase.FixedFont QFontDatabase.SystemFont.FixedFont
+QFontDatabase.TitleFont QFontDatabase.SystemFont.TitleFont
+QFontDatabase.SmallestReadableFont QFontDatabase.SystemFont.SmallestReadableFont
+QFontDatabase.Any QFontDatabase.WritingSystem.Any
+QFontDatabase.Latin QFontDatabase.WritingSystem.Latin
+QFontDatabase.Greek QFontDatabase.WritingSystem.Greek
+QFontDatabase.Cyrillic QFontDatabase.WritingSystem.Cyrillic
+QFontDatabase.Armenian QFontDatabase.WritingSystem.Armenian
+QFontDatabase.Hebrew QFontDatabase.WritingSystem.Hebrew
+QFontDatabase.Arabic QFontDatabase.WritingSystem.Arabic
+QFontDatabase.Syriac QFontDatabase.WritingSystem.Syriac
+QFontDatabase.Thaana QFontDatabase.WritingSystem.Thaana
+QFontDatabase.Devanagari QFontDatabase.WritingSystem.Devanagari
+QFontDatabase.Bengali QFontDatabase.WritingSystem.Bengali
+QFontDatabase.Gurmukhi QFontDatabase.WritingSystem.Gurmukhi
+QFontDatabase.Gujarati QFontDatabase.WritingSystem.Gujarati
+QFontDatabase.Oriya QFontDatabase.WritingSystem.Oriya
+QFontDatabase.Tamil QFontDatabase.WritingSystem.Tamil
+QFontDatabase.Telugu QFontDatabase.WritingSystem.Telugu
+QFontDatabase.Kannada QFontDatabase.WritingSystem.Kannada
+QFontDatabase.Malayalam QFontDatabase.WritingSystem.Malayalam
+QFontDatabase.Sinhala QFontDatabase.WritingSystem.Sinhala
+QFontDatabase.Thai QFontDatabase.WritingSystem.Thai
+QFontDatabase.Lao QFontDatabase.WritingSystem.Lao
+QFontDatabase.Tibetan QFontDatabase.WritingSystem.Tibetan
+QFontDatabase.Myanmar QFontDatabase.WritingSystem.Myanmar
+QFontDatabase.Georgian QFontDatabase.WritingSystem.Georgian
+QFontDatabase.Khmer QFontDatabase.WritingSystem.Khmer
+QFontDatabase.SimplifiedChinese QFontDatabase.WritingSystem.SimplifiedChinese
+QFontDatabase.TraditionalChinese QFontDatabase.WritingSystem.TraditionalChinese
+QFontDatabase.Japanese QFontDatabase.WritingSystem.Japanese
+QFontDatabase.Korean QFontDatabase.WritingSystem.Korean
+QFontDatabase.Vietnamese QFontDatabase.WritingSystem.Vietnamese
+QFontDatabase.Other QFontDatabase.WritingSystem.Other
+QFontDatabase.Symbol QFontDatabase.WritingSystem.Symbol
+QFontDatabase.Ogham QFontDatabase.WritingSystem.Ogham
+QFontDatabase.Runic QFontDatabase.WritingSystem.Runic
+QFontDatabase.Nko QFontDatabase.WritingSystem.Nko
+QGlyphRun.Overline QGlyphRun.GlyphRunFlag.Overline
+QGlyphRun.Underline QGlyphRun.GlyphRunFlag.Underline
+QGlyphRun.StrikeOut QGlyphRun.GlyphRunFlag.StrikeOut
+QGlyphRun.RightToLeft QGlyphRun.GlyphRunFlag.RightToLeft
+QGlyphRun.SplitLigature QGlyphRun.GlyphRunFlag.SplitLigature
+QIcon.On QIcon.State.On
+QIcon.Off QIcon.State.Off
+QIcon.Normal QIcon.Mode.Normal
+QIcon.Disabled QIcon.Mode.Disabled
+QIcon.Active QIcon.Mode.Active
+QIcon.Selected QIcon.Mode.Selected
+QIconEngine.AvailableSizesHook QIconEngine.IconEngineHook.AvailableSizesHook
+QIconEngine.IconNameHook QIconEngine.IconEngineHook.IconNameHook
+QIconEngine.IsNullHook QIconEngine.IconEngineHook.IsNullHook
+QIconEngine.ScaledPixmapHook QIconEngine.IconEngineHook.ScaledPixmapHook
+QImage.Format_Invalid QImage.Format.Format_Invalid
+QImage.Format_Mono QImage.Format.Format_Mono
+QImage.Format_MonoLSB QImage.Format.Format_MonoLSB
+QImage.Format_Indexed8 QImage.Format.Format_Indexed8
+QImage.Format_RGB32 QImage.Format.Format_RGB32
+QImage.Format_ARGB32 QImage.Format.Format_ARGB32
+QImage.Format_ARGB32_Premultiplied QImage.Format.Format_ARGB32_Premultiplied
+QImage.Format_RGB16 QImage.Format.Format_RGB16
+QImage.Format_ARGB8565_Premultiplied QImage.Format.Format_ARGB8565_Premultiplied
+QImage.Format_RGB666 QImage.Format.Format_RGB666
+QImage.Format_ARGB6666_Premultiplied QImage.Format.Format_ARGB6666_Premultiplied
+QImage.Format_RGB555 QImage.Format.Format_RGB555
+QImage.Format_ARGB8555_Premultiplied QImage.Format.Format_ARGB8555_Premultiplied
+QImage.Format_RGB888 QImage.Format.Format_RGB888
+QImage.Format_RGB444 QImage.Format.Format_RGB444
+QImage.Format_ARGB4444_Premultiplied QImage.Format.Format_ARGB4444_Premultiplied
+QImage.Format_RGBX8888 QImage.Format.Format_RGBX8888
+QImage.Format_RGBA8888 QImage.Format.Format_RGBA8888
+QImage.Format_RGBA8888_Premultiplied QImage.Format.Format_RGBA8888_Premultiplied
+QImage.Format_BGR30 QImage.Format.Format_BGR30
+QImage.Format_A2BGR30_Premultiplied QImage.Format.Format_A2BGR30_Premultiplied
+QImage.Format_RGB30 QImage.Format.Format_RGB30
+QImage.Format_A2RGB30_Premultiplied QImage.Format.Format_A2RGB30_Premultiplied
+QImage.Format_Alpha8 QImage.Format.Format_Alpha8
+QImage.Format_Grayscale8 QImage.Format.Format_Grayscale8
+QImage.Format_RGBX64 QImage.Format.Format_RGBX64
+QImage.Format_RGBA64 QImage.Format.Format_RGBA64
+QImage.Format_RGBA64_Premultiplied QImage.Format.Format_RGBA64_Premultiplied
+QImage.Format_Grayscale16 QImage.Format.Format_Grayscale16
+QImage.Format_BGR888 QImage.Format.Format_BGR888
+QImage.InvertRgb QImage.InvertMode.InvertRgb
+QImage.InvertRgba QImage.InvertMode.InvertRgba
+QImageIOHandler.TransformationNone QImageIOHandler.Transformation.TransformationNone
+QImageIOHandler.TransformationMirror QImageIOHandler.Transformation.TransformationMirror
+QImageIOHandler.TransformationFlip QImageIOHandler.Transformation.TransformationFlip
+QImageIOHandler.TransformationRotate180 QImageIOHandler.Transformation.TransformationRotate180
+QImageIOHandler.TransformationRotate90 QImageIOHandler.Transformation.TransformationRotate90
+QImageIOHandler.TransformationMirrorAndRotate90 QImageIOHandler.Transformation.TransformationMirrorAndRotate90
+QImageIOHandler.TransformationFlipAndRotate90 QImageIOHandler.Transformation.TransformationFlipAndRotate90
+QImageIOHandler.TransformationRotate270 QImageIOHandler.Transformation.TransformationRotate270
+QImageIOHandler.Size QImageIOHandler.ImageOption.Size
+QImageIOHandler.ClipRect QImageIOHandler.ImageOption.ClipRect
+QImageIOHandler.Description QImageIOHandler.ImageOption.Description
+QImageIOHandler.ScaledClipRect QImageIOHandler.ImageOption.ScaledClipRect
+QImageIOHandler.ScaledSize QImageIOHandler.ImageOption.ScaledSize
+QImageIOHandler.CompressionRatio QImageIOHandler.ImageOption.CompressionRatio
+QImageIOHandler.Gamma QImageIOHandler.ImageOption.Gamma
+QImageIOHandler.Quality QImageIOHandler.ImageOption.Quality
+QImageIOHandler.Name QImageIOHandler.ImageOption.Name
+QImageIOHandler.SubType QImageIOHandler.ImageOption.SubType
+QImageIOHandler.IncrementalReading QImageIOHandler.ImageOption.IncrementalReading
+QImageIOHandler.Endianness QImageIOHandler.ImageOption.Endianness
+QImageIOHandler.Animation QImageIOHandler.ImageOption.Animation
+QImageIOHandler.BackgroundColor QImageIOHandler.ImageOption.BackgroundColor
+QImageIOHandler.SupportedSubTypes QImageIOHandler.ImageOption.SupportedSubTypes
+QImageIOHandler.OptimizedWrite QImageIOHandler.ImageOption.OptimizedWrite
+QImageIOHandler.ProgressiveScanWrite QImageIOHandler.ImageOption.ProgressiveScanWrite
+QImageIOHandler.ImageTransformation QImageIOHandler.ImageOption.ImageTransformation
+QImageIOHandler.TransformedByDefault QImageIOHandler.ImageOption.TransformedByDefault
+QImageReader.UnknownError QImageReader.ImageReaderError.UnknownError
+QImageReader.FileNotFoundError QImageReader.ImageReaderError.FileNotFoundError
+QImageReader.DeviceError QImageReader.ImageReaderError.DeviceError
+QImageReader.UnsupportedFormatError QImageReader.ImageReaderError.UnsupportedFormatError
+QImageReader.InvalidDataError QImageReader.ImageReaderError.InvalidDataError
+QImageWriter.UnknownError QImageWriter.ImageWriterError.UnknownError
+QImageWriter.DeviceError QImageWriter.ImageWriterError.DeviceError
+QImageWriter.UnsupportedFormatError QImageWriter.ImageWriterError.UnsupportedFormatError
+QImageWriter.InvalidImageError QImageWriter.ImageWriterError.InvalidImageError
+QInputMethod.Click QInputMethod.Action.Click
+QInputMethod.ContextMenu QInputMethod.Action.ContextMenu
+QKeySequence.UnknownKey QKeySequence.StandardKey.UnknownKey
+QKeySequence.HelpContents QKeySequence.StandardKey.HelpContents
+QKeySequence.WhatsThis QKeySequence.StandardKey.WhatsThis
+QKeySequence.Open QKeySequence.StandardKey.Open
+QKeySequence.Close QKeySequence.StandardKey.Close
+QKeySequence.Save QKeySequence.StandardKey.Save
+QKeySequence.New QKeySequence.StandardKey.New
+QKeySequence.Delete QKeySequence.StandardKey.Delete
+QKeySequence.Cut QKeySequence.StandardKey.Cut
+QKeySequence.Copy QKeySequence.StandardKey.Copy
+QKeySequence.Paste QKeySequence.StandardKey.Paste
+QKeySequence.Undo QKeySequence.StandardKey.Undo
+QKeySequence.Redo QKeySequence.StandardKey.Redo
+QKeySequence.Back QKeySequence.StandardKey.Back
+QKeySequence.Forward QKeySequence.StandardKey.Forward
+QKeySequence.Refresh QKeySequence.StandardKey.Refresh
+QKeySequence.ZoomIn QKeySequence.StandardKey.ZoomIn
+QKeySequence.ZoomOut QKeySequence.StandardKey.ZoomOut
+QKeySequence.Print QKeySequence.StandardKey.Print
+QKeySequence.AddTab QKeySequence.StandardKey.AddTab
+QKeySequence.NextChild QKeySequence.StandardKey.NextChild
+QKeySequence.PreviousChild QKeySequence.StandardKey.PreviousChild
+QKeySequence.Find QKeySequence.StandardKey.Find
+QKeySequence.FindNext QKeySequence.StandardKey.FindNext
+QKeySequence.FindPrevious QKeySequence.StandardKey.FindPrevious
+QKeySequence.Replace QKeySequence.StandardKey.Replace
+QKeySequence.SelectAll QKeySequence.StandardKey.SelectAll
+QKeySequence.Bold QKeySequence.StandardKey.Bold
+QKeySequence.Italic QKeySequence.StandardKey.Italic
+QKeySequence.Underline QKeySequence.StandardKey.Underline
+QKeySequence.MoveToNextChar QKeySequence.StandardKey.MoveToNextChar
+QKeySequence.MoveToPreviousChar QKeySequence.StandardKey.MoveToPreviousChar
+QKeySequence.MoveToNextWord QKeySequence.StandardKey.MoveToNextWord
+QKeySequence.MoveToPreviousWord QKeySequence.StandardKey.MoveToPreviousWord
+QKeySequence.MoveToNextLine QKeySequence.StandardKey.MoveToNextLine
+QKeySequence.MoveToPreviousLine QKeySequence.StandardKey.MoveToPreviousLine
+QKeySequence.MoveToNextPage QKeySequence.StandardKey.MoveToNextPage
+QKeySequence.MoveToPreviousPage QKeySequence.StandardKey.MoveToPreviousPage
+QKeySequence.MoveToStartOfLine QKeySequence.StandardKey.MoveToStartOfLine
+QKeySequence.MoveToEndOfLine QKeySequence.StandardKey.MoveToEndOfLine
+QKeySequence.MoveToStartOfBlock QKeySequence.StandardKey.MoveToStartOfBlock
+QKeySequence.MoveToEndOfBlock QKeySequence.StandardKey.MoveToEndOfBlock
+QKeySequence.MoveToStartOfDocument QKeySequence.StandardKey.MoveToStartOfDocument
+QKeySequence.MoveToEndOfDocument QKeySequence.StandardKey.MoveToEndOfDocument
+QKeySequence.SelectNextChar QKeySequence.StandardKey.SelectNextChar
+QKeySequence.SelectPreviousChar QKeySequence.StandardKey.SelectPreviousChar
+QKeySequence.SelectNextWord QKeySequence.StandardKey.SelectNextWord
+QKeySequence.SelectPreviousWord QKeySequence.StandardKey.SelectPreviousWord
+QKeySequence.SelectNextLine QKeySequence.StandardKey.SelectNextLine
+QKeySequence.SelectPreviousLine QKeySequence.StandardKey.SelectPreviousLine
+QKeySequence.SelectNextPage QKeySequence.StandardKey.SelectNextPage
+QKeySequence.SelectPreviousPage QKeySequence.StandardKey.SelectPreviousPage
+QKeySequence.SelectStartOfLine QKeySequence.StandardKey.SelectStartOfLine
+QKeySequence.SelectEndOfLine QKeySequence.StandardKey.SelectEndOfLine
+QKeySequence.SelectStartOfBlock QKeySequence.StandardKey.SelectStartOfBlock
+QKeySequence.SelectEndOfBlock QKeySequence.StandardKey.SelectEndOfBlock
+QKeySequence.SelectStartOfDocument QKeySequence.StandardKey.SelectStartOfDocument
+QKeySequence.SelectEndOfDocument QKeySequence.StandardKey.SelectEndOfDocument
+QKeySequence.DeleteStartOfWord QKeySequence.StandardKey.DeleteStartOfWord
+QKeySequence.DeleteEndOfWord QKeySequence.StandardKey.DeleteEndOfWord
+QKeySequence.DeleteEndOfLine QKeySequence.StandardKey.DeleteEndOfLine
+QKeySequence.InsertParagraphSeparator QKeySequence.StandardKey.InsertParagraphSeparator
+QKeySequence.InsertLineSeparator QKeySequence.StandardKey.InsertLineSeparator
+QKeySequence.SaveAs QKeySequence.StandardKey.SaveAs
+QKeySequence.Preferences QKeySequence.StandardKey.Preferences
+QKeySequence.Quit QKeySequence.StandardKey.Quit
+QKeySequence.FullScreen QKeySequence.StandardKey.FullScreen
+QKeySequence.Deselect QKeySequence.StandardKey.Deselect
+QKeySequence.DeleteCompleteLine QKeySequence.StandardKey.DeleteCompleteLine
+QKeySequence.Backspace QKeySequence.StandardKey.Backspace
+QKeySequence.Cancel QKeySequence.StandardKey.Cancel
+QKeySequence.NoMatch QKeySequence.SequenceMatch.NoMatch
+QKeySequence.PartialMatch QKeySequence.SequenceMatch.PartialMatch
+QKeySequence.ExactMatch QKeySequence.SequenceMatch.ExactMatch
+QKeySequence.NativeText QKeySequence.SequenceFormat.NativeText
+QKeySequence.PortableText QKeySequence.SequenceFormat.PortableText
+QMovie.CacheNone QMovie.CacheMode.CacheNone
+QMovie.CacheAll QMovie.CacheMode.CacheAll
+QMovie.NotRunning QMovie.MovieState.NotRunning
+QMovie.Paused QMovie.MovieState.Paused
+QMovie.Running QMovie.MovieState.Running
+QSurface.RasterSurface QSurface.SurfaceType.RasterSurface
+QSurface.OpenGLSurface QSurface.SurfaceType.OpenGLSurface
+QSurface.RasterGLSurface QSurface.SurfaceType.RasterGLSurface
+QSurface.OpenVGSurface QSurface.SurfaceType.OpenVGSurface
+QSurface.VulkanSurface QSurface.SurfaceType.VulkanSurface
+QSurface.MetalSurface QSurface.SurfaceType.MetalSurface
+QSurface.Window QSurface.SurfaceClass.Window
+QSurface.Offscreen QSurface.SurfaceClass.Offscreen
+QOpenGLBuffer.RangeRead QOpenGLBuffer.RangeAccessFlag.RangeRead
+QOpenGLBuffer.RangeWrite QOpenGLBuffer.RangeAccessFlag.RangeWrite
+QOpenGLBuffer.RangeInvalidate QOpenGLBuffer.RangeAccessFlag.RangeInvalidate
+QOpenGLBuffer.RangeInvalidateBuffer QOpenGLBuffer.RangeAccessFlag.RangeInvalidateBuffer
+QOpenGLBuffer.RangeFlushExplicit QOpenGLBuffer.RangeAccessFlag.RangeFlushExplicit
+QOpenGLBuffer.RangeUnsynchronized QOpenGLBuffer.RangeAccessFlag.RangeUnsynchronized
+QOpenGLBuffer.ReadOnly QOpenGLBuffer.Access.ReadOnly
+QOpenGLBuffer.WriteOnly QOpenGLBuffer.Access.WriteOnly
+QOpenGLBuffer.ReadWrite QOpenGLBuffer.Access.ReadWrite
+QOpenGLBuffer.StreamDraw QOpenGLBuffer.UsagePattern.StreamDraw
+QOpenGLBuffer.StreamRead QOpenGLBuffer.UsagePattern.StreamRead
+QOpenGLBuffer.StreamCopy QOpenGLBuffer.UsagePattern.StreamCopy
+QOpenGLBuffer.StaticDraw QOpenGLBuffer.UsagePattern.StaticDraw
+QOpenGLBuffer.StaticRead QOpenGLBuffer.UsagePattern.StaticRead
+QOpenGLBuffer.StaticCopy QOpenGLBuffer.UsagePattern.StaticCopy
+QOpenGLBuffer.DynamicDraw QOpenGLBuffer.UsagePattern.DynamicDraw
+QOpenGLBuffer.DynamicRead QOpenGLBuffer.UsagePattern.DynamicRead
+QOpenGLBuffer.DynamicCopy QOpenGLBuffer.UsagePattern.DynamicCopy
+QOpenGLBuffer.VertexBuffer QOpenGLBuffer.Type.VertexBuffer
+QOpenGLBuffer.IndexBuffer QOpenGLBuffer.Type.IndexBuffer
+QOpenGLBuffer.PixelPackBuffer QOpenGLBuffer.Type.PixelPackBuffer
+QOpenGLBuffer.PixelUnpackBuffer QOpenGLBuffer.Type.PixelUnpackBuffer
+QOpenGLContext.LibGL QOpenGLContext.OpenGLModuleType.LibGL
+QOpenGLContext.LibGLES QOpenGLContext.OpenGLModuleType.LibGLES
+QOpenGLDebugMessage.InvalidSeverity QOpenGLDebugMessage.Severity.InvalidSeverity
+QOpenGLDebugMessage.HighSeverity QOpenGLDebugMessage.Severity.HighSeverity
+QOpenGLDebugMessage.MediumSeverity QOpenGLDebugMessage.Severity.MediumSeverity
+QOpenGLDebugMessage.LowSeverity QOpenGLDebugMessage.Severity.LowSeverity
+QOpenGLDebugMessage.NotificationSeverity QOpenGLDebugMessage.Severity.NotificationSeverity
+QOpenGLDebugMessage.AnySeverity QOpenGLDebugMessage.Severity.AnySeverity
+QOpenGLDebugMessage.InvalidType QOpenGLDebugMessage.Type.InvalidType
+QOpenGLDebugMessage.ErrorType QOpenGLDebugMessage.Type.ErrorType
+QOpenGLDebugMessage.DeprecatedBehaviorType QOpenGLDebugMessage.Type.DeprecatedBehaviorType
+QOpenGLDebugMessage.UndefinedBehaviorType QOpenGLDebugMessage.Type.UndefinedBehaviorType
+QOpenGLDebugMessage.PortabilityType QOpenGLDebugMessage.Type.PortabilityType
+QOpenGLDebugMessage.PerformanceType QOpenGLDebugMessage.Type.PerformanceType
+QOpenGLDebugMessage.OtherType QOpenGLDebugMessage.Type.OtherType
+QOpenGLDebugMessage.MarkerType QOpenGLDebugMessage.Type.MarkerType
+QOpenGLDebugMessage.GroupPushType QOpenGLDebugMessage.Type.GroupPushType
+QOpenGLDebugMessage.GroupPopType QOpenGLDebugMessage.Type.GroupPopType
+QOpenGLDebugMessage.AnyType QOpenGLDebugMessage.Type.AnyType
+QOpenGLDebugMessage.InvalidSource QOpenGLDebugMessage.Source.InvalidSource
+QOpenGLDebugMessage.APISource QOpenGLDebugMessage.Source.APISource
+QOpenGLDebugMessage.WindowSystemSource QOpenGLDebugMessage.Source.WindowSystemSource
+QOpenGLDebugMessage.ShaderCompilerSource QOpenGLDebugMessage.Source.ShaderCompilerSource
+QOpenGLDebugMessage.ThirdPartySource QOpenGLDebugMessage.Source.ThirdPartySource
+QOpenGLDebugMessage.ApplicationSource QOpenGLDebugMessage.Source.ApplicationSource
+QOpenGLDebugMessage.OtherSource QOpenGLDebugMessage.Source.OtherSource
+QOpenGLDebugMessage.AnySource QOpenGLDebugMessage.Source.AnySource
+QOpenGLDebugLogger.AsynchronousLogging QOpenGLDebugLogger.LoggingMode.AsynchronousLogging
+QOpenGLDebugLogger.SynchronousLogging QOpenGLDebugLogger.LoggingMode.SynchronousLogging
+QOpenGLFramebufferObject.DontRestoreFramebufferBinding QOpenGLFramebufferObject.FramebufferRestorePolicy.DontRestoreFramebufferBinding
+QOpenGLFramebufferObject.RestoreFramebufferBindingToDefault QOpenGLFramebufferObject.FramebufferRestorePolicy.RestoreFramebufferBindingToDefault
+QOpenGLFramebufferObject.RestoreFrameBufferBinding QOpenGLFramebufferObject.FramebufferRestorePolicy.RestoreFrameBufferBinding
+QOpenGLFramebufferObject.NoAttachment QOpenGLFramebufferObject.Attachment.NoAttachment
+QOpenGLFramebufferObject.CombinedDepthStencil QOpenGLFramebufferObject.Attachment.CombinedDepthStencil
+QOpenGLFramebufferObject.Depth QOpenGLFramebufferObject.Attachment.Depth
+QOpenGLShader.Vertex QOpenGLShader.ShaderTypeBit.Vertex
+QOpenGLShader.Fragment QOpenGLShader.ShaderTypeBit.Fragment
+QOpenGLShader.Geometry QOpenGLShader.ShaderTypeBit.Geometry
+QOpenGLShader.TessellationControl QOpenGLShader.ShaderTypeBit.TessellationControl
+QOpenGLShader.TessellationEvaluation QOpenGLShader.ShaderTypeBit.TessellationEvaluation
+QOpenGLShader.Compute QOpenGLShader.ShaderTypeBit.Compute
+QOpenGLTexture.CompareRefToTexture QOpenGLTexture.ComparisonMode.CompareRefToTexture
+QOpenGLTexture.CompareNone QOpenGLTexture.ComparisonMode.CompareNone
+QOpenGLTexture.CompareLessEqual QOpenGLTexture.ComparisonFunction.CompareLessEqual
+QOpenGLTexture.CompareGreaterEqual QOpenGLTexture.ComparisonFunction.CompareGreaterEqual
+QOpenGLTexture.CompareLess QOpenGLTexture.ComparisonFunction.CompareLess
+QOpenGLTexture.CompareGreater QOpenGLTexture.ComparisonFunction.CompareGreater
+QOpenGLTexture.CompareEqual QOpenGLTexture.ComparisonFunction.CompareEqual
+QOpenGLTexture.CommpareNotEqual QOpenGLTexture.ComparisonFunction.CommpareNotEqual
+QOpenGLTexture.CompareAlways QOpenGLTexture.ComparisonFunction.CompareAlways
+QOpenGLTexture.CompareNever QOpenGLTexture.ComparisonFunction.CompareNever
+QOpenGLTexture.DirectionS QOpenGLTexture.CoordinateDirection.DirectionS
+QOpenGLTexture.DirectionT QOpenGLTexture.CoordinateDirection.DirectionT
+QOpenGLTexture.DirectionR QOpenGLTexture.CoordinateDirection.DirectionR
+QOpenGLTexture.Repeat QOpenGLTexture.WrapMode.Repeat
+QOpenGLTexture.MirroredRepeat QOpenGLTexture.WrapMode.MirroredRepeat
+QOpenGLTexture.ClampToEdge QOpenGLTexture.WrapMode.ClampToEdge
+QOpenGLTexture.ClampToBorder QOpenGLTexture.WrapMode.ClampToBorder
+QOpenGLTexture.Nearest QOpenGLTexture.Filter.Nearest
+QOpenGLTexture.Linear QOpenGLTexture.Filter.Linear
+QOpenGLTexture.NearestMipMapNearest QOpenGLTexture.Filter.NearestMipMapNearest
+QOpenGLTexture.NearestMipMapLinear QOpenGLTexture.Filter.NearestMipMapLinear
+QOpenGLTexture.LinearMipMapNearest QOpenGLTexture.Filter.LinearMipMapNearest
+QOpenGLTexture.LinearMipMapLinear QOpenGLTexture.Filter.LinearMipMapLinear
+QOpenGLTexture.DepthMode QOpenGLTexture.DepthStencilMode.DepthMode
+QOpenGLTexture.StencilMode QOpenGLTexture.DepthStencilMode.StencilMode
+QOpenGLTexture.RedValue QOpenGLTexture.SwizzleValue.RedValue
+QOpenGLTexture.GreenValue QOpenGLTexture.SwizzleValue.GreenValue
+QOpenGLTexture.BlueValue QOpenGLTexture.SwizzleValue.BlueValue
+QOpenGLTexture.AlphaValue QOpenGLTexture.SwizzleValue.AlphaValue
+QOpenGLTexture.ZeroValue QOpenGLTexture.SwizzleValue.ZeroValue
+QOpenGLTexture.OneValue QOpenGLTexture.SwizzleValue.OneValue
+QOpenGLTexture.SwizzleRed QOpenGLTexture.SwizzleComponent.SwizzleRed
+QOpenGLTexture.SwizzleGreen QOpenGLTexture.SwizzleComponent.SwizzleGreen
+QOpenGLTexture.SwizzleBlue QOpenGLTexture.SwizzleComponent.SwizzleBlue
+QOpenGLTexture.SwizzleAlpha QOpenGLTexture.SwizzleComponent.SwizzleAlpha
+QOpenGLTexture.ImmutableStorage QOpenGLTexture.Feature.ImmutableStorage
+QOpenGLTexture.ImmutableMultisampleStorage QOpenGLTexture.Feature.ImmutableMultisampleStorage
+QOpenGLTexture.TextureRectangle QOpenGLTexture.Feature.TextureRectangle
+QOpenGLTexture.TextureArrays QOpenGLTexture.Feature.TextureArrays
+QOpenGLTexture.Texture3D QOpenGLTexture.Feature.Texture3D
+QOpenGLTexture.TextureMultisample QOpenGLTexture.Feature.TextureMultisample
+QOpenGLTexture.TextureBuffer QOpenGLTexture.Feature.TextureBuffer
+QOpenGLTexture.TextureCubeMapArrays QOpenGLTexture.Feature.TextureCubeMapArrays
+QOpenGLTexture.Swizzle QOpenGLTexture.Feature.Swizzle
+QOpenGLTexture.StencilTexturing QOpenGLTexture.Feature.StencilTexturing
+QOpenGLTexture.AnisotropicFiltering QOpenGLTexture.Feature.AnisotropicFiltering
+QOpenGLTexture.NPOTTextures QOpenGLTexture.Feature.NPOTTextures
+QOpenGLTexture.NPOTTextureRepeat QOpenGLTexture.Feature.NPOTTextureRepeat
+QOpenGLTexture.Texture1D QOpenGLTexture.Feature.Texture1D
+QOpenGLTexture.TextureComparisonOperators QOpenGLTexture.Feature.TextureComparisonOperators
+QOpenGLTexture.TextureMipMapLevel QOpenGLTexture.Feature.TextureMipMapLevel
+QOpenGLTexture.NoPixelType QOpenGLTexture.PixelType.NoPixelType
+QOpenGLTexture.Int8 QOpenGLTexture.PixelType.Int8
+QOpenGLTexture.UInt8 QOpenGLTexture.PixelType.UInt8
+QOpenGLTexture.Int16 QOpenGLTexture.PixelType.Int16
+QOpenGLTexture.UInt16 QOpenGLTexture.PixelType.UInt16
+QOpenGLTexture.Int32 QOpenGLTexture.PixelType.Int32
+QOpenGLTexture.UInt32 QOpenGLTexture.PixelType.UInt32
+QOpenGLTexture.Float16 QOpenGLTexture.PixelType.Float16
+QOpenGLTexture.Float16OES QOpenGLTexture.PixelType.Float16OES
+QOpenGLTexture.Float32 QOpenGLTexture.PixelType.Float32
+QOpenGLTexture.UInt32_RGB9_E5 QOpenGLTexture.PixelType.UInt32_RGB9_E5
+QOpenGLTexture.UInt32_RG11B10F QOpenGLTexture.PixelType.UInt32_RG11B10F
+QOpenGLTexture.UInt8_RG3B2 QOpenGLTexture.PixelType.UInt8_RG3B2
+QOpenGLTexture.UInt8_RG3B2_Rev QOpenGLTexture.PixelType.UInt8_RG3B2_Rev
+QOpenGLTexture.UInt16_RGB5A1 QOpenGLTexture.PixelType.UInt16_RGB5A1
+QOpenGLTexture.UInt16_RGB5A1_Rev QOpenGLTexture.PixelType.UInt16_RGB5A1_Rev
+QOpenGLTexture.UInt16_R5G6B5 QOpenGLTexture.PixelType.UInt16_R5G6B5
+QOpenGLTexture.UInt16_R5G6B5_Rev QOpenGLTexture.PixelType.UInt16_R5G6B5_Rev
+QOpenGLTexture.UInt16_RGBA4 QOpenGLTexture.PixelType.UInt16_RGBA4
+QOpenGLTexture.UInt16_RGBA4_Rev QOpenGLTexture.PixelType.UInt16_RGBA4_Rev
+QOpenGLTexture.UInt32_RGB10A2 QOpenGLTexture.PixelType.UInt32_RGB10A2
+QOpenGLTexture.UInt32_RGB10A2_Rev QOpenGLTexture.PixelType.UInt32_RGB10A2_Rev
+QOpenGLTexture.UInt32_RGBA8 QOpenGLTexture.PixelType.UInt32_RGBA8
+QOpenGLTexture.UInt32_RGBA8_Rev QOpenGLTexture.PixelType.UInt32_RGBA8_Rev
+QOpenGLTexture.UInt32_D24S8 QOpenGLTexture.PixelType.UInt32_D24S8
+QOpenGLTexture.Float32_D32_UInt32_S8_X24 QOpenGLTexture.PixelType.Float32_D32_UInt32_S8_X24
+QOpenGLTexture.NoSourceFormat QOpenGLTexture.PixelFormat.NoSourceFormat
+QOpenGLTexture.Red QOpenGLTexture.PixelFormat.Red
+QOpenGLTexture.RG QOpenGLTexture.PixelFormat.RG
+QOpenGLTexture.RGB QOpenGLTexture.PixelFormat.RGB
+QOpenGLTexture.BGR QOpenGLTexture.PixelFormat.BGR
+QOpenGLTexture.RGBA QOpenGLTexture.PixelFormat.RGBA
+QOpenGLTexture.BGRA QOpenGLTexture.PixelFormat.BGRA
+QOpenGLTexture.Red_Integer QOpenGLTexture.PixelFormat.Red_Integer
+QOpenGLTexture.RG_Integer QOpenGLTexture.PixelFormat.RG_Integer
+QOpenGLTexture.RGB_Integer QOpenGLTexture.PixelFormat.RGB_Integer
+QOpenGLTexture.BGR_Integer QOpenGLTexture.PixelFormat.BGR_Integer
+QOpenGLTexture.RGBA_Integer QOpenGLTexture.PixelFormat.RGBA_Integer
+QOpenGLTexture.BGRA_Integer QOpenGLTexture.PixelFormat.BGRA_Integer
+QOpenGLTexture.Depth QOpenGLTexture.PixelFormat.Depth
+QOpenGLTexture.DepthStencil QOpenGLTexture.PixelFormat.DepthStencil
+QOpenGLTexture.Alpha QOpenGLTexture.PixelFormat.Alpha
+QOpenGLTexture.Luminance QOpenGLTexture.PixelFormat.Luminance
+QOpenGLTexture.LuminanceAlpha QOpenGLTexture.PixelFormat.LuminanceAlpha
+QOpenGLTexture.Stencil QOpenGLTexture.PixelFormat.Stencil
+QOpenGLTexture.CubeMapPositiveX QOpenGLTexture.CubeMapFace.CubeMapPositiveX
+QOpenGLTexture.CubeMapNegativeX QOpenGLTexture.CubeMapFace.CubeMapNegativeX
+QOpenGLTexture.CubeMapPositiveY QOpenGLTexture.CubeMapFace.CubeMapPositiveY
+QOpenGLTexture.CubeMapNegativeY QOpenGLTexture.CubeMapFace.CubeMapNegativeY
+QOpenGLTexture.CubeMapPositiveZ QOpenGLTexture.CubeMapFace.CubeMapPositiveZ
+QOpenGLTexture.CubeMapNegativeZ QOpenGLTexture.CubeMapFace.CubeMapNegativeZ
+QOpenGLTexture.NoFormat QOpenGLTexture.TextureFormat.NoFormat
+QOpenGLTexture.R8_UNorm QOpenGLTexture.TextureFormat.R8_UNorm
+QOpenGLTexture.RG8_UNorm QOpenGLTexture.TextureFormat.RG8_UNorm
+QOpenGLTexture.RGB8_UNorm QOpenGLTexture.TextureFormat.RGB8_UNorm
+QOpenGLTexture.RGBA8_UNorm QOpenGLTexture.TextureFormat.RGBA8_UNorm
+QOpenGLTexture.R16_UNorm QOpenGLTexture.TextureFormat.R16_UNorm
+QOpenGLTexture.RG16_UNorm QOpenGLTexture.TextureFormat.RG16_UNorm
+QOpenGLTexture.RGB16_UNorm QOpenGLTexture.TextureFormat.RGB16_UNorm
+QOpenGLTexture.RGBA16_UNorm QOpenGLTexture.TextureFormat.RGBA16_UNorm
+QOpenGLTexture.R8_SNorm QOpenGLTexture.TextureFormat.R8_SNorm
+QOpenGLTexture.RG8_SNorm QOpenGLTexture.TextureFormat.RG8_SNorm
+QOpenGLTexture.RGB8_SNorm QOpenGLTexture.TextureFormat.RGB8_SNorm
+QOpenGLTexture.RGBA8_SNorm QOpenGLTexture.TextureFormat.RGBA8_SNorm
+QOpenGLTexture.R16_SNorm QOpenGLTexture.TextureFormat.R16_SNorm
+QOpenGLTexture.RG16_SNorm QOpenGLTexture.TextureFormat.RG16_SNorm
+QOpenGLTexture.RGB16_SNorm QOpenGLTexture.TextureFormat.RGB16_SNorm
+QOpenGLTexture.RGBA16_SNorm QOpenGLTexture.TextureFormat.RGBA16_SNorm
+QOpenGLTexture.R8U QOpenGLTexture.TextureFormat.R8U
+QOpenGLTexture.RG8U QOpenGLTexture.TextureFormat.RG8U
+QOpenGLTexture.RGB8U QOpenGLTexture.TextureFormat.RGB8U
+QOpenGLTexture.RGBA8U QOpenGLTexture.TextureFormat.RGBA8U
+QOpenGLTexture.R16U QOpenGLTexture.TextureFormat.R16U
+QOpenGLTexture.RG16U QOpenGLTexture.TextureFormat.RG16U
+QOpenGLTexture.RGB16U QOpenGLTexture.TextureFormat.RGB16U
+QOpenGLTexture.RGBA16U QOpenGLTexture.TextureFormat.RGBA16U
+QOpenGLTexture.R32U QOpenGLTexture.TextureFormat.R32U
+QOpenGLTexture.RG32U QOpenGLTexture.TextureFormat.RG32U
+QOpenGLTexture.RGB32U QOpenGLTexture.TextureFormat.RGB32U
+QOpenGLTexture.RGBA32U QOpenGLTexture.TextureFormat.RGBA32U
+QOpenGLTexture.R8I QOpenGLTexture.TextureFormat.R8I
+QOpenGLTexture.RG8I QOpenGLTexture.TextureFormat.RG8I
+QOpenGLTexture.RGB8I QOpenGLTexture.TextureFormat.RGB8I
+QOpenGLTexture.RGBA8I QOpenGLTexture.TextureFormat.RGBA8I
+QOpenGLTexture.R16I QOpenGLTexture.TextureFormat.R16I
+QOpenGLTexture.RG16I QOpenGLTexture.TextureFormat.RG16I
+QOpenGLTexture.RGB16I QOpenGLTexture.TextureFormat.RGB16I
+QOpenGLTexture.RGBA16I QOpenGLTexture.TextureFormat.RGBA16I
+QOpenGLTexture.R32I QOpenGLTexture.TextureFormat.R32I
+QOpenGLTexture.RG32I QOpenGLTexture.TextureFormat.RG32I
+QOpenGLTexture.RGB32I QOpenGLTexture.TextureFormat.RGB32I
+QOpenGLTexture.RGBA32I QOpenGLTexture.TextureFormat.RGBA32I
+QOpenGLTexture.R16F QOpenGLTexture.TextureFormat.R16F
+QOpenGLTexture.RG16F QOpenGLTexture.TextureFormat.RG16F
+QOpenGLTexture.RGB16F QOpenGLTexture.TextureFormat.RGB16F
+QOpenGLTexture.RGBA16F QOpenGLTexture.TextureFormat.RGBA16F
+QOpenGLTexture.R32F QOpenGLTexture.TextureFormat.R32F
+QOpenGLTexture.RG32F QOpenGLTexture.TextureFormat.RG32F
+QOpenGLTexture.RGB32F QOpenGLTexture.TextureFormat.RGB32F
+QOpenGLTexture.RGBA32F QOpenGLTexture.TextureFormat.RGBA32F
+QOpenGLTexture.RGB9E5 QOpenGLTexture.TextureFormat.RGB9E5
+QOpenGLTexture.RG11B10F QOpenGLTexture.TextureFormat.RG11B10F
+QOpenGLTexture.RG3B2 QOpenGLTexture.TextureFormat.RG3B2
+QOpenGLTexture.R5G6B5 QOpenGLTexture.TextureFormat.R5G6B5
+QOpenGLTexture.RGB5A1 QOpenGLTexture.TextureFormat.RGB5A1
+QOpenGLTexture.RGBA4 QOpenGLTexture.TextureFormat.RGBA4
+QOpenGLTexture.RGB10A2 QOpenGLTexture.TextureFormat.RGB10A2
+QOpenGLTexture.D16 QOpenGLTexture.TextureFormat.D16
+QOpenGLTexture.D24 QOpenGLTexture.TextureFormat.D24
+QOpenGLTexture.D24S8 QOpenGLTexture.TextureFormat.D24S8
+QOpenGLTexture.D32 QOpenGLTexture.TextureFormat.D32
+QOpenGLTexture.D32F QOpenGLTexture.TextureFormat.D32F
+QOpenGLTexture.D32FS8X24 QOpenGLTexture.TextureFormat.D32FS8X24
+QOpenGLTexture.RGB_DXT1 QOpenGLTexture.TextureFormat.RGB_DXT1
+QOpenGLTexture.RGBA_DXT1 QOpenGLTexture.TextureFormat.RGBA_DXT1
+QOpenGLTexture.RGBA_DXT3 QOpenGLTexture.TextureFormat.RGBA_DXT3
+QOpenGLTexture.RGBA_DXT5 QOpenGLTexture.TextureFormat.RGBA_DXT5
+QOpenGLTexture.R_ATI1N_UNorm QOpenGLTexture.TextureFormat.R_ATI1N_UNorm
+QOpenGLTexture.R_ATI1N_SNorm QOpenGLTexture.TextureFormat.R_ATI1N_SNorm
+QOpenGLTexture.RG_ATI2N_UNorm QOpenGLTexture.TextureFormat.RG_ATI2N_UNorm
+QOpenGLTexture.RG_ATI2N_SNorm QOpenGLTexture.TextureFormat.RG_ATI2N_SNorm
+QOpenGLTexture.RGB_BP_UNSIGNED_FLOAT QOpenGLTexture.TextureFormat.RGB_BP_UNSIGNED_FLOAT
+QOpenGLTexture.RGB_BP_SIGNED_FLOAT QOpenGLTexture.TextureFormat.RGB_BP_SIGNED_FLOAT
+QOpenGLTexture.RGB_BP_UNorm QOpenGLTexture.TextureFormat.RGB_BP_UNorm
+QOpenGLTexture.SRGB8 QOpenGLTexture.TextureFormat.SRGB8
+QOpenGLTexture.SRGB8_Alpha8 QOpenGLTexture.TextureFormat.SRGB8_Alpha8
+QOpenGLTexture.SRGB_DXT1 QOpenGLTexture.TextureFormat.SRGB_DXT1
+QOpenGLTexture.SRGB_Alpha_DXT1 QOpenGLTexture.TextureFormat.SRGB_Alpha_DXT1
+QOpenGLTexture.SRGB_Alpha_DXT3 QOpenGLTexture.TextureFormat.SRGB_Alpha_DXT3
+QOpenGLTexture.SRGB_Alpha_DXT5 QOpenGLTexture.TextureFormat.SRGB_Alpha_DXT5
+QOpenGLTexture.SRGB_BP_UNorm QOpenGLTexture.TextureFormat.SRGB_BP_UNorm
+QOpenGLTexture.DepthFormat QOpenGLTexture.TextureFormat.DepthFormat
+QOpenGLTexture.AlphaFormat QOpenGLTexture.TextureFormat.AlphaFormat
+QOpenGLTexture.RGBFormat QOpenGLTexture.TextureFormat.RGBFormat
+QOpenGLTexture.RGBAFormat QOpenGLTexture.TextureFormat.RGBAFormat
+QOpenGLTexture.LuminanceFormat QOpenGLTexture.TextureFormat.LuminanceFormat
+QOpenGLTexture.LuminanceAlphaFormat QOpenGLTexture.TextureFormat.LuminanceAlphaFormat
+QOpenGLTexture.S8 QOpenGLTexture.TextureFormat.S8
+QOpenGLTexture.R11_EAC_UNorm QOpenGLTexture.TextureFormat.R11_EAC_UNorm
+QOpenGLTexture.R11_EAC_SNorm QOpenGLTexture.TextureFormat.R11_EAC_SNorm
+QOpenGLTexture.RG11_EAC_UNorm QOpenGLTexture.TextureFormat.RG11_EAC_UNorm
+QOpenGLTexture.RG11_EAC_SNorm QOpenGLTexture.TextureFormat.RG11_EAC_SNorm
+QOpenGLTexture.RGB8_ETC2 QOpenGLTexture.TextureFormat.RGB8_ETC2
+QOpenGLTexture.SRGB8_ETC2 QOpenGLTexture.TextureFormat.SRGB8_ETC2
+QOpenGLTexture.RGB8_PunchThrough_Alpha1_ETC2 QOpenGLTexture.TextureFormat.RGB8_PunchThrough_Alpha1_ETC2
+QOpenGLTexture.SRGB8_PunchThrough_Alpha1_ETC2 QOpenGLTexture.TextureFormat.SRGB8_PunchThrough_Alpha1_ETC2
+QOpenGLTexture.RGBA8_ETC2_EAC QOpenGLTexture.TextureFormat.RGBA8_ETC2_EAC
+QOpenGLTexture.SRGB8_Alpha8_ETC2_EAC QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ETC2_EAC
+QOpenGLTexture.RGB8_ETC1 QOpenGLTexture.TextureFormat.RGB8_ETC1
+QOpenGLTexture.RGBA_ASTC_4x4 QOpenGLTexture.TextureFormat.RGBA_ASTC_4x4
+QOpenGLTexture.RGBA_ASTC_5x4 QOpenGLTexture.TextureFormat.RGBA_ASTC_5x4
+QOpenGLTexture.RGBA_ASTC_5x5 QOpenGLTexture.TextureFormat.RGBA_ASTC_5x5
+QOpenGLTexture.RGBA_ASTC_6x5 QOpenGLTexture.TextureFormat.RGBA_ASTC_6x5
+QOpenGLTexture.RGBA_ASTC_6x6 QOpenGLTexture.TextureFormat.RGBA_ASTC_6x6
+QOpenGLTexture.RGBA_ASTC_8x5 QOpenGLTexture.TextureFormat.RGBA_ASTC_8x5
+QOpenGLTexture.RGBA_ASTC_8x6 QOpenGLTexture.TextureFormat.RGBA_ASTC_8x6
+QOpenGLTexture.RGBA_ASTC_8x8 QOpenGLTexture.TextureFormat.RGBA_ASTC_8x8
+QOpenGLTexture.RGBA_ASTC_10x5 QOpenGLTexture.TextureFormat.RGBA_ASTC_10x5
+QOpenGLTexture.RGBA_ASTC_10x6 QOpenGLTexture.TextureFormat.RGBA_ASTC_10x6
+QOpenGLTexture.RGBA_ASTC_10x8 QOpenGLTexture.TextureFormat.RGBA_ASTC_10x8
+QOpenGLTexture.RGBA_ASTC_10x10 QOpenGLTexture.TextureFormat.RGBA_ASTC_10x10
+QOpenGLTexture.RGBA_ASTC_12x10 QOpenGLTexture.TextureFormat.RGBA_ASTC_12x10
+QOpenGLTexture.RGBA_ASTC_12x12 QOpenGLTexture.TextureFormat.RGBA_ASTC_12x12
+QOpenGLTexture.SRGB8_Alpha8_ASTC_4x4 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_4x4
+QOpenGLTexture.SRGB8_Alpha8_ASTC_5x4 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_5x4
+QOpenGLTexture.SRGB8_Alpha8_ASTC_5x5 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_5x5
+QOpenGLTexture.SRGB8_Alpha8_ASTC_6x5 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_6x5
+QOpenGLTexture.SRGB8_Alpha8_ASTC_6x6 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_6x6
+QOpenGLTexture.SRGB8_Alpha8_ASTC_8x5 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_8x5
+QOpenGLTexture.SRGB8_Alpha8_ASTC_8x6 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_8x6
+QOpenGLTexture.SRGB8_Alpha8_ASTC_8x8 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_8x8
+QOpenGLTexture.SRGB8_Alpha8_ASTC_10x5 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_10x5
+QOpenGLTexture.SRGB8_Alpha8_ASTC_10x6 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_10x6
+QOpenGLTexture.SRGB8_Alpha8_ASTC_10x8 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_10x8
+QOpenGLTexture.SRGB8_Alpha8_ASTC_10x10 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_10x10
+QOpenGLTexture.SRGB8_Alpha8_ASTC_12x10 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_12x10
+QOpenGLTexture.SRGB8_Alpha8_ASTC_12x12 QOpenGLTexture.TextureFormat.SRGB8_Alpha8_ASTC_12x12
+QOpenGLTexture.ResetTextureUnit QOpenGLTexture.TextureUnitReset.ResetTextureUnit
+QOpenGLTexture.DontResetTextureUnit QOpenGLTexture.TextureUnitReset.DontResetTextureUnit
+QOpenGLTexture.GenerateMipMaps QOpenGLTexture.MipMapGeneration.GenerateMipMaps
+QOpenGLTexture.DontGenerateMipMaps QOpenGLTexture.MipMapGeneration.DontGenerateMipMaps
+QOpenGLTexture.BindingTarget1D QOpenGLTexture.BindingTarget.BindingTarget1D
+QOpenGLTexture.BindingTarget1DArray QOpenGLTexture.BindingTarget.BindingTarget1DArray
+QOpenGLTexture.BindingTarget2D QOpenGLTexture.BindingTarget.BindingTarget2D
+QOpenGLTexture.BindingTarget2DArray QOpenGLTexture.BindingTarget.BindingTarget2DArray
+QOpenGLTexture.BindingTarget3D QOpenGLTexture.BindingTarget.BindingTarget3D
+QOpenGLTexture.BindingTargetCubeMap QOpenGLTexture.BindingTarget.BindingTargetCubeMap
+QOpenGLTexture.BindingTargetCubeMapArray QOpenGLTexture.BindingTarget.BindingTargetCubeMapArray
+QOpenGLTexture.BindingTarget2DMultisample QOpenGLTexture.BindingTarget.BindingTarget2DMultisample
+QOpenGLTexture.BindingTarget2DMultisampleArray QOpenGLTexture.BindingTarget.BindingTarget2DMultisampleArray
+QOpenGLTexture.BindingTargetRectangle QOpenGLTexture.BindingTarget.BindingTargetRectangle
+QOpenGLTexture.BindingTargetBuffer QOpenGLTexture.BindingTarget.BindingTargetBuffer
+QOpenGLTexture.Target1D QOpenGLTexture.Target.Target1D
+QOpenGLTexture.Target1DArray QOpenGLTexture.Target.Target1DArray
+QOpenGLTexture.Target2D QOpenGLTexture.Target.Target2D
+QOpenGLTexture.Target2DArray QOpenGLTexture.Target.Target2DArray
+QOpenGLTexture.Target3D QOpenGLTexture.Target.Target3D
+QOpenGLTexture.TargetCubeMap QOpenGLTexture.Target.TargetCubeMap
+QOpenGLTexture.TargetCubeMapArray QOpenGLTexture.Target.TargetCubeMapArray
+QOpenGLTexture.Target2DMultisample QOpenGLTexture.Target.Target2DMultisample
+QOpenGLTexture.Target2DMultisampleArray QOpenGLTexture.Target.Target2DMultisampleArray
+QOpenGLTexture.TargetRectangle QOpenGLTexture.Target.TargetRectangle
+QOpenGLTexture.TargetBuffer QOpenGLTexture.Target.TargetBuffer
+QOpenGLTextureBlitter.OriginBottomLeft QOpenGLTextureBlitter.Origin.OriginBottomLeft
+QOpenGLTextureBlitter.OriginTopLeft QOpenGLTextureBlitter.Origin.OriginTopLeft
+QWindow.Hidden QWindow.Visibility.Hidden
+QWindow.AutomaticVisibility QWindow.Visibility.AutomaticVisibility
+QWindow.Windowed QWindow.Visibility.Windowed
+QWindow.Minimized QWindow.Visibility.Minimized
+QWindow.Maximized QWindow.Visibility.Maximized
+QWindow.FullScreen QWindow.Visibility.FullScreen
+QWindow.ExcludeTransients QWindow.AncestorMode.ExcludeTransients
+QWindow.IncludeTransients QWindow.AncestorMode.IncludeTransients
+QOpenGLWindow.NoPartialUpdate QOpenGLWindow.UpdateBehavior.NoPartialUpdate
+QOpenGLWindow.PartialUpdateBlit QOpenGLWindow.UpdateBehavior.PartialUpdateBlit
+QOpenGLWindow.PartialUpdateBlend QOpenGLWindow.UpdateBehavior.PartialUpdateBlend
+QPagedPaintDevice.PdfVersion_1_4 QPagedPaintDevice.PdfVersion.PdfVersion_1_4
+QPagedPaintDevice.PdfVersion_A1b QPagedPaintDevice.PdfVersion.PdfVersion_A1b
+QPagedPaintDevice.PdfVersion_1_6 QPagedPaintDevice.PdfVersion.PdfVersion_1_6
+QPagedPaintDevice.A4 QPagedPaintDevice.PageSize.A4
+QPagedPaintDevice.B5 QPagedPaintDevice.PageSize.B5
+QPagedPaintDevice.Letter QPagedPaintDevice.PageSize.Letter
+QPagedPaintDevice.Legal QPagedPaintDevice.PageSize.Legal
+QPagedPaintDevice.Executive QPagedPaintDevice.PageSize.Executive
+QPagedPaintDevice.A0 QPagedPaintDevice.PageSize.A0
+QPagedPaintDevice.A1 QPagedPaintDevice.PageSize.A1
+QPagedPaintDevice.A2 QPagedPaintDevice.PageSize.A2
+QPagedPaintDevice.A3 QPagedPaintDevice.PageSize.A3
+QPagedPaintDevice.A5 QPagedPaintDevice.PageSize.A5
+QPagedPaintDevice.A6 QPagedPaintDevice.PageSize.A6
+QPagedPaintDevice.A7 QPagedPaintDevice.PageSize.A7
+QPagedPaintDevice.A8 QPagedPaintDevice.PageSize.A8
+QPagedPaintDevice.A9 QPagedPaintDevice.PageSize.A9
+QPagedPaintDevice.B0 QPagedPaintDevice.PageSize.B0
+QPagedPaintDevice.B1 QPagedPaintDevice.PageSize.B1
+QPagedPaintDevice.B10 QPagedPaintDevice.PageSize.B10
+QPagedPaintDevice.B2 QPagedPaintDevice.PageSize.B2
+QPagedPaintDevice.B3 QPagedPaintDevice.PageSize.B3
+QPagedPaintDevice.B4 QPagedPaintDevice.PageSize.B4
+QPagedPaintDevice.B6 QPagedPaintDevice.PageSize.B6
+QPagedPaintDevice.B7 QPagedPaintDevice.PageSize.B7
+QPagedPaintDevice.B8 QPagedPaintDevice.PageSize.B8
+QPagedPaintDevice.B9 QPagedPaintDevice.PageSize.B9
+QPagedPaintDevice.C5E QPagedPaintDevice.PageSize.C5E
+QPagedPaintDevice.Comm10E QPagedPaintDevice.PageSize.Comm10E
+QPagedPaintDevice.DLE QPagedPaintDevice.PageSize.DLE
+QPagedPaintDevice.Folio QPagedPaintDevice.PageSize.Folio
+QPagedPaintDevice.Ledger QPagedPaintDevice.PageSize.Ledger
+QPagedPaintDevice.Tabloid QPagedPaintDevice.PageSize.Tabloid
+QPagedPaintDevice.Custom QPagedPaintDevice.PageSize.Custom
+QPagedPaintDevice.A10 QPagedPaintDevice.PageSize.A10
+QPagedPaintDevice.A3Extra QPagedPaintDevice.PageSize.A3Extra
+QPagedPaintDevice.A4Extra QPagedPaintDevice.PageSize.A4Extra
+QPagedPaintDevice.A4Plus QPagedPaintDevice.PageSize.A4Plus
+QPagedPaintDevice.A4Small QPagedPaintDevice.PageSize.A4Small
+QPagedPaintDevice.A5Extra QPagedPaintDevice.PageSize.A5Extra
+QPagedPaintDevice.B5Extra QPagedPaintDevice.PageSize.B5Extra
+QPagedPaintDevice.JisB0 QPagedPaintDevice.PageSize.JisB0
+QPagedPaintDevice.JisB1 QPagedPaintDevice.PageSize.JisB1
+QPagedPaintDevice.JisB2 QPagedPaintDevice.PageSize.JisB2
+QPagedPaintDevice.JisB3 QPagedPaintDevice.PageSize.JisB3
+QPagedPaintDevice.JisB4 QPagedPaintDevice.PageSize.JisB4
+QPagedPaintDevice.JisB5 QPagedPaintDevice.PageSize.JisB5
+QPagedPaintDevice.JisB6 QPagedPaintDevice.PageSize.JisB6
+QPagedPaintDevice.JisB7 QPagedPaintDevice.PageSize.JisB7
+QPagedPaintDevice.JisB8 QPagedPaintDevice.PageSize.JisB8
+QPagedPaintDevice.JisB9 QPagedPaintDevice.PageSize.JisB9
+QPagedPaintDevice.JisB10 QPagedPaintDevice.PageSize.JisB10
+QPagedPaintDevice.AnsiC QPagedPaintDevice.PageSize.AnsiC
+QPagedPaintDevice.AnsiD QPagedPaintDevice.PageSize.AnsiD
+QPagedPaintDevice.AnsiE QPagedPaintDevice.PageSize.AnsiE
+QPagedPaintDevice.LegalExtra QPagedPaintDevice.PageSize.LegalExtra
+QPagedPaintDevice.LetterExtra QPagedPaintDevice.PageSize.LetterExtra
+QPagedPaintDevice.LetterPlus QPagedPaintDevice.PageSize.LetterPlus
+QPagedPaintDevice.LetterSmall QPagedPaintDevice.PageSize.LetterSmall
+QPagedPaintDevice.TabloidExtra QPagedPaintDevice.PageSize.TabloidExtra
+QPagedPaintDevice.ArchA QPagedPaintDevice.PageSize.ArchA
+QPagedPaintDevice.ArchB QPagedPaintDevice.PageSize.ArchB
+QPagedPaintDevice.ArchC QPagedPaintDevice.PageSize.ArchC
+QPagedPaintDevice.ArchD QPagedPaintDevice.PageSize.ArchD
+QPagedPaintDevice.ArchE QPagedPaintDevice.PageSize.ArchE
+QPagedPaintDevice.Imperial7x9 QPagedPaintDevice.PageSize.Imperial7x9
+QPagedPaintDevice.Imperial8x10 QPagedPaintDevice.PageSize.Imperial8x10
+QPagedPaintDevice.Imperial9x11 QPagedPaintDevice.PageSize.Imperial9x11
+QPagedPaintDevice.Imperial9x12 QPagedPaintDevice.PageSize.Imperial9x12
+QPagedPaintDevice.Imperial10x11 QPagedPaintDevice.PageSize.Imperial10x11
+QPagedPaintDevice.Imperial10x13 QPagedPaintDevice.PageSize.Imperial10x13
+QPagedPaintDevice.Imperial10x14 QPagedPaintDevice.PageSize.Imperial10x14
+QPagedPaintDevice.Imperial12x11 QPagedPaintDevice.PageSize.Imperial12x11
+QPagedPaintDevice.Imperial15x11 QPagedPaintDevice.PageSize.Imperial15x11
+QPagedPaintDevice.ExecutiveStandard QPagedPaintDevice.PageSize.ExecutiveStandard
+QPagedPaintDevice.Note QPagedPaintDevice.PageSize.Note
+QPagedPaintDevice.Quarto QPagedPaintDevice.PageSize.Quarto
+QPagedPaintDevice.Statement QPagedPaintDevice.PageSize.Statement
+QPagedPaintDevice.SuperA QPagedPaintDevice.PageSize.SuperA
+QPagedPaintDevice.SuperB QPagedPaintDevice.PageSize.SuperB
+QPagedPaintDevice.Postcard QPagedPaintDevice.PageSize.Postcard
+QPagedPaintDevice.DoublePostcard QPagedPaintDevice.PageSize.DoublePostcard
+QPagedPaintDevice.Prc16K QPagedPaintDevice.PageSize.Prc16K
+QPagedPaintDevice.Prc32K QPagedPaintDevice.PageSize.Prc32K
+QPagedPaintDevice.Prc32KBig QPagedPaintDevice.PageSize.Prc32KBig
+QPagedPaintDevice.FanFoldUS QPagedPaintDevice.PageSize.FanFoldUS
+QPagedPaintDevice.FanFoldGerman QPagedPaintDevice.PageSize.FanFoldGerman
+QPagedPaintDevice.FanFoldGermanLegal QPagedPaintDevice.PageSize.FanFoldGermanLegal
+QPagedPaintDevice.EnvelopeB4 QPagedPaintDevice.PageSize.EnvelopeB4
+QPagedPaintDevice.EnvelopeB5 QPagedPaintDevice.PageSize.EnvelopeB5
+QPagedPaintDevice.EnvelopeB6 QPagedPaintDevice.PageSize.EnvelopeB6
+QPagedPaintDevice.EnvelopeC0 QPagedPaintDevice.PageSize.EnvelopeC0
+QPagedPaintDevice.EnvelopeC1 QPagedPaintDevice.PageSize.EnvelopeC1
+QPagedPaintDevice.EnvelopeC2 QPagedPaintDevice.PageSize.EnvelopeC2
+QPagedPaintDevice.EnvelopeC3 QPagedPaintDevice.PageSize.EnvelopeC3
+QPagedPaintDevice.EnvelopeC4 QPagedPaintDevice.PageSize.EnvelopeC4
+QPagedPaintDevice.EnvelopeC6 QPagedPaintDevice.PageSize.EnvelopeC6
+QPagedPaintDevice.EnvelopeC65 QPagedPaintDevice.PageSize.EnvelopeC65
+QPagedPaintDevice.EnvelopeC7 QPagedPaintDevice.PageSize.EnvelopeC7
+QPagedPaintDevice.Envelope9 QPagedPaintDevice.PageSize.Envelope9
+QPagedPaintDevice.Envelope11 QPagedPaintDevice.PageSize.Envelope11
+QPagedPaintDevice.Envelope12 QPagedPaintDevice.PageSize.Envelope12
+QPagedPaintDevice.Envelope14 QPagedPaintDevice.PageSize.Envelope14
+QPagedPaintDevice.EnvelopeMonarch QPagedPaintDevice.PageSize.EnvelopeMonarch
+QPagedPaintDevice.EnvelopePersonal QPagedPaintDevice.PageSize.EnvelopePersonal
+QPagedPaintDevice.EnvelopeChou3 QPagedPaintDevice.PageSize.EnvelopeChou3
+QPagedPaintDevice.EnvelopeChou4 QPagedPaintDevice.PageSize.EnvelopeChou4
+QPagedPaintDevice.EnvelopeInvite QPagedPaintDevice.PageSize.EnvelopeInvite
+QPagedPaintDevice.EnvelopeItalian QPagedPaintDevice.PageSize.EnvelopeItalian
+QPagedPaintDevice.EnvelopeKaku2 QPagedPaintDevice.PageSize.EnvelopeKaku2
+QPagedPaintDevice.EnvelopeKaku3 QPagedPaintDevice.PageSize.EnvelopeKaku3
+QPagedPaintDevice.EnvelopePrc1 QPagedPaintDevice.PageSize.EnvelopePrc1
+QPagedPaintDevice.EnvelopePrc2 QPagedPaintDevice.PageSize.EnvelopePrc2
+QPagedPaintDevice.EnvelopePrc3 QPagedPaintDevice.PageSize.EnvelopePrc3
+QPagedPaintDevice.EnvelopePrc4 QPagedPaintDevice.PageSize.EnvelopePrc4
+QPagedPaintDevice.EnvelopePrc5 QPagedPaintDevice.PageSize.EnvelopePrc5
+QPagedPaintDevice.EnvelopePrc6 QPagedPaintDevice.PageSize.EnvelopePrc6
+QPagedPaintDevice.EnvelopePrc7 QPagedPaintDevice.PageSize.EnvelopePrc7
+QPagedPaintDevice.EnvelopePrc8 QPagedPaintDevice.PageSize.EnvelopePrc8
+QPagedPaintDevice.EnvelopePrc9 QPagedPaintDevice.PageSize.EnvelopePrc9
+QPagedPaintDevice.EnvelopePrc10 QPagedPaintDevice.PageSize.EnvelopePrc10
+QPagedPaintDevice.EnvelopeYou4 QPagedPaintDevice.PageSize.EnvelopeYou4
+QPagedPaintDevice.NPaperSize QPagedPaintDevice.PageSize.NPaperSize
+QPagedPaintDevice.AnsiA QPagedPaintDevice.PageSize.AnsiA
+QPagedPaintDevice.AnsiB QPagedPaintDevice.PageSize.AnsiB
+QPagedPaintDevice.EnvelopeC5 QPagedPaintDevice.PageSize.EnvelopeC5
+QPagedPaintDevice.EnvelopeDL QPagedPaintDevice.PageSize.EnvelopeDL
+QPagedPaintDevice.Envelope10 QPagedPaintDevice.PageSize.Envelope10
+QPagedPaintDevice.LastPageSize QPagedPaintDevice.PageSize.LastPageSize
+QPageLayout.StandardMode QPageLayout.Mode.StandardMode
+QPageLayout.FullPageMode QPageLayout.Mode.FullPageMode
+QPageLayout.Portrait QPageLayout.Orientation.Portrait
+QPageLayout.Landscape QPageLayout.Orientation.Landscape
+QPageLayout.Millimeter QPageLayout.Unit.Millimeter
+QPageLayout.Point QPageLayout.Unit.Point
+QPageLayout.Inch QPageLayout.Unit.Inch
+QPageLayout.Pica QPageLayout.Unit.Pica
+QPageLayout.Didot QPageLayout.Unit.Didot
+QPageLayout.Cicero QPageLayout.Unit.Cicero
+QPageSize.FuzzyMatch QPageSize.SizeMatchPolicy.FuzzyMatch
+QPageSize.FuzzyOrientationMatch QPageSize.SizeMatchPolicy.FuzzyOrientationMatch
+QPageSize.ExactMatch QPageSize.SizeMatchPolicy.ExactMatch
+QPageSize.Millimeter QPageSize.Unit.Millimeter
+QPageSize.Point QPageSize.Unit.Point
+QPageSize.Inch QPageSize.Unit.Inch
+QPageSize.Pica QPageSize.Unit.Pica
+QPageSize.Didot QPageSize.Unit.Didot
+QPageSize.Cicero QPageSize.Unit.Cicero
+QPageSize.A4 QPageSize.PageSizeId.A4
+QPageSize.B5 QPageSize.PageSizeId.B5
+QPageSize.Letter QPageSize.PageSizeId.Letter
+QPageSize.Legal QPageSize.PageSizeId.Legal
+QPageSize.Executive QPageSize.PageSizeId.Executive
+QPageSize.A0 QPageSize.PageSizeId.A0
+QPageSize.A1 QPageSize.PageSizeId.A1
+QPageSize.A2 QPageSize.PageSizeId.A2
+QPageSize.A3 QPageSize.PageSizeId.A3
+QPageSize.A5 QPageSize.PageSizeId.A5
+QPageSize.A6 QPageSize.PageSizeId.A6
+QPageSize.A7 QPageSize.PageSizeId.A7
+QPageSize.A8 QPageSize.PageSizeId.A8
+QPageSize.A9 QPageSize.PageSizeId.A9
+QPageSize.B0 QPageSize.PageSizeId.B0
+QPageSize.B1 QPageSize.PageSizeId.B1
+QPageSize.B10 QPageSize.PageSizeId.B10
+QPageSize.B2 QPageSize.PageSizeId.B2
+QPageSize.B3 QPageSize.PageSizeId.B3
+QPageSize.B4 QPageSize.PageSizeId.B4
+QPageSize.B6 QPageSize.PageSizeId.B6
+QPageSize.B7 QPageSize.PageSizeId.B7
+QPageSize.B8 QPageSize.PageSizeId.B8
+QPageSize.B9 QPageSize.PageSizeId.B9
+QPageSize.C5E QPageSize.PageSizeId.C5E
+QPageSize.Comm10E QPageSize.PageSizeId.Comm10E
+QPageSize.DLE QPageSize.PageSizeId.DLE
+QPageSize.Folio QPageSize.PageSizeId.Folio
+QPageSize.Ledger QPageSize.PageSizeId.Ledger
+QPageSize.Tabloid QPageSize.PageSizeId.Tabloid
+QPageSize.Custom QPageSize.PageSizeId.Custom
+QPageSize.A10 QPageSize.PageSizeId.A10
+QPageSize.A3Extra QPageSize.PageSizeId.A3Extra
+QPageSize.A4Extra QPageSize.PageSizeId.A4Extra
+QPageSize.A4Plus QPageSize.PageSizeId.A4Plus
+QPageSize.A4Small QPageSize.PageSizeId.A4Small
+QPageSize.A5Extra QPageSize.PageSizeId.A5Extra
+QPageSize.B5Extra QPageSize.PageSizeId.B5Extra
+QPageSize.JisB0 QPageSize.PageSizeId.JisB0
+QPageSize.JisB1 QPageSize.PageSizeId.JisB1
+QPageSize.JisB2 QPageSize.PageSizeId.JisB2
+QPageSize.JisB3 QPageSize.PageSizeId.JisB3
+QPageSize.JisB4 QPageSize.PageSizeId.JisB4
+QPageSize.JisB5 QPageSize.PageSizeId.JisB5
+QPageSize.JisB6 QPageSize.PageSizeId.JisB6
+QPageSize.JisB7 QPageSize.PageSizeId.JisB7
+QPageSize.JisB8 QPageSize.PageSizeId.JisB8
+QPageSize.JisB9 QPageSize.PageSizeId.JisB9
+QPageSize.JisB10 QPageSize.PageSizeId.JisB10
+QPageSize.AnsiC QPageSize.PageSizeId.AnsiC
+QPageSize.AnsiD QPageSize.PageSizeId.AnsiD
+QPageSize.AnsiE QPageSize.PageSizeId.AnsiE
+QPageSize.LegalExtra QPageSize.PageSizeId.LegalExtra
+QPageSize.LetterExtra QPageSize.PageSizeId.LetterExtra
+QPageSize.LetterPlus QPageSize.PageSizeId.LetterPlus
+QPageSize.LetterSmall QPageSize.PageSizeId.LetterSmall
+QPageSize.TabloidExtra QPageSize.PageSizeId.TabloidExtra
+QPageSize.ArchA QPageSize.PageSizeId.ArchA
+QPageSize.ArchB QPageSize.PageSizeId.ArchB
+QPageSize.ArchC QPageSize.PageSizeId.ArchC
+QPageSize.ArchD QPageSize.PageSizeId.ArchD
+QPageSize.ArchE QPageSize.PageSizeId.ArchE
+QPageSize.Imperial7x9 QPageSize.PageSizeId.Imperial7x9
+QPageSize.Imperial8x10 QPageSize.PageSizeId.Imperial8x10
+QPageSize.Imperial9x11 QPageSize.PageSizeId.Imperial9x11
+QPageSize.Imperial9x12 QPageSize.PageSizeId.Imperial9x12
+QPageSize.Imperial10x11 QPageSize.PageSizeId.Imperial10x11
+QPageSize.Imperial10x13 QPageSize.PageSizeId.Imperial10x13
+QPageSize.Imperial10x14 QPageSize.PageSizeId.Imperial10x14
+QPageSize.Imperial12x11 QPageSize.PageSizeId.Imperial12x11
+QPageSize.Imperial15x11 QPageSize.PageSizeId.Imperial15x11
+QPageSize.ExecutiveStandard QPageSize.PageSizeId.ExecutiveStandard
+QPageSize.Note QPageSize.PageSizeId.Note
+QPageSize.Quarto QPageSize.PageSizeId.Quarto
+QPageSize.Statement QPageSize.PageSizeId.Statement
+QPageSize.SuperA QPageSize.PageSizeId.SuperA
+QPageSize.SuperB QPageSize.PageSizeId.SuperB
+QPageSize.Postcard QPageSize.PageSizeId.Postcard
+QPageSize.DoublePostcard QPageSize.PageSizeId.DoublePostcard
+QPageSize.Prc16K QPageSize.PageSizeId.Prc16K
+QPageSize.Prc32K QPageSize.PageSizeId.Prc32K
+QPageSize.Prc32KBig QPageSize.PageSizeId.Prc32KBig
+QPageSize.FanFoldUS QPageSize.PageSizeId.FanFoldUS
+QPageSize.FanFoldGerman QPageSize.PageSizeId.FanFoldGerman
+QPageSize.FanFoldGermanLegal QPageSize.PageSizeId.FanFoldGermanLegal
+QPageSize.EnvelopeB4 QPageSize.PageSizeId.EnvelopeB4
+QPageSize.EnvelopeB5 QPageSize.PageSizeId.EnvelopeB5
+QPageSize.EnvelopeB6 QPageSize.PageSizeId.EnvelopeB6
+QPageSize.EnvelopeC0 QPageSize.PageSizeId.EnvelopeC0
+QPageSize.EnvelopeC1 QPageSize.PageSizeId.EnvelopeC1
+QPageSize.EnvelopeC2 QPageSize.PageSizeId.EnvelopeC2
+QPageSize.EnvelopeC3 QPageSize.PageSizeId.EnvelopeC3
+QPageSize.EnvelopeC4 QPageSize.PageSizeId.EnvelopeC4
+QPageSize.EnvelopeC6 QPageSize.PageSizeId.EnvelopeC6
+QPageSize.EnvelopeC65 QPageSize.PageSizeId.EnvelopeC65
+QPageSize.EnvelopeC7 QPageSize.PageSizeId.EnvelopeC7
+QPageSize.Envelope9 QPageSize.PageSizeId.Envelope9
+QPageSize.Envelope11 QPageSize.PageSizeId.Envelope11
+QPageSize.Envelope12 QPageSize.PageSizeId.Envelope12
+QPageSize.Envelope14 QPageSize.PageSizeId.Envelope14
+QPageSize.EnvelopeMonarch QPageSize.PageSizeId.EnvelopeMonarch
+QPageSize.EnvelopePersonal QPageSize.PageSizeId.EnvelopePersonal
+QPageSize.EnvelopeChou3 QPageSize.PageSizeId.EnvelopeChou3
+QPageSize.EnvelopeChou4 QPageSize.PageSizeId.EnvelopeChou4
+QPageSize.EnvelopeInvite QPageSize.PageSizeId.EnvelopeInvite
+QPageSize.EnvelopeItalian QPageSize.PageSizeId.EnvelopeItalian
+QPageSize.EnvelopeKaku2 QPageSize.PageSizeId.EnvelopeKaku2
+QPageSize.EnvelopeKaku3 QPageSize.PageSizeId.EnvelopeKaku3
+QPageSize.EnvelopePrc1 QPageSize.PageSizeId.EnvelopePrc1
+QPageSize.EnvelopePrc2 QPageSize.PageSizeId.EnvelopePrc2
+QPageSize.EnvelopePrc3 QPageSize.PageSizeId.EnvelopePrc3
+QPageSize.EnvelopePrc4 QPageSize.PageSizeId.EnvelopePrc4
+QPageSize.EnvelopePrc5 QPageSize.PageSizeId.EnvelopePrc5
+QPageSize.EnvelopePrc6 QPageSize.PageSizeId.EnvelopePrc6
+QPageSize.EnvelopePrc7 QPageSize.PageSizeId.EnvelopePrc7
+QPageSize.EnvelopePrc8 QPageSize.PageSizeId.EnvelopePrc8
+QPageSize.EnvelopePrc9 QPageSize.PageSizeId.EnvelopePrc9
+QPageSize.EnvelopePrc10 QPageSize.PageSizeId.EnvelopePrc10
+QPageSize.EnvelopeYou4 QPageSize.PageSizeId.EnvelopeYou4
+QPageSize.NPageSize QPageSize.PageSizeId.NPageSize
+QPageSize.NPaperSize QPageSize.PageSizeId.NPaperSize
+QPageSize.AnsiA QPageSize.PageSizeId.AnsiA
+QPageSize.AnsiB QPageSize.PageSizeId.AnsiB
+QPageSize.EnvelopeC5 QPageSize.PageSizeId.EnvelopeC5
+QPageSize.EnvelopeDL QPageSize.PageSizeId.EnvelopeDL
+QPageSize.Envelope10 QPageSize.PageSizeId.Envelope10
+QPageSize.LastPageSize QPageSize.PageSizeId.LastPageSize
+QPainter.OpaqueHint QPainter.PixmapFragmentHint.OpaqueHint
+QPainter.CompositionMode_SourceOver QPainter.CompositionMode.CompositionMode_SourceOver
+QPainter.CompositionMode_DestinationOver QPainter.CompositionMode.CompositionMode_DestinationOver
+QPainter.CompositionMode_Clear QPainter.CompositionMode.CompositionMode_Clear
+QPainter.CompositionMode_Source QPainter.CompositionMode.CompositionMode_Source
+QPainter.CompositionMode_Destination QPainter.CompositionMode.CompositionMode_Destination
+QPainter.CompositionMode_SourceIn QPainter.CompositionMode.CompositionMode_SourceIn
+QPainter.CompositionMode_DestinationIn QPainter.CompositionMode.CompositionMode_DestinationIn
+QPainter.CompositionMode_SourceOut QPainter.CompositionMode.CompositionMode_SourceOut
+QPainter.CompositionMode_DestinationOut QPainter.CompositionMode.CompositionMode_DestinationOut
+QPainter.CompositionMode_SourceAtop QPainter.CompositionMode.CompositionMode_SourceAtop
+QPainter.CompositionMode_DestinationAtop QPainter.CompositionMode.CompositionMode_DestinationAtop
+QPainter.CompositionMode_Xor QPainter.CompositionMode.CompositionMode_Xor
+QPainter.CompositionMode_Plus QPainter.CompositionMode.CompositionMode_Plus
+QPainter.CompositionMode_Multiply QPainter.CompositionMode.CompositionMode_Multiply
+QPainter.CompositionMode_Screen QPainter.CompositionMode.CompositionMode_Screen
+QPainter.CompositionMode_Overlay QPainter.CompositionMode.CompositionMode_Overlay
+QPainter.CompositionMode_Darken QPainter.CompositionMode.CompositionMode_Darken
+QPainter.CompositionMode_Lighten QPainter.CompositionMode.CompositionMode_Lighten
+QPainter.CompositionMode_ColorDodge QPainter.CompositionMode.CompositionMode_ColorDodge
+QPainter.CompositionMode_ColorBurn QPainter.CompositionMode.CompositionMode_ColorBurn
+QPainter.CompositionMode_HardLight QPainter.CompositionMode.CompositionMode_HardLight
+QPainter.CompositionMode_SoftLight QPainter.CompositionMode.CompositionMode_SoftLight
+QPainter.CompositionMode_Difference QPainter.CompositionMode.CompositionMode_Difference
+QPainter.CompositionMode_Exclusion QPainter.CompositionMode.CompositionMode_Exclusion
+QPainter.RasterOp_SourceOrDestination QPainter.CompositionMode.RasterOp_SourceOrDestination
+QPainter.RasterOp_SourceAndDestination QPainter.CompositionMode.RasterOp_SourceAndDestination
+QPainter.RasterOp_SourceXorDestination QPainter.CompositionMode.RasterOp_SourceXorDestination
+QPainter.RasterOp_NotSourceAndNotDestination QPainter.CompositionMode.RasterOp_NotSourceAndNotDestination
+QPainter.RasterOp_NotSourceOrNotDestination QPainter.CompositionMode.RasterOp_NotSourceOrNotDestination
+QPainter.RasterOp_NotSourceXorDestination QPainter.CompositionMode.RasterOp_NotSourceXorDestination
+QPainter.RasterOp_NotSource QPainter.CompositionMode.RasterOp_NotSource
+QPainter.RasterOp_NotSourceAndDestination QPainter.CompositionMode.RasterOp_NotSourceAndDestination
+QPainter.RasterOp_SourceAndNotDestination QPainter.CompositionMode.RasterOp_SourceAndNotDestination
+QPainter.RasterOp_NotSourceOrDestination QPainter.CompositionMode.RasterOp_NotSourceOrDestination
+QPainter.RasterOp_SourceOrNotDestination QPainter.CompositionMode.RasterOp_SourceOrNotDestination
+QPainter.RasterOp_ClearDestination QPainter.CompositionMode.RasterOp_ClearDestination
+QPainter.RasterOp_SetDestination QPainter.CompositionMode.RasterOp_SetDestination
+QPainter.RasterOp_NotDestination QPainter.CompositionMode.RasterOp_NotDestination
+QPainter.Antialiasing QPainter.RenderHint.Antialiasing
+QPainter.TextAntialiasing QPainter.RenderHint.TextAntialiasing
+QPainter.SmoothPixmapTransform QPainter.RenderHint.SmoothPixmapTransform
+QPainter.HighQualityAntialiasing QPainter.RenderHint.HighQualityAntialiasing
+QPainter.NonCosmeticDefaultPen QPainter.RenderHint.NonCosmeticDefaultPen
+QPainter.Qt4CompatiblePainting QPainter.RenderHint.Qt4CompatiblePainting
+QPainter.LosslessImageRendering QPainter.RenderHint.LosslessImageRendering
+QTextItem.RightToLeft QTextItem.RenderFlag.RightToLeft
+QTextItem.Overline QTextItem.RenderFlag.Overline
+QTextItem.Underline QTextItem.RenderFlag.Underline
+QTextItem.StrikeOut QTextItem.RenderFlag.StrikeOut
+QPaintEngine.X11 QPaintEngine.Type.X11
+QPaintEngine.Windows QPaintEngine.Type.Windows
+QPaintEngine.QuickDraw QPaintEngine.Type.QuickDraw
+QPaintEngine.CoreGraphics QPaintEngine.Type.CoreGraphics
+QPaintEngine.MacPrinter QPaintEngine.Type.MacPrinter
+QPaintEngine.QWindowSystem QPaintEngine.Type.QWindowSystem
+QPaintEngine.PostScript QPaintEngine.Type.PostScript
+QPaintEngine.OpenGL QPaintEngine.Type.OpenGL
+QPaintEngine.Picture QPaintEngine.Type.Picture
+QPaintEngine.SVG QPaintEngine.Type.SVG
+QPaintEngine.Raster QPaintEngine.Type.Raster
+QPaintEngine.Direct3D QPaintEngine.Type.Direct3D
+QPaintEngine.Pdf QPaintEngine.Type.Pdf
+QPaintEngine.OpenVG QPaintEngine.Type.OpenVG
+QPaintEngine.OpenGL2 QPaintEngine.Type.OpenGL2
+QPaintEngine.PaintBuffer QPaintEngine.Type.PaintBuffer
+QPaintEngine.Blitter QPaintEngine.Type.Blitter
+QPaintEngine.Direct2D QPaintEngine.Type.Direct2D
+QPaintEngine.User QPaintEngine.Type.User
+QPaintEngine.MaxUser QPaintEngine.Type.MaxUser
+QPaintEngine.OddEvenMode QPaintEngine.PolygonDrawMode.OddEvenMode
+QPaintEngine.WindingMode QPaintEngine.PolygonDrawMode.WindingMode
+QPaintEngine.ConvexMode QPaintEngine.PolygonDrawMode.ConvexMode
+QPaintEngine.PolylineMode QPaintEngine.PolygonDrawMode.PolylineMode
+QPaintEngine.DirtyPen QPaintEngine.DirtyFlag.DirtyPen
+QPaintEngine.DirtyBrush QPaintEngine.DirtyFlag.DirtyBrush
+QPaintEngine.DirtyBrushOrigin QPaintEngine.DirtyFlag.DirtyBrushOrigin
+QPaintEngine.DirtyFont QPaintEngine.DirtyFlag.DirtyFont
+QPaintEngine.DirtyBackground QPaintEngine.DirtyFlag.DirtyBackground
+QPaintEngine.DirtyBackgroundMode QPaintEngine.DirtyFlag.DirtyBackgroundMode
+QPaintEngine.DirtyTransform QPaintEngine.DirtyFlag.DirtyTransform
+QPaintEngine.DirtyClipRegion QPaintEngine.DirtyFlag.DirtyClipRegion
+QPaintEngine.DirtyClipPath QPaintEngine.DirtyFlag.DirtyClipPath
+QPaintEngine.DirtyHints QPaintEngine.DirtyFlag.DirtyHints
+QPaintEngine.DirtyCompositionMode QPaintEngine.DirtyFlag.DirtyCompositionMode
+QPaintEngine.DirtyClipEnabled QPaintEngine.DirtyFlag.DirtyClipEnabled
+QPaintEngine.DirtyOpacity QPaintEngine.DirtyFlag.DirtyOpacity
+QPaintEngine.AllDirty QPaintEngine.DirtyFlag.AllDirty
+QPaintEngine.PrimitiveTransform QPaintEngine.PaintEngineFeature.PrimitiveTransform
+QPaintEngine.PatternTransform QPaintEngine.PaintEngineFeature.PatternTransform
+QPaintEngine.PixmapTransform QPaintEngine.PaintEngineFeature.PixmapTransform
+QPaintEngine.PatternBrush QPaintEngine.PaintEngineFeature.PatternBrush
+QPaintEngine.LinearGradientFill QPaintEngine.PaintEngineFeature.LinearGradientFill
+QPaintEngine.RadialGradientFill QPaintEngine.PaintEngineFeature.RadialGradientFill
+QPaintEngine.ConicalGradientFill QPaintEngine.PaintEngineFeature.ConicalGradientFill
+QPaintEngine.AlphaBlend QPaintEngine.PaintEngineFeature.AlphaBlend
+QPaintEngine.PorterDuff QPaintEngine.PaintEngineFeature.PorterDuff
+QPaintEngine.PainterPaths QPaintEngine.PaintEngineFeature.PainterPaths
+QPaintEngine.Antialiasing QPaintEngine.PaintEngineFeature.Antialiasing
+QPaintEngine.BrushStroke QPaintEngine.PaintEngineFeature.BrushStroke
+QPaintEngine.ConstantOpacity QPaintEngine.PaintEngineFeature.ConstantOpacity
+QPaintEngine.MaskedBrush QPaintEngine.PaintEngineFeature.MaskedBrush
+QPaintEngine.PaintOutsidePaintEvent QPaintEngine.PaintEngineFeature.PaintOutsidePaintEvent
+QPaintEngine.PerspectiveTransform QPaintEngine.PaintEngineFeature.PerspectiveTransform
+QPaintEngine.BlendModes QPaintEngine.PaintEngineFeature.BlendModes
+QPaintEngine.ObjectBoundingModeGradients QPaintEngine.PaintEngineFeature.ObjectBoundingModeGradients
+QPaintEngine.RasterOpModes QPaintEngine.PaintEngineFeature.RasterOpModes
+QPaintEngine.AllFeatures QPaintEngine.PaintEngineFeature.AllFeatures
+QPainterPath.MoveToElement QPainterPath.ElementType.MoveToElement
+QPainterPath.LineToElement QPainterPath.ElementType.LineToElement
+QPainterPath.CurveToElement QPainterPath.ElementType.CurveToElement
+QPainterPath.CurveToDataElement QPainterPath.ElementType.CurveToDataElement
+QPalette.WindowText QPalette.ColorRole.WindowText
+QPalette.Foreground QPalette.ColorRole.Foreground
+QPalette.Button QPalette.ColorRole.Button
+QPalette.Light QPalette.ColorRole.Light
+QPalette.Midlight QPalette.ColorRole.Midlight
+QPalette.Dark QPalette.ColorRole.Dark
+QPalette.Mid QPalette.ColorRole.Mid
+QPalette.Text QPalette.ColorRole.Text
+QPalette.BrightText QPalette.ColorRole.BrightText
+QPalette.ButtonText QPalette.ColorRole.ButtonText
+QPalette.Base QPalette.ColorRole.Base
+QPalette.Window QPalette.ColorRole.Window
+QPalette.Background QPalette.ColorRole.Background
+QPalette.Shadow QPalette.ColorRole.Shadow
+QPalette.Highlight QPalette.ColorRole.Highlight
+QPalette.HighlightedText QPalette.ColorRole.HighlightedText
+QPalette.Link QPalette.ColorRole.Link
+QPalette.LinkVisited QPalette.ColorRole.LinkVisited
+QPalette.AlternateBase QPalette.ColorRole.AlternateBase
+QPalette.ToolTipBase QPalette.ColorRole.ToolTipBase
+QPalette.ToolTipText QPalette.ColorRole.ToolTipText
+QPalette.PlaceholderText QPalette.ColorRole.PlaceholderText
+QPalette.NoRole QPalette.ColorRole.NoRole
+QPalette.NColorRoles QPalette.ColorRole.NColorRoles
+QPalette.Active QPalette.ColorGroup.Active
+QPalette.Disabled QPalette.ColorGroup.Disabled
+QPalette.Inactive QPalette.ColorGroup.Inactive
+QPalette.NColorGroups QPalette.ColorGroup.NColorGroups
+QPalette.Current QPalette.ColorGroup.Current
+QPalette.All QPalette.ColorGroup.All
+QPalette.Normal QPalette.ColorGroup.Normal
+QPixelFormat.LittleEndian QPixelFormat.ByteOrder.LittleEndian
+QPixelFormat.BigEndian QPixelFormat.ByteOrder.BigEndian
+QPixelFormat.CurrentSystemEndian QPixelFormat.ByteOrder.CurrentSystemEndian
+QPixelFormat.YUV444 QPixelFormat.YUVLayout.YUV444
+QPixelFormat.YUV422 QPixelFormat.YUVLayout.YUV422
+QPixelFormat.YUV411 QPixelFormat.YUVLayout.YUV411
+QPixelFormat.YUV420P QPixelFormat.YUVLayout.YUV420P
+QPixelFormat.YUV420SP QPixelFormat.YUVLayout.YUV420SP
+QPixelFormat.YV12 QPixelFormat.YUVLayout.YV12
+QPixelFormat.UYVY QPixelFormat.YUVLayout.UYVY
+QPixelFormat.YUYV QPixelFormat.YUVLayout.YUYV
+QPixelFormat.NV12 QPixelFormat.YUVLayout.NV12
+QPixelFormat.NV21 QPixelFormat.YUVLayout.NV21
+QPixelFormat.IMC1 QPixelFormat.YUVLayout.IMC1
+QPixelFormat.IMC2 QPixelFormat.YUVLayout.IMC2
+QPixelFormat.IMC3 QPixelFormat.YUVLayout.IMC3
+QPixelFormat.IMC4 QPixelFormat.YUVLayout.IMC4
+QPixelFormat.Y8 QPixelFormat.YUVLayout.Y8
+QPixelFormat.Y16 QPixelFormat.YUVLayout.Y16
+QPixelFormat.UnsignedInteger QPixelFormat.TypeInterpretation.UnsignedInteger
+QPixelFormat.UnsignedShort QPixelFormat.TypeInterpretation.UnsignedShort
+QPixelFormat.UnsignedByte QPixelFormat.TypeInterpretation.UnsignedByte
+QPixelFormat.FloatingPoint QPixelFormat.TypeInterpretation.FloatingPoint
+QPixelFormat.NotPremultiplied QPixelFormat.AlphaPremultiplied.NotPremultiplied
+QPixelFormat.Premultiplied QPixelFormat.AlphaPremultiplied.Premultiplied
+QPixelFormat.AtBeginning QPixelFormat.AlphaPosition.AtBeginning
+QPixelFormat.AtEnd QPixelFormat.AlphaPosition.AtEnd
+QPixelFormat.UsesAlpha QPixelFormat.AlphaUsage.UsesAlpha
+QPixelFormat.IgnoresAlpha QPixelFormat.AlphaUsage.IgnoresAlpha
+QPixelFormat.RGB QPixelFormat.ColorModel.RGB
+QPixelFormat.BGR QPixelFormat.ColorModel.BGR
+QPixelFormat.Indexed QPixelFormat.ColorModel.Indexed
+QPixelFormat.Grayscale QPixelFormat.ColorModel.Grayscale
+QPixelFormat.CMYK QPixelFormat.ColorModel.CMYK
+QPixelFormat.HSL QPixelFormat.ColorModel.HSL
+QPixelFormat.HSV QPixelFormat.ColorModel.HSV
+QPixelFormat.YUV QPixelFormat.ColorModel.YUV
+QPixelFormat.Alpha QPixelFormat.ColorModel.Alpha
+QRawFont.SeparateAdvances QRawFont.LayoutFlag.SeparateAdvances
+QRawFont.KernedAdvances QRawFont.LayoutFlag.KernedAdvances
+QRawFont.UseDesignMetrics QRawFont.LayoutFlag.UseDesignMetrics
+QRawFont.PixelAntialiasing QRawFont.AntialiasingType.PixelAntialiasing
+QRawFont.SubPixelAntialiasing QRawFont.AntialiasingType.SubPixelAntialiasing
+QRegion.Rectangle QRegion.RegionType.Rectangle
+QRegion.Ellipse QRegion.RegionType.Ellipse
+QSessionManager.RestartIfRunning QSessionManager.RestartHint.RestartIfRunning
+QSessionManager.RestartAnyway QSessionManager.RestartHint.RestartAnyway
+QSessionManager.RestartImmediately QSessionManager.RestartHint.RestartImmediately
+QSessionManager.RestartNever QSessionManager.RestartHint.RestartNever
+QStandardItem.Type QStandardItem.ItemType.Type
+QStandardItem.UserType QStandardItem.ItemType.UserType
+QStaticText.ModerateCaching QStaticText.PerformanceHint.ModerateCaching
+QStaticText.AggressiveCaching QStaticText.PerformanceHint.AggressiveCaching
+QSurfaceFormat.DefaultColorSpace QSurfaceFormat.ColorSpace.DefaultColorSpace
+QSurfaceFormat.sRGBColorSpace QSurfaceFormat.ColorSpace.sRGBColorSpace
+QSurfaceFormat.NoProfile QSurfaceFormat.OpenGLContextProfile.NoProfile
+QSurfaceFormat.CoreProfile QSurfaceFormat.OpenGLContextProfile.CoreProfile
+QSurfaceFormat.CompatibilityProfile QSurfaceFormat.OpenGLContextProfile.CompatibilityProfile
+QSurfaceFormat.DefaultRenderableType QSurfaceFormat.RenderableType.DefaultRenderableType
+QSurfaceFormat.OpenGL QSurfaceFormat.RenderableType.OpenGL
+QSurfaceFormat.OpenGLES QSurfaceFormat.RenderableType.OpenGLES
+QSurfaceFormat.OpenVG QSurfaceFormat.RenderableType.OpenVG
+QSurfaceFormat.DefaultSwapBehavior QSurfaceFormat.SwapBehavior.DefaultSwapBehavior
+QSurfaceFormat.SingleBuffer QSurfaceFormat.SwapBehavior.SingleBuffer
+QSurfaceFormat.DoubleBuffer QSurfaceFormat.SwapBehavior.DoubleBuffer
+QSurfaceFormat.TripleBuffer QSurfaceFormat.SwapBehavior.TripleBuffer
+QSurfaceFormat.StereoBuffers QSurfaceFormat.FormatOption.StereoBuffers
+QSurfaceFormat.DebugContext QSurfaceFormat.FormatOption.DebugContext
+QSurfaceFormat.DeprecatedFunctions QSurfaceFormat.FormatOption.DeprecatedFunctions
+QSurfaceFormat.ResetNotification QSurfaceFormat.FormatOption.ResetNotification
+QTextCursor.WordUnderCursor QTextCursor.SelectionType.WordUnderCursor
+QTextCursor.LineUnderCursor QTextCursor.SelectionType.LineUnderCursor
+QTextCursor.BlockUnderCursor QTextCursor.SelectionType.BlockUnderCursor
+QTextCursor.Document QTextCursor.SelectionType.Document
+QTextCursor.NoMove QTextCursor.MoveOperation.NoMove
+QTextCursor.Start QTextCursor.MoveOperation.Start
+QTextCursor.Up QTextCursor.MoveOperation.Up
+QTextCursor.StartOfLine QTextCursor.MoveOperation.StartOfLine
+QTextCursor.StartOfBlock QTextCursor.MoveOperation.StartOfBlock
+QTextCursor.StartOfWord QTextCursor.MoveOperation.StartOfWord
+QTextCursor.PreviousBlock QTextCursor.MoveOperation.PreviousBlock
+QTextCursor.PreviousCharacter QTextCursor.MoveOperation.PreviousCharacter
+QTextCursor.PreviousWord QTextCursor.MoveOperation.PreviousWord
+QTextCursor.Left QTextCursor.MoveOperation.Left
+QTextCursor.WordLeft QTextCursor.MoveOperation.WordLeft
+QTextCursor.End QTextCursor.MoveOperation.End
+QTextCursor.Down QTextCursor.MoveOperation.Down
+QTextCursor.EndOfLine QTextCursor.MoveOperation.EndOfLine
+QTextCursor.EndOfWord QTextCursor.MoveOperation.EndOfWord
+QTextCursor.EndOfBlock QTextCursor.MoveOperation.EndOfBlock
+QTextCursor.NextBlock QTextCursor.MoveOperation.NextBlock
+QTextCursor.NextCharacter QTextCursor.MoveOperation.NextCharacter
+QTextCursor.NextWord QTextCursor.MoveOperation.NextWord
+QTextCursor.Right QTextCursor.MoveOperation.Right
+QTextCursor.WordRight QTextCursor.MoveOperation.WordRight
+QTextCursor.NextCell QTextCursor.MoveOperation.NextCell
+QTextCursor.PreviousCell QTextCursor.MoveOperation.PreviousCell
+QTextCursor.NextRow QTextCursor.MoveOperation.NextRow
+QTextCursor.PreviousRow QTextCursor.MoveOperation.PreviousRow
+QTextCursor.MoveAnchor QTextCursor.MoveMode.MoveAnchor
+QTextCursor.KeepAnchor QTextCursor.MoveMode.KeepAnchor
+QTextDocument.MarkdownNoHTML QTextDocument.MarkdownFeature.MarkdownNoHTML
+QTextDocument.MarkdownDialectCommonMark QTextDocument.MarkdownFeature.MarkdownDialectCommonMark
+QTextDocument.MarkdownDialectGitHub QTextDocument.MarkdownFeature.MarkdownDialectGitHub
+QTextDocument.UndoStack QTextDocument.Stacks.UndoStack
+QTextDocument.RedoStack QTextDocument.Stacks.RedoStack
+QTextDocument.UndoAndRedoStacks QTextDocument.Stacks.UndoAndRedoStacks
+QTextDocument.UnknownResource QTextDocument.ResourceType.UnknownResource
+QTextDocument.HtmlResource QTextDocument.ResourceType.HtmlResource
+QTextDocument.ImageResource QTextDocument.ResourceType.ImageResource
+QTextDocument.StyleSheetResource QTextDocument.ResourceType.StyleSheetResource
+QTextDocument.MarkdownResource QTextDocument.ResourceType.MarkdownResource
+QTextDocument.UserResource QTextDocument.ResourceType.UserResource
+QTextDocument.FindBackward QTextDocument.FindFlag.FindBackward
+QTextDocument.FindCaseSensitively QTextDocument.FindFlag.FindCaseSensitively
+QTextDocument.FindWholeWords QTextDocument.FindFlag.FindWholeWords
+QTextDocument.DocumentTitle QTextDocument.MetaInformation.DocumentTitle
+QTextDocument.DocumentUrl QTextDocument.MetaInformation.DocumentUrl
+QTextLength.VariableLength QTextLength.Type.VariableLength
+QTextLength.FixedLength QTextLength.Type.FixedLength
+QTextLength.PercentageLength QTextLength.Type.PercentageLength
+QTextFormat.ObjectIndex QTextFormat.Property.ObjectIndex
+QTextFormat.CssFloat QTextFormat.Property.CssFloat
+QTextFormat.LayoutDirection QTextFormat.Property.LayoutDirection
+QTextFormat.OutlinePen QTextFormat.Property.OutlinePen
+QTextFormat.BackgroundBrush QTextFormat.Property.BackgroundBrush
+QTextFormat.ForegroundBrush QTextFormat.Property.ForegroundBrush
+QTextFormat.BlockAlignment QTextFormat.Property.BlockAlignment
+QTextFormat.BlockTopMargin QTextFormat.Property.BlockTopMargin
+QTextFormat.BlockBottomMargin QTextFormat.Property.BlockBottomMargin
+QTextFormat.BlockLeftMargin QTextFormat.Property.BlockLeftMargin
+QTextFormat.BlockRightMargin QTextFormat.Property.BlockRightMargin
+QTextFormat.TextIndent QTextFormat.Property.TextIndent
+QTextFormat.BlockIndent QTextFormat.Property.BlockIndent
+QTextFormat.BlockNonBreakableLines QTextFormat.Property.BlockNonBreakableLines
+QTextFormat.BlockTrailingHorizontalRulerWidth QTextFormat.Property.BlockTrailingHorizontalRulerWidth
+QTextFormat.FontFamily QTextFormat.Property.FontFamily
+QTextFormat.FontPointSize QTextFormat.Property.FontPointSize
+QTextFormat.FontSizeAdjustment QTextFormat.Property.FontSizeAdjustment
+QTextFormat.FontSizeIncrement QTextFormat.Property.FontSizeIncrement
+QTextFormat.FontWeight QTextFormat.Property.FontWeight
+QTextFormat.FontItalic QTextFormat.Property.FontItalic
+QTextFormat.FontUnderline QTextFormat.Property.FontUnderline
+QTextFormat.FontOverline QTextFormat.Property.FontOverline
+QTextFormat.FontStrikeOut QTextFormat.Property.FontStrikeOut
+QTextFormat.FontFixedPitch QTextFormat.Property.FontFixedPitch
+QTextFormat.FontPixelSize QTextFormat.Property.FontPixelSize
+QTextFormat.TextUnderlineColor QTextFormat.Property.TextUnderlineColor
+QTextFormat.TextVerticalAlignment QTextFormat.Property.TextVerticalAlignment
+QTextFormat.TextOutline QTextFormat.Property.TextOutline
+QTextFormat.IsAnchor QTextFormat.Property.IsAnchor
+QTextFormat.AnchorHref QTextFormat.Property.AnchorHref
+QTextFormat.AnchorName QTextFormat.Property.AnchorName
+QTextFormat.ObjectType QTextFormat.Property.ObjectType
+QTextFormat.ListStyle QTextFormat.Property.ListStyle
+QTextFormat.ListIndent QTextFormat.Property.ListIndent
+QTextFormat.FrameBorder QTextFormat.Property.FrameBorder
+QTextFormat.FrameMargin QTextFormat.Property.FrameMargin
+QTextFormat.FramePadding QTextFormat.Property.FramePadding
+QTextFormat.FrameWidth QTextFormat.Property.FrameWidth
+QTextFormat.FrameHeight QTextFormat.Property.FrameHeight
+QTextFormat.TableColumns QTextFormat.Property.TableColumns
+QTextFormat.TableColumnWidthConstraints QTextFormat.Property.TableColumnWidthConstraints
+QTextFormat.TableCellSpacing QTextFormat.Property.TableCellSpacing
+QTextFormat.TableCellPadding QTextFormat.Property.TableCellPadding
+QTextFormat.TableCellRowSpan QTextFormat.Property.TableCellRowSpan
+QTextFormat.TableCellColumnSpan QTextFormat.Property.TableCellColumnSpan
+QTextFormat.ImageName QTextFormat.Property.ImageName
+QTextFormat.ImageWidth QTextFormat.Property.ImageWidth
+QTextFormat.ImageHeight QTextFormat.Property.ImageHeight
+QTextFormat.TextUnderlineStyle QTextFormat.Property.TextUnderlineStyle
+QTextFormat.TableHeaderRowCount QTextFormat.Property.TableHeaderRowCount
+QTextFormat.FullWidthSelection QTextFormat.Property.FullWidthSelection
+QTextFormat.PageBreakPolicy QTextFormat.Property.PageBreakPolicy
+QTextFormat.TextToolTip QTextFormat.Property.TextToolTip
+QTextFormat.FrameTopMargin QTextFormat.Property.FrameTopMargin
+QTextFormat.FrameBottomMargin QTextFormat.Property.FrameBottomMargin
+QTextFormat.FrameLeftMargin QTextFormat.Property.FrameLeftMargin
+QTextFormat.FrameRightMargin QTextFormat.Property.FrameRightMargin
+QTextFormat.FrameBorderBrush QTextFormat.Property.FrameBorderBrush
+QTextFormat.FrameBorderStyle QTextFormat.Property.FrameBorderStyle
+QTextFormat.BackgroundImageUrl QTextFormat.Property.BackgroundImageUrl
+QTextFormat.TabPositions QTextFormat.Property.TabPositions
+QTextFormat.FirstFontProperty QTextFormat.Property.FirstFontProperty
+QTextFormat.FontCapitalization QTextFormat.Property.FontCapitalization
+QTextFormat.FontLetterSpacing QTextFormat.Property.FontLetterSpacing
+QTextFormat.FontWordSpacing QTextFormat.Property.FontWordSpacing
+QTextFormat.LastFontProperty QTextFormat.Property.LastFontProperty
+QTextFormat.TableCellTopPadding QTextFormat.Property.TableCellTopPadding
+QTextFormat.TableCellBottomPadding QTextFormat.Property.TableCellBottomPadding
+QTextFormat.TableCellLeftPadding QTextFormat.Property.TableCellLeftPadding
+QTextFormat.TableCellRightPadding QTextFormat.Property.TableCellRightPadding
+QTextFormat.FontStyleHint QTextFormat.Property.FontStyleHint
+QTextFormat.FontStyleStrategy QTextFormat.Property.FontStyleStrategy
+QTextFormat.FontKerning QTextFormat.Property.FontKerning
+QTextFormat.LineHeight QTextFormat.Property.LineHeight
+QTextFormat.LineHeightType QTextFormat.Property.LineHeightType
+QTextFormat.FontHintingPreference QTextFormat.Property.FontHintingPreference
+QTextFormat.ListNumberPrefix QTextFormat.Property.ListNumberPrefix
+QTextFormat.ListNumberSuffix QTextFormat.Property.ListNumberSuffix
+QTextFormat.FontStretch QTextFormat.Property.FontStretch
+QTextFormat.FontLetterSpacingType QTextFormat.Property.FontLetterSpacingType
+QTextFormat.HeadingLevel QTextFormat.Property.HeadingLevel
+QTextFormat.ImageQuality QTextFormat.Property.ImageQuality
+QTextFormat.FontFamilies QTextFormat.Property.FontFamilies
+QTextFormat.FontStyleName QTextFormat.Property.FontStyleName
+QTextFormat.BlockQuoteLevel QTextFormat.Property.BlockQuoteLevel
+QTextFormat.BlockCodeLanguage QTextFormat.Property.BlockCodeLanguage
+QTextFormat.BlockCodeFence QTextFormat.Property.BlockCodeFence
+QTextFormat.BlockMarker QTextFormat.Property.BlockMarker
+QTextFormat.TableBorderCollapse QTextFormat.Property.TableBorderCollapse
+QTextFormat.TableCellTopBorder QTextFormat.Property.TableCellTopBorder
+QTextFormat.TableCellBottomBorder QTextFormat.Property.TableCellBottomBorder
+QTextFormat.TableCellLeftBorder QTextFormat.Property.TableCellLeftBorder
+QTextFormat.TableCellRightBorder QTextFormat.Property.TableCellRightBorder
+QTextFormat.TableCellTopBorderStyle QTextFormat.Property.TableCellTopBorderStyle
+QTextFormat.TableCellBottomBorderStyle QTextFormat.Property.TableCellBottomBorderStyle
+QTextFormat.TableCellLeftBorderStyle QTextFormat.Property.TableCellLeftBorderStyle
+QTextFormat.TableCellRightBorderStyle QTextFormat.Property.TableCellRightBorderStyle
+QTextFormat.TableCellTopBorderBrush QTextFormat.Property.TableCellTopBorderBrush
+QTextFormat.TableCellBottomBorderBrush QTextFormat.Property.TableCellBottomBorderBrush
+QTextFormat.TableCellLeftBorderBrush QTextFormat.Property.TableCellLeftBorderBrush
+QTextFormat.TableCellRightBorderBrush QTextFormat.Property.TableCellRightBorderBrush
+QTextFormat.ImageTitle QTextFormat.Property.ImageTitle
+QTextFormat.ImageAltText QTextFormat.Property.ImageAltText
+QTextFormat.UserProperty QTextFormat.Property.UserProperty
+QTextFormat.PageBreak_Auto QTextFormat.PageBreakFlag.PageBreak_Auto
+QTextFormat.PageBreak_AlwaysBefore QTextFormat.PageBreakFlag.PageBreak_AlwaysBefore
+QTextFormat.PageBreak_AlwaysAfter QTextFormat.PageBreakFlag.PageBreak_AlwaysAfter
+QTextFormat.NoObject QTextFormat.ObjectTypes.NoObject
+QTextFormat.ImageObject QTextFormat.ObjectTypes.ImageObject
+QTextFormat.TableObject QTextFormat.ObjectTypes.TableObject
+QTextFormat.TableCellObject QTextFormat.ObjectTypes.TableCellObject
+QTextFormat.UserObject QTextFormat.ObjectTypes.UserObject
+QTextFormat.InvalidFormat QTextFormat.FormatType.InvalidFormat
+QTextFormat.BlockFormat QTextFormat.FormatType.BlockFormat
+QTextFormat.CharFormat QTextFormat.FormatType.CharFormat
+QTextFormat.ListFormat QTextFormat.FormatType.ListFormat
+QTextFormat.TableFormat QTextFormat.FormatType.TableFormat
+QTextFormat.FrameFormat QTextFormat.FormatType.FrameFormat
+QTextFormat.UserFormat QTextFormat.FormatType.UserFormat
+QTextCharFormat.FontPropertiesSpecifiedOnly QTextCharFormat.FontPropertiesInheritanceBehavior.FontPropertiesSpecifiedOnly
+QTextCharFormat.FontPropertiesAll QTextCharFormat.FontPropertiesInheritanceBehavior.FontPropertiesAll
+QTextCharFormat.NoUnderline QTextCharFormat.UnderlineStyle.NoUnderline
+QTextCharFormat.SingleUnderline QTextCharFormat.UnderlineStyle.SingleUnderline
+QTextCharFormat.DashUnderline QTextCharFormat.UnderlineStyle.DashUnderline
+QTextCharFormat.DotLine QTextCharFormat.UnderlineStyle.DotLine
+QTextCharFormat.DashDotLine QTextCharFormat.UnderlineStyle.DashDotLine
+QTextCharFormat.DashDotDotLine QTextCharFormat.UnderlineStyle.DashDotDotLine
+QTextCharFormat.WaveUnderline QTextCharFormat.UnderlineStyle.WaveUnderline
+QTextCharFormat.SpellCheckUnderline QTextCharFormat.UnderlineStyle.SpellCheckUnderline
+QTextCharFormat.AlignNormal QTextCharFormat.VerticalAlignment.AlignNormal
+QTextCharFormat.AlignSuperScript QTextCharFormat.VerticalAlignment.AlignSuperScript
+QTextCharFormat.AlignSubScript QTextCharFormat.VerticalAlignment.AlignSubScript
+QTextCharFormat.AlignMiddle QTextCharFormat.VerticalAlignment.AlignMiddle
+QTextCharFormat.AlignTop QTextCharFormat.VerticalAlignment.AlignTop
+QTextCharFormat.AlignBottom QTextCharFormat.VerticalAlignment.AlignBottom
+QTextCharFormat.AlignBaseline QTextCharFormat.VerticalAlignment.AlignBaseline
+QTextBlockFormat.NoMarker QTextBlockFormat.MarkerType.NoMarker
+QTextBlockFormat.Unchecked QTextBlockFormat.MarkerType.Unchecked
+QTextBlockFormat.Checked QTextBlockFormat.MarkerType.Checked
+QTextBlockFormat.SingleHeight QTextBlockFormat.LineHeightTypes.SingleHeight
+QTextBlockFormat.ProportionalHeight QTextBlockFormat.LineHeightTypes.ProportionalHeight
+QTextBlockFormat.FixedHeight QTextBlockFormat.LineHeightTypes.FixedHeight
+QTextBlockFormat.MinimumHeight QTextBlockFormat.LineHeightTypes.MinimumHeight
+QTextBlockFormat.LineDistanceHeight QTextBlockFormat.LineHeightTypes.LineDistanceHeight
+QTextListFormat.ListDisc QTextListFormat.Style.ListDisc
+QTextListFormat.ListCircle QTextListFormat.Style.ListCircle
+QTextListFormat.ListSquare QTextListFormat.Style.ListSquare
+QTextListFormat.ListDecimal QTextListFormat.Style.ListDecimal
+QTextListFormat.ListLowerAlpha QTextListFormat.Style.ListLowerAlpha
+QTextListFormat.ListUpperAlpha QTextListFormat.Style.ListUpperAlpha
+QTextListFormat.ListLowerRoman QTextListFormat.Style.ListLowerRoman
+QTextListFormat.ListUpperRoman QTextListFormat.Style.ListUpperRoman
+QTextFrameFormat.BorderStyle_None QTextFrameFormat.BorderStyle.BorderStyle_None
+QTextFrameFormat.BorderStyle_Dotted QTextFrameFormat.BorderStyle.BorderStyle_Dotted
+QTextFrameFormat.BorderStyle_Dashed QTextFrameFormat.BorderStyle.BorderStyle_Dashed
+QTextFrameFormat.BorderStyle_Solid QTextFrameFormat.BorderStyle.BorderStyle_Solid
+QTextFrameFormat.BorderStyle_Double QTextFrameFormat.BorderStyle.BorderStyle_Double
+QTextFrameFormat.BorderStyle_DotDash QTextFrameFormat.BorderStyle.BorderStyle_DotDash
+QTextFrameFormat.BorderStyle_DotDotDash QTextFrameFormat.BorderStyle.BorderStyle_DotDotDash
+QTextFrameFormat.BorderStyle_Groove QTextFrameFormat.BorderStyle.BorderStyle_Groove
+QTextFrameFormat.BorderStyle_Ridge QTextFrameFormat.BorderStyle.BorderStyle_Ridge
+QTextFrameFormat.BorderStyle_Inset QTextFrameFormat.BorderStyle.BorderStyle_Inset
+QTextFrameFormat.BorderStyle_Outset QTextFrameFormat.BorderStyle.BorderStyle_Outset
+QTextFrameFormat.InFlow QTextFrameFormat.Position.InFlow
+QTextFrameFormat.FloatLeft QTextFrameFormat.Position.FloatLeft
+QTextFrameFormat.FloatRight QTextFrameFormat.Position.FloatRight
+QTextLayout.SkipCharacters QTextLayout.CursorMode.SkipCharacters
+QTextLayout.SkipWords QTextLayout.CursorMode.SkipWords
+QTextLine.CursorBetweenCharacters QTextLine.CursorPosition.CursorBetweenCharacters
+QTextLine.CursorOnCharacter QTextLine.CursorPosition.CursorOnCharacter
+QTextLine.Leading QTextLine.Edge.Leading
+QTextLine.Trailing QTextLine.Edge.Trailing
+QTextOption.LeftTab QTextOption.TabType.LeftTab
+QTextOption.RightTab QTextOption.TabType.RightTab
+QTextOption.CenterTab QTextOption.TabType.CenterTab
+QTextOption.DelimiterTab QTextOption.TabType.DelimiterTab
+QTextOption.IncludeTrailingSpaces QTextOption.Flag.IncludeTrailingSpaces
+QTextOption.ShowTabsAndSpaces QTextOption.Flag.ShowTabsAndSpaces
+QTextOption.ShowLineAndParagraphSeparators QTextOption.Flag.ShowLineAndParagraphSeparators
+QTextOption.AddSpaceForLineAndParagraphSeparators QTextOption.Flag.AddSpaceForLineAndParagraphSeparators
+QTextOption.SuppressColors QTextOption.Flag.SuppressColors
+QTextOption.ShowDocumentTerminator QTextOption.Flag.ShowDocumentTerminator
+QTextOption.NoWrap QTextOption.WrapMode.NoWrap
+QTextOption.WordWrap QTextOption.WrapMode.WordWrap
+QTextOption.ManualWrap QTextOption.WrapMode.ManualWrap
+QTextOption.WrapAnywhere QTextOption.WrapMode.WrapAnywhere
+QTextOption.WrapAtWordBoundaryOrAnywhere QTextOption.WrapMode.WrapAtWordBoundaryOrAnywhere
+QTouchDevice.Position QTouchDevice.CapabilityFlag.Position
+QTouchDevice.Area QTouchDevice.CapabilityFlag.Area
+QTouchDevice.Pressure QTouchDevice.CapabilityFlag.Pressure
+QTouchDevice.Velocity QTouchDevice.CapabilityFlag.Velocity
+QTouchDevice.RawPositions QTouchDevice.CapabilityFlag.RawPositions
+QTouchDevice.NormalizedPosition QTouchDevice.CapabilityFlag.NormalizedPosition
+QTouchDevice.MouseEmulation QTouchDevice.CapabilityFlag.MouseEmulation
+QTouchDevice.TouchScreen QTouchDevice.DeviceType.TouchScreen
+QTouchDevice.TouchPad QTouchDevice.DeviceType.TouchPad
+QTransform.TxNone QTransform.TransformationType.TxNone
+QTransform.TxTranslate QTransform.TransformationType.TxTranslate
+QTransform.TxScale QTransform.TransformationType.TxScale
+QTransform.TxRotate QTransform.TransformationType.TxRotate
+QTransform.TxShear QTransform.TransformationType.TxShear
+QTransform.TxProject QTransform.TransformationType.TxProject
+QValidator.Invalid QValidator.State.Invalid
+QValidator.Intermediate QValidator.State.Intermediate
+QValidator.Acceptable QValidator.State.Acceptable
+QDoubleValidator.StandardNotation QDoubleValidator.Notation.StandardNotation
+QDoubleValidator.ScientificNotation QDoubleValidator.Notation.ScientificNotation
+QInputMethodEvent.type QInputMethodEvent.AttributeType.type
+QTouchEvent.TouchPoint.Pen QTouchEvent.TouchPoint.InfoFlag.Pen
+QTouchEvent.TouchPoint.Token QTouchEvent.TouchPoint.InfoFlag.Token
+QPainterPath.type QPainterPath.ElementType.type
+QTextOption.type QTextOption.TabType.type
+QHelpSearchQuery.DEFAULT QHelpSearchQuery.FieldName.DEFAULT
+QHelpSearchQuery.FUZZY QHelpSearchQuery.FieldName.FUZZY
+QHelpSearchQuery.WITHOUT QHelpSearchQuery.FieldName.WITHOUT
+QHelpSearchQuery.PHRASE QHelpSearchQuery.FieldName.PHRASE
+QHelpSearchQuery.ALL QHelpSearchQuery.FieldName.ALL
+QHelpSearchQuery.ATLEAST QHelpSearchQuery.FieldName.ATLEAST
+QGeoCodeReply.NoError QGeoCodeReply.Error.NoError
+QGeoCodeReply.EngineNotSetError QGeoCodeReply.Error.EngineNotSetError
+QGeoCodeReply.CommunicationError QGeoCodeReply.Error.CommunicationError
+QGeoCodeReply.ParseError QGeoCodeReply.Error.ParseError
+QGeoCodeReply.UnsupportedOptionError QGeoCodeReply.Error.UnsupportedOptionError
+QGeoCodeReply.CombinationError QGeoCodeReply.Error.CombinationError
+QGeoCodeReply.UnknownError QGeoCodeReply.Error.UnknownError
+QGeoManeuver.NoDirection QGeoManeuver.InstructionDirection.NoDirection
+QGeoManeuver.DirectionForward QGeoManeuver.InstructionDirection.DirectionForward
+QGeoManeuver.DirectionBearRight QGeoManeuver.InstructionDirection.DirectionBearRight
+QGeoManeuver.DirectionLightRight QGeoManeuver.InstructionDirection.DirectionLightRight
+QGeoManeuver.DirectionRight QGeoManeuver.InstructionDirection.DirectionRight
+QGeoManeuver.DirectionHardRight QGeoManeuver.InstructionDirection.DirectionHardRight
+QGeoManeuver.DirectionUTurnRight QGeoManeuver.InstructionDirection.DirectionUTurnRight
+QGeoManeuver.DirectionUTurnLeft QGeoManeuver.InstructionDirection.DirectionUTurnLeft
+QGeoManeuver.DirectionHardLeft QGeoManeuver.InstructionDirection.DirectionHardLeft
+QGeoManeuver.DirectionLeft QGeoManeuver.InstructionDirection.DirectionLeft
+QGeoManeuver.DirectionLightLeft QGeoManeuver.InstructionDirection.DirectionLightLeft
+QGeoManeuver.DirectionBearLeft QGeoManeuver.InstructionDirection.DirectionBearLeft
+QGeoRouteReply.NoError QGeoRouteReply.Error.NoError
+QGeoRouteReply.EngineNotSetError QGeoRouteReply.Error.EngineNotSetError
+QGeoRouteReply.CommunicationError QGeoRouteReply.Error.CommunicationError
+QGeoRouteReply.ParseError QGeoRouteReply.Error.ParseError
+QGeoRouteReply.UnsupportedOptionError QGeoRouteReply.Error.UnsupportedOptionError
+QGeoRouteReply.UnknownError QGeoRouteReply.Error.UnknownError
+QGeoRouteRequest.NoManeuvers QGeoRouteRequest.ManeuverDetail.NoManeuvers
+QGeoRouteRequest.BasicManeuvers QGeoRouteRequest.ManeuverDetail.BasicManeuvers
+QGeoRouteRequest.NoSegmentData QGeoRouteRequest.SegmentDetail.NoSegmentData
+QGeoRouteRequest.BasicSegmentData QGeoRouteRequest.SegmentDetail.BasicSegmentData
+QGeoRouteRequest.ShortestRoute QGeoRouteRequest.RouteOptimization.ShortestRoute
+QGeoRouteRequest.FastestRoute QGeoRouteRequest.RouteOptimization.FastestRoute
+QGeoRouteRequest.MostEconomicRoute QGeoRouteRequest.RouteOptimization.MostEconomicRoute
+QGeoRouteRequest.MostScenicRoute QGeoRouteRequest.RouteOptimization.MostScenicRoute
+QGeoRouteRequest.NeutralFeatureWeight QGeoRouteRequest.FeatureWeight.NeutralFeatureWeight
+QGeoRouteRequest.PreferFeatureWeight QGeoRouteRequest.FeatureWeight.PreferFeatureWeight
+QGeoRouteRequest.RequireFeatureWeight QGeoRouteRequest.FeatureWeight.RequireFeatureWeight
+QGeoRouteRequest.AvoidFeatureWeight QGeoRouteRequest.FeatureWeight.AvoidFeatureWeight
+QGeoRouteRequest.DisallowFeatureWeight QGeoRouteRequest.FeatureWeight.DisallowFeatureWeight
+QGeoRouteRequest.NoFeature QGeoRouteRequest.FeatureType.NoFeature
+QGeoRouteRequest.TollFeature QGeoRouteRequest.FeatureType.TollFeature
+QGeoRouteRequest.HighwayFeature QGeoRouteRequest.FeatureType.HighwayFeature
+QGeoRouteRequest.PublicTransitFeature QGeoRouteRequest.FeatureType.PublicTransitFeature
+QGeoRouteRequest.FerryFeature QGeoRouteRequest.FeatureType.FerryFeature
+QGeoRouteRequest.TunnelFeature QGeoRouteRequest.FeatureType.TunnelFeature
+QGeoRouteRequest.DirtRoadFeature QGeoRouteRequest.FeatureType.DirtRoadFeature
+QGeoRouteRequest.ParksFeature QGeoRouteRequest.FeatureType.ParksFeature
+QGeoRouteRequest.MotorPoolLaneFeature QGeoRouteRequest.FeatureType.MotorPoolLaneFeature
+QGeoRouteRequest.TrafficFeature QGeoRouteRequest.FeatureType.TrafficFeature
+QGeoRouteRequest.CarTravel QGeoRouteRequest.TravelMode.CarTravel
+QGeoRouteRequest.PedestrianTravel QGeoRouteRequest.TravelMode.PedestrianTravel
+QGeoRouteRequest.BicycleTravel QGeoRouteRequest.TravelMode.BicycleTravel
+QGeoRouteRequest.PublicTransitTravel QGeoRouteRequest.TravelMode.PublicTransitTravel
+QGeoRouteRequest.TruckTravel QGeoRouteRequest.TravelMode.TruckTravel
+QGeoServiceProvider.NoNavigationFeatures QGeoServiceProvider.NavigationFeature.NoNavigationFeatures
+QGeoServiceProvider.OnlineNavigationFeature QGeoServiceProvider.NavigationFeature.OnlineNavigationFeature
+QGeoServiceProvider.OfflineNavigationFeature QGeoServiceProvider.NavigationFeature.OfflineNavigationFeature
+QGeoServiceProvider.AnyNavigationFeatures QGeoServiceProvider.NavigationFeature.AnyNavigationFeatures
+QGeoServiceProvider.NoPlacesFeatures QGeoServiceProvider.PlacesFeature.NoPlacesFeatures
+QGeoServiceProvider.OnlinePlacesFeature QGeoServiceProvider.PlacesFeature.OnlinePlacesFeature
+QGeoServiceProvider.OfflinePlacesFeature QGeoServiceProvider.PlacesFeature.OfflinePlacesFeature
+QGeoServiceProvider.SavePlaceFeature QGeoServiceProvider.PlacesFeature.SavePlaceFeature
+QGeoServiceProvider.RemovePlaceFeature QGeoServiceProvider.PlacesFeature.RemovePlaceFeature
+QGeoServiceProvider.SaveCategoryFeature QGeoServiceProvider.PlacesFeature.SaveCategoryFeature
+QGeoServiceProvider.RemoveCategoryFeature QGeoServiceProvider.PlacesFeature.RemoveCategoryFeature
+QGeoServiceProvider.PlaceRecommendationsFeature QGeoServiceProvider.PlacesFeature.PlaceRecommendationsFeature
+QGeoServiceProvider.SearchSuggestionsFeature QGeoServiceProvider.PlacesFeature.SearchSuggestionsFeature
+QGeoServiceProvider.LocalizedPlacesFeature QGeoServiceProvider.PlacesFeature.LocalizedPlacesFeature
+QGeoServiceProvider.NotificationsFeature QGeoServiceProvider.PlacesFeature.NotificationsFeature
+QGeoServiceProvider.PlaceMatchingFeature QGeoServiceProvider.PlacesFeature.PlaceMatchingFeature
+QGeoServiceProvider.AnyPlacesFeatures QGeoServiceProvider.PlacesFeature.AnyPlacesFeatures
+QGeoServiceProvider.NoMappingFeatures QGeoServiceProvider.MappingFeature.NoMappingFeatures
+QGeoServiceProvider.OnlineMappingFeature QGeoServiceProvider.MappingFeature.OnlineMappingFeature
+QGeoServiceProvider.OfflineMappingFeature QGeoServiceProvider.MappingFeature.OfflineMappingFeature
+QGeoServiceProvider.LocalizedMappingFeature QGeoServiceProvider.MappingFeature.LocalizedMappingFeature
+QGeoServiceProvider.AnyMappingFeatures QGeoServiceProvider.MappingFeature.AnyMappingFeatures
+QGeoServiceProvider.NoGeocodingFeatures QGeoServiceProvider.GeocodingFeature.NoGeocodingFeatures
+QGeoServiceProvider.OnlineGeocodingFeature QGeoServiceProvider.GeocodingFeature.OnlineGeocodingFeature
+QGeoServiceProvider.OfflineGeocodingFeature QGeoServiceProvider.GeocodingFeature.OfflineGeocodingFeature
+QGeoServiceProvider.ReverseGeocodingFeature QGeoServiceProvider.GeocodingFeature.ReverseGeocodingFeature
+QGeoServiceProvider.LocalizedGeocodingFeature QGeoServiceProvider.GeocodingFeature.LocalizedGeocodingFeature
+QGeoServiceProvider.AnyGeocodingFeatures QGeoServiceProvider.GeocodingFeature.AnyGeocodingFeatures
+QGeoServiceProvider.NoRoutingFeatures QGeoServiceProvider.RoutingFeature.NoRoutingFeatures
+QGeoServiceProvider.OnlineRoutingFeature QGeoServiceProvider.RoutingFeature.OnlineRoutingFeature
+QGeoServiceProvider.OfflineRoutingFeature QGeoServiceProvider.RoutingFeature.OfflineRoutingFeature
+QGeoServiceProvider.LocalizedRoutingFeature QGeoServiceProvider.RoutingFeature.LocalizedRoutingFeature
+QGeoServiceProvider.RouteUpdatesFeature QGeoServiceProvider.RoutingFeature.RouteUpdatesFeature
+QGeoServiceProvider.AlternativeRoutesFeature QGeoServiceProvider.RoutingFeature.AlternativeRoutesFeature
+QGeoServiceProvider.ExcludeAreasRoutingFeature QGeoServiceProvider.RoutingFeature.ExcludeAreasRoutingFeature
+QGeoServiceProvider.AnyRoutingFeatures QGeoServiceProvider.RoutingFeature.AnyRoutingFeatures
+QGeoServiceProvider.NoError QGeoServiceProvider.Error.NoError
+QGeoServiceProvider.NotSupportedError QGeoServiceProvider.Error.NotSupportedError
+QGeoServiceProvider.UnknownParameterError QGeoServiceProvider.Error.UnknownParameterError
+QGeoServiceProvider.MissingRequiredParameterError QGeoServiceProvider.Error.MissingRequiredParameterError
+QGeoServiceProvider.ConnectionError QGeoServiceProvider.Error.ConnectionError
+QGeoServiceProvider.LoaderError QGeoServiceProvider.Error.LoaderError
+QLocation.UnspecifiedVisibility QLocation.Visibility.UnspecifiedVisibility
+QLocation.DeviceVisibility QLocation.Visibility.DeviceVisibility
+QLocation.PrivateVisibility QLocation.Visibility.PrivateVisibility
+QLocation.PublicVisibility QLocation.Visibility.PublicVisibility
+QPlaceContent.NoType QPlaceContent.Type.NoType
+QPlaceContent.ImageType QPlaceContent.Type.ImageType
+QPlaceContent.ReviewType QPlaceContent.Type.ReviewType
+QPlaceContent.EditorialType QPlaceContent.Type.EditorialType
+QPlaceContent.CustomType QPlaceContent.Type.CustomType
+QPlaceReply.Reply QPlaceReply.Type.Reply
+QPlaceReply.DetailsReply QPlaceReply.Type.DetailsReply
+QPlaceReply.SearchReply QPlaceReply.Type.SearchReply
+QPlaceReply.SearchSuggestionReply QPlaceReply.Type.SearchSuggestionReply
+QPlaceReply.ContentReply QPlaceReply.Type.ContentReply
+QPlaceReply.IdReply QPlaceReply.Type.IdReply
+QPlaceReply.MatchReply QPlaceReply.Type.MatchReply
+QPlaceReply.NoError QPlaceReply.Error.NoError
+QPlaceReply.PlaceDoesNotExistError QPlaceReply.Error.PlaceDoesNotExistError
+QPlaceReply.CategoryDoesNotExistError QPlaceReply.Error.CategoryDoesNotExistError
+QPlaceReply.CommunicationError QPlaceReply.Error.CommunicationError
+QPlaceReply.ParseError QPlaceReply.Error.ParseError
+QPlaceReply.PermissionsError QPlaceReply.Error.PermissionsError
+QPlaceReply.UnsupportedError QPlaceReply.Error.UnsupportedError
+QPlaceReply.BadArgumentError QPlaceReply.Error.BadArgumentError
+QPlaceReply.CancelError QPlaceReply.Error.CancelError
+QPlaceReply.UnknownError QPlaceReply.Error.UnknownError
+QPlaceIdReply.SavePlace QPlaceIdReply.OperationType.SavePlace
+QPlaceIdReply.SaveCategory QPlaceIdReply.OperationType.SaveCategory
+QPlaceIdReply.RemovePlace QPlaceIdReply.OperationType.RemovePlace
+QPlaceIdReply.RemoveCategory QPlaceIdReply.OperationType.RemoveCategory
+QPlaceSearchResult.UnknownSearchResult QPlaceSearchResult.SearchResultType.UnknownSearchResult
+QPlaceSearchResult.PlaceResult QPlaceSearchResult.SearchResultType.PlaceResult
+QPlaceSearchResult.ProposedSearchResult QPlaceSearchResult.SearchResultType.ProposedSearchResult
+QPlaceSearchRequest.UnspecifiedHint QPlaceSearchRequest.RelevanceHint.UnspecifiedHint
+QPlaceSearchRequest.DistanceHint QPlaceSearchRequest.RelevanceHint.DistanceHint
+QPlaceSearchRequest.LexicalPlaceNameHint QPlaceSearchRequest.RelevanceHint.LexicalPlaceNameHint
+QAbstractVideoBuffer.NotMapped QAbstractVideoBuffer.MapMode.NotMapped
+QAbstractVideoBuffer.ReadOnly QAbstractVideoBuffer.MapMode.ReadOnly
+QAbstractVideoBuffer.WriteOnly QAbstractVideoBuffer.MapMode.WriteOnly
+QAbstractVideoBuffer.ReadWrite QAbstractVideoBuffer.MapMode.ReadWrite
+QAbstractVideoBuffer.NoHandle QAbstractVideoBuffer.HandleType.NoHandle
+QAbstractVideoBuffer.GLTextureHandle QAbstractVideoBuffer.HandleType.GLTextureHandle
+QAbstractVideoBuffer.XvShmImageHandle QAbstractVideoBuffer.HandleType.XvShmImageHandle
+QAbstractVideoBuffer.CoreImageHandle QAbstractVideoBuffer.HandleType.CoreImageHandle
+QAbstractVideoBuffer.QPixmapHandle QAbstractVideoBuffer.HandleType.QPixmapHandle
+QAbstractVideoBuffer.EGLImageHandle QAbstractVideoBuffer.HandleType.EGLImageHandle
+QAbstractVideoBuffer.UserHandle QAbstractVideoBuffer.HandleType.UserHandle
+QVideoFilterRunnable.LastInChain QVideoFilterRunnable.RunFlag.LastInChain
+QAbstractVideoSurface.NoError QAbstractVideoSurface.Error.NoError
+QAbstractVideoSurface.UnsupportedFormatError QAbstractVideoSurface.Error.UnsupportedFormatError
+QAbstractVideoSurface.IncorrectFormatError QAbstractVideoSurface.Error.IncorrectFormatError
+QAbstractVideoSurface.StoppedError QAbstractVideoSurface.Error.StoppedError
+QAbstractVideoSurface.ResourceError QAbstractVideoSurface.Error.ResourceError
+QAudio.LinearVolumeScale QAudio.VolumeScale.LinearVolumeScale
+QAudio.CubicVolumeScale QAudio.VolumeScale.CubicVolumeScale
+QAudio.LogarithmicVolumeScale QAudio.VolumeScale.LogarithmicVolumeScale
+QAudio.DecibelVolumeScale QAudio.VolumeScale.DecibelVolumeScale
+QAudio.UnknownRole QAudio.Role.UnknownRole
+QAudio.MusicRole QAudio.Role.MusicRole
+QAudio.VideoRole QAudio.Role.VideoRole
+QAudio.VoiceCommunicationRole QAudio.Role.VoiceCommunicationRole
+QAudio.AlarmRole QAudio.Role.AlarmRole
+QAudio.NotificationRole QAudio.Role.NotificationRole
+QAudio.RingtoneRole QAudio.Role.RingtoneRole
+QAudio.AccessibilityRole QAudio.Role.AccessibilityRole
+QAudio.SonificationRole QAudio.Role.SonificationRole
+QAudio.GameRole QAudio.Role.GameRole
+QAudio.CustomRole QAudio.Role.CustomRole
+QAudio.AudioInput QAudio.Mode.AudioInput
+QAudio.AudioOutput QAudio.Mode.AudioOutput
+QAudio.ActiveState QAudio.State.ActiveState
+QAudio.SuspendedState QAudio.State.SuspendedState
+QAudio.StoppedState QAudio.State.StoppedState
+QAudio.IdleState QAudio.State.IdleState
+QAudio.InterruptedState QAudio.State.InterruptedState
+QAudio.NoError QAudio.Error.NoError
+QAudio.OpenError QAudio.Error.OpenError
+QAudio.IOError QAudio.Error.IOError
+QAudio.UnderrunError QAudio.Error.UnderrunError
+QAudio.FatalError QAudio.Error.FatalError
+QAudioDecoder.NoError QAudioDecoder.Error.NoError
+QAudioDecoder.ResourceError QAudioDecoder.Error.ResourceError
+QAudioDecoder.FormatError QAudioDecoder.Error.FormatError
+QAudioDecoder.AccessDeniedError QAudioDecoder.Error.AccessDeniedError
+QAudioDecoder.ServiceMissingError QAudioDecoder.Error.ServiceMissingError
+QAudioDecoder.StoppedState QAudioDecoder.State.StoppedState
+QAudioDecoder.DecodingState QAudioDecoder.State.DecodingState
+QAudioFormat.BigEndian QAudioFormat.Endian.BigEndian
+QAudioFormat.LittleEndian QAudioFormat.Endian.LittleEndian
+QAudioFormat.Unknown QAudioFormat.SampleType.Unknown
+QAudioFormat.SignedInt QAudioFormat.SampleType.SignedInt
+QAudioFormat.UnSignedInt QAudioFormat.SampleType.UnSignedInt
+QAudioFormat.Float QAudioFormat.SampleType.Float
+QMediaRecorder.NoError QMediaRecorder.Error.NoError
+QMediaRecorder.ResourceError QMediaRecorder.Error.ResourceError
+QMediaRecorder.FormatError QMediaRecorder.Error.FormatError
+QMediaRecorder.OutOfSpaceError QMediaRecorder.Error.OutOfSpaceError
+QMediaRecorder.UnavailableStatus QMediaRecorder.Status.UnavailableStatus
+QMediaRecorder.UnloadedStatus QMediaRecorder.Status.UnloadedStatus
+QMediaRecorder.LoadingStatus QMediaRecorder.Status.LoadingStatus
+QMediaRecorder.LoadedStatus QMediaRecorder.Status.LoadedStatus
+QMediaRecorder.StartingStatus QMediaRecorder.Status.StartingStatus
+QMediaRecorder.RecordingStatus QMediaRecorder.Status.RecordingStatus
+QMediaRecorder.PausedStatus QMediaRecorder.Status.PausedStatus
+QMediaRecorder.FinalizingStatus QMediaRecorder.Status.FinalizingStatus
+QMediaRecorder.StoppedState QMediaRecorder.State.StoppedState
+QMediaRecorder.RecordingState QMediaRecorder.State.RecordingState
+QMediaRecorder.PausedState QMediaRecorder.State.PausedState
+QCamera.UnspecifiedPosition QCamera.Position.UnspecifiedPosition
+QCamera.BackFace QCamera.Position.BackFace
+QCamera.FrontFace QCamera.Position.FrontFace
+QCamera.NoLock QCamera.LockType.NoLock
+QCamera.LockExposure QCamera.LockType.LockExposure
+QCamera.LockWhiteBalance QCamera.LockType.LockWhiteBalance
+QCamera.LockFocus QCamera.LockType.LockFocus
+QCamera.UserRequest QCamera.LockChangeReason.UserRequest
+QCamera.LockAcquired QCamera.LockChangeReason.LockAcquired
+QCamera.LockFailed QCamera.LockChangeReason.LockFailed
+QCamera.LockLost QCamera.LockChangeReason.LockLost
+QCamera.LockTemporaryLost QCamera.LockChangeReason.LockTemporaryLost
+QCamera.Unlocked QCamera.LockStatus.Unlocked
+QCamera.Searching QCamera.LockStatus.Searching
+QCamera.Locked QCamera.LockStatus.Locked
+QCamera.NoError QCamera.Error.NoError
+QCamera.CameraError QCamera.Error.CameraError
+QCamera.InvalidRequestError QCamera.Error.InvalidRequestError
+QCamera.ServiceMissingError QCamera.Error.ServiceMissingError
+QCamera.NotSupportedFeatureError QCamera.Error.NotSupportedFeatureError
+QCamera.CaptureViewfinder QCamera.CaptureMode.CaptureViewfinder
+QCamera.CaptureStillImage QCamera.CaptureMode.CaptureStillImage
+QCamera.CaptureVideo QCamera.CaptureMode.CaptureVideo
+QCamera.UnloadedState QCamera.State.UnloadedState
+QCamera.LoadedState QCamera.State.LoadedState
+QCamera.ActiveState QCamera.State.ActiveState
+QCamera.UnavailableStatus QCamera.Status.UnavailableStatus
+QCamera.UnloadedStatus QCamera.Status.UnloadedStatus
+QCamera.LoadingStatus QCamera.Status.LoadingStatus
+QCamera.UnloadingStatus QCamera.Status.UnloadingStatus
+QCamera.LoadedStatus QCamera.Status.LoadedStatus
+QCamera.StandbyStatus QCamera.Status.StandbyStatus
+QCamera.StartingStatus QCamera.Status.StartingStatus
+QCamera.StoppingStatus QCamera.Status.StoppingStatus
+QCamera.ActiveStatus QCamera.Status.ActiveStatus
+QCameraControl.CaptureMode QCameraControl.PropertyChangeType.CaptureMode
+QCameraControl.ImageEncodingSettings QCameraControl.PropertyChangeType.ImageEncodingSettings
+QCameraControl.VideoEncodingSettings QCameraControl.PropertyChangeType.VideoEncodingSettings
+QCameraControl.Viewfinder QCameraControl.PropertyChangeType.Viewfinder
+QCameraControl.ViewfinderSettings QCameraControl.PropertyChangeType.ViewfinderSettings
+QCameraExposure.MeteringMatrix QCameraExposure.MeteringMode.MeteringMatrix
+QCameraExposure.MeteringAverage QCameraExposure.MeteringMode.MeteringAverage
+QCameraExposure.MeteringSpot QCameraExposure.MeteringMode.MeteringSpot
+QCameraExposure.ExposureAuto QCameraExposure.ExposureMode.ExposureAuto
+QCameraExposure.ExposureManual QCameraExposure.ExposureMode.ExposureManual
+QCameraExposure.ExposurePortrait QCameraExposure.ExposureMode.ExposurePortrait
+QCameraExposure.ExposureNight QCameraExposure.ExposureMode.ExposureNight
+QCameraExposure.ExposureBacklight QCameraExposure.ExposureMode.ExposureBacklight
+QCameraExposure.ExposureSpotlight QCameraExposure.ExposureMode.ExposureSpotlight
+QCameraExposure.ExposureSports QCameraExposure.ExposureMode.ExposureSports
+QCameraExposure.ExposureSnow QCameraExposure.ExposureMode.ExposureSnow
+QCameraExposure.ExposureBeach QCameraExposure.ExposureMode.ExposureBeach
+QCameraExposure.ExposureLargeAperture QCameraExposure.ExposureMode.ExposureLargeAperture
+QCameraExposure.ExposureSmallAperture QCameraExposure.ExposureMode.ExposureSmallAperture
+QCameraExposure.ExposureAction QCameraExposure.ExposureMode.ExposureAction
+QCameraExposure.ExposureLandscape QCameraExposure.ExposureMode.ExposureLandscape
+QCameraExposure.ExposureNightPortrait QCameraExposure.ExposureMode.ExposureNightPortrait
+QCameraExposure.ExposureTheatre QCameraExposure.ExposureMode.ExposureTheatre
+QCameraExposure.ExposureSunset QCameraExposure.ExposureMode.ExposureSunset
+QCameraExposure.ExposureSteadyPhoto QCameraExposure.ExposureMode.ExposureSteadyPhoto
+QCameraExposure.ExposureFireworks QCameraExposure.ExposureMode.ExposureFireworks
+QCameraExposure.ExposureParty QCameraExposure.ExposureMode.ExposureParty
+QCameraExposure.ExposureCandlelight QCameraExposure.ExposureMode.ExposureCandlelight
+QCameraExposure.ExposureBarcode QCameraExposure.ExposureMode.ExposureBarcode
+QCameraExposure.ExposureModeVendor QCameraExposure.ExposureMode.ExposureModeVendor
+QCameraExposure.FlashAuto QCameraExposure.FlashMode.FlashAuto
+QCameraExposure.FlashOff QCameraExposure.FlashMode.FlashOff
+QCameraExposure.FlashOn QCameraExposure.FlashMode.FlashOn
+QCameraExposure.FlashRedEyeReduction QCameraExposure.FlashMode.FlashRedEyeReduction
+QCameraExposure.FlashFill QCameraExposure.FlashMode.FlashFill
+QCameraExposure.FlashTorch QCameraExposure.FlashMode.FlashTorch
+QCameraExposure.FlashVideoLight QCameraExposure.FlashMode.FlashVideoLight
+QCameraExposure.FlashSlowSyncFrontCurtain QCameraExposure.FlashMode.FlashSlowSyncFrontCurtain
+QCameraExposure.FlashSlowSyncRearCurtain QCameraExposure.FlashMode.FlashSlowSyncRearCurtain
+QCameraExposure.FlashManual QCameraExposure.FlashMode.FlashManual
+QCameraExposureControl.ISO QCameraExposureControl.ExposureParameter.ISO
+QCameraExposureControl.Aperture QCameraExposureControl.ExposureParameter.Aperture
+QCameraExposureControl.ShutterSpeed QCameraExposureControl.ExposureParameter.ShutterSpeed
+QCameraExposureControl.ExposureCompensation QCameraExposureControl.ExposureParameter.ExposureCompensation
+QCameraExposureControl.FlashPower QCameraExposureControl.ExposureParameter.FlashPower
+QCameraExposureControl.FlashCompensation QCameraExposureControl.ExposureParameter.FlashCompensation
+QCameraExposureControl.TorchPower QCameraExposureControl.ExposureParameter.TorchPower
+QCameraExposureControl.SpotMeteringPoint QCameraExposureControl.ExposureParameter.SpotMeteringPoint
+QCameraExposureControl.ExposureMode QCameraExposureControl.ExposureParameter.ExposureMode
+QCameraExposureControl.MeteringMode QCameraExposureControl.ExposureParameter.MeteringMode
+QCameraExposureControl.ExtendedExposureParameter QCameraExposureControl.ExposureParameter.ExtendedExposureParameter
+QCameraFeedbackControl.ViewfinderStarted QCameraFeedbackControl.EventType.ViewfinderStarted
+QCameraFeedbackControl.ViewfinderStopped QCameraFeedbackControl.EventType.ViewfinderStopped
+QCameraFeedbackControl.ImageCaptured QCameraFeedbackControl.EventType.ImageCaptured
+QCameraFeedbackControl.ImageSaved QCameraFeedbackControl.EventType.ImageSaved
+QCameraFeedbackControl.ImageError QCameraFeedbackControl.EventType.ImageError
+QCameraFeedbackControl.RecordingStarted QCameraFeedbackControl.EventType.RecordingStarted
+QCameraFeedbackControl.RecordingInProgress QCameraFeedbackControl.EventType.RecordingInProgress
+QCameraFeedbackControl.RecordingStopped QCameraFeedbackControl.EventType.RecordingStopped
+QCameraFeedbackControl.AutoFocusInProgress QCameraFeedbackControl.EventType.AutoFocusInProgress
+QCameraFeedbackControl.AutoFocusLocked QCameraFeedbackControl.EventType.AutoFocusLocked
+QCameraFeedbackControl.AutoFocusFailed QCameraFeedbackControl.EventType.AutoFocusFailed
+QCameraFocusZone.Invalid QCameraFocusZone.FocusZoneStatus.Invalid
+QCameraFocusZone.Unused QCameraFocusZone.FocusZoneStatus.Unused
+QCameraFocusZone.Selected QCameraFocusZone.FocusZoneStatus.Selected
+QCameraFocusZone.Focused QCameraFocusZone.FocusZoneStatus.Focused
+QCameraFocus.FocusPointAuto QCameraFocus.FocusPointMode.FocusPointAuto
+QCameraFocus.FocusPointCenter QCameraFocus.FocusPointMode.FocusPointCenter
+QCameraFocus.FocusPointFaceDetection QCameraFocus.FocusPointMode.FocusPointFaceDetection
+QCameraFocus.FocusPointCustom QCameraFocus.FocusPointMode.FocusPointCustom
+QCameraFocus.ManualFocus QCameraFocus.FocusMode.ManualFocus
+QCameraFocus.HyperfocalFocus QCameraFocus.FocusMode.HyperfocalFocus
+QCameraFocus.InfinityFocus QCameraFocus.FocusMode.InfinityFocus
+QCameraFocus.AutoFocus QCameraFocus.FocusMode.AutoFocus
+QCameraFocus.ContinuousFocus QCameraFocus.FocusMode.ContinuousFocus
+QCameraFocus.MacroFocus QCameraFocus.FocusMode.MacroFocus
+QCameraImageCapture.CaptureToFile QCameraImageCapture.CaptureDestination.CaptureToFile
+QCameraImageCapture.CaptureToBuffer QCameraImageCapture.CaptureDestination.CaptureToBuffer
+QCameraImageCapture.SingleImageCapture QCameraImageCapture.DriveMode.SingleImageCapture
+QCameraImageCapture.NoError QCameraImageCapture.Error.NoError
+QCameraImageCapture.NotReadyError QCameraImageCapture.Error.NotReadyError
+QCameraImageCapture.ResourceError QCameraImageCapture.Error.ResourceError
+QCameraImageCapture.OutOfSpaceError QCameraImageCapture.Error.OutOfSpaceError
+QCameraImageCapture.NotSupportedFeatureError QCameraImageCapture.Error.NotSupportedFeatureError
+QCameraImageCapture.FormatError QCameraImageCapture.Error.FormatError
+QCameraImageProcessing.ColorFilterNone QCameraImageProcessing.ColorFilter.ColorFilterNone
+QCameraImageProcessing.ColorFilterGrayscale QCameraImageProcessing.ColorFilter.ColorFilterGrayscale
+QCameraImageProcessing.ColorFilterNegative QCameraImageProcessing.ColorFilter.ColorFilterNegative
+QCameraImageProcessing.ColorFilterSolarize QCameraImageProcessing.ColorFilter.ColorFilterSolarize
+QCameraImageProcessing.ColorFilterSepia QCameraImageProcessing.ColorFilter.ColorFilterSepia
+QCameraImageProcessing.ColorFilterPosterize QCameraImageProcessing.ColorFilter.ColorFilterPosterize
+QCameraImageProcessing.ColorFilterWhiteboard QCameraImageProcessing.ColorFilter.ColorFilterWhiteboard
+QCameraImageProcessing.ColorFilterBlackboard QCameraImageProcessing.ColorFilter.ColorFilterBlackboard
+QCameraImageProcessing.ColorFilterAqua QCameraImageProcessing.ColorFilter.ColorFilterAqua
+QCameraImageProcessing.ColorFilterVendor QCameraImageProcessing.ColorFilter.ColorFilterVendor
+QCameraImageProcessing.WhiteBalanceAuto QCameraImageProcessing.WhiteBalanceMode.WhiteBalanceAuto
+QCameraImageProcessing.WhiteBalanceManual QCameraImageProcessing.WhiteBalanceMode.WhiteBalanceManual
+QCameraImageProcessing.WhiteBalanceSunlight QCameraImageProcessing.WhiteBalanceMode.WhiteBalanceSunlight
+QCameraImageProcessing.WhiteBalanceCloudy QCameraImageProcessing.WhiteBalanceMode.WhiteBalanceCloudy
+QCameraImageProcessing.WhiteBalanceShade QCameraImageProcessing.WhiteBalanceMode.WhiteBalanceShade
+QCameraImageProcessing.WhiteBalanceTungsten QCameraImageProcessing.WhiteBalanceMode.WhiteBalanceTungsten
+QCameraImageProcessing.WhiteBalanceFluorescent QCameraImageProcessing.WhiteBalanceMode.WhiteBalanceFluorescent
+QCameraImageProcessing.WhiteBalanceFlash QCameraImageProcessing.WhiteBalanceMode.WhiteBalanceFlash
+QCameraImageProcessing.WhiteBalanceSunset QCameraImageProcessing.WhiteBalanceMode.WhiteBalanceSunset
+QCameraImageProcessing.WhiteBalanceVendor QCameraImageProcessing.WhiteBalanceMode.WhiteBalanceVendor
+QCameraImageProcessingControl.WhiteBalancePreset QCameraImageProcessingControl.ProcessingParameter.WhiteBalancePreset
+QCameraImageProcessingControl.ColorTemperature QCameraImageProcessingControl.ProcessingParameter.ColorTemperature
+QCameraImageProcessingControl.Contrast QCameraImageProcessingControl.ProcessingParameter.Contrast
+QCameraImageProcessingControl.Saturation QCameraImageProcessingControl.ProcessingParameter.Saturation
+QCameraImageProcessingControl.Brightness QCameraImageProcessingControl.ProcessingParameter.Brightness
+QCameraImageProcessingControl.Sharpening QCameraImageProcessingControl.ProcessingParameter.Sharpening
+QCameraImageProcessingControl.Denoising QCameraImageProcessingControl.ProcessingParameter.Denoising
+QCameraImageProcessingControl.ContrastAdjustment QCameraImageProcessingControl.ProcessingParameter.ContrastAdjustment
+QCameraImageProcessingControl.SaturationAdjustment QCameraImageProcessingControl.ProcessingParameter.SaturationAdjustment
+QCameraImageProcessingControl.BrightnessAdjustment QCameraImageProcessingControl.ProcessingParameter.BrightnessAdjustment
+QCameraImageProcessingControl.SharpeningAdjustment QCameraImageProcessingControl.ProcessingParameter.SharpeningAdjustment
+QCameraImageProcessingControl.DenoisingAdjustment QCameraImageProcessingControl.ProcessingParameter.DenoisingAdjustment
+QCameraImageProcessingControl.ColorFilter QCameraImageProcessingControl.ProcessingParameter.ColorFilter
+QCameraImageProcessingControl.ExtendedParameter QCameraImageProcessingControl.ProcessingParameter.ExtendedParameter
+QCameraViewfinderSettingsControl.Resolution QCameraViewfinderSettingsControl.ViewfinderParameter.Resolution
+QCameraViewfinderSettingsControl.PixelAspectRatio QCameraViewfinderSettingsControl.ViewfinderParameter.PixelAspectRatio
+QCameraViewfinderSettingsControl.MinimumFrameRate QCameraViewfinderSettingsControl.ViewfinderParameter.MinimumFrameRate
+QCameraViewfinderSettingsControl.MaximumFrameRate QCameraViewfinderSettingsControl.ViewfinderParameter.MaximumFrameRate
+QCameraViewfinderSettingsControl.PixelFormat QCameraViewfinderSettingsControl.ViewfinderParameter.PixelFormat
+QCameraViewfinderSettingsControl.UserParameter QCameraViewfinderSettingsControl.ViewfinderParameter.UserParameter
+QMediaPlayer.NoError QMediaPlayer.Error.NoError
+QMediaPlayer.ResourceError QMediaPlayer.Error.ResourceError
+QMediaPlayer.FormatError QMediaPlayer.Error.FormatError
+QMediaPlayer.NetworkError QMediaPlayer.Error.NetworkError
+QMediaPlayer.AccessDeniedError QMediaPlayer.Error.AccessDeniedError
+QMediaPlayer.ServiceMissingError QMediaPlayer.Error.ServiceMissingError
+QMediaPlayer.LowLatency QMediaPlayer.Flag.LowLatency
+QMediaPlayer.StreamPlayback QMediaPlayer.Flag.StreamPlayback
+QMediaPlayer.VideoSurface QMediaPlayer.Flag.VideoSurface
+QMediaPlayer.UnknownMediaStatus QMediaPlayer.MediaStatus.UnknownMediaStatus
+QMediaPlayer.NoMedia QMediaPlayer.MediaStatus.NoMedia
+QMediaPlayer.LoadingMedia QMediaPlayer.MediaStatus.LoadingMedia
+QMediaPlayer.LoadedMedia QMediaPlayer.MediaStatus.LoadedMedia
+QMediaPlayer.StalledMedia QMediaPlayer.MediaStatus.StalledMedia
+QMediaPlayer.BufferingMedia QMediaPlayer.MediaStatus.BufferingMedia
+QMediaPlayer.BufferedMedia QMediaPlayer.MediaStatus.BufferedMedia
+QMediaPlayer.EndOfMedia QMediaPlayer.MediaStatus.EndOfMedia
+QMediaPlayer.InvalidMedia QMediaPlayer.MediaStatus.InvalidMedia
+QMediaPlayer.StoppedState QMediaPlayer.State.StoppedState
+QMediaPlayer.PlayingState QMediaPlayer.State.PlayingState
+QMediaPlayer.PausedState QMediaPlayer.State.PausedState
+QMediaPlaylist.NoError QMediaPlaylist.Error.NoError
+QMediaPlaylist.FormatError QMediaPlaylist.Error.FormatError
+QMediaPlaylist.FormatNotSupportedError QMediaPlaylist.Error.FormatNotSupportedError
+QMediaPlaylist.NetworkError QMediaPlaylist.Error.NetworkError
+QMediaPlaylist.AccessDeniedError QMediaPlaylist.Error.AccessDeniedError
+QMediaPlaylist.CurrentItemOnce QMediaPlaylist.PlaybackMode.CurrentItemOnce
+QMediaPlaylist.CurrentItemInLoop QMediaPlaylist.PlaybackMode.CurrentItemInLoop
+QMediaPlaylist.Sequential QMediaPlaylist.PlaybackMode.Sequential
+QMediaPlaylist.Loop QMediaPlaylist.PlaybackMode.Loop
+QMediaPlaylist.Random QMediaPlaylist.PlaybackMode.Random
+QMediaStreamsControl.UnknownStream QMediaStreamsControl.StreamType.UnknownStream
+QMediaStreamsControl.VideoStream QMediaStreamsControl.StreamType.VideoStream
+QMediaStreamsControl.AudioStream QMediaStreamsControl.StreamType.AudioStream
+QMediaStreamsControl.SubPictureStream QMediaStreamsControl.StreamType.SubPictureStream
+QMediaStreamsControl.DataStream QMediaStreamsControl.StreamType.DataStream
+QMultimedia.Available QMultimedia.AvailabilityStatus.Available
+QMultimedia.ServiceMissing QMultimedia.AvailabilityStatus.ServiceMissing
+QMultimedia.Busy QMultimedia.AvailabilityStatus.Busy
+QMultimedia.ResourceError QMultimedia.AvailabilityStatus.ResourceError
+QMultimedia.ConstantQualityEncoding QMultimedia.EncodingMode.ConstantQualityEncoding
+QMultimedia.ConstantBitRateEncoding QMultimedia.EncodingMode.ConstantBitRateEncoding
+QMultimedia.AverageBitRateEncoding QMultimedia.EncodingMode.AverageBitRateEncoding
+QMultimedia.TwoPassEncoding QMultimedia.EncodingMode.TwoPassEncoding
+QMultimedia.VeryLowQuality QMultimedia.EncodingQuality.VeryLowQuality
+QMultimedia.LowQuality QMultimedia.EncodingQuality.LowQuality
+QMultimedia.NormalQuality QMultimedia.EncodingQuality.NormalQuality
+QMultimedia.HighQuality QMultimedia.EncodingQuality.HighQuality
+QMultimedia.VeryHighQuality QMultimedia.EncodingQuality.VeryHighQuality
+QMultimedia.NotSupported QMultimedia.SupportEstimate.NotSupported
+QMultimedia.MaybeSupported QMultimedia.SupportEstimate.MaybeSupported
+QMultimedia.ProbablySupported QMultimedia.SupportEstimate.ProbablySupported
+QMultimedia.PreferredService QMultimedia.SupportEstimate.PreferredService
+QRadioData.Undefined QRadioData.ProgramType.Undefined
+QRadioData.News QRadioData.ProgramType.News
+QRadioData.CurrentAffairs QRadioData.ProgramType.CurrentAffairs
+QRadioData.Information QRadioData.ProgramType.Information
+QRadioData.Sport QRadioData.ProgramType.Sport
+QRadioData.Education QRadioData.ProgramType.Education
+QRadioData.Drama QRadioData.ProgramType.Drama
+QRadioData.Culture QRadioData.ProgramType.Culture
+QRadioData.Science QRadioData.ProgramType.Science
+QRadioData.Varied QRadioData.ProgramType.Varied
+QRadioData.PopMusic QRadioData.ProgramType.PopMusic
+QRadioData.RockMusic QRadioData.ProgramType.RockMusic
+QRadioData.EasyListening QRadioData.ProgramType.EasyListening
+QRadioData.LightClassical QRadioData.ProgramType.LightClassical
+QRadioData.SeriousClassical QRadioData.ProgramType.SeriousClassical
+QRadioData.OtherMusic QRadioData.ProgramType.OtherMusic
+QRadioData.Weather QRadioData.ProgramType.Weather
+QRadioData.Finance QRadioData.ProgramType.Finance
+QRadioData.ChildrensProgrammes QRadioData.ProgramType.ChildrensProgrammes
+QRadioData.SocialAffairs QRadioData.ProgramType.SocialAffairs
+QRadioData.Religion QRadioData.ProgramType.Religion
+QRadioData.PhoneIn QRadioData.ProgramType.PhoneIn
+QRadioData.Travel QRadioData.ProgramType.Travel
+QRadioData.Leisure QRadioData.ProgramType.Leisure
+QRadioData.JazzMusic QRadioData.ProgramType.JazzMusic
+QRadioData.CountryMusic QRadioData.ProgramType.CountryMusic
+QRadioData.NationalMusic QRadioData.ProgramType.NationalMusic
+QRadioData.OldiesMusic QRadioData.ProgramType.OldiesMusic
+QRadioData.FolkMusic QRadioData.ProgramType.FolkMusic
+QRadioData.Documentary QRadioData.ProgramType.Documentary
+QRadioData.AlarmTest QRadioData.ProgramType.AlarmTest
+QRadioData.Alarm QRadioData.ProgramType.Alarm
+QRadioData.Talk QRadioData.ProgramType.Talk
+QRadioData.ClassicRock QRadioData.ProgramType.ClassicRock
+QRadioData.AdultHits QRadioData.ProgramType.AdultHits
+QRadioData.SoftRock QRadioData.ProgramType.SoftRock
+QRadioData.Top40 QRadioData.ProgramType.Top40
+QRadioData.Soft QRadioData.ProgramType.Soft
+QRadioData.Nostalgia QRadioData.ProgramType.Nostalgia
+QRadioData.Classical QRadioData.ProgramType.Classical
+QRadioData.RhythmAndBlues QRadioData.ProgramType.RhythmAndBlues
+QRadioData.SoftRhythmAndBlues QRadioData.ProgramType.SoftRhythmAndBlues
+QRadioData.Language QRadioData.ProgramType.Language
+QRadioData.ReligiousMusic QRadioData.ProgramType.ReligiousMusic
+QRadioData.ReligiousTalk QRadioData.ProgramType.ReligiousTalk
+QRadioData.Personality QRadioData.ProgramType.Personality
+QRadioData.Public QRadioData.ProgramType.Public
+QRadioData.College QRadioData.ProgramType.College
+QRadioData.NoError QRadioData.Error.NoError
+QRadioData.ResourceError QRadioData.Error.ResourceError
+QRadioData.OpenError QRadioData.Error.OpenError
+QRadioData.OutOfRangeError QRadioData.Error.OutOfRangeError
+QRadioTuner.SearchFast QRadioTuner.SearchMode.SearchFast
+QRadioTuner.SearchGetStationId QRadioTuner.SearchMode.SearchGetStationId
+QRadioTuner.ForceStereo QRadioTuner.StereoMode.ForceStereo
+QRadioTuner.ForceMono QRadioTuner.StereoMode.ForceMono
+QRadioTuner.Auto QRadioTuner.StereoMode.Auto
+QRadioTuner.NoError QRadioTuner.Error.NoError
+QRadioTuner.ResourceError QRadioTuner.Error.ResourceError
+QRadioTuner.OpenError QRadioTuner.Error.OpenError
+QRadioTuner.OutOfRangeError QRadioTuner.Error.OutOfRangeError
+QRadioTuner.AM QRadioTuner.Band.AM
+QRadioTuner.FM QRadioTuner.Band.FM
+QRadioTuner.SW QRadioTuner.Band.SW
+QRadioTuner.LW QRadioTuner.Band.LW
+QRadioTuner.FM2 QRadioTuner.Band.FM2
+QRadioTuner.ActiveState QRadioTuner.State.ActiveState
+QRadioTuner.StoppedState QRadioTuner.State.StoppedState
+QSound.Infinite QSound.Loop.Infinite
+QSoundEffect.Null QSoundEffect.Status.Null
+QSoundEffect.Loading QSoundEffect.Status.Loading
+QSoundEffect.Ready QSoundEffect.Status.Ready
+QSoundEffect.Error QSoundEffect.Status.Error
+QSoundEffect.Infinite QSoundEffect.Loop.Infinite
+QVideoFrame.Format_Invalid QVideoFrame.PixelFormat.Format_Invalid
+QVideoFrame.Format_ARGB32 QVideoFrame.PixelFormat.Format_ARGB32
+QVideoFrame.Format_ARGB32_Premultiplied QVideoFrame.PixelFormat.Format_ARGB32_Premultiplied
+QVideoFrame.Format_RGB32 QVideoFrame.PixelFormat.Format_RGB32
+QVideoFrame.Format_RGB24 QVideoFrame.PixelFormat.Format_RGB24
+QVideoFrame.Format_RGB565 QVideoFrame.PixelFormat.Format_RGB565
+QVideoFrame.Format_RGB555 QVideoFrame.PixelFormat.Format_RGB555
+QVideoFrame.Format_ARGB8565_Premultiplied QVideoFrame.PixelFormat.Format_ARGB8565_Premultiplied
+QVideoFrame.Format_BGRA32 QVideoFrame.PixelFormat.Format_BGRA32
+QVideoFrame.Format_BGRA32_Premultiplied QVideoFrame.PixelFormat.Format_BGRA32_Premultiplied
+QVideoFrame.Format_BGR32 QVideoFrame.PixelFormat.Format_BGR32
+QVideoFrame.Format_BGR24 QVideoFrame.PixelFormat.Format_BGR24
+QVideoFrame.Format_BGR565 QVideoFrame.PixelFormat.Format_BGR565
+QVideoFrame.Format_BGR555 QVideoFrame.PixelFormat.Format_BGR555
+QVideoFrame.Format_BGRA5658_Premultiplied QVideoFrame.PixelFormat.Format_BGRA5658_Premultiplied
+QVideoFrame.Format_AYUV444 QVideoFrame.PixelFormat.Format_AYUV444
+QVideoFrame.Format_AYUV444_Premultiplied QVideoFrame.PixelFormat.Format_AYUV444_Premultiplied
+QVideoFrame.Format_YUV444 QVideoFrame.PixelFormat.Format_YUV444
+QVideoFrame.Format_YUV420P QVideoFrame.PixelFormat.Format_YUV420P
+QVideoFrame.Format_YV12 QVideoFrame.PixelFormat.Format_YV12
+QVideoFrame.Format_UYVY QVideoFrame.PixelFormat.Format_UYVY
+QVideoFrame.Format_YUYV QVideoFrame.PixelFormat.Format_YUYV
+QVideoFrame.Format_NV12 QVideoFrame.PixelFormat.Format_NV12
+QVideoFrame.Format_NV21 QVideoFrame.PixelFormat.Format_NV21
+QVideoFrame.Format_IMC1 QVideoFrame.PixelFormat.Format_IMC1
+QVideoFrame.Format_IMC2 QVideoFrame.PixelFormat.Format_IMC2
+QVideoFrame.Format_IMC3 QVideoFrame.PixelFormat.Format_IMC3
+QVideoFrame.Format_IMC4 QVideoFrame.PixelFormat.Format_IMC4
+QVideoFrame.Format_Y8 QVideoFrame.PixelFormat.Format_Y8
+QVideoFrame.Format_Y16 QVideoFrame.PixelFormat.Format_Y16
+QVideoFrame.Format_Jpeg QVideoFrame.PixelFormat.Format_Jpeg
+QVideoFrame.Format_CameraRaw QVideoFrame.PixelFormat.Format_CameraRaw
+QVideoFrame.Format_AdobeDng QVideoFrame.PixelFormat.Format_AdobeDng
+QVideoFrame.Format_ABGR32 QVideoFrame.PixelFormat.Format_ABGR32
+QVideoFrame.Format_YUV422P QVideoFrame.PixelFormat.Format_YUV422P
+QVideoFrame.Format_User QVideoFrame.PixelFormat.Format_User
+QVideoFrame.ProgressiveFrame QVideoFrame.FieldType.ProgressiveFrame
+QVideoFrame.TopField QVideoFrame.FieldType.TopField
+QVideoFrame.BottomField QVideoFrame.FieldType.BottomField
+QVideoFrame.InterlacedFrame QVideoFrame.FieldType.InterlacedFrame
+QVideoSurfaceFormat.YCbCr_Undefined QVideoSurfaceFormat.YCbCrColorSpace.YCbCr_Undefined
+QVideoSurfaceFormat.YCbCr_BT601 QVideoSurfaceFormat.YCbCrColorSpace.YCbCr_BT601
+QVideoSurfaceFormat.YCbCr_BT709 QVideoSurfaceFormat.YCbCrColorSpace.YCbCr_BT709
+QVideoSurfaceFormat.YCbCr_xvYCC601 QVideoSurfaceFormat.YCbCrColorSpace.YCbCr_xvYCC601
+QVideoSurfaceFormat.YCbCr_xvYCC709 QVideoSurfaceFormat.YCbCrColorSpace.YCbCr_xvYCC709
+QVideoSurfaceFormat.YCbCr_JPEG QVideoSurfaceFormat.YCbCrColorSpace.YCbCr_JPEG
+QVideoSurfaceFormat.TopToBottom QVideoSurfaceFormat.Direction.TopToBottom
+QVideoSurfaceFormat.BottomToTop QVideoSurfaceFormat.Direction.BottomToTop
+QAbstractSocket.PauseNever QAbstractSocket.PauseMode.PauseNever
+QAbstractSocket.PauseOnSslErrors QAbstractSocket.PauseMode.PauseOnSslErrors
+QAbstractSocket.DefaultForPlatform QAbstractSocket.BindFlag.DefaultForPlatform
+QAbstractSocket.ShareAddress QAbstractSocket.BindFlag.ShareAddress
+QAbstractSocket.DontShareAddress QAbstractSocket.BindFlag.DontShareAddress
+QAbstractSocket.ReuseAddressHint QAbstractSocket.BindFlag.ReuseAddressHint
+QAbstractSocket.LowDelayOption QAbstractSocket.SocketOption.LowDelayOption
+QAbstractSocket.KeepAliveOption QAbstractSocket.SocketOption.KeepAliveOption
+QAbstractSocket.MulticastTtlOption QAbstractSocket.SocketOption.MulticastTtlOption
+QAbstractSocket.MulticastLoopbackOption QAbstractSocket.SocketOption.MulticastLoopbackOption
+QAbstractSocket.TypeOfServiceOption QAbstractSocket.SocketOption.TypeOfServiceOption
+QAbstractSocket.SendBufferSizeSocketOption QAbstractSocket.SocketOption.SendBufferSizeSocketOption
+QAbstractSocket.ReceiveBufferSizeSocketOption QAbstractSocket.SocketOption.ReceiveBufferSizeSocketOption
+QAbstractSocket.PathMtuSocketOption QAbstractSocket.SocketOption.PathMtuSocketOption
+QAbstractSocket.UnconnectedState QAbstractSocket.SocketState.UnconnectedState
+QAbstractSocket.HostLookupState QAbstractSocket.SocketState.HostLookupState
+QAbstractSocket.ConnectingState QAbstractSocket.SocketState.ConnectingState
+QAbstractSocket.ConnectedState QAbstractSocket.SocketState.ConnectedState
+QAbstractSocket.BoundState QAbstractSocket.SocketState.BoundState
+QAbstractSocket.ListeningState QAbstractSocket.SocketState.ListeningState
+QAbstractSocket.ClosingState QAbstractSocket.SocketState.ClosingState
+QAbstractSocket.ConnectionRefusedError QAbstractSocket.SocketError.ConnectionRefusedError
+QAbstractSocket.RemoteHostClosedError QAbstractSocket.SocketError.RemoteHostClosedError
+QAbstractSocket.HostNotFoundError QAbstractSocket.SocketError.HostNotFoundError
+QAbstractSocket.SocketAccessError QAbstractSocket.SocketError.SocketAccessError
+QAbstractSocket.SocketResourceError QAbstractSocket.SocketError.SocketResourceError
+QAbstractSocket.SocketTimeoutError QAbstractSocket.SocketError.SocketTimeoutError
+QAbstractSocket.DatagramTooLargeError QAbstractSocket.SocketError.DatagramTooLargeError
+QAbstractSocket.NetworkError QAbstractSocket.SocketError.NetworkError
+QAbstractSocket.AddressInUseError QAbstractSocket.SocketError.AddressInUseError
+QAbstractSocket.SocketAddressNotAvailableError QAbstractSocket.SocketError.SocketAddressNotAvailableError
+QAbstractSocket.UnsupportedSocketOperationError QAbstractSocket.SocketError.UnsupportedSocketOperationError
+QAbstractSocket.UnfinishedSocketOperationError QAbstractSocket.SocketError.UnfinishedSocketOperationError
+QAbstractSocket.ProxyAuthenticationRequiredError QAbstractSocket.SocketError.ProxyAuthenticationRequiredError
+QAbstractSocket.SslHandshakeFailedError QAbstractSocket.SocketError.SslHandshakeFailedError
+QAbstractSocket.ProxyConnectionRefusedError QAbstractSocket.SocketError.ProxyConnectionRefusedError
+QAbstractSocket.ProxyConnectionClosedError QAbstractSocket.SocketError.ProxyConnectionClosedError
+QAbstractSocket.ProxyConnectionTimeoutError QAbstractSocket.SocketError.ProxyConnectionTimeoutError
+QAbstractSocket.ProxyNotFoundError QAbstractSocket.SocketError.ProxyNotFoundError
+QAbstractSocket.ProxyProtocolError QAbstractSocket.SocketError.ProxyProtocolError
+QAbstractSocket.OperationError QAbstractSocket.SocketError.OperationError
+QAbstractSocket.SslInternalError QAbstractSocket.SocketError.SslInternalError
+QAbstractSocket.SslInvalidUserDataError QAbstractSocket.SocketError.SslInvalidUserDataError
+QAbstractSocket.TemporaryError QAbstractSocket.SocketError.TemporaryError
+QAbstractSocket.UnknownSocketError QAbstractSocket.SocketError.UnknownSocketError
+QAbstractSocket.IPv4Protocol QAbstractSocket.NetworkLayerProtocol.IPv4Protocol
+QAbstractSocket.IPv6Protocol QAbstractSocket.NetworkLayerProtocol.IPv6Protocol
+QAbstractSocket.AnyIPProtocol QAbstractSocket.NetworkLayerProtocol.AnyIPProtocol
+QAbstractSocket.UnknownNetworkLayerProtocol QAbstractSocket.NetworkLayerProtocol.UnknownNetworkLayerProtocol
+QAbstractSocket.TcpSocket QAbstractSocket.SocketType.TcpSocket
+QAbstractSocket.UdpSocket QAbstractSocket.SocketType.UdpSocket
+QAbstractSocket.SctpSocket QAbstractSocket.SocketType.SctpSocket
+QAbstractSocket.UnknownSocketType QAbstractSocket.SocketType.UnknownSocketType
+QDnsLookup.A QDnsLookup.Type.A
+QDnsLookup.AAAA QDnsLookup.Type.AAAA
+QDnsLookup.ANY QDnsLookup.Type.ANY
+QDnsLookup.CNAME QDnsLookup.Type.CNAME
+QDnsLookup.MX QDnsLookup.Type.MX
+QDnsLookup.NS QDnsLookup.Type.NS
+QDnsLookup.PTR QDnsLookup.Type.PTR
+QDnsLookup.SRV QDnsLookup.Type.SRV
+QDnsLookup.TXT QDnsLookup.Type.TXT
+QDnsLookup.NoError QDnsLookup.Error.NoError
+QDnsLookup.ResolverError QDnsLookup.Error.ResolverError
+QDnsLookup.OperationCancelledError QDnsLookup.Error.OperationCancelledError
+QDnsLookup.InvalidRequestError QDnsLookup.Error.InvalidRequestError
+QDnsLookup.InvalidReplyError QDnsLookup.Error.InvalidReplyError
+QDnsLookup.ServerFailureError QDnsLookup.Error.ServerFailureError
+QDnsLookup.ServerRefusedError QDnsLookup.Error.ServerRefusedError
+QDnsLookup.NotFoundError QDnsLookup.Error.NotFoundError
+QHostAddress.ConvertV4MappedToIPv4 QHostAddress.ConversionModeFlag.ConvertV4MappedToIPv4
+QHostAddress.ConvertV4CompatToIPv4 QHostAddress.ConversionModeFlag.ConvertV4CompatToIPv4
+QHostAddress.ConvertUnspecifiedAddress QHostAddress.ConversionModeFlag.ConvertUnspecifiedAddress
+QHostAddress.ConvertLocalHost QHostAddress.ConversionModeFlag.ConvertLocalHost
+QHostAddress.TolerantConversion QHostAddress.ConversionModeFlag.TolerantConversion
+QHostAddress.StrictConversion QHostAddress.ConversionModeFlag.StrictConversion
+QHostAddress.Null QHostAddress.SpecialAddress.Null
+QHostAddress.Broadcast QHostAddress.SpecialAddress.Broadcast
+QHostAddress.LocalHost QHostAddress.SpecialAddress.LocalHost
+QHostAddress.LocalHostIPv6 QHostAddress.SpecialAddress.LocalHostIPv6
+QHostAddress.AnyIPv4 QHostAddress.SpecialAddress.AnyIPv4
+QHostAddress.AnyIPv6 QHostAddress.SpecialAddress.AnyIPv6
+QHostAddress.Any QHostAddress.SpecialAddress.Any
+QHostInfo.NoError QHostInfo.HostInfoError.NoError
+QHostInfo.HostNotFound QHostInfo.HostInfoError.HostNotFound
+QHostInfo.UnknownError QHostInfo.HostInfoError.UnknownError
+QHstsPolicy.IncludeSubDomains QHstsPolicy.PolicyFlag.IncludeSubDomains
+QHttpMultiPart.MixedType QHttpMultiPart.ContentType.MixedType
+QHttpMultiPart.RelatedType QHttpMultiPart.ContentType.RelatedType
+QHttpMultiPart.FormDataType QHttpMultiPart.ContentType.FormDataType
+QHttpMultiPart.AlternativeType QHttpMultiPart.ContentType.AlternativeType
+QLocalServer.UserAccessOption QLocalServer.SocketOption.UserAccessOption
+QLocalServer.GroupAccessOption QLocalServer.SocketOption.GroupAccessOption
+QLocalServer.OtherAccessOption QLocalServer.SocketOption.OtherAccessOption
+QLocalServer.WorldAccessOption QLocalServer.SocketOption.WorldAccessOption
+QLocalSocket.UnconnectedState QLocalSocket.LocalSocketState.UnconnectedState
+QLocalSocket.ConnectingState QLocalSocket.LocalSocketState.ConnectingState
+QLocalSocket.ConnectedState QLocalSocket.LocalSocketState.ConnectedState
+QLocalSocket.ClosingState QLocalSocket.LocalSocketState.ClosingState
+QLocalSocket.ConnectionRefusedError QLocalSocket.LocalSocketError.ConnectionRefusedError
+QLocalSocket.PeerClosedError QLocalSocket.LocalSocketError.PeerClosedError
+QLocalSocket.ServerNotFoundError QLocalSocket.LocalSocketError.ServerNotFoundError
+QLocalSocket.SocketAccessError QLocalSocket.LocalSocketError.SocketAccessError
+QLocalSocket.SocketResourceError QLocalSocket.LocalSocketError.SocketResourceError
+QLocalSocket.SocketTimeoutError QLocalSocket.LocalSocketError.SocketTimeoutError
+QLocalSocket.DatagramTooLargeError QLocalSocket.LocalSocketError.DatagramTooLargeError
+QLocalSocket.ConnectionError QLocalSocket.LocalSocketError.ConnectionError
+QLocalSocket.UnsupportedSocketOperationError QLocalSocket.LocalSocketError.UnsupportedSocketOperationError
+QLocalSocket.OperationError QLocalSocket.LocalSocketError.OperationError
+QLocalSocket.UnknownSocketError QLocalSocket.LocalSocketError.UnknownSocketError
+QNetworkAccessManager.UnknownAccessibility QNetworkAccessManager.NetworkAccessibility.UnknownAccessibility
+QNetworkAccessManager.NotAccessible QNetworkAccessManager.NetworkAccessibility.NotAccessible
+QNetworkAccessManager.Accessible QNetworkAccessManager.NetworkAccessibility.Accessible
+QNetworkAccessManager.HeadOperation QNetworkAccessManager.Operation.HeadOperation
+QNetworkAccessManager.GetOperation QNetworkAccessManager.Operation.GetOperation
+QNetworkAccessManager.PutOperation QNetworkAccessManager.Operation.PutOperation
+QNetworkAccessManager.PostOperation QNetworkAccessManager.Operation.PostOperation
+QNetworkAccessManager.DeleteOperation QNetworkAccessManager.Operation.DeleteOperation
+QNetworkAccessManager.CustomOperation QNetworkAccessManager.Operation.CustomOperation
+QNetworkConfigurationManager.CanStartAndStopInterfaces QNetworkConfigurationManager.Capability.CanStartAndStopInterfaces
+QNetworkConfigurationManager.DirectConnectionRouting QNetworkConfigurationManager.Capability.DirectConnectionRouting
+QNetworkConfigurationManager.SystemSessionSupport QNetworkConfigurationManager.Capability.SystemSessionSupport
+QNetworkConfigurationManager.ApplicationLevelRoaming QNetworkConfigurationManager.Capability.ApplicationLevelRoaming
+QNetworkConfigurationManager.ForcedRoaming QNetworkConfigurationManager.Capability.ForcedRoaming
+QNetworkConfigurationManager.DataStatistics QNetworkConfigurationManager.Capability.DataStatistics
+QNetworkConfigurationManager.NetworkSessionRequired QNetworkConfigurationManager.Capability.NetworkSessionRequired
+QNetworkConfiguration.BearerUnknown QNetworkConfiguration.BearerType.BearerUnknown
+QNetworkConfiguration.BearerEthernet QNetworkConfiguration.BearerType.BearerEthernet
+QNetworkConfiguration.BearerWLAN QNetworkConfiguration.BearerType.BearerWLAN
+QNetworkConfiguration.Bearer2G QNetworkConfiguration.BearerType.Bearer2G
+QNetworkConfiguration.BearerCDMA2000 QNetworkConfiguration.BearerType.BearerCDMA2000
+QNetworkConfiguration.BearerWCDMA QNetworkConfiguration.BearerType.BearerWCDMA
+QNetworkConfiguration.BearerHSPA QNetworkConfiguration.BearerType.BearerHSPA
+QNetworkConfiguration.BearerBluetooth QNetworkConfiguration.BearerType.BearerBluetooth
+QNetworkConfiguration.BearerWiMAX QNetworkConfiguration.BearerType.BearerWiMAX
+QNetworkConfiguration.BearerEVDO QNetworkConfiguration.BearerType.BearerEVDO
+QNetworkConfiguration.BearerLTE QNetworkConfiguration.BearerType.BearerLTE
+QNetworkConfiguration.Bearer3G QNetworkConfiguration.BearerType.Bearer3G
+QNetworkConfiguration.Bearer4G QNetworkConfiguration.BearerType.Bearer4G
+QNetworkConfiguration.Undefined QNetworkConfiguration.StateFlag.Undefined
+QNetworkConfiguration.Defined QNetworkConfiguration.StateFlag.Defined
+QNetworkConfiguration.Discovered QNetworkConfiguration.StateFlag.Discovered
+QNetworkConfiguration.Active QNetworkConfiguration.StateFlag.Active
+QNetworkConfiguration.UnknownPurpose QNetworkConfiguration.Purpose.UnknownPurpose
+QNetworkConfiguration.PublicPurpose QNetworkConfiguration.Purpose.PublicPurpose
+QNetworkConfiguration.PrivatePurpose QNetworkConfiguration.Purpose.PrivatePurpose
+QNetworkConfiguration.ServiceSpecificPurpose QNetworkConfiguration.Purpose.ServiceSpecificPurpose
+QNetworkConfiguration.InternetAccessPoint QNetworkConfiguration.Type.InternetAccessPoint
+QNetworkConfiguration.ServiceNetwork QNetworkConfiguration.Type.ServiceNetwork
+QNetworkConfiguration.UserChoice QNetworkConfiguration.Type.UserChoice
+QNetworkConfiguration.Invalid QNetworkConfiguration.Type.Invalid
+QNetworkCookie.NameAndValueOnly QNetworkCookie.RawForm.NameAndValueOnly
+QNetworkCookie.Full QNetworkCookie.RawForm.Full
+QNetworkAddressEntry.DnsEligibilityUnknown QNetworkAddressEntry.DnsEligibilityStatus.DnsEligibilityUnknown
+QNetworkAddressEntry.DnsIneligible QNetworkAddressEntry.DnsEligibilityStatus.DnsIneligible
+QNetworkAddressEntry.DnsEligible QNetworkAddressEntry.DnsEligibilityStatus.DnsEligible
+QNetworkInterface.Unknown QNetworkInterface.InterfaceType.Unknown
+QNetworkInterface.Loopback QNetworkInterface.InterfaceType.Loopback
+QNetworkInterface.Virtual QNetworkInterface.InterfaceType.Virtual
+QNetworkInterface.Ethernet QNetworkInterface.InterfaceType.Ethernet
+QNetworkInterface.Slip QNetworkInterface.InterfaceType.Slip
+QNetworkInterface.CanBus QNetworkInterface.InterfaceType.CanBus
+QNetworkInterface.Ppp QNetworkInterface.InterfaceType.Ppp
+QNetworkInterface.Fddi QNetworkInterface.InterfaceType.Fddi
+QNetworkInterface.Wifi QNetworkInterface.InterfaceType.Wifi
+QNetworkInterface.Ieee80211 QNetworkInterface.InterfaceType.Ieee80211
+QNetworkInterface.Phonet QNetworkInterface.InterfaceType.Phonet
+QNetworkInterface.Ieee802154 QNetworkInterface.InterfaceType.Ieee802154
+QNetworkInterface.SixLoWPAN QNetworkInterface.InterfaceType.SixLoWPAN
+QNetworkInterface.Ieee80216 QNetworkInterface.InterfaceType.Ieee80216
+QNetworkInterface.Ieee1394 QNetworkInterface.InterfaceType.Ieee1394
+QNetworkInterface.IsUp QNetworkInterface.InterfaceFlag.IsUp
+QNetworkInterface.IsRunning QNetworkInterface.InterfaceFlag.IsRunning
+QNetworkInterface.CanBroadcast QNetworkInterface.InterfaceFlag.CanBroadcast
+QNetworkInterface.IsLoopBack QNetworkInterface.InterfaceFlag.IsLoopBack
+QNetworkInterface.IsPointToPoint QNetworkInterface.InterfaceFlag.IsPointToPoint
+QNetworkInterface.CanMulticast QNetworkInterface.InterfaceFlag.CanMulticast
+QNetworkProxy.TunnelingCapability QNetworkProxy.Capability.TunnelingCapability
+QNetworkProxy.ListeningCapability QNetworkProxy.Capability.ListeningCapability
+QNetworkProxy.UdpTunnelingCapability QNetworkProxy.Capability.UdpTunnelingCapability
+QNetworkProxy.CachingCapability QNetworkProxy.Capability.CachingCapability
+QNetworkProxy.HostNameLookupCapability QNetworkProxy.Capability.HostNameLookupCapability
+QNetworkProxy.SctpTunnelingCapability QNetworkProxy.Capability.SctpTunnelingCapability
+QNetworkProxy.SctpListeningCapability QNetworkProxy.Capability.SctpListeningCapability
+QNetworkProxy.DefaultProxy QNetworkProxy.ProxyType.DefaultProxy
+QNetworkProxy.Socks5Proxy QNetworkProxy.ProxyType.Socks5Proxy
+QNetworkProxy.NoProxy QNetworkProxy.ProxyType.NoProxy
+QNetworkProxy.HttpProxy QNetworkProxy.ProxyType.HttpProxy
+QNetworkProxy.HttpCachingProxy QNetworkProxy.ProxyType.HttpCachingProxy
+QNetworkProxy.FtpCachingProxy QNetworkProxy.ProxyType.FtpCachingProxy
+QNetworkProxyQuery.TcpSocket QNetworkProxyQuery.QueryType.TcpSocket
+QNetworkProxyQuery.UdpSocket QNetworkProxyQuery.QueryType.UdpSocket
+QNetworkProxyQuery.TcpServer QNetworkProxyQuery.QueryType.TcpServer
+QNetworkProxyQuery.UrlRequest QNetworkProxyQuery.QueryType.UrlRequest
+QNetworkProxyQuery.SctpSocket QNetworkProxyQuery.QueryType.SctpSocket
+QNetworkProxyQuery.SctpServer QNetworkProxyQuery.QueryType.SctpServer
+QNetworkReply.NoError QNetworkReply.NetworkError.NoError
+QNetworkReply.ConnectionRefusedError QNetworkReply.NetworkError.ConnectionRefusedError
+QNetworkReply.RemoteHostClosedError QNetworkReply.NetworkError.RemoteHostClosedError
+QNetworkReply.HostNotFoundError QNetworkReply.NetworkError.HostNotFoundError
+QNetworkReply.TimeoutError QNetworkReply.NetworkError.TimeoutError
+QNetworkReply.OperationCanceledError QNetworkReply.NetworkError.OperationCanceledError
+QNetworkReply.SslHandshakeFailedError QNetworkReply.NetworkError.SslHandshakeFailedError
+QNetworkReply.UnknownNetworkError QNetworkReply.NetworkError.UnknownNetworkError
+QNetworkReply.ProxyConnectionRefusedError QNetworkReply.NetworkError.ProxyConnectionRefusedError
+QNetworkReply.ProxyConnectionClosedError QNetworkReply.NetworkError.ProxyConnectionClosedError
+QNetworkReply.ProxyNotFoundError QNetworkReply.NetworkError.ProxyNotFoundError
+QNetworkReply.ProxyTimeoutError QNetworkReply.NetworkError.ProxyTimeoutError
+QNetworkReply.ProxyAuthenticationRequiredError QNetworkReply.NetworkError.ProxyAuthenticationRequiredError
+QNetworkReply.UnknownProxyError QNetworkReply.NetworkError.UnknownProxyError
+QNetworkReply.ContentAccessDenied QNetworkReply.NetworkError.ContentAccessDenied
+QNetworkReply.ContentOperationNotPermittedError QNetworkReply.NetworkError.ContentOperationNotPermittedError
+QNetworkReply.ContentNotFoundError QNetworkReply.NetworkError.ContentNotFoundError
+QNetworkReply.AuthenticationRequiredError QNetworkReply.NetworkError.AuthenticationRequiredError
+QNetworkReply.UnknownContentError QNetworkReply.NetworkError.UnknownContentError
+QNetworkReply.ProtocolUnknownError QNetworkReply.NetworkError.ProtocolUnknownError
+QNetworkReply.ProtocolInvalidOperationError QNetworkReply.NetworkError.ProtocolInvalidOperationError
+QNetworkReply.ProtocolFailure QNetworkReply.NetworkError.ProtocolFailure
+QNetworkReply.ContentReSendError QNetworkReply.NetworkError.ContentReSendError
+QNetworkReply.TemporaryNetworkFailureError QNetworkReply.NetworkError.TemporaryNetworkFailureError
+QNetworkReply.NetworkSessionFailedError QNetworkReply.NetworkError.NetworkSessionFailedError
+QNetworkReply.BackgroundRequestNotAllowedError QNetworkReply.NetworkError.BackgroundRequestNotAllowedError
+QNetworkReply.ContentConflictError QNetworkReply.NetworkError.ContentConflictError
+QNetworkReply.ContentGoneError QNetworkReply.NetworkError.ContentGoneError
+QNetworkReply.InternalServerError QNetworkReply.NetworkError.InternalServerError
+QNetworkReply.OperationNotImplementedError QNetworkReply.NetworkError.OperationNotImplementedError
+QNetworkReply.ServiceUnavailableError QNetworkReply.NetworkError.ServiceUnavailableError
+QNetworkReply.UnknownServerError QNetworkReply.NetworkError.UnknownServerError
+QNetworkReply.TooManyRedirectsError QNetworkReply.NetworkError.TooManyRedirectsError
+QNetworkReply.InsecureRedirectError QNetworkReply.NetworkError.InsecureRedirectError
+QNetworkRequest.DefaultTransferTimeoutConstant QNetworkRequest.TransferTimeoutConstant.DefaultTransferTimeoutConstant
+QNetworkRequest.ManualRedirectPolicy QNetworkRequest.RedirectPolicy.ManualRedirectPolicy
+QNetworkRequest.NoLessSafeRedirectPolicy QNetworkRequest.RedirectPolicy.NoLessSafeRedirectPolicy
+QNetworkRequest.SameOriginRedirectPolicy QNetworkRequest.RedirectPolicy.SameOriginRedirectPolicy
+QNetworkRequest.UserVerifiedRedirectPolicy QNetworkRequest.RedirectPolicy.UserVerifiedRedirectPolicy
+QNetworkRequest.HighPriority QNetworkRequest.Priority.HighPriority
+QNetworkRequest.NormalPriority QNetworkRequest.Priority.NormalPriority
+QNetworkRequest.LowPriority QNetworkRequest.Priority.LowPriority
+QNetworkRequest.Automatic QNetworkRequest.LoadControl.Automatic
+QNetworkRequest.Manual QNetworkRequest.LoadControl.Manual
+QNetworkRequest.AlwaysNetwork QNetworkRequest.CacheLoadControl.AlwaysNetwork
+QNetworkRequest.PreferNetwork QNetworkRequest.CacheLoadControl.PreferNetwork
+QNetworkRequest.PreferCache QNetworkRequest.CacheLoadControl.PreferCache
+QNetworkRequest.AlwaysCache QNetworkRequest.CacheLoadControl.AlwaysCache
+QNetworkRequest.HttpStatusCodeAttribute QNetworkRequest.Attribute.HttpStatusCodeAttribute
+QNetworkRequest.HttpReasonPhraseAttribute QNetworkRequest.Attribute.HttpReasonPhraseAttribute
+QNetworkRequest.RedirectionTargetAttribute QNetworkRequest.Attribute.RedirectionTargetAttribute
+QNetworkRequest.ConnectionEncryptedAttribute QNetworkRequest.Attribute.ConnectionEncryptedAttribute
+QNetworkRequest.CacheLoadControlAttribute QNetworkRequest.Attribute.CacheLoadControlAttribute
+QNetworkRequest.CacheSaveControlAttribute QNetworkRequest.Attribute.CacheSaveControlAttribute
+QNetworkRequest.SourceIsFromCacheAttribute QNetworkRequest.Attribute.SourceIsFromCacheAttribute
+QNetworkRequest.DoNotBufferUploadDataAttribute QNetworkRequest.Attribute.DoNotBufferUploadDataAttribute
+QNetworkRequest.HttpPipeliningAllowedAttribute QNetworkRequest.Attribute.HttpPipeliningAllowedAttribute
+QNetworkRequest.HttpPipeliningWasUsedAttribute QNetworkRequest.Attribute.HttpPipeliningWasUsedAttribute
+QNetworkRequest.CustomVerbAttribute QNetworkRequest.Attribute.CustomVerbAttribute
+QNetworkRequest.CookieLoadControlAttribute QNetworkRequest.Attribute.CookieLoadControlAttribute
+QNetworkRequest.AuthenticationReuseAttribute QNetworkRequest.Attribute.AuthenticationReuseAttribute
+QNetworkRequest.CookieSaveControlAttribute QNetworkRequest.Attribute.CookieSaveControlAttribute
+QNetworkRequest.BackgroundRequestAttribute QNetworkRequest.Attribute.BackgroundRequestAttribute
+QNetworkRequest.SpdyAllowedAttribute QNetworkRequest.Attribute.SpdyAllowedAttribute
+QNetworkRequest.SpdyWasUsedAttribute QNetworkRequest.Attribute.SpdyWasUsedAttribute
+QNetworkRequest.EmitAllUploadProgressSignalsAttribute QNetworkRequest.Attribute.EmitAllUploadProgressSignalsAttribute
+QNetworkRequest.FollowRedirectsAttribute QNetworkRequest.Attribute.FollowRedirectsAttribute
+QNetworkRequest.HTTP2AllowedAttribute QNetworkRequest.Attribute.HTTP2AllowedAttribute
+QNetworkRequest.Http2AllowedAttribute QNetworkRequest.Attribute.Http2AllowedAttribute
+QNetworkRequest.HTTP2WasUsedAttribute QNetworkRequest.Attribute.HTTP2WasUsedAttribute
+QNetworkRequest.Http2WasUsedAttribute QNetworkRequest.Attribute.Http2WasUsedAttribute
+QNetworkRequest.OriginalContentLengthAttribute QNetworkRequest.Attribute.OriginalContentLengthAttribute
+QNetworkRequest.RedirectPolicyAttribute QNetworkRequest.Attribute.RedirectPolicyAttribute
+QNetworkRequest.Http2DirectAttribute QNetworkRequest.Attribute.Http2DirectAttribute
+QNetworkRequest.AutoDeleteReplyOnFinishAttribute QNetworkRequest.Attribute.AutoDeleteReplyOnFinishAttribute
+QNetworkRequest.User QNetworkRequest.Attribute.User
+QNetworkRequest.UserMax QNetworkRequest.Attribute.UserMax
+QNetworkRequest.ContentTypeHeader QNetworkRequest.KnownHeaders.ContentTypeHeader
+QNetworkRequest.ContentLengthHeader QNetworkRequest.KnownHeaders.ContentLengthHeader
+QNetworkRequest.LocationHeader QNetworkRequest.KnownHeaders.LocationHeader
+QNetworkRequest.LastModifiedHeader QNetworkRequest.KnownHeaders.LastModifiedHeader
+QNetworkRequest.CookieHeader QNetworkRequest.KnownHeaders.CookieHeader
+QNetworkRequest.SetCookieHeader QNetworkRequest.KnownHeaders.SetCookieHeader
+QNetworkRequest.ContentDispositionHeader QNetworkRequest.KnownHeaders.ContentDispositionHeader
+QNetworkRequest.UserAgentHeader QNetworkRequest.KnownHeaders.UserAgentHeader
+QNetworkRequest.ServerHeader QNetworkRequest.KnownHeaders.ServerHeader
+QNetworkRequest.IfModifiedSinceHeader QNetworkRequest.KnownHeaders.IfModifiedSinceHeader
+QNetworkRequest.ETagHeader QNetworkRequest.KnownHeaders.ETagHeader
+QNetworkRequest.IfMatchHeader QNetworkRequest.KnownHeaders.IfMatchHeader
+QNetworkRequest.IfNoneMatchHeader QNetworkRequest.KnownHeaders.IfNoneMatchHeader
+QNetworkSession.NoPolicy QNetworkSession.UsagePolicy.NoPolicy
+QNetworkSession.NoBackgroundTrafficPolicy QNetworkSession.UsagePolicy.NoBackgroundTrafficPolicy
+QNetworkSession.UnknownSessionError QNetworkSession.SessionError.UnknownSessionError
+QNetworkSession.SessionAbortedError QNetworkSession.SessionError.SessionAbortedError
+QNetworkSession.RoamingError QNetworkSession.SessionError.RoamingError
+QNetworkSession.OperationNotSupportedError QNetworkSession.SessionError.OperationNotSupportedError
+QNetworkSession.InvalidConfigurationError QNetworkSession.SessionError.InvalidConfigurationError
+QNetworkSession.Invalid QNetworkSession.State.Invalid
+QNetworkSession.NotAvailable QNetworkSession.State.NotAvailable
+QNetworkSession.Connecting QNetworkSession.State.Connecting
+QNetworkSession.Connected QNetworkSession.State.Connected
+QNetworkSession.Closing QNetworkSession.State.Closing
+QNetworkSession.Disconnected QNetworkSession.State.Disconnected
+QNetworkSession.Roaming QNetworkSession.State.Roaming
+QSsl.SslOptionDisableEmptyFragments QSsl.SslOption.SslOptionDisableEmptyFragments
+QSsl.SslOptionDisableSessionTickets QSsl.SslOption.SslOptionDisableSessionTickets
+QSsl.SslOptionDisableCompression QSsl.SslOption.SslOptionDisableCompression
+QSsl.SslOptionDisableServerNameIndication QSsl.SslOption.SslOptionDisableServerNameIndication
+QSsl.SslOptionDisableLegacyRenegotiation QSsl.SslOption.SslOptionDisableLegacyRenegotiation
+QSsl.SslOptionDisableSessionSharing QSsl.SslOption.SslOptionDisableSessionSharing
+QSsl.SslOptionDisableSessionPersistence QSsl.SslOption.SslOptionDisableSessionPersistence
+QSsl.SslOptionDisableServerCipherPreference QSsl.SslOption.SslOptionDisableServerCipherPreference
+QSsl.UnknownProtocol QSsl.SslProtocol.UnknownProtocol
+QSsl.SslV3 QSsl.SslProtocol.SslV3
+QSsl.SslV2 QSsl.SslProtocol.SslV2
+QSsl.TlsV1_0 QSsl.SslProtocol.TlsV1_0
+QSsl.TlsV1_0OrLater QSsl.SslProtocol.TlsV1_0OrLater
+QSsl.TlsV1_1 QSsl.SslProtocol.TlsV1_1
+QSsl.TlsV1_1OrLater QSsl.SslProtocol.TlsV1_1OrLater
+QSsl.TlsV1_2 QSsl.SslProtocol.TlsV1_2
+QSsl.TlsV1_2OrLater QSsl.SslProtocol.TlsV1_2OrLater
+QSsl.AnyProtocol QSsl.SslProtocol.AnyProtocol
+QSsl.TlsV1SslV3 QSsl.SslProtocol.TlsV1SslV3
+QSsl.SecureProtocols QSsl.SslProtocol.SecureProtocols
+QSsl.DtlsV1_0 QSsl.SslProtocol.DtlsV1_0
+QSsl.DtlsV1_0OrLater QSsl.SslProtocol.DtlsV1_0OrLater
+QSsl.DtlsV1_2 QSsl.SslProtocol.DtlsV1_2
+QSsl.DtlsV1_2OrLater QSsl.SslProtocol.DtlsV1_2OrLater
+QSsl.TlsV1_3 QSsl.SslProtocol.TlsV1_3
+QSsl.TlsV1_3OrLater QSsl.SslProtocol.TlsV1_3OrLater
+QSsl.EmailEntry QSsl.AlternativeNameEntryType.EmailEntry
+QSsl.DnsEntry QSsl.AlternativeNameEntryType.DnsEntry
+QSsl.IpAddressEntry QSsl.AlternativeNameEntryType.IpAddressEntry
+QSsl.Opaque QSsl.KeyAlgorithm.Opaque
+QSsl.Rsa QSsl.KeyAlgorithm.Rsa
+QSsl.Dsa QSsl.KeyAlgorithm.Dsa
+QSsl.Ec QSsl.KeyAlgorithm.Ec
+QSsl.Dh QSsl.KeyAlgorithm.Dh
+QSsl.Pem QSsl.EncodingFormat.Pem
+QSsl.Der QSsl.EncodingFormat.Der
+QSsl.PrivateKey QSsl.KeyType.PrivateKey
+QSsl.PublicKey QSsl.KeyType.PublicKey
+QSslCertificate.RegularExpression QSslCertificate.PatternSyntax.RegularExpression
+QSslCertificate.Wildcard QSslCertificate.PatternSyntax.Wildcard
+QSslCertificate.FixedString QSslCertificate.PatternSyntax.FixedString
+QSslCertificate.Organization QSslCertificate.SubjectInfo.Organization
+QSslCertificate.CommonName QSslCertificate.SubjectInfo.CommonName
+QSslCertificate.LocalityName QSslCertificate.SubjectInfo.LocalityName
+QSslCertificate.OrganizationalUnitName QSslCertificate.SubjectInfo.OrganizationalUnitName
+QSslCertificate.CountryName QSslCertificate.SubjectInfo.CountryName
+QSslCertificate.StateOrProvinceName QSslCertificate.SubjectInfo.StateOrProvinceName
+QSslCertificate.DistinguishedNameQualifier QSslCertificate.SubjectInfo.DistinguishedNameQualifier
+QSslCertificate.SerialNumber QSslCertificate.SubjectInfo.SerialNumber
+QSslCertificate.EmailAddress QSslCertificate.SubjectInfo.EmailAddress
+QSslConfiguration.NextProtocolNegotiationNone QSslConfiguration.NextProtocolNegotiationStatus.NextProtocolNegotiationNone
+QSslConfiguration.NextProtocolNegotiationNegotiated QSslConfiguration.NextProtocolNegotiationStatus.NextProtocolNegotiationNegotiated
+QSslConfiguration.NextProtocolNegotiationUnsupported QSslConfiguration.NextProtocolNegotiationStatus.NextProtocolNegotiationUnsupported
+QSslDiffieHellmanParameters.NoError QSslDiffieHellmanParameters.Error.NoError
+QSslDiffieHellmanParameters.InvalidInputDataError QSslDiffieHellmanParameters.Error.InvalidInputDataError
+QSslDiffieHellmanParameters.UnsafeParametersError QSslDiffieHellmanParameters.Error.UnsafeParametersError
+QSslError.UnspecifiedError QSslError.SslError.UnspecifiedError
+QSslError.NoError QSslError.SslError.NoError
+QSslError.UnableToGetIssuerCertificate QSslError.SslError.UnableToGetIssuerCertificate
+QSslError.UnableToDecryptCertificateSignature QSslError.SslError.UnableToDecryptCertificateSignature
+QSslError.UnableToDecodeIssuerPublicKey QSslError.SslError.UnableToDecodeIssuerPublicKey
+QSslError.CertificateSignatureFailed QSslError.SslError.CertificateSignatureFailed
+QSslError.CertificateNotYetValid QSslError.SslError.CertificateNotYetValid
+QSslError.CertificateExpired QSslError.SslError.CertificateExpired
+QSslError.InvalidNotBeforeField QSslError.SslError.InvalidNotBeforeField
+QSslError.InvalidNotAfterField QSslError.SslError.InvalidNotAfterField
+QSslError.SelfSignedCertificate QSslError.SslError.SelfSignedCertificate
+QSslError.SelfSignedCertificateInChain QSslError.SslError.SelfSignedCertificateInChain
+QSslError.UnableToGetLocalIssuerCertificate QSslError.SslError.UnableToGetLocalIssuerCertificate
+QSslError.UnableToVerifyFirstCertificate QSslError.SslError.UnableToVerifyFirstCertificate
+QSslError.CertificateRevoked QSslError.SslError.CertificateRevoked
+QSslError.InvalidCaCertificate QSslError.SslError.InvalidCaCertificate
+QSslError.PathLengthExceeded QSslError.SslError.PathLengthExceeded
+QSslError.InvalidPurpose QSslError.SslError.InvalidPurpose
+QSslError.CertificateUntrusted QSslError.SslError.CertificateUntrusted
+QSslError.CertificateRejected QSslError.SslError.CertificateRejected
+QSslError.SubjectIssuerMismatch QSslError.SslError.SubjectIssuerMismatch
+QSslError.AuthorityIssuerSerialNumberMismatch QSslError.SslError.AuthorityIssuerSerialNumberMismatch
+QSslError.NoPeerCertificate QSslError.SslError.NoPeerCertificate
+QSslError.HostNameMismatch QSslError.SslError.HostNameMismatch
+QSslError.NoSslSupport QSslError.SslError.NoSslSupport
+QSslError.CertificateBlacklisted QSslError.SslError.CertificateBlacklisted
+QSslError.CertificateStatusUnknown QSslError.SslError.CertificateStatusUnknown
+QSslError.OcspNoResponseFound QSslError.SslError.OcspNoResponseFound
+QSslError.OcspMalformedRequest QSslError.SslError.OcspMalformedRequest
+QSslError.OcspMalformedResponse QSslError.SslError.OcspMalformedResponse
+QSslError.OcspInternalError QSslError.SslError.OcspInternalError
+QSslError.OcspTryLater QSslError.SslError.OcspTryLater
+QSslError.OcspSigRequred QSslError.SslError.OcspSigRequred
+QSslError.OcspUnauthorized QSslError.SslError.OcspUnauthorized
+QSslError.OcspResponseCannotBeTrusted QSslError.SslError.OcspResponseCannotBeTrusted
+QSslError.OcspResponseCertIdUnknown QSslError.SslError.OcspResponseCertIdUnknown
+QSslError.OcspResponseExpired QSslError.SslError.OcspResponseExpired
+QSslError.OcspStatusUnknown QSslError.SslError.OcspStatusUnknown
+QSslSocket.VerifyNone QSslSocket.PeerVerifyMode.VerifyNone
+QSslSocket.QueryPeer QSslSocket.PeerVerifyMode.QueryPeer
+QSslSocket.VerifyPeer QSslSocket.PeerVerifyMode.VerifyPeer
+QSslSocket.AutoVerifyPeer QSslSocket.PeerVerifyMode.AutoVerifyPeer
+QSslSocket.UnencryptedMode QSslSocket.SslMode.UnencryptedMode
+QSslSocket.SslClientMode QSslSocket.SslMode.SslClientMode
+QSslSocket.SslServerMode QSslSocket.SslMode.SslServerMode
+QGL.DoubleBuffer QGL.FormatOption.DoubleBuffer
+QGL.DepthBuffer QGL.FormatOption.DepthBuffer
+QGL.Rgba QGL.FormatOption.Rgba
+QGL.AlphaChannel QGL.FormatOption.AlphaChannel
+QGL.AccumBuffer QGL.FormatOption.AccumBuffer
+QGL.StencilBuffer QGL.FormatOption.StencilBuffer
+QGL.StereoBuffers QGL.FormatOption.StereoBuffers
+QGL.DirectRendering QGL.FormatOption.DirectRendering
+QGL.HasOverlay QGL.FormatOption.HasOverlay
+QGL.SampleBuffers QGL.FormatOption.SampleBuffers
+QGL.SingleBuffer QGL.FormatOption.SingleBuffer
+QGL.NoDepthBuffer QGL.FormatOption.NoDepthBuffer
+QGL.ColorIndex QGL.FormatOption.ColorIndex
+QGL.NoAlphaChannel QGL.FormatOption.NoAlphaChannel
+QGL.NoAccumBuffer QGL.FormatOption.NoAccumBuffer
+QGL.NoStencilBuffer QGL.FormatOption.NoStencilBuffer
+QGL.NoStereoBuffers QGL.FormatOption.NoStereoBuffers
+QGL.IndirectRendering QGL.FormatOption.IndirectRendering
+QGL.NoOverlay QGL.FormatOption.NoOverlay
+QGL.NoSampleBuffers QGL.FormatOption.NoSampleBuffers
+QGL.DeprecatedFunctions QGL.FormatOption.DeprecatedFunctions
+QGL.NoDeprecatedFunctions QGL.FormatOption.NoDeprecatedFunctions
+QGLFormat.NoProfile QGLFormat.OpenGLContextProfile.NoProfile
+QGLFormat.CoreProfile QGLFormat.OpenGLContextProfile.CoreProfile
+QGLFormat.CompatibilityProfile QGLFormat.OpenGLContextProfile.CompatibilityProfile
+QGLFormat.OpenGL_Version_None QGLFormat.OpenGLVersionFlag.OpenGL_Version_None
+QGLFormat.OpenGL_Version_1_1 QGLFormat.OpenGLVersionFlag.OpenGL_Version_1_1
+QGLFormat.OpenGL_Version_1_2 QGLFormat.OpenGLVersionFlag.OpenGL_Version_1_2
+QGLFormat.OpenGL_Version_1_3 QGLFormat.OpenGLVersionFlag.OpenGL_Version_1_3
+QGLFormat.OpenGL_Version_1_4 QGLFormat.OpenGLVersionFlag.OpenGL_Version_1_4
+QGLFormat.OpenGL_Version_1_5 QGLFormat.OpenGLVersionFlag.OpenGL_Version_1_5
+QGLFormat.OpenGL_Version_2_0 QGLFormat.OpenGLVersionFlag.OpenGL_Version_2_0
+QGLFormat.OpenGL_Version_2_1 QGLFormat.OpenGLVersionFlag.OpenGL_Version_2_1
+QGLFormat.OpenGL_Version_3_0 QGLFormat.OpenGLVersionFlag.OpenGL_Version_3_0
+QGLFormat.OpenGL_Version_3_1 QGLFormat.OpenGLVersionFlag.OpenGL_Version_3_1
+QGLFormat.OpenGL_Version_3_2 QGLFormat.OpenGLVersionFlag.OpenGL_Version_3_2
+QGLFormat.OpenGL_Version_3_3 QGLFormat.OpenGLVersionFlag.OpenGL_Version_3_3
+QGLFormat.OpenGL_Version_4_0 QGLFormat.OpenGLVersionFlag.OpenGL_Version_4_0
+QGLFormat.OpenGL_Version_4_1 QGLFormat.OpenGLVersionFlag.OpenGL_Version_4_1
+QGLFormat.OpenGL_Version_4_2 QGLFormat.OpenGLVersionFlag.OpenGL_Version_4_2
+QGLFormat.OpenGL_Version_4_3 QGLFormat.OpenGLVersionFlag.OpenGL_Version_4_3
+QGLFormat.OpenGL_ES_Common_Version_1_0 QGLFormat.OpenGLVersionFlag.OpenGL_ES_Common_Version_1_0
+QGLFormat.OpenGL_ES_CommonLite_Version_1_0 QGLFormat.OpenGLVersionFlag.OpenGL_ES_CommonLite_Version_1_0
+QGLFormat.OpenGL_ES_Common_Version_1_1 QGLFormat.OpenGLVersionFlag.OpenGL_ES_Common_Version_1_1
+QGLFormat.OpenGL_ES_CommonLite_Version_1_1 QGLFormat.OpenGLVersionFlag.OpenGL_ES_CommonLite_Version_1_1
+QGLFormat.OpenGL_ES_Version_2_0 QGLFormat.OpenGLVersionFlag.OpenGL_ES_Version_2_0
+QGLContext.NoBindOption QGLContext.BindOption.NoBindOption
+QGLContext.InvertedYBindOption QGLContext.BindOption.InvertedYBindOption
+QGLContext.MipmapBindOption QGLContext.BindOption.MipmapBindOption
+QGLContext.PremultipliedAlphaBindOption QGLContext.BindOption.PremultipliedAlphaBindOption
+QGLContext.LinearFilteringBindOption QGLContext.BindOption.LinearFilteringBindOption
+QGLContext.DefaultBindOption QGLContext.BindOption.DefaultBindOption
+QGeoAreaMonitorSource.PersistentAreaMonitorFeature QGeoAreaMonitorSource.AreaMonitorFeature.PersistentAreaMonitorFeature
+QGeoAreaMonitorSource.AnyAreaMonitorFeature QGeoAreaMonitorSource.AreaMonitorFeature.AnyAreaMonitorFeature
+QGeoAreaMonitorSource.AccessError QGeoAreaMonitorSource.Error.AccessError
+QGeoAreaMonitorSource.InsufficientPositionInfo QGeoAreaMonitorSource.Error.InsufficientPositionInfo
+QGeoAreaMonitorSource.UnknownSourceError QGeoAreaMonitorSource.Error.UnknownSourceError
+QGeoAreaMonitorSource.NoError QGeoAreaMonitorSource.Error.NoError
+QGeoShape.UnknownType QGeoShape.ShapeType.UnknownType
+QGeoShape.RectangleType QGeoShape.ShapeType.RectangleType
+QGeoShape.CircleType QGeoShape.ShapeType.CircleType
+QGeoShape.PathType QGeoShape.ShapeType.PathType
+QGeoShape.PolygonType QGeoShape.ShapeType.PolygonType
+QGeoCoordinate.Degrees QGeoCoordinate.CoordinateFormat.Degrees
+QGeoCoordinate.DegreesWithHemisphere QGeoCoordinate.CoordinateFormat.DegreesWithHemisphere
+QGeoCoordinate.DegreesMinutes QGeoCoordinate.CoordinateFormat.DegreesMinutes
+QGeoCoordinate.DegreesMinutesWithHemisphere QGeoCoordinate.CoordinateFormat.DegreesMinutesWithHemisphere
+QGeoCoordinate.DegreesMinutesSeconds QGeoCoordinate.CoordinateFormat.DegreesMinutesSeconds
+QGeoCoordinate.DegreesMinutesSecondsWithHemisphere QGeoCoordinate.CoordinateFormat.DegreesMinutesSecondsWithHemisphere
+QGeoCoordinate.InvalidCoordinate QGeoCoordinate.CoordinateType.InvalidCoordinate
+QGeoCoordinate.Coordinate2D QGeoCoordinate.CoordinateType.Coordinate2D
+QGeoCoordinate.Coordinate3D QGeoCoordinate.CoordinateType.Coordinate3D
+QGeoPositionInfo.Direction QGeoPositionInfo.Attribute.Direction
+QGeoPositionInfo.GroundSpeed QGeoPositionInfo.Attribute.GroundSpeed
+QGeoPositionInfo.VerticalSpeed QGeoPositionInfo.Attribute.VerticalSpeed
+QGeoPositionInfo.MagneticVariation QGeoPositionInfo.Attribute.MagneticVariation
+QGeoPositionInfo.HorizontalAccuracy QGeoPositionInfo.Attribute.HorizontalAccuracy
+QGeoPositionInfo.VerticalAccuracy QGeoPositionInfo.Attribute.VerticalAccuracy
+QGeoPositionInfoSource.NoPositioningMethods QGeoPositionInfoSource.PositioningMethod.NoPositioningMethods
+QGeoPositionInfoSource.SatellitePositioningMethods QGeoPositionInfoSource.PositioningMethod.SatellitePositioningMethods
+QGeoPositionInfoSource.NonSatellitePositioningMethods QGeoPositionInfoSource.PositioningMethod.NonSatellitePositioningMethods
+QGeoPositionInfoSource.AllPositioningMethods QGeoPositionInfoSource.PositioningMethod.AllPositioningMethods
+QGeoPositionInfoSource.AccessError QGeoPositionInfoSource.Error.AccessError
+QGeoPositionInfoSource.ClosedError QGeoPositionInfoSource.Error.ClosedError
+QGeoPositionInfoSource.UnknownSourceError QGeoPositionInfoSource.Error.UnknownSourceError
+QGeoPositionInfoSource.NoError QGeoPositionInfoSource.Error.NoError
+QGeoSatelliteInfo.Undefined QGeoSatelliteInfo.SatelliteSystem.Undefined
+QGeoSatelliteInfo.GPS QGeoSatelliteInfo.SatelliteSystem.GPS
+QGeoSatelliteInfo.GLONASS QGeoSatelliteInfo.SatelliteSystem.GLONASS
+QGeoSatelliteInfo.Elevation QGeoSatelliteInfo.Attribute.Elevation
+QGeoSatelliteInfo.Azimuth QGeoSatelliteInfo.Attribute.Azimuth
+QGeoSatelliteInfoSource.AccessError QGeoSatelliteInfoSource.Error.AccessError
+QGeoSatelliteInfoSource.ClosedError QGeoSatelliteInfoSource.Error.ClosedError
+QGeoSatelliteInfoSource.NoError QGeoSatelliteInfoSource.Error.NoError
+QGeoSatelliteInfoSource.UnknownSourceError QGeoSatelliteInfoSource.Error.UnknownSourceError
+QNmeaPositionInfoSource.RealTimeMode QNmeaPositionInfoSource.UpdateMode.RealTimeMode
+QNmeaPositionInfoSource.SimulationMode QNmeaPositionInfoSource.UpdateMode.SimulationMode
+QAbstractPrintDialog.None_ QAbstractPrintDialog.PrintDialogOption.None_
+QAbstractPrintDialog.PrintToFile QAbstractPrintDialog.PrintDialogOption.PrintToFile
+QAbstractPrintDialog.PrintSelection QAbstractPrintDialog.PrintDialogOption.PrintSelection
+QAbstractPrintDialog.PrintPageRange QAbstractPrintDialog.PrintDialogOption.PrintPageRange
+QAbstractPrintDialog.PrintCollateCopies QAbstractPrintDialog.PrintDialogOption.PrintCollateCopies
+QAbstractPrintDialog.PrintShowPageSize QAbstractPrintDialog.PrintDialogOption.PrintShowPageSize
+QAbstractPrintDialog.PrintCurrentPage QAbstractPrintDialog.PrintDialogOption.PrintCurrentPage
+QAbstractPrintDialog.AllPages QAbstractPrintDialog.PrintRange.AllPages
+QAbstractPrintDialog.Selection QAbstractPrintDialog.PrintRange.Selection
+QAbstractPrintDialog.PageRange QAbstractPrintDialog.PrintRange.PageRange
+QAbstractPrintDialog.CurrentPage QAbstractPrintDialog.PrintRange.CurrentPage
+QPrintEngine.PPK_CollateCopies QPrintEngine.PrintEnginePropertyKey.PPK_CollateCopies
+QPrintEngine.PPK_ColorMode QPrintEngine.PrintEnginePropertyKey.PPK_ColorMode
+QPrintEngine.PPK_Creator QPrintEngine.PrintEnginePropertyKey.PPK_Creator
+QPrintEngine.PPK_DocumentName QPrintEngine.PrintEnginePropertyKey.PPK_DocumentName
+QPrintEngine.PPK_FullPage QPrintEngine.PrintEnginePropertyKey.PPK_FullPage
+QPrintEngine.PPK_NumberOfCopies QPrintEngine.PrintEnginePropertyKey.PPK_NumberOfCopies
+QPrintEngine.PPK_Orientation QPrintEngine.PrintEnginePropertyKey.PPK_Orientation
+QPrintEngine.PPK_OutputFileName QPrintEngine.PrintEnginePropertyKey.PPK_OutputFileName
+QPrintEngine.PPK_PageOrder QPrintEngine.PrintEnginePropertyKey.PPK_PageOrder
+QPrintEngine.PPK_PageRect QPrintEngine.PrintEnginePropertyKey.PPK_PageRect
+QPrintEngine.PPK_PageSize QPrintEngine.PrintEnginePropertyKey.PPK_PageSize
+QPrintEngine.PPK_PaperRect QPrintEngine.PrintEnginePropertyKey.PPK_PaperRect
+QPrintEngine.PPK_PaperSource QPrintEngine.PrintEnginePropertyKey.PPK_PaperSource
+QPrintEngine.PPK_PrinterName QPrintEngine.PrintEnginePropertyKey.PPK_PrinterName
+QPrintEngine.PPK_PrinterProgram QPrintEngine.PrintEnginePropertyKey.PPK_PrinterProgram
+QPrintEngine.PPK_Resolution QPrintEngine.PrintEnginePropertyKey.PPK_Resolution
+QPrintEngine.PPK_SelectionOption QPrintEngine.PrintEnginePropertyKey.PPK_SelectionOption
+QPrintEngine.PPK_SupportedResolutions QPrintEngine.PrintEnginePropertyKey.PPK_SupportedResolutions
+QPrintEngine.PPK_WindowsPageSize QPrintEngine.PrintEnginePropertyKey.PPK_WindowsPageSize
+QPrintEngine.PPK_FontEmbedding QPrintEngine.PrintEnginePropertyKey.PPK_FontEmbedding
+QPrintEngine.PPK_Duplex QPrintEngine.PrintEnginePropertyKey.PPK_Duplex
+QPrintEngine.PPK_PaperSources QPrintEngine.PrintEnginePropertyKey.PPK_PaperSources
+QPrintEngine.PPK_CustomPaperSize QPrintEngine.PrintEnginePropertyKey.PPK_CustomPaperSize
+QPrintEngine.PPK_PageMargins QPrintEngine.PrintEnginePropertyKey.PPK_PageMargins
+QPrintEngine.PPK_PaperSize QPrintEngine.PrintEnginePropertyKey.PPK_PaperSize
+QPrintEngine.PPK_CopyCount QPrintEngine.PrintEnginePropertyKey.PPK_CopyCount
+QPrintEngine.PPK_SupportsMultipleCopies QPrintEngine.PrintEnginePropertyKey.PPK_SupportsMultipleCopies
+QPrintEngine.PPK_PaperName QPrintEngine.PrintEnginePropertyKey.PPK_PaperName
+QPrintEngine.PPK_QPageSize QPrintEngine.PrintEnginePropertyKey.PPK_QPageSize
+QPrintEngine.PPK_QPageMargins QPrintEngine.PrintEnginePropertyKey.PPK_QPageMargins
+QPrintEngine.PPK_QPageLayout QPrintEngine.PrintEnginePropertyKey.PPK_QPageLayout
+QPrintEngine.PPK_CustomBase QPrintEngine.PrintEnginePropertyKey.PPK_CustomBase
+QPrinter.DuplexNone QPrinter.DuplexMode.DuplexNone
+QPrinter.DuplexAuto QPrinter.DuplexMode.DuplexAuto
+QPrinter.DuplexLongSide QPrinter.DuplexMode.DuplexLongSide
+QPrinter.DuplexShortSide QPrinter.DuplexMode.DuplexShortSide
+QPrinter.Millimeter QPrinter.Unit.Millimeter
+QPrinter.Point QPrinter.Unit.Point
+QPrinter.Inch QPrinter.Unit.Inch
+QPrinter.Pica QPrinter.Unit.Pica
+QPrinter.Didot QPrinter.Unit.Didot
+QPrinter.Cicero QPrinter.Unit.Cicero
+QPrinter.DevicePixel QPrinter.Unit.DevicePixel
+QPrinter.AllPages QPrinter.PrintRange.AllPages
+QPrinter.Selection QPrinter.PrintRange.Selection
+QPrinter.PageRange QPrinter.PrintRange.PageRange
+QPrinter.CurrentPage QPrinter.PrintRange.CurrentPage
+QPrinter.NativeFormat QPrinter.OutputFormat.NativeFormat
+QPrinter.PdfFormat QPrinter.OutputFormat.PdfFormat
+QPrinter.Idle QPrinter.PrinterState.Idle
+QPrinter.Active QPrinter.PrinterState.Active
+QPrinter.Aborted QPrinter.PrinterState.Aborted
+QPrinter.Error QPrinter.PrinterState.Error
+QPrinter.OnlyOne QPrinter.PaperSource.OnlyOne
+QPrinter.Lower QPrinter.PaperSource.Lower
+QPrinter.Middle QPrinter.PaperSource.Middle
+QPrinter.Manual QPrinter.PaperSource.Manual
+QPrinter.Envelope QPrinter.PaperSource.Envelope
+QPrinter.EnvelopeManual QPrinter.PaperSource.EnvelopeManual
+QPrinter.Auto QPrinter.PaperSource.Auto
+QPrinter.Tractor QPrinter.PaperSource.Tractor
+QPrinter.SmallFormat QPrinter.PaperSource.SmallFormat
+QPrinter.LargeFormat QPrinter.PaperSource.LargeFormat
+QPrinter.LargeCapacity QPrinter.PaperSource.LargeCapacity
+QPrinter.Cassette QPrinter.PaperSource.Cassette
+QPrinter.FormSource QPrinter.PaperSource.FormSource
+QPrinter.MaxPageSource QPrinter.PaperSource.MaxPageSource
+QPrinter.Upper QPrinter.PaperSource.Upper
+QPrinter.CustomSource QPrinter.PaperSource.CustomSource
+QPrinter.LastPaperSource QPrinter.PaperSource.LastPaperSource
+QPrinter.GrayScale QPrinter.ColorMode.GrayScale
+QPrinter.Color QPrinter.ColorMode.Color
+QPrinter.FirstPageFirst QPrinter.PageOrder.FirstPageFirst
+QPrinter.LastPageFirst QPrinter.PageOrder.LastPageFirst
+QPrinter.Portrait QPrinter.Orientation.Portrait
+QPrinter.Landscape QPrinter.Orientation.Landscape
+QPrinter.ScreenResolution QPrinter.PrinterMode.ScreenResolution
+QPrinter.PrinterResolution QPrinter.PrinterMode.PrinterResolution
+QPrinter.HighResolution QPrinter.PrinterMode.HighResolution
+QPrintPreviewWidget.CustomZoom QPrintPreviewWidget.ZoomMode.CustomZoom
+QPrintPreviewWidget.FitToWidth QPrintPreviewWidget.ZoomMode.FitToWidth
+QPrintPreviewWidget.FitInView QPrintPreviewWidget.ZoomMode.FitInView
+QPrintPreviewWidget.SinglePageView QPrintPreviewWidget.ViewMode.SinglePageView
+QPrintPreviewWidget.FacingPagesView QPrintPreviewWidget.ViewMode.FacingPagesView
+QPrintPreviewWidget.AllPagesView QPrintPreviewWidget.ViewMode.AllPagesView
+QJSEngine.TranslationExtension QJSEngine.Extension.TranslationExtension
+QJSEngine.ConsoleExtension QJSEngine.Extension.ConsoleExtension
+QJSEngine.GarbageCollectionExtension QJSEngine.Extension.GarbageCollectionExtension
+QJSEngine.AllExtensions QJSEngine.Extension.AllExtensions
+QJSValue.GenericError QJSValue.ErrorType.GenericError
+QJSValue.EvalError QJSValue.ErrorType.EvalError
+QJSValue.RangeError QJSValue.ErrorType.RangeError
+QJSValue.ReferenceError QJSValue.ErrorType.ReferenceError
+QJSValue.SyntaxError QJSValue.ErrorType.SyntaxError
+QJSValue.TypeError QJSValue.ErrorType.TypeError
+QJSValue.URIError QJSValue.ErrorType.URIError
+QJSValue.NullValue QJSValue.SpecialValue.NullValue
+QJSValue.UndefinedValue QJSValue.SpecialValue.UndefinedValue
+QQmlAbstractUrlInterceptor.QmlFile QQmlAbstractUrlInterceptor.DataType.QmlFile
+QQmlAbstractUrlInterceptor.JavaScriptFile QQmlAbstractUrlInterceptor.DataType.JavaScriptFile
+QQmlAbstractUrlInterceptor.QmldirFile QQmlAbstractUrlInterceptor.DataType.QmldirFile
+QQmlAbstractUrlInterceptor.UrlString QQmlAbstractUrlInterceptor.DataType.UrlString
+QQmlEngine.CppOwnership QQmlEngine.ObjectOwnership.CppOwnership
+QQmlEngine.JavaScriptOwnership QQmlEngine.ObjectOwnership.JavaScriptOwnership
+QQmlComponent.Null QQmlComponent.Status.Null
+QQmlComponent.Ready QQmlComponent.Status.Ready
+QQmlComponent.Loading QQmlComponent.Status.Loading
+QQmlComponent.Error QQmlComponent.Status.Error
+QQmlComponent.PreferSynchronous QQmlComponent.CompilationMode.PreferSynchronous
+QQmlComponent.Asynchronous QQmlComponent.CompilationMode.Asynchronous
+QQmlImageProviderBase.ForceAsynchronousImageLoading QQmlImageProviderBase.Flag.ForceAsynchronousImageLoading
+QQmlImageProviderBase.Image QQmlImageProviderBase.ImageType.Image
+QQmlImageProviderBase.Pixmap QQmlImageProviderBase.ImageType.Pixmap
+QQmlImageProviderBase.Texture QQmlImageProviderBase.ImageType.Texture
+QQmlImageProviderBase.ImageResponse QQmlImageProviderBase.ImageType.ImageResponse
+QQmlIncubator.Null QQmlIncubator.Status.Null
+QQmlIncubator.Ready QQmlIncubator.Status.Ready
+QQmlIncubator.Loading QQmlIncubator.Status.Loading
+QQmlIncubator.Error QQmlIncubator.Status.Error
+QQmlIncubator.Asynchronous QQmlIncubator.IncubationMode.Asynchronous
+QQmlIncubator.AsynchronousIfNested QQmlIncubator.IncubationMode.AsynchronousIfNested
+QQmlIncubator.Synchronous QQmlIncubator.IncubationMode.Synchronous
+QQmlProperty.Invalid QQmlProperty.Type.Invalid
+QQmlProperty.Property QQmlProperty.Type.Property
+QQmlProperty.SignalProperty QQmlProperty.Type.SignalProperty
+QQmlProperty.InvalidCategory QQmlProperty.PropertyTypeCategory.InvalidCategory
+QQmlProperty.List QQmlProperty.PropertyTypeCategory.List
+QQmlProperty.Object QQmlProperty.PropertyTypeCategory.Object
+QQmlProperty.Normal QQmlProperty.PropertyTypeCategory.Normal
+QQuickItem.TopLeft QQuickItem.TransformOrigin.TopLeft
+QQuickItem.Top QQuickItem.TransformOrigin.Top
+QQuickItem.TopRight QQuickItem.TransformOrigin.TopRight
+QQuickItem.Left QQuickItem.TransformOrigin.Left
+QQuickItem.Center QQuickItem.TransformOrigin.Center
+QQuickItem.Right QQuickItem.TransformOrigin.Right
+QQuickItem.BottomLeft QQuickItem.TransformOrigin.BottomLeft
+QQuickItem.Bottom QQuickItem.TransformOrigin.Bottom
+QQuickItem.BottomRight QQuickItem.TransformOrigin.BottomRight
+QQuickItem.ItemChildAddedChange QQuickItem.ItemChange.ItemChildAddedChange
+QQuickItem.ItemChildRemovedChange QQuickItem.ItemChange.ItemChildRemovedChange
+QQuickItem.ItemSceneChange QQuickItem.ItemChange.ItemSceneChange
+QQuickItem.ItemVisibleHasChanged QQuickItem.ItemChange.ItemVisibleHasChanged
+QQuickItem.ItemParentHasChanged QQuickItem.ItemChange.ItemParentHasChanged
+QQuickItem.ItemOpacityHasChanged QQuickItem.ItemChange.ItemOpacityHasChanged
+QQuickItem.ItemActiveFocusHasChanged QQuickItem.ItemChange.ItemActiveFocusHasChanged
+QQuickItem.ItemRotationHasChanged QQuickItem.ItemChange.ItemRotationHasChanged
+QQuickItem.ItemAntialiasingHasChanged QQuickItem.ItemChange.ItemAntialiasingHasChanged
+QQuickItem.ItemDevicePixelRatioHasChanged QQuickItem.ItemChange.ItemDevicePixelRatioHasChanged
+QQuickItem.ItemEnabledHasChanged QQuickItem.ItemChange.ItemEnabledHasChanged
+QQuickItem.ItemClipsChildrenToShape QQuickItem.Flag.ItemClipsChildrenToShape
+QQuickItem.ItemAcceptsInputMethod QQuickItem.Flag.ItemAcceptsInputMethod
+QQuickItem.ItemIsFocusScope QQuickItem.Flag.ItemIsFocusScope
+QQuickItem.ItemHasContents QQuickItem.Flag.ItemHasContents
+QQuickItem.ItemAcceptsDrops QQuickItem.Flag.ItemAcceptsDrops
+QQuickPaintedItem.FastFBOResizing QQuickPaintedItem.PerformanceHint.FastFBOResizing
+QQuickPaintedItem.Image QQuickPaintedItem.RenderTarget.Image
+QQuickPaintedItem.FramebufferObject QQuickPaintedItem.RenderTarget.FramebufferObject
+QQuickPaintedItem.InvertedYFramebufferObject QQuickPaintedItem.RenderTarget.InvertedYFramebufferObject
+QQuickWindow.NativeObjectTexture QQuickWindow.NativeObjectType.NativeObjectTexture
+QQuickWindow.QtTextRendering QQuickWindow.TextRenderType.QtTextRendering
+QQuickWindow.NativeTextRendering QQuickWindow.TextRenderType.NativeTextRendering
+QQuickWindow.BeforeSynchronizingStage QQuickWindow.RenderStage.BeforeSynchronizingStage
+QQuickWindow.AfterSynchronizingStage QQuickWindow.RenderStage.AfterSynchronizingStage
+QQuickWindow.BeforeRenderingStage QQuickWindow.RenderStage.BeforeRenderingStage
+QQuickWindow.AfterRenderingStage QQuickWindow.RenderStage.AfterRenderingStage
+QQuickWindow.AfterSwapStage QQuickWindow.RenderStage.AfterSwapStage
+QQuickWindow.NoStage QQuickWindow.RenderStage.NoStage
+QQuickWindow.ContextNotAvailable QQuickWindow.SceneGraphError.ContextNotAvailable
+QQuickWindow.TextureHasAlphaChannel QQuickWindow.CreateTextureOption.TextureHasAlphaChannel
+QQuickWindow.TextureHasMipmaps QQuickWindow.CreateTextureOption.TextureHasMipmaps
+QQuickWindow.TextureOwnsGLTexture QQuickWindow.CreateTextureOption.TextureOwnsGLTexture
+QQuickWindow.TextureCanUseAtlas QQuickWindow.CreateTextureOption.TextureCanUseAtlas
+QQuickWindow.TextureIsOpaque QQuickWindow.CreateTextureOption.TextureIsOpaque
+QQuickView.Null QQuickView.Status.Null
+QQuickView.Ready QQuickView.Status.Ready
+QQuickView.Loading QQuickView.Status.Loading
+QQuickView.Error QQuickView.Status.Error
+QQuickView.SizeViewToRootObject QQuickView.ResizeMode.SizeViewToRootObject
+QQuickView.SizeRootObjectToView QQuickView.ResizeMode.SizeRootObjectToView
+QSGAbstractRenderer.MatrixTransformFlipY QSGAbstractRenderer.MatrixTransformFlag.MatrixTransformFlipY
+QSGAbstractRenderer.ClearColorBuffer QSGAbstractRenderer.ClearModeBit.ClearColorBuffer
+QSGAbstractRenderer.ClearDepthBuffer QSGAbstractRenderer.ClearModeBit.ClearDepthBuffer
+QSGAbstractRenderer.ClearStencilBuffer QSGAbstractRenderer.ClearModeBit.ClearStencilBuffer
+QSGEngine.TextureHasAlphaChannel QSGEngine.CreateTextureOption.TextureHasAlphaChannel
+QSGEngine.TextureOwnsGLTexture QSGEngine.CreateTextureOption.TextureOwnsGLTexture
+QSGEngine.TextureCanUseAtlas QSGEngine.CreateTextureOption.TextureCanUseAtlas
+QSGEngine.TextureIsOpaque QSGEngine.CreateTextureOption.TextureIsOpaque
+QSGMaterial.Blending QSGMaterial.Flag.Blending
+QSGMaterial.RequiresDeterminant QSGMaterial.Flag.RequiresDeterminant
+QSGMaterial.RequiresFullMatrixExceptTranslate QSGMaterial.Flag.RequiresFullMatrixExceptTranslate
+QSGMaterial.RequiresFullMatrix QSGMaterial.Flag.RequiresFullMatrix
+QSGMaterial.CustomCompileStep QSGMaterial.Flag.CustomCompileStep
+QSGMaterial.SupportsRhiShader QSGMaterial.Flag.SupportsRhiShader
+QSGMaterial.RhiShaderWanted QSGMaterial.Flag.RhiShaderWanted
+QSGGeometry.ByteType QSGGeometry.Type.ByteType
+QSGGeometry.UnsignedByteType QSGGeometry.Type.UnsignedByteType
+QSGGeometry.ShortType QSGGeometry.Type.ShortType
+QSGGeometry.UnsignedShortType QSGGeometry.Type.UnsignedShortType
+QSGGeometry.IntType QSGGeometry.Type.IntType
+QSGGeometry.UnsignedIntType QSGGeometry.Type.UnsignedIntType
+QSGGeometry.FloatType QSGGeometry.Type.FloatType
+QSGGeometry.Bytes2Type QSGGeometry.Type.Bytes2Type
+QSGGeometry.Bytes3Type QSGGeometry.Type.Bytes3Type
+QSGGeometry.Bytes4Type QSGGeometry.Type.Bytes4Type
+QSGGeometry.DoubleType QSGGeometry.Type.DoubleType
+QSGGeometry.DrawPoints QSGGeometry.DrawingMode.DrawPoints
+QSGGeometry.DrawLines QSGGeometry.DrawingMode.DrawLines
+QSGGeometry.DrawLineLoop QSGGeometry.DrawingMode.DrawLineLoop
+QSGGeometry.DrawLineStrip QSGGeometry.DrawingMode.DrawLineStrip
+QSGGeometry.DrawTriangles QSGGeometry.DrawingMode.DrawTriangles
+QSGGeometry.DrawTriangleStrip QSGGeometry.DrawingMode.DrawTriangleStrip
+QSGGeometry.DrawTriangleFan QSGGeometry.DrawingMode.DrawTriangleFan
+QSGGeometry.UnknownAttribute QSGGeometry.AttributeType.UnknownAttribute
+QSGGeometry.PositionAttribute QSGGeometry.AttributeType.PositionAttribute
+QSGGeometry.ColorAttribute QSGGeometry.AttributeType.ColorAttribute
+QSGGeometry.TexCoordAttribute QSGGeometry.AttributeType.TexCoordAttribute
+QSGGeometry.TexCoord1Attribute QSGGeometry.AttributeType.TexCoord1Attribute
+QSGGeometry.TexCoord2Attribute QSGGeometry.AttributeType.TexCoord2Attribute
+QSGGeometry.AlwaysUploadPattern QSGGeometry.DataPattern.AlwaysUploadPattern
+QSGGeometry.StreamPattern QSGGeometry.DataPattern.StreamPattern
+QSGGeometry.DynamicPattern QSGGeometry.DataPattern.DynamicPattern
+QSGGeometry.StaticPattern QSGGeometry.DataPattern.StaticPattern
+QSGNode.DirtyMatrix QSGNode.DirtyStateBit.DirtyMatrix
+QSGNode.DirtyNodeAdded QSGNode.DirtyStateBit.DirtyNodeAdded
+QSGNode.DirtyNodeRemoved QSGNode.DirtyStateBit.DirtyNodeRemoved
+QSGNode.DirtyGeometry QSGNode.DirtyStateBit.DirtyGeometry
+QSGNode.DirtyMaterial QSGNode.DirtyStateBit.DirtyMaterial
+QSGNode.DirtyOpacity QSGNode.DirtyStateBit.DirtyOpacity
+QSGNode.OwnedByParent QSGNode.Flag.OwnedByParent
+QSGNode.UsePreprocess QSGNode.Flag.UsePreprocess
+QSGNode.OwnsGeometry QSGNode.Flag.OwnsGeometry
+QSGNode.OwnsMaterial QSGNode.Flag.OwnsMaterial
+QSGNode.OwnsOpaqueMaterial QSGNode.Flag.OwnsOpaqueMaterial
+QSGNode.BasicNodeType QSGNode.NodeType.BasicNodeType
+QSGNode.GeometryNodeType QSGNode.NodeType.GeometryNodeType
+QSGNode.TransformNodeType QSGNode.NodeType.TransformNodeType
+QSGNode.ClipNodeType QSGNode.NodeType.ClipNodeType
+QSGNode.OpacityNodeType QSGNode.NodeType.OpacityNodeType
+QSGImageNode.NoTransform QSGImageNode.TextureCoordinatesTransformFlag.NoTransform
+QSGImageNode.MirrorHorizontally QSGImageNode.TextureCoordinatesTransformFlag.MirrorHorizontally
+QSGImageNode.MirrorVertically QSGImageNode.TextureCoordinatesTransformFlag.MirrorVertically
+QSGMaterialRhiShader.UpdatesGraphicsPipelineState QSGMaterialRhiShader.Flag.UpdatesGraphicsPipelineState
+QSGRendererInterface.ShaderSourceString QSGRendererInterface.ShaderSourceType.ShaderSourceString
+QSGRendererInterface.ShaderSourceFile QSGRendererInterface.ShaderSourceType.ShaderSourceFile
+QSGRendererInterface.ShaderByteCode QSGRendererInterface.ShaderSourceType.ShaderByteCode
+QSGRendererInterface.RuntimeCompilation QSGRendererInterface.ShaderCompilationType.RuntimeCompilation
+QSGRendererInterface.OfflineCompilation QSGRendererInterface.ShaderCompilationType.OfflineCompilation
+QSGRendererInterface.UnknownShadingLanguage QSGRendererInterface.ShaderType.UnknownShadingLanguage
+QSGRendererInterface.GLSL QSGRendererInterface.ShaderType.GLSL
+QSGRendererInterface.HLSL QSGRendererInterface.ShaderType.HLSL
+QSGRendererInterface.RhiShader QSGRendererInterface.ShaderType.RhiShader
+QSGRendererInterface.DeviceResource QSGRendererInterface.Resource.DeviceResource
+QSGRendererInterface.CommandQueueResource QSGRendererInterface.Resource.CommandQueueResource
+QSGRendererInterface.CommandListResource QSGRendererInterface.Resource.CommandListResource
+QSGRendererInterface.PainterResource QSGRendererInterface.Resource.PainterResource
+QSGRendererInterface.RhiResource QSGRendererInterface.Resource.RhiResource
+QSGRendererInterface.PhysicalDeviceResource QSGRendererInterface.Resource.PhysicalDeviceResource
+QSGRendererInterface.OpenGLContextResource QSGRendererInterface.Resource.OpenGLContextResource
+QSGRendererInterface.DeviceContextResource QSGRendererInterface.Resource.DeviceContextResource
+QSGRendererInterface.CommandEncoderResource QSGRendererInterface.Resource.CommandEncoderResource
+QSGRendererInterface.VulkanInstanceResource QSGRendererInterface.Resource.VulkanInstanceResource
+QSGRendererInterface.RenderPassResource QSGRendererInterface.Resource.RenderPassResource
+QSGRendererInterface.Unknown QSGRendererInterface.GraphicsApi.Unknown
+QSGRendererInterface.Software QSGRendererInterface.GraphicsApi.Software
+QSGRendererInterface.OpenGL QSGRendererInterface.GraphicsApi.OpenGL
+QSGRendererInterface.Direct3D12 QSGRendererInterface.GraphicsApi.Direct3D12
+QSGRendererInterface.OpenVG QSGRendererInterface.GraphicsApi.OpenVG
+QSGRendererInterface.OpenGLRhi QSGRendererInterface.GraphicsApi.OpenGLRhi
+QSGRendererInterface.Direct3D11Rhi QSGRendererInterface.GraphicsApi.Direct3D11Rhi
+QSGRendererInterface.VulkanRhi QSGRendererInterface.GraphicsApi.VulkanRhi
+QSGRendererInterface.MetalRhi QSGRendererInterface.GraphicsApi.MetalRhi
+QSGRendererInterface.NullRhi QSGRendererInterface.GraphicsApi.NullRhi
+QSGRenderNode.BoundedRectRendering QSGRenderNode.RenderingFlag.BoundedRectRendering
+QSGRenderNode.DepthAwareRendering QSGRenderNode.RenderingFlag.DepthAwareRendering
+QSGRenderNode.OpaqueRendering QSGRenderNode.RenderingFlag.OpaqueRendering
+QSGRenderNode.DepthState QSGRenderNode.StateFlag.DepthState
+QSGRenderNode.StencilState QSGRenderNode.StateFlag.StencilState
+QSGRenderNode.ScissorState QSGRenderNode.StateFlag.ScissorState
+QSGRenderNode.ColorState QSGRenderNode.StateFlag.ColorState
+QSGRenderNode.BlendState QSGRenderNode.StateFlag.BlendState
+QSGRenderNode.CullState QSGRenderNode.StateFlag.CullState
+QSGRenderNode.ViewportState QSGRenderNode.StateFlag.ViewportState
+QSGRenderNode.RenderTargetState QSGRenderNode.StateFlag.RenderTargetState
+QSGSimpleTextureNode.NoTransform QSGSimpleTextureNode.TextureCoordinatesTransformFlag.NoTransform
+QSGSimpleTextureNode.MirrorHorizontally QSGSimpleTextureNode.TextureCoordinatesTransformFlag.MirrorHorizontally
+QSGSimpleTextureNode.MirrorVertically QSGSimpleTextureNode.TextureCoordinatesTransformFlag.MirrorVertically
+QSGTexture.AnisotropyNone QSGTexture.AnisotropyLevel.AnisotropyNone
+QSGTexture.Anisotropy2x QSGTexture.AnisotropyLevel.Anisotropy2x
+QSGTexture.Anisotropy4x QSGTexture.AnisotropyLevel.Anisotropy4x
+QSGTexture.Anisotropy8x QSGTexture.AnisotropyLevel.Anisotropy8x
+QSGTexture.Anisotropy16x QSGTexture.AnisotropyLevel.Anisotropy16x
+QSGTexture.None_ QSGTexture.Filtering.None_
+QSGTexture.Nearest QSGTexture.Filtering.Nearest
+QSGTexture.Linear QSGTexture.Filtering.Linear
+QSGTexture.Repeat QSGTexture.WrapMode.Repeat
+QSGTexture.ClampToEdge QSGTexture.WrapMode.ClampToEdge
+QSGTexture.MirroredRepeat QSGTexture.WrapMode.MirroredRepeat
+QSGGeometry.attributeType QSGGeometry.AttributeType.attributeType
+QSGMaterialShader.RenderState.DirtyMatrix QSGMaterialShader.RenderState.DirtyState.DirtyMatrix
+QSGMaterialShader.RenderState.DirtyOpacity QSGMaterialShader.RenderState.DirtyState.DirtyOpacity
+QSGMaterialShader.RenderState.DirtyCachedMaterialData QSGMaterialShader.RenderState.DirtyState.DirtyCachedMaterialData
+QSGMaterialShader.RenderState.DirtyAll QSGMaterialShader.RenderState.DirtyState.DirtyAll
+QSGMaterialRhiShader.GraphicsPipelineState.CullNone QSGMaterialRhiShader.GraphicsPipelineState.CullMode.CullNone
+QSGMaterialRhiShader.GraphicsPipelineState.CullFront QSGMaterialRhiShader.GraphicsPipelineState.CullMode.CullFront
+QSGMaterialRhiShader.GraphicsPipelineState.CullBack QSGMaterialRhiShader.GraphicsPipelineState.CullMode.CullBack
+QSGMaterialRhiShader.GraphicsPipelineState.R QSGMaterialRhiShader.GraphicsPipelineState.ColorMaskComponent.R
+QSGMaterialRhiShader.GraphicsPipelineState.G QSGMaterialRhiShader.GraphicsPipelineState.ColorMaskComponent.G
+QSGMaterialRhiShader.GraphicsPipelineState.B QSGMaterialRhiShader.GraphicsPipelineState.ColorMaskComponent.B
+QSGMaterialRhiShader.GraphicsPipelineState.A QSGMaterialRhiShader.GraphicsPipelineState.ColorMaskComponent.A
+QSGMaterialRhiShader.GraphicsPipelineState.Zero QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.Zero
+QSGMaterialRhiShader.GraphicsPipelineState.One QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.One
+QSGMaterialRhiShader.GraphicsPipelineState.SrcColor QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.SrcColor
+QSGMaterialRhiShader.GraphicsPipelineState.OneMinusSrcColor QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.OneMinusSrcColor
+QSGMaterialRhiShader.GraphicsPipelineState.DstColor QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.DstColor
+QSGMaterialRhiShader.GraphicsPipelineState.OneMinusDstColor QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.OneMinusDstColor
+QSGMaterialRhiShader.GraphicsPipelineState.SrcAlpha QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.SrcAlpha
+QSGMaterialRhiShader.GraphicsPipelineState.OneMinusSrcAlpha QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.OneMinusSrcAlpha
+QSGMaterialRhiShader.GraphicsPipelineState.DstAlpha QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.DstAlpha
+QSGMaterialRhiShader.GraphicsPipelineState.OneMinusDstAlpha QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.OneMinusDstAlpha
+QSGMaterialRhiShader.GraphicsPipelineState.ConstantColor QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.ConstantColor
+QSGMaterialRhiShader.GraphicsPipelineState.OneMinusConstantColor QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.OneMinusConstantColor
+QSGMaterialRhiShader.GraphicsPipelineState.ConstantAlpha QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.ConstantAlpha
+QSGMaterialRhiShader.GraphicsPipelineState.OneMinusConstantAlpha QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.OneMinusConstantAlpha
+QSGMaterialRhiShader.GraphicsPipelineState.SrcAlphaSaturate QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.SrcAlphaSaturate
+QSGMaterialRhiShader.GraphicsPipelineState.Src1Color QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.Src1Color
+QSGMaterialRhiShader.GraphicsPipelineState.OneMinusSrc1Color QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.OneMinusSrc1Color
+QSGMaterialRhiShader.GraphicsPipelineState.Src1Alpha QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.Src1Alpha
+QSGMaterialRhiShader.GraphicsPipelineState.OneMinusSrc1Alpha QSGMaterialRhiShader.GraphicsPipelineState.BlendFactor.OneMinusSrc1Alpha
+QQuickWidget.Null QQuickWidget.Status.Null
+QQuickWidget.Ready QQuickWidget.Status.Ready
+QQuickWidget.Loading QQuickWidget.Status.Loading
+QQuickWidget.Error QQuickWidget.Status.Error
+QQuickWidget.SizeViewToRootObject QQuickWidget.ResizeMode.SizeViewToRootObject
+QQuickWidget.SizeRootObjectToView QQuickWidget.ResizeMode.SizeRootObjectToView
+QSensor.FixedOrientation QSensor.AxesOrientationMode.FixedOrientation
+QSensor.AutomaticOrientation QSensor.AxesOrientationMode.AutomaticOrientation
+QSensor.UserOrientation QSensor.AxesOrientationMode.UserOrientation
+QSensor.Buffering QSensor.Feature.Buffering
+QSensor.AlwaysOn QSensor.Feature.AlwaysOn
+QSensor.GeoValues QSensor.Feature.GeoValues
+QSensor.FieldOfView QSensor.Feature.FieldOfView
+QSensor.AccelerationMode QSensor.Feature.AccelerationMode
+QSensor.SkipDuplicates QSensor.Feature.SkipDuplicates
+QSensor.AxesOrientation QSensor.Feature.AxesOrientation
+QSensor.PressureSensorTemperature QSensor.Feature.PressureSensorTemperature
+QAccelerometer.Combined QAccelerometer.AccelerationMode.Combined
+QAccelerometer.Gravity QAccelerometer.AccelerationMode.Gravity
+QAccelerometer.User QAccelerometer.AccelerationMode.User
+QAmbientLightReading.Undefined QAmbientLightReading.LightLevel.Undefined
+QAmbientLightReading.Dark QAmbientLightReading.LightLevel.Dark
+QAmbientLightReading.Twilight QAmbientLightReading.LightLevel.Twilight
+QAmbientLightReading.Light QAmbientLightReading.LightLevel.Light
+QAmbientLightReading.Bright QAmbientLightReading.LightLevel.Bright
+QAmbientLightReading.Sunny QAmbientLightReading.LightLevel.Sunny
+QOrientationReading.Undefined QOrientationReading.Orientation.Undefined
+QOrientationReading.TopUp QOrientationReading.Orientation.TopUp
+QOrientationReading.TopDown QOrientationReading.Orientation.TopDown
+QOrientationReading.LeftUp QOrientationReading.Orientation.LeftUp
+QOrientationReading.RightUp QOrientationReading.Orientation.RightUp
+QOrientationReading.FaceUp QOrientationReading.Orientation.FaceUp
+QOrientationReading.FaceDown QOrientationReading.Orientation.FaceDown
+QTapReading.Undefined QTapReading.TapDirection.Undefined
+QTapReading.X QTapReading.TapDirection.X
+QTapReading.Y QTapReading.TapDirection.Y
+QTapReading.Z QTapReading.TapDirection.Z
+QTapReading.X_Pos QTapReading.TapDirection.X_Pos
+QTapReading.Y_Pos QTapReading.TapDirection.Y_Pos
+QTapReading.Z_Pos QTapReading.TapDirection.Z_Pos
+QTapReading.X_Neg QTapReading.TapDirection.X_Neg
+QTapReading.Y_Neg QTapReading.TapDirection.Y_Neg
+QTapReading.Z_Neg QTapReading.TapDirection.Z_Neg
+QTapReading.X_Both QTapReading.TapDirection.X_Both
+QTapReading.Y_Both QTapReading.TapDirection.Y_Both
+QTapReading.Z_Both QTapReading.TapDirection.Z_Both
+QSqlDriver.UnknownDbms QSqlDriver.DbmsType.UnknownDbms
+QSqlDriver.MSSqlServer QSqlDriver.DbmsType.MSSqlServer
+QSqlDriver.MySqlServer QSqlDriver.DbmsType.MySqlServer
+QSqlDriver.PostgreSQL QSqlDriver.DbmsType.PostgreSQL
+QSqlDriver.Oracle QSqlDriver.DbmsType.Oracle
+QSqlDriver.Sybase QSqlDriver.DbmsType.Sybase
+QSqlDriver.SQLite QSqlDriver.DbmsType.SQLite
+QSqlDriver.Interbase QSqlDriver.DbmsType.Interbase
+QSqlDriver.DB2 QSqlDriver.DbmsType.DB2
+QSqlDriver.UnknownSource QSqlDriver.NotificationSource.UnknownSource
+QSqlDriver.SelfSource QSqlDriver.NotificationSource.SelfSource
+QSqlDriver.OtherSource QSqlDriver.NotificationSource.OtherSource
+QSqlDriver.FieldName QSqlDriver.IdentifierType.FieldName
+QSqlDriver.TableName QSqlDriver.IdentifierType.TableName
+QSqlDriver.WhereStatement QSqlDriver.StatementType.WhereStatement
+QSqlDriver.SelectStatement QSqlDriver.StatementType.SelectStatement
+QSqlDriver.UpdateStatement QSqlDriver.StatementType.UpdateStatement
+QSqlDriver.InsertStatement QSqlDriver.StatementType.InsertStatement
+QSqlDriver.DeleteStatement QSqlDriver.StatementType.DeleteStatement
+QSqlDriver.Transactions QSqlDriver.DriverFeature.Transactions
+QSqlDriver.QuerySize QSqlDriver.DriverFeature.QuerySize
+QSqlDriver.BLOB QSqlDriver.DriverFeature.BLOB
+QSqlDriver.Unicode QSqlDriver.DriverFeature.Unicode
+QSqlDriver.PreparedQueries QSqlDriver.DriverFeature.PreparedQueries
+QSqlDriver.NamedPlaceholders QSqlDriver.DriverFeature.NamedPlaceholders
+QSqlDriver.PositionalPlaceholders QSqlDriver.DriverFeature.PositionalPlaceholders
+QSqlDriver.LastInsertId QSqlDriver.DriverFeature.LastInsertId
+QSqlDriver.BatchOperations QSqlDriver.DriverFeature.BatchOperations
+QSqlDriver.SimpleLocking QSqlDriver.DriverFeature.SimpleLocking
+QSqlDriver.LowPrecisionNumbers QSqlDriver.DriverFeature.LowPrecisionNumbers
+QSqlDriver.EventNotifications QSqlDriver.DriverFeature.EventNotifications
+QSqlDriver.FinishQuery QSqlDriver.DriverFeature.FinishQuery
+QSqlDriver.MultipleResultSets QSqlDriver.DriverFeature.MultipleResultSets
+QSqlError.NoError QSqlError.ErrorType.NoError
+QSqlError.ConnectionError QSqlError.ErrorType.ConnectionError
+QSqlError.StatementError QSqlError.ErrorType.StatementError
+QSqlError.TransactionError QSqlError.ErrorType.TransactionError
+QSqlError.UnknownError QSqlError.ErrorType.UnknownError
+QSqlField.Unknown QSqlField.RequiredStatus.Unknown
+QSqlField.Optional QSqlField.RequiredStatus.Optional
+QSqlField.Required QSqlField.RequiredStatus.Required
+QSqlQuery.ValuesAsRows QSqlQuery.BatchExecutionMode.ValuesAsRows
+QSqlQuery.ValuesAsColumns QSqlQuery.BatchExecutionMode.ValuesAsColumns
+QSqlTableModel.OnFieldChange QSqlTableModel.EditStrategy.OnFieldChange
+QSqlTableModel.OnRowChange QSqlTableModel.EditStrategy.OnRowChange
+QSqlTableModel.OnManualSubmit QSqlTableModel.EditStrategy.OnManualSubmit
+QSqlRelationalTableModel.InnerJoin QSqlRelationalTableModel.JoinMode.InnerJoin
+QSqlRelationalTableModel.LeftJoin QSqlRelationalTableModel.JoinMode.LeftJoin
+QSqlResult.PositionalBinding QSqlResult.BindingSyntax.PositionalBinding
+QSqlResult.NamedBinding QSqlResult.BindingSyntax.NamedBinding
+QSql.LowPrecisionInt32 QSql.NumericalPrecisionPolicy.LowPrecisionInt32
+QSql.LowPrecisionInt64 QSql.NumericalPrecisionPolicy.LowPrecisionInt64
+QSql.LowPrecisionDouble QSql.NumericalPrecisionPolicy.LowPrecisionDouble
+QSql.HighPrecision QSql.NumericalPrecisionPolicy.HighPrecision
+QSql.Tables QSql.TableType.Tables
+QSql.SystemTables QSql.TableType.SystemTables
+QSql.Views QSql.TableType.Views
+QSql.AllTables QSql.TableType.AllTables
+QSql.In QSql.ParamTypeFlag.In
+QSql.Out QSql.ParamTypeFlag.Out
+QSql.InOut QSql.ParamTypeFlag.InOut
+QSql.Binary QSql.ParamTypeFlag.Binary
+QSql.BeforeFirstRow QSql.Location.BeforeFirstRow
+QSql.AfterLastRow QSql.Location.AfterLastRow
+QAbstractItemModelTester.QtTest QAbstractItemModelTester.FailureReportingMode.QtTest
+QAbstractItemModelTester.Warning QAbstractItemModelTester.FailureReportingMode.Warning
+QAbstractItemModelTester.Fatal QAbstractItemModelTester.FailureReportingMode.Fatal
+QTest.Press QTest.KeyAction.Press
+QTest.Release QTest.KeyAction.Release
+QTest.Click QTest.KeyAction.Click
+QTest.Shortcut QTest.KeyAction.Shortcut
+QTextToSpeech.Ready QTextToSpeech.State.Ready
+QTextToSpeech.Speaking QTextToSpeech.State.Speaking
+QTextToSpeech.Paused QTextToSpeech.State.Paused
+QTextToSpeech.BackendError QTextToSpeech.State.BackendError
+QVoice.Child QVoice.Age.Child
+QVoice.Teenager QVoice.Age.Teenager
+QVoice.Adult QVoice.Age.Adult
+QVoice.Senior QVoice.Age.Senior
+QVoice.Other QVoice.Age.Other
+QVoice.Male QVoice.Gender.Male
+QVoice.Female QVoice.Gender.Female
+QVoice.Unknown QVoice.Gender.Unknown
+QQuickWebEngineProfile.NoPersistentCookies QQuickWebEngineProfile.PersistentCookiesPolicy.NoPersistentCookies
+QQuickWebEngineProfile.AllowPersistentCookies QQuickWebEngineProfile.PersistentCookiesPolicy.AllowPersistentCookies
+QQuickWebEngineProfile.ForcePersistentCookies QQuickWebEngineProfile.PersistentCookiesPolicy.ForcePersistentCookies
+QQuickWebEngineProfile.MemoryHttpCache QQuickWebEngineProfile.HttpCacheType.MemoryHttpCache
+QQuickWebEngineProfile.DiskHttpCache QQuickWebEngineProfile.HttpCacheType.DiskHttpCache
+QQuickWebEngineProfile.NoCache QQuickWebEngineProfile.HttpCacheType.NoCache
+QQuickWebEngineScript.MainWorld QQuickWebEngineScript.ScriptWorldId.MainWorld
+QQuickWebEngineScript.ApplicationWorld QQuickWebEngineScript.ScriptWorldId.ApplicationWorld
+QQuickWebEngineScript.UserWorld QQuickWebEngineScript.ScriptWorldId.UserWorld
+QQuickWebEngineScript.Deferred QQuickWebEngineScript.InjectionPoint.Deferred
+QQuickWebEngineScript.DocumentReady QQuickWebEngineScript.InjectionPoint.DocumentReady
+QQuickWebEngineScript.DocumentCreation QQuickWebEngineScript.InjectionPoint.DocumentCreation
+QWebEngineHttpRequest.Get QWebEngineHttpRequest.Method.Get
+QWebEngineHttpRequest.Post QWebEngineHttpRequest.Method.Post
+QWebEngineUrlRequestInfo.NavigationTypeLink QWebEngineUrlRequestInfo.NavigationType.NavigationTypeLink
+QWebEngineUrlRequestInfo.NavigationTypeTyped QWebEngineUrlRequestInfo.NavigationType.NavigationTypeTyped
+QWebEngineUrlRequestInfo.NavigationTypeFormSubmitted QWebEngineUrlRequestInfo.NavigationType.NavigationTypeFormSubmitted
+QWebEngineUrlRequestInfo.NavigationTypeBackForward QWebEngineUrlRequestInfo.NavigationType.NavigationTypeBackForward
+QWebEngineUrlRequestInfo.NavigationTypeReload QWebEngineUrlRequestInfo.NavigationType.NavigationTypeReload
+QWebEngineUrlRequestInfo.NavigationTypeRedirect QWebEngineUrlRequestInfo.NavigationType.NavigationTypeRedirect
+QWebEngineUrlRequestInfo.NavigationTypeOther QWebEngineUrlRequestInfo.NavigationType.NavigationTypeOther
+QWebEngineUrlRequestInfo.ResourceTypeMainFrame QWebEngineUrlRequestInfo.ResourceType.ResourceTypeMainFrame
+QWebEngineUrlRequestInfo.ResourceTypeSubFrame QWebEngineUrlRequestInfo.ResourceType.ResourceTypeSubFrame
+QWebEngineUrlRequestInfo.ResourceTypeStylesheet QWebEngineUrlRequestInfo.ResourceType.ResourceTypeStylesheet
+QWebEngineUrlRequestInfo.ResourceTypeScript QWebEngineUrlRequestInfo.ResourceType.ResourceTypeScript
+QWebEngineUrlRequestInfo.ResourceTypeImage QWebEngineUrlRequestInfo.ResourceType.ResourceTypeImage
+QWebEngineUrlRequestInfo.ResourceTypeFontResource QWebEngineUrlRequestInfo.ResourceType.ResourceTypeFontResource
+QWebEngineUrlRequestInfo.ResourceTypeSubResource QWebEngineUrlRequestInfo.ResourceType.ResourceTypeSubResource
+QWebEngineUrlRequestInfo.ResourceTypeObject QWebEngineUrlRequestInfo.ResourceType.ResourceTypeObject
+QWebEngineUrlRequestInfo.ResourceTypeMedia QWebEngineUrlRequestInfo.ResourceType.ResourceTypeMedia
+QWebEngineUrlRequestInfo.ResourceTypeWorker QWebEngineUrlRequestInfo.ResourceType.ResourceTypeWorker
+QWebEngineUrlRequestInfo.ResourceTypeSharedWorker QWebEngineUrlRequestInfo.ResourceType.ResourceTypeSharedWorker
+QWebEngineUrlRequestInfo.ResourceTypePrefetch QWebEngineUrlRequestInfo.ResourceType.ResourceTypePrefetch
+QWebEngineUrlRequestInfo.ResourceTypeFavicon QWebEngineUrlRequestInfo.ResourceType.ResourceTypeFavicon
+QWebEngineUrlRequestInfo.ResourceTypeXhr QWebEngineUrlRequestInfo.ResourceType.ResourceTypeXhr
+QWebEngineUrlRequestInfo.ResourceTypePing QWebEngineUrlRequestInfo.ResourceType.ResourceTypePing
+QWebEngineUrlRequestInfo.ResourceTypeServiceWorker QWebEngineUrlRequestInfo.ResourceType.ResourceTypeServiceWorker
+QWebEngineUrlRequestInfo.ResourceTypeUnknown QWebEngineUrlRequestInfo.ResourceType.ResourceTypeUnknown
+QWebEngineUrlRequestInfo.ResourceTypeCspReport QWebEngineUrlRequestInfo.ResourceType.ResourceTypeCspReport
+QWebEngineUrlRequestInfo.ResourceTypePluginResource QWebEngineUrlRequestInfo.ResourceType.ResourceTypePluginResource
+QWebEngineUrlRequestInfo.ResourceTypeNavigationPreloadMainFrame QWebEngineUrlRequestInfo.ResourceType.ResourceTypeNavigationPreloadMainFrame
+QWebEngineUrlRequestInfo.ResourceTypeNavigationPreloadSubFrame QWebEngineUrlRequestInfo.ResourceType.ResourceTypeNavigationPreloadSubFrame
+QWebEngineUrlRequestJob.NoError QWebEngineUrlRequestJob.Error.NoError
+QWebEngineUrlRequestJob.UrlNotFound QWebEngineUrlRequestJob.Error.UrlNotFound
+QWebEngineUrlRequestJob.UrlInvalid QWebEngineUrlRequestJob.Error.UrlInvalid
+QWebEngineUrlRequestJob.RequestAborted QWebEngineUrlRequestJob.Error.RequestAborted
+QWebEngineUrlRequestJob.RequestDenied QWebEngineUrlRequestJob.Error.RequestDenied
+QWebEngineUrlRequestJob.RequestFailed QWebEngineUrlRequestJob.Error.RequestFailed
+QWebEngineUrlScheme.SecureScheme QWebEngineUrlScheme.Flag.SecureScheme
+QWebEngineUrlScheme.LocalScheme QWebEngineUrlScheme.Flag.LocalScheme
+QWebEngineUrlScheme.LocalAccessAllowed QWebEngineUrlScheme.Flag.LocalAccessAllowed
+QWebEngineUrlScheme.NoAccessAllowed QWebEngineUrlScheme.Flag.NoAccessAllowed
+QWebEngineUrlScheme.ServiceWorkersAllowed QWebEngineUrlScheme.Flag.ServiceWorkersAllowed
+QWebEngineUrlScheme.ViewSourceAllowed QWebEngineUrlScheme.Flag.ViewSourceAllowed
+QWebEngineUrlScheme.ContentSecurityPolicyIgnored QWebEngineUrlScheme.Flag.ContentSecurityPolicyIgnored
+QWebEngineUrlScheme.CorsEnabled QWebEngineUrlScheme.Flag.CorsEnabled
+QWebEngineUrlScheme.PortUnspecified QWebEngineUrlScheme.SpecialPort.PortUnspecified
+QWebEngineUrlScheme.HostPortAndUserInformation QWebEngineUrlScheme.Syntax.HostPortAndUserInformation
+QWebEngineUrlScheme.HostAndPort QWebEngineUrlScheme.Syntax.HostAndPort
+QWebEngineUrlScheme.Host QWebEngineUrlScheme.Syntax.Host
+QWebEngineUrlScheme.Path QWebEngineUrlScheme.Syntax.Path
+QWebEngineCertificateError.SslPinnedKeyNotInCertificateChain QWebEngineCertificateError.Error.SslPinnedKeyNotInCertificateChain
+QWebEngineCertificateError.CertificateCommonNameInvalid QWebEngineCertificateError.Error.CertificateCommonNameInvalid
+QWebEngineCertificateError.CertificateDateInvalid QWebEngineCertificateError.Error.CertificateDateInvalid
+QWebEngineCertificateError.CertificateAuthorityInvalid QWebEngineCertificateError.Error.CertificateAuthorityInvalid
+QWebEngineCertificateError.CertificateContainsErrors QWebEngineCertificateError.Error.CertificateContainsErrors
+QWebEngineCertificateError.CertificateNoRevocationMechanism QWebEngineCertificateError.Error.CertificateNoRevocationMechanism
+QWebEngineCertificateError.CertificateUnableToCheckRevocation QWebEngineCertificateError.Error.CertificateUnableToCheckRevocation
+QWebEngineCertificateError.CertificateRevoked QWebEngineCertificateError.Error.CertificateRevoked
+QWebEngineCertificateError.CertificateInvalid QWebEngineCertificateError.Error.CertificateInvalid
+QWebEngineCertificateError.CertificateWeakSignatureAlgorithm QWebEngineCertificateError.Error.CertificateWeakSignatureAlgorithm
+QWebEngineCertificateError.CertificateNonUniqueName QWebEngineCertificateError.Error.CertificateNonUniqueName
+QWebEngineCertificateError.CertificateWeakKey QWebEngineCertificateError.Error.CertificateWeakKey
+QWebEngineCertificateError.CertificateNameConstraintViolation QWebEngineCertificateError.Error.CertificateNameConstraintViolation
+QWebEngineCertificateError.CertificateValidityTooLong QWebEngineCertificateError.Error.CertificateValidityTooLong
+QWebEngineCertificateError.CertificateTransparencyRequired QWebEngineCertificateError.Error.CertificateTransparencyRequired
+QWebEngineCertificateError.CertificateKnownInterceptionBlocked QWebEngineCertificateError.Error.CertificateKnownInterceptionBlocked
+QWebEngineContextMenuData.CanUndo QWebEngineContextMenuData.EditFlag.CanUndo
+QWebEngineContextMenuData.CanRedo QWebEngineContextMenuData.EditFlag.CanRedo
+QWebEngineContextMenuData.CanCut QWebEngineContextMenuData.EditFlag.CanCut
+QWebEngineContextMenuData.CanCopy QWebEngineContextMenuData.EditFlag.CanCopy
+QWebEngineContextMenuData.CanPaste QWebEngineContextMenuData.EditFlag.CanPaste
+QWebEngineContextMenuData.CanDelete QWebEngineContextMenuData.EditFlag.CanDelete
+QWebEngineContextMenuData.CanSelectAll QWebEngineContextMenuData.EditFlag.CanSelectAll
+QWebEngineContextMenuData.CanTranslate QWebEngineContextMenuData.EditFlag.CanTranslate
+QWebEngineContextMenuData.CanEditRichly QWebEngineContextMenuData.EditFlag.CanEditRichly
+QWebEngineContextMenuData.MediaInError QWebEngineContextMenuData.MediaFlag.MediaInError
+QWebEngineContextMenuData.MediaPaused QWebEngineContextMenuData.MediaFlag.MediaPaused
+QWebEngineContextMenuData.MediaMuted QWebEngineContextMenuData.MediaFlag.MediaMuted
+QWebEngineContextMenuData.MediaLoop QWebEngineContextMenuData.MediaFlag.MediaLoop
+QWebEngineContextMenuData.MediaCanSave QWebEngineContextMenuData.MediaFlag.MediaCanSave
+QWebEngineContextMenuData.MediaHasAudio QWebEngineContextMenuData.MediaFlag.MediaHasAudio
+QWebEngineContextMenuData.MediaCanToggleControls QWebEngineContextMenuData.MediaFlag.MediaCanToggleControls
+QWebEngineContextMenuData.MediaControls QWebEngineContextMenuData.MediaFlag.MediaControls
+QWebEngineContextMenuData.MediaCanPrint QWebEngineContextMenuData.MediaFlag.MediaCanPrint
+QWebEngineContextMenuData.MediaCanRotate QWebEngineContextMenuData.MediaFlag.MediaCanRotate
+QWebEngineContextMenuData.MediaTypeNone QWebEngineContextMenuData.MediaType.MediaTypeNone
+QWebEngineContextMenuData.MediaTypeImage QWebEngineContextMenuData.MediaType.MediaTypeImage
+QWebEngineContextMenuData.MediaTypeVideo QWebEngineContextMenuData.MediaType.MediaTypeVideo
+QWebEngineContextMenuData.MediaTypeAudio QWebEngineContextMenuData.MediaType.MediaTypeAudio
+QWebEngineContextMenuData.MediaTypeCanvas QWebEngineContextMenuData.MediaType.MediaTypeCanvas
+QWebEngineContextMenuData.MediaTypeFile QWebEngineContextMenuData.MediaType.MediaTypeFile
+QWebEngineContextMenuData.MediaTypePlugin QWebEngineContextMenuData.MediaType.MediaTypePlugin
+QWebEngineDownloadItem.NoReason QWebEngineDownloadItem.DownloadInterruptReason.NoReason
+QWebEngineDownloadItem.FileFailed QWebEngineDownloadItem.DownloadInterruptReason.FileFailed
+QWebEngineDownloadItem.FileAccessDenied QWebEngineDownloadItem.DownloadInterruptReason.FileAccessDenied
+QWebEngineDownloadItem.FileNoSpace QWebEngineDownloadItem.DownloadInterruptReason.FileNoSpace
+QWebEngineDownloadItem.FileNameTooLong QWebEngineDownloadItem.DownloadInterruptReason.FileNameTooLong
+QWebEngineDownloadItem.FileTooLarge QWebEngineDownloadItem.DownloadInterruptReason.FileTooLarge
+QWebEngineDownloadItem.FileVirusInfected QWebEngineDownloadItem.DownloadInterruptReason.FileVirusInfected
+QWebEngineDownloadItem.FileTransientError QWebEngineDownloadItem.DownloadInterruptReason.FileTransientError
+QWebEngineDownloadItem.FileBlocked QWebEngineDownloadItem.DownloadInterruptReason.FileBlocked
+QWebEngineDownloadItem.FileSecurityCheckFailed QWebEngineDownloadItem.DownloadInterruptReason.FileSecurityCheckFailed
+QWebEngineDownloadItem.FileTooShort QWebEngineDownloadItem.DownloadInterruptReason.FileTooShort
+QWebEngineDownloadItem.FileHashMismatch QWebEngineDownloadItem.DownloadInterruptReason.FileHashMismatch
+QWebEngineDownloadItem.NetworkFailed QWebEngineDownloadItem.DownloadInterruptReason.NetworkFailed
+QWebEngineDownloadItem.NetworkTimeout QWebEngineDownloadItem.DownloadInterruptReason.NetworkTimeout
+QWebEngineDownloadItem.NetworkDisconnected QWebEngineDownloadItem.DownloadInterruptReason.NetworkDisconnected
+QWebEngineDownloadItem.NetworkServerDown QWebEngineDownloadItem.DownloadInterruptReason.NetworkServerDown
+QWebEngineDownloadItem.NetworkInvalidRequest QWebEngineDownloadItem.DownloadInterruptReason.NetworkInvalidRequest
+QWebEngineDownloadItem.ServerFailed QWebEngineDownloadItem.DownloadInterruptReason.ServerFailed
+QWebEngineDownloadItem.ServerBadContent QWebEngineDownloadItem.DownloadInterruptReason.ServerBadContent
+QWebEngineDownloadItem.ServerUnauthorized QWebEngineDownloadItem.DownloadInterruptReason.ServerUnauthorized
+QWebEngineDownloadItem.ServerCertProblem QWebEngineDownloadItem.DownloadInterruptReason.ServerCertProblem
+QWebEngineDownloadItem.ServerForbidden QWebEngineDownloadItem.DownloadInterruptReason.ServerForbidden
+QWebEngineDownloadItem.ServerUnreachable QWebEngineDownloadItem.DownloadInterruptReason.ServerUnreachable
+QWebEngineDownloadItem.UserCanceled QWebEngineDownloadItem.DownloadInterruptReason.UserCanceled
+QWebEngineDownloadItem.Attachment QWebEngineDownloadItem.DownloadType.Attachment
+QWebEngineDownloadItem.DownloadAttribute QWebEngineDownloadItem.DownloadType.DownloadAttribute
+QWebEngineDownloadItem.UserRequested QWebEngineDownloadItem.DownloadType.UserRequested
+QWebEngineDownloadItem.SavePage QWebEngineDownloadItem.DownloadType.SavePage
+QWebEngineDownloadItem.UnknownSaveFormat QWebEngineDownloadItem.SavePageFormat.UnknownSaveFormat
+QWebEngineDownloadItem.SingleHtmlSaveFormat QWebEngineDownloadItem.SavePageFormat.SingleHtmlSaveFormat
+QWebEngineDownloadItem.CompleteHtmlSaveFormat QWebEngineDownloadItem.SavePageFormat.CompleteHtmlSaveFormat
+QWebEngineDownloadItem.MimeHtmlSaveFormat QWebEngineDownloadItem.SavePageFormat.MimeHtmlSaveFormat
+QWebEngineDownloadItem.DownloadRequested QWebEngineDownloadItem.DownloadState.DownloadRequested
+QWebEngineDownloadItem.DownloadInProgress QWebEngineDownloadItem.DownloadState.DownloadInProgress
+QWebEngineDownloadItem.DownloadCompleted QWebEngineDownloadItem.DownloadState.DownloadCompleted
+QWebEngineDownloadItem.DownloadCancelled QWebEngineDownloadItem.DownloadState.DownloadCancelled
+QWebEngineDownloadItem.DownloadInterrupted QWebEngineDownloadItem.DownloadState.DownloadInterrupted
+QWebEnginePage.Active QWebEnginePage.LifecycleState.Active
+QWebEnginePage.Frozen QWebEnginePage.LifecycleState.Frozen
+QWebEnginePage.Discarded QWebEnginePage.LifecycleState.Discarded
+QWebEnginePage.NormalTerminationStatus QWebEnginePage.RenderProcessTerminationStatus.NormalTerminationStatus
+QWebEnginePage.AbnormalTerminationStatus QWebEnginePage.RenderProcessTerminationStatus.AbnormalTerminationStatus
+QWebEnginePage.CrashedTerminationStatus QWebEnginePage.RenderProcessTerminationStatus.CrashedTerminationStatus
+QWebEnginePage.KilledTerminationStatus QWebEnginePage.RenderProcessTerminationStatus.KilledTerminationStatus
+QWebEnginePage.NavigationTypeLinkClicked QWebEnginePage.NavigationType.NavigationTypeLinkClicked
+QWebEnginePage.NavigationTypeTyped QWebEnginePage.NavigationType.NavigationTypeTyped
+QWebEnginePage.NavigationTypeFormSubmitted QWebEnginePage.NavigationType.NavigationTypeFormSubmitted
+QWebEnginePage.NavigationTypeBackForward QWebEnginePage.NavigationType.NavigationTypeBackForward
+QWebEnginePage.NavigationTypeReload QWebEnginePage.NavigationType.NavigationTypeReload
+QWebEnginePage.NavigationTypeRedirect QWebEnginePage.NavigationType.NavigationTypeRedirect
+QWebEnginePage.NavigationTypeOther QWebEnginePage.NavigationType.NavigationTypeOther
+QWebEnginePage.InfoMessageLevel QWebEnginePage.JavaScriptConsoleMessageLevel.InfoMessageLevel
+QWebEnginePage.WarningMessageLevel QWebEnginePage.JavaScriptConsoleMessageLevel.WarningMessageLevel
+QWebEnginePage.ErrorMessageLevel QWebEnginePage.JavaScriptConsoleMessageLevel.ErrorMessageLevel
+QWebEnginePage.FileSelectOpen QWebEnginePage.FileSelectionMode.FileSelectOpen
+QWebEnginePage.FileSelectOpenMultiple QWebEnginePage.FileSelectionMode.FileSelectOpenMultiple
+QWebEnginePage.Notifications QWebEnginePage.Feature.Notifications
+QWebEnginePage.Geolocation QWebEnginePage.Feature.Geolocation
+QWebEnginePage.MediaAudioCapture QWebEnginePage.Feature.MediaAudioCapture
+QWebEnginePage.MediaVideoCapture QWebEnginePage.Feature.MediaVideoCapture
+QWebEnginePage.MediaAudioVideoCapture QWebEnginePage.Feature.MediaAudioVideoCapture
+QWebEnginePage.MouseLock QWebEnginePage.Feature.MouseLock
+QWebEnginePage.DesktopVideoCapture QWebEnginePage.Feature.DesktopVideoCapture
+QWebEnginePage.DesktopAudioVideoCapture QWebEnginePage.Feature.DesktopAudioVideoCapture
+QWebEnginePage.PermissionUnknown QWebEnginePage.PermissionPolicy.PermissionUnknown
+QWebEnginePage.PermissionGrantedByUser QWebEnginePage.PermissionPolicy.PermissionGrantedByUser
+QWebEnginePage.PermissionDeniedByUser QWebEnginePage.PermissionPolicy.PermissionDeniedByUser
+QWebEnginePage.WebBrowserWindow QWebEnginePage.WebWindowType.WebBrowserWindow
+QWebEnginePage.WebBrowserTab QWebEnginePage.WebWindowType.WebBrowserTab
+QWebEnginePage.WebDialog QWebEnginePage.WebWindowType.WebDialog
+QWebEnginePage.WebBrowserBackgroundTab QWebEnginePage.WebWindowType.WebBrowserBackgroundTab
+QWebEnginePage.FindBackward QWebEnginePage.FindFlag.FindBackward
+QWebEnginePage.FindCaseSensitively QWebEnginePage.FindFlag.FindCaseSensitively
+QWebEnginePage.NoWebAction QWebEnginePage.WebAction.NoWebAction
+QWebEnginePage.Back QWebEnginePage.WebAction.Back
+QWebEnginePage.Forward QWebEnginePage.WebAction.Forward
+QWebEnginePage.Stop QWebEnginePage.WebAction.Stop
+QWebEnginePage.Reload QWebEnginePage.WebAction.Reload
+QWebEnginePage.Cut QWebEnginePage.WebAction.Cut
+QWebEnginePage.Copy QWebEnginePage.WebAction.Copy
+QWebEnginePage.Paste QWebEnginePage.WebAction.Paste
+QWebEnginePage.Undo QWebEnginePage.WebAction.Undo
+QWebEnginePage.Redo QWebEnginePage.WebAction.Redo
+QWebEnginePage.SelectAll QWebEnginePage.WebAction.SelectAll
+QWebEnginePage.ReloadAndBypassCache QWebEnginePage.WebAction.ReloadAndBypassCache
+QWebEnginePage.PasteAndMatchStyle QWebEnginePage.WebAction.PasteAndMatchStyle
+QWebEnginePage.OpenLinkInThisWindow QWebEnginePage.WebAction.OpenLinkInThisWindow
+QWebEnginePage.OpenLinkInNewWindow QWebEnginePage.WebAction.OpenLinkInNewWindow
+QWebEnginePage.OpenLinkInNewTab QWebEnginePage.WebAction.OpenLinkInNewTab
+QWebEnginePage.CopyLinkToClipboard QWebEnginePage.WebAction.CopyLinkToClipboard
+QWebEnginePage.DownloadLinkToDisk QWebEnginePage.WebAction.DownloadLinkToDisk
+QWebEnginePage.CopyImageToClipboard QWebEnginePage.WebAction.CopyImageToClipboard
+QWebEnginePage.CopyImageUrlToClipboard QWebEnginePage.WebAction.CopyImageUrlToClipboard
+QWebEnginePage.DownloadImageToDisk QWebEnginePage.WebAction.DownloadImageToDisk
+QWebEnginePage.CopyMediaUrlToClipboard QWebEnginePage.WebAction.CopyMediaUrlToClipboard
+QWebEnginePage.ToggleMediaControls QWebEnginePage.WebAction.ToggleMediaControls
+QWebEnginePage.ToggleMediaLoop QWebEnginePage.WebAction.ToggleMediaLoop
+QWebEnginePage.ToggleMediaPlayPause QWebEnginePage.WebAction.ToggleMediaPlayPause
+QWebEnginePage.ToggleMediaMute QWebEnginePage.WebAction.ToggleMediaMute
+QWebEnginePage.DownloadMediaToDisk QWebEnginePage.WebAction.DownloadMediaToDisk
+QWebEnginePage.InspectElement QWebEnginePage.WebAction.InspectElement
+QWebEnginePage.ExitFullScreen QWebEnginePage.WebAction.ExitFullScreen
+QWebEnginePage.RequestClose QWebEnginePage.WebAction.RequestClose
+QWebEnginePage.Unselect QWebEnginePage.WebAction.Unselect
+QWebEnginePage.SavePage QWebEnginePage.WebAction.SavePage
+QWebEnginePage.OpenLinkInNewBackgroundTab QWebEnginePage.WebAction.OpenLinkInNewBackgroundTab
+QWebEnginePage.ViewSource QWebEnginePage.WebAction.ViewSource
+QWebEnginePage.ToggleBold QWebEnginePage.WebAction.ToggleBold
+QWebEnginePage.ToggleItalic QWebEnginePage.WebAction.ToggleItalic
+QWebEnginePage.ToggleUnderline QWebEnginePage.WebAction.ToggleUnderline
+QWebEnginePage.ToggleStrikethrough QWebEnginePage.WebAction.ToggleStrikethrough
+QWebEnginePage.AlignLeft QWebEnginePage.WebAction.AlignLeft
+QWebEnginePage.AlignCenter QWebEnginePage.WebAction.AlignCenter
+QWebEnginePage.AlignRight QWebEnginePage.WebAction.AlignRight
+QWebEnginePage.AlignJustified QWebEnginePage.WebAction.AlignJustified
+QWebEnginePage.Indent QWebEnginePage.WebAction.Indent
+QWebEnginePage.Outdent QWebEnginePage.WebAction.Outdent
+QWebEnginePage.InsertOrderedList QWebEnginePage.WebAction.InsertOrderedList
+QWebEnginePage.InsertUnorderedList QWebEnginePage.WebAction.InsertUnorderedList
+QWebEngineProfile.NoPersistentCookies QWebEngineProfile.PersistentCookiesPolicy.NoPersistentCookies
+QWebEngineProfile.AllowPersistentCookies QWebEngineProfile.PersistentCookiesPolicy.AllowPersistentCookies
+QWebEngineProfile.ForcePersistentCookies QWebEngineProfile.PersistentCookiesPolicy.ForcePersistentCookies
+QWebEngineProfile.MemoryHttpCache QWebEngineProfile.HttpCacheType.MemoryHttpCache
+QWebEngineProfile.DiskHttpCache QWebEngineProfile.HttpCacheType.DiskHttpCache
+QWebEngineProfile.NoCache QWebEngineProfile.HttpCacheType.NoCache
+QWebEngineScript.MainWorld QWebEngineScript.ScriptWorldId.MainWorld
+QWebEngineScript.ApplicationWorld QWebEngineScript.ScriptWorldId.ApplicationWorld
+QWebEngineScript.UserWorld QWebEngineScript.ScriptWorldId.UserWorld
+QWebEngineScript.Deferred QWebEngineScript.InjectionPoint.Deferred
+QWebEngineScript.DocumentReady QWebEngineScript.InjectionPoint.DocumentReady
+QWebEngineScript.DocumentCreation QWebEngineScript.InjectionPoint.DocumentCreation
+QWebEngineSettings.DisallowUnknownUrlSchemes QWebEngineSettings.UnknownUrlSchemePolicy.DisallowUnknownUrlSchemes
+QWebEngineSettings.AllowUnknownUrlSchemesFromUserInteraction QWebEngineSettings.UnknownUrlSchemePolicy.AllowUnknownUrlSchemesFromUserInteraction
+QWebEngineSettings.AllowAllUnknownUrlSchemes QWebEngineSettings.UnknownUrlSchemePolicy.AllowAllUnknownUrlSchemes
+QWebEngineSettings.MinimumFontSize QWebEngineSettings.FontSize.MinimumFontSize
+QWebEngineSettings.MinimumLogicalFontSize QWebEngineSettings.FontSize.MinimumLogicalFontSize
+QWebEngineSettings.DefaultFontSize QWebEngineSettings.FontSize.DefaultFontSize
+QWebEngineSettings.DefaultFixedFontSize QWebEngineSettings.FontSize.DefaultFixedFontSize
+QWebEngineSettings.AutoLoadImages QWebEngineSettings.WebAttribute.AutoLoadImages
+QWebEngineSettings.JavascriptEnabled QWebEngineSettings.WebAttribute.JavascriptEnabled
+QWebEngineSettings.JavascriptCanOpenWindows QWebEngineSettings.WebAttribute.JavascriptCanOpenWindows
+QWebEngineSettings.JavascriptCanAccessClipboard QWebEngineSettings.WebAttribute.JavascriptCanAccessClipboard
+QWebEngineSettings.LinksIncludedInFocusChain QWebEngineSettings.WebAttribute.LinksIncludedInFocusChain
+QWebEngineSettings.LocalStorageEnabled QWebEngineSettings.WebAttribute.LocalStorageEnabled
+QWebEngineSettings.LocalContentCanAccessRemoteUrls QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls
+QWebEngineSettings.XSSAuditingEnabled QWebEngineSettings.WebAttribute.XSSAuditingEnabled
+QWebEngineSettings.SpatialNavigationEnabled QWebEngineSettings.WebAttribute.SpatialNavigationEnabled
+QWebEngineSettings.LocalContentCanAccessFileUrls QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls
+QWebEngineSettings.HyperlinkAuditingEnabled QWebEngineSettings.WebAttribute.HyperlinkAuditingEnabled
+QWebEngineSettings.ScrollAnimatorEnabled QWebEngineSettings.WebAttribute.ScrollAnimatorEnabled
+QWebEngineSettings.ErrorPageEnabled QWebEngineSettings.WebAttribute.ErrorPageEnabled
+QWebEngineSettings.PluginsEnabled QWebEngineSettings.WebAttribute.PluginsEnabled
+QWebEngineSettings.FullScreenSupportEnabled QWebEngineSettings.WebAttribute.FullScreenSupportEnabled
+QWebEngineSettings.ScreenCaptureEnabled QWebEngineSettings.WebAttribute.ScreenCaptureEnabled
+QWebEngineSettings.WebGLEnabled QWebEngineSettings.WebAttribute.WebGLEnabled
+QWebEngineSettings.Accelerated2dCanvasEnabled QWebEngineSettings.WebAttribute.Accelerated2dCanvasEnabled
+QWebEngineSettings.AutoLoadIconsForPage QWebEngineSettings.WebAttribute.AutoLoadIconsForPage
+QWebEngineSettings.TouchIconsEnabled QWebEngineSettings.WebAttribute.TouchIconsEnabled
+QWebEngineSettings.FocusOnNavigationEnabled QWebEngineSettings.WebAttribute.FocusOnNavigationEnabled
+QWebEngineSettings.PrintElementBackgrounds QWebEngineSettings.WebAttribute.PrintElementBackgrounds
+QWebEngineSettings.AllowRunningInsecureContent QWebEngineSettings.WebAttribute.AllowRunningInsecureContent
+QWebEngineSettings.AllowGeolocationOnInsecureOrigins QWebEngineSettings.WebAttribute.AllowGeolocationOnInsecureOrigins
+QWebEngineSettings.AllowWindowActivationFromJavaScript QWebEngineSettings.WebAttribute.AllowWindowActivationFromJavaScript
+QWebEngineSettings.ShowScrollBars QWebEngineSettings.WebAttribute.ShowScrollBars
+QWebEngineSettings.PlaybackRequiresUserGesture QWebEngineSettings.WebAttribute.PlaybackRequiresUserGesture
+QWebEngineSettings.WebRTCPublicInterfacesOnly QWebEngineSettings.WebAttribute.WebRTCPublicInterfacesOnly
+QWebEngineSettings.JavascriptCanPaste QWebEngineSettings.WebAttribute.JavascriptCanPaste
+QWebEngineSettings.DnsPrefetchEnabled QWebEngineSettings.WebAttribute.DnsPrefetchEnabled
+QWebEngineSettings.PdfViewerEnabled QWebEngineSettings.WebAttribute.PdfViewerEnabled
+QWebEngineSettings.StandardFont QWebEngineSettings.FontFamily.StandardFont
+QWebEngineSettings.FixedFont QWebEngineSettings.FontFamily.FixedFont
+QWebEngineSettings.SerifFont QWebEngineSettings.FontFamily.SerifFont
+QWebEngineSettings.SansSerifFont QWebEngineSettings.FontFamily.SansSerifFont
+QWebEngineSettings.CursiveFont QWebEngineSettings.FontFamily.CursiveFont
+QWebEngineSettings.FantasyFont QWebEngineSettings.FontFamily.FantasyFont
+QWebEngineSettings.PictographFont QWebEngineSettings.FontFamily.PictographFont
+QWebElement.InlineStyle QWebElement.StyleResolveStrategy.InlineStyle
+QWebElement.CascadedStyle QWebElement.StyleResolveStrategy.CascadedStyle
+QWebElement.ComputedStyle QWebElement.StyleResolveStrategy.ComputedStyle
+QWebSecurityOrigin.AllowSubdomains QWebSecurityOrigin.SubdomainSetting.AllowSubdomains
+QWebSecurityOrigin.DisallowSubdomains QWebSecurityOrigin.SubdomainSetting.DisallowSubdomains
+QWebSettings.AlwaysAllowThirdPartyCookies QWebSettings.ThirdPartyCookiePolicy.AlwaysAllowThirdPartyCookies
+QWebSettings.AlwaysBlockThirdPartyCookies QWebSettings.ThirdPartyCookiePolicy.AlwaysBlockThirdPartyCookies
+QWebSettings.AllowThirdPartyWithExistingCookies QWebSettings.ThirdPartyCookiePolicy.AllowThirdPartyWithExistingCookies
+QWebSettings.MinimumFontSize QWebSettings.FontSize.MinimumFontSize
+QWebSettings.MinimumLogicalFontSize QWebSettings.FontSize.MinimumLogicalFontSize
+QWebSettings.DefaultFontSize QWebSettings.FontSize.DefaultFontSize
+QWebSettings.DefaultFixedFontSize QWebSettings.FontSize.DefaultFixedFontSize
+QWebSettings.MissingImageGraphic QWebSettings.WebGraphic.MissingImageGraphic
+QWebSettings.MissingPluginGraphic QWebSettings.WebGraphic.MissingPluginGraphic
+QWebSettings.DefaultFrameIconGraphic QWebSettings.WebGraphic.DefaultFrameIconGraphic
+QWebSettings.TextAreaSizeGripCornerGraphic QWebSettings.WebGraphic.TextAreaSizeGripCornerGraphic
+QWebSettings.InputSpeechButtonGraphic QWebSettings.WebGraphic.InputSpeechButtonGraphic
+QWebSettings.SearchCancelButtonGraphic QWebSettings.WebGraphic.SearchCancelButtonGraphic
+QWebSettings.SearchCancelButtonPressedGraphic QWebSettings.WebGraphic.SearchCancelButtonPressedGraphic
+QWebSettings.AutoLoadImages QWebSettings.WebAttribute.AutoLoadImages
+QWebSettings.JavascriptEnabled QWebSettings.WebAttribute.JavascriptEnabled
+QWebSettings.JavaEnabled QWebSettings.WebAttribute.JavaEnabled
+QWebSettings.PluginsEnabled QWebSettings.WebAttribute.PluginsEnabled
+QWebSettings.PrivateBrowsingEnabled QWebSettings.WebAttribute.PrivateBrowsingEnabled
+QWebSettings.JavascriptCanOpenWindows QWebSettings.WebAttribute.JavascriptCanOpenWindows
+QWebSettings.JavascriptCanCloseWindows QWebSettings.WebAttribute.JavascriptCanCloseWindows
+QWebSettings.JavascriptCanAccessClipboard QWebSettings.WebAttribute.JavascriptCanAccessClipboard
+QWebSettings.DeveloperExtrasEnabled QWebSettings.WebAttribute.DeveloperExtrasEnabled
+QWebSettings.LinksIncludedInFocusChain QWebSettings.WebAttribute.LinksIncludedInFocusChain
+QWebSettings.ZoomTextOnly QWebSettings.WebAttribute.ZoomTextOnly
+QWebSettings.PrintElementBackgrounds QWebSettings.WebAttribute.PrintElementBackgrounds
+QWebSettings.OfflineStorageDatabaseEnabled QWebSettings.WebAttribute.OfflineStorageDatabaseEnabled
+QWebSettings.OfflineWebApplicationCacheEnabled QWebSettings.WebAttribute.OfflineWebApplicationCacheEnabled
+QWebSettings.LocalStorageDatabaseEnabled QWebSettings.WebAttribute.LocalStorageDatabaseEnabled
+QWebSettings.LocalStorageEnabled QWebSettings.WebAttribute.LocalStorageEnabled
+QWebSettings.LocalContentCanAccessRemoteUrls QWebSettings.WebAttribute.LocalContentCanAccessRemoteUrls
+QWebSettings.DnsPrefetchEnabled QWebSettings.WebAttribute.DnsPrefetchEnabled
+QWebSettings.XSSAuditingEnabled QWebSettings.WebAttribute.XSSAuditingEnabled
+QWebSettings.AcceleratedCompositingEnabled QWebSettings.WebAttribute.AcceleratedCompositingEnabled
+QWebSettings.SpatialNavigationEnabled QWebSettings.WebAttribute.SpatialNavigationEnabled
+QWebSettings.LocalContentCanAccessFileUrls QWebSettings.WebAttribute.LocalContentCanAccessFileUrls
+QWebSettings.TiledBackingStoreEnabled QWebSettings.WebAttribute.TiledBackingStoreEnabled
+QWebSettings.FrameFlatteningEnabled QWebSettings.WebAttribute.FrameFlatteningEnabled
+QWebSettings.SiteSpecificQuirksEnabled QWebSettings.WebAttribute.SiteSpecificQuirksEnabled
+QWebSettings.WebGLEnabled QWebSettings.WebAttribute.WebGLEnabled
+QWebSettings.HyperlinkAuditingEnabled QWebSettings.WebAttribute.HyperlinkAuditingEnabled
+QWebSettings.CSSRegionsEnabled QWebSettings.WebAttribute.CSSRegionsEnabled
+QWebSettings.CSSGridLayoutEnabled QWebSettings.WebAttribute.CSSGridLayoutEnabled
+QWebSettings.ScrollAnimatorEnabled QWebSettings.WebAttribute.ScrollAnimatorEnabled
+QWebSettings.CaretBrowsingEnabled QWebSettings.WebAttribute.CaretBrowsingEnabled
+QWebSettings.NotificationsEnabled QWebSettings.WebAttribute.NotificationsEnabled
+QWebSettings.WebAudioEnabled QWebSettings.WebAttribute.WebAudioEnabled
+QWebSettings.Accelerated2dCanvasEnabled QWebSettings.WebAttribute.Accelerated2dCanvasEnabled
+QWebSettings.StandardFont QWebSettings.FontFamily.StandardFont
+QWebSettings.FixedFont QWebSettings.FontFamily.FixedFont
+QWebSettings.SerifFont QWebSettings.FontFamily.SerifFont
+QWebSettings.SansSerifFont QWebSettings.FontFamily.SansSerifFont
+QWebSettings.CursiveFont QWebSettings.FontFamily.CursiveFont
+QWebSettings.FantasyFont QWebSettings.FontFamily.FantasyFont
+QWebFrame.ContentsLayer QWebFrame.RenderLayer.ContentsLayer
+QWebFrame.ScrollBarLayer QWebFrame.RenderLayer.ScrollBarLayer
+QWebFrame.PanIconLayer QWebFrame.RenderLayer.PanIconLayer
+QWebFrame.AllLayers QWebFrame.RenderLayer.AllLayers
+QWebFrame.QtOwnership QWebFrame.ValueOwnership.QtOwnership
+QWebFrame.ScriptOwnership QWebFrame.ValueOwnership.ScriptOwnership
+QWebFrame.AutoOwnership QWebFrame.ValueOwnership.AutoOwnership
+QWebPage.VisibilityStateVisible QWebPage.VisibilityState.VisibilityStateVisible
+QWebPage.VisibilityStateHidden QWebPage.VisibilityState.VisibilityStateHidden
+QWebPage.VisibilityStatePrerender QWebPage.VisibilityState.VisibilityStatePrerender
+QWebPage.VisibilityStateUnloaded QWebPage.VisibilityState.VisibilityStateUnloaded
+QWebPage.Notifications QWebPage.Feature.Notifications
+QWebPage.Geolocation QWebPage.Feature.Geolocation
+QWebPage.PermissionUnknown QWebPage.PermissionPolicy.PermissionUnknown
+QWebPage.PermissionGrantedByUser QWebPage.PermissionPolicy.PermissionGrantedByUser
+QWebPage.PermissionDeniedByUser QWebPage.PermissionPolicy.PermissionDeniedByUser
+QWebPage.QtNetwork QWebPage.ErrorDomain.QtNetwork
+QWebPage.Http QWebPage.ErrorDomain.Http
+QWebPage.WebKit QWebPage.ErrorDomain.WebKit
+QWebPage.ChooseMultipleFilesExtension QWebPage.Extension.ChooseMultipleFilesExtension
+QWebPage.ErrorPageExtension QWebPage.Extension.ErrorPageExtension
+QWebPage.WebBrowserWindow QWebPage.WebWindowType.WebBrowserWindow
+QWebPage.WebModalDialog QWebPage.WebWindowType.WebModalDialog
+QWebPage.DontDelegateLinks QWebPage.LinkDelegationPolicy.DontDelegateLinks
+QWebPage.DelegateExternalLinks QWebPage.LinkDelegationPolicy.DelegateExternalLinks
+QWebPage.DelegateAllLinks QWebPage.LinkDelegationPolicy.DelegateAllLinks
+QWebPage.FindBackward QWebPage.FindFlag.FindBackward
+QWebPage.FindCaseSensitively QWebPage.FindFlag.FindCaseSensitively
+QWebPage.FindWrapsAroundDocument QWebPage.FindFlag.FindWrapsAroundDocument
+QWebPage.HighlightAllOccurrences QWebPage.FindFlag.HighlightAllOccurrences
+QWebPage.FindAtWordBeginningsOnly QWebPage.FindFlag.FindAtWordBeginningsOnly
+QWebPage.TreatMedialCapitalAsWordBeginning QWebPage.FindFlag.TreatMedialCapitalAsWordBeginning
+QWebPage.FindBeginsInSelection QWebPage.FindFlag.FindBeginsInSelection
+QWebPage.NoWebAction QWebPage.WebAction.NoWebAction
+QWebPage.OpenLink QWebPage.WebAction.OpenLink
+QWebPage.OpenLinkInNewWindow QWebPage.WebAction.OpenLinkInNewWindow
+QWebPage.OpenFrameInNewWindow QWebPage.WebAction.OpenFrameInNewWindow
+QWebPage.DownloadLinkToDisk QWebPage.WebAction.DownloadLinkToDisk
+QWebPage.CopyLinkToClipboard QWebPage.WebAction.CopyLinkToClipboard
+QWebPage.OpenImageInNewWindow QWebPage.WebAction.OpenImageInNewWindow
+QWebPage.DownloadImageToDisk QWebPage.WebAction.DownloadImageToDisk
+QWebPage.CopyImageToClipboard QWebPage.WebAction.CopyImageToClipboard
+QWebPage.Back QWebPage.WebAction.Back
+QWebPage.Forward QWebPage.WebAction.Forward
+QWebPage.Stop QWebPage.WebAction.Stop
+QWebPage.Reload QWebPage.WebAction.Reload
+QWebPage.Cut QWebPage.WebAction.Cut
+QWebPage.Copy QWebPage.WebAction.Copy
+QWebPage.Paste QWebPage.WebAction.Paste
+QWebPage.Undo QWebPage.WebAction.Undo
+QWebPage.Redo QWebPage.WebAction.Redo
+QWebPage.MoveToNextChar QWebPage.WebAction.MoveToNextChar
+QWebPage.MoveToPreviousChar QWebPage.WebAction.MoveToPreviousChar
+QWebPage.MoveToNextWord QWebPage.WebAction.MoveToNextWord
+QWebPage.MoveToPreviousWord QWebPage.WebAction.MoveToPreviousWord
+QWebPage.MoveToNextLine QWebPage.WebAction.MoveToNextLine
+QWebPage.MoveToPreviousLine QWebPage.WebAction.MoveToPreviousLine
+QWebPage.MoveToStartOfLine QWebPage.WebAction.MoveToStartOfLine
+QWebPage.MoveToEndOfLine QWebPage.WebAction.MoveToEndOfLine
+QWebPage.MoveToStartOfBlock QWebPage.WebAction.MoveToStartOfBlock
+QWebPage.MoveToEndOfBlock QWebPage.WebAction.MoveToEndOfBlock
+QWebPage.MoveToStartOfDocument QWebPage.WebAction.MoveToStartOfDocument
+QWebPage.MoveToEndOfDocument QWebPage.WebAction.MoveToEndOfDocument
+QWebPage.SelectNextChar QWebPage.WebAction.SelectNextChar
+QWebPage.SelectPreviousChar QWebPage.WebAction.SelectPreviousChar
+QWebPage.SelectNextWord QWebPage.WebAction.SelectNextWord
+QWebPage.SelectPreviousWord QWebPage.WebAction.SelectPreviousWord
+QWebPage.SelectNextLine QWebPage.WebAction.SelectNextLine
+QWebPage.SelectPreviousLine QWebPage.WebAction.SelectPreviousLine
+QWebPage.SelectStartOfLine QWebPage.WebAction.SelectStartOfLine
+QWebPage.SelectEndOfLine QWebPage.WebAction.SelectEndOfLine
+QWebPage.SelectStartOfBlock QWebPage.WebAction.SelectStartOfBlock
+QWebPage.SelectEndOfBlock QWebPage.WebAction.SelectEndOfBlock
+QWebPage.SelectStartOfDocument QWebPage.WebAction.SelectStartOfDocument
+QWebPage.SelectEndOfDocument QWebPage.WebAction.SelectEndOfDocument
+QWebPage.DeleteStartOfWord QWebPage.WebAction.DeleteStartOfWord
+QWebPage.DeleteEndOfWord QWebPage.WebAction.DeleteEndOfWord
+QWebPage.SetTextDirectionDefault QWebPage.WebAction.SetTextDirectionDefault
+QWebPage.SetTextDirectionLeftToRight QWebPage.WebAction.SetTextDirectionLeftToRight
+QWebPage.SetTextDirectionRightToLeft QWebPage.WebAction.SetTextDirectionRightToLeft
+QWebPage.ToggleBold QWebPage.WebAction.ToggleBold
+QWebPage.ToggleItalic QWebPage.WebAction.ToggleItalic
+QWebPage.ToggleUnderline QWebPage.WebAction.ToggleUnderline
+QWebPage.InspectElement QWebPage.WebAction.InspectElement
+QWebPage.InsertParagraphSeparator QWebPage.WebAction.InsertParagraphSeparator
+QWebPage.InsertLineSeparator QWebPage.WebAction.InsertLineSeparator
+QWebPage.SelectAll QWebPage.WebAction.SelectAll
+QWebPage.ReloadAndBypassCache QWebPage.WebAction.ReloadAndBypassCache
+QWebPage.PasteAndMatchStyle QWebPage.WebAction.PasteAndMatchStyle
+QWebPage.RemoveFormat QWebPage.WebAction.RemoveFormat
+QWebPage.ToggleStrikethrough QWebPage.WebAction.ToggleStrikethrough
+QWebPage.ToggleSubscript QWebPage.WebAction.ToggleSubscript
+QWebPage.ToggleSuperscript QWebPage.WebAction.ToggleSuperscript
+QWebPage.InsertUnorderedList QWebPage.WebAction.InsertUnorderedList
+QWebPage.InsertOrderedList QWebPage.WebAction.InsertOrderedList
+QWebPage.Indent QWebPage.WebAction.Indent
+QWebPage.Outdent QWebPage.WebAction.Outdent
+QWebPage.AlignCenter QWebPage.WebAction.AlignCenter
+QWebPage.AlignJustified QWebPage.WebAction.AlignJustified
+QWebPage.AlignLeft QWebPage.WebAction.AlignLeft
+QWebPage.AlignRight QWebPage.WebAction.AlignRight
+QWebPage.StopScheduledPageRefresh QWebPage.WebAction.StopScheduledPageRefresh
+QWebPage.CopyImageUrlToClipboard QWebPage.WebAction.CopyImageUrlToClipboard
+QWebPage.OpenLinkInThisWindow QWebPage.WebAction.OpenLinkInThisWindow
+QWebPage.DownloadMediaToDisk QWebPage.WebAction.DownloadMediaToDisk
+QWebPage.CopyMediaUrlToClipboard QWebPage.WebAction.CopyMediaUrlToClipboard
+QWebPage.ToggleMediaControls QWebPage.WebAction.ToggleMediaControls
+QWebPage.ToggleMediaLoop QWebPage.WebAction.ToggleMediaLoop
+QWebPage.ToggleMediaPlayPause QWebPage.WebAction.ToggleMediaPlayPause
+QWebPage.ToggleMediaMute QWebPage.WebAction.ToggleMediaMute
+QWebPage.ToggleVideoFullscreen QWebPage.WebAction.ToggleVideoFullscreen
+QWebPage.NavigationTypeLinkClicked QWebPage.NavigationType.NavigationTypeLinkClicked
+QWebPage.NavigationTypeFormSubmitted QWebPage.NavigationType.NavigationTypeFormSubmitted
+QWebPage.NavigationTypeBackOrForward QWebPage.NavigationType.NavigationTypeBackOrForward
+QWebPage.NavigationTypeReload QWebPage.NavigationType.NavigationTypeReload
+QWebPage.NavigationTypeFormResubmitted QWebPage.NavigationType.NavigationTypeFormResubmitted
+QWebPage.NavigationTypeOther QWebPage.NavigationType.NavigationTypeOther
+QWebPage.domain QWebPage.ErrorDomain.domain
+QWidget.DrawWindowBackground QWidget.RenderFlag.DrawWindowBackground
+QWidget.DrawChildren QWidget.RenderFlag.DrawChildren
+QWidget.IgnoreMask QWidget.RenderFlag.IgnoreMask
+QAbstractItemDelegate.NoHint QAbstractItemDelegate.EndEditHint.NoHint
+QAbstractItemDelegate.EditNextItem QAbstractItemDelegate.EndEditHint.EditNextItem
+QAbstractItemDelegate.EditPreviousItem QAbstractItemDelegate.EndEditHint.EditPreviousItem
+QAbstractItemDelegate.SubmitModelCache QAbstractItemDelegate.EndEditHint.SubmitModelCache
+QAbstractItemDelegate.RevertModelCache QAbstractItemDelegate.EndEditHint.RevertModelCache
+QFrame.Shadow_Mask QFrame.StyleMask.Shadow_Mask
+QFrame.Shape_Mask QFrame.StyleMask.Shape_Mask
+QFrame.NoFrame QFrame.Shape.NoFrame
+QFrame.Box QFrame.Shape.Box
+QFrame.Panel QFrame.Shape.Panel
+QFrame.WinPanel QFrame.Shape.WinPanel
+QFrame.HLine QFrame.Shape.HLine
+QFrame.VLine QFrame.Shape.VLine
+QFrame.StyledPanel QFrame.Shape.StyledPanel
+QFrame.Plain QFrame.Shadow.Plain
+QFrame.Raised QFrame.Shadow.Raised
+QFrame.Sunken QFrame.Shadow.Sunken
+QAbstractScrollArea.AdjustIgnored QAbstractScrollArea.SizeAdjustPolicy.AdjustIgnored
+QAbstractScrollArea.AdjustToContentsOnFirstShow QAbstractScrollArea.SizeAdjustPolicy.AdjustToContentsOnFirstShow
+QAbstractScrollArea.AdjustToContents QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents
+QAbstractItemView.OnItem QAbstractItemView.DropIndicatorPosition.OnItem
+QAbstractItemView.AboveItem QAbstractItemView.DropIndicatorPosition.AboveItem
+QAbstractItemView.BelowItem QAbstractItemView.DropIndicatorPosition.BelowItem
+QAbstractItemView.OnViewport QAbstractItemView.DropIndicatorPosition.OnViewport
+QAbstractItemView.NoState QAbstractItemView.State.NoState
+QAbstractItemView.DraggingState QAbstractItemView.State.DraggingState
+QAbstractItemView.DragSelectingState QAbstractItemView.State.DragSelectingState
+QAbstractItemView.EditingState QAbstractItemView.State.EditingState
+QAbstractItemView.ExpandingState QAbstractItemView.State.ExpandingState
+QAbstractItemView.CollapsingState QAbstractItemView.State.CollapsingState
+QAbstractItemView.AnimatingState QAbstractItemView.State.AnimatingState
+QAbstractItemView.MoveUp QAbstractItemView.CursorAction.MoveUp
+QAbstractItemView.MoveDown QAbstractItemView.CursorAction.MoveDown
+QAbstractItemView.MoveLeft QAbstractItemView.CursorAction.MoveLeft
+QAbstractItemView.MoveRight QAbstractItemView.CursorAction.MoveRight
+QAbstractItemView.MoveHome QAbstractItemView.CursorAction.MoveHome
+QAbstractItemView.MoveEnd QAbstractItemView.CursorAction.MoveEnd
+QAbstractItemView.MovePageUp QAbstractItemView.CursorAction.MovePageUp
+QAbstractItemView.MovePageDown QAbstractItemView.CursorAction.MovePageDown
+QAbstractItemView.MoveNext QAbstractItemView.CursorAction.MoveNext
+QAbstractItemView.MovePrevious QAbstractItemView.CursorAction.MovePrevious
+QAbstractItemView.NoSelection QAbstractItemView.SelectionMode.NoSelection
+QAbstractItemView.SingleSelection QAbstractItemView.SelectionMode.SingleSelection
+QAbstractItemView.MultiSelection QAbstractItemView.SelectionMode.MultiSelection
+QAbstractItemView.ExtendedSelection QAbstractItemView.SelectionMode.ExtendedSelection
+QAbstractItemView.ContiguousSelection QAbstractItemView.SelectionMode.ContiguousSelection
+QAbstractItemView.SelectItems QAbstractItemView.SelectionBehavior.SelectItems
+QAbstractItemView.SelectRows QAbstractItemView.SelectionBehavior.SelectRows
+QAbstractItemView.SelectColumns QAbstractItemView.SelectionBehavior.SelectColumns
+QAbstractItemView.ScrollPerItem QAbstractItemView.ScrollMode.ScrollPerItem
+QAbstractItemView.ScrollPerPixel QAbstractItemView.ScrollMode.ScrollPerPixel
+QAbstractItemView.EnsureVisible QAbstractItemView.ScrollHint.EnsureVisible
+QAbstractItemView.PositionAtTop QAbstractItemView.ScrollHint.PositionAtTop
+QAbstractItemView.PositionAtBottom QAbstractItemView.ScrollHint.PositionAtBottom
+QAbstractItemView.PositionAtCenter QAbstractItemView.ScrollHint.PositionAtCenter
+QAbstractItemView.NoEditTriggers QAbstractItemView.EditTrigger.NoEditTriggers
+QAbstractItemView.CurrentChanged QAbstractItemView.EditTrigger.CurrentChanged
+QAbstractItemView.DoubleClicked QAbstractItemView.EditTrigger.DoubleClicked
+QAbstractItemView.SelectedClicked QAbstractItemView.EditTrigger.SelectedClicked
+QAbstractItemView.EditKeyPressed QAbstractItemView.EditTrigger.EditKeyPressed
+QAbstractItemView.AnyKeyPressed QAbstractItemView.EditTrigger.AnyKeyPressed
+QAbstractItemView.AllEditTriggers QAbstractItemView.EditTrigger.AllEditTriggers
+QAbstractItemView.NoDragDrop QAbstractItemView.DragDropMode.NoDragDrop
+QAbstractItemView.DragOnly QAbstractItemView.DragDropMode.DragOnly
+QAbstractItemView.DropOnly QAbstractItemView.DragDropMode.DropOnly
+QAbstractItemView.DragDrop QAbstractItemView.DragDropMode.DragDrop
+QAbstractItemView.InternalMove QAbstractItemView.DragDropMode.InternalMove
+QAbstractSlider.SliderRangeChange QAbstractSlider.SliderChange.SliderRangeChange
+QAbstractSlider.SliderOrientationChange QAbstractSlider.SliderChange.SliderOrientationChange
+QAbstractSlider.SliderStepsChange QAbstractSlider.SliderChange.SliderStepsChange
+QAbstractSlider.SliderValueChange QAbstractSlider.SliderChange.SliderValueChange
+QAbstractSlider.SliderNoAction QAbstractSlider.SliderAction.SliderNoAction
+QAbstractSlider.SliderSingleStepAdd QAbstractSlider.SliderAction.SliderSingleStepAdd
+QAbstractSlider.SliderSingleStepSub QAbstractSlider.SliderAction.SliderSingleStepSub
+QAbstractSlider.SliderPageStepAdd QAbstractSlider.SliderAction.SliderPageStepAdd
+QAbstractSlider.SliderPageStepSub QAbstractSlider.SliderAction.SliderPageStepSub
+QAbstractSlider.SliderToMinimum QAbstractSlider.SliderAction.SliderToMinimum
+QAbstractSlider.SliderToMaximum QAbstractSlider.SliderAction.SliderToMaximum
+QAbstractSlider.SliderMove QAbstractSlider.SliderAction.SliderMove
+QAbstractSpinBox.DefaultStepType QAbstractSpinBox.StepType.DefaultStepType
+QAbstractSpinBox.AdaptiveDecimalStepType QAbstractSpinBox.StepType.AdaptiveDecimalStepType
+QAbstractSpinBox.CorrectToPreviousValue QAbstractSpinBox.CorrectionMode.CorrectToPreviousValue
+QAbstractSpinBox.CorrectToNearestValue QAbstractSpinBox.CorrectionMode.CorrectToNearestValue
+QAbstractSpinBox.UpDownArrows QAbstractSpinBox.ButtonSymbols.UpDownArrows
+QAbstractSpinBox.PlusMinus QAbstractSpinBox.ButtonSymbols.PlusMinus
+QAbstractSpinBox.NoButtons QAbstractSpinBox.ButtonSymbols.NoButtons
+QAbstractSpinBox.StepNone QAbstractSpinBox.StepEnabledFlag.StepNone
+QAbstractSpinBox.StepUpEnabled QAbstractSpinBox.StepEnabledFlag.StepUpEnabled
+QAbstractSpinBox.StepDownEnabled QAbstractSpinBox.StepEnabledFlag.StepDownEnabled
+QAction.LowPriority QAction.Priority.LowPriority
+QAction.NormalPriority QAction.Priority.NormalPriority
+QAction.HighPriority QAction.Priority.HighPriority
+QAction.NoRole QAction.MenuRole.NoRole
+QAction.TextHeuristicRole QAction.MenuRole.TextHeuristicRole
+QAction.ApplicationSpecificRole QAction.MenuRole.ApplicationSpecificRole
+QAction.AboutQtRole QAction.MenuRole.AboutQtRole
+QAction.AboutRole QAction.MenuRole.AboutRole
+QAction.PreferencesRole QAction.MenuRole.PreferencesRole
+QAction.QuitRole QAction.MenuRole.QuitRole
+QAction.Trigger QAction.ActionEvent.Trigger
+QAction.Hover QAction.ActionEvent.Hover
+QActionGroup.None_ QActionGroup.ExclusionPolicy.None_
+QActionGroup.Exclusive QActionGroup.ExclusionPolicy.Exclusive
+QActionGroup.ExclusiveOptional QActionGroup.ExclusionPolicy.ExclusiveOptional
+QApplication.NormalColor QApplication.ColorSpec.NormalColor
+QApplication.CustomColor QApplication.ColorSpec.CustomColor
+QApplication.ManyColor QApplication.ColorSpec.ManyColor
+QLayout.SetDefaultConstraint QLayout.SizeConstraint.SetDefaultConstraint
+QLayout.SetNoConstraint QLayout.SizeConstraint.SetNoConstraint
+QLayout.SetMinimumSize QLayout.SizeConstraint.SetMinimumSize
+QLayout.SetFixedSize QLayout.SizeConstraint.SetFixedSize
+QLayout.SetMaximumSize QLayout.SizeConstraint.SetMaximumSize
+QLayout.SetMinAndMaxSize QLayout.SizeConstraint.SetMinAndMaxSize
+QBoxLayout.LeftToRight QBoxLayout.Direction.LeftToRight
+QBoxLayout.RightToLeft QBoxLayout.Direction.RightToLeft
+QBoxLayout.TopToBottom QBoxLayout.Direction.TopToBottom
+QBoxLayout.BottomToTop QBoxLayout.Direction.BottomToTop
+QBoxLayout.Down QBoxLayout.Direction.Down
+QBoxLayout.Up QBoxLayout.Direction.Up
+QCalendarWidget.NoSelection QCalendarWidget.SelectionMode.NoSelection
+QCalendarWidget.SingleSelection QCalendarWidget.SelectionMode.SingleSelection
+QCalendarWidget.NoVerticalHeader QCalendarWidget.VerticalHeaderFormat.NoVerticalHeader
+QCalendarWidget.ISOWeekNumbers QCalendarWidget.VerticalHeaderFormat.ISOWeekNumbers
+QCalendarWidget.NoHorizontalHeader QCalendarWidget.HorizontalHeaderFormat.NoHorizontalHeader
+QCalendarWidget.SingleLetterDayNames QCalendarWidget.HorizontalHeaderFormat.SingleLetterDayNames
+QCalendarWidget.ShortDayNames QCalendarWidget.HorizontalHeaderFormat.ShortDayNames
+QCalendarWidget.LongDayNames QCalendarWidget.HorizontalHeaderFormat.LongDayNames
+QDialog.Rejected QDialog.DialogCode.Rejected
+QDialog.Accepted QDialog.DialogCode.Accepted
+QColorDialog.ShowAlphaChannel QColorDialog.ColorDialogOption.ShowAlphaChannel
+QColorDialog.NoButtons QColorDialog.ColorDialogOption.NoButtons
+QColorDialog.DontUseNativeDialog QColorDialog.ColorDialogOption.DontUseNativeDialog
+QComboBox.AdjustToContents QComboBox.SizeAdjustPolicy.AdjustToContents
+QComboBox.AdjustToContentsOnFirstShow QComboBox.SizeAdjustPolicy.AdjustToContentsOnFirstShow
+QComboBox.AdjustToMinimumContentsLength QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLength
+QComboBox.AdjustToMinimumContentsLengthWithIcon QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon
+QComboBox.NoInsert QComboBox.InsertPolicy.NoInsert
+QComboBox.InsertAtTop QComboBox.InsertPolicy.InsertAtTop
+QComboBox.InsertAtCurrent QComboBox.InsertPolicy.InsertAtCurrent
+QComboBox.InsertAtBottom QComboBox.InsertPolicy.InsertAtBottom
+QComboBox.InsertAfterCurrent QComboBox.InsertPolicy.InsertAfterCurrent
+QComboBox.InsertBeforeCurrent QComboBox.InsertPolicy.InsertBeforeCurrent
+QComboBox.InsertAlphabetically QComboBox.InsertPolicy.InsertAlphabetically
+QStyle.RSIP_OnMouseClickAndAlreadyFocused QStyle.RequestSoftwareInputPanel.RSIP_OnMouseClickAndAlreadyFocused
+QStyle.RSIP_OnMouseClick QStyle.RequestSoftwareInputPanel.RSIP_OnMouseClick
+QStyle.SP_TitleBarMenuButton QStyle.StandardPixmap.SP_TitleBarMenuButton
+QStyle.SP_TitleBarMinButton QStyle.StandardPixmap.SP_TitleBarMinButton
+QStyle.SP_TitleBarMaxButton QStyle.StandardPixmap.SP_TitleBarMaxButton
+QStyle.SP_TitleBarCloseButton QStyle.StandardPixmap.SP_TitleBarCloseButton
+QStyle.SP_TitleBarNormalButton QStyle.StandardPixmap.SP_TitleBarNormalButton
+QStyle.SP_TitleBarShadeButton QStyle.StandardPixmap.SP_TitleBarShadeButton
+QStyle.SP_TitleBarUnshadeButton QStyle.StandardPixmap.SP_TitleBarUnshadeButton
+QStyle.SP_TitleBarContextHelpButton QStyle.StandardPixmap.SP_TitleBarContextHelpButton
+QStyle.SP_DockWidgetCloseButton QStyle.StandardPixmap.SP_DockWidgetCloseButton
+QStyle.SP_MessageBoxInformation QStyle.StandardPixmap.SP_MessageBoxInformation
+QStyle.SP_MessageBoxWarning QStyle.StandardPixmap.SP_MessageBoxWarning
+QStyle.SP_MessageBoxCritical QStyle.StandardPixmap.SP_MessageBoxCritical
+QStyle.SP_MessageBoxQuestion QStyle.StandardPixmap.SP_MessageBoxQuestion
+QStyle.SP_DesktopIcon QStyle.StandardPixmap.SP_DesktopIcon
+QStyle.SP_TrashIcon QStyle.StandardPixmap.SP_TrashIcon
+QStyle.SP_ComputerIcon QStyle.StandardPixmap.SP_ComputerIcon
+QStyle.SP_DriveFDIcon QStyle.StandardPixmap.SP_DriveFDIcon
+QStyle.SP_DriveHDIcon QStyle.StandardPixmap.SP_DriveHDIcon
+QStyle.SP_DriveCDIcon QStyle.StandardPixmap.SP_DriveCDIcon
+QStyle.SP_DriveDVDIcon QStyle.StandardPixmap.SP_DriveDVDIcon
+QStyle.SP_DriveNetIcon QStyle.StandardPixmap.SP_DriveNetIcon
+QStyle.SP_DirOpenIcon QStyle.StandardPixmap.SP_DirOpenIcon
+QStyle.SP_DirClosedIcon QStyle.StandardPixmap.SP_DirClosedIcon
+QStyle.SP_DirLinkIcon QStyle.StandardPixmap.SP_DirLinkIcon
+QStyle.SP_FileIcon QStyle.StandardPixmap.SP_FileIcon
+QStyle.SP_FileLinkIcon QStyle.StandardPixmap.SP_FileLinkIcon
+QStyle.SP_ToolBarHorizontalExtensionButton QStyle.StandardPixmap.SP_ToolBarHorizontalExtensionButton
+QStyle.SP_ToolBarVerticalExtensionButton QStyle.StandardPixmap.SP_ToolBarVerticalExtensionButton
+QStyle.SP_FileDialogStart QStyle.StandardPixmap.SP_FileDialogStart
+QStyle.SP_FileDialogEnd QStyle.StandardPixmap.SP_FileDialogEnd
+QStyle.SP_FileDialogToParent QStyle.StandardPixmap.SP_FileDialogToParent
+QStyle.SP_FileDialogNewFolder QStyle.StandardPixmap.SP_FileDialogNewFolder
+QStyle.SP_FileDialogDetailedView QStyle.StandardPixmap.SP_FileDialogDetailedView
+QStyle.SP_FileDialogInfoView QStyle.StandardPixmap.SP_FileDialogInfoView
+QStyle.SP_FileDialogContentsView QStyle.StandardPixmap.SP_FileDialogContentsView
+QStyle.SP_FileDialogListView QStyle.StandardPixmap.SP_FileDialogListView
+QStyle.SP_FileDialogBack QStyle.StandardPixmap.SP_FileDialogBack
+QStyle.SP_DirIcon QStyle.StandardPixmap.SP_DirIcon
+QStyle.SP_DialogOkButton QStyle.StandardPixmap.SP_DialogOkButton
+QStyle.SP_DialogCancelButton QStyle.StandardPixmap.SP_DialogCancelButton
+QStyle.SP_DialogHelpButton QStyle.StandardPixmap.SP_DialogHelpButton
+QStyle.SP_DialogOpenButton QStyle.StandardPixmap.SP_DialogOpenButton
+QStyle.SP_DialogSaveButton QStyle.StandardPixmap.SP_DialogSaveButton
+QStyle.SP_DialogCloseButton QStyle.StandardPixmap.SP_DialogCloseButton
+QStyle.SP_DialogApplyButton QStyle.StandardPixmap.SP_DialogApplyButton
+QStyle.SP_DialogResetButton QStyle.StandardPixmap.SP_DialogResetButton
+QStyle.SP_DialogDiscardButton QStyle.StandardPixmap.SP_DialogDiscardButton
+QStyle.SP_DialogYesButton QStyle.StandardPixmap.SP_DialogYesButton
+QStyle.SP_DialogNoButton QStyle.StandardPixmap.SP_DialogNoButton
+QStyle.SP_ArrowUp QStyle.StandardPixmap.SP_ArrowUp
+QStyle.SP_ArrowDown QStyle.StandardPixmap.SP_ArrowDown
+QStyle.SP_ArrowLeft QStyle.StandardPixmap.SP_ArrowLeft
+QStyle.SP_ArrowRight QStyle.StandardPixmap.SP_ArrowRight
+QStyle.SP_ArrowBack QStyle.StandardPixmap.SP_ArrowBack
+QStyle.SP_ArrowForward QStyle.StandardPixmap.SP_ArrowForward
+QStyle.SP_DirHomeIcon QStyle.StandardPixmap.SP_DirHomeIcon
+QStyle.SP_CommandLink QStyle.StandardPixmap.SP_CommandLink
+QStyle.SP_VistaShield QStyle.StandardPixmap.SP_VistaShield
+QStyle.SP_BrowserReload QStyle.StandardPixmap.SP_BrowserReload
+QStyle.SP_BrowserStop QStyle.StandardPixmap.SP_BrowserStop
+QStyle.SP_MediaPlay QStyle.StandardPixmap.SP_MediaPlay
+QStyle.SP_MediaStop QStyle.StandardPixmap.SP_MediaStop
+QStyle.SP_MediaPause QStyle.StandardPixmap.SP_MediaPause
+QStyle.SP_MediaSkipForward QStyle.StandardPixmap.SP_MediaSkipForward
+QStyle.SP_MediaSkipBackward QStyle.StandardPixmap.SP_MediaSkipBackward
+QStyle.SP_MediaSeekForward QStyle.StandardPixmap.SP_MediaSeekForward
+QStyle.SP_MediaSeekBackward QStyle.StandardPixmap.SP_MediaSeekBackward
+QStyle.SP_MediaVolume QStyle.StandardPixmap.SP_MediaVolume
+QStyle.SP_MediaVolumeMuted QStyle.StandardPixmap.SP_MediaVolumeMuted
+QStyle.SP_DirLinkOpenIcon QStyle.StandardPixmap.SP_DirLinkOpenIcon
+QStyle.SP_LineEditClearButton QStyle.StandardPixmap.SP_LineEditClearButton
+QStyle.SP_DialogYesToAllButton QStyle.StandardPixmap.SP_DialogYesToAllButton
+QStyle.SP_DialogNoToAllButton QStyle.StandardPixmap.SP_DialogNoToAllButton
+QStyle.SP_DialogSaveAllButton QStyle.StandardPixmap.SP_DialogSaveAllButton
+QStyle.SP_DialogAbortButton QStyle.StandardPixmap.SP_DialogAbortButton
+QStyle.SP_DialogRetryButton QStyle.StandardPixmap.SP_DialogRetryButton
+QStyle.SP_DialogIgnoreButton QStyle.StandardPixmap.SP_DialogIgnoreButton
+QStyle.SP_RestoreDefaultsButton QStyle.StandardPixmap.SP_RestoreDefaultsButton
+QStyle.SP_CustomBase QStyle.StandardPixmap.SP_CustomBase
+QStyle.SH_EtchDisabledText QStyle.StyleHint.SH_EtchDisabledText
+QStyle.SH_DitherDisabledText QStyle.StyleHint.SH_DitherDisabledText
+QStyle.SH_ScrollBar_MiddleClickAbsolutePosition QStyle.StyleHint.SH_ScrollBar_MiddleClickAbsolutePosition
+QStyle.SH_ScrollBar_ScrollWhenPointerLeavesControl QStyle.StyleHint.SH_ScrollBar_ScrollWhenPointerLeavesControl
+QStyle.SH_TabBar_SelectMouseType QStyle.StyleHint.SH_TabBar_SelectMouseType
+QStyle.SH_TabBar_Alignment QStyle.StyleHint.SH_TabBar_Alignment
+QStyle.SH_Header_ArrowAlignment QStyle.StyleHint.SH_Header_ArrowAlignment
+QStyle.SH_Slider_SnapToValue QStyle.StyleHint.SH_Slider_SnapToValue
+QStyle.SH_Slider_SloppyKeyEvents QStyle.StyleHint.SH_Slider_SloppyKeyEvents
+QStyle.SH_ProgressDialog_CenterCancelButton QStyle.StyleHint.SH_ProgressDialog_CenterCancelButton
+QStyle.SH_ProgressDialog_TextLabelAlignment QStyle.StyleHint.SH_ProgressDialog_TextLabelAlignment
+QStyle.SH_PrintDialog_RightAlignButtons QStyle.StyleHint.SH_PrintDialog_RightAlignButtons
+QStyle.SH_MainWindow_SpaceBelowMenuBar QStyle.StyleHint.SH_MainWindow_SpaceBelowMenuBar
+QStyle.SH_FontDialog_SelectAssociatedText QStyle.StyleHint.SH_FontDialog_SelectAssociatedText
+QStyle.SH_Menu_AllowActiveAndDisabled QStyle.StyleHint.SH_Menu_AllowActiveAndDisabled
+QStyle.SH_Menu_SpaceActivatesItem QStyle.StyleHint.SH_Menu_SpaceActivatesItem
+QStyle.SH_Menu_SubMenuPopupDelay QStyle.StyleHint.SH_Menu_SubMenuPopupDelay
+QStyle.SH_ScrollView_FrameOnlyAroundContents QStyle.StyleHint.SH_ScrollView_FrameOnlyAroundContents
+QStyle.SH_MenuBar_AltKeyNavigation QStyle.StyleHint.SH_MenuBar_AltKeyNavigation
+QStyle.SH_ComboBox_ListMouseTracking QStyle.StyleHint.SH_ComboBox_ListMouseTracking
+QStyle.SH_Menu_MouseTracking QStyle.StyleHint.SH_Menu_MouseTracking
+QStyle.SH_MenuBar_MouseTracking QStyle.StyleHint.SH_MenuBar_MouseTracking
+QStyle.SH_ItemView_ChangeHighlightOnFocus QStyle.StyleHint.SH_ItemView_ChangeHighlightOnFocus
+QStyle.SH_Widget_ShareActivation QStyle.StyleHint.SH_Widget_ShareActivation
+QStyle.SH_Workspace_FillSpaceOnMaximize QStyle.StyleHint.SH_Workspace_FillSpaceOnMaximize
+QStyle.SH_ComboBox_Popup QStyle.StyleHint.SH_ComboBox_Popup
+QStyle.SH_TitleBar_NoBorder QStyle.StyleHint.SH_TitleBar_NoBorder
+QStyle.SH_ScrollBar_StopMouseOverSlider QStyle.StyleHint.SH_ScrollBar_StopMouseOverSlider
+QStyle.SH_BlinkCursorWhenTextSelected QStyle.StyleHint.SH_BlinkCursorWhenTextSelected
+QStyle.SH_RichText_FullWidthSelection QStyle.StyleHint.SH_RichText_FullWidthSelection
+QStyle.SH_Menu_Scrollable QStyle.StyleHint.SH_Menu_Scrollable
+QStyle.SH_GroupBox_TextLabelVerticalAlignment QStyle.StyleHint.SH_GroupBox_TextLabelVerticalAlignment
+QStyle.SH_GroupBox_TextLabelColor QStyle.StyleHint.SH_GroupBox_TextLabelColor
+QStyle.SH_Menu_SloppySubMenus QStyle.StyleHint.SH_Menu_SloppySubMenus
+QStyle.SH_Table_GridLineColor QStyle.StyleHint.SH_Table_GridLineColor
+QStyle.SH_LineEdit_PasswordCharacter QStyle.StyleHint.SH_LineEdit_PasswordCharacter
+QStyle.SH_DialogButtons_DefaultButton QStyle.StyleHint.SH_DialogButtons_DefaultButton
+QStyle.SH_ToolBox_SelectedPageTitleBold QStyle.StyleHint.SH_ToolBox_SelectedPageTitleBold
+QStyle.SH_TabBar_PreferNoArrows QStyle.StyleHint.SH_TabBar_PreferNoArrows
+QStyle.SH_ScrollBar_LeftClickAbsolutePosition QStyle.StyleHint.SH_ScrollBar_LeftClickAbsolutePosition
+QStyle.SH_UnderlineShortcut QStyle.StyleHint.SH_UnderlineShortcut
+QStyle.SH_SpinBox_AnimateButton QStyle.StyleHint.SH_SpinBox_AnimateButton
+QStyle.SH_SpinBox_KeyPressAutoRepeatRate QStyle.StyleHint.SH_SpinBox_KeyPressAutoRepeatRate
+QStyle.SH_SpinBox_ClickAutoRepeatRate QStyle.StyleHint.SH_SpinBox_ClickAutoRepeatRate
+QStyle.SH_Menu_FillScreenWithScroll QStyle.StyleHint.SH_Menu_FillScreenWithScroll
+QStyle.SH_ToolTipLabel_Opacity QStyle.StyleHint.SH_ToolTipLabel_Opacity
+QStyle.SH_DrawMenuBarSeparator QStyle.StyleHint.SH_DrawMenuBarSeparator
+QStyle.SH_TitleBar_ModifyNotification QStyle.StyleHint.SH_TitleBar_ModifyNotification
+QStyle.SH_Button_FocusPolicy QStyle.StyleHint.SH_Button_FocusPolicy
+QStyle.SH_MessageBox_UseBorderForButtonSpacing QStyle.StyleHint.SH_MessageBox_UseBorderForButtonSpacing
+QStyle.SH_TitleBar_AutoRaise QStyle.StyleHint.SH_TitleBar_AutoRaise
+QStyle.SH_ToolButton_PopupDelay QStyle.StyleHint.SH_ToolButton_PopupDelay
+QStyle.SH_FocusFrame_Mask QStyle.StyleHint.SH_FocusFrame_Mask
+QStyle.SH_RubberBand_Mask QStyle.StyleHint.SH_RubberBand_Mask
+QStyle.SH_WindowFrame_Mask QStyle.StyleHint.SH_WindowFrame_Mask
+QStyle.SH_SpinControls_DisableOnBounds QStyle.StyleHint.SH_SpinControls_DisableOnBounds
+QStyle.SH_Dial_BackgroundRole QStyle.StyleHint.SH_Dial_BackgroundRole
+QStyle.SH_ComboBox_LayoutDirection QStyle.StyleHint.SH_ComboBox_LayoutDirection
+QStyle.SH_ItemView_EllipsisLocation QStyle.StyleHint.SH_ItemView_EllipsisLocation
+QStyle.SH_ItemView_ShowDecorationSelected QStyle.StyleHint.SH_ItemView_ShowDecorationSelected
+QStyle.SH_ItemView_ActivateItemOnSingleClick QStyle.StyleHint.SH_ItemView_ActivateItemOnSingleClick
+QStyle.SH_ScrollBar_ContextMenu QStyle.StyleHint.SH_ScrollBar_ContextMenu
+QStyle.SH_ScrollBar_RollBetweenButtons QStyle.StyleHint.SH_ScrollBar_RollBetweenButtons
+QStyle.SH_Slider_StopMouseOverSlider QStyle.StyleHint.SH_Slider_StopMouseOverSlider
+QStyle.SH_Slider_AbsoluteSetButtons QStyle.StyleHint.SH_Slider_AbsoluteSetButtons
+QStyle.SH_Slider_PageSetButtons QStyle.StyleHint.SH_Slider_PageSetButtons
+QStyle.SH_Menu_KeyboardSearch QStyle.StyleHint.SH_Menu_KeyboardSearch
+QStyle.SH_TabBar_ElideMode QStyle.StyleHint.SH_TabBar_ElideMode
+QStyle.SH_DialogButtonLayout QStyle.StyleHint.SH_DialogButtonLayout
+QStyle.SH_ComboBox_PopupFrameStyle QStyle.StyleHint.SH_ComboBox_PopupFrameStyle
+QStyle.SH_MessageBox_TextInteractionFlags QStyle.StyleHint.SH_MessageBox_TextInteractionFlags
+QStyle.SH_DialogButtonBox_ButtonsHaveIcons QStyle.StyleHint.SH_DialogButtonBox_ButtonsHaveIcons
+QStyle.SH_SpellCheckUnderlineStyle QStyle.StyleHint.SH_SpellCheckUnderlineStyle
+QStyle.SH_MessageBox_CenterButtons QStyle.StyleHint.SH_MessageBox_CenterButtons
+QStyle.SH_Menu_SelectionWrap QStyle.StyleHint.SH_Menu_SelectionWrap
+QStyle.SH_ItemView_MovementWithoutUpdatingSelection QStyle.StyleHint.SH_ItemView_MovementWithoutUpdatingSelection
+QStyle.SH_ToolTip_Mask QStyle.StyleHint.SH_ToolTip_Mask
+QStyle.SH_FocusFrame_AboveWidget QStyle.StyleHint.SH_FocusFrame_AboveWidget
+QStyle.SH_TextControl_FocusIndicatorTextCharFormat QStyle.StyleHint.SH_TextControl_FocusIndicatorTextCharFormat
+QStyle.SH_WizardStyle QStyle.StyleHint.SH_WizardStyle
+QStyle.SH_ItemView_ArrowKeysNavigateIntoChildren QStyle.StyleHint.SH_ItemView_ArrowKeysNavigateIntoChildren
+QStyle.SH_Menu_Mask QStyle.StyleHint.SH_Menu_Mask
+QStyle.SH_Menu_FlashTriggeredItem QStyle.StyleHint.SH_Menu_FlashTriggeredItem
+QStyle.SH_Menu_FadeOutOnHide QStyle.StyleHint.SH_Menu_FadeOutOnHide
+QStyle.SH_SpinBox_ClickAutoRepeatThreshold QStyle.StyleHint.SH_SpinBox_ClickAutoRepeatThreshold
+QStyle.SH_ItemView_PaintAlternatingRowColorsForEmptyArea QStyle.StyleHint.SH_ItemView_PaintAlternatingRowColorsForEmptyArea
+QStyle.SH_FormLayoutWrapPolicy QStyle.StyleHint.SH_FormLayoutWrapPolicy
+QStyle.SH_TabWidget_DefaultTabPosition QStyle.StyleHint.SH_TabWidget_DefaultTabPosition
+QStyle.SH_ToolBar_Movable QStyle.StyleHint.SH_ToolBar_Movable
+QStyle.SH_FormLayoutFieldGrowthPolicy QStyle.StyleHint.SH_FormLayoutFieldGrowthPolicy
+QStyle.SH_FormLayoutFormAlignment QStyle.StyleHint.SH_FormLayoutFormAlignment
+QStyle.SH_FormLayoutLabelAlignment QStyle.StyleHint.SH_FormLayoutLabelAlignment
+QStyle.SH_ItemView_DrawDelegateFrame QStyle.StyleHint.SH_ItemView_DrawDelegateFrame
+QStyle.SH_TabBar_CloseButtonPosition QStyle.StyleHint.SH_TabBar_CloseButtonPosition
+QStyle.SH_DockWidget_ButtonsHaveFrame QStyle.StyleHint.SH_DockWidget_ButtonsHaveFrame
+QStyle.SH_ToolButtonStyle QStyle.StyleHint.SH_ToolButtonStyle
+QStyle.SH_RequestSoftwareInputPanel QStyle.StyleHint.SH_RequestSoftwareInputPanel
+QStyle.SH_ListViewExpand_SelectMouseType QStyle.StyleHint.SH_ListViewExpand_SelectMouseType
+QStyle.SH_ScrollBar_Transient QStyle.StyleHint.SH_ScrollBar_Transient
+QStyle.SH_Menu_SupportsSections QStyle.StyleHint.SH_Menu_SupportsSections
+QStyle.SH_ToolTip_WakeUpDelay QStyle.StyleHint.SH_ToolTip_WakeUpDelay
+QStyle.SH_ToolTip_FallAsleepDelay QStyle.StyleHint.SH_ToolTip_FallAsleepDelay
+QStyle.SH_Widget_Animate QStyle.StyleHint.SH_Widget_Animate
+QStyle.SH_Splitter_OpaqueResize QStyle.StyleHint.SH_Splitter_OpaqueResize
+QStyle.SH_LineEdit_PasswordMaskDelay QStyle.StyleHint.SH_LineEdit_PasswordMaskDelay
+QStyle.SH_TabBar_ChangeCurrentDelay QStyle.StyleHint.SH_TabBar_ChangeCurrentDelay
+QStyle.SH_Menu_SubMenuUniDirection QStyle.StyleHint.SH_Menu_SubMenuUniDirection
+QStyle.SH_Menu_SubMenuUniDirectionFailCount QStyle.StyleHint.SH_Menu_SubMenuUniDirectionFailCount
+QStyle.SH_Menu_SubMenuSloppySelectOtherActions QStyle.StyleHint.SH_Menu_SubMenuSloppySelectOtherActions
+QStyle.SH_Menu_SubMenuSloppyCloseTimeout QStyle.StyleHint.SH_Menu_SubMenuSloppyCloseTimeout
+QStyle.SH_Menu_SubMenuResetWhenReenteringParent QStyle.StyleHint.SH_Menu_SubMenuResetWhenReenteringParent
+QStyle.SH_Menu_SubMenuDontStartSloppyOnLeave QStyle.StyleHint.SH_Menu_SubMenuDontStartSloppyOnLeave
+QStyle.SH_ItemView_ScrollMode QStyle.StyleHint.SH_ItemView_ScrollMode
+QStyle.SH_TitleBar_ShowToolTipsOnButtons QStyle.StyleHint.SH_TitleBar_ShowToolTipsOnButtons
+QStyle.SH_Widget_Animation_Duration QStyle.StyleHint.SH_Widget_Animation_Duration
+QStyle.SH_ComboBox_AllowWheelScrolling QStyle.StyleHint.SH_ComboBox_AllowWheelScrolling
+QStyle.SH_SpinBox_ButtonsInsideFrame QStyle.StyleHint.SH_SpinBox_ButtonsInsideFrame
+QStyle.SH_SpinBox_StepModifier QStyle.StyleHint.SH_SpinBox_StepModifier
+QStyle.SH_CustomBase QStyle.StyleHint.SH_CustomBase
+QStyle.CT_PushButton QStyle.ContentsType.CT_PushButton
+QStyle.CT_CheckBox QStyle.ContentsType.CT_CheckBox
+QStyle.CT_RadioButton QStyle.ContentsType.CT_RadioButton
+QStyle.CT_ToolButton QStyle.ContentsType.CT_ToolButton
+QStyle.CT_ComboBox QStyle.ContentsType.CT_ComboBox
+QStyle.CT_Splitter QStyle.ContentsType.CT_Splitter
+QStyle.CT_ProgressBar QStyle.ContentsType.CT_ProgressBar
+QStyle.CT_MenuItem QStyle.ContentsType.CT_MenuItem
+QStyle.CT_MenuBarItem QStyle.ContentsType.CT_MenuBarItem
+QStyle.CT_MenuBar QStyle.ContentsType.CT_MenuBar
+QStyle.CT_Menu QStyle.ContentsType.CT_Menu
+QStyle.CT_TabBarTab QStyle.ContentsType.CT_TabBarTab
+QStyle.CT_Slider QStyle.ContentsType.CT_Slider
+QStyle.CT_ScrollBar QStyle.ContentsType.CT_ScrollBar
+QStyle.CT_LineEdit QStyle.ContentsType.CT_LineEdit
+QStyle.CT_SpinBox QStyle.ContentsType.CT_SpinBox
+QStyle.CT_SizeGrip QStyle.ContentsType.CT_SizeGrip
+QStyle.CT_TabWidget QStyle.ContentsType.CT_TabWidget
+QStyle.CT_DialogButtons QStyle.ContentsType.CT_DialogButtons
+QStyle.CT_HeaderSection QStyle.ContentsType.CT_HeaderSection
+QStyle.CT_GroupBox QStyle.ContentsType.CT_GroupBox
+QStyle.CT_MdiControls QStyle.ContentsType.CT_MdiControls
+QStyle.CT_ItemViewItem QStyle.ContentsType.CT_ItemViewItem
+QStyle.CT_CustomBase QStyle.ContentsType.CT_CustomBase
+QStyle.PM_ButtonMargin QStyle.PixelMetric.PM_ButtonMargin
+QStyle.PM_ButtonDefaultIndicator QStyle.PixelMetric.PM_ButtonDefaultIndicator
+QStyle.PM_MenuButtonIndicator QStyle.PixelMetric.PM_MenuButtonIndicator
+QStyle.PM_ButtonShiftHorizontal QStyle.PixelMetric.PM_ButtonShiftHorizontal
+QStyle.PM_ButtonShiftVertical QStyle.PixelMetric.PM_ButtonShiftVertical
+QStyle.PM_DefaultFrameWidth QStyle.PixelMetric.PM_DefaultFrameWidth
+QStyle.PM_SpinBoxFrameWidth QStyle.PixelMetric.PM_SpinBoxFrameWidth
+QStyle.PM_ComboBoxFrameWidth QStyle.PixelMetric.PM_ComboBoxFrameWidth
+QStyle.PM_MaximumDragDistance QStyle.PixelMetric.PM_MaximumDragDistance
+QStyle.PM_ScrollBarExtent QStyle.PixelMetric.PM_ScrollBarExtent
+QStyle.PM_ScrollBarSliderMin QStyle.PixelMetric.PM_ScrollBarSliderMin
+QStyle.PM_SliderThickness QStyle.PixelMetric.PM_SliderThickness
+QStyle.PM_SliderControlThickness QStyle.PixelMetric.PM_SliderControlThickness
+QStyle.PM_SliderLength QStyle.PixelMetric.PM_SliderLength
+QStyle.PM_SliderTickmarkOffset QStyle.PixelMetric.PM_SliderTickmarkOffset
+QStyle.PM_SliderSpaceAvailable QStyle.PixelMetric.PM_SliderSpaceAvailable
+QStyle.PM_DockWidgetSeparatorExtent QStyle.PixelMetric.PM_DockWidgetSeparatorExtent
+QStyle.PM_DockWidgetHandleExtent QStyle.PixelMetric.PM_DockWidgetHandleExtent
+QStyle.PM_DockWidgetFrameWidth QStyle.PixelMetric.PM_DockWidgetFrameWidth
+QStyle.PM_TabBarTabOverlap QStyle.PixelMetric.PM_TabBarTabOverlap
+QStyle.PM_TabBarTabHSpace QStyle.PixelMetric.PM_TabBarTabHSpace
+QStyle.PM_TabBarTabVSpace QStyle.PixelMetric.PM_TabBarTabVSpace
+QStyle.PM_TabBarBaseHeight QStyle.PixelMetric.PM_TabBarBaseHeight
+QStyle.PM_TabBarBaseOverlap QStyle.PixelMetric.PM_TabBarBaseOverlap
+QStyle.PM_ProgressBarChunkWidth QStyle.PixelMetric.PM_ProgressBarChunkWidth
+QStyle.PM_SplitterWidth QStyle.PixelMetric.PM_SplitterWidth
+QStyle.PM_TitleBarHeight QStyle.PixelMetric.PM_TitleBarHeight
+QStyle.PM_MenuScrollerHeight QStyle.PixelMetric.PM_MenuScrollerHeight
+QStyle.PM_MenuHMargin QStyle.PixelMetric.PM_MenuHMargin
+QStyle.PM_MenuVMargin QStyle.PixelMetric.PM_MenuVMargin
+QStyle.PM_MenuPanelWidth QStyle.PixelMetric.PM_MenuPanelWidth
+QStyle.PM_MenuTearoffHeight QStyle.PixelMetric.PM_MenuTearoffHeight
+QStyle.PM_MenuDesktopFrameWidth QStyle.PixelMetric.PM_MenuDesktopFrameWidth
+QStyle.PM_MenuBarPanelWidth QStyle.PixelMetric.PM_MenuBarPanelWidth
+QStyle.PM_MenuBarItemSpacing QStyle.PixelMetric.PM_MenuBarItemSpacing
+QStyle.PM_MenuBarVMargin QStyle.PixelMetric.PM_MenuBarVMargin
+QStyle.PM_MenuBarHMargin QStyle.PixelMetric.PM_MenuBarHMargin
+QStyle.PM_IndicatorWidth QStyle.PixelMetric.PM_IndicatorWidth
+QStyle.PM_IndicatorHeight QStyle.PixelMetric.PM_IndicatorHeight
+QStyle.PM_ExclusiveIndicatorWidth QStyle.PixelMetric.PM_ExclusiveIndicatorWidth
+QStyle.PM_ExclusiveIndicatorHeight QStyle.PixelMetric.PM_ExclusiveIndicatorHeight
+QStyle.PM_DialogButtonsSeparator QStyle.PixelMetric.PM_DialogButtonsSeparator
+QStyle.PM_DialogButtonsButtonWidth QStyle.PixelMetric.PM_DialogButtonsButtonWidth
+QStyle.PM_DialogButtonsButtonHeight QStyle.PixelMetric.PM_DialogButtonsButtonHeight
+QStyle.PM_MdiSubWindowFrameWidth QStyle.PixelMetric.PM_MdiSubWindowFrameWidth
+QStyle.PM_MDIFrameWidth QStyle.PixelMetric.PM_MDIFrameWidth
+QStyle.PM_MdiSubWindowMinimizedWidth QStyle.PixelMetric.PM_MdiSubWindowMinimizedWidth
+QStyle.PM_MDIMinimizedWidth QStyle.PixelMetric.PM_MDIMinimizedWidth
+QStyle.PM_HeaderMargin QStyle.PixelMetric.PM_HeaderMargin
+QStyle.PM_HeaderMarkSize QStyle.PixelMetric.PM_HeaderMarkSize
+QStyle.PM_HeaderGripMargin QStyle.PixelMetric.PM_HeaderGripMargin
+QStyle.PM_TabBarTabShiftHorizontal QStyle.PixelMetric.PM_TabBarTabShiftHorizontal
+QStyle.PM_TabBarTabShiftVertical QStyle.PixelMetric.PM_TabBarTabShiftVertical
+QStyle.PM_TabBarScrollButtonWidth QStyle.PixelMetric.PM_TabBarScrollButtonWidth
+QStyle.PM_ToolBarFrameWidth QStyle.PixelMetric.PM_ToolBarFrameWidth
+QStyle.PM_ToolBarHandleExtent QStyle.PixelMetric.PM_ToolBarHandleExtent
+QStyle.PM_ToolBarItemSpacing QStyle.PixelMetric.PM_ToolBarItemSpacing
+QStyle.PM_ToolBarItemMargin QStyle.PixelMetric.PM_ToolBarItemMargin
+QStyle.PM_ToolBarSeparatorExtent QStyle.PixelMetric.PM_ToolBarSeparatorExtent
+QStyle.PM_ToolBarExtensionExtent QStyle.PixelMetric.PM_ToolBarExtensionExtent
+QStyle.PM_SpinBoxSliderHeight QStyle.PixelMetric.PM_SpinBoxSliderHeight
+QStyle.PM_DefaultTopLevelMargin QStyle.PixelMetric.PM_DefaultTopLevelMargin
+QStyle.PM_DefaultChildMargin QStyle.PixelMetric.PM_DefaultChildMargin
+QStyle.PM_DefaultLayoutSpacing QStyle.PixelMetric.PM_DefaultLayoutSpacing
+QStyle.PM_ToolBarIconSize QStyle.PixelMetric.PM_ToolBarIconSize
+QStyle.PM_ListViewIconSize QStyle.PixelMetric.PM_ListViewIconSize
+QStyle.PM_IconViewIconSize QStyle.PixelMetric.PM_IconViewIconSize
+QStyle.PM_SmallIconSize QStyle.PixelMetric.PM_SmallIconSize
+QStyle.PM_LargeIconSize QStyle.PixelMetric.PM_LargeIconSize
+QStyle.PM_FocusFrameVMargin QStyle.PixelMetric.PM_FocusFrameVMargin
+QStyle.PM_FocusFrameHMargin QStyle.PixelMetric.PM_FocusFrameHMargin
+QStyle.PM_ToolTipLabelFrameWidth QStyle.PixelMetric.PM_ToolTipLabelFrameWidth
+QStyle.PM_CheckBoxLabelSpacing QStyle.PixelMetric.PM_CheckBoxLabelSpacing
+QStyle.PM_TabBarIconSize QStyle.PixelMetric.PM_TabBarIconSize
+QStyle.PM_SizeGripSize QStyle.PixelMetric.PM_SizeGripSize
+QStyle.PM_DockWidgetTitleMargin QStyle.PixelMetric.PM_DockWidgetTitleMargin
+QStyle.PM_MessageBoxIconSize QStyle.PixelMetric.PM_MessageBoxIconSize
+QStyle.PM_ButtonIconSize QStyle.PixelMetric.PM_ButtonIconSize
+QStyle.PM_DockWidgetTitleBarButtonMargin QStyle.PixelMetric.PM_DockWidgetTitleBarButtonMargin
+QStyle.PM_RadioButtonLabelSpacing QStyle.PixelMetric.PM_RadioButtonLabelSpacing
+QStyle.PM_LayoutLeftMargin QStyle.PixelMetric.PM_LayoutLeftMargin
+QStyle.PM_LayoutTopMargin QStyle.PixelMetric.PM_LayoutTopMargin
+QStyle.PM_LayoutRightMargin QStyle.PixelMetric.PM_LayoutRightMargin
+QStyle.PM_LayoutBottomMargin QStyle.PixelMetric.PM_LayoutBottomMargin
+QStyle.PM_LayoutHorizontalSpacing QStyle.PixelMetric.PM_LayoutHorizontalSpacing
+QStyle.PM_LayoutVerticalSpacing QStyle.PixelMetric.PM_LayoutVerticalSpacing
+QStyle.PM_TabBar_ScrollButtonOverlap QStyle.PixelMetric.PM_TabBar_ScrollButtonOverlap
+QStyle.PM_TextCursorWidth QStyle.PixelMetric.PM_TextCursorWidth
+QStyle.PM_TabCloseIndicatorWidth QStyle.PixelMetric.PM_TabCloseIndicatorWidth
+QStyle.PM_TabCloseIndicatorHeight QStyle.PixelMetric.PM_TabCloseIndicatorHeight
+QStyle.PM_ScrollView_ScrollBarSpacing QStyle.PixelMetric.PM_ScrollView_ScrollBarSpacing
+QStyle.PM_SubMenuOverlap QStyle.PixelMetric.PM_SubMenuOverlap
+QStyle.PM_ScrollView_ScrollBarOverlap QStyle.PixelMetric.PM_ScrollView_ScrollBarOverlap
+QStyle.PM_TreeViewIndentation QStyle.PixelMetric.PM_TreeViewIndentation
+QStyle.PM_HeaderDefaultSectionSizeHorizontal QStyle.PixelMetric.PM_HeaderDefaultSectionSizeHorizontal
+QStyle.PM_HeaderDefaultSectionSizeVertical QStyle.PixelMetric.PM_HeaderDefaultSectionSizeVertical
+QStyle.PM_TitleBarButtonIconSize QStyle.PixelMetric.PM_TitleBarButtonIconSize
+QStyle.PM_TitleBarButtonSize QStyle.PixelMetric.PM_TitleBarButtonSize
+QStyle.PM_CustomBase QStyle.PixelMetric.PM_CustomBase
+QStyle.SC_None QStyle.SubControl.SC_None
+QStyle.SC_ScrollBarAddLine QStyle.SubControl.SC_ScrollBarAddLine
+QStyle.SC_ScrollBarSubLine QStyle.SubControl.SC_ScrollBarSubLine
+QStyle.SC_ScrollBarAddPage QStyle.SubControl.SC_ScrollBarAddPage
+QStyle.SC_ScrollBarSubPage QStyle.SubControl.SC_ScrollBarSubPage
+QStyle.SC_ScrollBarFirst QStyle.SubControl.SC_ScrollBarFirst
+QStyle.SC_ScrollBarLast QStyle.SubControl.SC_ScrollBarLast
+QStyle.SC_ScrollBarSlider QStyle.SubControl.SC_ScrollBarSlider
+QStyle.SC_ScrollBarGroove QStyle.SubControl.SC_ScrollBarGroove
+QStyle.SC_SpinBoxUp QStyle.SubControl.SC_SpinBoxUp
+QStyle.SC_SpinBoxDown QStyle.SubControl.SC_SpinBoxDown
+QStyle.SC_SpinBoxFrame QStyle.SubControl.SC_SpinBoxFrame
+QStyle.SC_SpinBoxEditField QStyle.SubControl.SC_SpinBoxEditField
+QStyle.SC_ComboBoxFrame QStyle.SubControl.SC_ComboBoxFrame
+QStyle.SC_ComboBoxEditField QStyle.SubControl.SC_ComboBoxEditField
+QStyle.SC_ComboBoxArrow QStyle.SubControl.SC_ComboBoxArrow
+QStyle.SC_ComboBoxListBoxPopup QStyle.SubControl.SC_ComboBoxListBoxPopup
+QStyle.SC_SliderGroove QStyle.SubControl.SC_SliderGroove
+QStyle.SC_SliderHandle QStyle.SubControl.SC_SliderHandle
+QStyle.SC_SliderTickmarks QStyle.SubControl.SC_SliderTickmarks
+QStyle.SC_ToolButton QStyle.SubControl.SC_ToolButton
+QStyle.SC_ToolButtonMenu QStyle.SubControl.SC_ToolButtonMenu
+QStyle.SC_TitleBarSysMenu QStyle.SubControl.SC_TitleBarSysMenu
+QStyle.SC_TitleBarMinButton QStyle.SubControl.SC_TitleBarMinButton
+QStyle.SC_TitleBarMaxButton QStyle.SubControl.SC_TitleBarMaxButton
+QStyle.SC_TitleBarCloseButton QStyle.SubControl.SC_TitleBarCloseButton
+QStyle.SC_TitleBarNormalButton QStyle.SubControl.SC_TitleBarNormalButton
+QStyle.SC_TitleBarShadeButton QStyle.SubControl.SC_TitleBarShadeButton
+QStyle.SC_TitleBarUnshadeButton QStyle.SubControl.SC_TitleBarUnshadeButton
+QStyle.SC_TitleBarContextHelpButton QStyle.SubControl.SC_TitleBarContextHelpButton
+QStyle.SC_TitleBarLabel QStyle.SubControl.SC_TitleBarLabel
+QStyle.SC_DialGroove QStyle.SubControl.SC_DialGroove
+QStyle.SC_DialHandle QStyle.SubControl.SC_DialHandle
+QStyle.SC_DialTickmarks QStyle.SubControl.SC_DialTickmarks
+QStyle.SC_GroupBoxCheckBox QStyle.SubControl.SC_GroupBoxCheckBox
+QStyle.SC_GroupBoxLabel QStyle.SubControl.SC_GroupBoxLabel
+QStyle.SC_GroupBoxContents QStyle.SubControl.SC_GroupBoxContents
+QStyle.SC_GroupBoxFrame QStyle.SubControl.SC_GroupBoxFrame
+QStyle.SC_MdiMinButton QStyle.SubControl.SC_MdiMinButton
+QStyle.SC_MdiNormalButton QStyle.SubControl.SC_MdiNormalButton
+QStyle.SC_MdiCloseButton QStyle.SubControl.SC_MdiCloseButton
+QStyle.SC_CustomBase QStyle.SubControl.SC_CustomBase
+QStyle.SC_All QStyle.SubControl.SC_All
+QStyle.CC_SpinBox QStyle.ComplexControl.CC_SpinBox
+QStyle.CC_ComboBox QStyle.ComplexControl.CC_ComboBox
+QStyle.CC_ScrollBar QStyle.ComplexControl.CC_ScrollBar
+QStyle.CC_Slider QStyle.ComplexControl.CC_Slider
+QStyle.CC_ToolButton QStyle.ComplexControl.CC_ToolButton
+QStyle.CC_TitleBar QStyle.ComplexControl.CC_TitleBar
+QStyle.CC_Dial QStyle.ComplexControl.CC_Dial
+QStyle.CC_GroupBox QStyle.ComplexControl.CC_GroupBox
+QStyle.CC_MdiControls QStyle.ComplexControl.CC_MdiControls
+QStyle.CC_CustomBase QStyle.ComplexControl.CC_CustomBase
+QStyle.SE_PushButtonContents QStyle.SubElement.SE_PushButtonContents
+QStyle.SE_PushButtonFocusRect QStyle.SubElement.SE_PushButtonFocusRect
+QStyle.SE_CheckBoxIndicator QStyle.SubElement.SE_CheckBoxIndicator
+QStyle.SE_CheckBoxContents QStyle.SubElement.SE_CheckBoxContents
+QStyle.SE_CheckBoxFocusRect QStyle.SubElement.SE_CheckBoxFocusRect
+QStyle.SE_CheckBoxClickRect QStyle.SubElement.SE_CheckBoxClickRect
+QStyle.SE_RadioButtonIndicator QStyle.SubElement.SE_RadioButtonIndicator
+QStyle.SE_RadioButtonContents QStyle.SubElement.SE_RadioButtonContents
+QStyle.SE_RadioButtonFocusRect QStyle.SubElement.SE_RadioButtonFocusRect
+QStyle.SE_RadioButtonClickRect QStyle.SubElement.SE_RadioButtonClickRect
+QStyle.SE_ComboBoxFocusRect QStyle.SubElement.SE_ComboBoxFocusRect
+QStyle.SE_SliderFocusRect QStyle.SubElement.SE_SliderFocusRect
+QStyle.SE_ProgressBarGroove QStyle.SubElement.SE_ProgressBarGroove
+QStyle.SE_ProgressBarContents QStyle.SubElement.SE_ProgressBarContents
+QStyle.SE_ProgressBarLabel QStyle.SubElement.SE_ProgressBarLabel
+QStyle.SE_ToolBoxTabContents QStyle.SubElement.SE_ToolBoxTabContents
+QStyle.SE_HeaderLabel QStyle.SubElement.SE_HeaderLabel
+QStyle.SE_HeaderArrow QStyle.SubElement.SE_HeaderArrow
+QStyle.SE_TabWidgetTabBar QStyle.SubElement.SE_TabWidgetTabBar
+QStyle.SE_TabWidgetTabPane QStyle.SubElement.SE_TabWidgetTabPane
+QStyle.SE_TabWidgetTabContents QStyle.SubElement.SE_TabWidgetTabContents
+QStyle.SE_TabWidgetLeftCorner QStyle.SubElement.SE_TabWidgetLeftCorner
+QStyle.SE_TabWidgetRightCorner QStyle.SubElement.SE_TabWidgetRightCorner
+QStyle.SE_ViewItemCheckIndicator QStyle.SubElement.SE_ViewItemCheckIndicator
+QStyle.SE_TabBarTearIndicator QStyle.SubElement.SE_TabBarTearIndicator
+QStyle.SE_TreeViewDisclosureItem QStyle.SubElement.SE_TreeViewDisclosureItem
+QStyle.SE_LineEditContents QStyle.SubElement.SE_LineEditContents
+QStyle.SE_FrameContents QStyle.SubElement.SE_FrameContents
+QStyle.SE_DockWidgetCloseButton QStyle.SubElement.SE_DockWidgetCloseButton
+QStyle.SE_DockWidgetFloatButton QStyle.SubElement.SE_DockWidgetFloatButton
+QStyle.SE_DockWidgetTitleBarText QStyle.SubElement.SE_DockWidgetTitleBarText
+QStyle.SE_DockWidgetIcon QStyle.SubElement.SE_DockWidgetIcon
+QStyle.SE_CheckBoxLayoutItem QStyle.SubElement.SE_CheckBoxLayoutItem
+QStyle.SE_ComboBoxLayoutItem QStyle.SubElement.SE_ComboBoxLayoutItem
+QStyle.SE_DateTimeEditLayoutItem QStyle.SubElement.SE_DateTimeEditLayoutItem
+QStyle.SE_DialogButtonBoxLayoutItem QStyle.SubElement.SE_DialogButtonBoxLayoutItem
+QStyle.SE_LabelLayoutItem QStyle.SubElement.SE_LabelLayoutItem
+QStyle.SE_ProgressBarLayoutItem QStyle.SubElement.SE_ProgressBarLayoutItem
+QStyle.SE_PushButtonLayoutItem QStyle.SubElement.SE_PushButtonLayoutItem
+QStyle.SE_RadioButtonLayoutItem QStyle.SubElement.SE_RadioButtonLayoutItem
+QStyle.SE_SliderLayoutItem QStyle.SubElement.SE_SliderLayoutItem
+QStyle.SE_SpinBoxLayoutItem QStyle.SubElement.SE_SpinBoxLayoutItem
+QStyle.SE_ToolButtonLayoutItem QStyle.SubElement.SE_ToolButtonLayoutItem
+QStyle.SE_FrameLayoutItem QStyle.SubElement.SE_FrameLayoutItem
+QStyle.SE_GroupBoxLayoutItem QStyle.SubElement.SE_GroupBoxLayoutItem
+QStyle.SE_TabWidgetLayoutItem QStyle.SubElement.SE_TabWidgetLayoutItem
+QStyle.SE_ItemViewItemCheckIndicator QStyle.SubElement.SE_ItemViewItemCheckIndicator
+QStyle.SE_ItemViewItemDecoration QStyle.SubElement.SE_ItemViewItemDecoration
+QStyle.SE_ItemViewItemText QStyle.SubElement.SE_ItemViewItemText
+QStyle.SE_ItemViewItemFocusRect QStyle.SubElement.SE_ItemViewItemFocusRect
+QStyle.SE_TabBarTabLeftButton QStyle.SubElement.SE_TabBarTabLeftButton
+QStyle.SE_TabBarTabRightButton QStyle.SubElement.SE_TabBarTabRightButton
+QStyle.SE_TabBarTabText QStyle.SubElement.SE_TabBarTabText
+QStyle.SE_ShapedFrameContents QStyle.SubElement.SE_ShapedFrameContents
+QStyle.SE_ToolBarHandle QStyle.SubElement.SE_ToolBarHandle
+QStyle.SE_TabBarTearIndicatorLeft QStyle.SubElement.SE_TabBarTearIndicatorLeft
+QStyle.SE_TabBarScrollLeftButton QStyle.SubElement.SE_TabBarScrollLeftButton
+QStyle.SE_TabBarScrollRightButton QStyle.SubElement.SE_TabBarScrollRightButton
+QStyle.SE_TabBarTearIndicatorRight QStyle.SubElement.SE_TabBarTearIndicatorRight
+QStyle.SE_PushButtonBevel QStyle.SubElement.SE_PushButtonBevel
+QStyle.SE_CustomBase QStyle.SubElement.SE_CustomBase
+QStyle.CE_PushButton QStyle.ControlElement.CE_PushButton
+QStyle.CE_PushButtonBevel QStyle.ControlElement.CE_PushButtonBevel
+QStyle.CE_PushButtonLabel QStyle.ControlElement.CE_PushButtonLabel
+QStyle.CE_CheckBox QStyle.ControlElement.CE_CheckBox
+QStyle.CE_CheckBoxLabel QStyle.ControlElement.CE_CheckBoxLabel
+QStyle.CE_RadioButton QStyle.ControlElement.CE_RadioButton
+QStyle.CE_RadioButtonLabel QStyle.ControlElement.CE_RadioButtonLabel
+QStyle.CE_TabBarTab QStyle.ControlElement.CE_TabBarTab
+QStyle.CE_TabBarTabShape QStyle.ControlElement.CE_TabBarTabShape
+QStyle.CE_TabBarTabLabel QStyle.ControlElement.CE_TabBarTabLabel
+QStyle.CE_ProgressBar QStyle.ControlElement.CE_ProgressBar
+QStyle.CE_ProgressBarGroove QStyle.ControlElement.CE_ProgressBarGroove
+QStyle.CE_ProgressBarContents QStyle.ControlElement.CE_ProgressBarContents
+QStyle.CE_ProgressBarLabel QStyle.ControlElement.CE_ProgressBarLabel
+QStyle.CE_MenuItem QStyle.ControlElement.CE_MenuItem
+QStyle.CE_MenuScroller QStyle.ControlElement.CE_MenuScroller
+QStyle.CE_MenuVMargin QStyle.ControlElement.CE_MenuVMargin
+QStyle.CE_MenuHMargin QStyle.ControlElement.CE_MenuHMargin
+QStyle.CE_MenuTearoff QStyle.ControlElement.CE_MenuTearoff
+QStyle.CE_MenuEmptyArea QStyle.ControlElement.CE_MenuEmptyArea
+QStyle.CE_MenuBarItem QStyle.ControlElement.CE_MenuBarItem
+QStyle.CE_MenuBarEmptyArea QStyle.ControlElement.CE_MenuBarEmptyArea
+QStyle.CE_ToolButtonLabel QStyle.ControlElement.CE_ToolButtonLabel
+QStyle.CE_Header QStyle.ControlElement.CE_Header
+QStyle.CE_HeaderSection QStyle.ControlElement.CE_HeaderSection
+QStyle.CE_HeaderLabel QStyle.ControlElement.CE_HeaderLabel
+QStyle.CE_ToolBoxTab QStyle.ControlElement.CE_ToolBoxTab
+QStyle.CE_SizeGrip QStyle.ControlElement.CE_SizeGrip
+QStyle.CE_Splitter QStyle.ControlElement.CE_Splitter
+QStyle.CE_RubberBand QStyle.ControlElement.CE_RubberBand
+QStyle.CE_DockWidgetTitle QStyle.ControlElement.CE_DockWidgetTitle
+QStyle.CE_ScrollBarAddLine QStyle.ControlElement.CE_ScrollBarAddLine
+QStyle.CE_ScrollBarSubLine QStyle.ControlElement.CE_ScrollBarSubLine
+QStyle.CE_ScrollBarAddPage QStyle.ControlElement.CE_ScrollBarAddPage
+QStyle.CE_ScrollBarSubPage QStyle.ControlElement.CE_ScrollBarSubPage
+QStyle.CE_ScrollBarSlider QStyle.ControlElement.CE_ScrollBarSlider
+QStyle.CE_ScrollBarFirst QStyle.ControlElement.CE_ScrollBarFirst
+QStyle.CE_ScrollBarLast QStyle.ControlElement.CE_ScrollBarLast
+QStyle.CE_FocusFrame QStyle.ControlElement.CE_FocusFrame
+QStyle.CE_ComboBoxLabel QStyle.ControlElement.CE_ComboBoxLabel
+QStyle.CE_ToolBar QStyle.ControlElement.CE_ToolBar
+QStyle.CE_ToolBoxTabShape QStyle.ControlElement.CE_ToolBoxTabShape
+QStyle.CE_ToolBoxTabLabel QStyle.ControlElement.CE_ToolBoxTabLabel
+QStyle.CE_HeaderEmptyArea QStyle.ControlElement.CE_HeaderEmptyArea
+QStyle.CE_ColumnViewGrip QStyle.ControlElement.CE_ColumnViewGrip
+QStyle.CE_ItemViewItem QStyle.ControlElement.CE_ItemViewItem
+QStyle.CE_ShapedFrame QStyle.ControlElement.CE_ShapedFrame
+QStyle.CE_CustomBase QStyle.ControlElement.CE_CustomBase
+QStyle.PE_Frame QStyle.PrimitiveElement.PE_Frame
+QStyle.PE_FrameDefaultButton QStyle.PrimitiveElement.PE_FrameDefaultButton
+QStyle.PE_FrameDockWidget QStyle.PrimitiveElement.PE_FrameDockWidget
+QStyle.PE_FrameFocusRect QStyle.PrimitiveElement.PE_FrameFocusRect
+QStyle.PE_FrameGroupBox QStyle.PrimitiveElement.PE_FrameGroupBox
+QStyle.PE_FrameLineEdit QStyle.PrimitiveElement.PE_FrameLineEdit
+QStyle.PE_FrameMenu QStyle.PrimitiveElement.PE_FrameMenu
+QStyle.PE_FrameStatusBar QStyle.PrimitiveElement.PE_FrameStatusBar
+QStyle.PE_FrameTabWidget QStyle.PrimitiveElement.PE_FrameTabWidget
+QStyle.PE_FrameWindow QStyle.PrimitiveElement.PE_FrameWindow
+QStyle.PE_FrameButtonBevel QStyle.PrimitiveElement.PE_FrameButtonBevel
+QStyle.PE_FrameButtonTool QStyle.PrimitiveElement.PE_FrameButtonTool
+QStyle.PE_FrameTabBarBase QStyle.PrimitiveElement.PE_FrameTabBarBase
+QStyle.PE_PanelButtonCommand QStyle.PrimitiveElement.PE_PanelButtonCommand
+QStyle.PE_PanelButtonBevel QStyle.PrimitiveElement.PE_PanelButtonBevel
+QStyle.PE_PanelButtonTool QStyle.PrimitiveElement.PE_PanelButtonTool
+QStyle.PE_PanelMenuBar QStyle.PrimitiveElement.PE_PanelMenuBar
+QStyle.PE_PanelToolBar QStyle.PrimitiveElement.PE_PanelToolBar
+QStyle.PE_PanelLineEdit QStyle.PrimitiveElement.PE_PanelLineEdit
+QStyle.PE_IndicatorArrowDown QStyle.PrimitiveElement.PE_IndicatorArrowDown
+QStyle.PE_IndicatorArrowLeft QStyle.PrimitiveElement.PE_IndicatorArrowLeft
+QStyle.PE_IndicatorArrowRight QStyle.PrimitiveElement.PE_IndicatorArrowRight
+QStyle.PE_IndicatorArrowUp QStyle.PrimitiveElement.PE_IndicatorArrowUp
+QStyle.PE_IndicatorBranch QStyle.PrimitiveElement.PE_IndicatorBranch
+QStyle.PE_IndicatorButtonDropDown QStyle.PrimitiveElement.PE_IndicatorButtonDropDown
+QStyle.PE_IndicatorViewItemCheck QStyle.PrimitiveElement.PE_IndicatorViewItemCheck
+QStyle.PE_IndicatorCheckBox QStyle.PrimitiveElement.PE_IndicatorCheckBox
+QStyle.PE_IndicatorDockWidgetResizeHandle QStyle.PrimitiveElement.PE_IndicatorDockWidgetResizeHandle
+QStyle.PE_IndicatorHeaderArrow QStyle.PrimitiveElement.PE_IndicatorHeaderArrow
+QStyle.PE_IndicatorMenuCheckMark QStyle.PrimitiveElement.PE_IndicatorMenuCheckMark
+QStyle.PE_IndicatorProgressChunk QStyle.PrimitiveElement.PE_IndicatorProgressChunk
+QStyle.PE_IndicatorRadioButton QStyle.PrimitiveElement.PE_IndicatorRadioButton
+QStyle.PE_IndicatorSpinDown QStyle.PrimitiveElement.PE_IndicatorSpinDown
+QStyle.PE_IndicatorSpinMinus QStyle.PrimitiveElement.PE_IndicatorSpinMinus
+QStyle.PE_IndicatorSpinPlus QStyle.PrimitiveElement.PE_IndicatorSpinPlus
+QStyle.PE_IndicatorSpinUp QStyle.PrimitiveElement.PE_IndicatorSpinUp
+QStyle.PE_IndicatorToolBarHandle QStyle.PrimitiveElement.PE_IndicatorToolBarHandle
+QStyle.PE_IndicatorToolBarSeparator QStyle.PrimitiveElement.PE_IndicatorToolBarSeparator
+QStyle.PE_PanelTipLabel QStyle.PrimitiveElement.PE_PanelTipLabel
+QStyle.PE_IndicatorTabTear QStyle.PrimitiveElement.PE_IndicatorTabTear
+QStyle.PE_PanelScrollAreaCorner QStyle.PrimitiveElement.PE_PanelScrollAreaCorner
+QStyle.PE_Widget QStyle.PrimitiveElement.PE_Widget
+QStyle.PE_IndicatorColumnViewArrow QStyle.PrimitiveElement.PE_IndicatorColumnViewArrow
+QStyle.PE_FrameStatusBarItem QStyle.PrimitiveElement.PE_FrameStatusBarItem
+QStyle.PE_IndicatorItemViewItemCheck QStyle.PrimitiveElement.PE_IndicatorItemViewItemCheck
+QStyle.PE_IndicatorItemViewItemDrop QStyle.PrimitiveElement.PE_IndicatorItemViewItemDrop
+QStyle.PE_PanelItemViewItem QStyle.PrimitiveElement.PE_PanelItemViewItem
+QStyle.PE_PanelItemViewRow QStyle.PrimitiveElement.PE_PanelItemViewRow
+QStyle.PE_PanelStatusBar QStyle.PrimitiveElement.PE_PanelStatusBar
+QStyle.PE_IndicatorTabClose QStyle.PrimitiveElement.PE_IndicatorTabClose
+QStyle.PE_PanelMenu QStyle.PrimitiveElement.PE_PanelMenu
+QStyle.PE_IndicatorTabTearLeft QStyle.PrimitiveElement.PE_IndicatorTabTearLeft
+QStyle.PE_IndicatorTabTearRight QStyle.PrimitiveElement.PE_IndicatorTabTearRight
+QStyle.PE_CustomBase QStyle.PrimitiveElement.PE_CustomBase
+QStyle.State_None QStyle.StateFlag.State_None
+QStyle.State_Enabled QStyle.StateFlag.State_Enabled
+QStyle.State_Raised QStyle.StateFlag.State_Raised
+QStyle.State_Sunken QStyle.StateFlag.State_Sunken
+QStyle.State_Off QStyle.StateFlag.State_Off
+QStyle.State_NoChange QStyle.StateFlag.State_NoChange
+QStyle.State_On QStyle.StateFlag.State_On
+QStyle.State_DownArrow QStyle.StateFlag.State_DownArrow
+QStyle.State_Horizontal QStyle.StateFlag.State_Horizontal
+QStyle.State_HasFocus QStyle.StateFlag.State_HasFocus
+QStyle.State_Top QStyle.StateFlag.State_Top
+QStyle.State_Bottom QStyle.StateFlag.State_Bottom
+QStyle.State_FocusAtBorder QStyle.StateFlag.State_FocusAtBorder
+QStyle.State_AutoRaise QStyle.StateFlag.State_AutoRaise
+QStyle.State_MouseOver QStyle.StateFlag.State_MouseOver
+QStyle.State_UpArrow QStyle.StateFlag.State_UpArrow
+QStyle.State_Selected QStyle.StateFlag.State_Selected
+QStyle.State_Active QStyle.StateFlag.State_Active
+QStyle.State_Open QStyle.StateFlag.State_Open
+QStyle.State_Children QStyle.StateFlag.State_Children
+QStyle.State_Item QStyle.StateFlag.State_Item
+QStyle.State_Sibling QStyle.StateFlag.State_Sibling
+QStyle.State_Editing QStyle.StateFlag.State_Editing
+QStyle.State_KeyboardFocusChange QStyle.StateFlag.State_KeyboardFocusChange
+QStyle.State_ReadOnly QStyle.StateFlag.State_ReadOnly
+QStyle.State_Window QStyle.StateFlag.State_Window
+QStyle.State_Small QStyle.StateFlag.State_Small
+QStyle.State_Mini QStyle.StateFlag.State_Mini
+QCompleter.UnsortedModel QCompleter.ModelSorting.UnsortedModel
+QCompleter.CaseSensitivelySortedModel QCompleter.ModelSorting.CaseSensitivelySortedModel
+QCompleter.CaseInsensitivelySortedModel QCompleter.ModelSorting.CaseInsensitivelySortedModel
+QCompleter.PopupCompletion QCompleter.CompletionMode.PopupCompletion
+QCompleter.UnfilteredPopupCompletion QCompleter.CompletionMode.UnfilteredPopupCompletion
+QCompleter.InlineCompletion QCompleter.CompletionMode.InlineCompletion
+QDataWidgetMapper.AutoSubmit QDataWidgetMapper.SubmitPolicy.AutoSubmit
+QDataWidgetMapper.ManualSubmit QDataWidgetMapper.SubmitPolicy.ManualSubmit
+QDateTimeEdit.NoSection QDateTimeEdit.Section.NoSection
+QDateTimeEdit.AmPmSection QDateTimeEdit.Section.AmPmSection
+QDateTimeEdit.MSecSection QDateTimeEdit.Section.MSecSection
+QDateTimeEdit.SecondSection QDateTimeEdit.Section.SecondSection
+QDateTimeEdit.MinuteSection QDateTimeEdit.Section.MinuteSection
+QDateTimeEdit.HourSection QDateTimeEdit.Section.HourSection
+QDateTimeEdit.DaySection QDateTimeEdit.Section.DaySection
+QDateTimeEdit.MonthSection QDateTimeEdit.Section.MonthSection
+QDateTimeEdit.YearSection QDateTimeEdit.Section.YearSection
+QDateTimeEdit.TimeSections_Mask QDateTimeEdit.Section.TimeSections_Mask
+QDateTimeEdit.DateSections_Mask QDateTimeEdit.Section.DateSections_Mask
+QDialogButtonBox.NoButton QDialogButtonBox.StandardButton.NoButton
+QDialogButtonBox.Ok QDialogButtonBox.StandardButton.Ok
+QDialogButtonBox.Save QDialogButtonBox.StandardButton.Save
+QDialogButtonBox.SaveAll QDialogButtonBox.StandardButton.SaveAll
+QDialogButtonBox.Open QDialogButtonBox.StandardButton.Open
+QDialogButtonBox.Yes QDialogButtonBox.StandardButton.Yes
+QDialogButtonBox.YesToAll QDialogButtonBox.StandardButton.YesToAll
+QDialogButtonBox.No QDialogButtonBox.StandardButton.No
+QDialogButtonBox.NoToAll QDialogButtonBox.StandardButton.NoToAll
+QDialogButtonBox.Abort QDialogButtonBox.StandardButton.Abort
+QDialogButtonBox.Retry QDialogButtonBox.StandardButton.Retry
+QDialogButtonBox.Ignore QDialogButtonBox.StandardButton.Ignore
+QDialogButtonBox.Close QDialogButtonBox.StandardButton.Close
+QDialogButtonBox.Cancel QDialogButtonBox.StandardButton.Cancel
+QDialogButtonBox.Discard QDialogButtonBox.StandardButton.Discard
+QDialogButtonBox.Help QDialogButtonBox.StandardButton.Help
+QDialogButtonBox.Apply QDialogButtonBox.StandardButton.Apply
+QDialogButtonBox.Reset QDialogButtonBox.StandardButton.Reset
+QDialogButtonBox.RestoreDefaults QDialogButtonBox.StandardButton.RestoreDefaults
+QDialogButtonBox.InvalidRole QDialogButtonBox.ButtonRole.InvalidRole
+QDialogButtonBox.AcceptRole QDialogButtonBox.ButtonRole.AcceptRole
+QDialogButtonBox.RejectRole QDialogButtonBox.ButtonRole.RejectRole
+QDialogButtonBox.DestructiveRole QDialogButtonBox.ButtonRole.DestructiveRole
+QDialogButtonBox.ActionRole QDialogButtonBox.ButtonRole.ActionRole
+QDialogButtonBox.HelpRole QDialogButtonBox.ButtonRole.HelpRole
+QDialogButtonBox.YesRole QDialogButtonBox.ButtonRole.YesRole
+QDialogButtonBox.NoRole QDialogButtonBox.ButtonRole.NoRole
+QDialogButtonBox.ResetRole QDialogButtonBox.ButtonRole.ResetRole
+QDialogButtonBox.ApplyRole QDialogButtonBox.ButtonRole.ApplyRole
+QDialogButtonBox.WinLayout QDialogButtonBox.ButtonLayout.WinLayout
+QDialogButtonBox.MacLayout QDialogButtonBox.ButtonLayout.MacLayout
+QDialogButtonBox.KdeLayout QDialogButtonBox.ButtonLayout.KdeLayout
+QDialogButtonBox.GnomeLayout QDialogButtonBox.ButtonLayout.GnomeLayout
+QDialogButtonBox.AndroidLayout QDialogButtonBox.ButtonLayout.AndroidLayout
+QDirModel.FileIconRole QDirModel.Roles.FileIconRole
+QDirModel.FilePathRole QDirModel.Roles.FilePathRole
+QDirModel.FileNameRole QDirModel.Roles.FileNameRole
+QDockWidget.DockWidgetClosable QDockWidget.DockWidgetFeature.DockWidgetClosable
+QDockWidget.DockWidgetMovable QDockWidget.DockWidgetFeature.DockWidgetMovable
+QDockWidget.DockWidgetFloatable QDockWidget.DockWidgetFeature.DockWidgetFloatable
+QDockWidget.DockWidgetVerticalTitleBar QDockWidget.DockWidgetFeature.DockWidgetVerticalTitleBar
+QDockWidget.AllDockWidgetFeatures QDockWidget.DockWidgetFeature.AllDockWidgetFeatures
+QDockWidget.NoDockWidgetFeatures QDockWidget.DockWidgetFeature.NoDockWidgetFeatures
+QFileDialog.ShowDirsOnly QFileDialog.Option.ShowDirsOnly
+QFileDialog.DontResolveSymlinks QFileDialog.Option.DontResolveSymlinks
+QFileDialog.DontConfirmOverwrite QFileDialog.Option.DontConfirmOverwrite
+QFileDialog.DontUseSheet QFileDialog.Option.DontUseSheet
+QFileDialog.DontUseNativeDialog QFileDialog.Option.DontUseNativeDialog
+QFileDialog.ReadOnly QFileDialog.Option.ReadOnly
+QFileDialog.HideNameFilterDetails QFileDialog.Option.HideNameFilterDetails
+QFileDialog.DontUseCustomDirectoryIcons QFileDialog.Option.DontUseCustomDirectoryIcons
+QFileDialog.LookIn QFileDialog.DialogLabel.LookIn
+QFileDialog.FileName QFileDialog.DialogLabel.FileName
+QFileDialog.FileType QFileDialog.DialogLabel.FileType
+QFileDialog.Accept QFileDialog.DialogLabel.Accept
+QFileDialog.Reject QFileDialog.DialogLabel.Reject
+QFileDialog.AcceptOpen QFileDialog.AcceptMode.AcceptOpen
+QFileDialog.AcceptSave QFileDialog.AcceptMode.AcceptSave
+QFileDialog.AnyFile QFileDialog.FileMode.AnyFile
+QFileDialog.ExistingFile QFileDialog.FileMode.ExistingFile
+QFileDialog.Directory QFileDialog.FileMode.Directory
+QFileDialog.ExistingFiles QFileDialog.FileMode.ExistingFiles
+QFileDialog.DirectoryOnly QFileDialog.FileMode.DirectoryOnly
+QFileDialog.Detail QFileDialog.ViewMode.Detail
+QFileDialog.List QFileDialog.ViewMode.List
+QFileIconProvider.DontUseCustomDirectoryIcons QFileIconProvider.Option.DontUseCustomDirectoryIcons
+QFileIconProvider.Computer QFileIconProvider.IconType.Computer
+QFileIconProvider.Desktop QFileIconProvider.IconType.Desktop
+QFileIconProvider.Trashcan QFileIconProvider.IconType.Trashcan
+QFileIconProvider.Network QFileIconProvider.IconType.Network
+QFileIconProvider.Drive QFileIconProvider.IconType.Drive
+QFileIconProvider.Folder QFileIconProvider.IconType.Folder
+QFileIconProvider.File QFileIconProvider.IconType.File
+QFileSystemModel.DontWatchForChanges QFileSystemModel.Option.DontWatchForChanges
+QFileSystemModel.DontResolveSymlinks QFileSystemModel.Option.DontResolveSymlinks
+QFileSystemModel.DontUseCustomDirectoryIcons QFileSystemModel.Option.DontUseCustomDirectoryIcons
+QFileSystemModel.FileIconRole QFileSystemModel.Roles.FileIconRole
+QFileSystemModel.FilePathRole QFileSystemModel.Roles.FilePathRole
+QFileSystemModel.FileNameRole QFileSystemModel.Roles.FileNameRole
+QFileSystemModel.FilePermissions QFileSystemModel.Roles.FilePermissions
+QFontComboBox.AllFonts QFontComboBox.FontFilter.AllFonts
+QFontComboBox.ScalableFonts QFontComboBox.FontFilter.ScalableFonts
+QFontComboBox.NonScalableFonts QFontComboBox.FontFilter.NonScalableFonts
+QFontComboBox.MonospacedFonts QFontComboBox.FontFilter.MonospacedFonts
+QFontComboBox.ProportionalFonts QFontComboBox.FontFilter.ProportionalFonts
+QFontDialog.NoButtons QFontDialog.FontDialogOption.NoButtons
+QFontDialog.DontUseNativeDialog QFontDialog.FontDialogOption.DontUseNativeDialog
+QFontDialog.ScalableFonts QFontDialog.FontDialogOption.ScalableFonts
+QFontDialog.NonScalableFonts QFontDialog.FontDialogOption.NonScalableFonts
+QFontDialog.MonospacedFonts QFontDialog.FontDialogOption.MonospacedFonts
+QFontDialog.ProportionalFonts QFontDialog.FontDialogOption.ProportionalFonts
+QFormLayout.LabelRole QFormLayout.ItemRole.LabelRole
+QFormLayout.FieldRole QFormLayout.ItemRole.FieldRole
+QFormLayout.SpanningRole QFormLayout.ItemRole.SpanningRole
+QFormLayout.DontWrapRows QFormLayout.RowWrapPolicy.DontWrapRows
+QFormLayout.WrapLongRows QFormLayout.RowWrapPolicy.WrapLongRows
+QFormLayout.WrapAllRows QFormLayout.RowWrapPolicy.WrapAllRows
+QFormLayout.FieldsStayAtSizeHint QFormLayout.FieldGrowthPolicy.FieldsStayAtSizeHint
+QFormLayout.ExpandingFieldsGrow QFormLayout.FieldGrowthPolicy.ExpandingFieldsGrow
+QFormLayout.AllNonFixedFieldsGrow QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow
+QGesture.CancelNone QGesture.GestureCancelPolicy.CancelNone
+QGesture.CancelAllInContext QGesture.GestureCancelPolicy.CancelAllInContext
+QPinchGesture.ScaleFactorChanged QPinchGesture.ChangeFlag.ScaleFactorChanged
+QPinchGesture.RotationAngleChanged QPinchGesture.ChangeFlag.RotationAngleChanged
+QPinchGesture.CenterPointChanged QPinchGesture.ChangeFlag.CenterPointChanged
+QSwipeGesture.NoDirection QSwipeGesture.SwipeDirection.NoDirection
+QSwipeGesture.Left QSwipeGesture.SwipeDirection.Left
+QSwipeGesture.Right QSwipeGesture.SwipeDirection.Right
+QSwipeGesture.Up QSwipeGesture.SwipeDirection.Up
+QSwipeGesture.Down QSwipeGesture.SwipeDirection.Down
+QGestureRecognizer.Ignore QGestureRecognizer.ResultFlag.Ignore
+QGestureRecognizer.MayBeGesture QGestureRecognizer.ResultFlag.MayBeGesture
+QGestureRecognizer.TriggerGesture QGestureRecognizer.ResultFlag.TriggerGesture
+QGestureRecognizer.FinishGesture QGestureRecognizer.ResultFlag.FinishGesture
+QGestureRecognizer.CancelGesture QGestureRecognizer.ResultFlag.CancelGesture
+QGestureRecognizer.ConsumeEventHint QGestureRecognizer.ResultFlag.ConsumeEventHint
+QGraphicsEffect.NoPad QGraphicsEffect.PixmapPadMode.NoPad
+QGraphicsEffect.PadToTransparentBorder QGraphicsEffect.PixmapPadMode.PadToTransparentBorder
+QGraphicsEffect.PadToEffectiveBoundingRect QGraphicsEffect.PixmapPadMode.PadToEffectiveBoundingRect
+QGraphicsEffect.SourceAttached QGraphicsEffect.ChangeFlag.SourceAttached
+QGraphicsEffect.SourceDetached QGraphicsEffect.ChangeFlag.SourceDetached
+QGraphicsEffect.SourceBoundingRectChanged QGraphicsEffect.ChangeFlag.SourceBoundingRectChanged
+QGraphicsEffect.SourceInvalidated QGraphicsEffect.ChangeFlag.SourceInvalidated
+QGraphicsBlurEffect.PerformanceHint QGraphicsBlurEffect.BlurHint.PerformanceHint
+QGraphicsBlurEffect.QualityHint QGraphicsBlurEffect.BlurHint.QualityHint
+QGraphicsBlurEffect.AnimationHint QGraphicsBlurEffect.BlurHint.AnimationHint
+QGraphicsItem.NonModal QGraphicsItem.PanelModality.NonModal
+QGraphicsItem.PanelModal QGraphicsItem.PanelModality.PanelModal
+QGraphicsItem.SceneModal QGraphicsItem.PanelModality.SceneModal
+QGraphicsItem.ItemIsMovable QGraphicsItem.GraphicsItemFlag.ItemIsMovable
+QGraphicsItem.ItemIsSelectable QGraphicsItem.GraphicsItemFlag.ItemIsSelectable
+QGraphicsItem.ItemIsFocusable QGraphicsItem.GraphicsItemFlag.ItemIsFocusable
+QGraphicsItem.ItemClipsToShape QGraphicsItem.GraphicsItemFlag.ItemClipsToShape
+QGraphicsItem.ItemClipsChildrenToShape QGraphicsItem.GraphicsItemFlag.ItemClipsChildrenToShape
+QGraphicsItem.ItemIgnoresTransformations QGraphicsItem.GraphicsItemFlag.ItemIgnoresTransformations
+QGraphicsItem.ItemIgnoresParentOpacity QGraphicsItem.GraphicsItemFlag.ItemIgnoresParentOpacity
+QGraphicsItem.ItemDoesntPropagateOpacityToChildren QGraphicsItem.GraphicsItemFlag.ItemDoesntPropagateOpacityToChildren
+QGraphicsItem.ItemStacksBehindParent QGraphicsItem.GraphicsItemFlag.ItemStacksBehindParent
+QGraphicsItem.ItemUsesExtendedStyleOption QGraphicsItem.GraphicsItemFlag.ItemUsesExtendedStyleOption
+QGraphicsItem.ItemHasNoContents QGraphicsItem.GraphicsItemFlag.ItemHasNoContents
+QGraphicsItem.ItemSendsGeometryChanges QGraphicsItem.GraphicsItemFlag.ItemSendsGeometryChanges
+QGraphicsItem.ItemAcceptsInputMethod QGraphicsItem.GraphicsItemFlag.ItemAcceptsInputMethod
+QGraphicsItem.ItemNegativeZStacksBehindParent QGraphicsItem.GraphicsItemFlag.ItemNegativeZStacksBehindParent
+QGraphicsItem.ItemIsPanel QGraphicsItem.GraphicsItemFlag.ItemIsPanel
+QGraphicsItem.ItemSendsScenePositionChanges QGraphicsItem.GraphicsItemFlag.ItemSendsScenePositionChanges
+QGraphicsItem.ItemContainsChildrenInShape QGraphicsItem.GraphicsItemFlag.ItemContainsChildrenInShape
+QGraphicsItem.ItemPositionChange QGraphicsItem.GraphicsItemChange.ItemPositionChange
+QGraphicsItem.ItemMatrixChange QGraphicsItem.GraphicsItemChange.ItemMatrixChange
+QGraphicsItem.ItemVisibleChange QGraphicsItem.GraphicsItemChange.ItemVisibleChange
+QGraphicsItem.ItemEnabledChange QGraphicsItem.GraphicsItemChange.ItemEnabledChange
+QGraphicsItem.ItemSelectedChange QGraphicsItem.GraphicsItemChange.ItemSelectedChange
+QGraphicsItem.ItemParentChange QGraphicsItem.GraphicsItemChange.ItemParentChange
+QGraphicsItem.ItemChildAddedChange QGraphicsItem.GraphicsItemChange.ItemChildAddedChange
+QGraphicsItem.ItemChildRemovedChange QGraphicsItem.GraphicsItemChange.ItemChildRemovedChange
+QGraphicsItem.ItemTransformChange QGraphicsItem.GraphicsItemChange.ItemTransformChange
+QGraphicsItem.ItemPositionHasChanged QGraphicsItem.GraphicsItemChange.ItemPositionHasChanged
+QGraphicsItem.ItemTransformHasChanged QGraphicsItem.GraphicsItemChange.ItemTransformHasChanged
+QGraphicsItem.ItemSceneChange QGraphicsItem.GraphicsItemChange.ItemSceneChange
+QGraphicsItem.ItemVisibleHasChanged QGraphicsItem.GraphicsItemChange.ItemVisibleHasChanged
+QGraphicsItem.ItemEnabledHasChanged QGraphicsItem.GraphicsItemChange.ItemEnabledHasChanged
+QGraphicsItem.ItemSelectedHasChanged QGraphicsItem.GraphicsItemChange.ItemSelectedHasChanged
+QGraphicsItem.ItemParentHasChanged QGraphicsItem.GraphicsItemChange.ItemParentHasChanged
+QGraphicsItem.ItemSceneHasChanged QGraphicsItem.GraphicsItemChange.ItemSceneHasChanged
+QGraphicsItem.ItemCursorChange QGraphicsItem.GraphicsItemChange.ItemCursorChange
+QGraphicsItem.ItemCursorHasChanged QGraphicsItem.GraphicsItemChange.ItemCursorHasChanged
+QGraphicsItem.ItemToolTipChange QGraphicsItem.GraphicsItemChange.ItemToolTipChange
+QGraphicsItem.ItemToolTipHasChanged QGraphicsItem.GraphicsItemChange.ItemToolTipHasChanged
+QGraphicsItem.ItemFlagsChange QGraphicsItem.GraphicsItemChange.ItemFlagsChange
+QGraphicsItem.ItemFlagsHaveChanged QGraphicsItem.GraphicsItemChange.ItemFlagsHaveChanged
+QGraphicsItem.ItemZValueChange QGraphicsItem.GraphicsItemChange.ItemZValueChange
+QGraphicsItem.ItemZValueHasChanged QGraphicsItem.GraphicsItemChange.ItemZValueHasChanged
+QGraphicsItem.ItemOpacityChange QGraphicsItem.GraphicsItemChange.ItemOpacityChange
+QGraphicsItem.ItemOpacityHasChanged QGraphicsItem.GraphicsItemChange.ItemOpacityHasChanged
+QGraphicsItem.ItemScenePositionHasChanged QGraphicsItem.GraphicsItemChange.ItemScenePositionHasChanged
+QGraphicsItem.ItemRotationChange QGraphicsItem.GraphicsItemChange.ItemRotationChange
+QGraphicsItem.ItemRotationHasChanged QGraphicsItem.GraphicsItemChange.ItemRotationHasChanged
+QGraphicsItem.ItemScaleChange QGraphicsItem.GraphicsItemChange.ItemScaleChange
+QGraphicsItem.ItemScaleHasChanged QGraphicsItem.GraphicsItemChange.ItemScaleHasChanged
+QGraphicsItem.ItemTransformOriginPointChange QGraphicsItem.GraphicsItemChange.ItemTransformOriginPointChange
+QGraphicsItem.ItemTransformOriginPointHasChanged QGraphicsItem.GraphicsItemChange.ItemTransformOriginPointHasChanged
+QGraphicsItem.NoCache QGraphicsItem.CacheMode.NoCache
+QGraphicsItem.ItemCoordinateCache QGraphicsItem.CacheMode.ItemCoordinateCache
+QGraphicsItem.DeviceCoordinateCache QGraphicsItem.CacheMode.DeviceCoordinateCache
+QGraphicsPixmapItem.MaskShape QGraphicsPixmapItem.ShapeMode.MaskShape
+QGraphicsPixmapItem.BoundingRectShape QGraphicsPixmapItem.ShapeMode.BoundingRectShape
+QGraphicsPixmapItem.HeuristicMaskShape QGraphicsPixmapItem.ShapeMode.HeuristicMaskShape
+QGraphicsScene.ItemLayer QGraphicsScene.SceneLayer.ItemLayer
+QGraphicsScene.BackgroundLayer QGraphicsScene.SceneLayer.BackgroundLayer
+QGraphicsScene.ForegroundLayer QGraphicsScene.SceneLayer.ForegroundLayer
+QGraphicsScene.AllLayers QGraphicsScene.SceneLayer.AllLayers
+QGraphicsScene.BspTreeIndex QGraphicsScene.ItemIndexMethod.BspTreeIndex
+QGraphicsScene.NoIndex QGraphicsScene.ItemIndexMethod.NoIndex
+QGraphicsSceneContextMenuEvent.Mouse QGraphicsSceneContextMenuEvent.Reason.Mouse
+QGraphicsSceneContextMenuEvent.Keyboard QGraphicsSceneContextMenuEvent.Reason.Keyboard
+QGraphicsSceneContextMenuEvent.Other QGraphicsSceneContextMenuEvent.Reason.Other
+QGraphicsView.DontClipPainter QGraphicsView.OptimizationFlag.DontClipPainter
+QGraphicsView.DontSavePainterState QGraphicsView.OptimizationFlag.DontSavePainterState
+QGraphicsView.DontAdjustForAntialiasing QGraphicsView.OptimizationFlag.DontAdjustForAntialiasing
+QGraphicsView.FullViewportUpdate QGraphicsView.ViewportUpdateMode.FullViewportUpdate
+QGraphicsView.MinimalViewportUpdate QGraphicsView.ViewportUpdateMode.MinimalViewportUpdate
+QGraphicsView.SmartViewportUpdate QGraphicsView.ViewportUpdateMode.SmartViewportUpdate
+QGraphicsView.BoundingRectViewportUpdate QGraphicsView.ViewportUpdateMode.BoundingRectViewportUpdate
+QGraphicsView.NoViewportUpdate QGraphicsView.ViewportUpdateMode.NoViewportUpdate
+QGraphicsView.NoAnchor QGraphicsView.ViewportAnchor.NoAnchor
+QGraphicsView.AnchorViewCenter QGraphicsView.ViewportAnchor.AnchorViewCenter
+QGraphicsView.AnchorUnderMouse QGraphicsView.ViewportAnchor.AnchorUnderMouse
+QGraphicsView.NoDrag QGraphicsView.DragMode.NoDrag
+QGraphicsView.ScrollHandDrag QGraphicsView.DragMode.ScrollHandDrag
+QGraphicsView.RubberBandDrag QGraphicsView.DragMode.RubberBandDrag
+QGraphicsView.CacheNone QGraphicsView.CacheModeFlag.CacheNone
+QGraphicsView.CacheBackground QGraphicsView.CacheModeFlag.CacheBackground
+QHeaderView.Interactive QHeaderView.ResizeMode.Interactive
+QHeaderView.Fixed QHeaderView.ResizeMode.Fixed
+QHeaderView.Stretch QHeaderView.ResizeMode.Stretch
+QHeaderView.ResizeToContents QHeaderView.ResizeMode.ResizeToContents
+QHeaderView.Custom QHeaderView.ResizeMode.Custom
+QInputDialog.TextInput QInputDialog.InputMode.TextInput
+QInputDialog.IntInput QInputDialog.InputMode.IntInput
+QInputDialog.DoubleInput QInputDialog.InputMode.DoubleInput
+QInputDialog.NoButtons QInputDialog.InputDialogOption.NoButtons
+QInputDialog.UseListViewForComboBoxItems QInputDialog.InputDialogOption.UseListViewForComboBoxItems
+QInputDialog.UsePlainTextEditForTextInput QInputDialog.InputDialogOption.UsePlainTextEditForTextInput
+QLCDNumber.Outline QLCDNumber.SegmentStyle.Outline
+QLCDNumber.Filled QLCDNumber.SegmentStyle.Filled
+QLCDNumber.Flat QLCDNumber.SegmentStyle.Flat
+QLCDNumber.Hex QLCDNumber.Mode.Hex
+QLCDNumber.Dec QLCDNumber.Mode.Dec
+QLCDNumber.Oct QLCDNumber.Mode.Oct
+QLCDNumber.Bin QLCDNumber.Mode.Bin
+QLineEdit.LeadingPosition QLineEdit.ActionPosition.LeadingPosition
+QLineEdit.TrailingPosition QLineEdit.ActionPosition.TrailingPosition
+QLineEdit.Normal QLineEdit.EchoMode.Normal
+QLineEdit.NoEcho QLineEdit.EchoMode.NoEcho
+QLineEdit.Password QLineEdit.EchoMode.Password
+QLineEdit.PasswordEchoOnEdit QLineEdit.EchoMode.PasswordEchoOnEdit
+QListView.ListMode QListView.ViewMode.ListMode
+QListView.IconMode QListView.ViewMode.IconMode
+QListView.SinglePass QListView.LayoutMode.SinglePass
+QListView.Batched QListView.LayoutMode.Batched
+QListView.Fixed QListView.ResizeMode.Fixed
+QListView.Adjust QListView.ResizeMode.Adjust
+QListView.LeftToRight QListView.Flow.LeftToRight
+QListView.TopToBottom QListView.Flow.TopToBottom
+QListView.Static QListView.Movement.Static
+QListView.Free QListView.Movement.Free
+QListView.Snap QListView.Movement.Snap
+QListWidgetItem.Type QListWidgetItem.ItemType.Type
+QListWidgetItem.UserType QListWidgetItem.ItemType.UserType
+QMainWindow.AnimatedDocks QMainWindow.DockOption.AnimatedDocks
+QMainWindow.AllowNestedDocks QMainWindow.DockOption.AllowNestedDocks
+QMainWindow.AllowTabbedDocks QMainWindow.DockOption.AllowTabbedDocks
+QMainWindow.ForceTabbedDocks QMainWindow.DockOption.ForceTabbedDocks
+QMainWindow.VerticalTabs QMainWindow.DockOption.VerticalTabs
+QMainWindow.GroupedDragging QMainWindow.DockOption.GroupedDragging
+QMdiArea.CreationOrder QMdiArea.WindowOrder.CreationOrder
+QMdiArea.StackingOrder QMdiArea.WindowOrder.StackingOrder
+QMdiArea.ActivationHistoryOrder QMdiArea.WindowOrder.ActivationHistoryOrder
+QMdiArea.SubWindowView QMdiArea.ViewMode.SubWindowView
+QMdiArea.TabbedView QMdiArea.ViewMode.TabbedView
+QMdiArea.DontMaximizeSubWindowOnActivation QMdiArea.AreaOption.DontMaximizeSubWindowOnActivation
+QMdiSubWindow.RubberBandResize QMdiSubWindow.SubWindowOption.RubberBandResize
+QMdiSubWindow.RubberBandMove QMdiSubWindow.SubWindowOption.RubberBandMove
+QMessageBox.NoButton QMessageBox.StandardButton.NoButton
+QMessageBox.Ok QMessageBox.StandardButton.Ok
+QMessageBox.Save QMessageBox.StandardButton.Save
+QMessageBox.SaveAll QMessageBox.StandardButton.SaveAll
+QMessageBox.Open QMessageBox.StandardButton.Open
+QMessageBox.Yes QMessageBox.StandardButton.Yes
+QMessageBox.YesToAll QMessageBox.StandardButton.YesToAll
+QMessageBox.No QMessageBox.StandardButton.No
+QMessageBox.NoToAll QMessageBox.StandardButton.NoToAll
+QMessageBox.Abort QMessageBox.StandardButton.Abort
+QMessageBox.Retry QMessageBox.StandardButton.Retry
+QMessageBox.Ignore QMessageBox.StandardButton.Ignore
+QMessageBox.Close QMessageBox.StandardButton.Close
+QMessageBox.Cancel QMessageBox.StandardButton.Cancel
+QMessageBox.Discard QMessageBox.StandardButton.Discard
+QMessageBox.Help QMessageBox.StandardButton.Help
+QMessageBox.Apply QMessageBox.StandardButton.Apply
+QMessageBox.Reset QMessageBox.StandardButton.Reset
+QMessageBox.RestoreDefaults QMessageBox.StandardButton.RestoreDefaults
+QMessageBox.FirstButton QMessageBox.StandardButton.FirstButton
+QMessageBox.LastButton QMessageBox.StandardButton.LastButton
+QMessageBox.YesAll QMessageBox.StandardButton.YesAll
+QMessageBox.NoAll QMessageBox.StandardButton.NoAll
+QMessageBox.Default QMessageBox.StandardButton.Default
+QMessageBox.Escape QMessageBox.StandardButton.Escape
+QMessageBox.FlagMask QMessageBox.StandardButton.FlagMask
+QMessageBox.ButtonMask QMessageBox.StandardButton.ButtonMask
+QMessageBox.NoIcon QMessageBox.Icon.NoIcon
+QMessageBox.Information QMessageBox.Icon.Information
+QMessageBox.Warning QMessageBox.Icon.Warning
+QMessageBox.Critical QMessageBox.Icon.Critical
+QMessageBox.Question QMessageBox.Icon.Question
+QMessageBox.InvalidRole QMessageBox.ButtonRole.InvalidRole
+QMessageBox.AcceptRole QMessageBox.ButtonRole.AcceptRole
+QMessageBox.RejectRole QMessageBox.ButtonRole.RejectRole
+QMessageBox.DestructiveRole QMessageBox.ButtonRole.DestructiveRole
+QMessageBox.ActionRole QMessageBox.ButtonRole.ActionRole
+QMessageBox.HelpRole QMessageBox.ButtonRole.HelpRole
+QMessageBox.YesRole QMessageBox.ButtonRole.YesRole
+QMessageBox.NoRole QMessageBox.ButtonRole.NoRole
+QMessageBox.ResetRole QMessageBox.ButtonRole.ResetRole
+QMessageBox.ApplyRole QMessageBox.ButtonRole.ApplyRole
+QOpenGLWidget.NoPartialUpdate QOpenGLWidget.UpdateBehavior.NoPartialUpdate
+QOpenGLWidget.PartialUpdate QOpenGLWidget.UpdateBehavior.PartialUpdate
+QPlainTextEdit.NoWrap QPlainTextEdit.LineWrapMode.NoWrap
+QPlainTextEdit.WidgetWidth QPlainTextEdit.LineWrapMode.WidgetWidth
+QProgressBar.TopToBottom QProgressBar.Direction.TopToBottom
+QProgressBar.BottomToTop QProgressBar.Direction.BottomToTop
+QRubberBand.Line QRubberBand.Shape.Line
+QRubberBand.Rectangle QRubberBand.Shape.Rectangle
+QScroller.InputPress QScroller.Input.InputPress
+QScroller.InputMove QScroller.Input.InputMove
+QScroller.InputRelease QScroller.Input.InputRelease
+QScroller.TouchGesture QScroller.ScrollerGestureType.TouchGesture
+QScroller.LeftMouseButtonGesture QScroller.ScrollerGestureType.LeftMouseButtonGesture
+QScroller.RightMouseButtonGesture QScroller.ScrollerGestureType.RightMouseButtonGesture
+QScroller.MiddleMouseButtonGesture QScroller.ScrollerGestureType.MiddleMouseButtonGesture
+QScroller.Inactive QScroller.State.Inactive
+QScroller.Pressed QScroller.State.Pressed
+QScroller.Dragging QScroller.State.Dragging
+QScroller.Scrolling QScroller.State.Scrolling
+QScrollerProperties.MousePressEventDelay QScrollerProperties.ScrollMetric.MousePressEventDelay
+QScrollerProperties.DragStartDistance QScrollerProperties.ScrollMetric.DragStartDistance
+QScrollerProperties.DragVelocitySmoothingFactor QScrollerProperties.ScrollMetric.DragVelocitySmoothingFactor
+QScrollerProperties.AxisLockThreshold QScrollerProperties.ScrollMetric.AxisLockThreshold
+QScrollerProperties.ScrollingCurve QScrollerProperties.ScrollMetric.ScrollingCurve
+QScrollerProperties.DecelerationFactor QScrollerProperties.ScrollMetric.DecelerationFactor
+QScrollerProperties.MinimumVelocity QScrollerProperties.ScrollMetric.MinimumVelocity
+QScrollerProperties.MaximumVelocity QScrollerProperties.ScrollMetric.MaximumVelocity
+QScrollerProperties.MaximumClickThroughVelocity QScrollerProperties.ScrollMetric.MaximumClickThroughVelocity
+QScrollerProperties.AcceleratingFlickMaximumTime QScrollerProperties.ScrollMetric.AcceleratingFlickMaximumTime
+QScrollerProperties.AcceleratingFlickSpeedupFactor QScrollerProperties.ScrollMetric.AcceleratingFlickSpeedupFactor
+QScrollerProperties.SnapPositionRatio QScrollerProperties.ScrollMetric.SnapPositionRatio
+QScrollerProperties.SnapTime QScrollerProperties.ScrollMetric.SnapTime
+QScrollerProperties.OvershootDragResistanceFactor QScrollerProperties.ScrollMetric.OvershootDragResistanceFactor
+QScrollerProperties.OvershootDragDistanceFactor QScrollerProperties.ScrollMetric.OvershootDragDistanceFactor
+QScrollerProperties.OvershootScrollDistanceFactor QScrollerProperties.ScrollMetric.OvershootScrollDistanceFactor
+QScrollerProperties.OvershootScrollTime QScrollerProperties.ScrollMetric.OvershootScrollTime
+QScrollerProperties.HorizontalOvershootPolicy QScrollerProperties.ScrollMetric.HorizontalOvershootPolicy
+QScrollerProperties.VerticalOvershootPolicy QScrollerProperties.ScrollMetric.VerticalOvershootPolicy
+QScrollerProperties.FrameRate QScrollerProperties.ScrollMetric.FrameRate
+QScrollerProperties.ScrollMetricCount QScrollerProperties.ScrollMetric.ScrollMetricCount
+QScrollerProperties.Standard QScrollerProperties.FrameRates.Standard
+QScrollerProperties.Fps60 QScrollerProperties.FrameRates.Fps60
+QScrollerProperties.Fps30 QScrollerProperties.FrameRates.Fps30
+QScrollerProperties.Fps20 QScrollerProperties.FrameRates.Fps20
+QScrollerProperties.OvershootWhenScrollable QScrollerProperties.OvershootPolicy.OvershootWhenScrollable
+QScrollerProperties.OvershootAlwaysOff QScrollerProperties.OvershootPolicy.OvershootAlwaysOff
+QScrollerProperties.OvershootAlwaysOn QScrollerProperties.OvershootPolicy.OvershootAlwaysOn
+QSizePolicy.DefaultType QSizePolicy.ControlType.DefaultType
+QSizePolicy.ButtonBox QSizePolicy.ControlType.ButtonBox
+QSizePolicy.CheckBox QSizePolicy.ControlType.CheckBox
+QSizePolicy.ComboBox QSizePolicy.ControlType.ComboBox
+QSizePolicy.Frame QSizePolicy.ControlType.Frame
+QSizePolicy.GroupBox QSizePolicy.ControlType.GroupBox
+QSizePolicy.Label QSizePolicy.ControlType.Label
+QSizePolicy.Line QSizePolicy.ControlType.Line
+QSizePolicy.LineEdit QSizePolicy.ControlType.LineEdit
+QSizePolicy.PushButton QSizePolicy.ControlType.PushButton
+QSizePolicy.RadioButton QSizePolicy.ControlType.RadioButton
+QSizePolicy.Slider QSizePolicy.ControlType.Slider
+QSizePolicy.SpinBox QSizePolicy.ControlType.SpinBox
+QSizePolicy.TabWidget QSizePolicy.ControlType.TabWidget
+QSizePolicy.ToolButton QSizePolicy.ControlType.ToolButton
+QSizePolicy.Fixed QSizePolicy.Policy.Fixed
+QSizePolicy.Minimum QSizePolicy.Policy.Minimum
+QSizePolicy.Maximum QSizePolicy.Policy.Maximum
+QSizePolicy.Preferred QSizePolicy.Policy.Preferred
+QSizePolicy.MinimumExpanding QSizePolicy.Policy.MinimumExpanding
+QSizePolicy.Expanding QSizePolicy.Policy.Expanding
+QSizePolicy.Ignored QSizePolicy.Policy.Ignored
+QSizePolicy.GrowFlag QSizePolicy.PolicyFlag.GrowFlag
+QSizePolicy.ExpandFlag QSizePolicy.PolicyFlag.ExpandFlag
+QSizePolicy.ShrinkFlag QSizePolicy.PolicyFlag.ShrinkFlag
+QSizePolicy.IgnoreFlag QSizePolicy.PolicyFlag.IgnoreFlag
+QSlider.NoTicks QSlider.TickPosition.NoTicks
+QSlider.TicksAbove QSlider.TickPosition.TicksAbove
+QSlider.TicksLeft QSlider.TickPosition.TicksLeft
+QSlider.TicksBelow QSlider.TickPosition.TicksBelow
+QSlider.TicksRight QSlider.TickPosition.TicksRight
+QSlider.TicksBothSides QSlider.TickPosition.TicksBothSides
+QStackedLayout.StackOne QStackedLayout.StackingMode.StackOne
+QStackedLayout.StackAll QStackedLayout.StackingMode.StackAll
+QStyleOption.Version QStyleOption.StyleOptionVersion.Version
+QStyleOption.Type QStyleOption.StyleOptionType.Type
+QStyleOption.SO_Default QStyleOption.OptionType.SO_Default
+QStyleOption.SO_FocusRect QStyleOption.OptionType.SO_FocusRect
+QStyleOption.SO_Button QStyleOption.OptionType.SO_Button
+QStyleOption.SO_Tab QStyleOption.OptionType.SO_Tab
+QStyleOption.SO_MenuItem QStyleOption.OptionType.SO_MenuItem
+QStyleOption.SO_Frame QStyleOption.OptionType.SO_Frame
+QStyleOption.SO_ProgressBar QStyleOption.OptionType.SO_ProgressBar
+QStyleOption.SO_ToolBox QStyleOption.OptionType.SO_ToolBox
+QStyleOption.SO_Header QStyleOption.OptionType.SO_Header
+QStyleOption.SO_DockWidget QStyleOption.OptionType.SO_DockWidget
+QStyleOption.SO_ViewItem QStyleOption.OptionType.SO_ViewItem
+QStyleOption.SO_TabWidgetFrame QStyleOption.OptionType.SO_TabWidgetFrame
+QStyleOption.SO_TabBarBase QStyleOption.OptionType.SO_TabBarBase
+QStyleOption.SO_RubberBand QStyleOption.OptionType.SO_RubberBand
+QStyleOption.SO_ToolBar QStyleOption.OptionType.SO_ToolBar
+QStyleOption.SO_Complex QStyleOption.OptionType.SO_Complex
+QStyleOption.SO_Slider QStyleOption.OptionType.SO_Slider
+QStyleOption.SO_SpinBox QStyleOption.OptionType.SO_SpinBox
+QStyleOption.SO_ToolButton QStyleOption.OptionType.SO_ToolButton
+QStyleOption.SO_ComboBox QStyleOption.OptionType.SO_ComboBox
+QStyleOption.SO_TitleBar QStyleOption.OptionType.SO_TitleBar
+QStyleOption.SO_GroupBox QStyleOption.OptionType.SO_GroupBox
+QStyleOption.SO_ComplexCustomBase QStyleOption.OptionType.SO_ComplexCustomBase
+QStyleOption.SO_GraphicsItem QStyleOption.OptionType.SO_GraphicsItem
+QStyleOption.SO_SizeGrip QStyleOption.OptionType.SO_SizeGrip
+QStyleOption.SO_CustomBase QStyleOption.OptionType.SO_CustomBase
+QStyleOptionFocusRect.Version QStyleOptionFocusRect.StyleOptionVersion.Version
+QStyleOptionFocusRect.Type QStyleOptionFocusRect.StyleOptionType.Type
+QStyleOptionFrame.None_ QStyleOptionFrame.FrameFeature.None_
+QStyleOptionFrame.Flat QStyleOptionFrame.FrameFeature.Flat
+QStyleOptionFrame.Rounded QStyleOptionFrame.FrameFeature.Rounded
+QStyleOptionFrame.Version QStyleOptionFrame.StyleOptionVersion.Version
+QStyleOptionFrame.Type QStyleOptionFrame.StyleOptionType.Type
+QStyleOptionTabWidgetFrame.Version QStyleOptionTabWidgetFrame.StyleOptionVersion.Version
+QStyleOptionTabWidgetFrame.Type QStyleOptionTabWidgetFrame.StyleOptionType.Type
+QTabBar.shape QTabBar.Shape.shape
+QStyleOptionTabBarBase.Version QStyleOptionTabBarBase.StyleOptionVersion.Version
+QStyleOptionTabBarBase.Type QStyleOptionTabBarBase.StyleOptionType.Type
+QTabBar.shape QTabBar.Shape.shape
+QStyleOptionHeader.None_ QStyleOptionHeader.SortIndicator.None_
+QStyleOptionHeader.SortUp QStyleOptionHeader.SortIndicator.SortUp
+QStyleOptionHeader.SortDown QStyleOptionHeader.SortIndicator.SortDown
+QStyleOptionHeader.NotAdjacent QStyleOptionHeader.SelectedPosition.NotAdjacent
+QStyleOptionHeader.NextIsSelected QStyleOptionHeader.SelectedPosition.NextIsSelected
+QStyleOptionHeader.PreviousIsSelected QStyleOptionHeader.SelectedPosition.PreviousIsSelected
+QStyleOptionHeader.NextAndPreviousAreSelected QStyleOptionHeader.SelectedPosition.NextAndPreviousAreSelected
+QStyleOptionHeader.Beginning QStyleOptionHeader.SectionPosition.Beginning
+QStyleOptionHeader.Middle QStyleOptionHeader.SectionPosition.Middle
+QStyleOptionHeader.End QStyleOptionHeader.SectionPosition.End
+QStyleOptionHeader.OnlyOneSection QStyleOptionHeader.SectionPosition.OnlyOneSection
+QStyleOptionHeader.Version QStyleOptionHeader.StyleOptionVersion.Version
+QStyleOptionHeader.Type QStyleOptionHeader.StyleOptionType.Type
+QStyleOptionHeader.position QStyleOptionHeader.SectionPosition.position
+QStyleOptionHeader.selectedPosition QStyleOptionHeader.SelectedPosition.selectedPosition
+QStyleOptionHeader.sortIndicator QStyleOptionHeader.SortIndicator.sortIndicator
+QStyleOptionButton.None_ QStyleOptionButton.ButtonFeature.None_
+QStyleOptionButton.Flat QStyleOptionButton.ButtonFeature.Flat
+QStyleOptionButton.HasMenu QStyleOptionButton.ButtonFeature.HasMenu
+QStyleOptionButton.DefaultButton QStyleOptionButton.ButtonFeature.DefaultButton
+QStyleOptionButton.AutoDefaultButton QStyleOptionButton.ButtonFeature.AutoDefaultButton
+QStyleOptionButton.CommandLinkButton QStyleOptionButton.ButtonFeature.CommandLinkButton
+QStyleOptionButton.Version QStyleOptionButton.StyleOptionVersion.Version
+QStyleOptionButton.Type QStyleOptionButton.StyleOptionType.Type
+QStyleOptionTab.None_ QStyleOptionTab.TabFeature.None_
+QStyleOptionTab.HasFrame QStyleOptionTab.TabFeature.HasFrame
+QStyleOptionTab.NoCornerWidgets QStyleOptionTab.CornerWidget.NoCornerWidgets
+QStyleOptionTab.LeftCornerWidget QStyleOptionTab.CornerWidget.LeftCornerWidget
+QStyleOptionTab.RightCornerWidget QStyleOptionTab.CornerWidget.RightCornerWidget
+QStyleOptionTab.NotAdjacent QStyleOptionTab.SelectedPosition.NotAdjacent
+QStyleOptionTab.NextIsSelected QStyleOptionTab.SelectedPosition.NextIsSelected
+QStyleOptionTab.PreviousIsSelected QStyleOptionTab.SelectedPosition.PreviousIsSelected
+QStyleOptionTab.Beginning QStyleOptionTab.TabPosition.Beginning
+QStyleOptionTab.Middle QStyleOptionTab.TabPosition.Middle
+QStyleOptionTab.End QStyleOptionTab.TabPosition.End
+QStyleOptionTab.OnlyOneTab QStyleOptionTab.TabPosition.OnlyOneTab
+QStyleOptionTab.Version QStyleOptionTab.StyleOptionVersion.Version
+QStyleOptionTab.Type QStyleOptionTab.StyleOptionType.Type
+QStyleOptionTab.position QStyleOptionTab.TabPosition.position
+QStyleOptionTab.selectedPosition QStyleOptionTab.SelectedPosition.selectedPosition
+QTabBar.shape QTabBar.Shape.shape
+QStyleOptionTabV4.Version QStyleOptionTabV4.StyleOptionVersion.Version
+QStyleOptionProgressBar.Version QStyleOptionProgressBar.StyleOptionVersion.Version
+QStyleOptionProgressBar.Type QStyleOptionProgressBar.StyleOptionType.Type
+QStyleOptionMenuItem.NotCheckable QStyleOptionMenuItem.CheckType.NotCheckable
+QStyleOptionMenuItem.Exclusive QStyleOptionMenuItem.CheckType.Exclusive
+QStyleOptionMenuItem.NonExclusive QStyleOptionMenuItem.CheckType.NonExclusive
+QStyleOptionMenuItem.Normal QStyleOptionMenuItem.MenuItemType.Normal
+QStyleOptionMenuItem.DefaultItem QStyleOptionMenuItem.MenuItemType.DefaultItem
+QStyleOptionMenuItem.Separator QStyleOptionMenuItem.MenuItemType.Separator
+QStyleOptionMenuItem.SubMenu QStyleOptionMenuItem.MenuItemType.SubMenu
+QStyleOptionMenuItem.Scroller QStyleOptionMenuItem.MenuItemType.Scroller
+QStyleOptionMenuItem.TearOff QStyleOptionMenuItem.MenuItemType.TearOff
+QStyleOptionMenuItem.Margin QStyleOptionMenuItem.MenuItemType.Margin
+QStyleOptionMenuItem.EmptyArea QStyleOptionMenuItem.MenuItemType.EmptyArea
+QStyleOptionMenuItem.Version QStyleOptionMenuItem.StyleOptionVersion.Version
+QStyleOptionMenuItem.Type QStyleOptionMenuItem.StyleOptionType.Type
+QStyleOptionMenuItem.checkType QStyleOptionMenuItem.CheckType.checkType
+QStyleOptionMenuItem.menuItemType QStyleOptionMenuItem.MenuItemType.menuItemType
+QStyleOptionDockWidget.Version QStyleOptionDockWidget.StyleOptionVersion.Version
+QStyleOptionDockWidget.Type QStyleOptionDockWidget.StyleOptionType.Type
+QStyleOptionViewItem.Invalid QStyleOptionViewItem.ViewItemPosition.Invalid
+QStyleOptionViewItem.Beginning QStyleOptionViewItem.ViewItemPosition.Beginning
+QStyleOptionViewItem.Middle QStyleOptionViewItem.ViewItemPosition.Middle
+QStyleOptionViewItem.End QStyleOptionViewItem.ViewItemPosition.End
+QStyleOptionViewItem.OnlyOne QStyleOptionViewItem.ViewItemPosition.OnlyOne
+QStyleOptionViewItem.None_ QStyleOptionViewItem.ViewItemFeature.None_
+QStyleOptionViewItem.WrapText QStyleOptionViewItem.ViewItemFeature.WrapText
+QStyleOptionViewItem.Alternate QStyleOptionViewItem.ViewItemFeature.Alternate
+QStyleOptionViewItem.HasCheckIndicator QStyleOptionViewItem.ViewItemFeature.HasCheckIndicator
+QStyleOptionViewItem.HasDisplay QStyleOptionViewItem.ViewItemFeature.HasDisplay
+QStyleOptionViewItem.HasDecoration QStyleOptionViewItem.ViewItemFeature.HasDecoration
+QStyleOptionViewItem.Left QStyleOptionViewItem.Position.Left
+QStyleOptionViewItem.Right QStyleOptionViewItem.Position.Right
+QStyleOptionViewItem.Top QStyleOptionViewItem.Position.Top
+QStyleOptionViewItem.Bottom QStyleOptionViewItem.Position.Bottom
+QStyleOptionViewItem.Version QStyleOptionViewItem.StyleOptionVersion.Version
+QStyleOptionViewItem.Type QStyleOptionViewItem.StyleOptionType.Type
+QStyleOptionViewItem.decorationPosition QStyleOptionViewItem.Position.decorationPosition
+QStyleOptionViewItem.viewItemPosition QStyleOptionViewItem.ViewItemPosition.viewItemPosition
+QStyleOptionToolBox.NotAdjacent QStyleOptionToolBox.SelectedPosition.NotAdjacent
+QStyleOptionToolBox.NextIsSelected QStyleOptionToolBox.SelectedPosition.NextIsSelected
+QStyleOptionToolBox.PreviousIsSelected QStyleOptionToolBox.SelectedPosition.PreviousIsSelected
+QStyleOptionToolBox.Beginning QStyleOptionToolBox.TabPosition.Beginning
+QStyleOptionToolBox.Middle QStyleOptionToolBox.TabPosition.Middle
+QStyleOptionToolBox.End QStyleOptionToolBox.TabPosition.End
+QStyleOptionToolBox.OnlyOneTab QStyleOptionToolBox.TabPosition.OnlyOneTab
+QStyleOptionToolBox.Version QStyleOptionToolBox.StyleOptionVersion.Version
+QStyleOptionToolBox.Type QStyleOptionToolBox.StyleOptionType.Type
+QStyleOptionToolBox.position QStyleOptionToolBox.TabPosition.position
+QStyleOptionToolBox.selectedPosition QStyleOptionToolBox.SelectedPosition.selectedPosition
+QStyleOptionRubberBand.Version QStyleOptionRubberBand.StyleOptionVersion.Version
+QStyleOptionRubberBand.Type QStyleOptionRubberBand.StyleOptionType.Type
+QStyleOptionComplex.Version QStyleOptionComplex.StyleOptionVersion.Version
+QStyleOptionComplex.Type QStyleOptionComplex.StyleOptionType.Type
+QStyleOptionSlider.Version QStyleOptionSlider.StyleOptionVersion.Version
+QStyleOptionSlider.Type QStyleOptionSlider.StyleOptionType.Type
+QStyleOptionSpinBox.Version QStyleOptionSpinBox.StyleOptionVersion.Version
+QStyleOptionSpinBox.Type QStyleOptionSpinBox.StyleOptionType.Type
+QStyleOptionToolButton.None_ QStyleOptionToolButton.ToolButtonFeature.None_
+QStyleOptionToolButton.Arrow QStyleOptionToolButton.ToolButtonFeature.Arrow
+QStyleOptionToolButton.Menu QStyleOptionToolButton.ToolButtonFeature.Menu
+QStyleOptionToolButton.PopupDelay QStyleOptionToolButton.ToolButtonFeature.PopupDelay
+QStyleOptionToolButton.MenuButtonPopup QStyleOptionToolButton.ToolButtonFeature.MenuButtonPopup
+QStyleOptionToolButton.HasMenu QStyleOptionToolButton.ToolButtonFeature.HasMenu
+QStyleOptionToolButton.Version QStyleOptionToolButton.StyleOptionVersion.Version
+QStyleOptionToolButton.Type QStyleOptionToolButton.StyleOptionType.Type
+QStyleOptionComboBox.Version QStyleOptionComboBox.StyleOptionVersion.Version
+QStyleOptionComboBox.Type QStyleOptionComboBox.StyleOptionType.Type
+QStyleOptionTitleBar.Version QStyleOptionTitleBar.StyleOptionVersion.Version
+QStyleOptionTitleBar.Type QStyleOptionTitleBar.StyleOptionType.Type
+QStyleHintReturn.Version QStyleHintReturn.StyleOptionVersion.Version
+QStyleHintReturn.Type QStyleHintReturn.StyleOptionType.Type
+QStyleHintReturn.SH_Default QStyleHintReturn.HintReturnType.SH_Default
+QStyleHintReturn.SH_Mask QStyleHintReturn.HintReturnType.SH_Mask
+QStyleHintReturn.SH_Variant QStyleHintReturn.HintReturnType.SH_Variant
+QStyleHintReturnMask.Version QStyleHintReturnMask.StyleOptionVersion.Version
+QStyleHintReturnMask.Type QStyleHintReturnMask.StyleOptionType.Type
+QStyleOptionToolBar.None_ QStyleOptionToolBar.ToolBarFeature.None_
+QStyleOptionToolBar.Movable QStyleOptionToolBar.ToolBarFeature.Movable
+QStyleOptionToolBar.Beginning QStyleOptionToolBar.ToolBarPosition.Beginning
+QStyleOptionToolBar.Middle QStyleOptionToolBar.ToolBarPosition.Middle
+QStyleOptionToolBar.End QStyleOptionToolBar.ToolBarPosition.End
+QStyleOptionToolBar.OnlyOne QStyleOptionToolBar.ToolBarPosition.OnlyOne
+QStyleOptionToolBar.Version QStyleOptionToolBar.StyleOptionVersion.Version
+QStyleOptionToolBar.Type QStyleOptionToolBar.StyleOptionType.Type
+QStyleOptionToolBar.positionOfLine QStyleOptionToolBar.ToolBarPosition.positionOfLine
+QStyleOptionToolBar.positionWithinLine QStyleOptionToolBar.ToolBarPosition.positionWithinLine
+QStyleOptionGroupBox.Version QStyleOptionGroupBox.StyleOptionVersion.Version
+QStyleOptionGroupBox.Type QStyleOptionGroupBox.StyleOptionType.Type
+QStyleOptionSizeGrip.Version QStyleOptionSizeGrip.StyleOptionVersion.Version
+QStyleOptionSizeGrip.Type QStyleOptionSizeGrip.StyleOptionType.Type
+QStyleOptionGraphicsItem.Version QStyleOptionGraphicsItem.StyleOptionVersion.Version
+QStyleOptionGraphicsItem.Type QStyleOptionGraphicsItem.StyleOptionType.Type
+QStyleHintReturnVariant.Version QStyleHintReturnVariant.StyleOptionVersion.Version
+QStyleHintReturnVariant.Type QStyleHintReturnVariant.StyleOptionType.Type
+QSystemTrayIcon.NoIcon QSystemTrayIcon.MessageIcon.NoIcon
+QSystemTrayIcon.Information QSystemTrayIcon.MessageIcon.Information
+QSystemTrayIcon.Warning QSystemTrayIcon.MessageIcon.Warning
+QSystemTrayIcon.Critical QSystemTrayIcon.MessageIcon.Critical
+QSystemTrayIcon.Unknown QSystemTrayIcon.ActivationReason.Unknown
+QSystemTrayIcon.Context QSystemTrayIcon.ActivationReason.Context
+QSystemTrayIcon.DoubleClick QSystemTrayIcon.ActivationReason.DoubleClick
+QSystemTrayIcon.Trigger QSystemTrayIcon.ActivationReason.Trigger
+QSystemTrayIcon.MiddleClick QSystemTrayIcon.ActivationReason.MiddleClick
+QTabBar.SelectLeftTab QTabBar.SelectionBehavior.SelectLeftTab
+QTabBar.SelectRightTab QTabBar.SelectionBehavior.SelectRightTab
+QTabBar.SelectPreviousTab QTabBar.SelectionBehavior.SelectPreviousTab
+QTabBar.LeftSide QTabBar.ButtonPosition.LeftSide
+QTabBar.RightSide QTabBar.ButtonPosition.RightSide
+QTabBar.RoundedNorth QTabBar.Shape.RoundedNorth
+QTabBar.RoundedSouth QTabBar.Shape.RoundedSouth
+QTabBar.RoundedWest QTabBar.Shape.RoundedWest
+QTabBar.RoundedEast QTabBar.Shape.RoundedEast
+QTabBar.TriangularNorth QTabBar.Shape.TriangularNorth
+QTabBar.TriangularSouth QTabBar.Shape.TriangularSouth
+QTabBar.TriangularWest QTabBar.Shape.TriangularWest
+QTabBar.TriangularEast QTabBar.Shape.TriangularEast
+QTableWidgetItem.Type QTableWidgetItem.ItemType.Type
+QTableWidgetItem.UserType QTableWidgetItem.ItemType.UserType
+QTabWidget.Rounded QTabWidget.TabShape.Rounded
+QTabWidget.Triangular QTabWidget.TabShape.Triangular
+QTabWidget.North QTabWidget.TabPosition.North
+QTabWidget.South QTabWidget.TabPosition.South
+QTabWidget.West QTabWidget.TabPosition.West
+QTabWidget.East QTabWidget.TabPosition.East
+QTextEdit.AutoNone QTextEdit.AutoFormattingFlag.AutoNone
+QTextEdit.AutoBulletList QTextEdit.AutoFormattingFlag.AutoBulletList
+QTextEdit.AutoAll QTextEdit.AutoFormattingFlag.AutoAll
+QTextEdit.NoWrap QTextEdit.LineWrapMode.NoWrap
+QTextEdit.WidgetWidth QTextEdit.LineWrapMode.WidgetWidth
+QTextEdit.FixedPixelWidth QTextEdit.LineWrapMode.FixedPixelWidth
+QTextEdit.FixedColumnWidth QTextEdit.LineWrapMode.FixedColumnWidth
+QToolButton.DelayedPopup QToolButton.ToolButtonPopupMode.DelayedPopup
+QToolButton.MenuButtonPopup QToolButton.ToolButtonPopupMode.MenuButtonPopup
+QToolButton.InstantPopup QToolButton.ToolButtonPopupMode.InstantPopup
+QTreeWidgetItem.ShowIndicator QTreeWidgetItem.ChildIndicatorPolicy.ShowIndicator
+QTreeWidgetItem.DontShowIndicator QTreeWidgetItem.ChildIndicatorPolicy.DontShowIndicator
+QTreeWidgetItem.DontShowIndicatorWhenChildless QTreeWidgetItem.ChildIndicatorPolicy.DontShowIndicatorWhenChildless
+QTreeWidgetItem.Type QTreeWidgetItem.ItemType.Type
+QTreeWidgetItem.UserType QTreeWidgetItem.ItemType.UserType
+QTreeWidgetItemIterator.All QTreeWidgetItemIterator.IteratorFlag.All
+QTreeWidgetItemIterator.Hidden QTreeWidgetItemIterator.IteratorFlag.Hidden
+QTreeWidgetItemIterator.NotHidden QTreeWidgetItemIterator.IteratorFlag.NotHidden
+QTreeWidgetItemIterator.Selected QTreeWidgetItemIterator.IteratorFlag.Selected
+QTreeWidgetItemIterator.Unselected QTreeWidgetItemIterator.IteratorFlag.Unselected
+QTreeWidgetItemIterator.Selectable QTreeWidgetItemIterator.IteratorFlag.Selectable
+QTreeWidgetItemIterator.NotSelectable QTreeWidgetItemIterator.IteratorFlag.NotSelectable
+QTreeWidgetItemIterator.DragEnabled QTreeWidgetItemIterator.IteratorFlag.DragEnabled
+QTreeWidgetItemIterator.DragDisabled QTreeWidgetItemIterator.IteratorFlag.DragDisabled
+QTreeWidgetItemIterator.DropEnabled QTreeWidgetItemIterator.IteratorFlag.DropEnabled
+QTreeWidgetItemIterator.DropDisabled QTreeWidgetItemIterator.IteratorFlag.DropDisabled
+QTreeWidgetItemIterator.HasChildren QTreeWidgetItemIterator.IteratorFlag.HasChildren
+QTreeWidgetItemIterator.NoChildren QTreeWidgetItemIterator.IteratorFlag.NoChildren
+QTreeWidgetItemIterator.Checked QTreeWidgetItemIterator.IteratorFlag.Checked
+QTreeWidgetItemIterator.NotChecked QTreeWidgetItemIterator.IteratorFlag.NotChecked
+QTreeWidgetItemIterator.Enabled QTreeWidgetItemIterator.IteratorFlag.Enabled
+QTreeWidgetItemIterator.Disabled QTreeWidgetItemIterator.IteratorFlag.Disabled
+QTreeWidgetItemIterator.Editable QTreeWidgetItemIterator.IteratorFlag.Editable
+QTreeWidgetItemIterator.NotEditable QTreeWidgetItemIterator.IteratorFlag.NotEditable
+QTreeWidgetItemIterator.UserFlag QTreeWidgetItemIterator.IteratorFlag.UserFlag
+QWizard.IndependentPages QWizard.WizardOption.IndependentPages
+QWizard.IgnoreSubTitles QWizard.WizardOption.IgnoreSubTitles
+QWizard.ExtendedWatermarkPixmap QWizard.WizardOption.ExtendedWatermarkPixmap
+QWizard.NoDefaultButton QWizard.WizardOption.NoDefaultButton
+QWizard.NoBackButtonOnStartPage QWizard.WizardOption.NoBackButtonOnStartPage
+QWizard.NoBackButtonOnLastPage QWizard.WizardOption.NoBackButtonOnLastPage
+QWizard.DisabledBackButtonOnLastPage QWizard.WizardOption.DisabledBackButtonOnLastPage
+QWizard.HaveNextButtonOnLastPage QWizard.WizardOption.HaveNextButtonOnLastPage
+QWizard.HaveFinishButtonOnEarlyPages QWizard.WizardOption.HaveFinishButtonOnEarlyPages
+QWizard.NoCancelButton QWizard.WizardOption.NoCancelButton
+QWizard.CancelButtonOnLeft QWizard.WizardOption.CancelButtonOnLeft
+QWizard.HaveHelpButton QWizard.WizardOption.HaveHelpButton
+QWizard.HelpButtonOnRight QWizard.WizardOption.HelpButtonOnRight
+QWizard.HaveCustomButton1 QWizard.WizardOption.HaveCustomButton1
+QWizard.HaveCustomButton2 QWizard.WizardOption.HaveCustomButton2
+QWizard.HaveCustomButton3 QWizard.WizardOption.HaveCustomButton3
+QWizard.NoCancelButtonOnLastPage QWizard.WizardOption.NoCancelButtonOnLastPage
+QWizard.ClassicStyle QWizard.WizardStyle.ClassicStyle
+QWizard.ModernStyle QWizard.WizardStyle.ModernStyle
+QWizard.MacStyle QWizard.WizardStyle.MacStyle
+QWizard.AeroStyle QWizard.WizardStyle.AeroStyle
+QWizard.WatermarkPixmap QWizard.WizardPixmap.WatermarkPixmap
+QWizard.LogoPixmap QWizard.WizardPixmap.LogoPixmap
+QWizard.BannerPixmap QWizard.WizardPixmap.BannerPixmap
+QWizard.BackgroundPixmap QWizard.WizardPixmap.BackgroundPixmap
+QWizard.BackButton QWizard.WizardButton.BackButton
+QWizard.NextButton QWizard.WizardButton.NextButton
+QWizard.CommitButton QWizard.WizardButton.CommitButton
+QWizard.FinishButton QWizard.WizardButton.FinishButton
+QWizard.CancelButton QWizard.WizardButton.CancelButton
+QWizard.HelpButton QWizard.WizardButton.HelpButton
+QWizard.CustomButton1 QWizard.WizardButton.CustomButton1
+QWizard.CustomButton2 QWizard.WizardButton.CustomButton2
+QWizard.CustomButton3 QWizard.WizardButton.CustomButton3
+QWizard.Stretch QWizard.WizardButton.Stretch
+QDomImplementation.AcceptInvalidChars QDomImplementation.InvalidDataPolicy.AcceptInvalidChars
+QDomImplementation.DropInvalidChars QDomImplementation.InvalidDataPolicy.DropInvalidChars
+QDomImplementation.ReturnNullNode QDomImplementation.InvalidDataPolicy.ReturnNullNode
+QDomNode.EncodingFromDocument QDomNode.EncodingPolicy.EncodingFromDocument
+QDomNode.EncodingFromTextStream QDomNode.EncodingPolicy.EncodingFromTextStream
+QDomNode.ElementNode QDomNode.NodeType.ElementNode
+QDomNode.AttributeNode QDomNode.NodeType.AttributeNode
+QDomNode.TextNode QDomNode.NodeType.TextNode
+QDomNode.CDATASectionNode QDomNode.NodeType.CDATASectionNode
+QDomNode.EntityReferenceNode QDomNode.NodeType.EntityReferenceNode
+QDomNode.EntityNode QDomNode.NodeType.EntityNode
+QDomNode.ProcessingInstructionNode QDomNode.NodeType.ProcessingInstructionNode
+QDomNode.CommentNode QDomNode.NodeType.CommentNode
+QDomNode.DocumentNode QDomNode.NodeType.DocumentNode
+QDomNode.DocumentTypeNode QDomNode.NodeType.DocumentTypeNode
+QDomNode.DocumentFragmentNode QDomNode.NodeType.DocumentFragmentNode
+QDomNode.NotationNode QDomNode.NodeType.NotationNode
+QDomNode.BaseNode QDomNode.NodeType.BaseNode
+QDomNode.CharacterDataNode QDomNode.NodeType.CharacterDataNode
+QXmlNodeModelIndex.Precedes QXmlNodeModelIndex.DocumentOrder.Precedes
+QXmlNodeModelIndex.Is QXmlNodeModelIndex.DocumentOrder.Is
+QXmlNodeModelIndex.Follows QXmlNodeModelIndex.DocumentOrder.Follows
+QXmlNodeModelIndex.Attribute QXmlNodeModelIndex.NodeKind.Attribute
+QXmlNodeModelIndex.Comment QXmlNodeModelIndex.NodeKind.Comment
+QXmlNodeModelIndex.Document QXmlNodeModelIndex.NodeKind.Document
+QXmlNodeModelIndex.Element QXmlNodeModelIndex.NodeKind.Element
+QXmlNodeModelIndex.Namespace QXmlNodeModelIndex.NodeKind.Namespace
+QXmlNodeModelIndex.ProcessingInstruction QXmlNodeModelIndex.NodeKind.ProcessingInstruction
+QXmlNodeModelIndex.Text QXmlNodeModelIndex.NodeKind.Text
+QAbstractXmlNodeModel.Parent QAbstractXmlNodeModel.SimpleAxis.Parent
+QAbstractXmlNodeModel.FirstChild QAbstractXmlNodeModel.SimpleAxis.FirstChild
+QAbstractXmlNodeModel.PreviousSibling QAbstractXmlNodeModel.SimpleAxis.PreviousSibling
+QAbstractXmlNodeModel.NextSibling QAbstractXmlNodeModel.SimpleAxis.NextSibling
+QXmlQuery.XQuery10 QXmlQuery.QueryLanguage.XQuery10
+QXmlQuery.XSLT20 QXmlQuery.QueryLanguage.XSLT20
diff --git a/scripts/dev/misc_checks.py b/scripts/dev/misc_checks.py
index d7beb80b8..998929827 100644
--- a/scripts/dev/misc_checks.py
+++ b/scripts/dev/misc_checks.py
@@ -266,6 +266,7 @@ def check_spelling(args: argparse.Namespace) -> Optional[bool]:
hint_data = pathlib.Path('tests', 'end2end', 'data', 'hints')
ignored = [
pathlib.Path('scripts', 'dev', 'misc_checks.py'),
+ pathlib.Path('scripts', 'dev', 'enums.txt'),
pathlib.Path('qutebrowser', '3rdparty', 'pdfjs'),
hint_data / 'ace' / 'ace.js',
hint_data / 'bootstrap' / 'bootstrap.css',
@@ -284,6 +285,38 @@ def check_spelling(args: argparse.Namespace) -> Optional[bool]:
return None
+def check_pyqt_imports(args: argparse.Namespace) -> Optional[bool]:
+ """Check for direct PyQt imports."""
+ ignored = [
+ pathlib.Path("qutebrowser", "qt"),
+ # FIXME:qt6 fix those too?
+ pathlib.Path("misc", "userscripts"),
+ pathlib.Path("scripts"),
+ ]
+ patterns = [
+ (
+ re.compile(r"from PyQt.* import"),
+ "Use 'from qutebrowser.qt.MODULE import ...' instead",
+ ),
+ (
+ re.compile(r"import PyQt.*"),
+ "Use 'import qutebrowser.qt.MODULE' instead",
+ )
+ ]
+ # FIXME:qt6 unify this with check_spelling somehow?
+ try:
+ ok = True
+ for path in _get_files(verbose=args.verbose, ignored=ignored):
+ with tokenize.open(str(path)) as f:
+ if not _check_spelling_file(path, f, patterns):
+ ok = False
+ print()
+ return ok
+ except Exception:
+ traceback.print_exc()
+ return None
+
+
def check_vcs_conflict(args: argparse.Namespace) -> Optional[bool]:
"""Check VCS conflict markers."""
try:
@@ -371,6 +404,7 @@ def main() -> int:
'git': check_git,
'vcs': check_vcs_conflict,
'spelling': check_spelling,
+ 'pyqt-imports': check_pyqt_imports,
'userscript-descriptions': check_userscripts_descriptions,
'userscript-shebangs': check_userscript_shebangs,
'changelog-urls': check_changelog_urls,
diff --git a/scripts/dev/rewrite_enums.py b/scripts/dev/rewrite_enums.py
new file mode 100644
index 000000000..cb3dedbd1
--- /dev/null
+++ b/scripts/dev/rewrite_enums.py
@@ -0,0 +1,45 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+
+# Copyright 2021-2022 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
+#
+# This file is part of qutebrowser.
+#
+# qutebrowser is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# qutebrowser is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+
+"""Rewrite PyQt enums based on rewrite_find_enums.py output."""
+
+
+import pathlib
+import sys
+import re
+
+script_path = pathlib.Path(__file__).parent
+
+replacements = []
+with (script_path / 'enums.txt').open(encoding="utf-8") as f:
+ for line in f:
+ orig, replacement = line.split()
+ orig_re = re.compile(re.escape(orig) + r'(?=\W)')
+ replacements.append((orig_re, replacement))
+
+
+for filename in sys.argv[1:]:
+ path = pathlib.Path(filename)
+ if path.suffix != '.py':
+ continue
+ content = path.read_text(encoding="utf-8")
+ print(filename)
+ for orig_re, replacement in replacements:
+ content = orig_re.sub(replacement, content)
+ path.write_text(content, encoding="utf-8")
diff --git a/scripts/dev/rewrite_find_enums.py b/scripts/dev/rewrite_find_enums.py
new file mode 100644
index 000000000..2ea7e81c6
--- /dev/null
+++ b/scripts/dev/rewrite_find_enums.py
@@ -0,0 +1,67 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+
+# Copyright 2021-2022 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
+#
+# This file is part of qutebrowser.
+#
+# qutebrowser is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# qutebrowser is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+
+
+"""Find all PyQt enum instances."""
+
+
+import pathlib
+import ast
+
+import PyQt5
+
+
+def find_enums(tree):
+ """Find all PyQt enums in an AST tree."""
+ for node in ast.walk(tree):
+ if not isinstance(node, ast.Assign):
+ continue
+ if node.type_comment is None:
+ continue
+ if '.' not in node.type_comment:
+ continue
+ if not node.type_comment.startswith("Q"):
+ continue
+ comment = node.type_comment.strip("'")
+ mod, cls = comment.rsplit(".", maxsplit=1)
+ assert len(node.targets) == 1
+ name = node.targets[0].id
+ yield (mod, cls, name)
+
+
+def main():
+ pyqt5_path = pathlib.Path(PyQt5.__file__).parent
+ pyi_files = list(pyqt5_path.glob("*.pyi"))
+ if not pyi_files:
+ print("No .pyi-files found for your PyQt installation!")
+ for path in pyi_files:
+ print(f"# {path.stem}")
+ tree = ast.parse(
+ path.read_text(),
+ filename=str(path),
+ type_comments=True,
+ )
+ for mod, cls, name in find_enums(tree):
+ old = f"{mod}.{name}"
+ new = f"{mod}.{cls}.{name}"
+ print(f"{old} {new}")
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/dev/rewrite_find_flags.py b/scripts/dev/rewrite_find_flags.py
new file mode 100644
index 000000000..79436f4c8
--- /dev/null
+++ b/scripts/dev/rewrite_find_flags.py
@@ -0,0 +1,83 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+
+# Copyright 2021-2022 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
+#
+# This file is part of qutebrowser.
+#
+# qutebrowser is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# qutebrowser is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+
+
+"""Find all PyQt flag instances."""
+
+import pathlib
+import ast
+
+import PyQt5
+
+
+def find_flags(tree):
+ """Find all PyQt flags in an AST tree."""
+ for node in ast.walk(tree):
+ if not isinstance(node, ast.FunctionDef):
+ continue
+ if node.name != "__init__":
+ continue
+
+ if len(node.args.args) == 1:
+ continue
+
+ annotation = node.args.args[1].annotation
+
+ if not isinstance(annotation, ast.Subscript):
+ continue
+
+ assert isinstance(annotation.value, ast.Attribute)
+ assert isinstance(annotation.value.value, ast.Name)
+ assert annotation.value.value.id == "typing"
+ if annotation.value.attr != "Union":
+ continue
+
+ assert isinstance(annotation.slice, ast.Tuple)
+ elts = annotation.slice.elts
+
+ if not all(isinstance(n, ast.Constant) for n in elts):
+ continue
+
+ names = [n.value for n in elts]
+ if not all("." in name for name in names):
+ continue
+
+ yield names
+
+
+def main():
+ pyqt5_path = pathlib.Path(PyQt5.__file__).parent
+ pyi_files = list(pyqt5_path.glob("*.pyi"))
+ if not pyi_files:
+ print("No .pyi-files found for your PyQt installation!")
+ for path in pyi_files:
+ #print(f"# {path.stem}")
+
+ tree = ast.parse(
+ path.read_text(),
+ filename=str(path),
+ type_comments=True,
+ )
+
+ for flag, enum in find_flags(tree):
+ print(flag, enum)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/dev/rewrite_qt_imports.sh b/scripts/dev/rewrite_qt_imports.sh
new file mode 100644
index 000000000..d655c297a
--- /dev/null
+++ b/scripts/dev/rewrite_qt_imports.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+fd -g '*.py' -E 'qt' qutebrowser/ tests/ | xargs sed -i \
+ -e 's/from PyQt5 import QtCore/from qutebrowser.qt import core as QtCore/' \
+ -e 's/from PyQt5 import QtWebEngine/from qutebrowser.qt import webengine as QtWebEngine/' \
+ -e 's/from PyQt5 import QtWebEngineWidgets/from qutebrowser.qt import webenginewidgets as QtWebEngineWidgets/' \
+ -e 's/from PyQt5 import QtWebKit/from qutebrowser.qt import webkit as QtWebKit/' \
+ -e 's/from PyQt5 import QtWebKitWidgets/from qutebrowser.qt import webkitwidgets as QtWebKitWidgets/' \
+ -e 's/from PyQt5.QtCore/from qutebrowser.qt.core/' \
+ -e 's/from PyQt5.QtGui/from qutebrowser.qt.gui/' \
+ -e 's/from PyQt5.QtNetwork/from qutebrowser.qt.network/' \
+ -e 's/from PyQt5.QtWebEngineCore/from qutebrowser.qt.webenginecore/' \
+ -e 's/from PyQt5.QtWebEngineWidgets/from qutebrowser.qt.webenginewidgets/' \
+ -e 's/from PyQt5.QtWebEngine/from qutebrowser.qt.webengine/' \
+ -e 's/from PyQt5.QtWebKitWidgets/from qutebrowser.qt.webkitwidgets/' \
+ -e 's/from PyQt5.QtWebKit/from qutebrowser.qt.webkit/' \
+ -e 's/from PyQt5.QtWidgets/from qutebrowser.qt.widgets/' \
+ -e 's/from PyQt5.QtPrintSupport/from qutebrowser.qt.printsupport/' \
+ -e 's/from PyQt5.QtQml/from qutebrowser.qt.qml/' \
+ -e 's/from PyQt5.QtSql/from qutebrowser.qt.sql/' \
+ -e 's/from PyQt5.QtTest/from qutebrowser.qt.test/' \
+ -e 's/from PyQt5.QtDBus/from qutebrowser.qt.dbus/'
diff --git a/scripts/dev/run_vulture.py b/scripts/dev/run_vulture.py
index 1f0018488..1e71b08d2 100755
--- a/scripts/dev/run_vulture.py
+++ b/scripts/dev/run_vulture.py
@@ -31,8 +31,8 @@ import vulture
import qutebrowser.app # pylint: disable=unused-import
from qutebrowser.extensions import loader
-from qutebrowser.misc import objects
-from qutebrowser.utils import utils, version
+from qutebrowser.misc import objects, sql
+from qutebrowser.utils import utils, version, qtutils
# To run the decorators from there
# pylint: disable=unused-import
from qutebrowser.browser.webkit.network import webkitqutescheme
@@ -146,6 +146,13 @@ def whitelist_generator(): # noqa: C901
for name in ['addr', 'addralign', 'entsize']:
yield f'qutebrowser.misc.elf.SectionHeader.{name}'
+ # For completeness
+ for name in list(qtutils.LibraryPath):
+ yield f'qutebrowser.utils.qtutils.LibraryPath.{name}'
+
+ for name in list(sql.SqliteErrorCode):
+ yield f'qutebrowser.misc.sql.SqliteErrorCode.{name}'
+
def filter_func(item):
"""Check if a missing function should be filtered or not.
diff --git a/scripts/link_pyqt.py b/scripts/link_pyqt.py
index 0ec7f2556..e27a54a68 100644
--- a/scripts/link_pyqt.py
+++ b/scripts/link_pyqt.py
@@ -126,15 +126,19 @@ def get_lib_path(executable, name, required=True):
raise ValueError("Unexpected output: {!r}".format(output))
-def link_pyqt(executable, venv_path):
+def link_pyqt(executable, venv_path, *, version='5'):
"""Symlink the systemwide PyQt/sip into the venv.
Args:
executable: The python executable where the source files are present.
venv_path: The path to the virtualenv site-packages.
+ version: The PyQt version to use.
"""
+ if version not in ["5", "6"]:
+ raise ValueError(f"Invalid version {version}")
+
try:
- get_lib_path(executable, 'PyQt5.sip')
+ get_lib_path(executable, f'PyQt{version}.sip')
except Error:
# There is no PyQt5.sip, so we need to copy the toplevel sip.
sip_file = get_lib_path(executable, 'sip')
@@ -143,7 +147,7 @@ def link_pyqt(executable, venv_path):
sip_file = None
sipconfig_file = get_lib_path(executable, 'sipconfig', required=False)
- pyqt_dir = os.path.dirname(get_lib_path(executable, 'PyQt5.QtCore'))
+ pyqt_dir = os.path.dirname(get_lib_path(executable, f'PyQt{version}.QtCore'))
for path in [sip_file, sipconfig_file, pyqt_dir]:
if path is None:
@@ -211,14 +215,7 @@ def main():
action='store_true')
args = parser.parse_args()
- if args.tox:
- # Workaround for the lack of negative factors in tox.ini
- if 'LINK_PYQT_SKIP' in os.environ:
- print('LINK_PYQT_SKIP set, exiting...')
- sys.exit(0)
- executable = get_tox_syspython(args.path)
- else:
- executable = sys.executable
+ executable = get_tox_syspython(args.path) if args.tox else sys.executable
venv_path = get_venv_lib_path(args.path)
link_pyqt(executable, venv_path)
diff --git a/scripts/mkvenv.py b/scripts/mkvenv.py
index 08174abc4..cd75874fc 100755
--- a/scripts/mkvenv.py
+++ b/scripts/mkvenv.py
@@ -38,6 +38,14 @@ from scripts import utils, link_pyqt
REPO_ROOT = pathlib.Path(__file__).parent.parent
+# for --only-binary / --no-binary
+PYQT_PACKAGES = [
+ "PyQt5",
+ "PyQtWebEngine",
+
+ "PyQt6",
+ "PyQt6-WebEngine",
+]
class Error(Exception):
@@ -78,6 +86,9 @@ def parse_args(argv: List[str] = None) -> argparse.Namespace:
parser.add_argument('--pyqt-wheels-dir',
default='wheels',
help="Directory to get PyQt wheels from.")
+ parser.add_argument('--pyqt-snapshot',
+ help="Comma-separated list to install from the Riverbank "
+ "PyQt snapshot server")
parser.add_argument('--virtualenv',
action='store_true',
help="Use virtualenv instead of venv.")
@@ -105,7 +116,7 @@ def _version_key(v):
try:
return tuple(int(v) for c in v.split('.'))
except ValueError:
- return 999
+ return (999,)
def pyqt_versions() -> List[str]:
@@ -123,6 +134,12 @@ def pyqt_versions() -> List[str]:
return versions + ['auto']
+def _is_qt6_version(version: str) -> bool:
+ """Check if the given version is Qt 6."""
+ # FIXME:qt6 Adjust once auto = Qt 6
+ return version == "6" or version.startswith("6.")
+
+
def run_venv(
venv_dir: pathlib.Path,
executable,
@@ -223,38 +240,46 @@ def install_pyqt_binary(venv_dir: pathlib.Path, version: str) -> None:
utils.print_col("No proprietary codec support will be available in "
"qutebrowser.", 'bold')
- supported_archs = {
- 'linux': {'x86_64'},
- 'win32': {'x86', 'AMD64'},
- 'darwin': {'x86_64'},
- }
+ if _is_qt6_version(version):
+ supported_archs = {
+ 'linux': {'x86_64'},
+ 'win32': {'AMD64'},
+ 'darwin': {'x86_64', 'arm64'},
+ }
+ else:
+ supported_archs = {
+ 'linux': {'x86_64'},
+ 'win32': {'x86', 'AMD64'},
+ 'darwin': {'x86_64'},
+ }
+
if sys.platform not in supported_archs:
- utils.print_error(f"{sys.platform} is not a supported platform by PyQt5 binary "
+ utils.print_error(f"{sys.platform} is not a supported platform by PyQt binary "
"packages, this will most likely fail.")
elif platform.machine() not in supported_archs[sys.platform]:
utils.print_error(
- f"{platform.machine()} is not a supported architecture for PyQt5 binaries "
+ f"{platform.machine()} is not a supported architecture for PyQt binaries "
f"on {sys.platform}, this will most likely fail.")
elif sys.platform == 'linux' and platform.libc_ver()[0] != 'glibc':
- utils.print_error("Non-glibc Linux is not a supported platform for PyQt5 "
+ utils.print_error("Non-glibc Linux is not a supported platform for PyQt "
"binaries, this will most likely fail.")
pip_install(venv_dir, '-r', pyqt_requirements_file(version),
- '--only-binary', 'PyQt5,PyQtWebEngine')
+ '--only-binary', ','.join(PYQT_PACKAGES))
def install_pyqt_source(venv_dir: pathlib.Path, version: str) -> None:
"""Install PyQt from the source tarball."""
utils.print_title("Installing PyQt from sources")
pip_install(venv_dir, '-r', pyqt_requirements_file(version),
- '--verbose', '--no-binary', 'PyQt5,PyQtWebEngine')
+ '--verbose', '--no-binary', ','.join(PYQT_PACKAGES))
-def install_pyqt_link(venv_dir: pathlib.Path) -> None:
+def install_pyqt_link(venv_dir: pathlib.Path, version: str) -> None:
"""Install PyQt by linking a system-wide install."""
utils.print_title("Linking system-wide PyQt")
lib_path = link_pyqt.get_venv_lib_path(str(venv_dir))
- link_pyqt.link_pyqt(sys.executable, lib_path)
+ link_pyqt.link_pyqt(sys.executable, lib_path, version=version)
def install_pyqt_wheels(venv_dir: pathlib.Path,
@@ -265,6 +290,13 @@ def install_pyqt_wheels(venv_dir: pathlib.Path,
pip_install(venv_dir, *wheels)
+def install_pyqt_shapshot(venv_dir: pathlib.Path, packages: List[str]) -> None:
+ """Install PyQt packages from the snapshot server."""
+ utils.print_title("Installing PyQt snapshots")
+ pip_install(venv_dir, '-U', *packages, '--no-deps', '--pre',
+ '--index-url', 'https://riverbankcomputing.com/pypi/simple/')
+
+
def apply_xcb_util_workaround(
venv_dir: pathlib.Path,
pyqt_type: str,
@@ -282,7 +314,7 @@ def apply_xcb_util_workaround(
if pyqt_type != 'binary':
print("Workaround not needed: Not installing from PyQt binaries.")
return
- if pyqt_version not in ['auto', '5.15']:
+ if _is_qt6_version(pyqt_version):
print("Workaround not needed: Not installing Qt 5.15.")
return
@@ -363,13 +395,13 @@ def _find_libs() -> Dict[Tuple[str, str], List[str]]:
return all_libs
-def run_qt_smoke_test(venv_dir: pathlib.Path) -> None:
+def run_qt_smoke_test_single(venv_dir: pathlib.Path, *, debug: bool) -> None:
"""Make sure the Qt installation works."""
utils.print_title("Running Qt smoke test")
code = [
'import sys',
- 'from PyQt5.QtWidgets import QApplication',
- 'from PyQt5.QtCore import qVersion, QT_VERSION_STR, PYQT_VERSION_STR',
+ 'from qutebrowser.qt.widgets import QApplication',
+ 'from qutebrowser.qt.core import qVersion, QT_VERSION_STR, PYQT_VERSION_STR',
'print(f"Python: {sys.version}")',
'print(f"qVersion: {qVersion()}")',
'print(f"QT_VERSION_STR: {QT_VERSION_STR}")',
@@ -382,16 +414,35 @@ def run_qt_smoke_test(venv_dir: pathlib.Path) -> None:
run_venv(
venv_dir,
'python', '-c', '; '.join(code),
- env={'QT_DEBUG_PLUGINS': '1'},
+ env={'QT_DEBUG_PLUGINS': '1'} if debug else {},
capture_error=True
)
except Error as e:
proc_e = e.__cause__
assert isinstance(proc_e, subprocess.CalledProcessError), proc_e
print(proc_e.stderr)
- raise Error(
- f"Smoke test failed with status {proc_e.returncode}. "
- "You might find additional information in the debug output above.")
+
+ msg = f"Smoke test failed with status {proc_e.returncode}."
+ if debug:
+ msg += " You might find additional information in the debug output above."
+ raise Error(msg)
+
+
+def run_qt_smoke_test(venv_dir: pathlib.Path, *, pyqt_version: str) -> None:
+ """Make sure the Qt installation works."""
+ # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-104415
+ no_debug = pyqt_version in ("6.3", "6") and sys.platform == "darwin"
+ if no_debug:
+ try:
+ run_qt_smoke_test_single(venv_dir, debug=False)
+ except Error as e:
+ print(e)
+ print("Rerunning with debug output...")
+ print("NOTE: This will likely segfault due to a Qt bug:")
+ print("https://bugreports.qt.io/browse/QTBUG-104415")
+ run_qt_smoke_test_single(venv_dir, debug=True)
+ else:
+ run_qt_smoke_test_single(venv_dir, debug=True)
def install_requirements(venv_dir: pathlib.Path) -> None:
@@ -444,10 +495,12 @@ def install_pyqt(venv_dir, args):
"""Install PyQt in the virtualenv."""
if args.pyqt_type == 'binary':
install_pyqt_binary(venv_dir, args.pyqt_version)
+ if args.pyqt_snapshot:
+ install_pyqt_shapshot(venv_dir, args.pyqt_snapshot.split(','))
elif args.pyqt_type == 'source':
install_pyqt_source(venv_dir, args.pyqt_version)
elif args.pyqt_type == 'link':
- install_pyqt_link(venv_dir)
+ install_pyqt_link(venv_dir, args.pyqt_version)
elif args.pyqt_type == 'wheels':
wheels_dir = pathlib.Path(args.pyqt_wheels_dir)
install_pyqt_wheels(venv_dir, wheels_dir)
@@ -463,13 +516,19 @@ def run(args) -> None:
utils.change_cwd()
if (args.pyqt_version != 'auto' and
- args.pyqt_type not in ['binary', 'source']):
+ args.pyqt_type not in ['binary', 'source', 'link']):
raise Error('The --pyqt-version option is only available when installing PyQt '
- 'from binary or source')
+ 'from binary, source, or linking it')
+ if args.pyqt_type == 'link' and args.pyqt_version not in ['auto', '5', '6']:
+ raise Error('Invalid --pyqt-version {args.pyqt_version}, only 5 or 6 '
+ 'permitted with --pyqt-type=link')
if args.pyqt_wheels_dir != 'wheels' and args.pyqt_type != 'wheels':
raise Error('The --pyqt-wheels-dir option is only available when installing '
'PyQt from wheels')
+ if args.pyqt_snapshot and args.pyqt_type != 'binary':
+ raise Error('The --pyqt-snapshot option is only available when installing '
+ 'PyQt from binaries')
if args.update:
utils.print_title("Updating repository")
@@ -484,14 +543,14 @@ def run(args) -> None:
install_pyqt(venv_dir, args)
apply_xcb_util_workaround(venv_dir, args.pyqt_type, args.pyqt_version)
- if args.pyqt_type != 'skip' and not args.skip_smoke_test:
- run_qt_smoke_test(venv_dir)
install_requirements(venv_dir)
install_qutebrowser(venv_dir)
if args.dev:
install_dev_requirements(venv_dir)
+ if args.pyqt_type != 'skip' and not args.skip_smoke_test:
+ run_qt_smoke_test(venv_dir, pyqt_version=args.pyqt_version)
if not args.skip_docs:
regenerate_docs(venv_dir)
diff --git a/scripts/testbrowser/testbrowser_webengine.py b/scripts/testbrowser/testbrowser_webengine.py
index 73fa6828e..4351d1f7f 100755
--- a/scripts/testbrowser/testbrowser_webengine.py
+++ b/scripts/testbrowser/testbrowser_webengine.py
@@ -23,9 +23,16 @@
import sys
import argparse
-from PyQt5.QtCore import QUrl
-from PyQt5.QtWidgets import QApplication
-from PyQt5.QtWebEngineWidgets import QWebEngineView
+try:
+ from PyQt6.QtCore import QUrl
+ from PyQt6.QtWidgets import QApplication
+ from PyQt6.QtWebEngineWidgets import QWebEngineView
+ print("Using PyQt6")
+except ImportError:
+ from PyQt5.QtCore import QUrl
+ from PyQt5.QtWidgets import QApplication
+ from PyQt5.QtWebEngineWidgets import QWebEngineView
+ print("Using PyQt5")
def parse_args():
diff --git a/tests/conftest.py b/tests/conftest.py
index 193b5bb5f..f875ac3d9 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -39,6 +39,7 @@ from helpers import testutils
from qutebrowser.utils import usertypes, utils, version
from qutebrowser.misc import objects, earlyinit
+from qutebrowser.qt import machinery
# To register commands
import qutebrowser.app # pylint: disable=unused-import
@@ -112,6 +113,16 @@ def _apply_platform_markers(config, item):
pytest.mark.skipif,
sys.getfilesystemencoding() == 'ascii',
"Skipped because of ASCII locale"),
+ ('qt5_only',
+ pytest.mark.skipif,
+ not machinery.IS_QT5,
+ f"Only runs on Qt 5, not {machinery.WRAPPER}"),
+ ('qt6_only',
+ pytest.mark.skipif,
+ not machinery.IS_QT6,
+ f"Only runs on Qt 6, not {machinery.WRAPPER}"),
+ ('qt5_xfail', pytest.mark.xfail, machinery.IS_QT5, "Fails on Qt 5"),
+ ('qt6_xfail', pytest.mark.skipif, machinery.IS_QT6, "Fails on Qt 6"),
('qtwebkit_openssl3_skip',
pytest.mark.skipif,
not config.webengine and ssl.OPENSSL_VERSION_INFO[0] == 3,
@@ -213,7 +224,9 @@ def qapp(qapp):
def pytest_addoption(parser):
parser.addoption('--qute-delay', action='store', default=0, type=int,
- help="Delay between qutebrowser commands.")
+ help="Delay (in ms) between qutebrowser commands.")
+ parser.addoption('--qute-delay-start', action='store', default=0, type=int,
+ help="Delay (in ms) after qutebrowser process started.")
parser.addoption('--qute-profile-subprocs', action='store_true',
default=False, help="Run cProfile for subprocesses.")
parser.addoption('--qute-backend', action='store',
@@ -255,9 +268,9 @@ def _select_backend(config):
# Fail early if selected backend is not available
# pylint: disable=unused-import
if backend == 'webkit':
- import PyQt5.QtWebKitWidgets
+ import qutebrowser.qt.webkitwidgets
elif backend == 'webengine':
- import PyQt5.QtWebEngineWidgets
+ import qutebrowser.qt.webenginewidgets
else:
raise utils.Unreachable(backend)
@@ -268,12 +281,12 @@ def _auto_select_backend():
# pylint: disable=unused-import
try:
# Try to use QtWebKit as the default backend
- import PyQt5.QtWebKitWidgets
+ import qutebrowser.qt.webkitwidgets
return 'webkit'
except ImportError:
# Try to use QtWebEngine as a fallback and fail early
# if that's also not available
- import PyQt5.QtWebEngineWidgets
+ import qutebrowser.qt.webenginewidgets
return 'webengine'
diff --git a/tests/end2end/conftest.py b/tests/end2end/conftest.py
index 5241ab4c3..bdc172857 100644
--- a/tests/end2end/conftest.py
+++ b/tests/end2end/conftest.py
@@ -27,7 +27,7 @@ import pstats
import operator
import pytest
-from PyQt5.QtCore import PYQT_VERSION, QCoreApplication
+from qutebrowser.qt.core import PYQT_VERSION, QCoreApplication
pytest.register_assert_rewrite('end2end.fixtures')
@@ -119,8 +119,9 @@ def _get_version_tag(tag):
)
elif package == 'pyqtwebengine':
try:
- from PyQt5.QtWebEngine import PYQT_WEBENGINE_VERSION
+ from qutebrowser.qt.webenginecore import PYQT_WEBENGINE_VERSION
except ImportError:
+ # QtWebKit
running_version = PYQT_VERSION
else:
running_version = PYQT_WEBENGINE_VERSION
@@ -152,7 +153,6 @@ def _get_backend_tag(tag):
pytest_marks = {
'qtwebengine_todo': pytest.mark.qtwebengine_todo,
'qtwebengine_skip': pytest.mark.qtwebengine_skip,
- 'qtwebengine_notifications': pytest.mark.qtwebengine_notifications,
'qtwebkit_skip': pytest.mark.qtwebkit_skip,
}
if not any(tag.startswith(t + ':') for t in pytest_marks):
@@ -179,10 +179,6 @@ if not getattr(sys, 'frozen', False):
def pytest_collection_modifyitems(config, items):
"""Apply @qtwebengine_* markers."""
- # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-75884
- # (note this isn't actually fixed properly before Qt 5.15)
- header_bug_fixed = qtutils.version_check('5.15', compiled=False)
-
lib_path = pathlib.Path(QCoreApplication.libraryPaths()[0])
qpdf_image_plugin = lib_path / 'imageformats' / 'libqpdf.so'
@@ -191,19 +187,12 @@ def pytest_collection_modifyitems(config, items):
config.webengine),
('qtwebengine_skip', 'Skipped with QtWebEngine', pytest.mark.skipif,
config.webengine),
- ('qtwebengine_notifications',
- 'Skipped unless QtWebEngine >= 5.13',
- pytest.mark.skipif,
- not (config.webengine and qtutils.version_check('5.13'))),
('qtwebkit_skip', 'Skipped with QtWebKit', pytest.mark.skipif,
not config.webengine),
('qtwebengine_flaky', 'Flaky with QtWebEngine', pytest.mark.skipif,
config.webengine),
('qtwebengine_mac_xfail', 'Fails on macOS with QtWebEngine',
pytest.mark.xfail, config.webengine and utils.is_mac),
- ('js_headers', 'Sets headers dynamically via JS',
- pytest.mark.skipif,
- config.webengine and not header_bug_fixed),
('qtwebkit_pdf_imageformat_skip',
'Skipped with QtWebKit if PDF image plugin is available',
pytest.mark.skipif,
diff --git a/tests/end2end/features/conftest.py b/tests/end2end/features/conftest.py
index d0caf46b9..43d953b26 100644
--- a/tests/end2end/features/conftest.py
+++ b/tests/end2end/features/conftest.py
@@ -35,8 +35,9 @@ import pytest
import pytest_bdd as bdd
import qutebrowser
-from qutebrowser.utils import log, utils, docutils
+from qutebrowser.utils import log, utils, docutils, version
from qutebrowser.browser import pdfjs
+from end2end.fixtures import testprocess
from helpers import testutils
@@ -194,6 +195,7 @@ def pdfjs_available(data_tmpdir):
@bdd.given('I clear the log')
+@bdd.when('I clear the log')
def clear_log_lines(quteproc):
quteproc.clear_data()
@@ -436,6 +438,20 @@ def update_documentation():
subprocess.run([sys.executable, update_script], check=True)
+@bdd.when("I wait until PDF.js is ready")
+def wait_pdfjs(quteproc):
+ quteproc.wait_for(message="load status for <qutebrowser.browser.* "
+ "tab_id=* url='qute://pdfjs/web/viewer.html?*'>: LoadStatus.success")
+ try:
+ quteproc.wait_for(message="JS: [qute://pdfjs/web/viewer.html?*] Uncaught TypeError: Cannot read property 'set' of undefined", timeout=100)
+ except testprocess.WaitForTimeout:
+ pass
+ else:
+ pytest.skip(f"Non-legacy PDF.js installation: {version._pdfjs_version()}")
+
+ quteproc.wait_for(message="[qute://pdfjs/*] PDF * (PDF.js: *)")
+
+
## Then
diff --git a/tests/end2end/features/downloads.feature b/tests/end2end/features/downloads.feature
index a1af893b6..47835fd79 100644
--- a/tests/end2end/features/downloads.feature
+++ b/tests/end2end/features/downloads.feature
@@ -61,7 +61,7 @@ Feature: Downloading things from a website.
And I open data/downloads/issue889.html
And I hint with args "links download" and follow a
And I run :tab-close
- And I wait for "* Handling redirect" in the log
+ And I wait for "redirected: *" in the log
Then no crash should happen
Scenario: Downloading with error in closed tab (issue 889)
@@ -136,24 +136,16 @@ Feature: Downloading things from a website.
And I wait until the download is finished
Then the downloaded file download with spaces.bin should exist
- @qtwebkit_skip @qt>=5.13
- Scenario: Downloading a file with evil content-disposition header (Qt 5.13 and newer)
+ @qtwebkit_skip
+ Scenario: Downloading a file with evil content-disposition header
# Content-Disposition: download; filename=..%2Ffoo
When I open response-headers?Content-Disposition=download;%20filename%3D..%252Ffoo without waiting
And I wait until the download is finished
Then the downloaded file ../foo should not exist
And the downloaded file foo should exist
- @qtwebkit_skip @qt<5.13
- Scenario: Downloading a file with evil content-disposition header (Qt 5.12)
- # Content-Disposition: download; filename=..%2Ffoo
- When I open response-headers?Content-Disposition=download;%20filename%3D..%252Ffoo without waiting
- And I wait until the download is finished
- Then the downloaded file ../foo should not exist
- And the downloaded file ..%2Ffoo should exist
-
- @qtwebkit_skip @qt>=5.13
- Scenario: Downloading a file with evil content-disposition header (Qt 5.13 or newer)
+ @qtwebkit_skip
+ Scenario: Downloading a file with evil content-disposition header 2
# Content-Disposition: download; filename=..%252Ffoo
When I open response-headers?Content-Disposition=download;%20filename%3D..%25252Ffoo without waiting
And I wait until the download is finished
@@ -338,7 +330,7 @@ Feature: Downloading things from a website.
Scenario: Cancelling an MHTML download (issue 1535)
When I open data/downloads/issue1535.html
And I run :download --mhtml
- And I wait for "fetch: PyQt5.QtCore.QUrl('http://localhost:*/drip?numbytes=128&duration=2') -> drip" in the log
+ And I wait for "fetch: Py*.QtCore.QUrl('http://localhost:*/drip?numbytes=128&duration=2') -> drip" in the log
And I run :download-cancel
Then no crash should happen
@@ -584,16 +576,15 @@ Feature: Downloading things from a website.
Scenario: Downloading with infinite redirect
When I set downloads.location.prompt to false
- And I run :download http://localhost:(port)/redirect/12 --dest redirection
- Then the error "Download error: Maximum redirection count reached!" should be shown
- And "Deleted *redirection" should be logged
+ And I run :download http://localhost:(port)/redirect/21 --dest redirection
+ Then the error "Download error: Too many redirects" should be shown
And the downloaded file redirection should not exist
Scenario: Downloading with redirect to itself
When I set downloads.location.prompt to false
And I run :download http://localhost:(port)/redirect-self
- And I wait until the download is finished
- Then the downloaded file redirect-self should exist
+ Then the error "Download error: Too many redirects" should be shown
+ And the downloaded file redirect-self should not exist
Scenario: Downloading with absolute redirect
When I set downloads.location.prompt to false
@@ -607,6 +598,15 @@ Feature: Downloading things from a website.
And I wait until the download is finished
Then the downloaded file relative-redirect should exist
+ Scenario: Downloading with insecure redirect
+ When I set downloads.location.prompt to false
+ And I set content.tls.certificate_errors to load-insecurely
+ And I download an SSL redirect page
+ # First error is due to the load-insecurely value above
+ Then the error "Certificate error: The certificate is self-signed, and untrusted" should be shown
+ And the error "Download error: Insecure redirect" should be shown
+ And the downloaded file download.bin should not exist
+
## Other
Scenario: Download without a content-size
@@ -646,8 +646,9 @@ Feature: Downloading things from a website.
When I set downloads.location.prompt to false
And I set content.pdfjs to true
And I open data/misc/test.pdf without waiting
- And I wait for the javascript message "PDF * [*] (PDF.js: *)"
+ And I wait until PDF.js is ready
And I run :click-element id download
+ And I clear the log
And I wait until the download is finished
# We get viewer.html as name on QtWebKit...
# Then the downloaded file test.pdf should exist
diff --git a/tests/end2end/features/keyinput.feature b/tests/end2end/features/keyinput.feature
index 556914e4d..50bda923e 100644
--- a/tests/end2end/features/keyinput.feature
+++ b/tests/end2end/features/keyinput.feature
@@ -42,7 +42,7 @@ Feature: Keyboard input
Scenario: :fake-key sending key to the website with other window focused
When I open data/keyinput/log.html
And I run :devtools
- And I wait for "Focus object changed: <PyQt5.QtWebKitWidgets.QWebView object at *>" in the log
+ And I wait for "Focus object changed: <Py*.QtWebKitWidgets.QWebView object at *>" in the log
And I run :fake-key x
And I run :devtools
And I wait for "Focus object changed: <qutebrowser.browser.webkit.webview.WebView *>" in the log
diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature
index b541954eb..480ce7339 100644
--- a/tests/end2end/features/misc.feature
+++ b/tests/end2end/features/misc.feature
@@ -186,7 +186,7 @@ Feature: Various utility commands.
@no_xvfb @posix @qtwebengine_skip
Scenario: Inspector smoke test
When I run :devtools
- And I wait for "Focus object changed: <PyQt5.QtWebKitWidgets.QWebView object at *>" in the log
+ And I wait for "Focus object changed: <Py*.QtWebKitWidgets.QWebView object at *>" in the log
And I run :devtools
And I wait for "Focus object changed: *" in the log
Then no crash should happen
@@ -195,7 +195,7 @@ Feature: Various utility commands.
@no_xvfb @posix @qtwebengine_skip
Scenario: Inspector smoke test 2
When I run :devtools
- And I wait for "Focus object changed: <PyQt5.QtWebKitWidgets.QWebView object at *>" in the log
+ And I wait for "Focus object changed: <Py*.QtWebKitWidgets.QWebView object at *>" in the log
And I run :devtools
And I wait for "Focus object changed: *" in the log
Then no crash should happen
@@ -364,7 +364,7 @@ Feature: Various utility commands.
# This still doesn't set window.navigator.language
# See https://bugreports.qt.io/browse/QTBUG-61949
- @qtwebkit_skip @js_headers
+ @qtwebkit_skip
Scenario: Accept-Language header (JS)
When I set content.headers.accept_language to it,fr
And I run :jseval console.log(window.navigator.languages)
@@ -376,7 +376,6 @@ Feature: Various utility commands.
And I run :jseval console.log(window.navigator.userAgent)
Then the header User-Agent should be set to toaster
- @js_headers
Scenario: User-agent header (JS)
When I set content.headers.user_agent to toaster
And I open about:blank
diff --git a/tests/end2end/features/prompts.feature b/tests/end2end/features/prompts.feature
index 3ef4b9567..f4ed605f9 100644
--- a/tests/end2end/features/prompts.feature
+++ b/tests/end2end/features/prompts.feature
@@ -98,7 +98,7 @@ Feature: Prompts
Then the javascript message "Alert done" should be logged
And the javascript message "notification permission granted" should be logged
- @qtwebengine_notifications
+ @qtwebkit_skip
Scenario: Async question interrupted by async one
Given I have a fresh instance
When I set content.notifications.enabled to ask
@@ -114,7 +114,7 @@ Feature: Prompts
Then the javascript message "notification permission granted" should be logged
And "Added quickmark test for *" should be logged
- @qtwebengine_notifications
+ @qtwebkit_skip
Scenario: Async question interrupted by blocking one
Given I have a fresh instance
When I set content.notifications.enabled to ask
@@ -280,7 +280,7 @@ Feature: Prompts
# Notifications
- @qtwebengine_notifications
+ @qtwebkit_skip
Scenario: Always rejecting notifications
Given I have a fresh instance
When I set content.notifications.enabled to false
@@ -288,7 +288,7 @@ Feature: Prompts
And I run :click-element id button
Then the javascript message "notification permission denied" should be logged
- @qtwebengine_notifications
+ @qtwebkit_skip
Scenario: Always accepting notifications
Given I have a fresh instance
When I set content.notifications.enabled to true
@@ -296,7 +296,7 @@ Feature: Prompts
And I run :click-element id button
Then the javascript message "notification permission granted" should be logged
- @qtwebengine_notifications
+ @qtwebkit_skip
Scenario: notifications with ask -> false
Given I have a fresh instance
When I set content.notifications.enabled to ask
@@ -306,7 +306,7 @@ Feature: Prompts
And I run :prompt-accept no
Then the javascript message "notification permission denied" should be logged
- @qtwebengine_notifications
+ @qtwebkit_skip
Scenario: notifications with ask -> false and save
Given I have a fresh instance
When I set content.notifications.enabled to ask
@@ -317,7 +317,7 @@ Feature: Prompts
Then the javascript message "notification permission denied" should be logged
And the per-domain option content.notifications.enabled should be set to false for http://localhost:(port)
- @qtwebengine_notifications
+ @qtwebkit_skip
Scenario: notifications with ask -> true
Given I have a fresh instance
When I set content.notifications.enabled to ask
@@ -327,7 +327,7 @@ Feature: Prompts
And I run :prompt-accept yes
Then the javascript message "notification permission granted" should be logged
- @qtwebengine_notifications
+ @qtwebkit_skip
Scenario: notifications with ask -> true and save
Given I have a fresh instance
When I set content.notifications.enabled to ask
@@ -349,7 +349,7 @@ Feature: Prompts
And I run :mode-leave
Then the javascript message "notification permission aborted" should be logged
- @qtwebengine_notifications
+ @qtwebkit_skip
Scenario: answering notification after closing tab
Given I have a fresh instance
When I set content.notifications.enabled to ask
@@ -523,7 +523,7 @@ Feature: Prompts
# https://github.com/qutebrowser/qutebrowser/issues/1249#issuecomment-175205531
# https://github.com/qutebrowser/qutebrowser/pull/2054#issuecomment-258285544
- @qtwebengine_notifications
+ @qtwebkit_skip
Scenario: Interrupting SSL prompt during a notification prompt
Given I have a fresh instance
When I set content.notifications.enabled to ask
diff --git a/tests/end2end/features/qutescheme.feature b/tests/end2end/features/qutescheme.feature
index 039434f1c..c5285b221 100644
--- a/tests/end2end/features/qutescheme.feature
+++ b/tests/end2end/features/qutescheme.feature
@@ -176,7 +176,8 @@ Feature: Special qute:// pages
Given pdfjs is available
When I set content.pdfjs to true
And I open data/misc/test.pdf without waiting
- Then the javascript message "PDF * [*] (PDF.js: *)" should be logged
+ And I wait until PDF.js is ready
+ # No "Then"
@qtwebkit_pdf_imageformat_skip
Scenario: pdfjs is not used when disabled
@@ -190,7 +191,7 @@ Feature: Special qute:// pages
When I set content.pdfjs to true
And I set downloads.location.prompt to true
And I open data/misc/test.pdf without waiting
- And I wait for "[qute://pdfjs/*] PDF * (PDF.js: *)" in the log
+ And I wait until PDF.js is ready
And I run :jseval document.getElementById("download").click()
And I wait for "Asking question <qutebrowser.utils.usertypes.Question default=* mode=<PromptMode.download: 5> option=None text=* title='Save file to:'>, *" in the log
And I run :mode-leave
diff --git a/tests/end2end/features/search.feature b/tests/end2end/features/search.feature
index 9446c36ac..d911a22af 100644
--- a/tests/end2end/features/search.feature
+++ b/tests/end2end/features/search.feature
@@ -249,7 +249,6 @@ Feature: Searching on a page
## wrapping prevented
- @qt>=5.14
Scenario: Preventing wrapping at the top of the page
When I set search.ignore_case to always
And I set search.wrap to false
@@ -261,7 +260,6 @@ Feature: Searching on a page
And I run :search-next
Then the message "Search hit TOP" should be shown
- @qt>=5.14
Scenario: Preventing wrapping at the bottom of the page
When I set search.ignore_case to always
And I set search.wrap to false
@@ -274,7 +272,7 @@ Feature: Searching on a page
## search match counter
- @qtwebkit_skip @qt>=5.14
+ @qtwebkit_skip
Scenario: Setting search match counter on search
When I set search.ignore_case to always
And I set search.wrap to true
@@ -282,7 +280,7 @@ Feature: Searching on a page
And I wait for "search found ba" in the log
Then "Setting search match text to 1/5" should be logged
- @qtwebkit_skip @qt>=5.14
+ @qtwebkit_skip
Scenario: Updating search match counter on search-next
When I set search.ignore_case to always
And I set search.wrap to true
@@ -294,7 +292,7 @@ Feature: Searching on a page
And I wait for "next_result found ba" in the log
Then "Setting search match text to 3/5" should be logged
- @qtwebkit_skip @qt>=5.14
+ @qtwebkit_skip
Scenario: Updating search match counter on search-prev with wrapping
When I set search.ignore_case to always
And I set search.wrap to true
@@ -304,7 +302,7 @@ Feature: Searching on a page
And I wait for the message "Search hit TOP, continuing at BOTTOM"
Then "Setting search match text to 5/5" should be logged
- @qtwebkit_skip @qt>=5.14
+ @qtwebkit_skip
Scenario: Updating search match counter on search-prev without wrapping
When I set search.ignore_case to always
And I set search.wrap to false
diff --git a/tests/end2end/features/test_downloads_bdd.py b/tests/end2end/features/test_downloads_bdd.py
index 95707f710..72f420141 100644
--- a/tests/end2end/features/test_downloads_bdd.py
+++ b/tests/end2end/features/test_downloads_bdd.py
@@ -23,7 +23,7 @@ import shlex
import pytest
import pytest_bdd as bdd
-from PyQt5.QtNetwork import QSslSocket
+from qutebrowser.qt.network import QSslSocket
bdd.scenarios('downloads.feature')
@@ -69,6 +69,13 @@ def check_ssl():
pytest.skip("QtNetwork SSL not supported")
+@bdd.when("I download an SSL redirect page")
+def download_ssl_redirect(server, ssl_server, quteproc):
+ path = "data/downloads/download.bin"
+ url = f"https://localhost:{ssl_server.port}/redirect-http/{path}?port={server.port}"
+ quteproc.send_cmd(f":download {url}")
+
+
@bdd.when("the unwritable dir is unwritable")
def check_unwritable(tmpdir):
unwritable = tmpdir / 'downloads' / 'unwritable'
diff --git a/tests/end2end/features/test_editor_bdd.py b/tests/end2end/features/test_editor_bdd.py
index 6a4da49de..d09f888e3 100644
--- a/tests/end2end/features/test_editor_bdd.py
+++ b/tests/end2end/features/test_editor_bdd.py
@@ -26,7 +26,7 @@ import time
import pytest
import pytest_bdd as bdd
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QFileSystemWatcher
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QObject, QFileSystemWatcher
bdd.scenarios('editor.feature')
from qutebrowser.utils import utils
diff --git a/tests/end2end/features/test_notifications_bdd.py b/tests/end2end/features/test_notifications_bdd.py
index 1e4bcf641..6c0fd5440 100644
--- a/tests/end2end/features/test_notifications_bdd.py
+++ b/tests/end2end/features/test_notifications_bdd.py
@@ -20,19 +20,13 @@
import pytest
import pytest_bdd as bdd
-from qutebrowser.utils import qtutils
-
bdd.scenarios('notifications.feature')
pytestmark = [
pytest.mark.usefixtures('notification_server'),
- pytest.mark.qtwebengine_notifications,
- pytest.mark.skipif(
- not qtutils.version_check('5.14'),
- reason="Custom notification presenters segfault with Qt/PyQtWebEngine 5.13",
- ),
+ pytest.mark.qtwebkit_skip,
]
@@ -88,9 +82,6 @@ def notification_image_dimensions(notification_server, width, height):
@bdd.then('the notification should be closed via web')
def notification_closed(notification_server):
- if not qtutils.version_check('5.15'):
- # Signal connection gets lost on Qt 5.14 as the notification gets destroyed
- pytest.skip("Broken with Qt 5.14")
msg = notification_server.last_msg()
assert msg.closed_via_web
diff --git a/tests/end2end/features/test_qutescheme_bdd.py b/tests/end2end/features/test_qutescheme_bdd.py
index e120cd2e7..3b6145988 100644
--- a/tests/end2end/features/test_qutescheme_bdd.py
+++ b/tests/end2end/features/test_qutescheme_bdd.py
@@ -19,17 +19,12 @@
import pytest_bdd as bdd
-from qutebrowser.utils import qtutils
-
bdd.scenarios('qutescheme.feature')
@bdd.then(bdd.parsers.parse("the {kind} request should be blocked"))
def request_blocked(request, quteproc, kind):
- blocking_set_msg = (
- "Blocking malicious request from qute://settings/set?* to "
- "qute://settings/set?*")
blocking_csrf_msg = (
"Blocking malicious request from "
"http://localhost:*/data/misc/qutescheme_csrf.html to "
@@ -39,7 +34,6 @@ def request_blocked(request, quteproc, kind):
"load local resource: qute://settings/set?*"
)
unsafe_redirect_msg = "Load error: ERR_UNSAFE_REDIRECT"
- blocked_request_msg = "Load error: ERR_BLOCKED_BY_CLIENT"
webkit_error_invalid = (
"Error while loading qute://settings/set?*: Invalid qute://settings "
@@ -48,18 +42,14 @@ def request_blocked(request, quteproc, kind):
"Error while loading qute://settings/set?*: Unsupported request type")
if request.config.webengine:
- # On Qt 5.12, we mark qute:// as a local scheme, causing most requests
- # being blocked by Chromium internally (logging to the JS console).
+ # We mark qute:// as a local scheme, causing most requests being blocked
+ # by Chromium internally (logging to the JS console).
expected_messages = {
'img': [blocking_js_msg],
'link': [blocking_js_msg],
- 'redirect': [blocking_set_msg, blocked_request_msg],
+ 'redirect': [unsafe_redirect_msg],
'form': [blocking_js_msg],
}
- if qtutils.version_check('5.15', compiled=False):
- # On Qt 5.15, Chromium blocks the redirect as ERR_UNSAFE_REDIRECT
- # instead.
- expected_messages['redirect'] = [unsafe_redirect_msg]
else: # QtWebKit
expected_messages = {
'img': [blocking_csrf_msg],
diff --git a/tests/end2end/fixtures/notificationserver.py b/tests/end2end/fixtures/notificationserver.py
index bea34c6d3..ec1953250 100644
--- a/tests/end2end/fixtures/notificationserver.py
+++ b/tests/end2end/fixtures/notificationserver.py
@@ -21,9 +21,9 @@ import dataclasses
import itertools
from typing import Dict, List
-from PyQt5.QtCore import QObject, QByteArray, QUrl, pyqtSlot
-from PyQt5.QtGui import QImage
-from PyQt5.QtDBus import QDBusConnection, QDBusMessage
+from qutebrowser.qt.core import QObject, QByteArray, QUrl, pyqtSlot
+from qutebrowser.qt.gui import QImage
+from qutebrowser.qt.dbus import QDBusConnection, QDBusMessage
import pytest
from qutebrowser.browser.webengine import notification
@@ -82,7 +82,7 @@ class TestNotificationServer(QObject):
notification.DBusNotificationAdapter.PATH,
notification.DBusNotificationAdapter.INTERFACE,
self,
- QDBusConnection.ExportAllSlots,
+ QDBusConnection.RegisterOption.ExportAllSlots,
)
return True
@@ -151,7 +151,7 @@ class TestNotificationServer(QObject):
assert channel_count == (4 if has_alpha else 3)
assert bytes_per_line >= width * channel_count
- qimage_format = QImage.Format_RGBA8888 if has_alpha else QImage.Format_RGB888
+ qimage_format = QImage.Format.Format_RGBA8888 if has_alpha else QImage.Format.Format_RGB888
img = QImage(data, width, height, bytes_per_line, qimage_format)
assert not img.isNull()
assert img.width() == width
@@ -196,7 +196,7 @@ class TestNotificationServer(QObject):
@pyqtSlot(QDBusMessage, result="uint")
def Notify(self, dbus_message: QDBusMessage) -> int:
assert dbus_message.signature() == 'susssasa{sv}i'
- assert dbus_message.type() == QDBusMessage.MethodCallMessage
+ assert dbus_message.type() == QDBusMessage.MessageType.MethodCallMessage
message = self._parse_notify_args(*dbus_message.arguments())
@@ -213,7 +213,7 @@ class TestNotificationServer(QObject):
def GetCapabilities(self, message: QDBusMessage) -> List[str]:
assert not message.signature()
assert not message.arguments()
- assert message.type() == QDBusMessage.MethodCallMessage
+ assert message.type() == QDBusMessage.MessageType.MethodCallMessage
capabilities = ["actions", "x-kde-origin-name"]
if self.supports_body_markup:
@@ -232,7 +232,7 @@ class TestNotificationServer(QObject):
@pyqtSlot(QDBusMessage)
def CloseNotification(self, dbus_message: QDBusMessage) -> None:
assert dbus_message.signature() == 'u'
- assert dbus_message.type() == QDBusMessage.MethodCallMessage
+ assert dbus_message.type() == QDBusMessage.MessageType.MethodCallMessage
message_id = dbus_message.arguments()[0]
self.messages[message_id].closed_via_web = True
@@ -246,7 +246,7 @@ def notification_server(qapp, quteproc_process):
# a connection on macOS, since it's theoretically possible to run DBus there.
pytest.skip("Skipping DBus on Windows")
- qb_pid = quteproc_process.proc.pid()
+ qb_pid = quteproc_process.proc.processId()
server = TestNotificationServer(
f"{notification.DBusNotificationAdapter.TEST_SERVICE}{qb_pid}")
registered = server.register()
diff --git a/tests/end2end/fixtures/quteprocess.py b/tests/end2end/fixtures/quteprocess.py
index 6b99d5bf0..df3a15ff1 100644
--- a/tests/end2end/fixtures/quteprocess.py
+++ b/tests/end2end/fixtures/quteprocess.py
@@ -33,8 +33,8 @@ import json
import yaml
import pytest
-from PyQt5.QtCore import pyqtSignal, QUrl, QPoint
-from PyQt5.QtGui import QImage, QColor
+from qutebrowser.qt.core import pyqtSignal, QUrl, QPoint
+from qutebrowser.qt.gui import QImage, QColor
from qutebrowser.misc import ipc
from qutebrowser.utils import log, utils, javascript
@@ -54,70 +54,13 @@ def is_ignored_qt_message(pytestconfig, message):
def is_ignored_lowlevel_message(message):
"""Check if we want to ignore a lowlevel process output."""
ignored_messages = [
- # https://travis-ci.org/qutebrowser/qutebrowser/jobs/157941720
- # ???
- 'Xlib: sequence lost*',
- # Started appearing with Qt 5.8...
- # https://patchwork.sourceware.org/patch/10255/
- ("*_dl_allocate_tls_init: Assertion `listp->slotinfo[cnt].gen <= "
- "GL(dl_tls_generation)' failed!*"),
- # ???
- 'getrlimit(RLIMIT_NOFILE) failed',
- 'libpng warning: Skipped (ignored) a chunk between APNG chunks',
- # Travis CI containers don't have a /etc/machine-id
- ('*D-Bus library appears to be incorrectly set up; failed to read '
- 'machine uuid: Failed to open "/etc/machine-id": No such file or '
- 'directory'),
- 'See the manual page for dbus-uuidgen to correct this issue.',
- # Travis CI macOS:
- # 2017-09-11 07:32:56.191 QtWebEngineProcess[5455:28501] Couldn't set
- # selectedTextBackgroundColor from default ()
- "* Couldn't set selectedTextBackgroundColor from default ()",
- # Mac Mini:
- # <<<< VTVideoEncoderSelection >>>>
- # VTSelectAndCreateVideoEncoderInstanceInternal: no video encoder
- # found for 'avc1'
- #
- # [22:32:03.636] VTSelectAndCreateVideoEncoderInstanceInternal
- # signalled err=-12908 (err) (Video encoder not available) at
- # /SourceCache/CoreMedia_frameworks/CoreMedia-1562.240/Sources/
- # VideoToolbox/VTVideoEncoderSelection.c line 1245
- #
- # [22:32:03.636] VTCompressionSessionCreate signalled err=-12908 (err)
- # (Could not select and open encoder instance) at
- # /SourceCache/CoreMedia_frameworks/CoreMedia-1562.240/Sources/
- # VideoToolbox/VTCompressionSession.c # line 946
- '*VTSelectAndCreateVideoEncoderInstanceInternal*',
- '*VTSelectAndCreateVideoEncoderInstanceInternal*',
- '*VTCompressionSessionCreate*',
- # During shutdown on AppVeyor:
- # https://ci.appveyor.com/project/qutebrowser/qutebrowser/build/master-2089/job/or4tbct1oeqsfhfm
- 'QNetworkProxyFactory: factory 0x* has returned an empty result set',
- # Qt 5.10 with debug Chromium
- # [1016/155149.941048:WARNING:stack_trace_posix.cc(625)] Failed to open
- # file: /home/florian/#14687139 (deleted)
- # Error: No such file or directory
- ' Error: No such file or directory',
- # Qt 5.7.1
- 'qt.network.ssl: QSslSocket: cannot call unresolved function *',
- # Qt 5.11
- # DevTools listening on ws://127.0.0.1:37945/devtools/browser/...
- 'DevTools listening on *',
- # /home/travis/build/qutebrowser/qutebrowser/.tox/py36-pyqt511-cov/lib/
- # python3.6/site-packages/PyQt5/Qt/libexec/QtWebEngineProcess:
- # /lib/x86_64-linux-gnu/libdbus-1.so.3: no version information
- # available (required by /home/travis/build/qutebrowser/qutebrowser/
- # .tox/py36-pyqt511-cov/lib/python3.6/site-packages/PyQt5/Qt/libexec/
- # ../lib/libQt5WebEngineCore.so.5)
- '*/QtWebEngineProcess: /lib/x86_64-linux-gnu/libdbus-1.so.3: no '
- 'version information available (required by '
- '*/libQt5WebEngineCore.so.5)',
-
- # hunter and Python 3.9
- # https://github.com/ionelmc/python-hunter/issues/87
- '<frozen importlib._bootstrap>:*: RuntimeWarning: builtins.type size changed, '
- 'may indicate binary incompatibility. Expected 872 from C header, got 880 from '
- 'PyObject',
+ # Qt 6.2 / 6.3
+ 'Fontconfig error: Cannot load default config file: No such file: (null)',
+ 'Fontconfig error: Cannot load default config file',
+
+ # Qt 6.4, from certificate error below, but on separate lines
+ '----- Certificate i=0 (*,CN=localhost,O=qutebrowser test certificate) -----',
+ 'ERROR: No matching issuer found',
]
return any(testutils.pattern_match(pattern=pattern, value=message)
for pattern in ignored_messages)
@@ -142,186 +85,8 @@ def is_ignored_chromium_message(line):
message = match.group('message')
ignored_messages = [
- # [27289:27289:0605/195958.776146:INFO:zygote_host_impl_linux.cc(107)]
- # No usable sandbox! Update your kernel or see
- # https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md
- # for more information on developing with the SUID sandbox. If you want
- # to live dangerously and need an immediate workaround, you can try
- # using --no-sandbox.
- 'No usable sandbox! Update your kernel or see *',
- # [30981:30992:0605/200633.041364:ERROR:cert_verify_proc_nss.cc(918)]
- # CERT_PKIXVerifyCert for localhost failed err=-8179
- 'CERT_PKIXVerifyCert for localhost failed err=*',
- # [1:1:0914/130428.060976:ERROR:broker_posix.cc(41)] Invalid node
- # channel message
- 'Invalid node channel message',
-
- # Qt 5.9.3
- # [30217:30229:1124/141512.682110:ERROR:
- # cert_verify_proc_openssl.cc(212)]
- # X509 Verification error self signed certificate : 18 : 0 : 4
- 'X509 Verification error self signed certificate : 18 : 0 : 4',
- # Qt 5.13
- # [27789:27805:0325/111821.127349:ERROR:ssl_client_socket_impl.cc(962)]
- # handshake failed; returned -1, SSL error code 1, net_error -202
- 'handshake failed; returned -1, SSL error code 1, net_error -202',
-
- # Not reproducible anymore?
-
- 'Running without the SUID sandbox! *',
- 'Unable to locate theme engine in module_path: *',
- 'Could not bind NETLINK socket: Address already in use',
- # Started appearing in sessions.feature with Qt 5.8...
- 'Invalid node channel message *',
- # Makes tests fail on Quantumcross' machine
- ('CreatePlatformSocket() returned an error, errno=97: Address family'
- 'not supported by protocol'),
-
- # Qt 5.9 with debug Chromium
-
- # [28121:28121:0605/191637.407848:WARNING:resource_bundle_qt.cpp(114)]
- # locale_file_path.empty() for locale
- 'locale_file_path.empty() for locale',
- # [26598:26598:0605/191429.639416:WARNING:audio_manager.cc(317)]
- # Multiple instances of AudioManager detected
- 'Multiple instances of AudioManager detected',
- # [25775:25788:0605/191240.931551:ERROR:quarantine_linux.cc(33)]
- # Could not set extended attribute user.xdg.origin.url on file
- # /tmp/pytest-of-florian/pytest-32/test_webengine_download_suffix0/
- # downloads/download.bin: Operation not supported
- ('Could not set extended attribute user.xdg.* on file *: '
- 'Operation not supported*'),
- # [5947:5947:0605/192837.856931:ERROR:render_process_impl.cc(112)]
- # WebFrame LEAKED 1 TIMES
- 'WebFrame LEAKED 1 TIMES',
-
- # Qt 5.10 with debug Chromium
- # [1016/155149.941048:WARNING:stack_trace_posix.cc(625)] Failed to open
- # file: /home/florian/#14687139 (deleted)
- # Error: No such file or directory
- 'Failed to open file: * (deleted)',
-
- # macOS on Travis
- # [5140:5379:0911/063441.239771:ERROR:mach_port_broker.mm(175)]
- # Unknown process 5176 is sending Mach IPC messages!
- 'Unknown process * is sending Mach IPC messages!',
- # [5205:44547:0913/142945.003625:ERROR:node_controller.cc(1268)] Error
- # on receiving Mach ports FFA56F125F699ADB.E28E252911A8704B. Dropping
- # message.
- 'Error on receiving Mach ports *. Dropping message.',
-
- # [2734:2746:1107/131154.072032:ERROR:nss_ocsp.cc(591)] No
- # URLRequestContext for NSS HTTP handler. host: ocsp.digicert.com
- 'No URLRequestContext for NSS HTTP handler. host: *',
-
- # https://bugreports.qt.io/browse/QTBUG-66661
- # [23359:23359:0319/115812.168578:WARNING:
- # render_frame_host_impl.cc(2744)] OnDidStopLoading was called twice.
- 'OnDidStopLoading was called twice.',
-
- # [30412:30412:0323/074933.387250:ERROR:node_channel.cc(899)] Dropping
- # message on closed channel.
- 'Dropping message on closed channel.',
- # [2204:1408:0703/113804.788:ERROR:
- # gpu_process_transport_factory.cc(1019)] Lost UI shared context.
- 'Lost UI shared context.',
-
- # [20870:20908:0607/081717.652282:ERROR:block_files.cc(465)] Failed to
- # open /tmp/qutebrowser-basedir-cg284f_m/data/webengine/GPUCache/data_2
- 'Failed to open *GPUCache*',
-
- # Qt 5.12
- # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-70702
- # [32123:32123:0923/224739.457307:ERROR:in_progress_cache_impl.cc(192)]
- # Cache is not initialized, cannot RetrieveEntry.
- 'Cache is not initialized, cannot RetrieveEntry.',
- 'Cache is not initialized, cannot AddOrReplaceEntry.',
- # [10518:10518:0924/121250.186121:WARNING:
- # render_frame_host_impl.cc(431)]
- # InterfaceRequest was dropped, the document is no longer active:
- # content.mojom.RendererAudioOutputStreamFactory
- 'InterfaceRequest was dropped, the document is no longer active: '
- 'content.mojom.RendererAudioOutputStreamFactory',
- # [1920:2168:0225/112442.664:ERROR:in_progress_cache_impl.cc(124)]
- # Could not write download entries to file: C:\Users\appveyor\AppData\
- # Local\Temp\1\qutebrowser-basedir-1l3jmxq4\data\webengine\
- # in_progress_download_metadata_store
- 'Could not write download entries to file: *',
-
- # Qt 5.13
- # [32651:32651:0325/130146.300817:WARNING:
- # render_frame_host_impl.cc(486)]
- # InterfaceRequest was dropped, the document is no longer active:
- # resource_coordinator.mojom.FrameCoordinationUnit
- 'InterfaceRequest was dropped, the document is no longer active: '
- 'resource_coordinator.mojom.FrameCoordinationUnit',
-
- # Qt 5.14
- # [1:7:1119/162200.709920:ERROR:command_buffer_proxy_impl.cc(124)]
- # ContextResult::kTransientFailure: Failed to send
- # GpuChannelMsg_CreateCommandBuffer.
- 'ContextResult::kTransientFailure: Failed to send '
- 'GpuChannelMsg_CreateCommandBuffer.',
- # [156330:156350:1121/120052.060701:WARNING:
- # important_file_writer.cc(97)]
- # temp file failure: /home/florian/.local/share/qutebrowser/
- # qutebrowser/QtWebEngine/Default/user_prefs.json : could not create
- # temporary file: No such file or directory (2)
- 'temp file failure: */qutebrowser/qutebrowser/QtWebEngine/Default/'
- 'user_prefs.json : could not create temporary file: No such file or '
- 'directory (2)',
- # [156330:156330:1121/120052.602236:ERROR:
- # viz_process_transport_factory.cc(331)]
- # Switching to software compositing.
- 'Switching to software compositing.',
- # [160686:160712:1121/121226.457866:ERROR:surface_manager.cc(438)]
- # Old/orphaned temporary reference to
- # SurfaceId(FrameSinkId[](5, 2), LocalSurfaceId(8, 1, 7C3A...))
- 'Old/orphaned temporary reference to '
- 'SurfaceId(FrameSinkId[](*), LocalSurfaceId(*))',
- # [79680:79705:0111/151113.071008:WARNING:
- # important_file_writer.cc(97)] temp file failure:
- # /tmp/qutebrowser-basedir-gwkvqpyp/data/webengine/user_prefs.json :
- # could not create temporary file: No such file or directory (2)
- # (Only in debug builds)
- # https://bugreports.qt.io/browse/QTBUG-78319
- 'temp file failure: * : could not create temporary file: No such file '
- 'or directory (2)',
-
- # Travis
- # test_ssl_error_with_contentssl_strict__true
- # [5306:5324:0417/151739.362362:ERROR:address_tracker_linux.cc(171)]
- # Could not bind NETLINK socket: Address already in use (98)
- 'Could not bind NETLINK socket: Address already in use (98)',
-
- # Qt 5.15 with AppVeyor
- # [2968:3108:0601/123442.125:ERROR:mf_helpers.cc(14)] Error in
- # dxva_video_decode_accelerator_win.cc on line 517
- 'Error in dxva_video_decode_accelerator_win.cc on line 517',
-
- # Qt 5.15 and debug build
- # [134188:134199:0609/132454.797229:WARNING:
- # simple_synchronous_entry.cc(1389)]
- # Could not open platform files for entry.
- # [134151:134187:0609/132456.754321:ERROR:process_posix.cc(333)]
- # Unable to terminate process 134188: No such process (3)
- # [134151:134187:0609/132456.754414:WARNING:internal_linux.cc(64)]
- # Failed to read /proc/134188/stat
- 'Could not open platform files for entry.',
- 'Unable to terminate process *: No such process (3)',
- 'Failed to read /proc/*/stat',
-
- # Qt 5.15.1 debug build (Chromium 83)
- # '[314297:7:0929/214605.491958:ERROR:context_provider_command_buffer.cc(145)]
- # GpuChannelHost failed to create command buffer.'
- 'GpuChannelHost failed to create command buffer.',
- # [338691:4:0929/220114.488847:WARNING:ipc_message_attachment_set.cc(49)]
- # MessageAttachmentSet destroyed with unconsumed attachments: 0/1
- 'MessageAttachmentSet destroyed with unconsumed attachments: *',
-
- # GitHub Actions with Qt 5.15.1
- ('SharedImageManager::ProduceGLTexture: Trying to produce a '
- 'representation from a non-existent mailbox. *'),
+ # GitHub Actions with Qt 5.15.2
+ 'SharedImageManager::ProduceGLTexture: Trying to produce a representation from a non-existent mailbox. *',
('[.DisplayCompositor]GL ERROR :GL_INVALID_OPERATION : '
'DoCreateAndTexStorage2DSharedImageINTERNAL: invalid mailbox name'),
('[.DisplayCompositor]GL ERROR :GL_INVALID_OPERATION : '
@@ -331,38 +96,40 @@ def is_ignored_chromium_message(line):
'filtering (maybe)?'),
('[.DisplayCompositor]GL ERROR :GL_INVALID_OPERATION : '
'DoEndSharedImageAccessCHROMIUM: bound texture is not a shared image'),
- 'Unable to map Index file',
-
- # WebRTC with Qt 5.13 / 5.14
- 'Failed to query stereo recording.',
- 'Accepting maxRetransmits = -1 for backwards compatibility',
- 'Accepting maxRetransmitTime = -1 for backwards compatibility',
-
- # Windows N:
- # https://github.com/microsoft/playwright/issues/2901
- ('DXVAVDA fatal error: could not LoadLibrary: *: The specified '
- 'module could not be found. (0x7E)'),
- # Qt 5.15.3 dev build
- r'Duplicate id found. Reassigning from * to *',
+ # [916:934:1213/080738.912432:ERROR:address_tracker_linux.cc(214)] Could not bind NETLINK socket: Address already in use (98)
+ 'Could not bind NETLINK socket: Address already in use (98)',
- # Flatpak
+ # Flatpak with data/crashers/webrtc.html (Qt 6.2)
+ # [9044:9113:0512/012126.284773:ERROR:mdns_responder.cc(868)] mDNS responder manager failed to start.
+ # [9044:9113:0512/012126.284818:ERROR:mdns_responder.cc(885)] The mDNS responder manager is not started yet.
'mDNS responder manager failed to start.',
'The mDNS responder manager is not started yet.',
- # GitHub Actions with Qt 5.15.0
- # [5387:5407:0713/142608.526916:ERROR:cache_util.cc(135)] Unable to
- # move cache folder
- # /tmp/qutebrowser-basedir-4x3ue9fq/data/webengine/GPUCache to
- # /tmp/qutebrowser-basedir-4x3ue9fq/data/webengine/old_GPUCache_000
- # [5387:5407:0713/142608.526934:ERROR:disk_cache.cc(184)] Unable to
- # create cache
- # [5387:5407:0713/142608.526938:ERROR:shader_disk_cache.cc(606)] Shader
- # Cache Creation failed: -2
- ('Unable to move cache folder */data/webengine/GPUCache to '
- '*/data/webengine/old_GPUCache_000'),
- 'Unable to create cache',
- 'Shader Cache Creation failed: -2',
+ # Qt 6.2:
+ # [503633:503650:0509/185222.442798:ERROR:ssl_client_socket_impl.cc(959)] handshake failed; returned -1, SSL error code 1, net_error -202
+ 'handshake failed; returned -1, SSL error code 1, net_error -202',
+
+ # Qt 6.2:
+ # [2432160:7:0429/195800.168435:ERROR:command_buffer_proxy_impl.cc(140)] ContextResult::kTransientFailure: Failed to send GpuChannelMsg_CreateCommandBuffer.
+ # Qt 6.3:
+ # [2435381:7:0429/200014.168057:ERROR:command_buffer_proxy_impl.cc(125)] ContextResult::kTransientFailure: Failed to send GpuControl.CreateCommandBuffer.
+ 'ContextResult::kTransientFailure: Failed to send *CreateCommandBuffer.',
+
+ # Qt 6.3:
+ # [4919:8:0530/170658.033287:ERROR:command_buffer_proxy_impl.cc(328)] GPU state invalid after WaitForGetOffsetInRange.
+ 'GPU state invalid after WaitForGetOffsetInRange.',
+ # [5469:5503:0621/183219.878182:ERROR:backend_impl.cc(1414)] Unable to map Index file
+ 'Unable to map Index file',
+
+ # Qt 6.4:
+ # [2456284:2456339:0715/110322.570154:ERROR:cert_verify_proc_builtin.cc(681)] CertVerifyProcBuiltin for localhost failed:
+ # ----- Certificate i=0 (1.2.840.113549.1.9.1=#6D61696C407175746562726F777365722E6F7267,CN=localhost,O=qutebrowser test certificate) -----
+ # ERROR: No matching issuer found
+ # (Note, subsequent lines above in is_ignored_lowlevel_message)
+ 'CertVerifyProcBuiltin for localhost failed:',
+ # [320667:320667:1124/135621.718232:ERROR:interface_endpoint_client.cc(687)] Message 4 rejected by interface blink.mojom.WidgetHost
+ 'Message 4 rejected by interface blink.mojom.WidgetHost',
]
return any(testutils.pattern_match(pattern=pattern, value=message)
for pattern in ignored_messages)
@@ -598,11 +365,11 @@ class QuteProc(testprocess.Process):
raise ValueError("Either both x/y or neither must be given!")
if x is None and y is None:
- point = 'PyQt5.QtCore.QPoint(*, *)' # not counting 0/0 here
+ point = 'Py*.QtCore.QPoint(*, *)' # not counting 0/0 here
elif x == '0' and y == '0':
- point = 'PyQt5.QtCore.QPoint()'
+ point = 'Py*.QtCore.QPoint()'
else:
- point = 'PyQt5.QtCore.QPoint({}, {})'.format(x, y)
+ point = 'Py*.QtCore.QPoint({}, {})'.format(x, y)
self.wait_for(category='webview',
message='Scroll position changed to ' + point)
@@ -676,7 +443,7 @@ class QuteProc(testprocess.Process):
except AttributeError:
pass
else:
- if call.failed or hasattr(call, 'wasxfail'):
+ if call.failed or hasattr(call, 'wasxfail') or call.skipped:
super().after_test()
return
@@ -695,6 +462,21 @@ class QuteProc(testprocess.Process):
self.wait_for(category='ipc', module='ipc', function='on_ready_read',
message='Read from socket *')
+ @contextlib.contextmanager
+ def disable_capturing(self):
+ capmanager = self.request.config.pluginmanager.getplugin("capturemanager")
+ with capmanager.global_and_fixture_disabled():
+ yield
+
+ def _after_start(self):
+ """Wait before continuing if requested, e.g. for debugger attachment."""
+ delay = self.request.config.getoption('--qute-delay-start')
+ if delay:
+ with self.disable_capturing():
+ print(f"- waiting {delay}ms for quteprocess "
+ f"(PID: {self.proc.processId()})...")
+ time.sleep(delay / 1000)
+
def send_ipc(self, commands, target_arg=''):
"""Send a raw command to the running IPC socket."""
delay = self.request.config.getoption('--qute-delay')
@@ -849,13 +631,13 @@ class QuteProc(testprocess.Process):
# We really need the same representation that the webview uses in
# its __repr__
- url = utils.elide(qurl.toDisplayString(QUrl.EncodeUnicode), 100)
+ url = utils.elide(qurl.toDisplayString(QUrl.ComponentFormattingOption.EncodeUnicode), 100)
assert url
pattern = re.compile(
r"(load status for <qutebrowser\.browser\..* "
r"tab_id=\d+ url='{url}/?'>: LoadStatus\.{load_status}|fetch: "
- r"PyQt5\.QtCore\.QUrl\('{url}'\) -> .*)".format(
+ r"Py.*\.QtCore\.QUrl\('{url}'\) -> .*)".format(
load_status=re.escape(load_status), url=re.escape(url)))
try:
diff --git a/tests/end2end/fixtures/test_quteprocess.py b/tests/end2end/fixtures/test_quteprocess.py
index c4b226972..7199bf015 100644
--- a/tests/end2end/fixtures/test_quteprocess.py
+++ b/tests/end2end/fixtures/test_quteprocess.py
@@ -35,6 +35,7 @@ class FakeRepCall:
def __init__(self):
self.failed = False
+ self.skipped = False
class FakeConfig:
@@ -143,7 +144,8 @@ def test_quteproc_skip_and_wait_for(qtbot, quteproc):
def test_qt_log_ignore(qtbot, quteproc):
"""Make sure the test passes when logging a qt_log_ignore message."""
with qtbot.wait_signal(quteproc.got_error):
- quteproc.send_cmd(':message-error "SpellCheck: test"')
+ quteproc.send_cmd(
+ ':message-error "QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to blabla"')
def test_quteprocess_quitting(qtbot, quteproc_process):
@@ -188,7 +190,7 @@ def test_quteprocess_quitting(qtbot, quteproc_process):
pytest.param(
'{"created": 86400, "msecs": 0, "levelname": "VDEBUG", "name": "foo", '
'"module": "foo", "funcName": "foo", "lineno": 0, "levelno": 9, '
- '"message": "SpellCheck: test"}',
+ '"message": "QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to blabla"}',
{'expected': True},
id='expected message'),
@@ -354,14 +356,11 @@ def test_set(quteproc, value):
# Unparsable
('Hello World', False),
# Without process/thread ID
- ('[0606/135039:ERROR:cert_verify_proc_nss.cc(925)] CERT_PKIXVerifyCert '
- 'for localhost failed err=-8179', True),
+ ('[0509/185222.442798:ERROR:ssl_client_socket_impl.cc(959)] handshake failed; returned -1, SSL error code 1, net_error -202', True),
# Random ignored message
- ('[26598:26598:0605/191429.639416:WARNING:audio_manager.cc(317)] Multiple '
- 'instances of AudioManager detected', True),
+ ('[503633:503650:0509/185222.442798:ERROR:ssl_client_socket_impl.cc(959)] handshake failed; returned -1, SSL error code 1, net_error -202', True),
# Not ignored
- ('[26598:26598:0605/191429.639416:WARNING:audio_manager.cc(317)] Test',
- False),
+ ('[26598:26598:0605/191429.639416:WARNING:audio_manager.cc(317)] Test', False),
])
def test_is_ignored_chromium_message(message, ignored):
assert quteprocess.is_ignored_chromium_message(message) == ignored
diff --git a/tests/end2end/fixtures/test_testprocess.py b/tests/end2end/fixtures/test_testprocess.py
index aa6f19c67..dd16b8b8f 100644
--- a/tests/end2end/fixtures/test_testprocess.py
+++ b/tests/end2end/fixtures/test_testprocess.py
@@ -25,7 +25,7 @@ import contextlib
import datetime
import pytest
-from PyQt5.QtCore import QProcess
+from qutebrowser.qt.core import QProcess
from end2end.fixtures import testprocess
@@ -53,7 +53,7 @@ class PythonProcess(testprocess.Process):
def __init__(self, request):
super().__init__(request)
- self.proc.setReadChannel(QProcess.StandardOutput)
+ self.proc.setReadChannel(QProcess.ProcessChannel.StandardOutput)
self.code = None
def _parse_line(self, line):
diff --git a/tests/end2end/fixtures/testprocess.py b/tests/end2end/fixtures/testprocess.py
index 96e700390..78c08a4c0 100644
--- a/tests/end2end/fixtures/testprocess.py
+++ b/tests/end2end/fixtures/testprocess.py
@@ -26,9 +26,9 @@ import dataclasses
import pytest
import pytestqt.wait_signal
-from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QProcess, QObject,
+from qutebrowser.qt.core import (pyqtSlot, pyqtSignal, QProcess, QObject,
QElapsedTimer, QProcessEnvironment)
-from PyQt5.QtTest import QSignalSpy
+from qutebrowser.qt.test import QSignalSpy
from helpers import testutils
@@ -151,7 +151,7 @@ class Process(QObject):
self._invalid = []
self._data = []
self.proc = QProcess()
- self.proc.setReadChannel(QProcess.StandardError)
+ self.proc.setReadChannel(QProcess.ProcessChannel.StandardError)
self.exit_expected = None # Not started at all yet
def _log(self, line):
@@ -325,7 +325,7 @@ class Process(QObject):
def is_running(self):
"""Check if the process is currently running."""
- return self.proc.state() == QProcess.Running
+ return self.proc.state() == QProcess.ProcessState.Running
def _match_data(self, value, expected):
"""Helper for wait_for to match a given value.
diff --git a/tests/end2end/fixtures/webserver.py b/tests/end2end/fixtures/webserver.py
index 2c2eab930..fc76c959d 100644
--- a/tests/end2end/fixtures/webserver.py
+++ b/tests/end2end/fixtures/webserver.py
@@ -28,7 +28,7 @@ import dataclasses
from http import HTTPStatus
import pytest
-from PyQt5.QtCore import pyqtSignal, QUrl
+from qutebrowser.qt.core import pyqtSignal, QUrl
from end2end.fixtures import testprocess
@@ -77,6 +77,7 @@ class Request(testprocess.Line):
'/redirect-to': [HTTPStatus.FOUND],
'/relative-redirect': [HTTPStatus.FOUND],
'/absolute-redirect': [HTTPStatus.FOUND],
+ '/redirect-http/data/downloads/download.bin': [HTTPStatus.FOUND],
'/cookies/set': [HTTPStatus.FOUND],
'/cookies/set-custom': [HTTPStatus.FOUND],
@@ -84,7 +85,7 @@ class Request(testprocess.Line):
'/500-inline': [HTTPStatus.INTERNAL_SERVER_ERROR],
'/500': [HTTPStatus.INTERNAL_SERVER_ERROR],
}
- for i in range(15):
+ for i in range(25):
path_to_statuses['/redirect/{}'.format(i)] = [HTTPStatus.FOUND]
for suffix in ['', '1', '2', '3', '4', '5', '6']:
key = ('/basic-auth/user{suffix}/password{suffix}'
diff --git a/tests/end2end/fixtures/webserver_sub_ssl.py b/tests/end2end/fixtures/webserver_sub_ssl.py
index ad4341201..d628c37b9 100644
--- a/tests/end2end/fixtures/webserver_sub_ssl.py
+++ b/tests/end2end/fixtures/webserver_sub_ssl.py
@@ -44,6 +44,14 @@ def send_data(path):
return webserver_sub.send_data(path)
+@app.route('/redirect-http/<path:path>')
+def redirect_http(path):
+ """Redirect to the given (plaintext) HTTP port on localhost."""
+ host, _orig_port = flask.request.server
+ port = flask.request.args["port"]
+ return flask.redirect(f"http://{host}:{port}/{path}")
+
+
@app.route('/favicon.ico')
def favicon():
return webserver_sub.favicon()
diff --git a/tests/end2end/test_dirbrowser.py b/tests/end2end/test_dirbrowser.py
index c2aa19233..ebf31abe2 100644
--- a/tests/end2end/test_dirbrowser.py
+++ b/tests/end2end/test_dirbrowser.py
@@ -27,7 +27,7 @@ from typing import List
import pytest
import bs4
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.utils import urlutils
from helpers import testutils
diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py
index 042089859..415aa5020 100644
--- a/tests/end2end/test_invocations.py
+++ b/tests/end2end/test_invocations.py
@@ -29,10 +29,10 @@ import json
import platform
import pytest
-from PyQt5.QtCore import QProcess, QPoint
+from qutebrowser.qt.core import QProcess, QPoint
from helpers import testutils
-from qutebrowser.utils import qtutils, utils
+from qutebrowser.utils import qtutils, utils, version
ascii_locale = pytest.mark.skipif(sys.hexversion >= 0x03070000,
@@ -262,7 +262,7 @@ def test_version(request):
# can't use quteproc_new here because it's confused by
# early process termination
proc = QProcess()
- proc.setProcessChannelMode(QProcess.SeparateChannels)
+ proc.setProcessChannelMode(QProcess.ProcessChannelMode.SeparateChannels)
proc.start(sys.executable, args)
ok = proc.waitForStarted(2000)
@@ -275,7 +275,7 @@ def test_version(request):
print(stderr)
assert ok
- assert proc.exitStatus() == QProcess.NormalExit
+ assert proc.exitStatus() == QProcess.ExitStatus.NormalExit
match = re.search(r'^qutebrowser\s+v\d+(\.\d+)', stdout, re.MULTILINE)
assert match is not None
@@ -412,7 +412,18 @@ def test_qute_settings_persistence(short_tmpdir, request, quteproc_new):
@pytest.mark.parametrize('value, expected', [
- ('always', 'http://localhost:(port2)/headers-link/(port)'),
+ # https://chromium-review.googlesource.com/c/chromium/src/+/2545444
+ pytest.param(
+ 'always',
+ 'http://localhost:(port2)/headers-link/(port)',
+ marks=pytest.mark.qt5_only,
+ ),
+ pytest.param(
+ 'always',
+ 'http://localhost:(port2)/',
+ marks=pytest.mark.qt6_only,
+ ),
+
('never', None),
('same-domain', 'http://localhost:(port2)/'), # None with QtWebKit
])
@@ -446,7 +457,7 @@ def test_referrer(quteproc_new, server, server2, request, value, expected):
def test_preferred_colorscheme_unsupported(request, quteproc_new):
"""Test versions without preferred-color-scheme support."""
- if request.config.webengine and qtutils.version_check('5.14'):
+ if request.config.webengine:
pytest.skip("preferred-color-scheme is supported")
args = _base_args(request.config) + ['--temp-basedir']
@@ -457,7 +468,6 @@ def test_preferred_colorscheme_unsupported(request, quteproc_new):
@pytest.mark.qtwebkit_skip
-@testutils.qt514
@pytest.mark.parametrize('value', ["dark", "light", "auto", None])
def test_preferred_colorscheme(request, quteproc_new, value):
"""Make sure the the preferred colorscheme is set."""
@@ -481,11 +491,7 @@ def test_preferred_colorscheme(request, quteproc_new, value):
None: [dark_text, light_text],
}
xfail = False
- if not qtutils.version_check('5.15.2', compiled=False):
- # On older versions, "light" is not supported, so the result will depend on the
- # environment.
- expected_values["light"].append(dark_text)
- elif qtutils.version_check('5.15.2', exact=True, compiled=False):
+ if qtutils.version_check('5.15.2', exact=True, compiled=False):
# Test the WORKAROUND https://bugreports.qt.io/browse/QTBUG-89753
# With that workaround, we should always get the light preference.
for key in ["auto", None]:
@@ -501,10 +507,13 @@ def test_preferred_colorscheme(request, quteproc_new, value):
pytest.xfail("QTBUG-89753")
-@testutils.qt514
def test_preferred_colorscheme_with_dark_mode(
request, quteproc_new, webengine_versions):
- """Test interaction between preferred-color-scheme and dark mode."""
+ """Test interaction between preferred-color-scheme and dark mode.
+
+ We would actually expect a color of 34, 34, 34 and 'Dark preference detected.'.
+ That was the behavior on Qt 5.14 and 5.15.0/.1.
+ """
if not request.config.webengine:
pytest.skip("Skipped with QtWebKit")
@@ -519,25 +528,26 @@ def test_preferred_colorscheme_with_dark_mode(
quteproc_new.open_path('data/darkmode/prefers-color-scheme.html')
content = quteproc_new.get_content()
- qtwe_version = webengine_versions.webengine
- xfail = None
- if utils.VersionNumber(5, 15, 3) <= qtwe_version <= utils.VersionNumber(6):
- # https://bugs.chromium.org/p/chromium/issues/detail?id=1177973
- # No workaround known.
- expected_text = 'Light preference detected.'
- # light website color, inverted by darkmode
- expected_color = (testutils.Color(123, 125, 123) if IS_ARM
- else testutils.Color(127, 127, 127))
- xfail = "Chromium bug 1177973"
- elif qtwe_version == utils.VersionNumber(5, 15, 2):
+ if webengine_versions.webengine == utils.VersionNumber(5, 15, 2):
# Our workaround breaks when dark mode is enabled...
# Also, for some reason, dark mode doesn't work on that page either!
expected_text = 'No preference detected.'
expected_color = testutils.Color(0, 170, 0) # green
xfail = "QTBUG-89753"
+ elif webengine_versions.webengine < utils.VersionNumber(6, 4):
+ # https://bugs.chromium.org/p/chromium/issues/detail?id=1177973
+ # No workaround known.
+ expected_text = 'Light preference detected.'
+ # light website color, inverted by darkmode
+ if webengine_versions.webengine >= utils.VersionNumber(6):
+ expected_color = (testutils.Color(148, 146, 148) if IS_ARM
+ else testutils.Color(144, 144, 144))
+ else:
+ expected_color = (testutils.Color(123, 125, 123) if IS_ARM
+ else testutils.Color(127, 127, 127))
+ xfail = "Chromium bug 1177973"
else:
- # Qt 5.14 and 5.15.0/.1 work correctly.
- # Hopefully, so does Qt 6.x in the future?
+ # Correct behavior on QtWebEngine 6.4 (and 5.14/5.15.0/5.15.1 in the past)
expected_text = 'Dark preference detected.'
expected_color = (testutils.Color(33, 32, 33) if IS_ARM
else testutils.Color(34, 34, 34)) # dark website color
@@ -557,7 +567,6 @@ def test_preferred_colorscheme_with_dark_mode(
@pytest.mark.qtwebkit_skip
@pytest.mark.parametrize('reason', [
'Explicitly enabled',
- pytest.param('Qt 5.14', marks=testutils.qt514),
'Qt version changed',
None,
])
@@ -582,9 +591,7 @@ def test_service_worker_workaround(
# Edit state file if needed
state_file = short_tmpdir / 'data' / 'state'
- if reason == 'Qt 5.14':
- state_file.remove()
- elif reason == 'Qt version changed':
+ if reason == 'Qt version changed':
parser = configparser.ConfigParser()
parser.read(state_file)
del parser['general']['qt_version']
@@ -608,7 +615,6 @@ def test_service_worker_workaround(
assert not service_worker_dir.exists()
-@testutils.qt513 # Qt 5.12 doesn't store cookies immediately
@pytest.mark.parametrize('store', [True, False])
def test_cookies_store(quteproc_new, request, short_tmpdir, store):
# Start test process
@@ -649,41 +655,57 @@ def test_cookies_store(quteproc_new, request, short_tmpdir, store):
'blank',
'lightness-cielab',
{
- ('5.15', None): testutils.Color(18, 18, 18),
- ('5.15', 'aarch64'): testutils.Color(16, 16, 16),
- ('5.14', None): testutils.Color(27, 27, 27),
- ('5.14', 'aarch64'): testutils.Color(24, 24, 24),
+ (None, None): testutils.Color(18, 18, 18),
+ (None, 'aarch64'): testutils.Color(16, 16, 16),
+ }
+ ),
+ (
+ 'blank',
+ 'lightness-hsl',
+ {
+ # FIXME:qt6 Why #121212 rather than #000000?
+ ('6.4', None): testutils.Color(18, 18, 18),
+ ('6.3', None): testutils.Color(18, 18, 18),
(None, None): testutils.Color(0, 0, 0),
}
),
- ('blank', 'lightness-hsl', {(None, None): testutils.Color(0, 0, 0)}),
- ('blank', 'brightness-rgb', {(None, None): testutils.Color(0, 0, 0)}),
+ (
+ 'blank',
+ 'brightness-rgb',
+ {
+ # FIXME:qt6 Why #121212 rather than #000000?
+ ('6.4', None): testutils.Color(18, 18, 18),
+ ('6.3', None): testutils.Color(18, 18, 18),
+ (None, None): testutils.Color(0, 0, 0)
+ }
+ ),
(
'yellow',
'lightness-cielab',
{
- ('5.15', None): testutils.Color(35, 34, 0),
- ('5.15', 'aarch64'): testutils.Color(33, 32, 0),
- ('5.14', None): testutils.Color(35, 34, 0),
- ('5.14', 'aarch64'): testutils.Color(33, 32, 0),
- (None, None): testutils.Color(204, 204, 0),
+ (None, None): testutils.Color(35, 34, 0),
+ (None, 'aarch64'): testutils.Color(33, 32, 0),
}
),
(
'yellow',
'lightness-hsl',
{
- (None, None): testutils.Color(204, 204, 0),
- (None, 'aarch64'): testutils.Color(206, 207, 0),
+ (None, None): testutils.Color(215, 215, 0),
+ (None, 'aarch64'): testutils.Color(214, 215, 0),
+ ('5.15', None): testutils.Color(204, 204, 0),
+ ('5.15', 'aarch64'): testutils.Color(206, 207, 0),
},
),
(
'yellow',
'brightness-rgb',
{
- (None, None): testutils.Color(0, 0, 204),
- (None, 'aarch64'): testutils.Color(0, 0, 206),
+ (None, None): testutils.Color(0, 0, 215),
+ (None, 'aarch64'): testutils.Color(0, 0, 214),
+ ('5.15', None): testutils.Color(0, 0, 204),
+ ('5.15', 'aarch64'): testutils.Color(0, 0, 206),
}
),
])
@@ -724,7 +746,7 @@ def test_dark_mode(webengine_versions, quteproc_new, request,
@pytest.mark.parametrize("suffix", ["inline", "display"])
-def test_dark_mode_mathml(quteproc_new, request, qtbot, suffix):
+def test_dark_mode_mathml(webengine_versions, quteproc_new, request, qtbot, suffix):
if not request.config.webengine:
pytest.skip("Skipped with QtWebKit")
@@ -739,7 +761,10 @@ def test_dark_mode_mathml(quteproc_new, request, qtbot, suffix):
quteproc_new.wait_for_js('Image loaded')
# First make sure loading finished by looking outside of the image
- expected = testutils.Color(0, 0, 206) if IS_ARM else testutils.Color(0, 0, 204)
+ if webengine_versions.webengine >= utils.VersionNumber(6):
+ expected = testutils.Color(0, 0, 214) if IS_ARM else testutils.Color(0, 0, 215)
+ else:
+ expected = testutils.Color(0, 0, 206) if IS_ARM else testutils.Color(0, 0, 204)
quteproc_new.get_screenshot(
probe_pos=QPoint(105, 0),
@@ -753,7 +778,6 @@ def test_dark_mode_mathml(quteproc_new, request, qtbot, suffix):
)
-@testutils.qt514
@pytest.mark.parametrize('value, preference', [
('true', 'Reduced motion'),
('false', 'No'),
@@ -787,8 +811,8 @@ def test_unavailable_backend(request, quteproc_new):
that the chosen backend is actually available - i.e., that the error message is
properly printed, rather than an unhandled exception.
"""
- qtwe_module = "PyQt5.QtWebEngineWidgets"
- qtwk_module = "PyQt5.QtWebKitWidgets"
+ qtwe_module = "qutebrowser.qt.webenginewidgets"
+ qtwk_module = "qutebrowser.qt.webkitwidgets"
# Note we want to try the *opposite* backend here.
if request.config.webengine:
pytest.importorskip(qtwe_module)
@@ -845,6 +869,13 @@ def test_sandboxing(
pytest.skip("Skipped with QtWebKit")
elif sandboxing == "enable-all" and testutils.disable_seccomp_bpf_sandbox():
pytest.skip("Full sandboxing not supported")
+ elif version.is_flatpak():
+ # https://github.com/flathub/io.qt.qtwebengine.BaseApp/pull/66
+ has_namespaces = False
+ expected_result = "You are NOT adequately sandboxed."
+ has_yama_non_broker = has_yama
+ else:
+ has_yama_non_broker = False
args = _base_args(request.config) + [
'--temp-basedir',
@@ -866,39 +897,21 @@ def test_sandboxing(
bpf_text = "Seccomp-BPF sandbox"
yama_text = "Ptrace Protection with Yama LSM"
- if "\n\n\n" in text:
- # Qt 5.12
- header, rest = text.split("\n", maxsplit=1)
- rest, result = rest.rsplit("\n\n", maxsplit=1)
- lines = rest.replace("\t\n", "\t").split("\n\n\n")
-
- expected_status = {
- "Namespace Sandbox": "Yes" if has_namespaces else "No",
- "Network namespaces": "Yes" if has_namespaces else "No",
- "PID namespaces": "Yes" if has_namespaces else "No",
- "SUID Sandbox": "No",
+ header, *lines, empty, result = text.split("\n")
+ assert not empty
- bpf_text: "Yes" if has_seccomp else "No",
- f"{bpf_text} supports TSYNC": "Yes" if has_seccomp else "No",
+ expected_status = {
+ "Layer 1 Sandbox": "Namespace" if has_namespaces else "None",
- "Yama LSM Enforcing": "Yes" if has_yama else "No",
- }
- else:
- header, *lines, empty, result = text.split("\n")
- assert not empty
+ "PID namespaces": "Yes" if has_namespaces else "No",
+ "Network namespaces": "Yes" if has_namespaces else "No",
- expected_status = {
- "Layer 1 Sandbox": "Namespace" if has_namespaces else "None",
+ bpf_text: "Yes" if has_seccomp else "No",
+ f"{bpf_text} supports TSYNC": "Yes" if has_seccomp else "No",
- "PID namespaces": "Yes" if has_namespaces else "No",
- "Network namespaces": "Yes" if has_namespaces else "No",
-
- bpf_text: "Yes" if has_seccomp else "No",
- f"{bpf_text} supports TSYNC": "Yes" if has_seccomp else "No",
-
- f"{yama_text} (Broker)": "Yes" if has_yama else "No",
- f"{yama_text} (Non-broker)": "No",
- }
+ f"{yama_text} (Broker)": "Yes" if has_yama else "No",
+ f"{yama_text} (Non-broker)": "Yes" if has_yama_non_broker else "No",
+ }
assert header == "Sandbox Status"
assert result == expected_result
diff --git a/tests/helpers/fixtures.py b/tests/helpers/fixtures.py
index 7a8931eac..d4744c67d 100644
--- a/tests/helpers/fixtures.py
+++ b/tests/helpers/fixtures.py
@@ -37,9 +37,9 @@ import dataclasses
import pytest
import py.path
-from PyQt5.QtCore import QSize, Qt
-from PyQt5.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout
-from PyQt5.QtNetwork import QNetworkCookieJar
+from qutebrowser.qt.core import QSize, Qt
+from qutebrowser.qt.widgets import QWidget, QHBoxLayout, QVBoxLayout
+from qutebrowser.qt.network import QNetworkCookieJar
import helpers.stubs as stubsmod
import qutebrowser
@@ -126,7 +126,7 @@ class FakeStatusBar(QWidget):
self.hbox = QHBoxLayout(self)
self.hbox.addStretch()
self.hbox.setContentsMargins(0, 0, 0, 0)
- self.setAttribute(Qt.WA_StyledBackground, True)
+ self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
self.setStyleSheet('background-color: red;')
def minimumSizeHint(self):
@@ -177,7 +177,7 @@ def testdata_scheme(qapp):
try:
global _qute_scheme_handler
from qutebrowser.browser.webengine import webenginequtescheme
- from PyQt5.QtWebEngineWidgets import QWebEngineProfile
+ from qutebrowser.qt.webenginecore import QWebEngineProfile
webenginequtescheme.init()
_qute_scheme_handler = webenginequtescheme.QuteSchemeHandler(
parent=qapp)
@@ -432,27 +432,30 @@ def unicode_encode_err():
@pytest.fixture(scope='session')
def qnam(qapp):
"""Session-wide QNetworkAccessManager."""
- from PyQt5.QtNetwork import QNetworkAccessManager
+ from qutebrowser.qt.network import QNetworkAccessManager
nam = QNetworkAccessManager()
- nam.setNetworkAccessible(QNetworkAccessManager.NotAccessible)
+ try:
+ nam.setNetworkAccessible(QNetworkAccessManager.NetworkAccessibility.NotAccessible)
+ except AttributeError:
+ # Qt 5 only, deprecated seemingly without replacement.
+ pass
return nam
@pytest.fixture
def webengineview(qtbot, monkeypatch, web_tab_setup):
"""Get a QWebEngineView if QtWebEngine is available."""
- QtWebEngineWidgets = pytest.importorskip('PyQt5.QtWebEngineWidgets')
+ QtWebEngineWidgets = pytest.importorskip('qutebrowser.qt.webenginewidgets')
monkeypatch.setattr(objects, 'backend', usertypes.Backend.QtWebEngine)
view = QtWebEngineWidgets.QWebEngineView()
qtbot.add_widget(view)
- yield view
- view.setPage(None) # Avoid warning if using QWebEngineProfile
+ return view
@pytest.fixture
def webpage(qnam, monkeypatch):
"""Get a new QWebPage object."""
- QtWebKitWidgets = pytest.importorskip('PyQt5.QtWebKitWidgets')
+ QtWebKitWidgets = pytest.importorskip('qutebrowser.qt.webkitwidgets')
monkeypatch.setattr(objects, 'backend', usertypes.Backend.QtWebKit)
class WebPageStub(QtWebKitWidgets.QWebPage):
@@ -477,7 +480,7 @@ def webpage(qnam, monkeypatch):
@pytest.fixture
def webview(qtbot, webpage):
"""Get a new QWebView object."""
- QtWebKitWidgets = pytest.importorskip('PyQt5.QtWebKitWidgets')
+ QtWebKitWidgets = pytest.importorskip('qutebrowser.qt.webkitwidgets')
view = QtWebKitWidgets.QWebView()
qtbot.add_widget(view)
@@ -734,7 +737,7 @@ def webengine_versions(testdata_scheme):
Calling qtwebengine_versions() initializes QtWebEngine, so we depend on
testdata_scheme here, to make sure that happens before.
"""
- pytest.importorskip('PyQt5.QtWebEngineWidgets')
+ pytest.importorskip('qutebrowser.qt.webenginewidgets')
return version.qtwebengine_versions()
diff --git a/tests/helpers/messagemock.py b/tests/helpers/messagemock.py
index 6f020618b..3ec882e54 100644
--- a/tests/helpers/messagemock.py
+++ b/tests/helpers/messagemock.py
@@ -22,7 +22,7 @@
import logging
import pytest
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
+from qutebrowser.qt.core import pyqtSlot, pyqtSignal, QObject
from qutebrowser.utils import usertypes, message
diff --git a/tests/helpers/stubs.py b/tests/helpers/stubs.py
index b71e0f3cf..134028012 100644
--- a/tests/helpers/stubs.py
+++ b/tests/helpers/stubs.py
@@ -30,11 +30,11 @@ import builtins
import importlib
import types
-from PyQt5.QtCore import pyqtSignal, QPoint, QProcess, QObject, QUrl, QByteArray
-from PyQt5.QtGui import QIcon
-from PyQt5.QtNetwork import (QNetworkRequest, QAbstractNetworkCache,
+from qutebrowser.qt.core import pyqtSignal, QPoint, QProcess, QObject, QUrl, QByteArray
+from qutebrowser.qt.gui import QIcon
+from qutebrowser.qt.network import (QNetworkRequest, QAbstractNetworkCache,
QNetworkCacheMetaData)
-from PyQt5.QtWidgets import QCommonStyle, QLineEdit, QWidget, QTabBar
+from qutebrowser.qt.widgets import QCommonStyle, QLineEdit, QWidget, QTabBar
from qutebrowser.browser import browsertab, downloads
from qutebrowser.utils import usertypes
@@ -135,7 +135,7 @@ class FakeNetworkReply:
"""QNetworkReply stub which provides a Content-Disposition header."""
KNOWN_HEADERS = {
- QNetworkRequest.ContentTypeHeader: 'Content-Type',
+ QNetworkRequest.KnownHeaders.ContentTypeHeader: 'Content-Type',
}
def __init__(self, headers=None, url=None):
@@ -302,17 +302,10 @@ class FakeSignal:
Attributes:
signal: The name of the signal, like pyqtSignal.
- _func: The function to be invoked when the signal gets called.
"""
- def __init__(self, name='fake', func=None):
+ def __init__(self, name='fake'):
self.signal = '2{}(int, int)'.format(name)
- self._func = func
-
- def __call__(self):
- if self._func is None:
- raise TypeError("'FakeSignal' object is not callable")
- return self._func()
def connect(self, slot):
"""Connect the signal to a slot.
diff --git a/tests/helpers/test_helper_utils.py b/tests/helpers/test_helper_utils.py
index 5d723429b..3a5f4c4bc 100644
--- a/tests/helpers/test_helper_utils.py
+++ b/tests/helpers/test_helper_utils.py
@@ -22,6 +22,8 @@ import pytest
from helpers import testutils
+from qutebrowser.qt.widgets import QFrame
+
@pytest.mark.parametrize('val1, val2', [
({'a': 1}, {'a': 1}),
@@ -78,3 +80,12 @@ def test_pattern_match(pattern, value, expected):
def test_nop_contextmanager():
with testutils.nop_contextmanager():
pass
+
+
+def test_enum_members():
+ expected = {
+ "Plain": QFrame.Shadow.Plain,
+ "Raised": QFrame.Shadow.Raised,
+ "Sunken": QFrame.Shadow.Sunken,
+ }
+ assert testutils.enum_members(QFrame, QFrame.Shadow) == expected
diff --git a/tests/helpers/testutils.py b/tests/helpers/testutils.py
index 4c6d253d7..0c8cdb8d0 100644
--- a/tests/helpers/testutils.py
+++ b/tests/helpers/testutils.py
@@ -21,6 +21,7 @@
import io
import re
+import enum
import gzip
import pprint
import os.path
@@ -31,17 +32,12 @@ import importlib.machinery
import pytest
-from PyQt5.QtGui import QColor
+from qutebrowser.qt.gui import QColor
-from qutebrowser.utils import qtutils, log, utils, version
+from qutebrowser.utils import log, utils, version
ON_CI = 'CI' in os.environ
-qt513 = pytest.mark.skipif(
- not qtutils.version_check('5.13'), reason="Needs Qt 5.13 or newer")
-qt514 = pytest.mark.skipif(
- not qtutils.version_check('5.14'), reason="Needs Qt 5.14 or newer")
-
class Color(QColor):
@@ -273,27 +269,13 @@ def disable_seccomp_bpf_sandbox():
newer kernels.
"""
try:
- from PyQt5 import QtWebEngine # pylint: disable=unused-import
+ from qutebrowser.qt import webenginecore # pylint: disable=unused-import
except ImportError:
# no QtWebEngine available
return False
- affected_versions = set()
- for base, patch_range in [
- # 5.12.0 to 5.12.10 (inclusive)
- ('5.12', range(0, 11)),
- # 5.13.0 to 5.13.2 (inclusive)
- ('5.13', range(0, 3)),
- # 5.14.0
- ('5.14', [0]),
- # 5.15.0 to 5.15.2 (inclusive)
- ('5.15', range(0, 3)),
- ]:
- for patch in patch_range:
- affected_versions.add(utils.VersionNumber.parse(f'{base}.{patch}'))
-
versions = version.qtwebengine_versions(avoid_init=True)
- return versions.webengine in affected_versions
+ return versions.webengine == utils.VersionNumber(5, 15, 2)
def import_userscript(name):
@@ -311,3 +293,17 @@ def import_userscript(name):
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
+
+
+def enum_members(base, enumtype):
+ """Get all members of a Qt enum."""
+ if issubclass(enumtype, enum.Enum):
+ # PyQt 6
+ return {m.name: m for m in enumtype}
+ else:
+ # PyQt 5
+ return {
+ name: value
+ for name, value in vars(base).items()
+ if isinstance(value, enumtype)
+ }
diff --git a/tests/unit/browser/test_browsertab.py b/tests/unit/browser/test_browsertab.py
new file mode 100644
index 000000000..60ae0942e
--- /dev/null
+++ b/tests/unit/browser/test_browsertab.py
@@ -0,0 +1,48 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+
+# Copyright 2022 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
+#
+# This file is part of qutebrowser.
+#
+# qutebrowser is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# qutebrowser is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+
+import pytest
+
+from qutebrowser.qt.core import QUrl
+from qutebrowser.browser import browsertab
+
+
+class TestAction:
+
+ def test_run_string_valid(self, qtbot, web_tab):
+ url_1 = QUrl("qute://testdata/data/backforward/1.txt")
+ url_2 = QUrl("qute://testdata/data/backforward/2.txt")
+
+ with qtbot.wait_signal(web_tab.load_finished):
+ web_tab.load_url(url_1)
+ with qtbot.wait_signal(web_tab.load_finished):
+ web_tab.load_url(url_2)
+
+ assert web_tab.url() == url_2
+ with qtbot.wait_signal(web_tab.load_finished):
+ web_tab.action.run_string("Back")
+ assert web_tab.url() == url_1
+
+ @pytest.mark.parametrize("member", ["blah", "PermissionUnknown"])
+ def test_run_string_invalid(self, qtbot, web_tab, member):
+ with pytest.raises(
+ browsertab.WebTabError,
+ match=f"{member} is not a valid web action!",
+ ):
+ web_tab.action.run_string(member)
diff --git a/tests/unit/browser/test_caret.py b/tests/unit/browser/test_caret.py
index 85301e358..60c401e4f 100644
--- a/tests/unit/browser/test_caret.py
+++ b/tests/unit/browser/test_caret.py
@@ -22,7 +22,7 @@
import textwrap
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.utils import usertypes
from qutebrowser.browser import browsertab
diff --git a/tests/unit/browser/test_downloadview.py b/tests/unit/browser/test_downloadview.py
index 84b50fad2..a64b6c12e 100644
--- a/tests/unit/browser/test_downloadview.py
+++ b/tests/unit/browser/test_downloadview.py
@@ -20,7 +20,7 @@
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.browser import downloads, qtnetworkdownloads, downloadview
diff --git a/tests/unit/browser/test_hints.py b/tests/unit/browser/test_hints.py
index 85c0a642c..403af74f8 100644
--- a/tests/unit/browser/test_hints.py
+++ b/tests/unit/browser/test_hints.py
@@ -23,7 +23,7 @@ import itertools
import operator
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.utils import usertypes
import qutebrowser.browser.hints
diff --git a/tests/unit/browser/test_history.py b/tests/unit/browser/test_history.py
index 268f21a08..4997567d3 100644
--- a/tests/unit/browser/test_history.py
+++ b/tests/unit/browser/test_history.py
@@ -22,7 +22,7 @@
import logging
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.browser import history
from qutebrowser.utils import urlutils, usertypes
@@ -276,7 +276,7 @@ class TestHistoryInterface:
@pytest.fixture
def hist_interface(self, web_history):
# pylint: disable=invalid-name
- QtWebKit = pytest.importorskip('PyQt5.QtWebKit')
+ QtWebKit = pytest.importorskip('qutebrowser.qt.webkit')
from qutebrowser.browser.webkit import webkithistory
QWebHistoryInterface = QtWebKit.QWebHistoryInterface
# pylint: enable=invalid-name
@@ -304,7 +304,7 @@ class TestInit:
history.web_history.setParent(None)
history.web_history = None
try:
- from PyQt5.QtWebKit import QWebHistoryInterface
+ from qutebrowser.qt.webkit import QWebHistoryInterface
QWebHistoryInterface.setDefaultInterface(None)
except ImportError:
pass
@@ -313,7 +313,7 @@ class TestInit:
usertypes.Backend.QtWebKit])
def test_init(self, backend, qapp, tmpdir, data_tmpdir, monkeypatch, cleanup_init):
if backend == usertypes.Backend.QtWebKit:
- pytest.importorskip('PyQt5.QtWebKitWidgets')
+ pytest.importorskip('qutebrowser.qt.webkitwidgets')
else:
assert backend == usertypes.Backend.QtWebEngine
@@ -322,7 +322,7 @@ class TestInit:
assert history.web_history.parent() is qapp
try:
- from PyQt5.QtWebKit import QWebHistoryInterface
+ from qutebrowser.qt.webkit import QWebHistoryInterface
except ImportError:
QWebHistoryInterface = None
diff --git a/tests/unit/browser/test_inspector.py b/tests/unit/browser/test_inspector.py
index 61ac9510d..35b570482 100644
--- a/tests/unit/browser/test_inspector.py
+++ b/tests/unit/browser/test_inspector.py
@@ -19,7 +19,7 @@
import pytest
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt.widgets import QWidget
from qutebrowser.browser import inspector
from qutebrowser.misc import miscwidgets
diff --git a/tests/unit/browser/test_navigate.py b/tests/unit/browser/test_navigate.py
index 7c3173602..b96624d0a 100644
--- a/tests/unit/browser/test_navigate.py
+++ b/tests/unit/browser/test_navigate.py
@@ -20,7 +20,7 @@
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.browser import navigate
from qutebrowser.utils import urlutils
diff --git a/tests/unit/browser/test_notification.py b/tests/unit/browser/test_notification.py
index e79c2e03b..e77b86c1a 100644
--- a/tests/unit/browser/test_notification.py
+++ b/tests/unit/browser/test_notification.py
@@ -25,26 +25,18 @@ import inspect
from typing import List, Dict, Any, Optional, TYPE_CHECKING
import pytest
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, QObject
-from PyQt5.QtGui import QImage
-from PyQt5.QtDBus import QDBusMessage, QDBus, QDBusConnection
-pytest.importorskip("PyQt5.QtWebEngineCore")
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QUrl, QObject
+from qutebrowser.qt.gui import QImage
+from qutebrowser.qt.dbus import QDBusMessage, QDBus, QDBusConnection
+pytest.importorskip("qutebrowser.qt.webenginecore")
if TYPE_CHECKING:
- from PyQt5.QtWebEngineCore import QWebEngineNotification
+ from qutebrowser.qt.webenginecore import QWebEngineNotification
from qutebrowser.config import configdata
from qutebrowser.misc import objects
from qutebrowser.browser.webengine import notification
-pytestmark = [
- pytest.mark.qtwebengine_notifications,
- # 5.13 only supports the default presenter
- pytest.mark.skipif(not notification._notifications_supported(),
- reason="Notifications not supported")
-]
-
-
class FakeDBusMessage:
def __init__(
diff --git a/tests/unit/browser/test_pdfjs.py b/tests/unit/browser/test_pdfjs.py
index c1e8d2efe..d002a3823 100644
--- a/tests/unit/browser/test_pdfjs.py
+++ b/tests/unit/browser/test_pdfjs.py
@@ -21,7 +21,7 @@ import logging
import os.path
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.browser import pdfjs
from qutebrowser.utils import urlmatch
@@ -52,7 +52,7 @@ def test_generate_pdfjs_page(available, snippet, monkeypatch):
assert snippet in content
-# Note that we got double protection, once because we use QUrl.FullyEncoded and
+# Note that we got double protection, once because we use QUrl.ComponentFormattingOption.FullyEncoded and
# because we use qutebrowser.utils.javascript.to_js. Characters like " are
# already replaced by QUrl.
@pytest.mark.parametrize('filename, expected', [
diff --git a/tests/unit/browser/test_qutescheme.py b/tests/unit/browser/test_qutescheme.py
index e4aa51243..3caee5621 100644
--- a/tests/unit/browser/test_qutescheme.py
+++ b/tests/unit/browser/test_qutescheme.py
@@ -24,11 +24,11 @@ import time
import logging
import py.path
-from PyQt5.QtCore import QUrl, QUrlQuery
+from qutebrowser.qt.core import QUrl, QUrlQuery
import pytest
from qutebrowser.browser import qutescheme, pdfjs, downloads
-from qutebrowser.utils import resources
+from qutebrowser.utils import resources, urlmatch
from qutebrowser.misc import guiprocess
@@ -291,3 +291,37 @@ class TestPDFJSHandler:
url.setQuery(query)
with pytest.raises(qutescheme.RequestDeniedError):
qutescheme.data_for_url(url)
+
+
+class TestQuteConfigdiff:
+
+ """Test the qute://configdiff handler."""
+
+ @pytest.fixture(autouse=True)
+ def prepare_config(self, config_stub):
+ config_stub.set_obj(
+ "content.javascript.enabled",
+ True,
+ pattern=urlmatch.UrlPattern("chrome-devtools://*"),
+ hide_userconfig=True,
+ )
+
+ @pytest.mark.parametrize("url, expected", [
+ (
+ "qute://configdiff/",
+ b"<Default configuration>",
+ ),
+ (
+ "qute://configdiff/?include_hidden=true",
+ b'chrome-devtools://*: content.javascript.enabled = true',
+ )
+ ])
+ def test_default_config(self, config_stub, url, expected):
+ _mimetype, data = qutescheme.data_for_url(QUrl(url))
+ assert data == expected
+
+ def test_changes(self, config_stub):
+ config_stub.set_obj("content.images", False)
+ url = QUrl('qute://configdiff/')
+ _mimetype, data = qutescheme.data_for_url(url)
+ assert data == b'content.images = false'
diff --git a/tests/unit/browser/test_signalfilter.py b/tests/unit/browser/test_signalfilter.py
index 35c7f3557..05e02bfd5 100644
--- a/tests/unit/browser/test_signalfilter.py
+++ b/tests/unit/browser/test_signalfilter.py
@@ -23,7 +23,7 @@ import logging
import dataclasses
import pytest
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
+from qutebrowser.qt.core import pyqtSignal, pyqtSlot, QObject
from qutebrowser.browser import signalfilter
diff --git a/tests/unit/browser/test_urlmarks.py b/tests/unit/browser/test_urlmarks.py
index 6b8d429a9..d2bac7692 100644
--- a/tests/unit/browser/test_urlmarks.py
+++ b/tests/unit/browser/test_urlmarks.py
@@ -22,7 +22,7 @@
import unittest.mock
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.browser import urlmarks
diff --git a/tests/unit/browser/webengine/test_darkmode.py b/tests/unit/browser/webengine/test_darkmode.py
index 3f5272dab..eab7af511 100644
--- a/tests/unit/browser/webengine/test_darkmode.py
+++ b/tests/unit/browser/webengine/test_darkmode.py
@@ -24,7 +24,6 @@ from qutebrowser.config import configdata
from qutebrowser.utils import usertypes, version, utils
from qutebrowser.browser.webengine import darkmode
from qutebrowser.misc import objects
-from helpers import testutils
@pytest.fixture(autouse=True)
@@ -43,38 +42,25 @@ def gentoo_versions():
@pytest.mark.parametrize('value, webengine_version, expected', [
# Auto
- ("auto", "5.14", []),
- ("auto", "5.15.0", []),
- ("auto", "5.15.1", []),
("auto", "5.15.2", [("preferredColorScheme", "2")]), # QTBUG-89753
("auto", "5.15.3", []),
- ("auto", "6.0.0", []),
+ ("auto", "6.2.0", []),
# Unset
- (None, "5.14", []),
- (None, "5.15.0", []),
- (None, "5.15.1", []),
(None, "5.15.2", [("preferredColorScheme", "2")]), # QTBUG-89753
(None, "5.15.3", []),
- (None, "6.0.0", []),
+ (None, "6.2.0", []),
# Dark
- ("dark", "5.14", []),
- ("dark", "5.15.0", []),
- ("dark", "5.15.1", []),
("dark", "5.15.2", [("preferredColorScheme", "1")]),
("dark", "5.15.3", [("preferredColorScheme", "0")]),
- ("dark", "6.0.0", [("preferredColorScheme", "0")]),
+ ("dark", "6.2.0", [("preferredColorScheme", "0")]),
# Light
- ("light", "5.14", []),
- ("light", "5.15.0", []),
- ("light", "5.15.1", []),
("light", "5.15.2", [("preferredColorScheme", "2")]),
("light", "5.15.3", [("preferredColorScheme", "1")]),
- ("light", "6.0.0", [("preferredColorScheme", "1")]),
+ ("light", "6.2.0", [("preferredColorScheme", "1")]),
])
-@testutils.qt514
def test_colorscheme(config_stub, value, webengine_version, expected):
versions = version.WebEngineVersions.from_pyqt(webengine_version)
if value is not None:
@@ -84,7 +70,6 @@ def test_colorscheme(config_stub, value, webengine_version, expected):
assert darkmode_settings['blink-settings'] == expected
-@testutils.qt514
def test_colorscheme_gentoo_workaround(config_stub, gentoo_versions):
config_stub.val.colors.webpage.preferred_color_scheme = "dark"
darkmode_settings = darkmode.settings(versions=gentoo_versions, special_flags=[])
@@ -93,17 +78,26 @@ def test_colorscheme_gentoo_workaround(config_stub, gentoo_versions):
@pytest.mark.parametrize('settings, expected', [
# Disabled
- ({}, []),
+ ({}, [('preferredColorScheme', '2')]),
# Enabled without customization
- ({'enabled': True}, [('darkModeEnabled', 'true')]),
+ (
+ {'enabled': True},
+ [
+ ('preferredColorScheme', '2'),
+ ('forceDarkModeEnabled', 'true'),
+ ('forceDarkModeImagePolicy', '2'),
+ ]
+ ),
# Algorithm
(
{'enabled': True, 'algorithm': 'brightness-rgb'},
[
- ('darkModeEnabled', 'true'),
- ('darkModeInversionAlgorithm', '2')
+ ('preferredColorScheme', '2'),
+ ('forceDarkModeEnabled', 'true'),
+ ('forceDarkModeInversionAlgorithm', '2'),
+ ('forceDarkModeImagePolicy', '2'),
],
),
])
@@ -111,37 +105,12 @@ def test_basics(config_stub, settings, expected):
for k, v in settings.items():
config_stub.set_obj('colors.webpage.darkmode.' + k, v)
- if expected:
- expected.append(('darkModeImagePolicy', '2'))
-
- # Using Qt 5.15.1 because it has the least special cases.
- versions = version.WebEngineVersions.from_pyqt('5.15.1')
+ # Using Qt 5.15.2 because it has the least special cases.
+ versions = version.WebEngineVersions.from_pyqt('5.15.2')
darkmode_settings = darkmode.settings(versions=versions, special_flags=[])
assert darkmode_settings['blink-settings'] == expected
-QT_514_SETTINGS = {'blink-settings': [
- ('darkMode', '2'),
- ('darkModeImagePolicy', '2'),
- ('darkModeGrayscale', 'true'),
-]}
-
-
-QT_515_0_SETTINGS = {'blink-settings': [
- ('darkModeEnabled', 'true'),
- ('darkModeInversionAlgorithm', '2'),
- ('darkModeGrayscale', 'true'),
-]}
-
-
-QT_515_1_SETTINGS = {'blink-settings': [
- ('darkModeEnabled', 'true'),
- ('darkModeInversionAlgorithm', '2'),
- ('darkModeImagePolicy', '2'),
- ('darkModeGrayscale', 'true'),
-]}
-
-
QT_515_2_SETTINGS = {'blink-settings': [
('preferredColorScheme', '2'), # QTBUG-89753
('forceDarkModeEnabled', 'true'),
@@ -162,13 +131,6 @@ QT_515_3_SETTINGS = {
@pytest.mark.parametrize('qversion, expected', [
- ('5.14.0', QT_514_SETTINGS),
- ('5.14.1', QT_514_SETTINGS),
- ('5.14.2', QT_514_SETTINGS),
-
- ('5.15.0', QT_515_0_SETTINGS),
- ('5.15.1', QT_515_1_SETTINGS),
-
('5.15.2', QT_515_2_SETTINGS),
('5.15.3', QT_515_3_SETTINGS),
])
@@ -186,7 +148,6 @@ def test_qt_version_differences(config_stub, qversion, expected):
assert darkmode_settings == expected
-@testutils.qt514
@pytest.mark.parametrize('setting, value, exp_key, exp_val', [
('contrast', -0.5,
'Contrast', '-0.5'),
@@ -207,25 +168,23 @@ def test_customization(config_stub, setting, value, exp_key, exp_val):
config_stub.val.colors.webpage.darkmode.enabled = True
config_stub.set_obj('colors.webpage.darkmode.' + setting, value)
- expected = []
- expected.append(('darkModeEnabled', 'true'))
+ expected = [
+ ('preferredColorScheme', '2'),
+ ('forceDarkModeEnabled', 'true'),
+ ]
if exp_key != 'ImagePolicy':
- expected.append(('darkModeImagePolicy', '2'))
- expected.append(('darkMode' + exp_key, exp_val))
+ expected.append(('forceDarkModeImagePolicy', '2'))
+ expected.append(('forceDarkMode' + exp_key, exp_val))
- versions = version.WebEngineVersions.from_pyqt('5.15.1')
+ versions = version.WebEngineVersions.from_pyqt('5.15.2')
darkmode_settings = darkmode.settings(versions=versions, special_flags=[])
assert darkmode_settings['blink-settings'] == expected
@pytest.mark.parametrize('webengine_version, expected', [
- ('5.13.0', darkmode.Variant.qt_511_to_513),
- ('5.14.0', darkmode.Variant.qt_514),
- ('5.15.0', darkmode.Variant.qt_515_0),
- ('5.15.1', darkmode.Variant.qt_515_1),
('5.15.2', darkmode.Variant.qt_515_2),
('5.15.3', darkmode.Variant.qt_515_3),
- ('6.0.0', darkmode.Variant.qt_515_3),
+ ('6.2.0', darkmode.Variant.qt_515_3),
])
def test_variant(webengine_version, expected):
versions = version.WebEngineVersions.from_pyqt(webengine_version)
@@ -237,11 +196,11 @@ def test_variant_gentoo_workaround(gentoo_versions):
@pytest.mark.parametrize('value, is_valid, expected', [
- ('invalid_value', False, darkmode.Variant.qt_515_0),
+ ('invalid_value', False, darkmode.Variant.qt_515_3),
('qt_515_2', True, darkmode.Variant.qt_515_2),
])
def test_variant_override(monkeypatch, caplog, value, is_valid, expected):
- versions = version.WebEngineVersions.from_pyqt('5.15.0')
+ versions = version.WebEngineVersions.from_pyqt('5.15.3')
monkeypatch.setenv('QUTE_DARKMODE_VARIANT', value)
with caplog.at_level(logging.WARNING):
@@ -251,25 +210,6 @@ def test_variant_override(monkeypatch, caplog, value, is_valid, expected):
assert (log_msg in caplog.messages) != is_valid
-def test_broken_smart_images_policy(config_stub, caplog):
- config_stub.val.colors.webpage.darkmode.enabled = True
- config_stub.val.colors.webpage.darkmode.policy.images = 'smart'
- versions = version.WebEngineVersions.from_pyqt('5.15.0')
-
- with caplog.at_level(logging.WARNING):
- darkmode_settings = darkmode.settings(versions=versions, special_flags=[])
-
- assert caplog.messages[-1] == (
- 'Ignoring colors.webpage.darkmode.policy.images = smart because of '
- 'Qt 5.15.0 bug')
-
- expected = [
- [('darkModeEnabled', 'true')], # Qt 5.15
- [('darkMode', '4')], # Qt 5.14
- ]
- assert darkmode_settings['blink-settings'] in expected
-
-
@pytest.mark.parametrize('flag, expected', [
('--blink-settings=key=value', [('key', 'value')]),
('--blink-settings=key=equal=rights', [('key', 'equal=rights')]),
@@ -278,12 +218,13 @@ def test_broken_smart_images_policy(config_stub, caplog):
])
def test_pass_through_existing_settings(config_stub, flag, expected):
config_stub.val.colors.webpage.darkmode.enabled = True
- versions = version.WebEngineVersions.from_pyqt('5.15.1')
+ versions = version.WebEngineVersions.from_pyqt('5.15.2')
settings = darkmode.settings(versions=versions, special_flags=[flag])
dark_mode_expected = [
- ('darkModeEnabled', 'true'),
- ('darkModeImagePolicy', '2'),
+ ('preferredColorScheme', '2'),
+ ('forceDarkModeEnabled', 'true'),
+ ('forceDarkModeImagePolicy', '2'),
]
assert settings['blink-settings'] == expected + dark_mode_expected
@@ -303,4 +244,3 @@ def test_options(configdata_init):
if opt.raw_backends is not None:
assert not opt.raw_backends['QtWebKit'], name
- assert opt.raw_backends['QtWebEngine'] == 'Qt 5.14', name
diff --git a/tests/unit/browser/webengine/test_webengine_cookies.py b/tests/unit/browser/webengine/test_webengine_cookies.py
index 1a74dfb3e..ff8668ed3 100644
--- a/tests/unit/browser/webengine/test_webengine_cookies.py
+++ b/tests/unit/browser/webengine/test_webengine_cookies.py
@@ -18,10 +18,9 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import pytest
-from PyQt5.QtCore import QUrl
-pytest.importorskip('PyQt5.QtWebEngineCore')
-from PyQt5.QtWebEngineCore import QWebEngineCookieStore
-from PyQt5.QtWebEngineWidgets import QWebEngineProfile
+from qutebrowser.qt.core import QUrl
+pytest.importorskip('qutebrowser.qt.webenginecore')
+from qutebrowser.qt.webenginecore import QWebEngineCookieStore, QWebEngineProfile
from qutebrowser.browser.webengine import cookies
from qutebrowser.utils import urlmatch
diff --git a/tests/unit/browser/webengine/test_webenginedownloads.py b/tests/unit/browser/webengine/test_webenginedownloads.py
index 877af3c9a..3902b9f2b 100644
--- a/tests/unit/browser/webengine/test_webenginedownloads.py
+++ b/tests/unit/browser/webengine/test_webenginedownloads.py
@@ -17,13 +17,12 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
-import os.path
import base64
import dataclasses
import pytest
-pytest.importorskip('PyQt5.QtWebEngineWidgets')
-from PyQt5.QtWebEngineWidgets import QWebEngineProfile
+pytest.importorskip('qutebrowser.qt.webenginecore')
+from qutebrowser.qt.webenginecore import QWebEngineProfile
from qutebrowser.utils import urlutils, usertypes, utils
from qutebrowser.browser.webengine import webenginedownloads
@@ -154,7 +153,8 @@ class TestDataUrlWorkaround:
def check_item(item):
assert item.mimeType() == 'application/pdf'
assert item.url().scheme() == 'data'
- assert os.path.basename(item.path()) == expected_names.before
+ assert item.downloadFileName() == expected_names.before
+
return True
with qtbot.wait_signal(webengine_profile.downloadRequested,
diff --git a/tests/unit/browser/webengine/test_webengineinterceptor.py b/tests/unit/browser/webengine/test_webengineinterceptor.py
index eb71e0c6e..f48d4a715 100644
--- a/tests/unit/browser/webengine/test_webengineinterceptor.py
+++ b/tests/unit/browser/webengine/test_webengineinterceptor.py
@@ -22,22 +22,26 @@
import pytest
-pytest.importorskip('PyQt5.QtWebEngineWidgets')
+pytest.importorskip('qutebrowser.qt.webenginecore')
-from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInfo
+from qutebrowser.qt.webenginecore import QWebEngineUrlRequestInfo
from qutebrowser.browser.webengine import interceptor
+from qutebrowser.utils import qtutils
+from helpers import testutils
def test_no_missing_resource_types():
request_interceptor = interceptor.RequestInterceptor()
- qb_keys = request_interceptor._resource_types.keys()
- qt_keys = {i for i in vars(QWebEngineUrlRequestInfo).values()
- if isinstance(i, QWebEngineUrlRequestInfo.ResourceType)}
+ qb_keys = set(request_interceptor._resource_types.keys())
+ qt_keys = set(testutils.enum_members(
+ QWebEngineUrlRequestInfo,
+ QWebEngineUrlRequestInfo.ResourceType,
+ ).values())
assert qt_keys == qb_keys
def test_resource_type_values():
request_interceptor = interceptor.RequestInterceptor()
for qt_value, qb_item in request_interceptor._resource_types.items():
- assert qt_value == qb_item.value
+ assert qtutils.extract_enum_val(qt_value) == qb_item.value
diff --git a/tests/unit/browser/webengine/test_webenginesettings.py b/tests/unit/browser/webengine/test_webenginesettings.py
index 111323af5..838ddd1b2 100644
--- a/tests/unit/browser/webengine/test_webenginesettings.py
+++ b/tests/unit/browser/webengine/test_webenginesettings.py
@@ -21,11 +21,12 @@ import logging
import pytest
-QtWebEngineWidgets = pytest.importorskip('PyQt5.QtWebEngineWidgets')
-QWebEngineSettings = QtWebEngineWidgets.QWebEngineSettings
+QtWebEngineCore = pytest.importorskip('qutebrowser.qt.webenginecore')
+QWebEngineSettings = QtWebEngineCore.QWebEngineSettings
from qutebrowser.browser.webengine import webenginesettings
from qutebrowser.utils import usertypes
+from qutebrowser.config import configdata
@pytest.fixture
@@ -46,7 +47,7 @@ def default_profile(monkeypatch):
Note we use a "private" profile here to avoid actually storing data during tests.
"""
- profile = QtWebEngineWidgets.QWebEngineProfile()
+ profile = QtWebEngineCore.QWebEngineProfile()
profile.setter = webenginesettings.ProfileSetter(profile)
monkeypatch.setattr(profile, 'isOffTheRecord', lambda: False)
monkeypatch.setattr(webenginesettings, 'default_profile', profile)
@@ -56,7 +57,7 @@ def default_profile(monkeypatch):
@pytest.fixture
def private_profile(monkeypatch):
"""A profile to use which is set as private_profile."""
- profile = QtWebEngineWidgets.QWebEngineProfile()
+ profile = QtWebEngineCore.QWebEngineProfile()
profile.setter = webenginesettings.ProfileSetter(profile)
monkeypatch.setattr(webenginesettings, 'private_profile', profile)
return profile
@@ -164,3 +165,8 @@ def test_parsed_user_agent(qapp):
parsed = webenginesettings.parsed_user_agent
assert parsed.upstream_browser_key == 'Chrome'
assert parsed.qt_key == 'QtWebEngine'
+
+
+def test_profile_setter_settings(private_profile, configdata_init):
+ for setting in private_profile.setter._name_to_method:
+ assert setting in set(configdata.DATA)
diff --git a/tests/unit/browser/webengine/test_webenginetab.py b/tests/unit/browser/webengine/test_webenginetab.py
index 30807bb4e..c5c611065 100644
--- a/tests/unit/browser/webengine/test_webenginetab.py
+++ b/tests/unit/browser/webengine/test_webenginetab.py
@@ -23,10 +23,10 @@ import logging
import textwrap
import pytest
-QtWebEngineWidgets = pytest.importorskip("PyQt5.QtWebEngineWidgets")
-QWebEnginePage = QtWebEngineWidgets.QWebEnginePage
-QWebEngineScriptCollection = QtWebEngineWidgets.QWebEngineScriptCollection
-QWebEngineScript = QtWebEngineWidgets.QWebEngineScript
+QtWebEngineCore = pytest.importorskip("qutebrowser.qt.webenginecore")
+QWebEnginePage = QtWebEngineCore.QWebEnginePage
+QWebEngineScriptCollection = QtWebEngineCore.QWebEngineScriptCollection
+QWebEngineScript = QtWebEngineCore.QWebEngineScript
from qutebrowser.browser import greasemonkey
from qutebrowser.utils import usertypes
@@ -131,17 +131,17 @@ class TestWebengineScripts:
scripts_helper.inject(scripts)
script = scripts_helper.get_script()
- assert script.injectionPoint() == QWebEngineScript.DocumentReady
+ assert script.injectionPoint() == QWebEngineScript.InjectionPoint.DocumentReady
@pytest.mark.parametrize('run_at, expected', [
# UserScript::DocumentElementCreation
- ('document-start', QWebEngineScript.DocumentCreation),
+ ('document-start', QWebEngineScript.InjectionPoint.DocumentCreation),
# UserScript::DocumentLoadFinished
- ('document-end', QWebEngineScript.DocumentReady),
+ ('document-end', QWebEngineScript.InjectionPoint.DocumentReady),
# UserScript::AfterLoad
- ('document-idle', QWebEngineScript.Deferred),
+ ('document-idle', QWebEngineScript.InjectionPoint.Deferred),
# default according to https://wiki.greasespot.net/Metadata_Block#.40run-at
- (None, QWebEngineScript.DocumentReady),
+ (None, QWebEngineScript.InjectionPoint.DocumentReady),
])
def test_greasemonkey_run_at_values(self, scripts_helper, run_at, expected):
if run_at is None:
@@ -204,18 +204,6 @@ class TestWebengineScripts:
scripts_helper.inject([script3])
-def test_notification_permission_workaround():
- """Make sure the value for QWebEnginePage::Notifications is correct."""
- try:
- notifications = QWebEnginePage.Notifications
- except AttributeError:
- pytest.skip("No Notifications member")
-
- permissions = webenginetab._WebEnginePermissions
- assert permissions._options[notifications] == 'content.notifications.enabled'
- assert permissions._messages[notifications] == 'show notifications'
-
-
class TestFindFlags:
@pytest.mark.parametrize("case_sensitive, backward, expected", [
diff --git a/tests/unit/browser/webengine/test_webview.py b/tests/unit/browser/webengine/test_webview.py
new file mode 100644
index 000000000..2ddcc8733
--- /dev/null
+++ b/tests/unit/browser/webengine/test_webview.py
@@ -0,0 +1,75 @@
+# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
+
+# Copyright 2022 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
+#
+# This file is part of qutebrowser.
+#
+# qutebrowser is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# qutebrowser is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+
+import re
+import dataclasses
+
+import pytest
+webview = pytest.importorskip('qutebrowser.browser.webengine.webview')
+
+from qutebrowser.qt.webenginecore import QWebEnginePage
+
+from helpers import testutils
+
+
+@dataclasses.dataclass
+class Naming:
+
+ prefix: str = ""
+ suffix: str = ""
+
+
+def camel_to_snake(naming, name):
+ if naming.prefix:
+ assert name.startswith(naming.prefix)
+ name = name[len(naming.prefix):]
+ if naming.suffix:
+ assert name.endswith(naming.suffix)
+ name = name[:-len(naming.suffix)]
+ # https://stackoverflow.com/a/1176023
+ return re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
+
+
+@pytest.mark.parametrize("naming, name, expected", [
+ (Naming(prefix="NavigationType"), "NavigationTypeLinkClicked", "link_clicked"),
+ (Naming(prefix="NavigationType"), "NavigationTypeTyped", "typed"),
+ (Naming(prefix="NavigationType"), "NavigationTypeBackForward", "back_forward"),
+ (Naming(suffix="MessageLevel"), "InfoMessageLevel", "info"),
+])
+def test_camel_to_snake(naming, name, expected):
+ assert camel_to_snake(naming, name) == expected
+
+
+@pytest.mark.parametrize("enum_type, naming, mapping", [
+ (
+ QWebEnginePage.JavaScriptConsoleMessageLevel,
+ Naming(suffix="MessageLevel"),
+ webview.WebEnginePage._JS_LOG_LEVEL_MAPPING,
+ ),
+ (
+ QWebEnginePage.NavigationType,
+ Naming(prefix="NavigationType"),
+ webview.WebEnginePage._NAVIGATION_TYPE_MAPPING,
+ )
+])
+def test_enum_mappings(enum_type, naming, mapping):
+ members = testutils.enum_members(QWebEnginePage, enum_type).items()
+ for name, val in members:
+ mapped = mapping[val]
+ assert camel_to_snake(naming, name) == mapped.name
diff --git a/tests/unit/browser/webkit/http/test_http.py b/tests/unit/browser/webkit/http/test_http.py
index d50f1c277..3e1a23105 100644
--- a/tests/unit/browser/webkit/http/test_http.py
+++ b/tests/unit/browser/webkit/http/test_http.py
@@ -24,7 +24,7 @@ import logging
import pytest
import hypothesis
from hypothesis import strategies
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.browser.webkit import http
diff --git a/tests/unit/browser/webkit/network/test_filescheme.py b/tests/unit/browser/webkit/network/test_filescheme.py
index 6d8b93fea..4f9d22108 100644
--- a/tests/unit/browser/webkit/network/test_filescheme.py
+++ b/tests/unit/browser/webkit/network/test_filescheme.py
@@ -24,8 +24,8 @@ from typing import List
import pytest
import bs4
-from PyQt5.QtCore import QUrl
-from PyQt5.QtNetwork import QNetworkRequest
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.network import QNetworkRequest
from qutebrowser.browser.webkit.network import filescheme
from qutebrowser.utils import urlutils, utils
diff --git a/tests/unit/browser/webkit/network/test_networkreply.py b/tests/unit/browser/webkit/network/test_networkreply.py
index 3cffb2fd7..fc400c1b2 100644
--- a/tests/unit/browser/webkit/network/test_networkreply.py
+++ b/tests/unit/browser/webkit/network/test_networkreply.py
@@ -21,8 +21,8 @@
import pytest
-from PyQt5.QtCore import QUrl, QIODevice
-from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
+from qutebrowser.qt.core import QUrl, QIODevice
+from qutebrowser.qt.network import QNetworkRequest, QNetworkReply
from qutebrowser.browser.webkit.network import networkreply
@@ -38,11 +38,11 @@ class TestFixedDataNetworkReply:
reply = networkreply.FixedDataNetworkReply(req, b'', 'test/foo')
assert reply.request() == req
assert reply.url() == req.url()
- assert reply.openMode() == QIODevice.ReadOnly
- assert reply.header(QNetworkRequest.ContentTypeHeader) == 'test/foo'
- http_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
+ assert reply.openMode() == QIODevice.OpenModeFlag.ReadOnly
+ assert reply.header(QNetworkRequest.KnownHeaders.ContentTypeHeader) == 'test/foo'
+ http_code = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute)
http_reason = reply.attribute(
- QNetworkRequest.HttpReasonPhraseAttribute)
+ QNetworkRequest.Attribute.HttpReasonPhraseAttribute)
assert http_code == 200
assert http_reason == 'OK'
assert reply.isFinished()
@@ -76,20 +76,20 @@ class TestFixedDataNetworkReply:
def test_error_network_reply(qtbot, req):
reply = networkreply.ErrorNetworkReply(
- req, "This is an error", QNetworkReply.UnknownNetworkError)
+ req, "This is an error", QNetworkReply.NetworkError.UnknownNetworkError)
- with qtbot.wait_signals([reply.error, reply.finished], order='strict'):
+ with qtbot.wait_signals([reply.errorOccurred, reply.finished], order='strict'):
pass
reply.abort() # shouldn't do anything
assert reply.request() == req
assert reply.url() == req.url()
- assert reply.openMode() == QIODevice.ReadOnly
+ assert reply.openMode() == QIODevice.OpenModeFlag.ReadOnly
assert reply.isFinished()
assert not reply.isRunning()
assert reply.bytesAvailable() == 0
assert reply.readData(1) == b''
- assert reply.error() == QNetworkReply.UnknownNetworkError
+ assert reply.error() == QNetworkReply.NetworkError.UnknownNetworkError
assert reply.errorString() == "This is an error"
@@ -97,5 +97,5 @@ def test_redirect_network_reply():
url = QUrl('https://www.example.com/')
reply = networkreply.RedirectNetworkReply(url)
assert reply.readData(1) == b''
- assert reply.attribute(QNetworkRequest.RedirectionTargetAttribute) == url
+ assert reply.attribute(QNetworkRequest.Attribute.RedirectionTargetAttribute) == url
reply.abort() # shouldn't do anything
diff --git a/tests/unit/browser/webkit/network/test_pac.py b/tests/unit/browser/webkit/network/test_pac.py
index 79b34be9a..8b9e29912 100644
--- a/tests/unit/browser/webkit/network/test_pac.py
+++ b/tests/unit/browser/webkit/network/test_pac.py
@@ -22,8 +22,8 @@ import threading
import logging
import pytest
-from PyQt5.QtCore import QUrl
-from PyQt5.QtNetwork import (QNetworkProxy, QNetworkProxyQuery, QHostInfo,
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.network import (QNetworkProxy, QNetworkProxyQuery, QHostInfo,
QHostAddress)
from qutebrowser.browser.network import pac
@@ -44,11 +44,11 @@ def _pac_common_test(test_str):
res = pac.PACResolver(fun_str)
proxies = res.resolve(QNetworkProxyQuery(QUrl("https://example.com/test")))
assert len(proxies) == 3
- assert proxies[0].type() == QNetworkProxy.NoProxy
- assert proxies[1].type() == QNetworkProxy.HttpProxy
+ assert proxies[0].type() == QNetworkProxy.ProxyType.NoProxy
+ assert proxies[1].type() == QNetworkProxy.ProxyType.HttpProxy
assert proxies[1].hostName() == "127.0.0.1"
assert proxies[1].port() == 8080
- assert proxies[2].type() == QNetworkProxy.Socks5Proxy
+ assert proxies[2].type() == QNetworkProxy.ProxyType.Socks5Proxy
assert proxies[2].hostName() == "192.168.1.1"
assert proxies[2].port() == 4444
diff --git a/tests/unit/browser/webkit/test_cache.py b/tests/unit/browser/webkit/test_cache.py
index 83d5054d7..90715ec21 100644
--- a/tests/unit/browser/webkit/test_cache.py
+++ b/tests/unit/browser/webkit/test_cache.py
@@ -19,8 +19,8 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import pytest
-from PyQt5.QtCore import QUrl, QDateTime
-from PyQt5.QtNetwork import QNetworkDiskCache, QNetworkCacheMetaData
+from qutebrowser.qt.core import QUrl, QDateTime
+from qutebrowser.qt.network import QNetworkDiskCache, QNetworkCacheMetaData
from qutebrowser.browser.webkit import cache
diff --git a/tests/unit/browser/webkit/test_certificateerror.py b/tests/unit/browser/webkit/test_certificateerror.py
index e615854ca..ad6d83262 100644
--- a/tests/unit/browser/webkit/test_certificateerror.py
+++ b/tests/unit/browser/webkit/test_certificateerror.py
@@ -18,7 +18,8 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import pytest
-from PyQt5.QtNetwork import QSslError
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.network import QSslError
from qutebrowser.browser.webkit import certificateerror
@@ -34,13 +35,13 @@ class FakeError:
@pytest.mark.parametrize('errors, expected', [
(
- [QSslError(QSslError.UnableToGetIssuerCertificate)],
+ [QSslError(QSslError.SslError.UnableToGetIssuerCertificate)],
['<p>The issuer certificate could not be found</p>'],
),
(
[
- QSslError(QSslError.UnableToGetIssuerCertificate),
- QSslError(QSslError.UnableToDecryptCertificateSignature),
+ QSslError(QSslError.SslError.UnableToGetIssuerCertificate),
+ QSslError(QSslError.SslError.UnableToDecryptCertificateSignature),
],
[
'<ul>',
@@ -67,7 +68,8 @@ class FakeError:
],
),
])
-def test_html(errors, expected):
- wrapper = certificateerror.CertificateErrorWrapper(errors)
+def test_html(stubs, errors, expected):
+ reply = stubs.FakeNetworkReply(url=QUrl("https://example.com"))
+ wrapper = certificateerror.CertificateErrorWrapper(reply=reply, errors=errors)
lines = [line.strip() for line in wrapper.html().splitlines() if line.strip()]
assert lines == expected
diff --git a/tests/unit/browser/webkit/test_cookies.py b/tests/unit/browser/webkit/test_cookies.py
index 81da561ce..f2a64f3bc 100644
--- a/tests/unit/browser/webkit/test_cookies.py
+++ b/tests/unit/browser/webkit/test_cookies.py
@@ -18,8 +18,8 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
-from PyQt5.QtNetwork import QNetworkCookie
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.network import QNetworkCookie
+from qutebrowser.qt.core import QUrl
import pytest
from qutebrowser.browser.webkit import cookies
diff --git a/tests/unit/browser/webkit/test_tabhistory.py b/tests/unit/browser/webkit/test_tabhistory.py
index d1c4a25a4..db9d1abcb 100644
--- a/tests/unit/browser/webkit/test_tabhistory.py
+++ b/tests/unit/browser/webkit/test_tabhistory.py
@@ -17,15 +17,18 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+# FIXME:qt6 (lint)
+# pylint: disable=no-name-in-module
+
"""Tests for webelement.tabhistory."""
import dataclasses
from typing import Any
import pytest
-pytest.importorskip('PyQt5.QtWebKit')
-from PyQt5.QtCore import QUrl, QPoint
-from PyQt5.QtWebKit import QWebHistory
+pytest.importorskip('qutebrowser.qt.webkit')
+from qutebrowser.qt.core import QUrl, QPoint
+from qutebrowser.qt.webkit import QWebHistory
from qutebrowser.browser.webkit import tabhistory
from qutebrowser.misc.sessions import TabHistoryItem as Item
diff --git a/tests/unit/browser/webkit/test_webview.py b/tests/unit/browser/webkit/test_webkit_view.py
index fcaaa2256..fcaaa2256 100644
--- a/tests/unit/browser/webkit/test_webview.py
+++ b/tests/unit/browser/webkit/test_webkit_view.py
diff --git a/tests/unit/browser/webkit/test_webkitelem.py b/tests/unit/browser/webkit/test_webkitelem.py
index d580fec99..504f1d64a 100644
--- a/tests/unit/browser/webkit/test_webkitelem.py
+++ b/tests/unit/browser/webkit/test_webkitelem.py
@@ -27,8 +27,8 @@ import itertools
import dataclasses
import pytest
-from PyQt5.QtCore import QRect, QPoint, QUrl
-QWebElement = pytest.importorskip('PyQt5.QtWebKit').QWebElement
+from qutebrowser.qt.core import QRect, QPoint, QUrl
+QWebElement = pytest.importorskip('qutebrowser.qt.webkit').QWebElement
from qutebrowser.browser import browsertab
from qutebrowser.browser.webkit import webkitelem
@@ -124,7 +124,7 @@ def get_webelem(geometry=None, frame=None, *, null=False, style=None,
def _style_property(name, strategy):
"""Helper function to act as styleProperty method."""
- if strategy != QWebElement.ComputedStyle:
+ if strategy != QWebElement.StyleResolveStrategy.ComputedStyle:
raise ValueError("styleProperty called with strategy != "
"ComputedStyle ({})!".format(strategy))
return style_dict[name]
diff --git a/tests/unit/browser/webkit/test_webkitsettings.py b/tests/unit/browser/webkit/test_webkitsettings.py
index 8b30b85aa..5fb6567d7 100644
--- a/tests/unit/browser/webkit/test_webkitsettings.py
+++ b/tests/unit/browser/webkit/test_webkitsettings.py
@@ -18,7 +18,7 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import pytest
-pytest.importorskip('PyQt5.QtWebKitWidgets')
+pytest.importorskip('qutebrowser.qt.webkitwidgets')
from qutebrowser.browser.webkit import webkitsettings
diff --git a/tests/unit/commands/test_argparser.py b/tests/unit/commands/test_argparser.py
index cfa94c552..2d95e4b4e 100644
--- a/tests/unit/commands/test_argparser.py
+++ b/tests/unit/commands/test_argparser.py
@@ -23,7 +23,7 @@ import inspect
import enum
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.commands import argparser, cmdexc
diff --git a/tests/unit/commands/test_userscripts.py b/tests/unit/commands/test_userscripts.py
index 7cf8f233c..bc83ed499 100644
--- a/tests/unit/commands/test_userscripts.py
+++ b/tests/unit/commands/test_userscripts.py
@@ -25,7 +25,7 @@ import logging
import signal
import pytest
-from PyQt5.QtCore import QFileSystemWatcher
+from qutebrowser.qt.core import QFileSystemWatcher
from qutebrowser.commands import userscripts
from qutebrowser.utils import utils
diff --git a/tests/unit/completion/test_completer.py b/tests/unit/completion/test_completer.py
index 23e4b771c..f8cfc9039 100644
--- a/tests/unit/completion/test_completer.py
+++ b/tests/unit/completion/test_completer.py
@@ -22,7 +22,7 @@
import unittest.mock
import pytest
-from PyQt5.QtGui import QStandardItemModel
+from qutebrowser.qt.gui import QStandardItemModel
from qutebrowser.completion import completer, completionwidget
from qutebrowser.commands import command
diff --git a/tests/unit/completion/test_completiondelegate.py b/tests/unit/completion/test_completiondelegate.py
index ad081ccbf..31df6f1ce 100644
--- a/tests/unit/completion/test_completiondelegate.py
+++ b/tests/unit/completion/test_completiondelegate.py
@@ -21,9 +21,9 @@ from unittest import mock
import hypothesis
import hypothesis.strategies
import pytest
-from PyQt5.QtCore import Qt
-from PyQt5.QtGui import QTextDocument, QColor
-from PyQt5.QtWidgets import QTextEdit
+from qutebrowser.qt.core import Qt
+from qutebrowser.qt.gui import QTextDocument, QColor
+from qutebrowser.qt.widgets import QTextEdit
from qutebrowser.completion import completiondelegate
@@ -51,7 +51,7 @@ from qutebrowser.completion import completiondelegate
])
def test_highlight(pat, txt, segments):
doc = QTextDocument(txt)
- highlighter = completiondelegate._Highlighter(doc, pat, Qt.red)
+ highlighter = completiondelegate._Highlighter(doc, pat, Qt.GlobalColor.red)
highlighter.setFormat = mock.Mock()
highlighter.highlightBlock(txt)
highlighter.setFormat.assert_has_calls([
@@ -65,7 +65,7 @@ def test_benchmark_highlight(benchmark):
doc = QTextDocument(txt)
def bench():
- highlighter = completiondelegate._Highlighter(doc, pat, Qt.red)
+ highlighter = completiondelegate._Highlighter(doc, pat, Qt.GlobalColor.red)
highlighter.highlightBlock(txt)
benchmark(bench)
@@ -75,7 +75,7 @@ def test_benchmark_highlight(benchmark):
def test_pattern_hypothesis(text):
"""Make sure we can't produce invalid patterns."""
doc = QTextDocument()
- completiondelegate._Highlighter(doc, text, Qt.red)
+ completiondelegate._Highlighter(doc, text, Qt.GlobalColor.red)
def test_highlighted(qtbot):
@@ -87,7 +87,7 @@ def test_highlighted(qtbot):
that is kind of hard, so we just test it in isolation here.
"""
doc = QTextDocument()
- completiondelegate._Highlighter(doc, 'Hello', Qt.red)
+ completiondelegate._Highlighter(doc, 'Hello', Qt.GlobalColor.red)
doc.setPlainText('Hello World')
# Needed so the highlighting actually works.
diff --git a/tests/unit/completion/test_completionmodel.py b/tests/unit/completion/test_completionmodel.py
index 2130f1f1c..95fadd57b 100644
--- a/tests/unit/completion/test_completionmodel.py
+++ b/tests/unit/completion/test_completionmodel.py
@@ -24,7 +24,7 @@ import hypothesis
from hypothesis import strategies
import pytest
-from PyQt5.QtCore import QModelIndex
+from qutebrowser.qt.core import QModelIndex
from qutebrowser.completion.models import completionmodel, listcategory
from qutebrowser.utils import qtutils
diff --git a/tests/unit/completion/test_completionwidget.py b/tests/unit/completion/test_completionwidget.py
index 074228332..90d5a5efb 100644
--- a/tests/unit/completion/test_completionwidget.py
+++ b/tests/unit/completion/test_completionwidget.py
@@ -22,7 +22,7 @@
from unittest import mock
import pytest
-from PyQt5.QtCore import QRect
+from qutebrowser.qt.core import QRect
from qutebrowser.completion import completionwidget
from qutebrowser.completion.models import completionmodel, listcategory
diff --git a/tests/unit/completion/test_models.py b/tests/unit/completion/test_models.py
index 2c00acf68..fb44006aa 100644
--- a/tests/unit/completion/test_models.py
+++ b/tests/unit/completion/test_models.py
@@ -31,9 +31,9 @@ from unittest import mock
import hypothesis
import hypothesis.strategies as hst
import pytest
-from PyQt5.QtCore import QUrl, QDateTime, QProcess
+from qutebrowser.qt.core import QUrl, QDateTime, QProcess
try:
- from PyQt5.QtWebEngineWidgets import (
+ from qutebrowser.qt.webenginecore import (
QWebEngineHistory, QWebEngineHistoryItem
)
except ImportError:
@@ -1348,7 +1348,7 @@ def test_url_completion_benchmark(benchmark, info,
@pytest.fixture
def tab_with_history(fake_web_tab, tabbed_browser_stubs, info, monkeypatch):
"""Returns a fake tab with some fake history items."""
- pytest.importorskip('PyQt5.QtWebEngineWidgets')
+ pytest.importorskip('qutebrowser.qt.webenginewidgets')
tab = fake_web_tab(QUrl('https://github.com'), 'GitHub', 0)
current_idx = 2
monkeypatch.setattr(
@@ -1490,7 +1490,7 @@ def test_process_completion(monkeypatch, stubs, info):
p1.cmd = 'cmd1'
p1.args = []
p1.outcome.running = False
- p1.outcome.status = QProcess.NormalExit
+ p1.outcome.status = QProcess.ExitStatus.NormalExit
p1.outcome.code = 0
p2.pid = 1002
@@ -1502,7 +1502,7 @@ def test_process_completion(monkeypatch, stubs, info):
p3.cmd = 'cmd3'
p3.args = []
p3.outcome.running = False
- p3.outcome.status = QProcess.NormalExit
+ p3.outcome.status = QProcess.ExitStatus.NormalExit
p3.outcome.code = 1
monkeypatch.setattr(guiprocess, 'all_processes', {
diff --git a/tests/unit/components/test_blockutils.py b/tests/unit/components/test_blockutils.py
index 08d8cee60..9d259a0b8 100644
--- a/tests/unit/components/test_blockutils.py
+++ b/tests/unit/components/test_blockutils.py
@@ -21,7 +21,7 @@
import io
from typing import IO
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
import pytest
diff --git a/tests/unit/components/test_braveadblock.py b/tests/unit/components/test_braveadblock.py
index fc50cb595..7dcffc91f 100644
--- a/tests/unit/components/test_braveadblock.py
+++ b/tests/unit/components/test_braveadblock.py
@@ -22,7 +22,7 @@ import logging
import csv
from typing import Iterable, Tuple
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
import pytest
@@ -327,7 +327,7 @@ def test_whitelist_on_dataset(config_stub, easylist_easyprivacy):
assert not blockutils.is_whitelisted_url(url)
config_stub.val.content.blocking.whitelist = []
assert not blockutils.is_whitelisted_url(url)
- whitelist_url = url.toString(QUrl.RemovePath) + "/*"
+ whitelist_url = url.toString(QUrl.UrlFormattingOption.RemovePath) + "/*"
config_stub.val.content.blocking.whitelist = [whitelist_url]
assert blockutils.is_whitelisted_url(url)
@@ -430,3 +430,8 @@ def test_corrupt_cache_handling(ad_blocker, message_mock, caplog):
assert msg.text == (
"Reading adblock filter data failed (corrupted data?). "
"Please run :adblock-update.")
+
+
+def test_resource_type_strings_complete():
+ defined = set(braveadblock._RESOURCE_TYPE_STRINGS) - {None}
+ assert defined == set(ResourceType)
diff --git a/tests/unit/components/test_hostblock.py b/tests/unit/components/test_hostblock.py
index 5949f92f8..92791f71f 100644
--- a/tests/unit/components/test_hostblock.py
+++ b/tests/unit/components/test_hostblock.py
@@ -24,7 +24,7 @@ import logging
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.components import hostblock
from qutebrowser.utils import urlmatch
diff --git a/tests/unit/components/test_readlinecommands.py b/tests/unit/components/test_readlinecommands.py
index af815b075..d10867a54 100644
--- a/tests/unit/components/test_readlinecommands.py
+++ b/tests/unit/components/test_readlinecommands.py
@@ -21,7 +21,7 @@ import os
import re
import inspect
-from PyQt5.QtWidgets import QLineEdit, QApplication
+from qutebrowser.qt.widgets import QLineEdit, QApplication
import pytest
from qutebrowser.components import readlinecommands
diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py
index fc6c6fc0c..fbb687947 100644
--- a/tests/unit/config/test_config.py
+++ b/tests/unit/config/test_config.py
@@ -23,8 +23,8 @@ import unittest.mock
import functools
import pytest
-from PyQt5.QtCore import QUrl
-from PyQt5.QtGui import QColor
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.gui import QColor
from qutebrowser.config import config, configdata, configexc
from qutebrowser.utils import usertypes, urlmatch
@@ -728,12 +728,20 @@ class TestConfig:
with qtbot.assert_not_emitted(conf.changed):
meth('colors.statusbar.normal.bg', '#abcdef', pattern=pattern)
- def test_dump_userconfig(self, conf):
+ @pytest.mark.parametrize("include_hidden", [True, False])
+ def test_dump_userconfig(self, conf, include_hidden):
conf.set_obj('content.plugins', True)
conf.set_obj('content.headers.custom', {'X-Foo': 'bar'})
- lines = ['content.headers.custom = {"X-Foo": "bar"}',
- 'content.plugins = true']
- assert conf.dump_userconfig().splitlines() == lines
+ conf.set_obj('content.webgl', False, hide_userconfig=True)
+
+ lines = [
+ 'content.headers.custom = {"X-Foo": "bar"}',
+ 'content.plugins = true',
+ ]
+ if include_hidden:
+ lines.append("content.webgl = false")
+
+ assert conf.dump_userconfig(include_hidden=include_hidden).splitlines() == lines
def test_dump_userconfig_default(self, conf):
assert conf.dump_userconfig() == '<Default configuration>'
@@ -771,7 +779,7 @@ class TestContainer:
@pytest.mark.parametrize('configapi, expected', [
(object(), 'rgb'),
- (None, QColor.Rgb),
+ (None, QColor.Spec.Rgb),
])
def test_getattr_option(self, container, configapi, expected):
container._configapi = configapi
diff --git a/tests/unit/config/test_configcommands.py b/tests/unit/config/test_configcommands.py
index e641efb00..40dfa48f8 100644
--- a/tests/unit/config/test_configcommands.py
+++ b/tests/unit/config/test_configcommands.py
@@ -23,7 +23,7 @@ import functools
import unittest.mock
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.config import configcommands
from qutebrowser.api import cmdutils
@@ -212,12 +212,17 @@ class TestSet:
commands.set(win_id=0, option='foo?')
-def test_diff(commands, tabbed_browser_stubs):
+@pytest.mark.parametrize("include_hidden, url", [
+ (True, "qute://configdiff?include_hidden=true"),
+ (False, "qute://configdiff"),
+])
+def test_diff(commands, tabbed_browser_stubs, include_hidden, url):
"""Run ':config-diff'.
- Should open qute://configdiff."""
- commands.config_diff(win_id=0)
- assert tabbed_browser_stubs[0].loaded_url == QUrl('qute://configdiff')
+ Should open qute://configdiff.
+ """
+ commands.config_diff(win_id=0, include_hidden=include_hidden)
+ assert tabbed_browser_stubs[0].loaded_url == QUrl(url)
class TestCycle:
diff --git a/tests/unit/config/test_configexc.py b/tests/unit/config/test_configexc.py
index ad09338ea..57d6391eb 100644
--- a/tests/unit/config/test_configexc.py
+++ b/tests/unit/config/test_configexc.py
@@ -70,7 +70,7 @@ def test_no_autoconfig_error():
@pytest.mark.parametrize('raw_backends', [
None,
- {'QtWebEngine': 'Qt 5.11', 'QtWebKit': False}
+ {'QtWebEngine': 'Qt 5.15', 'QtWebKit': False}
])
def test_backend_error(raw_backends):
e = configexc.BackendError('foo', usertypes.Backend.QtWebKit, raw_backends)
@@ -80,8 +80,8 @@ def test_backend_error(raw_backends):
def test_backend_error_condition():
e = configexc.BackendError('foo', usertypes.Backend.QtWebEngine,
- {'QtWebEngine': 'Qt 5.11', 'QtWebKit': True})
- expected = "The foo setting needs Qt 5.11 with the QtWebEngine backend!"
+ {'QtWebEngine': 'Qt 6.11', 'QtWebKit': True})
+ expected = "The foo setting needs Qt 6.11 with the QtWebEngine backend!"
assert str(e) == expected
diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py
index e0ebbabdf..394214a8b 100644
--- a/tests/unit/config/test_configfiles.py
+++ b/tests/unit/config/test_configfiles.py
@@ -25,7 +25,7 @@ import textwrap
import logging
import pytest
-from PyQt5.QtCore import QSettings
+from qutebrowser.qt.core import QSettings
from qutebrowser.config import (config, configfiles, configexc, configdata,
configtypes)
@@ -77,54 +77,74 @@ def autoconfig(config_tmpdir):
@pytest.mark.parametrize('old_data, insert, new_data', [
- (None,
- False,
- '[general]\n'
- 'qt_version = 5.6.7\n'
- 'qtwe_version = 7.8.9\n'
- 'version = 1.2.3\n'
- '\n'
- '[geometry]\n'
- '\n'
- '[inspector]\n'
- '\n'),
- ('[general]\n'
- 'fooled = true',
- False,
- '[general]\n'
- 'qt_version = 5.6.7\n'
- 'qtwe_version = 7.8.9\n'
- 'version = 1.2.3\n'
- '\n'
- '[geometry]\n'
- '\n'
- '[inspector]\n'
- '\n'),
- ('[general]\n'
- 'foobar = 42',
- False,
- '[general]\n'
- 'foobar = 42\n'
- 'qt_version = 5.6.7\n'
- 'qtwe_version = 7.8.9\n'
- 'version = 1.2.3\n'
- '\n'
- '[geometry]\n'
- '\n'
- '[inspector]\n'
- '\n'),
- (None,
- True,
- '[general]\n'
- 'qt_version = 5.6.7\n'
- 'qtwe_version = 7.8.9\n'
- 'version = 1.2.3\n'
- 'newval = 23\n'
- '\n'
- '[geometry]\n'
- '\n'
- '[inspector]\n'
- '\n'),
+ (
+ None,
+
+ False,
+
+ '[general]\n'
+ 'qt_version = 5.6.7\n'
+ 'qtwe_version = 7.8.9\n'
+ 'chromium_version = 123\n'
+ 'version = 1.2.3\n'
+ '\n'
+ '[geometry]\n'
+ '\n'
+ '[inspector]\n'
+ '\n',
+ ),
+ (
+ '[general]\n'
+ 'fooled = true',
+
+ False,
+
+ '[general]\n'
+ 'qt_version = 5.6.7\n'
+ 'qtwe_version = 7.8.9\n'
+ 'chromium_version = 123\n'
+ 'version = 1.2.3\n'
+ '\n'
+ '[geometry]\n'
+ '\n'
+ '[inspector]\n'
+ '\n'
+ ),
+ (
+ '[general]\n'
+ 'foobar = 42',
+
+ False,
+
+ '[general]\n'
+ 'foobar = 42\n'
+ 'qt_version = 5.6.7\n'
+ 'qtwe_version = 7.8.9\n'
+ 'chromium_version = 123\n'
+ 'version = 1.2.3\n'
+ '\n'
+ '[geometry]\n'
+ '\n'
+ '[inspector]\n'
+ '\n'
+ ),
+ (
+ None,
+
+ True,
+
+ '[general]\n'
+ 'qt_version = 5.6.7\n'
+ 'qtwe_version = 7.8.9\n'
+ 'chromium_version = 123\n'
+ 'version = 1.2.3\n'
+ 'newval = 23\n'
+ '\n'
+ '[geometry]\n'
+ '\n'
+ '[inspector]\n'
+ '\n'
+ ),
])
def test_state_config(
fake_save_manager, data_tmpdir, monkeypatch, qtwe_version_patcher,
@@ -132,7 +152,7 @@ def test_state_config(
):
monkeypatch.setattr(configfiles.qutebrowser, '__version__', '1.2.3')
monkeypatch.setattr(configfiles, 'qVersion', lambda: '5.6.7')
- qtwe_version_patcher('7.8.9')
+ qtwe_version_patcher('7.8.9', chromium_version='123.4.5.6')
statefile = data_tmpdir / 'state'
if old_data is not None:
@@ -167,18 +187,18 @@ def state_writer(data_tmpdir):
@pytest.fixture
def qtwe_version_patcher(monkeypatch):
try:
- from PyQt5 import QtWebEngineWidgets # pylint: disable=unused-import
+ from qutebrowser.qt import webenginecore # pylint: disable=unused-import
except ImportError:
pytest.skip("QtWebEngine not available")
- def patch(ver):
+ def patch(ver, chromium_version=None):
monkeypatch.setattr(
configfiles.version,
'qtwebengine_versions',
lambda avoid_init=False:
version.WebEngineVersions(
webengine=utils.VersionNumber.parse(ver),
- chromium=None,
+ chromium=chromium_version,
source='test',
)
)
@@ -222,13 +242,21 @@ def test_qtwe_version_changed(state_writer, qtwe_version_patcher,
assert state.qtwe_version_changed == changed
-def test_qtwe_version_changed_webkit(stubs, monkeypatch, state_writer):
- fake = stubs.ImportFake({'PyQt5.QtWebEngineWidgets': False}, monkeypatch)
+@pytest.mark.parametrize("key, attribute, expected", [
+ ("qtwe_version", "qtwe_version_changed", False),
+ ("chromium_version", "chromium_version_changed", configfiles.VersionChange.unknown),
+])
+@pytest.mark.parametrize("value", ["no", None])
+def test_version_changed_webkit(stubs, monkeypatch, state_writer,
+ key, value, attribute, expected):
+ fake = stubs.ImportFake({'qutebrowser.qt.webenginewidgets': False}, monkeypatch)
fake.patch()
- state_writer('qtwe_version', 'no')
+ if value is not None:
+ state_writer(key, value)
+
state = configfiles.StateConfig()
- assert not state.qtwe_version_changed
+ assert getattr(state, attribute) == expected
@pytest.mark.parametrize('old_version, new_version, expected', [
@@ -260,14 +288,77 @@ def test_qutebrowser_version_changed(
assert state.qutebrowser_version_changed == expected
-def test_qutebrowser_version_unparsable(state_writer, monkeypatch, caplog):
- state_writer('version', 'blabla')
+@pytest.mark.parametrize('old_version, new_version, expected', [
+ (None, '90', configfiles.VersionChange.unknown),
+ ('90', '90', configfiles.VersionChange.equal),
+
+ ('90', '94', configfiles.VersionChange.minor),
+ ('83', '87', configfiles.VersionChange.minor),
+
+ ('83', '90', configfiles.VersionChange.major),
+ ('87', '90', configfiles.VersionChange.major),
+ ('83', '94', configfiles.VersionChange.major),
+ ('87', '94', configfiles.VersionChange.major),
+
+ ('94', '90', configfiles.VersionChange.downgrade),
+ ('94', '87', configfiles.VersionChange.downgrade),
+ ('90', '83', configfiles.VersionChange.downgrade),
+])
+def test_chromium_version_changed(
+ state_writer, qtwe_version_patcher,
+ old_version, new_version, expected):
+ qtwe_version_patcher('6.2', chromium_version=new_version)
+
+ if old_version is not None:
+ state_writer('chromium_version', old_version)
+
+ state = configfiles.StateConfig()
+ assert state.chromium_version_changed == expected
+
+
+@pytest.mark.parametrize('old_qtwe_version, new_chromium_version, expected', [
+ (None, '90', configfiles.VersionChange.unknown),
+ ('6.2.0', '90', configfiles.VersionChange.equal),
+ ('6.2.1', '94', configfiles.VersionChange.minor),
+ ('5.15.2', '90', configfiles.VersionChange.major),
+ ('6.3.0', '90', configfiles.VersionChange.downgrade),
+
+])
+def test_chromium_version_changed_inferring(
+ state_writer, qtwe_version_patcher,
+ old_qtwe_version, new_chromium_version, expected):
+ qtwe_version_patcher('6.2', chromium_version=new_chromium_version)
+
+ if old_qtwe_version is not None:
+ state_writer('qtwe_version', old_qtwe_version)
+
+ state = configfiles.StateConfig()
+ assert state.chromium_version_changed == expected
+
+
+@pytest.mark.parametrize("key, msg, attribute", [
+ ("version", "old version", "qutebrowser_version_changed"),
+ pytest.param(
+ "qtwe_version",
+ "old QtWebEngine version",
+ "chromium_version_changed",
+ marks=pytest.mark.qtwebkit_skip,
+ ),
+ pytest.param(
+ "chromium_version",
+ "old Chromium version",
+ "chromium_version_changed",
+ marks=pytest.mark.qtwebkit_skip,
+ ),
+])
+def test_version_unparsable(state_writer, caplog, key, msg, attribute):
+ state_writer(key, 'blabla')
with caplog.at_level(logging.WARNING):
state = configfiles.StateConfig()
- assert caplog.messages == ['Unable to parse old version blabla']
- assert state.qutebrowser_version_changed == configfiles.VersionChange.unknown
+ assert caplog.messages == [f'Unable to parse {msg} blabla']
+ assert getattr(state, attribute) == configfiles.VersionChange.unknown
@pytest.mark.parametrize('value, filterstr, matches', [
diff --git a/tests/unit/config/test_configinit.py b/tests/unit/config/test_configinit.py
index 870c3826b..77867628b 100644
--- a/tests/unit/config/test_configinit.py
+++ b/tests/unit/config/test_configinit.py
@@ -427,7 +427,7 @@ def test_get_backend(monkeypatch, args, config_stub,
real_import = __import__
def fake_import(name, *args, **kwargs):
- if name != 'PyQt5.QtWebKit':
+ if name != 'qutebrowser.qt.webkit':
return real_import(name, *args, **kwargs)
raise ImportError
diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py
index 99b8a5de0..d89083a86 100644
--- a/tests/unit/config/test_configtypes.py
+++ b/tests/unit/config/test_configtypes.py
@@ -29,9 +29,9 @@ import dataclasses
import pytest
import hypothesis
from hypothesis import strategies
-from PyQt5.QtCore import QUrl
-from PyQt5.QtGui import QColor, QFont
-from PyQt5.QtNetwork import QNetworkProxy
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.gui import QColor, QFont
+from qutebrowser.qt.network import QNetworkProxy
from qutebrowser.misc import objects
from qutebrowser.config import configtypes, configexc
@@ -46,22 +46,16 @@ class Font(QFont):
"""A QFont with a nicer repr()."""
def __repr__(self):
- weight = debug.qenum_key(QFont, self.weight(), add_base=True,
- klass=QFont.Weight)
- kwargs = {
- 'family': self.family(),
- 'pt': self.pointSize(),
- 'px': self.pixelSize(),
- 'weight': weight,
- 'style': self.style(),
- }
- try:
- kwargs['families'] = self.families()
- except AttributeError:
- # Added in Qt 5.13
- pass
-
- return utils.get_repr(self, **kwargs)
+ weight = debug.qenum_key(QFont, self.weight(), klass=QFont.Weight)
+ return utils.get_repr(
+ self,
+ family=self.family(),
+ pt=self.pointSize(),
+ px=self.pixelSize(),
+ weight=weight,
+ style=self.style(),
+ families=self.families(),
+ )
class RegexEq:
@@ -1379,46 +1373,46 @@ class TestFont:
TESTS = {
# (style, weight, pointsize, pixelsize, family
'"Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Normal, -1, -1, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Normal, -1, -1, 'Foobar Neue'),
'inconsolatazi4':
- FontDesc(QFont.StyleNormal, QFont.Normal, -1, -1,
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Normal, -1, -1,
'inconsolatazi4'),
'Terminus (TTF)':
- FontDesc(QFont.StyleNormal, QFont.Normal, -1, -1,
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Normal, -1, -1,
'Terminus (TTF)'),
'10pt "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Normal, 10, None, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Normal, 10, None, 'Foobar Neue'),
'10PT "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Normal, 10, None, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Normal, 10, None, 'Foobar Neue'),
'10px "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Normal, None, 10, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Normal, None, 10, 'Foobar Neue'),
'10PX "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Normal, None, 10, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Normal, None, 10, 'Foobar Neue'),
'bold "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Bold, -1, -1, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Bold, -1, -1, 'Foobar Neue'),
'italic "Foobar Neue"':
- FontDesc(QFont.StyleItalic, QFont.Normal, -1, -1, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleItalic, QFont.Weight.Normal, -1, -1, 'Foobar Neue'),
'oblique "Foobar Neue"':
- FontDesc(QFont.StyleOblique, QFont.Normal, -1, -1, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleOblique, QFont.Weight.Normal, -1, -1, 'Foobar Neue'),
'normal bold "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Bold, -1, -1, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Bold, -1, -1, 'Foobar Neue'),
'bold italic "Foobar Neue"':
- FontDesc(QFont.StyleItalic, QFont.Bold, -1, -1, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleItalic, QFont.Weight.Bold, -1, -1, 'Foobar Neue'),
'bold 10pt "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Bold, 10, None, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Bold, 10, None, 'Foobar Neue'),
'italic 10pt "Foobar Neue"':
- FontDesc(QFont.StyleItalic, QFont.Normal, 10, None, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleItalic, QFont.Weight.Normal, 10, None, 'Foobar Neue'),
'oblique 10pt "Foobar Neue"':
- FontDesc(QFont.StyleOblique, QFont.Normal, 10, None,
+ FontDesc(QFont.Style.StyleOblique, QFont.Weight.Normal, 10, None,
'Foobar Neue'),
'normal bold 10pt "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Bold, 10, None, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, QFont.Weight.Bold, 10, None, 'Foobar Neue'),
'bold italic 10pt "Foobar Neue"':
- FontDesc(QFont.StyleItalic, QFont.Bold, 10, None, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleItalic, QFont.Weight.Bold, 10, None, 'Foobar Neue'),
'normal 300 10pt "Foobar Neue"':
- FontDesc(QFont.StyleNormal, 37, 10, None, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, 37, 10, None, 'Foobar Neue'),
'normal 800 10pt "Foobar Neue"':
- FontDesc(QFont.StyleNormal, 99, 10, None, 'Foobar Neue'),
+ FontDesc(QFont.Style.StyleNormal, 99, 10, None, 'Foobar Neue'),
}
font_xfail = pytest.mark.xfail(reason='FIXME: #103')
@@ -1895,11 +1889,11 @@ class TestProxy:
@pytest.mark.parametrize('val, expected', [
('system', configtypes.SYSTEM_PROXY),
- ('none', QNetworkProxy(QNetworkProxy.NoProxy)),
+ ('none', QNetworkProxy(QNetworkProxy.ProxyType.NoProxy)),
('socks://example.com/',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com')),
+ QNetworkProxy(QNetworkProxy.ProxyType.Socks5Proxy, 'example.com')),
('socks5://foo:bar@example.com:2323',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com', 2323,
+ QNetworkProxy(QNetworkProxy.ProxyType.Socks5Proxy, 'example.com', 2323,
'foo', 'bar')),
('pac+http://example.com/proxy.pac',
pac.PACFetcher(QUrl('pac+http://example.com/proxy.pac'))),
diff --git a/tests/unit/config/test_configutils.py b/tests/unit/config/test_configutils.py
index 3fc5cd561..15f031bd4 100644
--- a/tests/unit/config/test_configutils.py
+++ b/tests/unit/config/test_configutils.py
@@ -20,8 +20,8 @@
import hypothesis
from hypothesis import strategies
import pytest
-from PyQt5.QtCore import QUrl
-from PyQt5.QtWidgets import QLabel
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.widgets import QLabel
from qutebrowser.config import configutils, configdata, configtypes, configexc
from qutebrowser.utils import urlmatch, usertypes, qtutils
diff --git a/tests/unit/config/test_qtargs.py b/tests/unit/config/test_qtargs.py
index 076ff6e3c..a65847929 100644
--- a/tests/unit/config/test_qtargs.py
+++ b/tests/unit/config/test_qtargs.py
@@ -23,9 +23,8 @@ import logging
import pytest
from qutebrowser import qutebrowser
-from qutebrowser.config import qtargs
+from qutebrowser.config import qtargs, configdata
from qutebrowser.utils import usertypes, version
-from helpers import testutils
@pytest.fixture
@@ -42,11 +41,17 @@ def parser(mocker):
@pytest.fixture
def version_patcher(monkeypatch):
"""Get a patching function to patch the QtWebEngine version."""
- def run(ver):
+ def run(ver) -> bool:
+ """Run patching.
+
+ Return:
+ True if we know the associated Chromium version, False otherwise
+ """
versions = version.WebEngineVersions.from_pyqt(ver)
monkeypatch.setattr(qtargs.objects, 'backend', usertypes.Backend.QtWebEngine)
monkeypatch.setattr(version, 'qtwebengine_versions',
lambda avoid_init: versions)
+ return versions.chromium_major is not None
return run
@@ -126,38 +131,21 @@ class TestWebEngineArgs:
@pytest.fixture(autouse=True)
def ensure_webengine(self, monkeypatch):
"""Skip all tests if QtWebEngine is unavailable."""
- pytest.importorskip("PyQt5.QtWebEngine")
+ pytest.importorskip("qutebrowser.qt.webenginecore")
monkeypatch.setattr(qtargs.objects, 'backend', usertypes.Backend.QtWebEngine)
- @pytest.mark.parametrize('backend, qt_version, expected', [
- (usertypes.Backend.QtWebEngine, '5.13.0', False),
- (usertypes.Backend.QtWebEngine, '5.14.0', True),
- (usertypes.Backend.QtWebEngine, '5.14.1', True),
- (usertypes.Backend.QtWebEngine, '5.15.0', False),
- (usertypes.Backend.QtWebEngine, '5.15.1', False),
-
- (usertypes.Backend.QtWebKit, '5.14.0', False),
- ])
- def test_shared_workers(self, config_stub, version_patcher, monkeypatch, parser,
- qt_version, backend, expected):
- version_patcher(qt_version)
- monkeypatch.setattr(qtargs.objects, 'backend', backend)
- parsed = parser.parse_args([])
- args = qtargs.qt_args(parsed)
- assert ('--disable-shared-workers' in args) == expected
+ @pytest.mark.parametrize("setting, values", qtargs._WEBENGINE_SETTINGS.items())
+ def test_settings_exist(self, setting, values, configdata_init):
+ option = configdata.DATA[setting]
+ for value in values:
+ option.typ.to_py(value) # for validation
@pytest.mark.parametrize('backend, qt_version, debug_flag, expected', [
- # Qt >= 5.12.3: Enable with -D stack, do nothing without it.
- (usertypes.Backend.QtWebEngine, '5.12.3', True, True),
- (usertypes.Backend.QtWebEngine, '5.12.3', False, None),
- # Qt < 5.12.3: Do nothing with -D stack, disable without it.
- (usertypes.Backend.QtWebEngine, '5.12.2', True, None),
- (usertypes.Backend.QtWebEngine, '5.12.2', False, False),
+ # QtWebEngine: Enable with -D stack, do nothing without it.
+ (usertypes.Backend.QtWebEngine, '5.15.2', True, True),
+ (usertypes.Backend.QtWebEngine, '5.15.2', False, None),
# QtWebKit: Do nothing
- (usertypes.Backend.QtWebKit, '5.12.3', True, None),
- (usertypes.Backend.QtWebKit, '5.12.3', False, None),
- (usertypes.Backend.QtWebKit, '5.12.2', True, None),
- (usertypes.Backend.QtWebKit, '5.12.2', False, None),
+ (usertypes.Backend.QtWebKit, '5.15.2', False, None),
])
def test_in_process_stack_traces(self, monkeypatch, parser, backend, version_patcher,
qt_version, debug_flag, expected):
@@ -301,20 +289,19 @@ class TestWebEngineArgs:
@pytest.mark.parametrize('qt_version, referer, arg', [
# 'always' -> no arguments
- ('5.15.0', 'always', None),
-
- # 'never' is handled via interceptor for most Qt versions
- ('5.12.3', 'never', '--no-referrers'),
- ('5.12.4', 'never', None),
- ('5.13.0', 'never', '--no-referrers'),
- ('5.13.1', 'never', None),
- ('5.14.0', 'never', None),
- ('5.15.0', 'never', None),
-
- # 'same-domain' - arguments depend on Qt versions
- ('5.13.0', 'same-domain', '--reduced-referrer-granularity'),
- ('5.14.0', 'same-domain', '--enable-features=ReducedReferrerGranularity'),
- ('5.15.0', 'same-domain', '--enable-features=ReducedReferrerGranularity'),
+ ('5.15.2', 'always', None),
+ ('5.15.3', 'always', None),
+
+ # 'never' is handled via interceptor
+ ('5.15.2', 'never', None),
+ ('5.15.3', 'never', None),
+
+ # 'same-domain'
+ ('5.15.2', 'same-domain', '--enable-features=ReducedReferrerGranularity'),
+ ('5.15.3', 'same-domain', '--enable-features=ReducedReferrerGranularity'),
+ # (Not available anymore)
+ ('6.2', 'same-domain', None),
+ ('6.3', 'same-domain', None),
])
def test_referer(self, config_stub, version_patcher, parser,
qt_version, referer, arg):
@@ -324,51 +311,15 @@ class TestWebEngineArgs:
parsed = parser.parse_args([])
args = qtargs.qt_args(parsed)
+ # Old QtWebEngine args
+ assert '--no-referrers' not in args
+ assert '--reduced-referrer-granularity' not in args
+
if arg is None:
- assert '--no-referrers' not in args
- assert '--reduced-referrer-granularity' not in args
assert '--enable-features=ReducedReferrerGranularity' not in args
else:
assert arg in args
- @pytest.mark.parametrize('value, qt_version, added', [
- ("dark", "5.13", False), # not supported
- ("dark", "5.14", True),
- ("dark", "5.15.0", True),
- ("dark", "5.15.1", True),
- # handled via blink setting
- ("dark", "5.15.2", False),
- ("dark", "5.15.3", False),
- ("dark", "6.0.0", False),
-
- ("light", "5.13", False),
- ("light", "5.14", False),
- ("light", "5.15.0", False),
- ("light", "5.15.1", False),
- ("light", "5.15.2", False),
- ("light", "5.15.3", False),
- ("light", "6.0.0", False),
-
- ("auto", "5.13", False),
- ("auto", "5.14", False),
- ("auto", "5.15.0", False),
- ("auto", "5.15.1", False),
- ("auto", "5.15.2", False),
- ("auto", "5.15.3", False),
- ("auto", "6.0.0", False),
- ])
- @testutils.qt514
- def test_preferred_color_scheme(
- self, config_stub, version_patcher, parser, value, qt_version, added):
- version_patcher(qt_version)
-
- config_stub.val.colors.webpage.preferred_color_scheme = value
-
- parsed = parser.parse_args([])
- args = qtargs.qt_args(parsed)
-
- assert ('--force-dark-mode' in args) == added
-
@pytest.mark.parametrize('bar, is_mac, added', [
# Overlay bar enabled
('overlay', False, True),
@@ -462,11 +413,9 @@ class TestWebEngineArgs:
assert blink_settings_args[0].startswith('--blink-settings=foo=bar,')
@pytest.mark.parametrize('qt_version, has_workaround', [
- ('5.14.0', False),
- ('5.15.1', False),
('5.15.2', True),
('5.15.3', False),
- ('6.0.0', False),
+ ('6.2.0', False),
])
def test_installedapp_workaround(self, parser, version_patcher, qt_version, has_workaround):
version_patcher(qt_version)
@@ -482,7 +431,6 @@ class TestWebEngineArgs:
assert disable_features_args == expected
@pytest.mark.parametrize('enabled', [True, False])
- @testutils.qt514
def test_media_keys(self, config_stub, parser, enabled):
config_stub.val.input.media_keys = enabled
@@ -493,10 +441,6 @@ class TestWebEngineArgs:
@pytest.mark.parametrize('variant, expected', [
(
- 'qt_515_1',
- ['--blink-settings=darkModeEnabled=true,darkModeImagePolicy=2'],
- ),
- (
'qt_515_2',
[
(
@@ -544,6 +488,28 @@ class TestWebEngineArgs:
args = qtargs.qt_args(parsed)
assert '--lang=de' in args
+ @pytest.mark.parametrize("version, expected", [
+ ('5.15.2', False),
+ ('5.15.9', False),
+ ('6.2.4', False),
+ ('6.3.1', False),
+ ('6.4.0', True),
+ ('6.5.0', True),
+ ])
+ def test_webengine_args(self, version_patcher, parser, version, expected):
+ known_chromium = version_patcher(version)
+ if not known_chromium:
+ pytest.skip("Don't know associated Chromium version")
+
+ parsed = parser.parse_args([])
+ args = qtargs.qt_args(parsed)
+
+ flag = "--webEngineArgs"
+ if expected:
+ assert args[1] == flag
+ else:
+ assert flag not in args
+
class TestEnvVars:
@@ -615,29 +581,20 @@ class TestEnvVars:
@pytest.mark.parametrize('new_qt', [True, False])
def test_highdpi(self, monkeypatch, config_stub, new_qt):
- """Test HighDPI environment variables.
-
- Depending on the Qt version, there's a different variable which should
- be set...
- """
- new_var = 'QT_ENABLE_HIGHDPI_SCALING'
- old_var = 'QT_AUTO_SCREEN_SCALE_FACTOR'
-
+ """Test HighDPI environment variables."""
monkeypatch.setattr(qtargs.objects, 'backend',
usertypes.Backend.QtWebEngine)
monkeypatch.setattr(qtargs.qtutils, 'version_check',
lambda version, exact=False, compiled=True:
new_qt)
- for envvar in [new_var, old_var]:
- monkeypatch.setenv(envvar, '') # to make sure it gets restored
- monkeypatch.delenv(envvar)
+ envvar = 'QT_ENABLE_HIGHDPI_SCALING'
+ monkeypatch.setenv(envvar, '') # to make sure it gets restored
+ monkeypatch.delenv(envvar)
config_stub.set_obj('qt.highdpi', True)
qtargs.init_envvars()
- envvar = new_var if new_qt else old_var
-
assert os.environ[envvar] == '1'
def test_env_vars_webkit(self, monkeypatch, config_stub):
diff --git a/tests/unit/config/test_qtargs_locale_workaround.py b/tests/unit/config/test_qtargs_locale_workaround.py
index 4a4152b80..c70ab0b63 100644
--- a/tests/unit/config/test_qtargs_locale_workaround.py
+++ b/tests/unit/config/test_qtargs_locale_workaround.py
@@ -20,13 +20,13 @@ import os
import pathlib
import pytest
-from PyQt5.QtCore import QLocale
+from qutebrowser.qt.core import QLocale
from qutebrowser.utils import utils
from qutebrowser.config import qtargs
-pytest.importorskip('PyQt5.QtWebEngineWidgets')
+pytest.importorskip('qutebrowser.qt.webenginewidgets')
@pytest.fixture(autouse=True)
diff --git a/tests/unit/config/test_stylesheet.py b/tests/unit/config/test_stylesheet.py
index 4ffa107ed..2a9e5fc6d 100644
--- a/tests/unit/config/test_stylesheet.py
+++ b/tests/unit/config/test_stylesheet.py
@@ -18,7 +18,7 @@
import pytest
-from PyQt5.QtCore import QObject
+from qutebrowser.qt.core import QObject
from qutebrowser.config import stylesheet
diff --git a/tests/unit/javascript/conftest.py b/tests/unit/javascript/conftest.py
index 4a7f09204..97ff994e4 100644
--- a/tests/unit/javascript/conftest.py
+++ b/tests/unit/javascript/conftest.py
@@ -23,7 +23,7 @@ import pathlib
import pytest
import jinja2
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
import qutebrowser
from qutebrowser.utils import usertypes
diff --git a/tests/unit/javascript/position_caret/test_position_caret.py b/tests/unit/javascript/position_caret/test_position_caret.py
index 70a1df333..1c399392f 100644
--- a/tests/unit/javascript/position_caret/test_position_caret.py
+++ b/tests/unit/javascript/position_caret/test_position_caret.py
@@ -21,18 +21,18 @@
import pytest
-QWebSettings = pytest.importorskip("PyQt5.QtWebKit").QWebSettings
-QWebPage = pytest.importorskip("PyQt5.QtWebKitWidgets").QWebPage
+QWebSettings = pytest.importorskip("qutebrowser.qt.webkit").QWebSettings
+QWebPage = pytest.importorskip("qutebrowser.qt.webkitwidgets").QWebPage
@pytest.fixture(autouse=True)
def enable_caret_browsing(qapp):
"""Fixture to enable caret browsing globally."""
settings = QWebSettings.globalSettings()
- old_value = settings.testAttribute(QWebSettings.CaretBrowsingEnabled)
- settings.setAttribute(QWebSettings.CaretBrowsingEnabled, True)
+ old_value = settings.testAttribute(QWebSettings.WebAttribute.CaretBrowsingEnabled)
+ settings.setAttribute(QWebSettings.WebAttribute.CaretBrowsingEnabled, True)
yield
- settings.setAttribute(QWebSettings.CaretBrowsingEnabled, old_value)
+ settings.setAttribute(QWebSettings.WebAttribute.CaretBrowsingEnabled, old_value)
class CaretTester:
diff --git a/tests/unit/javascript/stylesheet/test_stylesheet_js.py b/tests/unit/javascript/stylesheet/test_stylesheet_js.py
index 1eebe3b7f..fd0189919 100644
--- a/tests/unit/javascript/stylesheet/test_stylesheet_js.py
+++ b/tests/unit/javascript/stylesheet/test_stylesheet_js.py
@@ -22,8 +22,8 @@
import pathlib
import pytest
-QtWebEngineWidgets = pytest.importorskip("PyQt5.QtWebEngineWidgets")
-QWebEngineProfile = QtWebEngineWidgets.QWebEngineProfile
+QtWebEngineCore = pytest.importorskip("qutebrowser.qt.webenginecore")
+QWebEngineProfile = QtWebEngineCore.QWebEngineProfile
from qutebrowser.utils import javascript
diff --git a/tests/unit/javascript/test_greasemonkey.py b/tests/unit/javascript/test_greasemonkey.py
index b298b1216..770023c18 100644
--- a/tests/unit/javascript/test_greasemonkey.py
+++ b/tests/unit/javascript/test_greasemonkey.py
@@ -23,7 +23,7 @@ import logging
import pathlib
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.utils import usertypes, version
from qutebrowser.browser import greasemonkey
diff --git a/tests/unit/javascript/test_js_execution.py b/tests/unit/javascript/test_js_execution.py
index e371e0f36..8a21d415a 100644
--- a/tests/unit/javascript/test_js_execution.py
+++ b/tests/unit/javascript/test_js_execution.py
@@ -17,6 +17,9 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
+# FIXME:qt6 (lint)
+# pylint: disable=no-name-in-module
+
"""Check how Qt behaves when trying to execute JS."""
@@ -28,8 +31,8 @@ def test_simple_js_webkit(webview, js_enabled, expected):
"""With QtWebKit, evaluateJavaScript works when JS is on."""
# If we get there (because of the webview fixture) we can be certain
# QtWebKit is available
- from PyQt5.QtWebKit import QWebSettings
- webview.settings().setAttribute(QWebSettings.JavascriptEnabled, js_enabled)
+ from qutebrowser.qt.webkit import QWebSettings
+ webview.settings().setAttribute(QWebSettings.WebAttribute.JavascriptEnabled, js_enabled)
result = webview.page().mainFrame().evaluateJavaScript('1 + 1')
assert result == expected
@@ -39,8 +42,8 @@ def test_element_js_webkit(webview, js_enabled, expected):
"""With QtWebKit, evaluateJavaScript on an element works with JS off."""
# If we get there (because of the webview fixture) we can be certain
# QtWebKit is available
- from PyQt5.QtWebKit import QWebSettings
- webview.settings().setAttribute(QWebSettings.JavascriptEnabled, js_enabled)
+ from qutebrowser.qt.webkit import QWebSettings
+ webview.settings().setAttribute(QWebSettings.WebAttribute.JavascriptEnabled, js_enabled)
elem = webview.page().mainFrame().documentElement()
result = elem.evaluateJavaScript('1 + 1')
assert result == expected
@@ -63,14 +66,14 @@ def test_simple_js_webengine(qtbot, webengineview, qapp,
"""With QtWebEngine, runJavaScript works even when JS is off."""
# If we get there (because of the webengineview fixture) we can be certain
# QtWebEngine is available
- from PyQt5.QtWebEngineWidgets import QWebEngineSettings, QWebEngineScript
+ from qutebrowser.qt.webenginecore import QWebEngineSettings, QWebEngineScript
- assert world in [QWebEngineScript.MainWorld,
- QWebEngineScript.ApplicationWorld,
- QWebEngineScript.UserWorld]
+ assert world in [QWebEngineScript.ScriptWorldId.MainWorld,
+ QWebEngineScript.ScriptWorldId.ApplicationWorld,
+ QWebEngineScript.ScriptWorldId.UserWorld]
settings = webengineview.settings()
- settings.setAttribute(QWebEngineSettings.JavascriptEnabled, js_enabled)
+ settings.setAttribute(QWebEngineSettings.WebAttribute.JavascriptEnabled, js_enabled)
qapp.processEvents()
page = webengineview.page()
diff --git a/tests/unit/javascript/test_js_quirks.py b/tests/unit/javascript/test_js_quirks.py
index 03c3c1493..da05a74a1 100644
--- a/tests/unit/javascript/test_js_quirks.py
+++ b/tests/unit/javascript/test_js_quirks.py
@@ -24,10 +24,14 @@ polyfills for. They should either pass because the polyfill is active, or pass b
the native functionality exists.
"""
+import pathlib
+
import pytest
+from qutebrowser.qt.core import QUrl
-from PyQt5.QtCore import QUrl
+import qutebrowser
from qutebrowser.utils import usertypes
+from qutebrowser.config import configdata
@pytest.mark.parametrize('base_url, source, expected', [
@@ -50,18 +54,6 @@ from qutebrowser.utils import usertypes
id='replace-all-reserved-string',
),
pytest.param(
- QUrl('https://test.qutebrowser.org/test'),
- 'typeof globalThis.setTimeout === "function"',
- True,
- id='global-this',
- ),
- pytest.param(
- QUrl(),
- 'Object.fromEntries([["0", "a"], ["1", "b"]])',
- {'0': 'a', '1': 'b'},
- id='object-fromentries',
- ),
- pytest.param(
QUrl("https://test.qutebrowser.org/linkedin"),
'[1, 2, 3].at(1)',
2,
@@ -73,3 +65,28 @@ def test_js_quirks(config_stub, js_tester_webengine, base_url, source, expected)
js_tester_webengine.tab._scripts._inject_site_specific_quirks()
js_tester_webengine.load('base.html', base_url=base_url)
js_tester_webengine.run(source, expected, world=usertypes.JsWorld.main)
+
+
+def test_js_quirks_match_files(webengine_tab):
+ quirks_path = pathlib.Path(qutebrowser.__file__).parent / "javascript" / "quirks"
+ suffix = ".user.js"
+ quirks_files = {p.name[:-len(suffix)] for p in quirks_path.glob(f"*{suffix}")}
+ quirks_code = {q.filename for q in webengine_tab._scripts._get_quirks()}
+ assert quirks_code == quirks_files
+
+
+def test_js_quirks_match_settings(webengine_tab, configdata_init):
+ opt = configdata.DATA["content.site_specific_quirks.skip"]
+ prefix = "js-"
+ valid_values = opt.typ.get_valid_values()
+ assert valid_values is not None
+ quirks_config = {
+ val[len(prefix):].replace("-", "_")
+ for val in valid_values
+ if val.startswith(prefix)
+ }
+
+ quirks_code = {q.filename for q in webengine_tab._scripts._get_quirks()}
+ quirks_code -= {"googledocs"} # special case, UA quirk
+
+ assert quirks_code == quirks_config
diff --git a/tests/unit/keyinput/conftest.py b/tests/unit/keyinput/conftest.py
index cfe491df2..e152755aa 100644
--- a/tests/unit/keyinput/conftest.py
+++ b/tests/unit/keyinput/conftest.py
@@ -21,6 +21,9 @@
import pytest
+import contextlib
+from qutebrowser.keyinput import keyutils
+
BINDINGS = {'prompt': {'<Ctrl-a>': 'message-info ctrla',
'a': 'message-info a',
@@ -45,3 +48,20 @@ def keyinput_bindings(config_stub, key_config_stub):
config_stub.val.bindings.default = {}
config_stub.val.bindings.commands = dict(BINDINGS)
config_stub.val.bindings.key_mappings = dict(MAPPINGS)
+
+
+@pytest.fixture
+def pyqt_enum_workaround():
+ """Get a context manager to ignore invalid key errors and skip the test.
+
+ WORKAROUND for
+ https://www.riverbankcomputing.com/pipermail/pyqt/2022-April/044607.html
+ """
+ @contextlib.contextmanager
+ def _pyqt_enum_workaround(exctype=keyutils.InvalidKeyError):
+ try:
+ yield
+ except exctype as e:
+ pytest.skip(f"PyQt enum workaround: {e}")
+
+ return _pyqt_enum_workaround
diff --git a/tests/unit/keyinput/key_data.py b/tests/unit/keyinput/key_data.py
index c451d2534..b0819c699 100644
--- a/tests/unit/keyinput/key_data.py
+++ b/tests/unit/keyinput/key_data.py
@@ -17,7 +17,7 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
-# pylint: disable=line-too-long
+# FIXME:qt6 (lint): disable=line-too-long
"""Data used by test_keyutils.py to test all keys."""
@@ -25,7 +25,7 @@
import dataclasses
from typing import Optional
-from PyQt5.QtCore import Qt
+from qutebrowser.qt.core import Qt
@dataclasses.dataclass(order=True)
@@ -50,7 +50,7 @@ class Key:
def __post_init__(self):
if self.attribute:
- self.member = getattr(Qt, 'Key_' + self.attribute, None)
+ self.member = getattr(Qt.Key, 'Key_' + self.attribute, None)
if self.name is None:
self.name = self.attribute
@@ -62,7 +62,7 @@ class Modifier:
Attributes:
attribute: The name of the Qt::KeyboardModifier attribute
- ('Shift' -> Qt.ShiftModifier)
+ ('Shift' -> Qt.KeyboardModifier.ShiftModifier)
name: The name returned by str(KeyInfo) with that modifier.
member: The numeric value.
"""
@@ -72,7 +72,7 @@ class Modifier:
member: Optional[int] = None
def __post_init__(self):
- self.member = getattr(Qt, self.attribute + 'Modifier')
+ self.member = getattr(Qt.KeyboardModifier, self.attribute + 'Modifier')
if self.name is None:
self.name = self.attribute
@@ -450,6 +450,8 @@ KEYS = [
Key('LaunchD', 'Launch (D)'),
Key('LaunchE', 'Launch (E)'),
Key('LaunchF', 'Launch (F)'),
+ Key('LaunchG', 'Launch (G)', qtest=False),
+ Key('LaunchH', 'Launch (H)', qtest=False),
Key('MonBrightnessUp', 'Monitor Brightness Up', qtest=False),
Key('MonBrightnessDown', 'Monitor Brightness Down', qtest=False),
Key('KeyboardLightOnOff', 'Keyboard Light On/Off', qtest=False),
@@ -476,7 +478,7 @@ KEYS = [
Key('Book', qtest=False),
Key('CD', qtest=False),
Key('Calculator', qtest=False),
- Key('ToDoList', 'To Do List', qtest=False),
+ Key('ToDoList', 'To-do list', qtest=False),
Key('ClearGrab', 'Clear Grab', qtest=False),
Key('Close', qtest=False),
Key('Copy', qtest=False),
@@ -541,10 +543,7 @@ KEYS = [
Key('TopMenu', 'Top Menu', qtest=False),
Key('PowerDown', 'Power Down', qtest=False),
Key('Suspend', qtest=False),
- Key('ContrastAdjust', 'Contrast Adjust', qtest=False),
-
- Key('LaunchG', 'Launch (G)', qtest=False),
- Key('LaunchH', 'Launch (H)', qtest=False),
+ Key('ContrastAdjust', 'Adjust contrast', qtest=False),
Key('TouchpadToggle', 'Touchpad Toggle', qtest=False),
Key('TouchpadOn', 'Touchpad On', qtest=False),
diff --git a/tests/unit/keyinput/test_basekeyparser.py b/tests/unit/keyinput/test_basekeyparser.py
index 84068bf47..c2592c197 100644
--- a/tests/unit/keyinput/test_basekeyparser.py
+++ b/tests/unit/keyinput/test_basekeyparser.py
@@ -21,7 +21,7 @@
from unittest import mock
-from PyQt5.QtCore import Qt
+from qutebrowser.qt.core import Qt
import pytest
from qutebrowser.keyinput import basekeyparser, keyutils
@@ -54,7 +54,7 @@ def handle_text():
"""Helper function to handle multiple fake keypresses."""
def func(kp, *args):
for key in args:
- info = keyutils.KeyInfo(key, Qt.NoModifier)
+ info = keyutils.KeyInfo(key, Qt.KeyboardModifier.NoModifier)
kp.handle(info.to_event())
return func
@@ -119,11 +119,11 @@ def test_read_config(keyparser, key_config_stub, changed_mode, expected):
class TestHandle:
def test_valid_key(self, prompt_keyparser, handle_text):
- modifier = Qt.MetaModifier if utils.is_mac else Qt.ControlModifier
+ modifier = Qt.KeyboardModifier.MetaModifier if utils.is_mac else Qt.KeyboardModifier.ControlModifier
infos = [
- keyutils.KeyInfo(Qt.Key_A, modifier),
- keyutils.KeyInfo(Qt.Key_X, modifier),
+ keyutils.KeyInfo(Qt.Key.Key_A, modifier),
+ keyutils.KeyInfo(Qt.Key.Key_X, modifier),
]
for info in infos:
prompt_keyparser.handle(info.to_event())
@@ -133,11 +133,11 @@ class TestHandle:
assert not prompt_keyparser._sequence
def test_valid_key_count(self, prompt_keyparser):
- modifier = Qt.MetaModifier if utils.is_mac else Qt.ControlModifier
+ modifier = Qt.KeyboardModifier.MetaModifier if utils.is_mac else Qt.KeyboardModifier.ControlModifier
infos = [
- keyutils.KeyInfo(Qt.Key_5, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_A, modifier),
+ keyutils.KeyInfo(Qt.Key.Key_5, Qt.KeyboardModifier.NoModifier),
+ keyutils.KeyInfo(Qt.Key.Key_A, modifier),
]
for info in infos:
prompt_keyparser.handle(info.to_event())
@@ -145,10 +145,10 @@ class TestHandle:
'message-info ctrla', 5)
@pytest.mark.parametrize('keys', [
- [(Qt.Key_B, Qt.NoModifier), (Qt.Key_C, Qt.NoModifier)],
- [(Qt.Key_A, Qt.ControlModifier | Qt.AltModifier)],
+ [(Qt.Key.Key_B, Qt.KeyboardModifier.NoModifier), (Qt.Key.Key_C, Qt.KeyboardModifier.NoModifier)],
+ [(Qt.Key.Key_A, Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.AltModifier)],
# Only modifier
- [(Qt.Key_Shift, Qt.ShiftModifier)],
+ [(Qt.Key.Key_Shift, Qt.KeyboardModifier.ShiftModifier)],
])
def test_invalid_keys(self, prompt_keyparser, keys):
for key, modifiers in keys:
@@ -158,40 +158,40 @@ class TestHandle:
assert not prompt_keyparser._sequence
def test_dry_run(self, prompt_keyparser):
- b_info = keyutils.KeyInfo(Qt.Key_B, Qt.NoModifier)
+ b_info = keyutils.KeyInfo(Qt.Key.Key_B, Qt.KeyboardModifier.NoModifier)
prompt_keyparser.handle(b_info.to_event())
- a_info = keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier)
+ a_info = keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.NoModifier)
prompt_keyparser.handle(a_info.to_event(), dry_run=True)
assert not prompt_keyparser.execute.called
assert prompt_keyparser._sequence
def test_dry_run_count(self, prompt_keyparser):
- info = keyutils.KeyInfo(Qt.Key_9, Qt.NoModifier)
+ info = keyutils.KeyInfo(Qt.Key.Key_9, Qt.KeyboardModifier.NoModifier)
prompt_keyparser.handle(info.to_event(), dry_run=True)
assert not prompt_keyparser._count
def test_invalid_key(self, prompt_keyparser):
- keys = [Qt.Key_B, 0x0]
+ keys = [Qt.Key.Key_B, 0x0]
for key in keys:
- info = keyutils.KeyInfo(key, Qt.NoModifier)
+ info = keyutils.KeyInfo(key, Qt.KeyboardModifier.NoModifier)
prompt_keyparser.handle(info.to_event())
assert not prompt_keyparser._sequence
def test_valid_keychain(self, handle_text, prompt_keyparser):
handle_text(prompt_keyparser,
# Press 'x' which is ignored because of no match
- Qt.Key_X,
+ Qt.Key.Key_X,
# Then start the real chain
- Qt.Key_B, Qt.Key_A)
+ Qt.Key.Key_B, Qt.Key.Key_A)
prompt_keyparser.execute.assert_called_with('message-info ba', None)
assert not prompt_keyparser._sequence
@pytest.mark.parametrize('key, modifiers, number', [
- (Qt.Key_0, Qt.NoModifier, 0),
- (Qt.Key_1, Qt.NoModifier, 1),
- (Qt.Key_1, Qt.KeypadModifier, 1),
+ (Qt.Key.Key_0, Qt.KeyboardModifier.NoModifier, 0),
+ (Qt.Key.Key_1, Qt.KeyboardModifier.NoModifier, 1),
+ (Qt.Key.Key_1, Qt.KeyboardModifier.KeypadModifier, 1),
])
def test_number_press(self, prompt_keyparser,
key, modifiers, number):
@@ -201,8 +201,8 @@ class TestHandle:
assert not prompt_keyparser._sequence
@pytest.mark.parametrize('modifiers, text', [
- (Qt.NoModifier, '2'),
- (Qt.KeypadModifier, 'num-2'),
+ (Qt.KeyboardModifier.NoModifier, '2'),
+ (Qt.KeyboardModifier.KeypadModifier, 'num-2'),
])
def test_number_press_keypad(self, keyparser, config_stub,
modifiers, text):
@@ -210,18 +210,18 @@ class TestHandle:
config_stub.val.bindings.commands = {'normal': {
'2': 'message-info 2',
'<Num+2>': 'message-info num-2'}}
- keyparser.handle(keyutils.KeyInfo(Qt.Key_2, modifiers).to_event())
+ keyparser.handle(keyutils.KeyInfo(Qt.Key.Key_2, modifiers).to_event())
command = 'message-info {}'.format(text)
keyparser.execute.assert_called_once_with(command, None)
assert not keyparser._sequence
def test_umlauts(self, handle_text, keyparser, config_stub):
config_stub.val.bindings.commands = {'normal': {'ü': 'message-info ü'}}
- handle_text(keyparser, Qt.Key_Udiaeresis)
+ handle_text(keyparser, Qt.Key.Key_Udiaeresis)
keyparser.execute.assert_called_once_with('message-info ü', None)
def test_mapping(self, config_stub, handle_text, prompt_keyparser):
- handle_text(prompt_keyparser, Qt.Key_X)
+ handle_text(prompt_keyparser, Qt.Key.Key_X)
prompt_keyparser.execute.assert_called_once_with(
'message-info a', None)
@@ -230,27 +230,27 @@ class TestHandle:
config_stub.val.bindings.commands = {'normal': {'a': 'nop'}}
config_stub.val.bindings.key_mappings = {'1': 'a'}
- info = keyutils.KeyInfo(Qt.Key_1, Qt.KeypadModifier)
+ info = keyutils.KeyInfo(Qt.Key.Key_1, Qt.KeyboardModifier.KeypadModifier)
keyparser.handle(info.to_event())
keyparser.execute.assert_called_once_with('nop', None)
def test_binding_and_mapping(self, config_stub, handle_text, prompt_keyparser):
"""with a conflicting binding/mapping, the binding should win."""
- handle_text(prompt_keyparser, Qt.Key_B)
+ handle_text(prompt_keyparser, Qt.Key.Key_B)
assert not prompt_keyparser.execute.called
def test_mapping_in_key_chain(self, config_stub, handle_text, keyparser):
"""A mapping should work even as part of a keychain."""
config_stub.val.bindings.commands = {'normal':
{'aa': 'message-info aa'}}
- handle_text(keyparser, Qt.Key_A, Qt.Key_X)
+ handle_text(keyparser, Qt.Key.Key_A, Qt.Key.Key_X)
keyparser.execute.assert_called_once_with('message-info aa', None)
def test_binding_with_shift(self, prompt_keyparser):
"""Simulate a binding which involves shift."""
- for key, modifiers in [(Qt.Key_Y, Qt.NoModifier),
- (Qt.Key_Shift, Qt.ShiftModifier),
- (Qt.Key_Y, Qt.ShiftModifier)]:
+ for key, modifiers in [(Qt.Key.Key_Y, Qt.KeyboardModifier.NoModifier),
+ (Qt.Key.Key_Shift, Qt.KeyboardModifier.ShiftModifier),
+ (Qt.Key.Key_Y, Qt.KeyboardModifier.ShiftModifier)]:
info = keyutils.KeyInfo(key, modifiers)
prompt_keyparser.handle(info.to_event())
@@ -264,7 +264,7 @@ class TestHandle:
'a': 'message-info foo'
}
}
- info = keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier)
+ info = keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.NoModifier)
keyparser.handle(info.to_event())
keyparser.execute.assert_called_once_with('message-info foo', None)
@@ -275,39 +275,39 @@ class TestCount:
def test_no_count(self, handle_text, prompt_keyparser):
"""Test with no count added."""
- handle_text(prompt_keyparser, Qt.Key_B, Qt.Key_A)
+ handle_text(prompt_keyparser, Qt.Key.Key_B, Qt.Key.Key_A)
prompt_keyparser.execute.assert_called_once_with(
'message-info ba', None)
assert not prompt_keyparser._sequence
def test_count_0(self, handle_text, prompt_keyparser):
- handle_text(prompt_keyparser, Qt.Key_0, Qt.Key_B, Qt.Key_A)
+ handle_text(prompt_keyparser, Qt.Key.Key_0, Qt.Key.Key_B, Qt.Key.Key_A)
calls = [mock.call('message-info 0', None),
mock.call('message-info ba', None)]
prompt_keyparser.execute.assert_has_calls(calls)
assert not prompt_keyparser._sequence
def test_count_42(self, handle_text, prompt_keyparser):
- handle_text(prompt_keyparser, Qt.Key_4, Qt.Key_2, Qt.Key_B, Qt.Key_A)
+ handle_text(prompt_keyparser, Qt.Key.Key_4, Qt.Key.Key_2, Qt.Key.Key_B, Qt.Key.Key_A)
prompt_keyparser.execute.assert_called_once_with('message-info ba', 42)
assert not prompt_keyparser._sequence
def test_count_42_invalid(self, handle_text, prompt_keyparser):
# Invalid call with ccx gets ignored
handle_text(prompt_keyparser,
- Qt.Key_4, Qt.Key_2, Qt.Key_C, Qt.Key_C, Qt.Key_X)
+ Qt.Key.Key_4, Qt.Key.Key_2, Qt.Key.Key_C, Qt.Key.Key_C, Qt.Key.Key_X)
assert not prompt_keyparser.execute.called
assert not prompt_keyparser._sequence
# Valid call with ccc gets the correct count
handle_text(prompt_keyparser,
- Qt.Key_2, Qt.Key_3, Qt.Key_C, Qt.Key_C, Qt.Key_C)
+ Qt.Key.Key_2, Qt.Key.Key_3, Qt.Key.Key_C, Qt.Key.Key_C, Qt.Key.Key_C)
prompt_keyparser.execute.assert_called_once_with(
'message-info ccc', 23)
assert not prompt_keyparser._sequence
def test_superscript(self, handle_text, prompt_keyparser):
# https://github.com/qutebrowser/qutebrowser/issues/3743
- handle_text(prompt_keyparser, Qt.Key_twosuperior, Qt.Key_B, Qt.Key_A)
+ handle_text(prompt_keyparser, Qt.Key.Key_twosuperior, Qt.Key.Key_B, Qt.Key.Key_A)
def test_count_keystring_update(self, qtbot,
handle_text, prompt_keyparser):
@@ -315,17 +315,17 @@ class TestCount:
with qtbot.wait_signals([
prompt_keyparser.keystring_updated,
prompt_keyparser.keystring_updated]) as blocker:
- handle_text(prompt_keyparser, Qt.Key_4, Qt.Key_2)
+ handle_text(prompt_keyparser, Qt.Key.Key_4, Qt.Key.Key_2)
sig1, sig2 = blocker.all_signals_and_args
assert sig1.args == ('4',)
assert sig2.args == ('42',)
def test_numpad(self, prompt_keyparser):
"""Make sure we can enter a count via numpad."""
- for key, modifiers in [(Qt.Key_4, Qt.KeypadModifier),
- (Qt.Key_2, Qt.KeypadModifier),
- (Qt.Key_B, Qt.NoModifier),
- (Qt.Key_A, Qt.NoModifier)]:
+ for key, modifiers in [(Qt.Key.Key_4, Qt.KeyboardModifier.KeypadModifier),
+ (Qt.Key.Key_2, Qt.KeyboardModifier.KeypadModifier),
+ (Qt.Key.Key_B, Qt.KeyboardModifier.NoModifier),
+ (Qt.Key.Key_A, Qt.KeyboardModifier.NoModifier)]:
info = keyutils.KeyInfo(key, modifiers)
prompt_keyparser.handle(info.to_event())
prompt_keyparser.execute.assert_called_once_with('message-info ba', 42)
@@ -352,7 +352,7 @@ def test_respect_config_when_matching_counts(keyparser, config_stub):
"""Don't match counts if disabled in the config."""
config_stub.val.input.match_counts = False
- info = keyutils.KeyInfo(Qt.Key_1, Qt.NoModifier)
+ info = keyutils.KeyInfo(Qt.Key.Key_1, Qt.KeyboardModifier.NoModifier)
keyparser.handle(info.to_event())
assert not keyparser._sequence
diff --git a/tests/unit/keyinput/test_bindingtrie.py b/tests/unit/keyinput/test_bindingtrie.py
index c769386c0..b0844c980 100644
--- a/tests/unit/keyinput/test_bindingtrie.py
+++ b/tests/unit/keyinput/test_bindingtrie.py
@@ -25,7 +25,7 @@ import textwrap
import pytest
-from PyQt5.QtGui import QKeySequence
+from qutebrowser.qt.gui import QKeySequence
from qutebrowser.keyinput import basekeyparser
from qutebrowser.keyinput import keyutils
@@ -39,7 +39,7 @@ def test_matches_single(entered, configured, match_type):
configured = keyutils.KeySequence.parse(configured)
trie = basekeyparser.BindingTrie()
trie[configured] = "eeloo"
- command = "eeloo" if match_type == QKeySequence.ExactMatch else None
+ command = "eeloo" if match_type == QKeySequence.SequenceMatch.ExactMatch else None
result = basekeyparser.MatchResult(match_type=match_type,
command=command,
sequence=entered)
@@ -82,22 +82,22 @@ def test_str():
@pytest.mark.parametrize('configured, expected', [
([],
# null match
- [('a', QKeySequence.NoMatch),
- ('', QKeySequence.NoMatch)]),
+ [('a', QKeySequence.SequenceMatch.NoMatch),
+ ('', QKeySequence.SequenceMatch.NoMatch)]),
(['abcd'],
- [('abcd', QKeySequence.ExactMatch),
- ('abc', QKeySequence.PartialMatch)]),
+ [('abcd', QKeySequence.SequenceMatch.ExactMatch),
+ ('abc', QKeySequence.SequenceMatch.PartialMatch)]),
(['aa', 'ab', 'ac', 'ad'],
- [('ac', QKeySequence.ExactMatch),
- ('a', QKeySequence.PartialMatch),
- ('f', QKeySequence.NoMatch),
- ('acd', QKeySequence.NoMatch)]),
+ [('ac', QKeySequence.SequenceMatch.ExactMatch),
+ ('a', QKeySequence.SequenceMatch.PartialMatch),
+ ('f', QKeySequence.SequenceMatch.NoMatch),
+ ('acd', QKeySequence.SequenceMatch.NoMatch)]),
(['aaaaaaab', 'aaaaaaac', 'aaaaaaad'],
- [('aaaaaaab', QKeySequence.ExactMatch),
- ('z', QKeySequence.NoMatch)]),
+ [('aaaaaaab', QKeySequence.SequenceMatch.ExactMatch),
+ ('z', QKeySequence.SequenceMatch.NoMatch)]),
(string.ascii_letters,
- [('a', QKeySequence.ExactMatch),
- ('!', QKeySequence.NoMatch)]),
+ [('a', QKeySequence.SequenceMatch.ExactMatch),
+ ('!', QKeySequence.SequenceMatch.NoMatch)]),
])
def test_matches_tree(configured, expected, benchmark):
trie = basekeyparser.BindingTrie()
@@ -107,7 +107,7 @@ def test_matches_tree(configured, expected, benchmark):
def run():
for entered, match_type in expected:
sequence = keyutils.KeySequence.parse(entered)
- command = ("eeloo" if match_type == QKeySequence.ExactMatch
+ command = ("eeloo" if match_type == QKeySequence.SequenceMatch.ExactMatch
else None)
result = basekeyparser.MatchResult(match_type=match_type,
command=command,
diff --git a/tests/unit/keyinput/test_keyutils.py b/tests/unit/keyinput/test_keyutils.py
index 195518127..8e7c3e276 100644
--- a/tests/unit/keyinput/test_keyutils.py
+++ b/tests/unit/keyinput/test_keyutils.py
@@ -22,10 +22,12 @@ import operator
import hypothesis
from hypothesis import strategies
import pytest
-from PyQt5.QtCore import Qt, QEvent, pyqtSignal
-from PyQt5.QtGui import QKeyEvent, QKeySequence
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt import machinery
+from qutebrowser.qt.core import Qt, QEvent, pyqtSignal
+from qutebrowser.qt.gui import QKeyEvent, QKeySequence
+from qutebrowser.qt.widgets import QWidget
+from helpers import testutils
from unit.keyinput import key_data
from qutebrowser.keyinput import keyutils
from qutebrowser.utils import utils
@@ -61,8 +63,7 @@ def qtest_key(request):
def test_key_data_keys():
"""Make sure all possible keys are in key_data.KEYS."""
key_names = {name[len("Key_"):]
- for name, value in sorted(vars(Qt).items())
- if isinstance(value, Qt.Key)}
+ for name in testutils.enum_members(Qt, Qt.Key)}
key_data_names = {key.attribute for key in sorted(key_data.KEYS)}
diff = key_names - key_data_names
assert not diff
@@ -71,9 +72,8 @@ def test_key_data_keys():
def test_key_data_modifiers():
"""Make sure all possible modifiers are in key_data.MODIFIERS."""
mod_names = {name[:-len("Modifier")]
- for name, value in sorted(vars(Qt).items())
- if isinstance(value, Qt.KeyboardModifier) and
- value not in [Qt.NoModifier, Qt.KeyboardModifierMask]}
+ for name, value in testutils.enum_members(Qt, Qt.KeyboardModifier).items()
+ if value not in [Qt.KeyboardModifier.NoModifier, Qt.KeyboardModifier.KeyboardModifierMask]}
mod_data_names = {mod.attribute for mod in sorted(key_data.MODIFIERS)}
diff = mod_names - mod_data_names
assert not diff
@@ -106,7 +106,7 @@ class TestKeyInfoText:
See key_data.py for inputs and expected values.
"""
- modifiers = Qt.ShiftModifier if upper else Qt.KeyboardModifiers()
+ modifiers = Qt.KeyboardModifier.ShiftModifier if upper else Qt.KeyboardModifier.NoModifier
info = keyutils.KeyInfo(qt_key.member, modifiers=modifiers)
expected = qt_key.uppertext if upper else qt_key.text
assert info.text() == expected
@@ -125,8 +125,7 @@ class TestKeyInfoText:
with qtbot.wait_signal(key_tester.got_text):
qtbot.keyPress(key_tester, qtest_key.member)
- info = keyutils.KeyInfo(qtest_key.member,
- modifiers=Qt.KeyboardModifiers())
+ info = keyutils.KeyInfo(qtest_key.member)
assert info.text() == key_tester.text.lower()
@@ -139,49 +138,58 @@ class TestKeyToString:
expected = qt_mod.name + '+'
assert keyutils._modifiers_to_string(qt_mod.member) == expected
+ @pytest.mark.skipif(machinery.IS_QT6, reason="Can't delete enum members on PyQt 6")
def test_missing(self, monkeypatch):
monkeypatch.delattr(keyutils.Qt, 'Key_AltGr')
# We don't want to test the key which is actually missing - we only
# want to know if the mapping still behaves properly.
- assert keyutils._key_to_string(Qt.Key_A) == 'A'
+ assert keyutils._key_to_string(Qt.Key.Key_A) == 'A'
@pytest.mark.parametrize('key, modifiers, expected', [
- (Qt.Key_A, Qt.NoModifier, 'a'),
- (Qt.Key_A, Qt.ShiftModifier, 'A'),
-
- (Qt.Key_Space, Qt.NoModifier, '<Space>'),
- (Qt.Key_Space, Qt.ShiftModifier, '<Shift+Space>'),
- (Qt.Key_Tab, Qt.ShiftModifier, '<Shift+Tab>'),
- (Qt.Key_A, Qt.ControlModifier, '<Ctrl+a>'),
- (Qt.Key_A, Qt.ControlModifier | Qt.ShiftModifier, '<Ctrl+Shift+a>'),
- (Qt.Key_A,
- Qt.ControlModifier | Qt.AltModifier | Qt.MetaModifier | Qt.ShiftModifier,
+ (Qt.Key.Key_A, Qt.KeyboardModifier.NoModifier, 'a'),
+ (Qt.Key.Key_A, Qt.KeyboardModifier.ShiftModifier, 'A'),
+
+ (Qt.Key.Key_Space, Qt.KeyboardModifier.NoModifier, '<Space>'),
+ (Qt.Key.Key_Space, Qt.KeyboardModifier.ShiftModifier, '<Shift+Space>'),
+ (Qt.Key.Key_Tab, Qt.KeyboardModifier.ShiftModifier, '<Shift+Tab>'),
+ (Qt.Key.Key_A, Qt.KeyboardModifier.ControlModifier, '<Ctrl+a>'),
+ (Qt.Key.Key_A, Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.ShiftModifier, '<Ctrl+Shift+a>'),
+ (Qt.Key.Key_A,
+ Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.AltModifier | Qt.KeyboardModifier.MetaModifier | Qt.KeyboardModifier.ShiftModifier,
'<Meta+Ctrl+Alt+Shift+a>'),
- (ord('Œ'), Qt.NoModifier, '<Œ>'),
- (ord('Œ'), Qt.ShiftModifier, '<Shift+Œ>'),
- (ord('Œ'), Qt.GroupSwitchModifier, '<AltGr+Œ>'),
- (ord('Œ'), Qt.GroupSwitchModifier | Qt.ShiftModifier, '<AltGr+Shift+Œ>'),
-
- (Qt.Key_Shift, Qt.ShiftModifier, '<Shift>'),
- (Qt.Key_Shift, Qt.ShiftModifier | Qt.ControlModifier, '<Ctrl+Shift>'),
- (Qt.Key_Alt, Qt.AltModifier, '<Alt>'),
- (Qt.Key_Shift, Qt.GroupSwitchModifier | Qt.ShiftModifier, '<AltGr+Shift>'),
- (Qt.Key_AltGr, Qt.GroupSwitchModifier, '<AltGr>'),
+ (ord('Œ'), Qt.KeyboardModifier.NoModifier, '<Œ>'),
+ (ord('Œ'), Qt.KeyboardModifier.ShiftModifier, '<Shift+Œ>'),
+ (ord('Œ'), Qt.KeyboardModifier.GroupSwitchModifier, '<AltGr+Œ>'),
+ (ord('Œ'), Qt.KeyboardModifier.GroupSwitchModifier | Qt.KeyboardModifier.ShiftModifier, '<AltGr+Shift+Œ>'),
+
+ (Qt.Key.Key_Shift, Qt.KeyboardModifier.ShiftModifier, '<Shift>'),
+ (Qt.Key.Key_Shift, Qt.KeyboardModifier.ShiftModifier | Qt.KeyboardModifier.ControlModifier, '<Ctrl+Shift>'),
+ (Qt.Key.Key_Alt, Qt.KeyboardModifier.AltModifier, '<Alt>'),
+ (Qt.Key.Key_Shift, Qt.KeyboardModifier.GroupSwitchModifier | Qt.KeyboardModifier.ShiftModifier, '<AltGr+Shift>'),
+ (Qt.Key.Key_AltGr, Qt.KeyboardModifier.GroupSwitchModifier, '<AltGr>'),
])
def test_key_info_str(key, modifiers, expected):
assert str(keyutils.KeyInfo(key, modifiers)) == expected
+def test_key_info_repr():
+ info = keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.ShiftModifier)
+ expected = (
+ "<qutebrowser.keyinput.keyutils.KeyInfo "
+ "key='Key_A' modifiers='ShiftModifier' text='A'>")
+ assert repr(info) == expected
+
+
@pytest.mark.parametrize('info1, info2, equal', [
- (keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier),
+ (keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.NoModifier),
+ keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.NoModifier),
True),
- (keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_B, Qt.NoModifier),
+ (keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.NoModifier),
+ keyutils.KeyInfo(Qt.Key.Key_B, Qt.KeyboardModifier.NoModifier),
False),
- (keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_B, Qt.ControlModifier),
+ (keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.NoModifier),
+ keyutils.KeyInfo(Qt.Key.Key_B, Qt.KeyboardModifier.ControlModifier),
False),
])
def test_hash(info1, info2, equal):
@@ -189,30 +197,34 @@ def test_hash(info1, info2, equal):
@pytest.mark.parametrize('key, modifiers, text, expected', [
- (0xd83c, Qt.NoModifier, '🏻', '<🏻>'),
- (0xd867, Qt.NoModifier, '𩷶', '<𩷶>'),
- (0xd867, Qt.ShiftModifier, '𩷶', '<Shift+𩷶>'),
+ (0xd83c, Qt.KeyboardModifier.NoModifier, '🏻', '<🏻>'),
+ (0xd867, Qt.KeyboardModifier.NoModifier, '𩷶', '<𩷶>'),
+ (0xd867, Qt.KeyboardModifier.ShiftModifier, '𩷶', '<Shift+𩷶>'),
])
-def test_surrogates(key, modifiers, text, expected):
- evt = QKeyEvent(QKeyEvent.KeyPress, key, modifiers, text)
- assert str(keyutils.KeyInfo.from_event(evt)) == expected
+def test_surrogates(key, modifiers, text, expected, pyqt_enum_workaround):
+ evt = QKeyEvent(QEvent.Type.KeyPress, key, modifiers, text)
+ with pyqt_enum_workaround():
+ info = keyutils.KeyInfo.from_event(evt)
+ assert str(info) == expected
@pytest.mark.parametrize('keys, expected', [
([0x1f3fb], '<🏻>'),
([0x29df6], '<𩷶>'),
- ([Qt.Key_Shift, 0x29df6], '<Shift><𩷶>'),
+ ([Qt.Key.Key_Shift, 0x29df6], '<Shift><𩷶>'),
([0x1f468, 0x200d, 0x1f468, 0x200d, 0x1f466], '<👨><‍><👨><‍><👦>'),
])
-def test_surrogate_sequences(keys, expected):
- seq = keyutils.KeySequence(*keys)
+def test_surrogate_sequences(keys, expected, pyqt_enum_workaround):
+ infos = [keyutils.KeyInfo(key) for key in keys]
+ with pyqt_enum_workaround(keyutils.KeyParseError):
+ seq = keyutils.KeySequence(*infos)
assert str(seq) == expected
# This shouldn't happen, but if it does we should handle it well
-def test_surrogate_error():
- evt = QKeyEvent(QKeyEvent.KeyPress, 0xd83e, Qt.NoModifier, '🤞🏻')
- with pytest.raises(keyutils.KeyParseError):
+def test_surrogate_error(pyqt_enum_workaround):
+ evt = QKeyEvent(QEvent.Type.KeyPress, 0xd83e, Qt.KeyboardModifier.NoModifier, '🤞🏻')
+ with pytest.raises(keyutils.KeyParseError), pyqt_enum_workaround():
keyutils.KeyInfo.from_event(evt)
@@ -246,8 +258,13 @@ def test_parse_keystr(keystr, parts):
class TestKeySequence:
def test_init(self):
- seq = keyutils.KeySequence(Qt.Key_A, Qt.Key_B, Qt.Key_C, Qt.Key_D,
- Qt.Key_E)
+ seq = keyutils.KeySequence(
+ keyutils.KeyInfo(Qt.Key.Key_A),
+ keyutils.KeyInfo(Qt.Key.Key_B),
+ keyutils.KeyInfo(Qt.Key.Key_C),
+ keyutils.KeyInfo(Qt.Key.Key_D),
+ keyutils.KeyInfo(Qt.Key.Key_E),
+ )
assert len(seq._sequences) == 2
assert len(seq._sequences[0]) == 4
assert len(seq._sequences[1]) == 1
@@ -256,10 +273,14 @@ class TestKeySequence:
seq = keyutils.KeySequence()
assert not seq
- @pytest.mark.parametrize('key', [Qt.Key_unknown, -1, 0])
+ @pytest.mark.parametrize('key', [Qt.Key.Key_unknown, keyutils._NIL_KEY])
def test_init_unknown(self, key):
with pytest.raises(keyutils.KeyParseError):
- keyutils.KeySequence(key)
+ keyutils.KeySequence(keyutils.KeyInfo(key))
+
+ def test_init_invalid(self):
+ with pytest.raises(AssertionError):
+ keyutils.KeyInfo(-1)
def test_parse_unknown(self):
with pytest.raises(keyutils.KeyParseError):
@@ -283,21 +304,17 @@ class TestKeySequence:
assert str(keyutils.KeySequence.parse(orig)) == normalized
def test_iter(self):
- seq = keyutils.KeySequence(Qt.Key_A | Qt.ControlModifier,
- Qt.Key_B | Qt.ShiftModifier,
- Qt.Key_C,
- Qt.Key_D,
- Qt.Key_E)
- expected = [keyutils.KeyInfo(Qt.Key_A, Qt.ControlModifier),
- keyutils.KeyInfo(Qt.Key_B, Qt.ShiftModifier),
- keyutils.KeyInfo(Qt.Key_C, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_D, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_E, Qt.NoModifier)]
- assert list(seq) == expected
+ infos = [keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.ControlModifier),
+ keyutils.KeyInfo(Qt.Key.Key_B, Qt.KeyboardModifier.ShiftModifier),
+ keyutils.KeyInfo(Qt.Key.Key_C),
+ keyutils.KeyInfo(Qt.Key.Key_D),
+ keyutils.KeyInfo(Qt.Key.Key_E)]
+ seq = keyutils.KeySequence(*infos)
+ assert list(seq) == infos
def test_repr(self):
- seq = keyutils.KeySequence(Qt.Key_A | Qt.ControlModifier,
- Qt.Key_B | Qt.ShiftModifier)
+ seq = keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.ControlModifier),
+ keyutils.KeyInfo(Qt.Key.Key_B, Qt.KeyboardModifier.ShiftModifier))
assert repr(seq) == ("<qutebrowser.keyinput.keyutils.KeySequence "
"keys='<Ctrl+a>B'>")
@@ -369,7 +386,7 @@ class TestKeySequence:
def test_getitem(self):
seq = keyutils.KeySequence.parse('ab')
- expected = keyutils.KeyInfo(Qt.Key_B, Qt.NoModifier)
+ expected = keyutils.KeyInfo(Qt.Key.Key_B, Qt.KeyboardModifier.NoModifier)
assert seq[1] == expected
def test_getitem_slice(self):
@@ -382,27 +399,27 @@ class TestKeySequence:
MATCH_TESTS = [
# config: abcd
- ('abc', 'abcd', QKeySequence.PartialMatch),
- ('abcd', 'abcd', QKeySequence.ExactMatch),
- ('ax', 'abcd', QKeySequence.NoMatch),
- ('abcdef', 'abcd', QKeySequence.NoMatch),
+ ('abc', 'abcd', QKeySequence.SequenceMatch.PartialMatch),
+ ('abcd', 'abcd', QKeySequence.SequenceMatch.ExactMatch),
+ ('ax', 'abcd', QKeySequence.SequenceMatch.NoMatch),
+ ('abcdef', 'abcd', QKeySequence.SequenceMatch.NoMatch),
# config: abcd ef
- ('abc', 'abcdef', QKeySequence.PartialMatch),
- ('abcde', 'abcdef', QKeySequence.PartialMatch),
- ('abcd', 'abcdef', QKeySequence.PartialMatch),
- ('abcdx', 'abcdef', QKeySequence.NoMatch),
- ('ax', 'abcdef', QKeySequence.NoMatch),
- ('abcdefg', 'abcdef', QKeySequence.NoMatch),
- ('abcdef', 'abcdef', QKeySequence.ExactMatch),
+ ('abc', 'abcdef', QKeySequence.SequenceMatch.PartialMatch),
+ ('abcde', 'abcdef', QKeySequence.SequenceMatch.PartialMatch),
+ ('abcd', 'abcdef', QKeySequence.SequenceMatch.PartialMatch),
+ ('abcdx', 'abcdef', QKeySequence.SequenceMatch.NoMatch),
+ ('ax', 'abcdef', QKeySequence.SequenceMatch.NoMatch),
+ ('abcdefg', 'abcdef', QKeySequence.SequenceMatch.NoMatch),
+ ('abcdef', 'abcdef', QKeySequence.SequenceMatch.ExactMatch),
# other examples
- ('ab', 'a', QKeySequence.NoMatch),
+ ('ab', 'a', QKeySequence.SequenceMatch.NoMatch),
# empty strings
- ('', '', QKeySequence.ExactMatch),
- ('', 'a', QKeySequence.PartialMatch),
- ('a', '', QKeySequence.NoMatch)]
+ ('', '', QKeySequence.SequenceMatch.ExactMatch),
+ ('', 'a', QKeySequence.SequenceMatch.PartialMatch),
+ ('a', '', QKeySequence.SequenceMatch.NoMatch)]
@pytest.mark.parametrize('entered, configured, match_type', MATCH_TESTS)
def test_matches(self, entered, configured, match_type):
@@ -411,75 +428,75 @@ class TestKeySequence:
assert entered.matches(configured) == match_type
@pytest.mark.parametrize('old, key, modifiers, text, expected', [
- ('a', Qt.Key_B, Qt.NoModifier, 'b', 'ab'),
- ('a', Qt.Key_B, Qt.ShiftModifier, 'B', 'aB'),
- ('a', Qt.Key_B, Qt.AltModifier | Qt.ShiftModifier, 'B',
+ ('a', Qt.Key.Key_B, Qt.KeyboardModifier.NoModifier, 'b', 'ab'),
+ ('a', Qt.Key.Key_B, Qt.KeyboardModifier.ShiftModifier, 'B', 'aB'),
+ ('a', Qt.Key.Key_B, Qt.KeyboardModifier.AltModifier | Qt.KeyboardModifier.ShiftModifier, 'B',
'a<Alt+Shift+b>'),
# Modifier stripping with symbols
- ('', Qt.Key_Colon, Qt.NoModifier, ':', ':'),
- ('', Qt.Key_Colon, Qt.ShiftModifier, ':', ':'),
- ('', Qt.Key_Colon, Qt.AltModifier | Qt.ShiftModifier, ':',
+ ('', Qt.Key.Key_Colon, Qt.KeyboardModifier.NoModifier, ':', ':'),
+ ('', Qt.Key.Key_Colon, Qt.KeyboardModifier.ShiftModifier, ':', ':'),
+ ('', Qt.Key.Key_Colon, Qt.KeyboardModifier.AltModifier | Qt.KeyboardModifier.ShiftModifier, ':',
'<Alt+Shift+:>'),
# Swapping Control/Meta on macOS
- ('', Qt.Key_A, Qt.ControlModifier, '',
+ ('', Qt.Key.Key_A, Qt.KeyboardModifier.ControlModifier, '',
'<Meta+A>' if utils.is_mac else '<Ctrl+A>'),
- ('', Qt.Key_A, Qt.ControlModifier | Qt.ShiftModifier, '',
+ ('', Qt.Key.Key_A, Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.ShiftModifier, '',
'<Meta+Shift+A>' if utils.is_mac else '<Ctrl+Shift+A>'),
- ('', Qt.Key_A, Qt.MetaModifier, '',
+ ('', Qt.Key.Key_A, Qt.KeyboardModifier.MetaModifier, '',
'<Ctrl+A>' if utils.is_mac else '<Meta+A>'),
# Handling of Backtab
- ('', Qt.Key_Backtab, Qt.NoModifier, '', '<Backtab>'),
- ('', Qt.Key_Backtab, Qt.ShiftModifier, '', '<Shift+Tab>'),
- ('', Qt.Key_Backtab, Qt.AltModifier | Qt.ShiftModifier, '',
+ ('', Qt.Key.Key_Backtab, Qt.KeyboardModifier.NoModifier, '', '<Backtab>'),
+ ('', Qt.Key.Key_Backtab, Qt.KeyboardModifier.ShiftModifier, '', '<Shift+Tab>'),
+ ('', Qt.Key.Key_Backtab, Qt.KeyboardModifier.AltModifier | Qt.KeyboardModifier.ShiftModifier, '',
'<Alt+Shift+Tab>'),
- # Stripping of Qt.GroupSwitchModifier
- ('', Qt.Key_A, Qt.GroupSwitchModifier, 'a', 'a'),
+ # Stripping of Qt.KeyboardModifier.GroupSwitchModifier
+ ('', Qt.Key.Key_A, Qt.KeyboardModifier.GroupSwitchModifier, 'a', 'a'),
])
def test_append_event(self, old, key, modifiers, text, expected):
seq = keyutils.KeySequence.parse(old)
- event = QKeyEvent(QKeyEvent.KeyPress, key, modifiers, text)
+ event = QKeyEvent(QEvent.Type.KeyPress, key, modifiers, text)
new = seq.append_event(event)
assert new == keyutils.KeySequence.parse(expected)
@pytest.mark.fake_os('mac')
@pytest.mark.parametrize('modifiers, expected', [
- (Qt.ControlModifier,
- Qt.MetaModifier),
- (Qt.MetaModifier,
- Qt.ControlModifier),
- (Qt.ControlModifier | Qt.MetaModifier,
- Qt.ControlModifier | Qt.MetaModifier),
- (Qt.ControlModifier | Qt.ShiftModifier,
- Qt.MetaModifier | Qt.ShiftModifier),
- (Qt.MetaModifier | Qt.ShiftModifier,
- Qt.ControlModifier | Qt.ShiftModifier),
- (Qt.ShiftModifier, Qt.ShiftModifier),
+ (Qt.KeyboardModifier.ControlModifier,
+ Qt.KeyboardModifier.MetaModifier),
+ (Qt.KeyboardModifier.MetaModifier,
+ Qt.KeyboardModifier.ControlModifier),
+ (Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.MetaModifier,
+ Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.MetaModifier),
+ (Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.ShiftModifier,
+ Qt.KeyboardModifier.MetaModifier | Qt.KeyboardModifier.ShiftModifier),
+ (Qt.KeyboardModifier.MetaModifier | Qt.KeyboardModifier.ShiftModifier,
+ Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.ShiftModifier),
+ (Qt.KeyboardModifier.ShiftModifier, Qt.KeyboardModifier.ShiftModifier),
])
def test_fake_mac(self, modifiers, expected):
"""Make sure Control/Meta are swapped with a simulated Mac."""
seq = keyutils.KeySequence()
- info = keyutils.KeyInfo(key=Qt.Key_A, modifiers=modifiers)
+ info = keyutils.KeyInfo(key=Qt.Key.Key_A, modifiers=modifiers)
new = seq.append_event(info.to_event())
- assert new[0] == keyutils.KeyInfo(Qt.Key_A, expected)
+ assert new[0] == keyutils.KeyInfo(Qt.Key.Key_A, expected)
- @pytest.mark.parametrize('key', [Qt.Key_unknown, 0x0])
+ @pytest.mark.parametrize('key', [Qt.Key.Key_unknown, 0x0])
def test_append_event_invalid(self, key):
seq = keyutils.KeySequence()
- event = QKeyEvent(QKeyEvent.KeyPress, key, Qt.NoModifier, '')
+ event = QKeyEvent(QEvent.Type.KeyPress, key, Qt.KeyboardModifier.NoModifier, '')
with pytest.raises(keyutils.KeyParseError):
seq.append_event(event)
def test_strip_modifiers(self):
- seq = keyutils.KeySequence(Qt.Key_0,
- Qt.Key_1 | Qt.KeypadModifier,
- Qt.Key_A | Qt.ControlModifier)
- expected = keyutils.KeySequence(Qt.Key_0,
- Qt.Key_1,
- Qt.Key_A | Qt.ControlModifier)
+ seq = keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_0),
+ keyutils.KeyInfo(Qt.Key.Key_1, Qt.KeyboardModifier.KeypadModifier),
+ keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.ControlModifier))
+ expected = keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_0),
+ keyutils.KeyInfo(Qt.Key.Key_1),
+ keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.ControlModifier))
assert seq.strip_modifiers() == expected
@pytest.mark.parametrize('inp, mappings, expected', [
@@ -497,31 +514,31 @@ class TestKeySequence:
@pytest.mark.parametrize('keystr, expected', [
('<Ctrl-Alt-y>',
- keyutils.KeySequence(Qt.ControlModifier | Qt.AltModifier | Qt.Key_Y)),
- ('x', keyutils.KeySequence(Qt.Key_X)),
- ('X', keyutils.KeySequence(Qt.ShiftModifier | Qt.Key_X)),
- ('<Escape>', keyutils.KeySequence(Qt.Key_Escape)),
- ('xyz', keyutils.KeySequence(Qt.Key_X, Qt.Key_Y, Qt.Key_Z)),
+ keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_Y, Qt.KeyboardModifier.ControlModifier | Qt.KeyboardModifier.AltModifier))),
+ ('x', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_X))),
+ ('X', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_X, Qt.KeyboardModifier.ShiftModifier))),
+ ('<Escape>', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_Escape))),
+ ('xyz', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_X), keyutils.KeyInfo(Qt.Key.Key_Y), keyutils.KeyInfo(Qt.Key.Key_Z))),
('<Control-x><Meta-y>',
- keyutils.KeySequence(Qt.ControlModifier | Qt.Key_X,
- Qt.MetaModifier | Qt.Key_Y)),
-
- ('<Shift-x>', keyutils.KeySequence(Qt.ShiftModifier | Qt.Key_X)),
- ('<Alt-x>', keyutils.KeySequence(Qt.AltModifier | Qt.Key_X)),
- ('<Control-x>', keyutils.KeySequence(Qt.ControlModifier | Qt.Key_X)),
- ('<Meta-x>', keyutils.KeySequence(Qt.MetaModifier | Qt.Key_X)),
- ('<Num-x>', keyutils.KeySequence(Qt.KeypadModifier | Qt.Key_X)),
-
- ('>', keyutils.KeySequence(Qt.Key_Greater)),
- ('<', keyutils.KeySequence(Qt.Key_Less)),
- ('a>', keyutils.KeySequence(Qt.Key_A, Qt.Key_Greater)),
- ('a<', keyutils.KeySequence(Qt.Key_A, Qt.Key_Less)),
- ('>a', keyutils.KeySequence(Qt.Key_Greater, Qt.Key_A)),
- ('<a', keyutils.KeySequence(Qt.Key_Less, Qt.Key_A)),
+ keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_X, Qt.KeyboardModifier.ControlModifier),
+ keyutils.KeyInfo(Qt.Key.Key_Y, Qt.KeyboardModifier.MetaModifier))),
+
+ ('<Shift-x>', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_X, Qt.KeyboardModifier.ShiftModifier))),
+ ('<Alt-x>', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_X, Qt.KeyboardModifier.AltModifier))),
+ ('<Control-x>', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_X, Qt.KeyboardModifier.ControlModifier))),
+ ('<Meta-x>', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_X, Qt.KeyboardModifier.MetaModifier))),
+ ('<Num-x>', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_X, Qt.KeyboardModifier.KeypadModifier))),
+
+ ('>', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_Greater))),
+ ('<', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_Less))),
+ ('a>', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_A), keyutils.KeyInfo(Qt.Key.Key_Greater))),
+ ('a<', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_A), keyutils.KeyInfo(Qt.Key.Key_Less))),
+ ('>a', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_Greater), keyutils.KeyInfo(Qt.Key.Key_A))),
+ ('<a', keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_Less), keyutils.KeyInfo(Qt.Key.Key_A))),
('<alt+greater>',
- keyutils.KeySequence(Qt.Key_Greater | Qt.AltModifier)),
+ keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_Greater, Qt.KeyboardModifier.AltModifier))),
('<alt+less>',
- keyutils.KeySequence(Qt.Key_Less | Qt.AltModifier)),
+ keyutils.KeySequence(keyutils.KeyInfo(Qt.Key.Key_Less, Qt.KeyboardModifier.AltModifier))),
('<alt+<>', keyutils.KeyParseError),
('<alt+>>', keyutils.KeyParseError),
@@ -547,79 +564,85 @@ class TestKeySequence:
def test_key_info_from_event():
- ev = QKeyEvent(QEvent.KeyPress, Qt.Key_A, Qt.ShiftModifier, 'A')
+ ev = QKeyEvent(QEvent.Type.KeyPress, Qt.Key.Key_A, Qt.KeyboardModifier.ShiftModifier, 'A')
info = keyutils.KeyInfo.from_event(ev)
- assert info.key == Qt.Key_A
- assert info.modifiers == Qt.ShiftModifier
+ assert info.key == Qt.Key.Key_A
+ assert info.modifiers == Qt.KeyboardModifier.ShiftModifier
def test_key_info_to_event():
- info = keyutils.KeyInfo(Qt.Key_A, Qt.ShiftModifier)
+ info = keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.ShiftModifier)
ev = info.to_event()
- assert ev.key() == Qt.Key_A
- assert ev.modifiers() == Qt.ShiftModifier
+ assert ev.key() == Qt.Key.Key_A
+ assert ev.modifiers() == Qt.KeyboardModifier.ShiftModifier
assert ev.text() == 'A'
-def test_key_info_to_int():
- info = keyutils.KeyInfo(Qt.Key_A, Qt.ShiftModifier)
- assert info.to_int() == Qt.Key_A | Qt.ShiftModifier
+def test_key_info_to_qt():
+ info = keyutils.KeyInfo(Qt.Key.Key_A, Qt.KeyboardModifier.ShiftModifier)
+ assert info.to_qt() == Qt.Key.Key_A | Qt.KeyboardModifier.ShiftModifier
@pytest.mark.parametrize('key, printable', [
- (Qt.Key_Control, False),
- (Qt.Key_Escape, False),
- (Qt.Key_Tab, False),
- (Qt.Key_Backtab, False),
- (Qt.Key_Backspace, False),
- (Qt.Key_Return, False),
- (Qt.Key_Enter, False),
- (Qt.Key_Space, False),
+ (Qt.Key.Key_Control, False),
+ (Qt.Key.Key_Escape, False),
+ (Qt.Key.Key_Tab, False),
+ (Qt.Key.Key_Backtab, False),
+ (Qt.Key.Key_Backspace, False),
+ (Qt.Key.Key_Return, False),
+ (Qt.Key.Key_Enter, False),
+ (Qt.Key.Key_Space, False),
(0x0, False), # Used by Qt for unknown keys
- (Qt.Key_ydiaeresis, True),
- (Qt.Key_X, True),
+ (Qt.Key.Key_ydiaeresis, True),
+ (Qt.Key.Key_X, True),
])
def test_is_printable(key, printable):
assert keyutils._is_printable(key) == printable
- assert keyutils.is_special(key, Qt.NoModifier) != printable
+ info = keyutils.KeyInfo(key, Qt.KeyboardModifier.NoModifier)
+ assert info.is_special() != printable
@pytest.mark.parametrize('key, modifiers, special', [
- (Qt.Key_Escape, Qt.NoModifier, True),
- (Qt.Key_Escape, Qt.ShiftModifier, True),
- (Qt.Key_Escape, Qt.ControlModifier, True),
- (Qt.Key_X, Qt.ControlModifier, True),
- (Qt.Key_X, Qt.NoModifier, False),
- (Qt.Key_2, Qt.KeypadModifier, True),
- (Qt.Key_2, Qt.NoModifier, False),
- (Qt.Key_Shift, Qt.ShiftModifier, True),
- (Qt.Key_Control, Qt.ControlModifier, True),
- (Qt.Key_Alt, Qt.AltModifier, True),
- (Qt.Key_Meta, Qt.MetaModifier, True),
- (Qt.Key_Mode_switch, Qt.GroupSwitchModifier, True),
+ (Qt.Key.Key_Escape, Qt.KeyboardModifier.NoModifier, True),
+ (Qt.Key.Key_Escape, Qt.KeyboardModifier.ShiftModifier, True),
+ (Qt.Key.Key_Escape, Qt.KeyboardModifier.ControlModifier, True),
+ (Qt.Key.Key_X, Qt.KeyboardModifier.ControlModifier, True),
+ (Qt.Key.Key_X, Qt.KeyboardModifier.NoModifier, False),
+ (Qt.Key.Key_2, Qt.KeyboardModifier.KeypadModifier, True),
+ (Qt.Key.Key_2, Qt.KeyboardModifier.NoModifier, False),
+ (Qt.Key.Key_Shift, Qt.KeyboardModifier.ShiftModifier, True),
+ (Qt.Key.Key_Control, Qt.KeyboardModifier.ControlModifier, True),
+ (Qt.Key.Key_Alt, Qt.KeyboardModifier.AltModifier, True),
+ (Qt.Key.Key_Meta, Qt.KeyboardModifier.MetaModifier, True),
+ (Qt.Key.Key_Mode_switch, Qt.KeyboardModifier.GroupSwitchModifier, True),
])
def test_is_special(key, modifiers, special):
- assert keyutils.is_special(key, modifiers) == special
+ assert keyutils.KeyInfo(key, modifiers).is_special() == special
@pytest.mark.parametrize('key, ismodifier', [
- (Qt.Key_Control, True),
- (Qt.Key_X, False),
- (Qt.Key_Super_L, False), # Modifier but not in _MODIFIER_MAP
+ (Qt.Key.Key_Control, True),
+ (Qt.Key.Key_X, False),
+ (Qt.Key.Key_Super_L, False), # Modifier but not in _MODIFIER_MAP
])
def test_is_modifier_key(key, ismodifier):
- assert keyutils.is_modifier_key(key) == ismodifier
+ assert keyutils.KeyInfo(key).is_modifier_key() == ismodifier
@pytest.mark.parametrize('func', [
keyutils._assert_plain_key,
keyutils._assert_plain_modifier,
keyutils._is_printable,
- keyutils.is_modifier_key,
keyutils._key_to_string,
keyutils._modifiers_to_string,
+ keyutils.KeyInfo,
])
def test_non_plain(func):
+ comb = Qt.Key.Key_X | Qt.KeyboardModifier.ControlModifier
+ if machinery.IS_QT6:
+ # QKeyCombination
+ comb = comb.toCombined()
+
with pytest.raises(AssertionError):
- func(Qt.Key_X | Qt.ControlModifier)
+ func(comb)
diff --git a/tests/unit/keyinput/test_modeman.py b/tests/unit/keyinput/test_modeman.py
index 8cc298f87..8d9a98002 100644
--- a/tests/unit/keyinput/test_modeman.py
+++ b/tests/unit/keyinput/test_modeman.py
@@ -19,7 +19,8 @@
import pytest
-from PyQt5.QtCore import Qt, QObject, pyqtSignal
+from qutebrowser.qt.core import Qt, QObject, pyqtSignal
+from qutebrowser.qt.gui import QKeyEvent, QKeySequence
from qutebrowser.utils import usertypes
from qutebrowser.keyinput import keyutils
@@ -37,8 +38,13 @@ class FakeKeyparser(QObject):
super().__init__()
self.passthrough = False
- def handle(self, evt, *, dry_run=False):
- return False
+ def handle(
+ self,
+ evt: QKeyEvent,
+ *,
+ dry_run: bool = False,
+ ) -> QKeySequence.SequenceMatch:
+ return QKeySequence.SequenceMatch.NoMatch
@pytest.fixture
@@ -53,11 +59,11 @@ def set_qapp(monkeypatch, qapp):
@pytest.mark.parametrize('key, modifiers, filtered', [
- (Qt.Key_A, Qt.NoModifier, True),
- (Qt.Key_Up, Qt.NoModifier, False),
+ (Qt.Key.Key_A, Qt.KeyboardModifier.NoModifier, True),
+ (Qt.Key.Key_Up, Qt.KeyboardModifier.NoModifier, False),
# https://github.com/qutebrowser/qutebrowser/issues/1207
- (Qt.Key_A, Qt.ShiftModifier, True),
- (Qt.Key_A, Qt.ShiftModifier | Qt.ControlModifier, False),
+ (Qt.Key.Key_A, Qt.KeyboardModifier.ShiftModifier, True),
+ (Qt.Key.Key_A, Qt.KeyboardModifier.ShiftModifier | Qt.KeyboardModifier.ControlModifier, False),
])
def test_non_alphanumeric(key, modifiers, filtered, modeman):
"""Make sure non-alphanumeric keys are passed through correctly."""
diff --git a/tests/unit/keyinput/test_modeparsers.py b/tests/unit/keyinput/test_modeparsers.py
index ff3758362..b997b0ab9 100644
--- a/tests/unit/keyinput/test_modeparsers.py
+++ b/tests/unit/keyinput/test_modeparsers.py
@@ -19,12 +19,13 @@
"""Tests for mode parsers."""
-from PyQt5.QtCore import Qt
-from PyQt5.QtGui import QKeySequence
+from qutebrowser.qt.core import Qt
+from qutebrowser.qt.gui import QKeySequence
import pytest
from qutebrowser.keyinput import modeparsers, keyutils
+from qutebrowser.config import configexc
@pytest.fixture
@@ -65,7 +66,7 @@ class TestsNormalKeyParser:
# Press 'b' for a partial match.
# Then we check if the timer has been set up correctly
- keyparser.handle(keyutils.KeyInfo(Qt.Key_B, Qt.NoModifier).to_event())
+ keyparser.handle(keyutils.KeyInfo(Qt.Key.Key_B, Qt.KeyboardModifier.NoModifier).to_event())
assert timer.isSingleShot()
assert timer.interval() == 100
assert timer.isActive()
@@ -122,33 +123,36 @@ class TestHintKeyParser:
),
])
def test_match(self, keyparser, hintmanager,
- bindings, keychain, prefix, hint):
- keyparser.update_bindings(bindings)
+ bindings, keychain, prefix, hint, pyqt_enum_workaround):
+ with pyqt_enum_workaround(keyutils.KeyParseError):
+ keyparser.update_bindings(bindings)
seq = keyutils.KeySequence.parse(keychain)
assert len(seq) == 2
match = keyparser.handle(seq[0].to_event())
- assert match == QKeySequence.PartialMatch
+ assert match == QKeySequence.SequenceMatch.PartialMatch
assert hintmanager.keystr == prefix
match = keyparser.handle(seq[1].to_event())
- assert match == QKeySequence.ExactMatch
+ assert match == QKeySequence.SequenceMatch.ExactMatch
assert hintmanager.keystr == hint
- def test_match_key_mappings(self, config_stub, keyparser, hintmanager):
- config_stub.val.bindings.key_mappings = {'α': 'a', 'σ': 's'}
+ def test_match_key_mappings(self, config_stub, keyparser, hintmanager,
+ pyqt_enum_workaround):
+ with pyqt_enum_workaround(configexc.ValidationError):
+ config_stub.val.bindings.key_mappings = {'α': 'a', 'σ': 's'}
keyparser.update_bindings(['aa', 'as'])
seq = keyutils.KeySequence.parse('ασ')
assert len(seq) == 2
match = keyparser.handle(seq[0].to_event())
- assert match == QKeySequence.PartialMatch
+ assert match == QKeySequence.SequenceMatch.PartialMatch
assert hintmanager.keystr == 'a'
match = keyparser.handle(seq[1].to_event())
- assert match == QKeySequence.ExactMatch
+ assert match == QKeySequence.SequenceMatch.ExactMatch
assert hintmanager.keystr == 'as'
def test_command(self, keyparser, config_stub, hintmanager, commandrunner):
@@ -159,17 +163,17 @@ class TestHintKeyParser:
keyparser.update_bindings(['xabcy'])
steps = [
- (Qt.Key_X, QKeySequence.PartialMatch, 'x'),
- (Qt.Key_A, QKeySequence.PartialMatch, ''),
- (Qt.Key_B, QKeySequence.PartialMatch, ''),
- (Qt.Key_C, QKeySequence.ExactMatch, ''),
+ (Qt.Key.Key_X, QKeySequence.SequenceMatch.PartialMatch, 'x'),
+ (Qt.Key.Key_A, QKeySequence.SequenceMatch.PartialMatch, ''),
+ (Qt.Key.Key_B, QKeySequence.SequenceMatch.PartialMatch, ''),
+ (Qt.Key.Key_C, QKeySequence.SequenceMatch.ExactMatch, ''),
]
for key, expected_match, keystr in steps:
- info = keyutils.KeyInfo(key, Qt.NoModifier)
+ info = keyutils.KeyInfo(key, Qt.KeyboardModifier.NoModifier)
match = keyparser.handle(info.to_event())
assert match == expected_match
assert hintmanager.keystr == keystr
- if key != Qt.Key_C:
+ if key != Qt.Key.Key_C:
assert not commandrunner.commands
assert commandrunner.commands == [('message-info abc', None)]
diff --git a/tests/unit/mainwindow/statusbar/test_textbase.py b/tests/unit/mainwindow/statusbar/test_textbase.py
index 33c4ffd76..6bceb4bc4 100644
--- a/tests/unit/mainwindow/statusbar/test_textbase.py
+++ b/tests/unit/mainwindow/statusbar/test_textbase.py
@@ -19,17 +19,17 @@
"""Test TextBase widget."""
-from PyQt5.QtCore import Qt
+from qutebrowser.qt.core import Qt
import pytest
from qutebrowser.mainwindow.statusbar.textbase import TextBase
@pytest.mark.parametrize('elidemode, check', [
- (Qt.ElideRight, lambda s: s.endswith('…') or s.endswith('...')),
- (Qt.ElideLeft, lambda s: s.startswith('…') or s.startswith('...')),
- (Qt.ElideMiddle, lambda s: '…' in s or '...' in s),
- (Qt.ElideNone, lambda s: '…' not in s and '...' not in s),
+ (Qt.TextElideMode.ElideRight, lambda s: s.endswith('…') or s.endswith('...')),
+ (Qt.TextElideMode.ElideLeft, lambda s: s.startswith('…') or s.startswith('...')),
+ (Qt.TextElideMode.ElideMiddle, lambda s: '…' in s or '...' in s),
+ (Qt.TextElideMode.ElideNone, lambda s: '…' not in s and '...' not in s),
])
def test_elided_text(fake_statusbar, qtbot, elidemode, check):
"""Ensure that a widget too small to hold the entire label text will elide.
diff --git a/tests/unit/mainwindow/statusbar/test_url.py b/tests/unit/mainwindow/statusbar/test_url.py
index efe4d6f93..353c47a3c 100644
--- a/tests/unit/mainwindow/statusbar/test_url.py
+++ b/tests/unit/mainwindow/statusbar/test_url.py
@@ -22,9 +22,9 @@
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
-from qutebrowser.utils import usertypes, urlutils
+from qutebrowser.utils import usertypes, urlutils, qtutils
from qutebrowser.mainwindow.statusbar import url
@@ -37,6 +37,18 @@ def url_widget(qtbot, monkeypatch, config_stub):
return widget
+qurl_idna2003 = pytest.mark.skipif(
+ qtutils.version_check("6.3.0", compiled=False),
+ reason="Different result with Qt >= 6.3.0: "
+ "https://bugreports.qt.io/browse/QTBUG-85371"
+)
+qurl_uts46 = pytest.mark.xfail(
+ not qtutils.version_check("6.3.0", compiled=False),
+ reason="Different result with Qt < 6.3.0: "
+ "https://bugreports.qt.io/browse/QTBUG-85371"
+)
+
+
@pytest.mark.parametrize('url_text, expected', [
('http://example.com/foo/bar.html', 'http://example.com/foo/bar.html'),
('http://test.gr/%CE%B1%CE%B2%CE%B3%CE%B4.txt', 'http://test.gr/αβγδ.txt'),
@@ -46,7 +58,16 @@ def url_widget(qtbot, monkeypatch, config_stub):
('http://username:secret%20password@test.com', 'http://username@test.com'),
('http://example.com%5b/', '(invalid URL!) http://example.com%5b/'),
# https://bugreports.qt.io/browse/QTBUG-60364
- ('http://www.xn--80ak6aa92e.com', 'http://www.xn--80ak6aa92e.com'),
+ pytest.param(
+ 'http://www.xn--80ak6aa92e.com',
+ 'http://www.xn--80ak6aa92e.com',
+ marks=qurl_idna2003
+ ),
+ pytest.param(
+ 'http://www.xn--80ak6aa92e.com',
+ '(www.xn--80ak6aa92e.com) http://www.аррӏе.com',
+ marks=qurl_uts46,
+ ),
# IDN URL
('http://www.ä.com', '(www.xn--4ca.com) http://www.ä.com'),
(None, ''),
diff --git a/tests/unit/mainwindow/test_messageview.py b/tests/unit/mainwindow/test_messageview.py
index 5ba0e4ffc..5c3f14b2e 100644
--- a/tests/unit/mainwindow/test_messageview.py
+++ b/tests/unit/mainwindow/test_messageview.py
@@ -20,7 +20,7 @@
import contextlib
import pytest
-from PyQt5.QtCore import Qt
+from qutebrowser.qt.core import Qt
from qutebrowser.mainwindow import messageview
from qutebrowser.utils import usertypes, message
@@ -90,7 +90,11 @@ def test_word_wrap(view, qtbot):
])
@pytest.mark.parametrize("replace", ["test", None])
def test_rich_text(view, qtbot, rich, higher, expected_format, replace):
- """Rich text should be rendered appropriately."""
+ """Rich text should be rendered appropriately.
+
+ This makes sure the title has been rendered as plain text by comparing the
+ heights of the two widgets. To ensure consistent results, we disable word-wrapping.
+ """
level = usertypes.MessageLevel.info
text = 'with <h1>markup</h1>'
text2 = 'with <h1>markup</h1> 2'
@@ -105,6 +109,7 @@ def test_rich_text(view, qtbot, rich, higher, expected_format, replace):
with ctx:
view.show_message(info1)
assert len(view._messages) == 1
+ view._messages[0].setWordWrap(False)
height1 = view.sizeHint().height()
assert height1 > 0
@@ -112,10 +117,14 @@ def test_rich_text(view, qtbot, rich, higher, expected_format, replace):
assert view._messages[0].textFormat() == Qt.TextFormat.PlainText # default
view.show_message(info2)
- height2 = view.sizeHint().height()
assert len(view._messages) == 1
+ view._messages[0].setWordWrap(False)
+
+ height2 = view.sizeHint().height()
+ assert height2 > 0
assert view._messages[0].textFormat() == expected_format
+
if higher:
assert height2 > height1
else:
@@ -239,10 +248,10 @@ def test_replacing_geometry(qtbot, view):
@pytest.mark.parametrize('button, count', [
- (Qt.LeftButton, 0),
- (Qt.MiddleButton, 0),
- (Qt.RightButton, 0),
- (Qt.BackButton, 2),
+ (Qt.MouseButton.LeftButton, 0),
+ (Qt.MouseButton.MiddleButton, 0),
+ (Qt.MouseButton.RightButton, 0),
+ (Qt.MouseButton.BackButton, 2),
])
def test_click_messages(qtbot, view, button, count):
"""Messages should disappear when we click on them."""
diff --git a/tests/unit/mainwindow/test_prompt.py b/tests/unit/mainwindow/test_prompt.py
index 3218959a5..4dbe5a41a 100644
--- a/tests/unit/mainwindow/test_prompt.py
+++ b/tests/unit/mainwindow/test_prompt.py
@@ -20,7 +20,7 @@
import os
import pytest
-from PyQt5.QtCore import Qt
+from qutebrowser.qt.core import Qt
from qutebrowser.mainwindow import prompt as promptmod
from qutebrowser.utils import usertypes
@@ -79,7 +79,7 @@ class TestFileCompletion:
# Deleting /f[oo/]
with qtbot.wait_signal(prompt._file_model.directoryLoaded):
for _ in range(3):
- qtbot.keyPress(prompt._lineedit, Qt.Key_Backspace)
+ qtbot.keyPress(prompt._lineedit, Qt.Key.Key_Backspace)
# For some reason, this isn't always called when using qtbot.keyPress.
prompt._set_fileview_root(prompt._lineedit.text())
@@ -90,7 +90,7 @@ class TestFileCompletion:
# Deleting /[foo]
for _ in range(3):
- qtbot.keyPress(prompt._lineedit, Qt.Key_Backspace)
+ qtbot.keyPress(prompt._lineedit, Qt.Key.Key_Backspace)
# We should now show / again, so tabbing twice gives us bar -> foo
prompt.item_focus('next')
@@ -99,8 +99,8 @@ class TestFileCompletion:
@pytest.mark.parametrize("keys, expected", [
([], ['bar', 'bat', 'foo']),
- ([Qt.Key_F], ['foo']),
- ([Qt.Key_A], ['bar', 'bat']),
+ ([Qt.Key.Key_F], ['foo']),
+ ([Qt.Key.Key_A], ['bar', 'bat']),
])
def test_filtering_path(self, qtbot, tmp_path, get_prompt, keys, expected):
testdir = tmp_path / 'test'
diff --git a/tests/unit/mainwindow/test_tabwidget.py b/tests/unit/mainwindow/test_tabwidget.py
index 564ca1b38..db300d7a6 100644
--- a/tests/unit/mainwindow/test_tabwidget.py
+++ b/tests/unit/mainwindow/test_tabwidget.py
@@ -23,7 +23,7 @@
import functools
import pytest
-from PyQt5.QtGui import QIcon, QPixmap
+from qutebrowser.qt.gui import QIcon, QPixmap
from qutebrowser.mainwindow import tabwidget
from qutebrowser.utils import usertypes
diff --git a/tests/unit/misc/test_autoupdate.py b/tests/unit/misc/test_autoupdate.py
index f7cf78248..72b63b0c4 100644
--- a/tests/unit/misc/test_autoupdate.py
+++ b/tests/unit/misc/test_autoupdate.py
@@ -21,7 +21,7 @@
"""Tests for qutebrowser.misc.autoupdate."""
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.misc import autoupdate, httpclient
diff --git a/tests/unit/misc/test_editor.py b/tests/unit/misc/test_editor.py
index bec775add..4fd915062 100644
--- a/tests/unit/misc/test_editor.py
+++ b/tests/unit/misc/test_editor.py
@@ -26,7 +26,7 @@ import os
import logging
import pytest
-from PyQt5.QtCore import QProcess
+from qutebrowser.qt.core import QProcess
from qutebrowser.misc import editor as editormod
from qutebrowser.utils import usertypes
@@ -81,7 +81,7 @@ class TestFileHandling:
filename = pathlib.Path(editor._filename)
assert filename.exists()
assert filename.name.startswith('qutebrowser-editor-')
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QProcess.ExitStatus.NormalExit)
assert filename.exists() != config_stub.val.editor.remove_file
@pytest.mark.parametrize('touch', [True, False])
@@ -92,7 +92,7 @@ class TestFileHandling:
path.touch()
editor.edit_file(str(path))
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QProcess.ExitStatus.NormalExit)
assert path.exists()
@@ -103,7 +103,7 @@ class TestFileHandling:
assert filename.exists()
with caplog.at_level(logging.ERROR):
- editor._proc._proc.finished.emit(1, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(1, QProcess.ExitStatus.NormalExit)
assert filename.exists()
@@ -115,9 +115,9 @@ class TestFileHandling:
filename = pathlib.Path(editor._filename)
assert filename.exists()
- editor._proc.error.emit(QProcess.Crashed)
+ editor._proc.error.emit(QProcess.ProcessError.Crashed)
with caplog.at_level(logging.ERROR):
- editor._proc._proc.finished.emit(0, QProcess.CrashExit)
+ editor._proc._proc.finished.emit(0, QProcess.ExitStatus.CrashExit)
assert filename.exists()
filename.unlink()
@@ -133,7 +133,7 @@ class TestFileHandling:
pytest.skip("File was still readable")
with caplog.at_level(logging.ERROR):
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QProcess.ExitStatus.NormalExit)
assert not filename.exists()
msg = message_mock.getmsg(usertypes.MessageLevel.error)
assert msg.text.startswith("Failed to read back edited file: ")
@@ -181,7 +181,7 @@ class TestFileHandling:
fname = msg.text[len(prefix):]
with qtbot.wait_signal(editor.editing_finished):
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QProcess.ExitStatus.NormalExit)
with open(fname, 'r', encoding='utf-8') as f:
assert f.read() == 'bar'
@@ -224,7 +224,7 @@ def test_modify(qtbot, editor, initial_text, edited_text):
f.write(edited_text)
with qtbot.wait_signal(editor.file_updated) as blocker:
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QProcess.ExitStatus.NormalExit)
assert blocker.args == [edited_text]
@@ -258,7 +258,7 @@ def test_modify_watch(qtbot):
assert blocker.args == ['baz']
with qtbot.assert_not_emitted(editor.file_updated):
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QProcess.ExitStatus.NormalExit)
def test_failing_watch(qtbot, caplog, monkeypatch):
@@ -276,7 +276,7 @@ def test_failing_watch(qtbot, caplog, monkeypatch):
_update_file(editor._filename, 'bar')
with qtbot.wait_signal(editor.file_updated) as blocker:
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QProcess.ExitStatus.NormalExit)
assert blocker.args == ['bar']
message = 'Failed to watch path: {}'.format(editor._filename)
@@ -293,7 +293,7 @@ def test_failing_unwatch(qtbot, caplog, monkeypatch):
editor.edit('foo')
with caplog.at_level(logging.ERROR):
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QProcess.ExitStatus.NormalExit)
message = 'Failed to unwatch paths: [{!r}]'.format(editor._filename)
assert caplog.messages[-1] == message
diff --git a/tests/unit/misc/test_elf.py b/tests/unit/misc/test_elf.py
index 7d3248da2..8a89d11fb 100644
--- a/tests/unit/misc/test_elf.py
+++ b/tests/unit/misc/test_elf.py
@@ -57,7 +57,7 @@ def test_result(qapp, caplog):
If that happens, please report a bug about it!
"""
- pytest.importorskip('PyQt5.QtWebEngineCore')
+ pytest.importorskip('qutebrowser.qt.webenginecore')
versions = elf.parse_webenginecore()
assert versions is not None
@@ -87,11 +87,52 @@ def test_result(qapp, caplog):
b"QtWebEngine/5.15.9 Chrome/87.0.4280.144\x00",
elf.Versions("5.15.9", "87.0.4280.144"),
),
+ # Piecing stuff together
+ (
+ (
+ b"\x00QtWebEngine/6.4.0 Chrome/98.0.47Navigation to external protocol "
+ b"blocked by sandb/webengine\x00"
+ b"lots-of-other-stuff\x00"
+ b"98.0.4758.90\x0099.0.4844.84\x00"
+ ),
+ elf.Versions("6.4.0", "98.0.4758.90"),
+ ),
])
def test_find_versions(data, expected):
assert elf._find_versions(data) == expected
+@pytest.mark.parametrize("data, message", [
+ # No match at all
+ (
+ b"blablabla",
+ "No match in .rodata"
+ ),
+ # Piecing stuff together: too short partial match
+ (
+ (
+ b"\x00QtWebEngine/6.4.0 Chrome/98bla\x00"
+ b"lots-of-other-stuff\x00"
+ b"98.0.4758.90\x0099.0.4844.84\x00"
+ ),
+ "Inconclusive partial Chromium bytes"
+ ),
+ # Piecing stuff together: no full match
+ (
+ (
+ b"\x00QtWebEngine/6.4.0 Chrome/98.0.47blabla"
+ b"lots-of-other-stuff\x00"
+ b"98.0.1234.56\x00"
+ ),
+ "No match in .rodata for full version"
+ ),
+])
+def test_find_versions_invalid(data, message):
+ with pytest.raises(elf.ParseError) as excinfo:
+ elf._find_versions(data)
+ assert str(excinfo.value) == message
+
+
@hypothesis.given(data=hst.builds(
lambda *a: b''.join(a),
hst.sampled_from([b'', b'\x7fELF', b'\x7fELF\x02\x01\x01']),
diff --git a/tests/unit/misc/test_guiprocess.py b/tests/unit/misc/test_guiprocess.py
index fa90391a8..d225ab2e2 100644
--- a/tests/unit/misc/test_guiprocess.py
+++ b/tests/unit/misc/test_guiprocess.py
@@ -23,7 +23,7 @@ import sys
import logging
import pytest
-from PyQt5.QtCore import QProcess, QUrl
+from qutebrowser.qt.core import QProcess, QUrl
from qutebrowser.misc import guiprocess
from qutebrowser.utils import usertypes, utils, version
@@ -36,7 +36,7 @@ def proc(qtbot, caplog):
"""A fixture providing a GUIProcess and cleaning it up after the test."""
p = guiprocess.GUIProcess('testprocess')
yield p
- if not sip.isdeleted(p._proc) and p._proc.state() != QProcess.NotRunning:
+ if not sip.isdeleted(p._proc) and p._proc.state() != QProcess.ProcessState.NotRunning:
with caplog.at_level(logging.ERROR):
with qtbot.wait_signal(p.finished, timeout=10000,
raising=False) as blocker:
@@ -126,7 +126,7 @@ def test_start(proc, qtbot, message_mock, py_proc):
assert not message_mock.messages
assert not proc.outcome.running
- assert proc.outcome.status == QProcess.NormalExit
+ assert proc.outcome.status == QProcess.ExitStatus.NormalExit
assert proc.outcome.code == 0
assert str(proc.outcome) == 'Testprocess exited successfully.'
assert proc.outcome.state_str() == 'successful'
@@ -433,7 +433,7 @@ def test_exit_unsuccessful(qtbot, proc, message_mock, py_proc, caplog):
assert msg.text == expected
assert not proc.outcome.running
- assert proc.outcome.status == QProcess.NormalExit
+ assert proc.outcome.status == QProcess.ExitStatus.NormalExit
assert proc.outcome.code == 1
assert str(proc.outcome) == 'Testprocess exited with status 1.'
assert proc.outcome.state_str() == 'unsuccessful'
@@ -453,7 +453,7 @@ def test_exit_crash(qtbot, proc, message_mock, py_proc, caplog):
assert msg.text == "Testprocess crashed. See :process for details."
assert not proc.outcome.running
- assert proc.outcome.status == QProcess.CrashExit
+ assert proc.outcome.status == QProcess.ExitStatus.CrashExit
assert str(proc.outcome) == 'Testprocess crashed.'
assert proc.outcome.state_str() == 'crashed'
assert not proc.outcome.was_successful()
diff --git a/tests/unit/misc/test_ipc.py b/tests/unit/misc/test_ipc.py
index eea4f9bb5..2390c6f90 100644
--- a/tests/unit/misc/test_ipc.py
+++ b/tests/unit/misc/test_ipc.py
@@ -30,9 +30,9 @@ from unittest import mock
from typing import Optional, List
import pytest
-from PyQt5.QtCore import pyqtSignal, QObject
-from PyQt5.QtNetwork import QLocalServer, QLocalSocket, QAbstractSocket
-from PyQt5.QtTest import QSignalSpy
+from qutebrowser.qt.core import pyqtSignal, QObject
+from qutebrowser.qt.network import QLocalServer, QLocalSocket, QAbstractSocket
+from qutebrowser.qt.test import QSignalSpy
import qutebrowser
from qutebrowser.misc import ipc
@@ -56,7 +56,7 @@ def ipc_server(qapp, qtbot):
server = ipc.IPCServer('qute-test')
yield server
if (server._socket is not None and
- server._socket.state() != QLocalSocket.UnconnectedState):
+ server._socket.state() != QLocalSocket.LocalSocketState.UnconnectedState):
with qtbot.wait_signal(server._socket.disconnected, raising=False):
server._socket.abort()
try:
@@ -78,7 +78,7 @@ def qlocalsocket(qapp):
socket = QLocalSocket()
yield socket
socket.disconnectFromServer()
- if socket.state() != QLocalSocket.UnconnectedState:
+ if socket.state() != QLocalSocket.LocalSocketState.UnconnectedState:
socket.waitForDisconnected(1000)
@@ -102,17 +102,17 @@ class FakeSocket(QObject):
readyRead = pyqtSignal() # noqa: N815
disconnected = pyqtSignal()
+ errorOccurred = pyqtSignal(QLocalSocket.LocalSocketError) # noqa: N815
- def __init__(self, *, error=QLocalSocket.UnknownSocketError, state=None,
+ def __init__(self, *, error=QLocalSocket.LocalSocketError.UnknownSocketError, state=None,
data=None, connect_successful=True, parent=None):
super().__init__(parent)
self._error_val = error
self._state_val = state
self._data = data
self._connect_successful = connect_successful
- self.error = stubs.FakeSignal('error', func=self._error)
- def _error(self):
+ def error(self):
return self._error_val
def state(self):
@@ -270,21 +270,21 @@ class TestExceptions:
def test_listen_error(self, qlocalserver):
qlocalserver.listen(None)
exc = ipc.ListenError(qlocalserver)
- assert exc.code == 2
+ assert exc.code == QAbstractSocket.SocketError.HostNotFoundError
assert exc.message == "QLocalServer::listen: Name error"
msg = ("Error while listening to IPC server: QLocalServer::listen: "
- "Name error (error 2)")
+ "Name error (HostNotFoundError)")
assert str(exc) == msg
with pytest.raises(ipc.Error):
raise exc
def test_socket_error(self, qlocalserver):
- socket = FakeSocket(error=QLocalSocket.ConnectionRefusedError)
+ socket = FakeSocket(error=QLocalSocket.LocalSocketError.ConnectionRefusedError)
exc = ipc.SocketError("testing", socket)
- assert exc.code == QLocalSocket.ConnectionRefusedError
+ assert exc.code == QLocalSocket.LocalSocketError.ConnectionRefusedError
assert exc.message == "Error string"
- assert str(exc) == "Error while testing: Error string (error 0)"
+ assert str(exc) == "Error while testing: Error string (ConnectionRefusedError)"
with pytest.raises(ipc.Error):
raise exc
@@ -322,7 +322,7 @@ class TestListen:
@pytest.mark.windows
def test_permissions_windows(self, ipc_server):
opts = ipc_server._server.socketOptions()
- assert opts == QLocalServer.UserAccessOption
+ assert opts == QLocalServer.SocketOption.UserAccessOption
@pytest.mark.posix
def test_permissions_posix(self, ipc_server):
@@ -406,21 +406,21 @@ class TestOnError:
ipc_server._socket = QLocalSocket()
ipc_server._timer.timeout.disconnect()
ipc_server._timer.start()
- ipc_server.on_error(QLocalSocket.PeerClosedError)
+ ipc_server.on_error(QLocalSocket.LocalSocketError.PeerClosedError)
assert not ipc_server._timer.isActive()
def test_other_error(self, ipc_server, monkeypatch):
socket = QLocalSocket()
ipc_server._socket = socket
monkeypatch.setattr(socket, 'error',
- lambda: QLocalSocket.ConnectionRefusedError)
+ lambda: QLocalSocket.LocalSocketError.ConnectionRefusedError)
monkeypatch.setattr(socket, 'errorString',
lambda: "Connection refused")
socket.setErrorString("Connection refused.")
with pytest.raises(ipc.Error, match=r"Error while handling IPC "
- r"connection: Connection refused \(error 0\)"):
- ipc_server.on_error(QLocalSocket.ConnectionRefusedError)
+ r"connection: Connection refused \(ConnectionRefusedError\)"):
+ ipc_server.on_error(QLocalSocket.LocalSocketError.ConnectionRefusedError)
class TestHandleConnection:
@@ -444,17 +444,17 @@ class TestHandleConnection:
assert any(message.startswith(msg) for message in caplog.messages)
def test_disconnected_immediately(self, ipc_server, caplog):
- socket = FakeSocket(state=QLocalSocket.UnconnectedState)
+ socket = FakeSocket(state=QLocalSocket.LocalSocketState.UnconnectedState)
ipc_server._server = FakeServer(socket)
ipc_server.handle_connection()
assert "Socket was disconnected immediately." in caplog.messages
def test_error_immediately(self, ipc_server, caplog):
- socket = FakeSocket(error=QLocalSocket.ConnectionError)
+ socket = FakeSocket(error=QLocalSocket.LocalSocketError.ConnectionError)
ipc_server._server = FakeServer(socket)
with pytest.raises(ipc.Error, match=r"Error while handling IPC "
- r"connection: Error string \(error 7\)"):
+ r"connection: Error string \(ConnectionError\)"):
ipc_server.handle_connection()
assert "We got an error immediately." in caplog.messages
@@ -552,7 +552,8 @@ class TestSendToRunningInstance:
def test_no_server(self, caplog):
sent = ipc.send_to_running_instance('qute-test', [], None)
assert not sent
- assert caplog.messages[-1] == "No existing instance present (error 2)"
+ expected = "No existing instance present (ServerNotFoundError)"
+ assert caplog.messages[-1] == expected
@pytest.mark.parametrize('has_cwd', [True, False])
@pytest.mark.linux(reason="Causes random trouble on Windows and macOS")
@@ -588,9 +589,9 @@ class TestSendToRunningInstance:
assert parsed == raw_expected
def test_socket_error(self):
- socket = FakeSocket(error=QLocalSocket.ConnectionError)
+ socket = FakeSocket(error=QLocalSocket.LocalSocketError.ConnectionError)
with pytest.raises(ipc.Error, match=r"Error while writing to running "
- r"instance: Error string \(error 7\)"):
+ r"instance: Error string \(ConnectionError\)"):
ipc.send_to_running_instance('qute-test', [], None, socket=socket)
def test_not_disconnected_immediately(self):
@@ -598,10 +599,10 @@ class TestSendToRunningInstance:
ipc.send_to_running_instance('qute-test', [], None, socket=socket)
def test_socket_error_no_server(self):
- socket = FakeSocket(error=QLocalSocket.ConnectionError,
+ socket = FakeSocket(error=QLocalSocket.LocalSocketError.ConnectionError,
connect_successful=False)
with pytest.raises(ipc.Error, match=r"Error while connecting to "
- r"running instance: Error string \(error 7\)"):
+ r"running instance: Error string \(ConnectionError\)"):
ipc.send_to_running_instance('qute-test', [], None, socket=socket)
@@ -657,6 +658,7 @@ class TestSendOrListen:
def qlocalserver_mock(self, mocker):
m = mocker.patch('qutebrowser.misc.ipc.QLocalServer', autospec=True)
m().errorString.return_value = "Error string"
+ m.SocketOption = QLocalServer.SocketOption
m().newConnection = stubs.FakeSignal()
return m
@@ -664,10 +666,8 @@ class TestSendOrListen:
def qlocalsocket_mock(self, mocker):
m = mocker.patch('qutebrowser.misc.ipc.QLocalSocket', autospec=True)
m().errorString.return_value = "Error string"
- for name in ['UnknownSocketError', 'UnconnectedState',
- 'ConnectionRefusedError', 'ServerNotFoundError',
- 'PeerClosedError']:
- setattr(m, name, getattr(QLocalSocket, name))
+ m.LocalSocketError = QLocalSocket.LocalSocketError
+ m.LocalSocketState = QLocalSocket.LocalSocketState
return m
@pytest.mark.linux(reason="Flaky on Windows and macOS")
@@ -701,14 +701,14 @@ class TestSendOrListen:
-> success
"""
qlocalserver_mock().listen.return_value = False
- err = QAbstractSocket.AddressInUseError
+ err = QAbstractSocket.SocketError.AddressInUseError
qlocalserver_mock().serverError.return_value = err
qlocalsocket_mock().waitForConnected.side_effect = [False, True]
qlocalsocket_mock().error.side_effect = [
- QLocalSocket.ServerNotFoundError,
- QLocalSocket.UnknownSocketError,
- QLocalSocket.UnknownSocketError, # error() gets called twice
+ QLocalSocket.LocalSocketError.ServerNotFoundError,
+ QLocalSocket.LocalSocketError.UnknownSocketError,
+ QLocalSocket.LocalSocketError.UnknownSocketError, # error() gets called twice
]
ret = ipc.send_or_listen(args)
@@ -717,9 +717,9 @@ class TestSendOrListen:
@pytest.mark.parametrize('has_error, exc_name, exc_msg', [
(True, 'SocketError',
- 'Error while writing to running instance: Error string (error 0)'),
+ 'Error while writing to running instance: Error string (ConnectionRefusedError)'),
(False, 'AddressInUseError',
- 'Error while listening to IPC server: Error string (error 8)'),
+ 'Error while listening to IPC server: Error string (AddressInUseError)'),
])
def test_address_in_use_error(self, qlocalserver_mock, qlocalsocket_mock,
stubs, caplog, args, has_error, exc_name,
@@ -734,18 +734,21 @@ class TestSendOrListen:
-> not sent / error
"""
qlocalserver_mock().listen.return_value = False
- err = QAbstractSocket.AddressInUseError
+ err = QAbstractSocket.SocketError.AddressInUseError
qlocalserver_mock().serverError.return_value = err
# If the second connection succeeds, we will have an error later.
# If it fails, that's the "not sent" case above.
qlocalsocket_mock().waitForConnected.side_effect = [False, has_error]
qlocalsocket_mock().error.side_effect = [
- QLocalSocket.ServerNotFoundError,
- QLocalSocket.ServerNotFoundError,
- QLocalSocket.ConnectionRefusedError,
- QLocalSocket.ConnectionRefusedError, # error() gets called twice
+ QLocalSocket.LocalSocketError.ServerNotFoundError,
+ QLocalSocket.LocalSocketError.ServerNotFoundError,
+ QLocalSocket.LocalSocketError.ConnectionRefusedError,
+ QLocalSocket.LocalSocketError.ConnectionRefusedError, # error() gets called twice
]
+ # For debug.qenum_key() on Qt 5
+ value_to_key = qlocalsocket_mock.staticMetaObject.enumerator().valueToKey
+ value_to_key.return_value = "ConnectionRefusedError"
with caplog.at_level(logging.ERROR):
with pytest.raises(ipc.Error):
@@ -766,7 +769,7 @@ class TestSendOrListen:
def test_error_while_listening(self, qlocalserver_mock, caplog, args):
"""Test an error with the first listen call."""
qlocalserver_mock().listen.return_value = False
- err = QAbstractSocket.SocketResourceError
+ err = QAbstractSocket.SocketError.SocketResourceError
qlocalserver_mock().serverError.return_value = err
with caplog.at_level(logging.ERROR):
@@ -780,7 +783,7 @@ class TestSendOrListen:
'pre_text: ',
'post_text: ',
('exception text: Error while listening to IPC server: Error '
- 'string (error 4)'),
+ 'string (SocketResourceError)'),
]
assert caplog.messages[-1] == '\n'.join(error_msgs)
@@ -809,7 +812,7 @@ def test_connect_inexistent(qlocalsocket):
would not work properly.
"""
qlocalsocket.connectToServer('qute-test-inexistent')
- assert qlocalsocket.error() == QLocalSocket.ServerNotFoundError
+ assert qlocalsocket.error() == QLocalSocket.LocalSocketError.ServerNotFoundError
@pytest.mark.posix
@@ -826,7 +829,7 @@ def test_socket_options_address_in_use_problem(qlocalserver, short_tmpdir):
assert ok
s2 = QLocalServer()
- s2.setSocketOptions(QLocalServer.UserAccessOption)
+ s2.setSocketOptions(QLocalServer.SocketOption.UserAccessOption)
ok = s2.listen(servername)
print(s2.errorString())
# We actually would expect ok == False here - but we want the test to fail
diff --git a/tests/unit/misc/test_miscwidgets.py b/tests/unit/misc/test_miscwidgets.py
index 3c5c1eef1..8ec40008b 100644
--- a/tests/unit/misc/test_miscwidgets.py
+++ b/tests/unit/misc/test_miscwidgets.py
@@ -19,8 +19,8 @@
import logging
-from PyQt5.QtCore import Qt, QSize
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt.core import Qt, QSize
+from qutebrowser.qt.widgets import QWidget
import pytest
from qutebrowser.misc import miscwidgets
@@ -48,9 +48,9 @@ class TestCommandLineEdit:
cmd_edit.home(True)
assert cmd_edit.cursorPosition() == len(':')
- qtbot.keyClick(cmd_edit, Qt.Key_Delete)
+ qtbot.keyClick(cmd_edit, Qt.Key.Key_Delete)
assert cmd_edit.text() == ':'
- qtbot.keyClick(cmd_edit, Qt.Key_Backspace)
+ qtbot.keyClick(cmd_edit, Qt.Key.Key_Backspace)
assert cmd_edit.text() == ':'
qtbot.keyClicks(cmd_edit, 'hey again')
@@ -76,7 +76,7 @@ class TestCommandLineEdit:
assert cmd_edit.text() == ':hello'
assert cmd_edit.cursorPosition() == len(':hello')
for _ in ':hello':
- qtbot.keyClick(cmd_edit, Qt.Key_Left, modifier=Qt.ShiftModifier)
+ qtbot.keyClick(cmd_edit, Qt.Key.Key_Left, modifier=Qt.KeyboardModifier.ShiftModifier)
assert cmd_edit.cursorPosition() == len(':')
assert cmd_edit.selectionStart() == len(':')
@@ -110,6 +110,21 @@ class TestWrapperLayout:
class TestFullscreenNotification:
+ @pytest.fixture
+ def widget_factory(self, qtbot, key_config_stub, blue_widget):
+ # We need to pass a visible parent widget, so that
+ # FullscreenNotification.__init__ can access
+ # self.window().windowHandle() to get the screen.
+ with qtbot.wait_exposed(blue_widget):
+ blue_widget.show()
+
+ def create():
+ w = miscwidgets.FullscreenNotification(blue_widget)
+ qtbot.add_widget(w)
+ return w
+
+ return create
+
@pytest.mark.parametrize('bindings, text', [
({'<escape>': 'fullscreen --leave'},
"Press <Escape> to exit fullscreen."),
@@ -117,18 +132,16 @@ class TestFullscreenNotification:
({'a': 'fullscreen --leave'}, "Press a to exit fullscreen."),
({}, "Page is now fullscreen."),
])
- def test_text(self, qtbot, config_stub, key_config_stub, bindings, text):
+ def test_text(self, widget_factory, config_stub, bindings, text):
config_stub.val.bindings.default = {}
config_stub.val.bindings.commands = {'normal': bindings}
- w = miscwidgets.FullscreenNotification()
- qtbot.add_widget(w)
- assert w.text() == text
+ widget = widget_factory()
+ assert widget.text() == text
- def test_timeout(self, qtbot, key_config_stub):
- w = miscwidgets.FullscreenNotification()
- qtbot.add_widget(w)
- with qtbot.wait_signal(w.destroyed):
- w.set_timeout(1)
+ def test_timeout(self, qtbot, widget_factory):
+ widget = widget_factory()
+ with qtbot.wait_signal(widget.destroyed):
+ widget.set_timeout(1)
@pytest.mark.usefixtures('state_config')
@@ -165,10 +178,10 @@ class TestInspectorSplitter:
@pytest.mark.parametrize(
'position, orientation, inspector_idx, webview_idx', [
- (inspector.Position.left, Qt.Horizontal, 0, 1),
- (inspector.Position.right, Qt.Horizontal, 1, 0),
- (inspector.Position.top, Qt.Vertical, 0, 1),
- (inspector.Position.bottom, Qt.Vertical, 1, 0),
+ (inspector.Position.left, Qt.Orientation.Horizontal, 0, 1),
+ (inspector.Position.right, Qt.Orientation.Horizontal, 1, 0),
+ (inspector.Position.top, Qt.Orientation.Vertical, 0, 1),
+ (inspector.Position.bottom, Qt.Orientation.Vertical, 1, 0),
]
)
def test_set_inspector(self, position, orientation,
@@ -260,7 +273,7 @@ class TestInspectorSplitter:
new_window_size, exp_inspector_size,
position, splitter, fake_inspector, qtbot):
def resize(dim):
- size = (QSize(dim, 666) if splitter.orientation() == Qt.Horizontal
+ size = (QSize(dim, 666) if splitter.orientation() == Qt.Orientation.Horizontal
else QSize(666, dim))
splitter.resize(size)
if splitter.size() != size:
diff --git a/tests/unit/misc/test_msgbox.py b/tests/unit/misc/test_msgbox.py
index c5c23639a..6eee28f32 100644
--- a/tests/unit/misc/test_msgbox.py
+++ b/tests/unit/misc/test_msgbox.py
@@ -20,8 +20,8 @@
import pytest
-from PyQt5.QtCore import Qt
-from PyQt5.QtWidgets import QMessageBox, QWidget
+from qutebrowser.qt.core import Qt
+from qutebrowser.qt.widgets import QMessageBox, QWidget
from qutebrowser.misc import msgbox
from qutebrowser.utils import utils
@@ -38,8 +38,8 @@ def test_attributes(qtbot):
text = 'text'
parent = QWidget()
qtbot.add_widget(parent)
- icon = QMessageBox.Critical
- buttons = QMessageBox.Ok | QMessageBox.Cancel
+ icon = QMessageBox.Icon.Critical
+ buttons = QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel
box = msgbox.msgbox(parent=parent, title=title, text=text, icon=icon,
buttons=buttons)
@@ -53,13 +53,13 @@ def test_attributes(qtbot):
@pytest.mark.parametrize('plain_text, expected', [
- (True, Qt.PlainText),
- (False, Qt.RichText),
- (None, Qt.AutoText),
+ (True, Qt.TextFormat.PlainText),
+ (False, Qt.TextFormat.RichText),
+ (None, Qt.TextFormat.AutoText),
])
def test_plain_text(qtbot, plain_text, expected):
box = msgbox.msgbox(parent=None, title='foo', text='foo',
- icon=QMessageBox.Information, plain_text=plain_text)
+ icon=QMessageBox.Icon.Information, plain_text=plain_text)
qtbot.add_widget(box)
assert box.textFormat() == expected
@@ -73,7 +73,7 @@ def test_finished_signal(qtbot):
signal_triggered = True
box = msgbox.msgbox(parent=None, title='foo', text='foo',
- icon=QMessageBox.Information, on_finished=on_finished)
+ icon=QMessageBox.Icon.Information, on_finished=on_finished)
qtbot.add_widget(box)
@@ -89,7 +89,7 @@ def test_information(qtbot):
if not utils.is_mac:
assert box.windowTitle() == 'foo'
assert box.text() == 'bar'
- assert box.icon() == QMessageBox.Information
+ assert box.icon() == QMessageBox.Icon.Information
def test_no_err_windows(fake_args, caplog):
diff --git a/tests/unit/misc/test_pastebin.py b/tests/unit/misc/test_pastebin.py
index 7a47e723c..906c4c3c6 100644
--- a/tests/unit/misc/test_pastebin.py
+++ b/tests/unit/misc/test_pastebin.py
@@ -19,7 +19,7 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.misc import httpclient, pastebin
diff --git a/tests/unit/misc/test_sessions.py b/tests/unit/misc/test_sessions.py
index ecd04572a..a19f69761 100644
--- a/tests/unit/misc/test_sessions.py
+++ b/tests/unit/misc/test_sessions.py
@@ -23,8 +23,8 @@ import logging
import pytest
import yaml
-from PyQt5.QtCore import QUrl, QPoint, QByteArray, QObject
-QWebView = pytest.importorskip('PyQt5.QtWebKitWidgets').QWebView
+from qutebrowser.qt.core import QUrl, QPoint, QByteArray, QObject
+QWebView = pytest.importorskip('qutebrowser.qt.webkitwidgets').QWebView
from qutebrowser.misc import sessions
from qutebrowser.misc.sessions import TabHistoryItem as Item
diff --git a/tests/unit/misc/test_sql.py b/tests/unit/misc/test_sql.py
index 42207177e..5e33a5a1e 100644
--- a/tests/unit/misc/test_sql.py
+++ b/tests/unit/misc/test_sql.py
@@ -19,11 +19,13 @@
"""Test the SQL API."""
+import sys
+import sqlite3
import pytest
import hypothesis
from hypothesis import strategies
-from PyQt5.QtSql import QSqlDatabase, QSqlError, QSqlQuery
+from qutebrowser.qt.sql import QSqlDatabase, QSqlError, QSqlQuery
from qutebrowser.misc import sql
@@ -91,17 +93,26 @@ def test_sqlerror(klass):
class TestSqlError:
@pytest.mark.parametrize('error_code, exception', [
- (sql.SqliteErrorCode.BUSY, sql.KnownError),
- (sql.SqliteErrorCode.CONSTRAINT, sql.BugError),
+ (sql.SqliteErrorCode.BUSY.value, sql.KnownError),
+ (sql.SqliteErrorCode.CONSTRAINT.value, sql.BugError),
+ # extended error codes
+ (
+ sql.SqliteErrorCode.IOERR.value | (1 << 8), # SQLITE_IOERR_READ
+ sql.KnownError
+ ),
+ (
+ sql.SqliteErrorCode.CONSTRAINT.value | (1 << 8), # SQLITE_CONSTRAINT_CHECK
+ sql.BugError
+ ),
])
def test_known(self, error_code, exception):
- sql_err = QSqlError("driver text", "db text", QSqlError.UnknownError,
- error_code)
+ sql_err = QSqlError("driver text", "db text", QSqlError.ErrorType.UnknownError,
+ str(error_code))
with pytest.raises(exception):
sql.raise_sqlite_error("Message", sql_err)
def test_logging(self, caplog):
- sql_err = QSqlError("driver text", "db text", QSqlError.UnknownError, '23')
+ sql_err = QSqlError("driver text", "db text", QSqlError.ErrorType.UnknownError, '23')
with pytest.raises(sql.BugError):
sql.raise_sqlite_error("Message", sql_err)
@@ -109,7 +120,7 @@ class TestSqlError:
'type: UnknownError',
'database text: db text',
'driver text: driver text',
- 'error code: 23']
+ 'error code: 23 -> SqliteErrorCode.AUTH']
assert caplog.messages == expected
@@ -119,6 +130,62 @@ class TestSqlError:
err = klass("Message", sql_err)
assert err.text() == "db text"
+ @pytest.mark.parametrize("code", list(sql.SqliteErrorCode))
+ @pytest.mark.skipif(
+ sys.version_info < (3, 11),
+ reason="sqlite error code constants added in Python 3.11",
+ )
+ def test_sqlite_error_codes(self, code):
+ """Cross check our error codes with the ones in Python 3.11+.
+
+ See https://github.com/python/cpython/commit/86d8b465231
+ """
+ pyvalue = getattr(sqlite3, f"SQLITE_{code.name}")
+ assert pyvalue == code.value
+
+ def test_sqlite_error_codes_reverse(self):
+ """Check if we have all error codes defined that Python has.
+
+ It would be nice if this was easier (and less guesswork).
+ However, the error codes are simply added as ints to the sqlite3 module
+ namespace (PyModule_AddIntConstant), and lots of other constants are there too.
+ """
+ # Start with all SQLITE_* names in the sqlite3 modules
+ consts = {n for n in dir(sqlite3) if n.startswith("SQLITE_")}
+ # All error codes we know about (tested above)
+ consts -= {f"SQLITE_{m.name}" for m in sql.SqliteErrorCode}
+ # Extended error codes or other constants. From the sqlite docs:
+ #
+ # Primary result code symbolic names are of the form "SQLITE_XXXXXX"
+ # where XXXXXX is a sequence of uppercase alphabetic characters.
+ # Extended result code names are of the form "SQLITE_XXXXXX_YYYYYYY"
+ # where the XXXXXX part is the corresponding primary result code and the
+ # YYYYYYY is an extension that further classifies the result code.
+ consts -= {c for c in consts if c.count("_") >= 2}
+ # All remaining sqlite constants which are *not* error codes.
+ consts -= {
+ "SQLITE_ANALYZE",
+ "SQLITE_ATTACH",
+ "SQLITE_DELETE",
+ "SQLITE_DENY",
+ "SQLITE_DETACH",
+ "SQLITE_FUNCTION",
+ "SQLITE_IGNORE",
+ "SQLITE_INSERT",
+ "SQLITE_PRAGMA",
+ "SQLITE_READ",
+ "SQLITE_RECURSIVE",
+ "SQLITE_REINDEX",
+ "SQLITE_SAVEPOINT",
+ "SQLITE_SELECT",
+ "SQLITE_TRANSACTION",
+ "SQLITE_UPDATE",
+ }
+ # If there is anything remaining here, either a new Python version added a new
+ # sqlite constant which is *not* an error, or there was a new error code added.
+ # Either add it to the set above, or to SqliteErrorCode.
+ assert not consts
+
def test_init_table(database):
database.table('Foo', ['name', 'val', 'lucky'])
diff --git a/tests/unit/misc/test_throttle.py b/tests/unit/misc/test_throttle.py
index 33e9949f2..e9d6267a1 100644
--- a/tests/unit/misc/test_throttle.py
+++ b/tests/unit/misc/test_throttle.py
@@ -21,9 +21,9 @@
from unittest import mock
-import sip
+from qutebrowser.qt import sip
import pytest
-from PyQt5.QtCore import QObject
+from qutebrowser.qt.core import QObject
from helpers import testutils
from qutebrowser.misc import throttle
diff --git a/tests/unit/misc/test_utilcmds.py b/tests/unit/misc/test_utilcmds.py
index 76bc015d2..2f3acc2f8 100644
--- a/tests/unit/misc/test_utilcmds.py
+++ b/tests/unit/misc/test_utilcmds.py
@@ -20,7 +20,7 @@
"""Tests for qutebrowser.misc.utilcmds."""
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.misc import utilcmds
from qutebrowser.api import cmdutils
diff --git a/tests/unit/misc/userscripts/test_qute_lastpass.py b/tests/unit/misc/userscripts/test_qute_lastpass.py
index ebd9a7591..aca3bb224 100644
--- a/tests/unit/misc/userscripts/test_qute_lastpass.py
+++ b/tests/unit/misc/userscripts/test_qute_lastpass.py
@@ -203,7 +203,7 @@ class TestQuteLastPassMain:
exit_code = qute_lastpass.main(arguments_mock)
assert exit_code == qute_lastpass.ExitCodes.FAILURE
- # pylint: disable=line-too-long
+ # FIXME:qt6 (lint): disable=line-too-long
stderr_mock.assert_called_with(
"LastPass CLI returned for www.example.com - Error: Could not find decryption key. Perhaps you need to login with `lpass login`.")
qutecommand_mock.assert_not_called()
diff --git a/tests/unit/test_app.py b/tests/unit/test_app.py
index e359f2136..a66f8451b 100644
--- a/tests/unit/test_app.py
+++ b/tests/unit/test_app.py
@@ -19,7 +19,7 @@
"""Tests for the qutebrowser.app module."""
-from PyQt5.QtCore import QBuffer
+from qutebrowser.qt.core import QBuffer
from qutebrowser.misc import objects
from qutebrowser import app
diff --git a/tests/unit/utils/test_debug.py b/tests/unit/utils/test_debug.py
index 62d0f4a7b..6d7135ecd 100644
--- a/tests/unit/utils/test_debug.py
+++ b/tests/unit/utils/test_debug.py
@@ -25,10 +25,10 @@ import time
import textwrap
import pytest
-from PyQt5.QtCore import pyqtSignal, Qt, QEvent, QObject, QTimer
-from PyQt5.QtWidgets import QStyle, QFrame, QSpinBox
+from qutebrowser.qt.core import pyqtSignal, Qt, QEvent, QObject, QTimer
+from qutebrowser.qt.widgets import QStyle, QFrame, QSpinBox
-from qutebrowser.utils import debug
+from qutebrowser.utils import debug, qtutils
from qutebrowser.misc import objects
@@ -40,7 +40,7 @@ class EventObject(QObject):
def test_log_events(qapp, caplog):
obj = EventObject()
- qapp.sendEvent(obj, QEvent(QEvent.User))
+ qapp.sendEvent(obj, QEvent(QEvent.Type.User))
qapp.processEvents()
assert caplog.messages == ['Event in test_debug.EventObject: User']
@@ -133,20 +133,22 @@ class TestQEnumKey:
assert hasattr(QFrame, 'staticMetaObject')
@pytest.mark.parametrize('base, value, klass, expected', [
- (QStyle, QStyle.PE_PanelButtonCommand, None, 'PE_PanelButtonCommand'),
- (QFrame, QFrame.Sunken, None, 'Sunken'),
+ (QStyle, QStyle.PrimitiveElement.PE_PanelButtonCommand, None, 'PE_PanelButtonCommand'),
+ (QFrame, QFrame.Shadow.Sunken, None, 'Sunken'),
(QFrame, 0x0030, QFrame.Shadow, 'Sunken'),
(QFrame, 0x1337, QFrame.Shadow, '0x1337'),
- (Qt, Qt.AnchorLeft, None, 'AnchorLeft'),
+ (Qt, Qt.AnchorPoint.AnchorLeft, None, 'AnchorLeft'),
+
+ # No static meta object, passing in an int on Qt 6
+ (QEvent, qtutils.extract_enum_val(QEvent.Type.User), QEvent.Type, 'User'),
+
+ # Unknown value with IntFlags
+ (Qt, Qt.AlignmentFlag(1024), None, '0x0400'),
])
def test_qenum_key(self, base, value, klass, expected):
key = debug.qenum_key(base, value, klass=klass)
assert key == expected
- def test_add_base(self):
- key = debug.qenum_key(QFrame, QFrame.Sunken, add_base=True)
- assert key == 'QFrame.Sunken'
-
def test_int_noklass(self):
"""Test passing an int without explicit klass given."""
with pytest.raises(TypeError):
@@ -160,18 +162,20 @@ class TestQFlagsKey:
https://github.com/qutebrowser/qutebrowser/issues/42
"""
- fixme = pytest.mark.xfail(reason="See issue #42", raises=AssertionError)
-
@pytest.mark.parametrize('base, value, klass, expected', [
- (Qt, Qt.AlignTop, None, 'AlignTop'),
- pytest.param(Qt, Qt.AlignLeft | Qt.AlignTop, None,
- 'AlignLeft|AlignTop', marks=fixme),
- (Qt, Qt.AlignCenter, None, 'AlignHCenter|AlignVCenter'),
- pytest.param(Qt, 0x0021, Qt.Alignment, 'AlignLeft|AlignTop',
- marks=fixme),
- (Qt, 0x1100, Qt.Alignment, '0x0100|0x1000'),
- (Qt, Qt.DockWidgetAreas(0), Qt.DockWidgetArea, 'NoDockWidgetArea'),
- (Qt, Qt.DockWidgetAreas(0), None, '0x0000'),
+ (Qt, Qt.AlignmentFlag.AlignTop, None, 'AlignTop'),
+ pytest.param(Qt, Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop, None,
+ 'AlignLeft|AlignTop', marks=pytest.mark.qt5_xfail(raises=AssertionError)),
+ (Qt, Qt.AlignmentFlag.AlignCenter, None, 'AlignHCenter|AlignVCenter'),
+ pytest.param(Qt, 0x0021, Qt.AlignmentFlag, 'AlignLeft|AlignTop',
+ marks=pytest.mark.qt5_xfail(raises=AssertionError)),
+ (Qt, 0x1100, Qt.AlignmentFlag, 'AlignBaseline|0x1000'),
+ (Qt, Qt.DockWidgetArea(0), Qt.DockWidgetArea, 'NoDockWidgetArea'),
+ (Qt, Qt.DockWidgetArea(0), None, 'NoDockWidgetArea'),
+ (Qt, Qt.KeyboardModifier.ShiftModifier, Qt.KeyboardModifier, 'ShiftModifier'),
+ (Qt, Qt.KeyboardModifier.ShiftModifier, None, 'ShiftModifier'),
+ (Qt, Qt.KeyboardModifier.ShiftModifier | Qt.KeyboardModifier.ControlModifier, Qt.KeyboardModifier, 'ShiftModifier|ControlModifier'),
+ pytest.param(Qt, Qt.KeyboardModifier.ShiftModifier | Qt.KeyboardModifier.ControlModifier, None, 'ShiftModifier|ControlModifier', marks=pytest.mark.qt5_xfail(raises=AssertionError)),
])
def test_qflags_key(self, base, value, klass, expected):
flags = debug.qflags_key(base, value, klass=klass)
@@ -186,7 +190,7 @@ class TestQFlagsKey:
No idea what's happening here exactly...
"""
- qwebpage = pytest.importorskip("PyQt5.QtWebKitWidgets").QWebPage
+ qwebpage = pytest.importorskip("qutebrowser.qt.webkitwidgets").QWebPage
flags = qwebpage.FindWrapsAroundDocument
flags |= qwebpage.FindBackward
@@ -197,11 +201,6 @@ class TestQFlagsKey:
flags,
klass=qwebpage.FindFlag)
- def test_add_base(self):
- """Test with add_base=True."""
- flags = debug.qflags_key(Qt, Qt.AlignTop, add_base=True)
- assert flags == 'Qt.AlignTop'
-
def test_int_noklass(self):
"""Test passing an int without explicit klass given."""
with pytest.raises(TypeError):
@@ -297,6 +296,6 @@ class TestGetAllObjects:
def test_get_all_objects_qapp(self, qapp, monkeypatch):
monkeypatch.setattr(objects, 'qapp', qapp)
objs = debug.get_all_objects()
- event_dispatcher = '<PyQt5.QtCore.QAbstractEventDispatcher object at'
- session_manager = '<PyQt5.QtGui.QSessionManager object at'
+ event_dispatcher = 'QtCore.QAbstractEventDispatcher object at'
+ session_manager = 'QtGui.QSessionManager object at'
assert event_dispatcher in objs or session_manager in objs
diff --git a/tests/unit/utils/test_error.py b/tests/unit/utils/test_error.py
index b59a7150b..576a048de 100644
--- a/tests/unit/utils/test_error.py
+++ b/tests/unit/utils/test_error.py
@@ -21,8 +21,8 @@
import logging
import pytest
-from PyQt5.QtCore import QTimer
-from PyQt5.QtWidgets import QMessageBox
+from qutebrowser.qt.core import QTimer
+from qutebrowser.qt.widgets import QMessageBox
from qutebrowser.utils import error, utils
from qutebrowser.misc import ipc
@@ -82,8 +82,8 @@ def test_err_windows(qtbot, qapp, pre_text, post_text, expected, caplog):
qtbot.add_widget(w)
if not utils.is_mac:
assert w.windowTitle() == 'title'
- assert w.icon() == QMessageBox.Critical
- assert w.standardButtons() == QMessageBox.Ok
+ assert w.icon() == QMessageBox.Icon.Critical
+ assert w.standardButtons() == QMessageBox.StandardButton.Ok
assert w.text() == expected
finally:
w.close()
diff --git a/tests/unit/utils/test_jinja.py b/tests/unit/utils/test_jinja.py
index 85be8a6e3..28ff09525 100644
--- a/tests/unit/utils/test_jinja.py
+++ b/tests/unit/utils/test_jinja.py
@@ -24,7 +24,7 @@ import logging
import jinja2.exceptions
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.utils import jinja
from qutebrowser.config import configexc
diff --git a/tests/unit/utils/test_log.py b/tests/unit/utils/test_log.py
index bbc6b02db..921d354d1 100644
--- a/tests/unit/utils/test_log.py
+++ b/tests/unit/utils/test_log.py
@@ -28,7 +28,7 @@ import dataclasses
import pytest
import _pytest.logging # pylint: disable=import-private-name
-from PyQt5 import QtCore
+from qutebrowser.qt import core as qtcore
from qutebrowser import qutebrowser
from qutebrowser.utils import log
@@ -243,7 +243,7 @@ class TestInitLog:
@pytest.fixture(autouse=True)
def setup(self, mocker):
- mocker.patch('qutebrowser.utils.log.QtCore.qInstallMessageHandler',
+ mocker.patch('qutebrowser.utils.log.qtcore.qInstallMessageHandler',
autospec=True)
yield
# Make sure logging is in a sensible default state
@@ -429,5 +429,5 @@ class TestQtMessageHandler:
def test_empty_message(self, caplog):
"""Make sure there's no crash with an empty message."""
- log.qt_message_handler(QtCore.QtDebugMsg, self.Context(), "")
+ log.qt_message_handler(qtcore.QtMsgType.QtDebugMsg, self.Context(), "")
assert caplog.messages == ["Logged empty message!"]
diff --git a/tests/unit/utils/test_qtutils.py b/tests/unit/utils/test_qtutils.py
index ad9adf032..6ae495826 100644
--- a/tests/unit/utils/test_qtutils.py
+++ b/tests/unit/utils/test_qtutils.py
@@ -28,9 +28,9 @@ import unittest
import unittest.mock
import pytest
-from PyQt5.QtCore import (QDataStream, QPoint, QUrl, QByteArray, QIODevice,
- QTimer, QBuffer, QFile, QProcess, QFileDevice)
-from PyQt5.QtGui import QColor
+from qutebrowser.qt.core import (QDataStream, QPoint, QUrl, QByteArray, QIODevice,
+ QTimer, QBuffer, QFile, QProcess, QFileDevice, QLibraryInfo, Qt)
+from qutebrowser.qt.gui import QColor
from qutebrowser.utils import qtutils, utils, usertypes
import overflow_test_cases
@@ -205,13 +205,13 @@ def test_ensure_valid(obj, raising, exc_reason, exc_str):
@pytest.mark.parametrize('status, raising, message', [
- (QDataStream.Ok, False, None),
- (QDataStream.ReadPastEnd, True, "The data stream has read past the end of "
- "the data in the underlying device."),
- (QDataStream.ReadCorruptData, True, "The data stream has read corrupt "
- "data."),
- (QDataStream.WriteFailed, True, "The data stream cannot write to the "
- "underlying device."),
+ (QDataStream.Status.Ok, False, None),
+ (QDataStream.Status.ReadPastEnd, True,
+ "The data stream has read past the end of the data in the underlying device."),
+ (QDataStream.Status.ReadCorruptData, True,
+ "The data stream has read corrupt data."),
+ (QDataStream.Status.WriteFailed, True,
+ "The data stream cannot write to the underlying device."),
])
def test_check_qdatastream(status, raising, message):
"""Test check_qdatastream.
@@ -232,8 +232,7 @@ def test_check_qdatastream(status, raising, message):
def test_qdatastream_status_count():
"""Make sure no new members are added to QDataStream.Status."""
- values = vars(QDataStream).values()
- status_vals = [e for e in values if isinstance(e, QDataStream.Status)]
+ status_vals = testutils.enum_members(QDataStream, QDataStream.Status)
assert len(status_vals) == 4
@@ -278,12 +277,12 @@ class TestSerializeStream:
def stream_mock(self):
"""Fixture providing a QDataStream-like mock."""
m = unittest.mock.MagicMock(spec=QDataStream)
- m.status.return_value = QDataStream.Ok
+ m.status.return_value = QDataStream.Status.Ok
return m
def test_serialize_pre_error_mock(self, stream_mock):
"""Test serialize_stream with an error already set."""
- stream_mock.status.return_value = QDataStream.ReadCorruptData
+ stream_mock.status.return_value = QDataStream.Status.ReadCorruptData
with pytest.raises(OSError, match="The data stream has read corrupt "
"data."):
@@ -295,7 +294,7 @@ class TestSerializeStream:
"""Test serialize_stream with an error while serializing."""
obj = QPoint()
stream_mock.__lshift__.side_effect = lambda _other: self._set_status(
- stream_mock, QDataStream.ReadCorruptData)
+ stream_mock, QDataStream.Status.ReadCorruptData)
with pytest.raises(OSError, match="The data stream has read corrupt "
"data."):
@@ -305,7 +304,7 @@ class TestSerializeStream:
def test_deserialize_pre_error_mock(self, stream_mock):
"""Test deserialize_stream with an error already set."""
- stream_mock.status.return_value = QDataStream.ReadCorruptData
+ stream_mock.status.return_value = QDataStream.Status.ReadCorruptData
with pytest.raises(OSError, match="The data stream has read corrupt "
"data."):
@@ -317,7 +316,7 @@ class TestSerializeStream:
"""Test deserialize_stream with an error while deserializing."""
obj = QPoint()
stream_mock.__rshift__.side_effect = lambda _other: self._set_status(
- stream_mock, QDataStream.ReadCorruptData)
+ stream_mock, QDataStream.Status.ReadCorruptData)
with pytest.raises(OSError, match="The data stream has read corrupt "
"data."):
@@ -331,10 +330,10 @@ class TestSerializeStream:
dest_obj = QPoint()
data = QByteArray()
- write_stream = QDataStream(data, QIODevice.WriteOnly)
+ write_stream = QDataStream(data, QIODevice.OpenModeFlag.WriteOnly)
qtutils.serialize_stream(write_stream, src_obj)
- read_stream = QDataStream(data, QIODevice.ReadOnly)
+ read_stream = QDataStream(data, QIODevice.OpenModeFlag.ReadOnly)
qtutils.deserialize_stream(read_stream, dest_obj)
assert src_obj == dest_obj
@@ -343,7 +342,7 @@ class TestSerializeStream:
def test_serialize_readonly_stream(self):
"""Test serialize_stream with a read-only stream."""
data = QByteArray()
- stream = QDataStream(data, QIODevice.ReadOnly)
+ stream = QDataStream(data, QIODevice.OpenModeFlag.ReadOnly)
with pytest.raises(OSError, match="The data stream cannot write to "
"the underlying device."):
qtutils.serialize_stream(stream, QPoint())
@@ -353,7 +352,7 @@ class TestSerializeStream:
"""Test deserialize_stream with a write-only stream."""
data = QByteArray()
obj = QPoint()
- stream = QDataStream(data, QIODevice.WriteOnly)
+ stream = QDataStream(data, QIODevice.OpenModeFlag.WriteOnly)
with pytest.raises(OSError, match="The data stream has read past the "
"end of the data in the underlying device."):
qtutils.deserialize_stream(stream, obj)
@@ -388,7 +387,7 @@ class TestSavefileOpen:
with qtutils.savefile_open('filename'):
pass
- qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly)
+ qsavefile_mock.open.assert_called_once_with(QIODevice.OpenModeFlag.WriteOnly)
qsavefile_mock.cancelWriting.assert_called_once_with()
def test_mock_exception(self, qsavefile_mock):
@@ -399,7 +398,7 @@ class TestSavefileOpen:
with qtutils.savefile_open('filename'):
raise SavefileTestException
- qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly)
+ qsavefile_mock.open.assert_called_once_with(QIODevice.OpenModeFlag.WriteOnly)
qsavefile_mock.cancelWriting.assert_called_once_with()
def test_mock_commit_failed(self, qsavefile_mock):
@@ -411,7 +410,7 @@ class TestSavefileOpen:
with qtutils.savefile_open('filename'):
pass
- qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly)
+ qsavefile_mock.open.assert_called_once_with(QIODevice.OpenModeFlag.WriteOnly)
assert not qsavefile_mock.cancelWriting.called
assert not qsavefile_mock.errorString.called
@@ -426,7 +425,7 @@ class TestSavefileOpen:
with qtutils.savefile_open('filename') as f:
f.write("Hello World")
- qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly)
+ qsavefile_mock.open.assert_called_once_with(QIODevice.OpenModeFlag.WriteOnly)
assert not qsavefile_mock.cancelWriting.called
qsavefile_mock.write.assert_called_once_with(b"Hello World")
@@ -539,10 +538,10 @@ if test_file is not None:
def open(self, _fname, mode):
"""Open an in-memory PyQIODevice instead of a real file."""
modes = {
- 'wb': QIODevice.WriteOnly | QIODevice.Truncate,
- 'w': QIODevice.WriteOnly | QIODevice.Text | QIODevice.Truncate,
- 'rb': QIODevice.ReadOnly,
- 'r': QIODevice.ReadOnly | QIODevice.Text,
+ 'wb': QIODevice.OpenModeFlag.WriteOnly | QIODevice.OpenModeFlag.Truncate,
+ 'w': QIODevice.OpenModeFlag.WriteOnly | QIODevice.OpenModeFlag.Text | QIODevice.OpenModeFlag.Truncate,
+ 'rb': QIODevice.OpenModeFlag.ReadOnly,
+ 'r': QIODevice.OpenModeFlag.ReadOnly | QIODevice.OpenModeFlag.Text,
}
try:
qt_mode = modes[mode]
@@ -656,14 +655,14 @@ class TestPyQIODevice:
Args:
method: The name of the method to call.
"""
- pyqiodev.open(QIODevice.WriteOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.WriteOnly)
func = getattr(pyqiodev, method)
with pytest.raises(OSError, match="Trying to read unreadable file!"):
func()
def test_unwritable(self, pyqiodev):
"""Test writing with a read-only device."""
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.ReadOnly)
with pytest.raises(OSError, match="Trying to write to unwritable "
"file!"):
pyqiodev.write(b'')
@@ -676,7 +675,7 @@ class TestPyQIODevice:
data: The data to write before checking if the length equals
len(data).
"""
- pyqiodev.open(QIODevice.WriteOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.WriteOnly)
pyqiodev.write(data)
assert len(pyqiodev) == len(data)
@@ -685,8 +684,8 @@ class TestPyQIODevice:
qf = QFile(str(tmp_path))
dev = qtutils.PyQIODevice(qf)
with pytest.raises(qtutils.QtOSError) as excinfo:
- dev.open(QIODevice.WriteOnly)
- assert excinfo.value.qt_errno == QFileDevice.OpenError
+ dev.open(QIODevice.OpenModeFlag.WriteOnly)
+ assert excinfo.value.qt_errno == QFileDevice.FileError.OpenError
assert dev.closed
def test_fileno(self, pyqiodev):
@@ -715,9 +714,9 @@ class TestPyQIODevice:
data: The expected data to read after seeking.
raising: Whether seeking should raise OSError.
"""
- with pyqiodev.open(QIODevice.WriteOnly) as f:
+ with pyqiodev.open(QIODevice.OpenModeFlag.WriteOnly) as f:
f.write(b'1234567890')
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.ReadOnly)
if raising:
with pytest.raises(OSError, match="seek failed!"):
pyqiodev.seek(offset, whence)
@@ -736,7 +735,7 @@ class TestPyQIODevice:
# pylint: enable=no-member,useless-suppression
else:
pytest.skip("Needs os.SEEK_HOLE or os.SEEK_DATA available.")
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.ReadOnly)
with pytest.raises(io.UnsupportedOperation):
pyqiodev.seek(0, whence)
@@ -765,7 +764,7 @@ class TestPyQIODevice:
def test_closed(self, pyqiodev):
"""Test the closed attribute."""
assert pyqiodev.closed
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.ReadOnly)
assert not pyqiodev.closed
pyqiodev.close()
assert pyqiodev.closed
@@ -773,14 +772,14 @@ class TestPyQIODevice:
def test_contextmanager(self, pyqiodev):
"""Make sure using the PyQIODevice as context manager works."""
assert pyqiodev.closed
- with pyqiodev.open(QIODevice.ReadOnly) as f:
+ with pyqiodev.open(QIODevice.OpenModeFlag.ReadOnly) as f:
assert not f.closed
assert f is pyqiodev
assert pyqiodev.closed
def test_flush(self, pyqiodev):
"""Make sure flushing doesn't raise an exception."""
- pyqiodev.open(QIODevice.WriteOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.WriteOnly)
pyqiodev.write(b'test')
pyqiodev.flush()
@@ -795,14 +794,14 @@ class TestPyQIODevice:
method: The name of the method to call.
ret: The return value we expect.
"""
- pyqiodev.open(QIODevice.WriteOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.WriteOnly)
func = getattr(pyqiodev, method)
assert func() == ret
@pytest.mark.parametrize('mode, readable, writable', [
- (QIODevice.ReadOnly, True, False),
- (QIODevice.ReadWrite, True, True),
- (QIODevice.WriteOnly, False, True),
+ (QIODevice.OpenModeFlag.ReadOnly, True, False),
+ (QIODevice.OpenModeFlag.ReadWrite, True, True),
+ (QIODevice.OpenModeFlag.WriteOnly, False, True),
])
def test_readable_writable(self, mode, readable, writable, pyqiodev):
"""Test readable() and writable().
@@ -831,19 +830,19 @@ class TestPyQIODevice:
size: The size to pass to readline()
chunks: A list of expected chunks to read.
"""
- with pyqiodev.open(QIODevice.WriteOnly) as f:
+ with pyqiodev.open(QIODevice.OpenModeFlag.WriteOnly) as f:
f.write(b'one\ntwo\nthree')
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.ReadOnly)
for i, chunk in enumerate(chunks, start=1):
print("Expecting chunk {}: {!r}".format(i, chunk))
assert pyqiodev.readline(size) == chunk
def test_write(self, pyqiodev):
"""Make sure writing and re-reading works."""
- with pyqiodev.open(QIODevice.WriteOnly) as f:
+ with pyqiodev.open(QIODevice.OpenModeFlag.WriteOnly) as f:
f.write(b'foo\n')
f.write(b'bar\n')
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.ReadOnly)
assert pyqiodev.read() == b'foo\nbar\n'
def test_write_error(self, pyqiodev_failing):
@@ -857,7 +856,7 @@ class TestPyQIODevice:
def test_write_error_real(self):
"""Test a real write error with /dev/full on supported systems."""
qf = QFile('/dev/full')
- qf.open(QIODevice.WriteOnly | QIODevice.Unbuffered)
+ qf.open(QIODevice.OpenModeFlag.WriteOnly | QIODevice.OpenModeFlag.Unbuffered)
dev = qtutils.PyQIODevice(qf)
with pytest.raises(OSError, match='No space left on device'):
dev.write(b'foo')
@@ -876,9 +875,9 @@ class TestPyQIODevice:
size: The size to pass to read()
chunks: A list of expected data chunks.
"""
- with pyqiodev.open(QIODevice.WriteOnly) as f:
+ with pyqiodev.open(QIODevice.OpenModeFlag.WriteOnly) as f:
f.write(b'1234567890')
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QIODevice.OpenModeFlag.ReadOnly)
for i, chunk in enumerate(chunks):
print("Expecting chunk {}: {!r}".format(i, chunk))
assert pyqiodev.read(size) == chunk
@@ -972,9 +971,9 @@ class TestInterpolateColor:
def test_invalid_colorspace(self, colors):
"""Test an invalid colorspace."""
with pytest.raises(ValueError):
- qtutils.interpolate_color(colors.white, colors.black, 10, QColor.Cmyk)
+ qtutils.interpolate_color(colors.white, colors.black, 10, QColor.Spec.Cmyk)
- @pytest.mark.parametrize('colorspace', [QColor.Rgb, QColor.Hsv, QColor.Hsl])
+ @pytest.mark.parametrize('colorspace', [QColor.Spec.Rgb, QColor.Spec.Hsv, QColor.Spec.Hsl])
def test_0_100(self, colors, colorspace):
"""Test 0% and 100% in different colorspaces."""
white = qtutils.interpolate_color(colors.white, colors.black, 0, colorspace)
@@ -985,7 +984,7 @@ class TestInterpolateColor:
def test_interpolation_rgb(self):
"""Test an interpolation in the RGB colorspace."""
color = qtutils.interpolate_color(
- testutils.Color(0, 40, 100), testutils.Color(0, 20, 200), 50, QColor.Rgb)
+ testutils.Color(0, 40, 100), testutils.Color(0, 20, 200), 50, QColor.Spec.Rgb)
assert testutils.Color(color) == testutils.Color(0, 30, 150)
def test_interpolation_hsv(self):
@@ -994,7 +993,7 @@ class TestInterpolateColor:
stop = testutils.Color()
start.setHsv(0, 40, 100)
stop.setHsv(0, 20, 200)
- color = qtutils.interpolate_color(start, stop, 50, QColor.Hsv)
+ color = qtutils.interpolate_color(start, stop, 50, QColor.Spec.Hsv)
expected = testutils.Color()
expected.setHsv(0, 30, 150)
assert testutils.Color(color) == expected
@@ -1005,12 +1004,12 @@ class TestInterpolateColor:
stop = testutils.Color()
start.setHsl(0, 40, 100)
stop.setHsl(0, 20, 200)
- color = qtutils.interpolate_color(start, stop, 50, QColor.Hsl)
+ color = qtutils.interpolate_color(start, stop, 50, QColor.Spec.Hsl)
expected = testutils.Color()
expected.setHsl(0, 30, 150)
assert testutils.Color(color) == expected
- @pytest.mark.parametrize('colorspace', [QColor.Rgb, QColor.Hsv, QColor.Hsl])
+ @pytest.mark.parametrize('colorspace', [QColor.Spec.Rgb, QColor.Spec.Hsv, QColor.Spec.Hsl])
def test_interpolation_alpha(self, colorspace):
"""Test interpolation of colorspace's alpha."""
start = testutils.Color(0, 0, 0, 30)
@@ -1030,3 +1029,41 @@ class TestInterpolateColor:
testutils.Color(0, 0, 0), testutils.Color(255, 255, 255), percentage, None)
assert isinstance(color, QColor)
assert testutils.Color(color) == testutils.Color(*expected)
+
+
+class TestLibraryPath:
+
+ def test_simple(self):
+ try:
+ # Qt 6
+ path = QLibraryInfo.path(QLibraryInfo.LibraryPath.DataPath)
+ except AttributeError:
+ # Qt 5
+ path = QLibraryInfo.location(QLibraryInfo.LibraryLocation.DataPath)
+
+ assert path
+ assert qtutils.library_path(qtutils.LibraryPath.data).as_posix() == path
+
+ @pytest.mark.parametrize("which", list(qtutils.LibraryPath))
+ def test_all(self, which):
+ if utils.is_windows and which == qtutils.LibraryPath.settings:
+ pytest.skip("Settings path not supported on Windows")
+ qtutils.library_path(which)
+ # The returned path doesn't necessarily exist.
+
+ def test_values_match_qt(self):
+ try:
+ # Qt 6
+ enumtype = QLibraryInfo.LibraryPath
+ except AttributeError:
+ enumtype = QLibraryInfo.LibraryLocation
+
+ our_names = {member.value for member in qtutils.LibraryPath}
+ qt_names = set(testutils.enum_members(QLibraryInfo, enumtype))
+ qt_names.discard("ImportsPath") # Moved to QmlImportsPath in Qt 6
+ assert qt_names == our_names
+
+
+def test_extract_enum_val():
+ value = qtutils.extract_enum_val(Qt.KeyboardModifier.ShiftModifier)
+ assert value == 0x02000000
diff --git a/tests/unit/utils/test_standarddir.py b/tests/unit/utils/test_standarddir.py
index dcb863d1d..ef1da5a07 100644
--- a/tests/unit/utils/test_standarddir.py
+++ b/tests/unit/utils/test_standarddir.py
@@ -28,10 +28,10 @@ import textwrap
import logging
import subprocess
-from PyQt5.QtCore import QStandardPaths
+from qutebrowser.qt.core import QStandardPaths
import pytest
-from qutebrowser.utils import standarddir, utils, qtutils, version
+from qutebrowser.utils import standarddir, utils, version
# Use a different application name for tests to make sure we don't change real
@@ -114,8 +114,8 @@ def test_fake_windows(tmpdir, monkeypatch, what):
def test_fake_haiku(tmpdir, monkeypatch):
"""Test getting data dir on HaikuOS."""
locations = {
- QStandardPaths.AppDataLocation: '',
- QStandardPaths.ConfigLocation: str(tmpdir / 'config' / APPNAME),
+ QStandardPaths.StandardLocation.AppDataLocation: '',
+ QStandardPaths.StandardLocation.ConfigLocation: str(tmpdir / 'config' / APPNAME),
}
monkeypatch.setattr(standarddir.QStandardPaths, 'writableLocation',
locations.get)
@@ -135,14 +135,14 @@ class TestWritableLocation:
'qutebrowser.utils.standarddir.QStandardPaths.writableLocation',
lambda typ: '')
with pytest.raises(standarddir.EmptyValueError):
- standarddir._writable_location(QStandardPaths.AppDataLocation)
+ standarddir._writable_location(QStandardPaths.StandardLocation.AppDataLocation)
def test_sep(self, monkeypatch):
"""Make sure the right kind of separator is used."""
monkeypatch.setattr(standarddir.os, 'sep', '\\')
monkeypatch.setattr(standarddir.os.path, 'join',
lambda *parts: '\\'.join(parts))
- loc = standarddir._writable_location(QStandardPaths.AppDataLocation)
+ loc = standarddir._writable_location(QStandardPaths.StandardLocation.AppDataLocation)
assert '/' not in loc
assert '\\' in loc
@@ -193,21 +193,6 @@ class TestStandardDir:
assert func() == str(tmp_path.joinpath(*subdirs))
@pytest.mark.linux
- @pytest.mark.qt_log_ignore(r'^QStandardPaths: ')
- @pytest.mark.skipif(
- qtutils.version_check('5.14', compiled=False),
- reason="Qt 5.14 automatically creates missing runtime dirs")
- def test_linux_invalid_runtimedir(self, monkeypatch, tmpdir):
- """With invalid XDG_RUNTIME_DIR, fall back to TempLocation."""
- tmpdir_env = tmpdir / 'temp'
- tmpdir_env.ensure(dir=True)
- monkeypatch.setenv('XDG_RUNTIME_DIR', str(tmpdir / 'does-not-exist'))
- monkeypatch.setenv('TMPDIR', str(tmpdir_env))
-
- standarddir._init_runtime(args=None)
- assert standarddir.runtime() == str(tmpdir_env / APPNAME)
-
- @pytest.mark.linux
@pytest.mark.parametrize('args_basedir', [True, False])
def test_flatpak_runtimedir(self, fake_flatpak, monkeypatch, tmp_path,
args_basedir):
@@ -471,7 +456,7 @@ def test_no_qapplication(qapp, tmpdir, monkeypatch):
sys.path = sys.argv[1:] # make sure we have the same python path
- from PyQt5.QtWidgets import QApplication
+ from qutebrowser.qt.widgets import QApplication
from qutebrowser.utils import standarddir
assert QApplication.instance() is None
diff --git a/tests/unit/utils/test_urlmatch.py b/tests/unit/utils/test_urlmatch.py
index caf52c76d..c1b9e11be 100644
--- a/tests/unit/utils/test_urlmatch.py
+++ b/tests/unit/utils/test_urlmatch.py
@@ -33,11 +33,11 @@ import string
import pytest
import hypothesis
import hypothesis.strategies as hst
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt.core import QUrl
from qutebrowser.utils import urlmatch
-# pylint: disable=line-too-long
+# FIXME:qt6 (lint): disable=line-too-long
@pytest.mark.parametrize('pattern, error', [
diff --git a/tests/unit/utils/test_urlutils.py b/tests/unit/utils/test_urlutils.py
index e5773e25e..a94ecef6a 100644
--- a/tests/unit/utils/test_urlutils.py
+++ b/tests/unit/utils/test_urlutils.py
@@ -24,15 +24,15 @@ import logging
import dataclasses
import urllib.parse
-from PyQt5.QtCore import QUrl
-from PyQt5.QtNetwork import QNetworkProxy
+from qutebrowser.qt.core import QUrl
+from qutebrowser.qt.network import QNetworkProxy
import pytest
import hypothesis
import hypothesis.strategies
from qutebrowser.api import cmdutils
from qutebrowser.browser.network import pac
-from qutebrowser.utils import utils, urlutils, usertypes
+from qutebrowser.utils import utils, urlutils, usertypes, qtutils
class FakeDNS:
@@ -321,7 +321,7 @@ def test_get_search_url_for_path_search(config_stub, url, host, path, open_base_
config_stub.val.url.open_base_url = open_base_url
url = urlutils._get_search_url(url)
assert url.host() == host
- assert url.path(options=QUrl.PrettyDecoded) == '/' + path
+ assert url.path(options=QUrl.ComponentFormattingOption.PrettyDecoded) == '/' + path
@pytest.mark.parametrize('url, host', [
@@ -638,6 +638,7 @@ class TestInvalidUrlError:
(False, 'http://example.org', 'https://example.org'), # different scheme
(False, 'http://example.org:80', 'http://example.org:8080'), # different port
])
+@pytest.mark.qt5_only # https://bugreports.qt.io/browse/QTBUG-80308
def test_same_domain(are_same, url1, url2):
"""Test same_domain."""
assert urlutils.same_domain(QUrl(url1), QUrl(url2)) == are_same
@@ -674,6 +675,18 @@ def test_data_url():
assert url == QUrl('data:text/plain;base64,Zm9v')
+qurl_idna2003 = pytest.mark.skipif(
+ qtutils.version_check("6.3.0", compiled=False),
+ reason="Different result with Qt >= 6.3.0: "
+ "https://bugreports.qt.io/browse/QTBUG-85371"
+)
+qurl_uts46 = pytest.mark.xfail(
+ not qtutils.version_check("6.3.0", compiled=False),
+ reason="Different result with Qt < 6.3.0: "
+ "https://bugreports.qt.io/browse/QTBUG-85371"
+)
+
+
@pytest.mark.parametrize('url, expected', [
# No IDN
(QUrl('http://www.example.com'), 'http://www.example.com'),
@@ -687,8 +700,16 @@ def test_data_url():
(QUrl('http://www.example.xn--p1ai'),
'(www.example.xn--p1ai) http://www.example.рф'),
# https://bugreports.qt.io/browse/QTBUG-60364
- (QUrl('http://www.xn--80ak6aa92e.com'),
- 'http://www.xn--80ak6aa92e.com'),
+ pytest.param(
+ QUrl('http://www.xn--80ak6aa92e.com'),
+ 'http://www.xn--80ak6aa92e.com',
+ marks=qurl_idna2003,
+ ),
+ pytest.param(
+ QUrl('http://www.xn--80ak6aa92e.com'),
+ '(www.xn--80ak6aa92e.com) http://www.аррӏе.com',
+ marks=qurl_uts46,
+ ),
])
def test_safe_display_string(url, expected):
assert urlutils.safe_display_string(url) == expected
@@ -703,20 +724,20 @@ class TestProxyFromUrl:
@pytest.mark.parametrize('url, expected', [
('socks://example.com/',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com')),
+ QNetworkProxy(QNetworkProxy.ProxyType.Socks5Proxy, 'example.com')),
('socks5://example.com',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com')),
+ QNetworkProxy(QNetworkProxy.ProxyType.Socks5Proxy, 'example.com')),
('socks5://example.com:2342',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com', 2342)),
+ QNetworkProxy(QNetworkProxy.ProxyType.Socks5Proxy, 'example.com', 2342)),
('socks5://foo@example.com',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com', 0, 'foo')),
+ QNetworkProxy(QNetworkProxy.ProxyType.Socks5Proxy, 'example.com', 0, 'foo')),
('socks5://foo:bar@example.com',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com', 0, 'foo',
+ QNetworkProxy(QNetworkProxy.ProxyType.Socks5Proxy, 'example.com', 0, 'foo',
'bar')),
('socks5://foo:bar@example.com:2323',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com', 2323,
+ QNetworkProxy(QNetworkProxy.ProxyType.Socks5Proxy, 'example.com', 2323,
'foo', 'bar')),
- ('direct://', QNetworkProxy(QNetworkProxy.NoProxy)),
+ ('direct://', QNetworkProxy(QNetworkProxy.ProxyType.NoProxy)),
])
def test_proxy_from_url_valid(self, url, expected):
assert urlutils.proxy_from_url(QUrl(url)) == expected
diff --git a/tests/unit/utils/test_utils.py b/tests/unit/utils/test_utils.py
index 4f81783c2..ad2c8b5f7 100644
--- a/tests/unit/utils/test_utils.py
+++ b/tests/unit/utils/test_utils.py
@@ -30,8 +30,8 @@ import shlex
import math
import operator
-from PyQt5.QtCore import QUrl, QRect, QPoint
-from PyQt5.QtGui import QClipboard
+from qutebrowser.qt.core import QUrl, QRect, QPoint
+from qutebrowser.qt.gui import QClipboard
import pytest
import hypothesis
from hypothesis import strategies, settings
@@ -683,7 +683,7 @@ class TestGetSetClipboard:
def test_set(self, clipboard_mock, caplog):
utils.set_clipboard('Hello World')
clipboard_mock.setText.assert_called_with('Hello World',
- mode=QClipboard.Clipboard)
+ mode=QClipboard.Mode.Clipboard)
assert not caplog.records
def test_set_unsupported_selection(self, clipboard_mock):
@@ -774,7 +774,7 @@ class TestOpenFile:
@pytest.fixture
def openurl_mock(self, mocker):
- return mocker.patch('PyQt5.QtGui.QDesktopServices.openUrl', spec={},
+ return mocker.patch('qutebrowser.qt.gui.QDesktopServices.openUrl', spec={},
new_callable=mocker.Mock)
def test_system_default_application(self, caplog, config_stub,
diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py
index 12ae1fd73..056cd8e4c 100644
--- a/tests/unit/utils/test_version.py
+++ b/tests/unit/utils/test_version.py
@@ -33,7 +33,7 @@ import dataclasses
import pytest
import hypothesis
import hypothesis.strategies
-from PyQt5.QtCore import PYQT_VERSION_STR
+from qutebrowser.qt.core import PYQT_VERSION_STR
import qutebrowser
from qutebrowser.config import config, websettings
@@ -979,13 +979,12 @@ class TestWebEngineVersions:
assert version.WebEngineVersions.from_elf(elf_version) == expected
@pytest.mark.parametrize('pyqt_version, chromium_version', [
- ('5.12.10', '69.0.3497.128'),
- ('5.14.2', '77.0.3865.129'),
- ('5.15.1', '80.0.3987.163'),
('5.15.2', '83.0.4103.122'),
('5.15.3', '87.0.4280.144'),
('5.15.4', '87.0.4280.144'),
('5.15.5', '87.0.4280.144'),
+ ('6.2.0', '90.0.4430.228'),
+ ('6.3.0', '94.0.4606.126'),
])
def test_from_pyqt(self, freezer, pyqt_version, chromium_version):
if freezer and pyqt_version in ['5.15.3', '5.15.4', '5.15.5']:
@@ -1006,16 +1005,16 @@ class TestWebEngineVersions:
pyqt_webengine_version = version._get_pyqt_webengine_qt_version()
if pyqt_webengine_version is None:
if '.dev' in PYQT_VERSION_STR:
- pytest.skip("dev version of PyQt5")
+ pytest.skip("dev version of PyQt")
try:
- from PyQt5.QtWebEngine import (
+ from qutebrowser.qt.webenginecore import (
PYQT_WEBENGINE_VERSION_STR, PYQT_WEBENGINE_VERSION)
except ImportError as e:
- # QtWebKit or QtWebEngine < 5.13
+ # QtWebKit
pytest.skip(str(e))
- if PYQT_WEBENGINE_VERSION >= 0x050F02:
+ if 0x060000 > PYQT_WEBENGINE_VERSION >= 0x050F02:
# Starting with Qt 5.15.2, we can only do bad guessing anyways...
pytest.skip("Could be QtWebEngine 5.15.2 or 5.15.3")
@@ -1063,18 +1062,18 @@ class TestChromiumVersion:
@pytest.fixture(autouse=True)
def clear_parsed_ua(self, monkeypatch):
- pytest.importorskip('PyQt5.QtWebEngineWidgets')
+ pytest.importorskip('qutebrowser.qt.webenginewidgets')
if webenginesettings is not None:
# Not available with QtWebKit
monkeypatch.setattr(webenginesettings, 'parsed_user_agent', None)
- def test_fake_ua(self, monkeypatch, caplog):
+ def test_fake_ua(self, monkeypatch, caplog, patch_no_api):
ver = '77.0.3865.98'
webenginesettings._init_user_agent_str(_QTWE_USER_AGENT.format(ver))
assert version.qtwebengine_versions().chromium == ver
- def test_prefers_saved_user_agent(self, monkeypatch):
+ def test_prefers_saved_user_agent(self, monkeypatch, patch_no_api):
webenginesettings._init_user_agent_str(_QTWE_USER_AGENT.format('87'))
class FakeProfile:
@@ -1090,7 +1089,16 @@ class TestChromiumVersion:
def test_avoided(self, monkeypatch):
versions = version.qtwebengine_versions(avoid_init=True)
- assert versions.source in ['ELF', 'importlib', 'PyQt', 'Qt']
+ assert versions.source in ['api', 'ELF', 'importlib', 'PyQt', 'Qt']
+
+ @pytest.fixture
+ def patch_no_api(self, monkeypatch):
+ """Simulate no PyQt API for getting its version."""
+ monkeypatch.delattr(
+ qutebrowser.qt.webenginecore,
+ "qWebEngineVersion",
+ raising=False,
+ )
@pytest.fixture
def patch_elf_fail(self, monkeypatch):
@@ -1098,11 +1106,6 @@ class TestChromiumVersion:
monkeypatch.setattr(elf, 'parse_webenginecore', lambda: None)
@pytest.fixture
- def patch_old_pyqt(self, monkeypatch):
- """Simulate an old PyQt without PYQT_WEBENGINE_VERSION_STR."""
- monkeypatch.setattr(version, 'PYQT_WEBENGINE_VERSION_STR', None)
-
- @pytest.fixture
def patch_no_importlib(self, monkeypatch, stubs):
"""Simulate missing importlib modules."""
import_fake = stubs.ImportFake({
@@ -1114,7 +1117,7 @@ class TestChromiumVersion:
@pytest.fixture
def importlib_patcher(self, monkeypatch):
"""Patch the importlib module."""
- def _patch(*, qt, qt5):
+ def _patch(*, qt, qt5, qt6):
try:
import importlib.metadata as importlib_metadata
except ImportError:
@@ -1125,8 +1128,10 @@ class TestChromiumVersion:
outcome = qt
elif name == 'PyQtWebEngine-Qt5':
outcome = qt5
+ elif name == 'PyQt6-WebEngine-Qt6':
+ outcome = qt6
else:
- raise utils.Unreachable(outcome)
+ raise utils.Unreachable(name)
if outcome is None:
raise importlib_metadata.PackageNotFoundError(name)
@@ -1138,16 +1143,14 @@ class TestChromiumVersion:
@pytest.fixture
def patch_importlib_no_package(self, importlib_patcher):
- """Simulate importlib not finding PyQtWebEngine-Qt[5]."""
- importlib_patcher(qt=None, qt5=None)
+ """Simulate importlib not finding PyQtWebEngine Qt packages."""
+ importlib_patcher(qt=None, qt5=None, qt6=None)
@pytest.mark.parametrize('patches, sources', [
- (['elf_fail'], ['importlib', 'PyQt', 'Qt']),
- (['elf_fail', 'old_pyqt'], ['importlib', 'Qt']),
- (['elf_fail', 'no_importlib'], ['PyQt', 'Qt']),
- (['elf_fail', 'no_importlib', 'old_pyqt'], ['Qt']),
- (['elf_fail', 'importlib_no_package'], ['PyQt', 'Qt']),
- (['elf_fail', 'importlib_no_package', 'old_pyqt'], ['Qt']),
+ (['no_api'], ['ELF', 'importlib', 'PyQt', 'Qt']),
+ (['no_api', 'elf_fail'], ['importlib', 'PyQt', 'Qt']),
+ (['no_api', 'elf_fail', 'no_importlib'], ['PyQt', 'Qt']),
+ (['no_api', 'elf_fail', 'importlib_no_package'], ['PyQt', 'Qt']),
], ids=','.join)
def test_simulated(self, request, patches, sources):
"""Test various simulated error conditions.
@@ -1163,17 +1166,41 @@ class TestChromiumVersion:
versions = version.qtwebengine_versions(avoid_init=True)
assert versions.source in sources
- @pytest.mark.parametrize('qt, qt5, expected', [
- (None, '5.15.4', utils.VersionNumber(5, 15, 4)),
- ('5.15.3', None, utils.VersionNumber(5, 15, 3)),
- ('5.15.3', '5.15.4', utils.VersionNumber(5, 15, 4)), # -Qt5 takes precedence
+ @pytest.mark.parametrize('qt, qt5, qt6, expected', [
+ pytest.param(
+ None, None, '6.3.0',
+ utils.VersionNumber(6, 3),
+ marks=pytest.mark.qt6_only,
+ ),
+ pytest.param(
+ '5.15.3', '5.15.4', '6.3.0',
+ utils.VersionNumber(6, 3),
+ marks=pytest.mark.qt6_only,
+ ),
+
+ pytest.param(
+ None, '5.15.4', None,
+ utils.VersionNumber(5, 15, 4),
+ marks=pytest.mark.qt5_only,
+ ),
+ pytest.param(
+ '5.15.3', None, None,
+ utils.VersionNumber(5, 15, 3),
+ marks=pytest.mark.qt5_only,
+ ),
+ # -Qt5 takes precedence
+ pytest.param(
+ '5.15.3', '5.15.4', None,
+ utils.VersionNumber(5, 15, 4),
+ marks=pytest.mark.qt5_only,
+ ),
])
- def test_importlib(self, qt, qt5, expected, patch_elf_fail, importlib_patcher):
+ def test_importlib(self, qt, qt5, qt6, expected, patch_elf_fail, patch_no_api, importlib_patcher):
"""Test the importlib version logic with different Qt packages.
With PyQtWebEngine 5.15.4, PyQtWebEngine-Qt was renamed to PyQtWebEngine-Qt5.
"""
- importlib_patcher(qt=qt, qt5=qt5)
+ importlib_patcher(qt=qt, qt5=qt5, qt6=qt6)
versions = version.qtwebengine_versions(avoid_init=True)
assert versions.source == 'importlib'
assert versions.webengine == expected
@@ -1182,9 +1209,10 @@ class TestChromiumVersion:
utils.VersionNumber(5, 12, 10),
utils.VersionNumber(5, 15, 3),
])
- def test_override(self, monkeypatch, override):
+ @pytest.mark.parametrize('avoid_init', [True, False])
+ def test_override(self, monkeypatch, override, avoid_init):
monkeypatch.setenv('QUTE_QTWEBENGINE_VERSION_OVERRIDE', str(override))
- versions = version.qtwebengine_versions(avoid_init=True)
+ versions = version.qtwebengine_versions(avoid_init=avoid_init)
assert versions.source == 'override'
assert versions.webengine == override
@@ -1237,7 +1265,7 @@ def test_version_info(params, stubs, monkeypatch, config_stub):
'_path_info': lambda: {'PATH DESC': 'PATH NAME'},
'objects.qapp': (stubs.FakeQApplication(style='STYLE', platform_name='PLATFORM')
if params.qapp else None),
- 'QLibraryInfo.location': (lambda _loc: 'QT PATH'),
+ 'qtutils.library_path': (lambda _loc: 'QT PATH'),
'sql.version': lambda: 'SQLITE VERSION',
'_uptime': lambda: datetime.timedelta(hours=1, minutes=23, seconds=45),
'config.instance.yaml_loaded': params.autoconfig_loaded,
@@ -1345,7 +1373,7 @@ class TestOpenGLInfo:
def test_func(self, qapp):
"""Simply call version.opengl_info() and see if it doesn't crash."""
- pytest.importorskip("PyQt5.QtOpenGL")
+ pytest.importorskip("qutebrowser.qt.opengl")
version.opengl_info()
def test_func_fake(self, qapp, monkeypatch):
diff --git a/tests/unit/utils/usertypes/test_timer.py b/tests/unit/utils/usertypes/test_timer.py
index 4dc85b06f..97c116f01 100644
--- a/tests/unit/utils/usertypes/test_timer.py
+++ b/tests/unit/utils/usertypes/test_timer.py
@@ -20,7 +20,7 @@
"""Tests for Timer."""
import pytest
-from PyQt5.QtCore import QObject
+from qutebrowser.qt.core import QObject
from qutebrowser.utils import usertypes
diff --git a/tox.ini b/tox.ini
index 53eb6938c..842e527b7 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,15 +4,17 @@
# and then run "tox" from this directory.
[tox]
-envlist = py38-pyqt515-cov,mypy,misc,vulture,flake8,pylint,pyroma,check-manifest,eslint,yamllint,actionlint
+envlist = py38-pyqt515-cov,mypy-pyqt5,misc,vulture,flake8,pylint,pyroma,check-manifest,eslint,yamllint,actionlint
distshare = {toxworkdir}
skipsdist = true
-minversion = 3.15
+minversion = 3.20
[testenv]
setenv =
PYTEST_QT_API=pyqt5
- pyqt{,512,513,514,515,5150}: LINK_PYQT_SKIP=true
+ QUTE_QT_WRAPPER=PyQt5
+ pyqt{62,63,64}: PYTEST_QT_API=pyqt6
+ pyqt{62,63,64}: QUTE_QT_WRAPPER=PyQt6
cov: PYTEST_ADDOPTS=--cov --cov-report xml --cov-report=html --cov-report=
passenv =
PYTHON
@@ -41,13 +43,13 @@ deps =
-r{toxinidir}/misc/requirements/requirements-tests.txt
-r{toxinidir}/misc/requirements/requirements-docs.txt
pyqt: -r{toxinidir}/misc/requirements/requirements-pyqt.txt
- pyqt512: -r{toxinidir}/misc/requirements/requirements-pyqt-5.12.txt
- pyqt513: -r{toxinidir}/misc/requirements/requirements-pyqt-5.13.txt
- pyqt514: -r{toxinidir}/misc/requirements/requirements-pyqt-5.14.txt
pyqt515: -r{toxinidir}/misc/requirements/requirements-pyqt-5.15.txt
- pyqt5150: -r{toxinidir}/misc/requirements/requirements-pyqt-5.15.0.txt
+ pyqt5152: -r{toxinidir}/misc/requirements/requirements-pyqt-5.15.2.txt
+ pyqt62: -r{toxinidir}/misc/requirements/requirements-pyqt-6.2.txt
+ pyqt63: -r{toxinidir}/misc/requirements/requirements-pyqt-6.3.txt
+ pyqt64: -r{toxinidir}/misc/requirements/requirements-pyqt-6.4.txt
commands =
- {envpython} scripts/link_pyqt.py --tox {envdir}
+ !pyqt-!pyqt515-!pyqt5152-!pyqt62-!pyqt63-!pyqt64: {envpython} scripts/link_pyqt.py --tox {envdir}
{envpython} -bb -m pytest {posargs:tests}
cov: {envpython} scripts/dev/check_coverage.py {posargs}
@@ -168,16 +170,19 @@ commands =
{envpython} scripts/dev/check_doc_changes.py {posargs}
{envpython} scripts/asciidoc2html.py {posargs}
-[testenv:pyinstaller-{64bit,32bit}]
+[testenv:pyinstaller-{64bit,32bit}{,-qt6}]
basepython = {env:PYTHON:python3}
passenv =
APPDATA
HOME
PYINSTALLER_DEBUG
+setenv =
+ qt6: PYINSTALLER_QT6=true
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/misc/requirements/requirements-pyinstaller.txt
- -r{toxinidir}/misc/requirements/requirements-pyqt.txt
+ !qt6: -r{toxinidir}/misc/requirements/requirements-pyqt.txt
+ qt6: -r{toxinidir}/misc/requirements/requirements-pyqt-6.txt
commands =
{envbindir}/pyinstaller --noconfirm misc/qutebrowser.spec
@@ -195,18 +200,22 @@ deps =
allowlist_externals = bash
commands = bash scripts/dev/run_shellcheck.sh {posargs}
-[testenv:mypy]
+[testenv:mypy-{pyqt5,pyqt6}]
basepython = {env:PYTHON:python3}
passenv =
TERM
MYPY_FORCE_TERMINAL_WIDTH
+setenv =
+ pyqt6: QUTE_CONSTANTS_ARGS=--always-true=USE_PYQT6 --always-false=USE_PYQT5 --always-false=USE_PYSIDE2 --always-false=USE_PYSIDE6 --always-false=IS_QT5 --always-true=IS_QT6
+ pyqt5: QUTE_CONSTANTS_ARGS=--always-false=USE_PYQT6 --always-true=USE_PYQT5 --always-false=USE_PYSIDE2 --always-false=USE_PYSIDE6 --always-true=IS_QT5 --always-false=IS_QT6
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/misc/requirements/requirements-dev.txt
-r{toxinidir}/misc/requirements/requirements-tests.txt
-r{toxinidir}/misc/requirements/requirements-mypy.txt
+ pyqt6: -r{toxinidir}/misc/requirements/requirements-pyqt-6.txt
commands =
- {envpython} -m mypy qutebrowser {posargs}
+ {envpython} -m mypy {env:QUTE_CONSTANTS_ARGS} qutebrowser {posargs}
[testenv:yamllint]
basepython = {env:PYTHON:python3}
@@ -221,12 +230,15 @@ allowlist_externals = actionlint
commands =
actionlint
-[testenv:mypy-diff]
+[testenv:mypy-{pyqt5,pyqt6}-diff]
basepython = {env:PYTHON:python3}
-passenv = {[testenv:mypy]passenv}
-deps = {[testenv:mypy]deps}
+passenv = {[testenv:mypy-pyqt6]passenv}
+deps = {[testenv:mypy-pyqt6]deps}
+setenv =
+ pyqt6: QUTE_CONSTANTS_ARGS=--always-true=USE_PYQT6 --always-false=USE_PYQT5 --always-false=USE_PYSIDE2 --always-false=USE_PYSIDE6 --always-false=IS_QT5 --always-true=IS_QT6
+ pyqt5: QUTE_CONSTANTS_ARGS=--always-false=USE_PYQT6 --always-true=USE_PYQT5 --always-false=USE_PYSIDE2 --always-false=USE_PYSIDE6 --always-true=IS_QT5 --always-false=IS_QT6
commands =
- {envpython} -m mypy --cobertura-xml-report {envtmpdir} qutebrowser tests {posargs}
+ {envpython} -m mypy --cobertura-xml-report {envtmpdir} {env:QUTE_CONSTANTS_ARGS} qutebrowser tests {posargs}
{envdir}/bin/diff-cover --fail-under=100 --compare-branch={env:DIFF_BRANCH:origin/{env:GITHUB_BASE_REF:master}} {envtmpdir}/cobertura.xml
[testenv:sphinx]
@@ -240,16 +252,21 @@ deps =
commands =
{envpython} -m sphinx -jauto -W --color {posargs} {toxinidir}/doc/extapi/ {toxinidir}/doc/extapi/_build/
-[testenv:build-release]
+[testenv:build-release{,-qt6}]
basepython = {env:PYTHON:python3}
passenv = *
+# Override default PyQt5 from [testenv]
+setenv =
+ qt6: QUTE_QT_WRAPPER=PyQt6
usedevelop = true
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/misc/requirements/requirements-tox.txt
-r{toxinidir}/misc/requirements/requirements-docs.txt
- -r{toxinidir}/misc/requirements/requirements-pyqt.txt
+ !qt6: -r{toxinidir}/misc/requirements/requirements-pyqt.txt
+ qt6: -r{toxinidir}/misc/requirements/requirements-pyqt-6.txt
-r{toxinidir}/misc/requirements/requirements-dev.txt
-r{toxinidir}/misc/requirements/requirements-pyinstaller.txt
commands =
- {envpython} {toxinidir}/scripts/dev/build_release.py {posargs}
+ !qt6: {envpython} {toxinidir}/scripts/dev/build_release.py {posargs}
+ qt6: {envpython} {toxinidir}/scripts/dev/build_release.py --qt6 {posargs}