Compare commits

..

25 Commits
main ... v3.6.2

Author SHA1 Message Date
qutebrowser bot b2c5d5fa0d Release v3.6.2 2025-11-27 20:57:11 +00:00
Florian Bruhin 73ae3abfc2 Update user agents
(cherry picked from commit 500a8df209)
2025-11-27 21:55:52 +01:00
Florian Bruhin e8af559bd7 Update changelog from main 2025-11-27 21:29:46 +01:00
Florian Bruhin 9816e176a7 qtargs: Remove old workaround with Qt 6.10.1
(cherry picked from commit b3e4dba731)
2025-11-27 21:29:34 +01:00
Florian Bruhin f7e7f8b168 tests: Use star-unpacking instead of itertools.chain
pytest will soon deprecate using a non-collection iterable in parametrize:
https://docs.pytest.org/en/latest/deprecations.html#parametrize-iterators

(cherry picked from commit 81d7b6a74c)
2025-11-27 17:59:10 +01:00
Rebecca 7dc9768976 Fixed minor issue in configuration docs
The docs show an example for adding domain filtering for configuration options. However the example only matches the root of a domain rather than all pages on a domain which is for example, the default case when using the `tsh` shortcut to disable/enable javascript on a page.

(cherry picked from commit 1cbb6fccf0)
2025-11-27 17:58:13 +01:00
Florian Bruhin dd790c3b72 Update requirements to Qt 6.10.1 2025-11-27 17:22:17 +01:00
Florian Bruhin f6aa7f6ba8 tests: Skip hangouts extension test on Qt 5 2025-11-23 11:43:09 +01:00
Florian Bruhin 4367cc65fe Avoid disabling off-the-record profile Hangouts extension with Qt 6.10.1
Otherwise this results in a crash, see #8785
2025-11-22 10:40:53 +01:00
gesh 22335c849a doc: Correct Arch Linux links
Arch hasn't been using the [community] repository for 9 months now[1],
correct the links for that.
Also, youtube-dl has been replaced in [extra] by yt-dlp[2][3], unsure
when -- I think this was in 2023?
Finally (and the trigger for this commit), given #8332, correct the
guidance on Arch Linux to point to pdfjs-legacy instead of pdfjs.

[1]: https://archlinux.org/news/cleaning-up-old-repositories/
[2]: https://aur.archlinux.org/packages/youtube-dl
[3]: https://archlinux.org/packages/extra/any/yt-dlp/

(cherry picked from commit 2f8234ee2e)
2025-11-21 23:43:59 +01:00
Florian Bruhin 56548455d5 tests: Improve test_version output
(cherry picked from commit 4f40a8b46b)
2025-11-21 23:42:52 +01:00
Florian Bruhin 4c6f9b4255 tests: Adjust permissions storage workaround for Qt 6.10.1
(cherry picked from commit 59a64af67f)
2025-11-21 23:42:52 +01:00
Florian Bruhin 300b075d79 Add QtWebEngine 6.10.1 security patch version
(cherry picked from commit 66cbe0d9c9)
2025-11-21 23:42:52 +01:00
Florian Bruhin b723a02087 tests: Stabilize flaky session scrolling test
Equivalent of d8079515fa
See #5390

(cherry picked from commit 0ef5053a65)
2025-11-21 23:42:52 +01:00
Florian Bruhin 86ed433b97 ci: Drop Archlinux Qt 5 images/jobs
For now, Qt 5 is still tested via the Qt 5.15 PyPI wheels.

See https://github.com/qutebrowser/qutebrowser/issues/8417#issuecomment-3495979318
https://lists.archlinux.org/archives/list/arch-dev-public@lists.archlinux.org/thread/U45C4RAW4IXVLO376XGFNLEGGFFXCULV/

(cherry picked from commit 9316d428ef)
2025-11-21 22:55:00 +01:00
Florian Bruhin 0c34bf2f79 version: Use correct profile for extension list
See #8785

(cherry picked from commit 8ae5e3d83b)
2025-11-21 22:51:33 +01:00
Jan Palus f86728e972 Unify librarry loading for X11/Wayland wmname
libwayland-client.so is development symlink used during linking and there's no need to
have it installed (usually shipped in -devel/-dev packages) on user's machines. Instead
of hardcoding library file name, use same mechanism as in libX11 which let's Python
figure the details and share common logic between X11 and Wayland.

Fixes #8771

(cherry picked from commit 25dc019886)
2025-11-11 09:10:04 +01:00
qutebrowser bot 2e5f805cce Release v3.6.1 2025-11-03 15:29:59 +00:00
Florian Bruhin 155b5cb241 Fix changelog
(cherry picked from commit 6e8e24050d)
2025-11-03 16:27:06 +01:00
Florian Bruhin 0deadea17f Adjust stack trace parsing for newer Python
(cherry picked from commit aa93eb1614)
2025-11-03 16:26:26 +01:00
Florian Bruhin b3377fccff Fix releasing focus when leaving command mode
The fix for #8223 in 6f21accfae
was misguided: We don't really care about the statusbar being hidden,
controlled release of keyboard focus needs to happen in any case where
we're hiding the command widget (as that's when we lose keyboard focus).

Fixes #8750.

(cherry picked from commit b646d606d7)
2025-10-25 16:45:13 +02:00
Florian Bruhin 11acdd2fdf ci: Fix finding existing draft release
(cherry picked from commit 1e4ddc2c6b)
2025-10-24 17:03:00 +02:00
Florian Bruhin 8f4e6ec06e scripts: Avoid showing entire file tree diff in CI log
(cherry picked from commit 3fce0518bd)
2025-10-24 17:02:59 +02:00
Florian Bruhin 52fd43c95e ci: Find existing draft release for reuploads
(cherry picked from commit 3808ebfdb3)
2025-10-24 16:23:37 +02:00
Florian Bruhin 26df4ce7e3 ci: Check out release branch for reuploads 2025-10-24 15:44:26 +02:00
37 changed files with 148 additions and 292 deletions

View File

@ -1,5 +1,5 @@
[tool.bumpversion]
current_version = "3.6.3"
current_version = "3.6.2"
commit = true
message = "Release v{new_version}"
tag = true

View File

@ -31,7 +31,7 @@ jobs:
- /home/runner/work/_temp/:/home/runner/work/_temp/
options: --privileged --tty
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up problem matchers
@ -48,7 +48,7 @@ jobs:
shell: bash
if: failure()
- name: Upload screenshots
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v4
with:
name: "end2end-screenshots-${{ steps.info.outputs.date }}-${{ steps.info.outputs.sha_short }}-${{ matrix.image }}"
path: |

View File

@ -34,10 +34,10 @@ jobs:
- testenv: actionlint
- testenv: package
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
persist-credentials: false
- uses: actions/cache@v5
- uses: actions/cache@v4
with:
path: |
.mypy_cache
@ -47,7 +47,7 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: '3.10'
- uses: actions/setup-node@v6
- uses: actions/setup-node@v5
with:
node-version: '22.x'
if: "matrix.testenv == 'eslint'"
@ -106,7 +106,7 @@ jobs:
- /home/runner/work/_temp/:/home/runner/work/_temp/
options: --privileged --tty
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up problem matchers
@ -121,7 +121,7 @@ jobs:
shell: bash
if: failure()
- name: Upload screenshots
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v4
with:
name: "end2end-screenshots-${{ steps.info.outputs.date }}-${{ steps.info.outputs.sha_short }}-${{ matrix.image }}"
path: |
@ -198,16 +198,16 @@ jobs:
- testenv: py314-pyqt610
os: ubuntu-24.04
python: "3.14"
### macOS Ventura
- testenv: py314-pyqt610
os: macos-13
python: "3.14"
args: "tests/unit" # Only run unit tests on macOS
### macOS Sonoma (M1 runner)
- testenv: py314-pyqt610
os: macos-14
python: "3.14"
args: "tests/unit" # Only run unit tests on macOS
### macOS Sequoia (Intel runner)
- testenv: py314-pyqt610
os: macos-15-intel
python: "3.14"
args: "tests/unit" # Only run unit tests on macOS
### Windows
- testenv: py314-pyqt610
os: windows-2022
@ -217,10 +217,10 @@ jobs:
python: "3.14"
runs-on: "${{ matrix.os }}"
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
persist-credentials: false
- uses: actions/cache@v5
- uses: actions/cache@v4
with:
path: |
.mypy_cache
@ -269,7 +269,7 @@ jobs:
shell: bash
if: failure()
- name: Upload screenshots
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v4
with:
name: "end2end-screenshots-${{ steps.info.outputs.date }}-${{ steps.info.outputs.sha_short }}-${{ matrix.testenv }}-${{ matrix.os }}"
path: |
@ -285,7 +285,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Initialize CodeQL

View File

@ -16,7 +16,7 @@ jobs:
- archlinux-webengine
- archlinux-webengine-unstable
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: '3.x'

View File

@ -14,7 +14,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: macos-15-intel
- os: macos-13
toxenv: build-release
name: macos-intel
- os: macos-14
@ -23,7 +23,7 @@ jobs:
- os: windows-latest
toxenv: build-release
name: windows
- os: macos-15-intel
- os: macos-13
args: --debug
toxenv: build-release
name: macos-debug-intel
@ -37,7 +37,7 @@ jobs:
runs-on: "${{ matrix.os }}"
timeout-minutes: 45
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up Python
@ -72,7 +72,7 @@ jobs:
echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
shell: bash
- name: Upload artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v4
with:
name: "qutebrowser-nightly-${{ steps.info.outputs.date }}-${{ steps.info.outputs.sha_short }}-${{ matrix.name }}"
path: |

View File

@ -18,7 +18,7 @@ jobs:
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up Python 3.9
@ -41,7 +41,7 @@ jobs:
- name: Run qutebrowser smoke test
run: "xvfb-run .venv/bin/python3 -m qutebrowser --no-err-windows --nowindow --temp-basedir about:blank ':later 500 quit'"
- name: Create pull request
uses: peter-evans/create-pull-request@v8
uses: peter-evans/create-pull-request@v7
with:
committer: qutebrowser bot <bot@qutebrowser.org>
author: qutebrowser bot <bot@qutebrowser.org>

View File

@ -62,7 +62,7 @@ jobs:
console.log(`sorted: ${sorted}`);
return sorted.at(-1);
result-encoding: string
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v6
with:
@ -78,7 +78,7 @@ jobs:
git config --global user.name "qutebrowser bot"
git config --global user.email "bot@qutebrowser.org"
- name: Switch to release branch
uses: actions/checkout@v6
uses: actions/checkout@v5
with:
ref: ${{ steps.find-branch.outputs.result }}
- name: Import GPG Key
@ -110,7 +110,6 @@ jobs:
- name: Cherry-pick release commit
if: ${{ inputs.release_type == 'patch' }}
run: |
git fetch origin main
git checkout main
git cherry-pick -x v${{ steps.bump.outputs.version }}
git push origin main
@ -154,8 +153,8 @@ jobs:
strategy:
matrix:
include:
- os: macos-14-large # Intel
- os: macos-14 # Apple Silicon
- os: macos-13
- os: macos-14
- os: windows-2022
- os: ubuntu-24.04
runs-on: "${{ matrix.os }}"
@ -164,7 +163,7 @@ jobs:
permissions:
contents: write # To upload release artifacts
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
ref: v${{ inputs.release_type == 'reupload' && needs.prepare.outputs.version_x || needs.prepare.outputs.version }}
- name: Set up Python

View File

@ -15,29 +15,6 @@ breaking changes (such as renamed commands) can happen in minor releases.
// `Fixed` for any bug fixes.
// `Security` to invite users to upgrade in case of vulnerabilities.
[[v3.6.4]]
v3.6.4 (unreleased)
-------------------
Fixed
~~~~~
- datalist dropdowns not opening correctly on Wayland/Sway (#8831).
This was caused by an old workaround for a different QtWebEngine issue,
which is now disabled for QtWebEngine 6.6.3 and newer.
[[v3.6.3]]
v3.6.3 (2025-11-30)
-------------------
Fixed
~~~~~
- New `qt.workarounds.disable_accessibility` setting, which disables Chromium
accessibility support. By default, is it set to `auto`, which only disables
accessibility on Qt versions with known issues. This works around a bug in Qt
6.10.1 causing frequent segfaults (#8797).
[[v3.6.2]]
v3.6.2 (2025-11-27)
-------------------

View File

@ -602,7 +602,6 @@ Info pages:
- chrome://device-log/ (QtWebEngine >= 6.3)
- chrome://gpu/
- chrome://sandbox/ (Linux only)
- chrome://qt/ (QtWebEngine >= 6.7)
Misc. / Debugging pages:
@ -613,7 +612,6 @@ Misc. / Debugging pages:
- chrome://ukm/ (QtWebEngine >= 5.15.3)
- chrome://user-actions/ (QtWebEngine >= 5.15.3)
- chrome://webrtc-logs/ (QtWebEngine >= 5.15.3)
- chrome://extensions/ (QtWebEngine >= 6.10)
Internals pages:

View File

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

View File

@ -44,7 +44,6 @@
</content_rating>
<releases>
<!-- Add new releases here -->
<release version='3.6.3' date='2025-11-30'/>
<release version='3.6.2' date='2025-11-27'/>
<release version='3.6.1' date='2025-11-03'/>
<release version='3.6.0' date='2025-10-24'/>

View File

@ -1,19 +1,19 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
annotated-types==0.7.0
anyio==4.12.0
anyio==4.11.0
autocommand==2.2.2
backports.tarfile==1.2.0
bracex==2.6
build==1.3.0
bump-my-version==1.2.5
certifi==2025.11.12
bump-my-version==1.2.4
certifi==2025.10.5
cffi==2.0.0
charset-normalizer==3.4.4
click==8.1.8
cryptography==46.0.3
docutils==0.22.3
exceptiongroup==1.3.1
docutils==0.22.2
exceptiongroup==1.3.0
github3.py==4.0.1
h11==0.16.0
httpcore==1.0.9
@ -30,36 +30,37 @@ jaraco.context==6.0.1
jaraco.functools==4.0.1
jaraco.text==3.12.1
jeepney==0.9.0
keyring==25.7.0
keyring==25.6.0
manhole==1.8.1
markdown-it-py==3.0.0
mdurl==0.1.2
more-itertools==10.8.0
nh3==0.3.2
nh3==0.3.1
packaging==25.0
platformdirs==4.4.0
prompt_toolkit==3.0.52
pycparser==2.23
pydantic==2.12.5
pydantic==2.12.3
pydantic-settings==2.11.0
pydantic_core==2.41.5
pydantic_core==2.41.4
Pygments==2.19.2
PyJWT==2.10.1
Pympler==1.1
pyproject_hooks==1.2.0
PyQt-builder==1.19.1
PyQt-builder==1.19.0
python-dateutil==2.9.0.post0
python-dotenv==1.2.1
python-dotenv==1.1.1
questionary==2.1.1
readme_renderer==44.0
requests==2.32.5
requests-toolbelt==1.0.0
rfc3986==2.0.0
rich==14.2.0
rich-click==1.9.4
rich-click==1.9.3
SecretStorage==3.3.3
sip==6.14.0
six==1.17.0
sniffio==1.3.1
tomli==2.3.0
tomlkit==0.13.3
twine==6.2.0
@ -67,7 +68,7 @@ typeguard==4.3.0
typing-inspection==0.4.2
typing_extensions==4.15.0
uritemplate==4.2.0
# urllib3==2.6.2
# urllib3==2.5.0
wcmatch==10.1
wcwidth==0.2.14
zipp==3.23.0

View File

@ -1,12 +1,11 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
chardet==5.2.0
diff_cover==10.0.0
diff_cover==9.7.1
Jinja2==3.1.6
librt==0.7.3
lxml==6.0.2
MarkupSafe==3.0.3
mypy==1.19.0
mypy==1.18.2
mypy_extensions==1.1.0
pathspec==0.12.1
pluggy==1.6.0
@ -14,7 +13,7 @@ Pygments==2.19.2
PyQt5-stubs==5.15.6.0
tomli==2.3.0
types-colorama==0.4.15.20250801
types-docutils==0.22.3.20251115
types-Pygments==2.19.0.20251121
types-docutils==0.22.2.20251006
types-Pygments==2.19.0.20250809
types-PyYAML==6.0.12.20250915
typing_extensions==4.15.0

View File

@ -1,8 +1,8 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
altgraph==0.17.5
altgraph==0.17.4
importlib_metadata==8.7.0
packaging==25.0
pyinstaller==6.17.0
pyinstaller-hooks-contrib==2025.10
pyinstaller==6.16.0
pyinstaller-hooks-contrib==2025.9
zipp==3.23.0

View File

@ -1,7 +1,7 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
astroid==3.3.11
certifi==2025.11.12
certifi==2025.10.5
cffi==2.0.0
charset-normalizer==3.4.4
cryptography==46.0.3
@ -24,5 +24,5 @@ tomli==2.3.0
tomlkit==0.13.3
typing_extensions==4.15.0
uritemplate==4.2.0
# urllib3==2.6.2
# urllib3==2.5.0
zipp==3.23.0

View File

@ -1,7 +1,7 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt5==5.15.11 # rq.filter: < 5.16
PyQt5-Qt5==5.15.18
PyQt5-Qt5==5.15.17
PyQt5_sip==12.17.1
PyQtWebEngine==5.15.7 # rq.filter: < 5.16
PyQtWebEngine-Qt5==5.15.18
PyQtWebEngine-Qt5==5.15.17

View File

@ -1,7 +1,7 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt5==5.15.11
PyQt5-Qt5==5.15.18
PyQt5-Qt5==5.15.17
PyQt5_sip==12.17.1
PyQtWebEngine==5.15.7
PyQtWebEngine-Qt5==5.15.18
PyQtWebEngine-Qt5==5.15.17

View File

@ -1,6 +1,6 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt6==6.10.1
PyQt6==6.10.0
PyQt6-Qt6==6.10.1
PyQt6-WebEngine==6.10.0
PyQt6-WebEngine-Qt6==6.10.1

View File

@ -1,6 +1,6 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt6==6.10.1
PyQt6==6.10.0
PyQt6-Qt6==6.10.1
PyQt6-WebEngine==6.10.0
PyQt6-WebEngine-Qt6==6.10.1

View File

@ -1,6 +1,6 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt6==6.10.1
PyQt6==6.10.0
PyQt6-Qt6==6.10.1
PyQt6-WebEngine==6.10.0
PyQt6-WebEngine-Qt6==6.10.1

View File

@ -1,18 +1,18 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
build==1.3.0
certifi==2025.11.12
certifi==2025.10.5
charset-normalizer==3.4.4
check-manifest==0.51
docutils==0.22.3
docutils==0.22.2
idna==3.11
importlib_metadata==8.7.0
packaging==25.0
Pygments==2.19.2
pyproject_hooks==1.2.0
pyroma==5.0.1
pyroma==5.0
requests==2.32.5
tomli==2.3.0
trove-classifiers==2025.12.1.14
urllib3==2.6.2
trove-classifiers==2025.9.11.17
urllib3==2.5.0
zipp==3.23.0

View File

@ -2,7 +2,7 @@
alabaster==0.7.16
babel==2.17.0
certifi==2025.11.12
certifi==2025.10.5
charset-normalizer==3.4.4
docutils==0.21.2
idna==3.11
@ -22,5 +22,5 @@ sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
tomli==2.3.0
urllib3==2.6.2
urllib3==2.5.0
zipp==3.23.0

View File

@ -3,15 +3,15 @@
attrs==25.4.0
autocommand==2.2.2
backports.tarfile==1.2.0
beautifulsoup4==4.14.3
beautifulsoup4==4.14.2
blinker==1.9.0
certifi==2025.11.12
certifi==2025.10.5
charset-normalizer==3.4.4
cheroot==11.1.2
cheroot==11.0.0
click==8.1.8
coverage==7.10.7
exceptiongroup==1.3.1
execnet==2.1.2
exceptiongroup==1.3.0
execnet==2.1.1
filelock==3.19.1
Flask==3.1.2
gherkin-official==29.0.0
@ -42,7 +42,7 @@ py-cpuinfo==9.0.0
Pygments==2.19.2
pytest==8.4.2
pytest-bdd==8.1.0
pytest-benchmark==5.2.3
pytest-benchmark==5.1.0
pytest-cov==7.0.0
pytest-instafail==0.5.0
pytest-mock==3.15.1
@ -61,7 +61,7 @@ tldextract==5.3.0
tomli==2.3.0
typeguard==4.3.0
typing_extensions==4.15.0
urllib3==2.6.2
urllib3==2.5.0
vulture==2.14
Werkzeug==3.1.4
Werkzeug==3.1.3
zipp==3.23.0

View File

@ -1,12 +1,12 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
cachetools==6.2.3
cachetools==6.2.1
chardet==5.2.0
colorama==0.4.6
distlib==0.4.0
filelock==3.19.1
packaging==25.0
pip==25.3
pip==25.2
platformdirs==4.4.0
pluggy==1.6.0
pyproject-api==1.9.1
@ -14,6 +14,6 @@ setuptools==80.9.0
tomli==2.3.0
tox==4.30.3 ; python_full_version!="3.14.0b1"
typing_extensions==4.15.0
virtualenv==20.35.4
virtualenv==20.35.3
wheel==0.45.1
tox @ git+https://github.com/tox-dev/tox ; python_full_version=="3.14.0b1"

View File

@ -14,7 +14,7 @@ __copyright__ = "Copyright 2013-{} Florian Bruhin (The Compiler)".format(_year)
__license__ = "GPL-3.0-or-later"
__maintainer__ = __author__
__email__ = "mail@qutebrowser.org"
__version__ = "3.6.3"
__version__ = "3.6.2"
__version_info__ = tuple(int(part) for part in __version__.split('.'))
__description__ = "A keyboard-driven, vim-like browser based on Python and Qt."

View File

@ -10,7 +10,7 @@ from qutebrowser.qt.gui import QKeyEvent
from qutebrowser.qt.widgets import QWidget
from qutebrowser.config import config
from qutebrowser.utils import log, message, usertypes, qtutils, version, utils
from qutebrowser.utils import log, message, usertypes, qtutils
from qutebrowser.keyinput import modeman, keyutils
@ -55,16 +55,16 @@ class ChildEventFilter(QObject):
# - This is a child event filter on a tab (self._widget is not None)
# - We find an old existing child which is a QQuickWidget and is
# currently focused.
# - We're using an affected QtWebEngine version
# - We're using QtWebEngine >= 6.4 (older versions are not affected)
children = [
c for c in self._widget.findChildren(
QWidget, "", Qt.FindChildOption.FindDirectChildrenOnly)
if c is not child and
c.hasFocus() and
c.metaObject() is not None and
c.metaObject().className() == "QQuickWidget" # Qt 6.4+
c.metaObject().className() == "QQuickWidget"
]
if children and version.qtwebengine_versions().webengine < utils.VersionNumber(6, 6, 3):
if children:
log.misc.debug("Focusing new child")
child.setFocus()

View File

@ -333,13 +333,8 @@ class Config(QObject):
pattern, hide_userconfig=hide_userconfig)
self.changed.emit(opt.name)
if pattern is not None:
log.config.debug("Config option changed: {} = {} for {}".format(
opt.name, value, pattern))
else:
log.config.debug("Config option changed: {} = {}".format(
opt.name, value))
log.config.debug("Config option changed: {} = {}".format(
opt.name, value))
def _check_yaml(self, opt: 'configdata.Option', save_yaml: bool) -> None:
"""Make sure the given option may be set in autoconfig.yml."""

View File

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

View File

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

View File

@ -23,7 +23,6 @@ import datetime
from typing import NoReturn
try:
import tkinter
import tkinter.messagebox
except ImportError:
tkinter = None # type: ignore[assignment]

View File

@ -37,6 +37,11 @@ def _load_library(name: str) -> ctypes.CDLL:
raise Error(f"Failed to load {name} library: {e}")
def _load_libwayland_client() -> ctypes.CDLL:
"""Load the Wayland client library."""
return _load_library("wayland-client")
def _pid_from_fd(fd: int) -> int:
"""Get the process ID from a file descriptor using SO_PEERCRED.
@ -116,7 +121,7 @@ def wayland_compositor_name() -> str:
Approach based on:
https://stackoverflow.com/questions/69302630/wayland-client-get-compositor-name
"""
wayland_client = _load_library("wayland-client")
wayland_client = _load_libwayland_client()
with _wayland_display(wayland_client) as display:
fd = _wayland_get_fd(wayland_client, display)
pid = _pid_from_fd(fd)
@ -139,6 +144,11 @@ _X11Display = NewType("_X11Display", "ctypes._Pointer[_X11DisplayStruct]")
_X11Window = NewType("_X11Window", int)
def _x11_load_lib() -> ctypes.CDLL:
"""Load the X11 library."""
return _load_library("X11")
@contextlib.contextmanager
def _x11_open_display(xlib: ctypes.CDLL) -> Iterator[_X11Display]:
"""Open a connection to the X11 display."""
@ -298,7 +308,7 @@ def _x11_get_wm_name(
def x11_wm_name() -> str:
"""Get the name of the running X11 window manager."""
xlib = _load_library("X11")
xlib = _x11_load_lib()
with _x11_open_display(xlib) as display:
atoms = _X11Atoms(
NET_SUPPORTING_WM_CHECK=_x11_intern_atom(

View File

@ -654,7 +654,6 @@ class WebEngineVersions:
utils.VersionNumber(6, 9): (_BASES[130], '133.0.6943.141'), # 2025-02-25
utils.VersionNumber(6, 9, 1): (_BASES[130], '136.0.7103.114'), # 2025-05-13
utils.VersionNumber(6, 9, 2): (_BASES[130], '139.0.7258.67'), # 2025-07-29
utils.VersionNumber(6, 9, 3): (_BASES[130], '140.0.7339.207'), # 2025-09-22
## Qt 6.10
utils.VersionNumber(6, 10): (_BASES[134], '140.0.7339.207'), # 2025-09-22

View File

@ -134,7 +134,7 @@ def _smoke_test_run(
return subprocess.run(argv, check=True, capture_output=True)
def smoke_test(executable: pathlib.Path, debug_build: bool) -> None:
def smoke_test(executable: pathlib.Path, debug: bool) -> None:
"""Try starting the given qutebrowser executable."""
stdout_whitelist = []
stderr_whitelist = [
@ -204,19 +204,8 @@ def smoke_test(executable: pathlib.Path, debug_build: bool) -> None:
r'\(0x80004002\)'),
])
try:
proc = _smoke_test_run(executable)
except subprocess.CalledProcessError as e:
print(f"Smoke test failed: {e}, running with --debug")
smoke_test_debug(
executable,
original_stdout=e.stdout.decode("utf-8"),
original_stderr=e.stderr.decode("utf-8"),
issue_description=str(e),
)
return
if debug_build:
proc = _smoke_test_run(executable)
if debug:
print("Skipping output check for debug build")
return
@ -225,64 +214,48 @@ def smoke_test(executable: pathlib.Path, debug_build: bool) -> None:
if stdout or stderr:
print("Unexpected output, running with --debug")
smoke_test_debug(
executable,
original_stdout=stdout,
original_stderr=stderr,
issue_description="Unexpected output",
)
proc = _smoke_test_run(executable, '--debug')
debug_stdout = proc.stdout.decode('utf-8')
debug_stderr = proc.stderr.decode('utf-8')
def smoke_test_debug(
executable: pathlib.Path,
*,
original_stdout: str,
original_stderr: str,
issue_description: str,
) -> None:
"""Run smoke test in debug mode to get more output."""
proc = _smoke_test_run(executable, '--debug')
debug_stdout = proc.stdout.decode('utf-8')
debug_stderr = proc.stderr.decode('utf-8')
lines = [
issue_description,
"",
]
if original_stdout:
lines += [
"stdout",
"------",
"",
original_stdout,
"",
]
if original_stderr:
lines += [
"stderr",
"------",
"",
original_stderr,
"",
]
if debug_stdout:
lines += [
"debug rerun stdout",
"------------------",
"",
debug_stdout,
"",
]
if debug_stderr:
lines += [
"debug rerun stderr",
"------------------",
"",
debug_stderr,
lines = [
"Unexpected output!",
"",
]
if stdout:
lines += [
"stdout",
"------",
"",
stdout,
"",
]
if stderr:
lines += [
"stderr",
"------",
"",
stderr,
"",
]
if debug_stdout:
lines += [
"debug rerun stdout",
"------------------",
"",
debug_stdout,
"",
]
if debug_stderr:
lines += [
"debug rerun stderr",
"------------------",
"",
debug_stderr,
"",
]
raise Exception("\n".join(lines)) # pylint: disable=broad-exception-raised
raise Exception("\n".join(lines)) # pylint: disable=broad-exception-raised
def verify_windows_exe(exe_path: pathlib.Path) -> None:
@ -338,7 +311,7 @@ def build_mac(
dist_path = pathlib.Path("dist")
utils.print_title("Running pre-dmg smoke test")
smoke_test(_mac_bin_path(dist_path), debug_build=debug)
smoke_test(_mac_bin_path(dist_path), debug=debug)
if skip_packaging:
return []
@ -361,7 +334,7 @@ def build_mac(
subprocess.run(['hdiutil', 'attach', dmg_path,
'-mountpoint', tmp_path], check=True)
try:
smoke_test(_mac_bin_path(tmp_path), debug_build=debug)
smoke_test(_mac_bin_path(tmp_path), debug=debug)
finally:
print("Waiting 10s for dmg to be detachable...")
time.sleep(10)
@ -420,7 +393,7 @@ def _build_windows_single(
verify_windows_exe(exe_path)
utils.print_title("Running smoke test")
smoke_test(exe_path, debug_build=debug)
smoke_test(exe_path, debug=debug)
if skip_packaging:
return []

View File

@ -23,7 +23,6 @@
"Mako": "https://docs.makotemplates.org/en/latest/changelog.html",
"hypothesis": "https://hypothesis.readthedocs.io/en/latest/changes.html",
"mypy": "https://github.com/python/mypy/blob/master/CHANGELOG.md",
"librt": "https://github.com/mypyc/librt/commits/master/",
"types-PyYAML": "https://github.com/python/typeshed/commits/main/stubs/PyYAML",
"types-colorama": "https://github.com/python/typeshed/commits/main/stubs/colorama",
"types-docutils": "https://github.com/python/typeshed/commits/main/stubs/docutils",
@ -102,6 +101,7 @@
"h11": "https://h11.readthedocs.io/en/latest/changes.html",
"httpcore": "https://github.com/encode/httpcore/blob/master/CHANGELOG.md",
"httpx": "https://github.com/encode/httpx/blob/master/CHANGELOG.md",
"sniffio": "https://sniffio.readthedocs.io/en/latest/history.html",
"six": "https://github.com/benjaminp/six/blob/master/CHANGES",
"altgraph": "https://github.com/ronaldoussoren/altgraph/blob/master/doc/changelog.rst",
"urllib3": "https://github.com/urllib3/urllib3/blob/main/CHANGES.rst",

View File

@ -263,14 +263,6 @@ def is_ignored_chromium_message(line):
"GetGpuDriverOverlayInfo: Failed to retrieve video device",
# [1784:7100:1022/150434.202:ERROR:direct_composition_support.cc(1122)]
"QueryInterface to IDCompositionDevice4 failed: No such interface supported (0x80004002)",
# Qt 6.10 on Windows + GitHub Actions
# [3508:6056:1103/172403.602:ERROR:cache_util_win.cc(20)]
"Unable to move the cache: The system cannot find the file specified. (0x2)",
# [3508:5516:1103/172403.608:ERROR:disk_cache.cc(216)]
"Unable to create cache",
# [3508:5516:1103/172403.608:ERROR:gpu_disk_cache.cc(711)]
"Gpu Cache Creation failed: -2",
]
return any(testutils.pattern_match(pattern=pattern, value=message)
for pattern in ignored_messages)

View File

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

View File

@ -21,7 +21,7 @@ from qutebrowser.misc import wmname
def test_load_libwayland_client():
"""Test loading the Wayland client library, which might or might not exist."""
try:
wmname._load_library("wayland-client")
wmname._load_libwayland_client()
except wmname.Error:
pass
@ -32,7 +32,7 @@ def test_load_libwayland_client_error(mocker: pytest_mock.MockerFixture):
mocker.patch("ctypes.CDLL", side_effect=OSError("Library not found"))
with pytest.raises(wmname.Error, match="Failed to load wayland-client"):
wmname._load_library("wayland-client")
wmname._load_libwayland_client()
@pytest.fixture
@ -178,7 +178,7 @@ def test_wayland_real():
def test_load_xlib():
"""Test loading Xlib, which might or might not exist."""
try:
wmname._load_library("X11")
wmname._x11_load_lib()
except wmname.Error:
pass
@ -188,7 +188,7 @@ def test_load_xlib_not_found(monkeypatch: pytest.MonkeyPatch):
monkeypatch.setattr(ctypes.util, "find_library", lambda x: None)
with pytest.raises(wmname.Error, match="X11 library not found"):
wmname._load_library("X11")
wmname._x11_load_lib()
def test_load_xlib_error(mocker: pytest_mock.MockerFixture):
@ -199,7 +199,7 @@ def test_load_xlib_error(mocker: pytest_mock.MockerFixture):
with pytest.raises(
wmname.Error, match="Failed to load X11 library: Failed to load library"
):
wmname._load_library("X11")
wmname._x11_load_lib()
@pytest.fixture
@ -290,7 +290,7 @@ def test_x11_get_wm_name(
qtbot.add_widget(w)
w.setWindowTitle("Test Window")
xlib = wmname._load_library("X11")
xlib = wmname._x11_load_lib()
with wmname._x11_open_display(xlib) as display:
atoms = wmname._X11Atoms(
NET_SUPPORTING_WM_CHECK=-1,