Compare commits

..

60 Commits
v3.6.2 ... main

Author SHA1 Message Date
Florian Bruhin 7e3df43463 Disable child focus workaround on unaffected Qt versions
The workaround added for #7820 seems to cause datalist dropdowns to lose focus
on Wayland. Let's just disable the old workaround on Qt versions that are not affected
by the original issue, which seems to be Qt 6.6.3+.

Fixes #8831.
2026-01-04 22:25:49 +01:00
Florian Bruhin 9ae082b29b version: Add QtWebEngine 6.9.3 2026-01-04 22:25:49 +01:00
dependabot[bot] b417f2a23b build(deps): bump peter-evans/create-pull-request from 7 to 8
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7 to 8.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v7...v8)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-16 12:51:26 +01:00
dependabot[bot] 615cee7309 build(deps): bump actions/upload-artifact from 5 to 6
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-16 12:51:19 +01:00
dependabot[bot] 65c1ca9691 build(deps): bump actions/cache from 4 to 5
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-16 12:51:09 +01:00
qutebrowser bot 12bed611c5 Update dependencies 2025-12-15 17:05:29 +01:00
Florian Bruhin bc72687d7d Update changelog URLs 2025-12-08 16:55:52 +01:00
Florian Bruhin c32b7d4b60 Fix dependency update issues 2025-12-08 10:53:13 +01:00
qutebrowser bot 3f9ef123e7 Update dependencies 2025-12-08 04:29:09 +00:00
Florian Bruhin f2547f8a09 scripts: Make smoke test fail output less confusing 2025-11-30 18:46:03 +01:00
qutebrowser bot edd5114492 Release v3.6.3
(cherry picked from commit ee13dac738)
2025-11-30 17:37:53 +00:00
Florian Bruhin 184a242937 ci: Make sure git knows the main branch
Something seems to have changed about how sparse checkouts are done on GHA, so the main branch isn't found.
2025-11-30 18:35:05 +01:00
Florian Bruhin 17c19a09b7 build_release: Try to get more information on crashes
Currently CI crashes on macOS, but without any useful logs.
2025-11-30 18:11:25 +01:00
Florian Bruhin 88aa47c377 Add qt.workarounds.disable_accessibility setting
This disables accessibility with Qt 6.10.1, which
causes frequent segfaults.

Closes #8797
2025-11-30 17:54:33 +01:00
dependabot[bot] 0570545342 build(deps): bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-30 00:15:59 +01:00
qutebrowser bot f408f20ad9 Release v3.6.2
(cherry picked from commit b2c5d5fa0d)
2025-11-27 20:57:13 +00:00
Florian Bruhin 500a8df209 Update user agents 2025-11-27 21:55:44 +01:00
Florian Bruhin 13d9904b90 Update changelog for v3.6.2 2025-11-27 21:29:21 +01:00
Florian Bruhin b3e4dba731 qtargs: Remove old workaround with Qt 6.10.1 2025-11-27 21:28:34 +01:00
qutebrowser bot 4164205663 Update dependencies 2025-11-27 17:21:32 +01:00
qutebrowser bot f5e2660890 Update dependencies 2025-11-24 16:37:39 +01:00
Florian Bruhin 69f3882ce3 tests: Skip hangouts extension test on Qt 5 2025-11-23 11:42:49 +01:00
Florian Bruhin 8e42727d31 Update changelog 2025-11-22 10:40:30 +01:00
Florian Bruhin 31a5737c61 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:38:46 +01:00
Florian Bruhin 8ae5e3d83b version: Use correct profile for extension list
See #8785
2025-11-21 22:50:52 +01:00
Florian Bruhin 4f40a8b46b tests: Improve test_version output 2025-11-21 18:39:24 +01:00
Florian Bruhin 59a64af67f tests: Adjust permissions storage workaround for Qt 6.10.1 2025-11-21 18:35:03 +01:00
Florian Bruhin 66cbe0d9c9 Add QtWebEngine 6.10.1 security patch version 2025-11-21 18:31:43 +01:00
Florian Bruhin 0ef5053a65 tests: Stabilize flaky session scrolling test
Equivalent of d8079515fa
See #5390
2025-11-18 15:00:20 +01:00
qutebrowser bot 6ddff3ae0d Update dependencies 2025-11-18 14:08:13 +01:00
Florian Bruhin 9316d428ef 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/
2025-11-11 09:13:30 +01:00
Florian Bruhin 71ed8cdbf5 Update changelog 2025-11-11 09:09:05 +01:00
Florian Bruhin 62fdb15532 Merge commit 'bc191b798' 2025-11-11 09:07:00 +01:00
Florian Bruhin bc191b798d wmname: Remove trivial functions 2025-11-11 09:06:49 +01:00
Florian Bruhin f8fbb0609f Update changelog 2025-11-11 08:46:36 +01:00
Florian Bruhin 55fb26fce1 Revert "fix: change fullscreen state when switching tab"
This reverts commit b89bf07d1e.

This turned out to be annoying when enabling fullscreen manually and then
switching through tabs.
2025-11-11 08:45:55 +01:00
Jan Palus 25dc019886
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
2025-11-11 00:51:05 +01:00
Florian Bruhin 81d7b6a74c 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
2025-11-10 13:02:26 +01:00
qutebrowser bot 6ec5504ab3 Update dependencies 2025-11-10 07:39:05 +01:00
Florian Bruhin 9b69c889ef doc: Add additional chrome:// pages 2025-11-07 11:45:51 +01:00
Florian Bruhin 4e87ef303f ci: Update macOS runners / versions
https://github.blog/changelog/2025-09-19-github-actions-macos-13-runner-image-is-closing-down/

- CI: Switch to macOS 15 Intel runner
  (macOS 14 is still tested with Apple Silicon)
- Nightly: Use macOS 15 Intel runner for nightly releases
  (macOS 14 would be better to align with actual Intel releases, but it is
  a -large runner, thus possibly metered)
- Releases: Use macOS 14 for Intel releases
  This is a -large runner, but releases don't happen often.
2025-11-05 16:51:43 +01:00
gesh 2f8234ee2e 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/
2025-11-05 14:26:04 +01:00
Florian Bruhin a8f0b47451 tests: Ignore more bogus Chromium messages 2025-11-03 18:32:17 +01:00
Florian Bruhin 4a5b7bd6e4 Update changelog 2025-11-03 18:10:24 +01:00
OmeletWithoutEgg b89bf07d1e fix: change fullscreen state when switching tab 2025-11-03 18:09:28 +01:00
Rebecca 70bf4689fc Fixed whitespace
Removed excess line of whitespace.
2025-11-03 18:09:01 +01:00
Rebecca 1cbb6fccf0 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.
2025-11-03 18:09:01 +01:00
Rebecca d3e4245d0f Improved logging for configuration loading
- When loading a configuration file, if the configuration uses domain filtering then the domain filter expression is logged in the debug log.
2025-11-03 18:09:01 +01:00
qutebrowser bot 3160048619 Release v3.6.1
(cherry picked from commit 2e5f805cce)
2025-11-03 15:30:02 +00:00
Florian Bruhin aa93eb1614 Adjust stack trace parsing for newer Python 2025-11-03 16:26:12 +01:00
qutebrowser bot df9cef3a58 Update dependencies 2025-11-03 06:33:33 +01:00
dependabot[bot] 214e2e9ac2 build(deps): bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 20:41:53 +01:00
qutebrowser bot 68574b88cc Update dependencies 2025-10-27 08:21:55 +01:00
Florian Bruhin 6e8e24050d Fix changelog 2025-10-26 23:02:14 +01:00
dependabot[bot] 5fe9bf97e3 build(deps): bump actions/setup-node from 5 to 6
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 5 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-25 22:36:25 +02:00
Florian Bruhin b646d606d7 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.
2025-10-25 16:43:06 +02:00
Florian Bruhin 1e4ddc2c6b ci: Fix finding existing draft release 2025-10-24 17:02:41 +02:00
Florian Bruhin 3fce0518bd scripts: Avoid showing entire file tree diff in CI log 2025-10-24 17:00:19 +02:00
Florian Bruhin 3808ebfdb3 ci: Find existing draft release for reuploads 2025-10-24 16:23:03 +02:00
Florian Bruhin 0421aacd64 ci: Check out release branch for reuploads 2025-10-24 15:45:15 +02:00
37 changed files with 292 additions and 148 deletions

View File

@ -1,5 +1,5 @@
[tool.bumpversion]
current_version = "3.6.2"
current_version = "3.6.3"
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@v5
- uses: actions/checkout@v6
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@v4
uses: actions/upload-artifact@v6
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@v5
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/cache@v4
- uses: actions/cache@v5
with:
path: |
.mypy_cache
@ -47,7 +47,7 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: '3.10'
- uses: actions/setup-node@v5
- uses: actions/setup-node@v6
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@v5
- uses: actions/checkout@v6
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@v4
uses: actions/upload-artifact@v6
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@v5
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/cache@v4
- uses: actions/cache@v5
with:
path: |
.mypy_cache
@ -269,7 +269,7 @@ jobs:
shell: bash
if: failure()
- name: Upload screenshots
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
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@v5
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Initialize CodeQL

View File

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

View File

@ -14,7 +14,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: macos-13
- os: macos-15-intel
toxenv: build-release
name: macos-intel
- os: macos-14
@ -23,7 +23,7 @@ jobs:
- os: windows-latest
toxenv: build-release
name: windows
- os: macos-13
- os: macos-15-intel
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@v5
- uses: actions/checkout@v6
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@v4
uses: actions/upload-artifact@v6
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@v5
- uses: actions/checkout@v6
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@v7
uses: peter-evans/create-pull-request@v8
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@v5
- uses: actions/checkout@v6
- 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@v5
uses: actions/checkout@v6
with:
ref: ${{ steps.find-branch.outputs.result }}
- name: Import GPG Key
@ -110,6 +110,7 @@ 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
@ -153,8 +154,8 @@ jobs:
strategy:
matrix:
include:
- os: macos-13
- os: macos-14
- os: macos-14-large # Intel
- os: macos-14 # Apple Silicon
- os: windows-2022
- os: ubuntu-24.04
runs-on: "${{ matrix.os }}"
@ -163,7 +164,7 @@ jobs:
permissions:
contents: write # To upload release artifacts
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
ref: v${{ inputs.release_type == 'reupload' && needs.prepare.outputs.version_x || needs.prepare.outputs.version }}
- name: Set up Python

View File

@ -15,6 +15,29 @@ 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,6 +602,7 @@ Info pages:
- chrome://device-log/ (QtWebEngine >= 6.3)
- chrome://gpu/
- chrome://sandbox/ (Linux only)
- chrome://qt/ (QtWebEngine >= 6.7)
Misc. / Debugging pages:
@ -612,6 +613,7 @@ 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,6 +302,7 @@
|<<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.
@ -3996,6 +3997,24 @@ 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,6 +44,7 @@
</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.11.0
anyio==4.12.0
autocommand==2.2.2
backports.tarfile==1.2.0
bracex==2.6
build==1.3.0
bump-my-version==1.2.4
certifi==2025.10.5
bump-my-version==1.2.5
certifi==2025.11.12
cffi==2.0.0
charset-normalizer==3.4.4
click==8.1.8
cryptography==46.0.3
docutils==0.22.2
exceptiongroup==1.3.0
docutils==0.22.3
exceptiongroup==1.3.1
github3.py==4.0.1
h11==0.16.0
httpcore==1.0.9
@ -30,37 +30,36 @@ jaraco.context==6.0.1
jaraco.functools==4.0.1
jaraco.text==3.12.1
jeepney==0.9.0
keyring==25.6.0
keyring==25.7.0
manhole==1.8.1
markdown-it-py==3.0.0
mdurl==0.1.2
more-itertools==10.8.0
nh3==0.3.1
nh3==0.3.2
packaging==25.0
platformdirs==4.4.0
prompt_toolkit==3.0.52
pycparser==2.23
pydantic==2.12.3
pydantic==2.12.5
pydantic-settings==2.11.0
pydantic_core==2.41.4
pydantic_core==2.41.5
Pygments==2.19.2
PyJWT==2.10.1
Pympler==1.1
pyproject_hooks==1.2.0
PyQt-builder==1.19.0
PyQt-builder==1.19.1
python-dateutil==2.9.0.post0
python-dotenv==1.1.1
python-dotenv==1.2.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.3
rich-click==1.9.4
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
@ -68,7 +67,7 @@ typeguard==4.3.0
typing-inspection==0.4.2
typing_extensions==4.15.0
uritemplate==4.2.0
# urllib3==2.5.0
# urllib3==2.6.2
wcmatch==10.1
wcwidth==0.2.14
zipp==3.23.0

View File

@ -1,11 +1,12 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
chardet==5.2.0
diff_cover==9.7.1
diff_cover==10.0.0
Jinja2==3.1.6
librt==0.7.3
lxml==6.0.2
MarkupSafe==3.0.3
mypy==1.18.2
mypy==1.19.0
mypy_extensions==1.1.0
pathspec==0.12.1
pluggy==1.6.0
@ -13,7 +14,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.2.20251006
types-Pygments==2.19.0.20250809
types-docutils==0.22.3.20251115
types-Pygments==2.19.0.20251121
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.4
altgraph==0.17.5
importlib_metadata==8.7.0
packaging==25.0
pyinstaller==6.16.0
pyinstaller-hooks-contrib==2025.9
pyinstaller==6.17.0
pyinstaller-hooks-contrib==2025.10
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.10.5
certifi==2025.11.12
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.5.0
# urllib3==2.6.2
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.17
PyQt5-Qt5==5.15.18
PyQt5_sip==12.17.1
PyQtWebEngine==5.15.7 # rq.filter: < 5.16
PyQtWebEngine-Qt5==5.15.17
PyQtWebEngine-Qt5==5.15.18

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.17
PyQt5-Qt5==5.15.18
PyQt5_sip==12.17.1
PyQtWebEngine==5.15.7
PyQtWebEngine-Qt5==5.15.17
PyQtWebEngine-Qt5==5.15.18

View File

@ -1,6 +1,6 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt6==6.10.0
PyQt6==6.10.1
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.0
PyQt6==6.10.1
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.0
PyQt6==6.10.1
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.10.5
certifi==2025.11.12
charset-normalizer==3.4.4
check-manifest==0.51
docutils==0.22.2
docutils==0.22.3
idna==3.11
importlib_metadata==8.7.0
packaging==25.0
Pygments==2.19.2
pyproject_hooks==1.2.0
pyroma==5.0
pyroma==5.0.1
requests==2.32.5
tomli==2.3.0
trove-classifiers==2025.9.11.17
urllib3==2.5.0
trove-classifiers==2025.12.1.14
urllib3==2.6.2
zipp==3.23.0

View File

@ -2,7 +2,7 @@
alabaster==0.7.16
babel==2.17.0
certifi==2025.10.5
certifi==2025.11.12
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.5.0
urllib3==2.6.2
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.2
beautifulsoup4==4.14.3
blinker==1.9.0
certifi==2025.10.5
certifi==2025.11.12
charset-normalizer==3.4.4
cheroot==11.0.0
cheroot==11.1.2
click==8.1.8
coverage==7.10.7
exceptiongroup==1.3.0
execnet==2.1.1
exceptiongroup==1.3.1
execnet==2.1.2
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.1.0
pytest-benchmark==5.2.3
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.5.0
urllib3==2.6.2
vulture==2.14
Werkzeug==3.1.3
Werkzeug==3.1.4
zipp==3.23.0

View File

@ -1,12 +1,12 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
cachetools==6.2.1
cachetools==6.2.3
chardet==5.2.0
colorama==0.4.6
distlib==0.4.0
filelock==3.19.1
packaging==25.0
pip==25.2
pip==25.3
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.3
virtualenv==20.35.4
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.2"
__version__ = "3.6.3"
__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
from qutebrowser.utils import log, message, usertypes, qtutils, version, utils
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 QtWebEngine >= 6.4 (older versions are not affected)
# - We're using an affected QtWebEngine version
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"
c.metaObject().className() == "QQuickWidget" # Qt 6.4+
]
if children:
if children and version.qtwebengine_versions().webengine < utils.VersionNumber(6, 6, 3):
log.misc.debug("Focusing new child")
child.setFocus()

View File

@ -333,8 +333,13 @@ class Config(QObject):
pattern, hide_userconfig=hide_userconfig)
self.changed.emit(opt.name)
log.config.debug("Config option changed: {} = {}".format(
opt.name, value))
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))
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,6 +422,19 @@ qt.workarounds.disable_hangouts_extension:
disabled to avoid crashes on Qt 6.5.0 to 6.5.3 if dark mode is enabled,
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,6 +362,16 @@ _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,6 +23,7 @@ import datetime
from typing import NoReturn
try:
import tkinter
import tkinter.messagebox
except ImportError:
tkinter = None # type: ignore[assignment]

View File

@ -37,11 +37,6 @@ 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.
@ -121,7 +116,7 @@ def wayland_compositor_name() -> str:
Approach based on:
https://stackoverflow.com/questions/69302630/wayland-client-get-compositor-name
"""
wayland_client = _load_libwayland_client()
wayland_client = _load_library("wayland-client")
with _wayland_display(wayland_client) as display:
fd = _wayland_get_fd(wayland_client, display)
pid = _pid_from_fd(fd)
@ -144,11 +139,6 @@ _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."""
@ -308,7 +298,7 @@ def _x11_get_wm_name(
def x11_wm_name() -> str:
"""Get the name of the running X11 window manager."""
xlib = _x11_load_lib()
xlib = _load_library("X11")
with _x11_open_display(xlib) as display:
atoms = _X11Atoms(
NET_SUPPORTING_WM_CHECK=_x11_intern_atom(

View File

@ -654,6 +654,7 @@ 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: bool) -> None:
def smoke_test(executable: pathlib.Path, debug_build: bool) -> None:
"""Try starting the given qutebrowser executable."""
stdout_whitelist = []
stderr_whitelist = [
@ -204,8 +204,19 @@ def smoke_test(executable: pathlib.Path, debug: bool) -> None:
r'\(0x80004002\)'),
])
proc = _smoke_test_run(executable)
if debug:
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:
print("Skipping output check for debug build")
return
@ -214,48 +225,64 @@ def smoke_test(executable: pathlib.Path, debug: bool) -> None:
if stdout or stderr:
print("Unexpected output, running with --debug")
proc = _smoke_test_run(executable, '--debug')
debug_stdout = proc.stdout.decode('utf-8')
debug_stderr = proc.stderr.decode('utf-8')
smoke_test_debug(
executable,
original_stdout=stdout,
original_stderr=stderr,
issue_description="Unexpected output",
)
lines = [
"Unexpected output!",
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,
"",
]
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:
@ -311,7 +338,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=debug)
smoke_test(_mac_bin_path(dist_path), debug_build=debug)
if skip_packaging:
return []
@ -334,7 +361,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_build=debug)
finally:
print("Waiting 10s for dmg to be detachable...")
time.sleep(10)
@ -393,7 +420,7 @@ def _build_windows_single(
verify_windows_exe(exe_path)
utils.print_title("Running smoke test")
smoke_test(exe_path, debug=debug)
smoke_test(exe_path, debug_build=debug)
if skip_packaging:
return []

View File

@ -23,6 +23,7 @@
"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",
@ -101,7 +102,6 @@
"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,6 +263,14 @@ 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
from qutebrowser.utils import usertypes, version, utils
@pytest.fixture
@ -52,6 +52,7 @@ 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)
@ -117,6 +118,14 @@ 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:
@ -190,6 +199,40 @@ 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_libwayland_client()
wmname._load_library("wayland-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_libwayland_client()
wmname._load_library("wayland-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._x11_load_lib()
wmname._load_library("X11")
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._x11_load_lib()
wmname._load_library("X11")
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._x11_load_lib()
wmname._load_library("X11")
@pytest.fixture
@ -290,7 +290,7 @@ def test_x11_get_wm_name(
qtbot.add_widget(w)
w.setWindowTitle("Test Window")
xlib = wmname._x11_load_lib()
xlib = wmname._load_library("X11")
with wmname._x11_open_display(xlib) as display:
atoms = wmname._X11Atoms(
NET_SUPPORTING_WM_CHECK=-1,