diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index af19f01850f..23de6e95af3 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
[bumpversion]
-current_version = 2.5.4
+current_version = 3.1.0
commit = True
message = Release v{new_version}
tag = True
diff --git a/.github/CONTRIBUTING.asciidoc b/.github/CONTRIBUTING.asciidoc
index 0d03af33665..9c119baa308 100644
--- a/.github/CONTRIBUTING.asciidoc
+++ b/.github/CONTRIBUTING.asciidoc
@@ -9,7 +9,7 @@ open pull requests.
pull request page after pushing changes.
- If you are stuck somewhere or have questions,
- https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/index.asciidoc#getting-help[please ask]!
+ https://github.com/qutebrowser/qutebrowser/blob/main/doc/help/index.asciidoc#getting-help[please ask]!
See the link:../doc/contributing.asciidoc[full contribution documentation] for
details and other useful hints.
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 4faa45afb19..65ab0afa3a7 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,2 +1,2 @@
github: The-Compiler
-custom: https://github.com/qutebrowser/qutebrowser/blob/master/README.asciidoc#donating
+custom: https://github.com/qutebrowser/qutebrowser/blob/main/README.asciidoc#donating
diff --git a/.github/workflows/bleeding.yml b/.github/workflows/bleeding.yml
index 59da1dfad81..2587d832bb9 100644
--- a/.github/workflows/bleeding.yml
+++ b/.github/workflows/bleeding.yml
@@ -12,25 +12,33 @@ jobs:
if: "github.repository == 'qutebrowser/qutebrowser'"
runs-on: ubuntu-20.04
timeout-minutes: 45
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - testenv: bleeding
+ image: "archlinux-webengine-unstable-qt6"
+ - testenv: bleeding-qt5
+ image: "archlinux-webengine-unstable"
container:
- image: "qutebrowser/ci:archlinux-webengine-unstable"
+ image: "qutebrowser/ci:${{ matrix.image }}"
env:
FORCE_COLOR: "1"
PY_COLORS: "1"
- DOCKER: "archlinux-webengine-unstable"
+ DOCKER: "${{ matrix.image }}"
CI: true
volumes:
# Hardcoded because we can't use ${{ runner.temp }} here apparently.
- /home/runner/work/_temp/:/home/runner/work/_temp/
options: --privileged --tty
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up problem matchers
run: "python scripts/dev/ci/problemmatchers.py py3 ${{ runner.temp }}"
- name: Run tox
- run: dbus-run-session tox -e bleeding
+ run: dbus-run-session tox -e ${{ matrix.testenv }}
irc:
timeout-minutes: 2
continue-on-error: true
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 64dddd2f849..fe1bbefe7b1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -33,8 +33,9 @@ jobs:
args: "-f gcc" # For problem matchers
- testenv: yamllint
- testenv: actionlint
+ - testenv: package
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/cache@v3
@@ -44,10 +45,10 @@ jobs:
.tox
~/.cache/pip
key: "${{ matrix.testenv }}-${{ hashFiles('misc/requirements/requirements-*.txt') }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('scripts/dev/pylint_checkers/qute_pylint/*.py') }}"
- - uses: actions/setup-python@v4
+ - uses: actions/setup-python@v5
with:
python-version: '3.10'
- - uses: actions/setup-node@v3
+ - uses: actions/setup-node@v4
with:
node-version: '16.x'
if: "matrix.testenv == 'eslint'"
@@ -56,7 +57,8 @@ jobs:
- name: Install dependencies
run: |
[[ ${{ matrix.testenv }} == eslint ]] && npm install -g eslint
- [[ ${{ matrix.testenv }} == docs ]] && sudo apt-get update && sudo apt-get install --no-install-recommends asciidoc
+ [[ ${{ matrix.testenv }} == docs ]] && sudo apt-get update && sudo apt-get install --no-install-recommends asciidoc libegl1-mesa
+ [[ ${{ matrix.testenv }} == vulture || ${{ matrix.testenv }} == pylint ]] && sudo apt-get update && sudo apt-get install --no-install-recommends libegl1-mesa
if [[ ${{ matrix.testenv }} == shellcheck ]]; then
scversion="stable"
bindir="$HOME/.local/bin"
@@ -89,17 +91,16 @@ jobs:
fail-fast: false
matrix:
include:
- - testenv: py
+ - testenv: py-qt5
image: archlinux-webkit
- - testenv: py
+ - testenv: py-qt5
image: archlinux-webengine
- - testenv: py-qt6
+ - testenv: py-qt5
+ image: archlinux-webengine-unstable
+ - testenv: py
image: archlinux-webengine-qt6
- testenv: py
- image: archlinux-webengine-unstable
- args: ""
- # - testenv: py
- # image: archlinux-webengine-unstable-qt6 # FIXME:qt6.5 activate
+ image: archlinux-webengine-unstable-qt6
container:
image: "qutebrowser/ci:${{ matrix.image }}"
env:
@@ -111,13 +112,13 @@ jobs:
- /home/runner/work/_temp/:/home/runner/work/_temp/
options: --privileged --tty
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up problem matchers
- run: "python scripts/dev/ci/problemmatchers.py py38 ${{ runner.temp }}"
+ run: "python scripts/dev/ci/problemmatchers.py tests ${{ runner.temp }}"
- name: Run tox
- run: "dbus-run-session -- tox -e ${{ matrix.testenv }} -- ${{ matrix.args }}"
+ run: "dbus-run-session -- tox -e ${{ matrix.testenv }}"
tests:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
@@ -156,31 +157,31 @@ jobs:
- testenv: py310-pyqt65
os: ubuntu-22.04
python: "3.10"
- ### PyQt 6.5 (Python 3.11)
- - testenv: py311-pyqt65
+ ### PyQt 6.6 (Python 3.11)
+ - testenv: py311-pyqt66
os: ubuntu-22.04
python: "3.11"
- ### PyQt 6.5 (Python 3.12)
- # - testenv: py312-pyqt65
- # os: ubuntu-22.04
- # python: "3.12-dev"
- ### macOS Big Sur: PyQt 5.15 (Python 3.9 to match PyInstaller env)
- - testenv: py39-pyqt515
+ ### PyQt 6.6 (Python 3.12)
+ - testenv: py312-pyqt66
+ os: ubuntu-22.04
+ python: "3.12"
+ ### macOS Big Sur
+ - testenv: py312-pyqt66
os: macos-11
- python: "3.9"
+ python: "3.12"
args: "tests/unit" # Only run unit tests on macOS
### macOS Monterey
- - testenv: py39-pyqt515
+ - testenv: py312-pyqt66
os: macos-12
- python: "3.9"
+ python: "3.12"
args: "tests/unit" # Only run unit tests on macOS
- ### Windows: PyQt 5.15 (Python 3.9 to match PyInstaller env)
- - testenv: py39-pyqt515
+ ### Windows
+ - testenv: py312-pyqt66
os: windows-2019
- python: "3.9"
+ python: "3.12"
runs-on: "${{ matrix.os }}"
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/cache@v3
@@ -191,7 +192,7 @@ jobs:
~/.cache/pip
key: "${{ matrix.testenv }}-${{ matrix.os }}-${{ matrix.python }}-${{ hashFiles('misc/requirements/requirements-*.txt') }}-${{ hashFiles('requirements.txt') }}"
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "${{ matrix.python }}"
- name: Set up problem matchers
@@ -228,16 +229,16 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
persist-credentials: false
- name: Initialize CodeQL
- uses: github/codeql-action/init@v2
+ uses: github/codeql-action/init@v3
with:
languages: javascript, python
queries: +security-extended
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v2
+ uses: github/codeql-action/analyze@v3
irc:
timeout-minutes: 2
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index cabf2d8c40a..3762e6f4829 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -15,27 +15,28 @@ jobs:
- archlinux-webkit
- archlinux-webengine
- archlinux-webengine-unstable
+ - archlinux-webengine-unstable-qt6
- archlinux-webengine-qt6
steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v4
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
with:
python-version: '3.x'
- run: pip install jinja2
- name: Generate Dockerfile
run: python3 generate.py ${{ matrix.image }}
working-directory: scripts/dev/ci/docker/
- - uses: docker/setup-buildx-action@v2
- - uses: docker/login-action@v2
+ - uses: docker/setup-buildx-action@v3
+ - uses: docker/login-action@v3
with:
username: qutebrowser
password: ${{ secrets.DOCKER_TOKEN }}
- - uses: docker/build-push-action@v4
+ - uses: docker/build-push-action@v5
with:
file: scripts/dev/ci/docker/Dockerfile
context: .
tags: "qutebrowser/ci:${{ matrix.image }}"
- push: ${{ github.ref == 'refs/heads/master' }}
+ push: ${{ github.ref == 'refs/heads/main' }}
irc:
timeout-minutes: 2
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 2254abb4a28..764bcae319a 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -15,60 +15,41 @@ jobs:
matrix:
include:
- os: macos-11
- branch: master
- toxenv: build-release
- name: macos
+ toxenv: build-release-qt5
+ name: qt5-macos
- os: windows-2019
- args: --64bit
- branch: master
- toxenv: build-release
- name: windows-64bit
- - os: windows-2019
- args: --32bit
- branch: master
- toxenv: build-release
- name: windows-32bit
-
+ toxenv: build-release-qt5
+ name: qt5-windows
- os: macos-11
args: --debug
- branch: master
- toxenv: build-release
- name: macos-debug
+ toxenv: build-release-qt5
+ name: qt5-macos-debug
- os: windows-2019
- args: --64bit --debug
- branch: master
+ args: --debug
+ toxenv: build-release-qt5
+ name: qt5-windows-debug
+ - os: macos-11
toxenv: build-release
- name: windows-64bit-debug
+ name: macos
- os: windows-2019
- args: --32bit --debug
- branch: master
toxenv: build-release
- name: windows-32bit-debug
-
- - os: macos-11
- toxenv: build-release-qt6
- name: qt6-macos
- - os: windows-2019
- args: --64bit
- toxenv: build-release-qt6
- name: qt6-windows-64bit
+ name: windows
- os: macos-11
args: --debug
- toxenv: build-release-qt6
- name: qt6-macos-debug
+ toxenv: build-release
+ name: macos-debug
- os: windows-2019
- args: --64bit --debug
- toxenv: build-release-qt6
- name: qt6-windows-64bit-debug
+ args: --debug
+ toxenv: build-release
+ name: windows-debug
runs-on: "${{ matrix.os }}"
timeout-minutes: 45
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
- ref: "${{ matrix.branch }}"
persist-credentials: false
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install dependencies
@@ -88,7 +69,7 @@ jobs:
echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
shell: bash
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: "qutebrowser-nightly-${{ steps.info.outputs.date }}-${{ steps.info.outputs.sha_short }}-${{ matrix.name }}"
path: |
diff --git a/.github/workflows/recompile-requirements.yml b/.github/workflows/recompile-requirements.yml
index 623f11ca505..1e5637a1058 100644
--- a/.github/workflows/recompile-requirements.yml
+++ b/.github/workflows/recompile-requirements.yml
@@ -18,11 +18,11 @@ jobs:
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Python 3.8
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
python-version: '3.8'
- name: Recompile requirements
@@ -31,7 +31,7 @@ jobs:
- name: Install apt dependencies
run: |
sudo apt-get update
- sudo apt-get install --no-install-recommends libyaml-dev libegl1-mesa libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 asciidoc python3-venv xvfb
+ sudo apt-get install --no-install-recommends libyaml-dev libegl1-mesa libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 asciidoc python3-venv xvfb
- name: Install dependencies
run: |
python -m pip install -U pip
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000000..9a751591f3a
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,223 @@
+name: Release
+
+on:
+ workflow_dispatch:
+ inputs:
+ release_type:
+ description: 'Release type'
+ required: true
+ default: 'patch'
+ type: choice
+ options:
+ - 'patch'
+ - 'minor'
+ - 'major'
+ # FIXME do we want a possibility to do prereleases here?
+ python_version:
+ description: 'Python version'
+ required: true
+ default: '3.12'
+ type: choice
+ options:
+ - '3.8'
+ - '3.9'
+ - '3.10'
+ - '3.11'
+ - '3.12'
+jobs:
+ prepare:
+ runs-on: ubuntu-20.04
+ timeout-minutes: 5
+ outputs:
+ version: ${{ steps.bump.outputs.version }}
+ release_id: ${{ steps.create-release.outputs.id }}
+ permissions:
+ contents: write # To push release commit/tag
+ steps:
+ - name: Find release branch
+ uses: actions/github-script@v7
+ id: find-branch
+ with:
+ script: |
+ if (context.payload.inputs.release_type != 'patch') {
+ return 'main';
+ }
+ const branches = await github.paginate(github.rest.repos.listBranches, {
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ });
+ const branch_names = branches.map(branch => branch.name);
+ console.log(`branches: ${branch_names}`);
+ const release_branches = branch_names.filter(branch => branch.match(/^v\d+\.\d+\.x$/));
+ if (release_branches.length === 0) {
+ core.setFailed('No release branch found!');
+ return '';
+ }
+ console.log(`release_branches: ${release_branches}`);
+ // Get newest release branch (biggest version number)
+ const sorted = release_branches.sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }));
+ console.log(`sorted: ${sorted}`);
+ return sorted.at(-1);
+ result-encoding: string
+ - uses: actions/checkout@v4
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ # Doesn't really matter what we prepare the release with, but let's
+ # use the same version for consistency.
+ python-version: ${{ github.event.inputs.python_version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install -U pip
+ python -m pip install -U -r misc/requirements/requirements-tox.txt
+ - name: Configure git
+ run: |
+ git config --global user.name "qutebrowser bot"
+ git config --global user.email "bot@qutebrowser.org"
+ - name: Switch to release branch
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ steps.find-branch.outputs.result }}
+ - name: Import GPG Key
+ run: |
+ gpg --import <<< "${{ secrets.QUTEBROWSER_BOT_GPGKEY }}"
+ - name: Bump version
+ id: bump
+ run: "tox -e update-version -- ${{ github.event.inputs.release_type }}"
+ - name: Check milestone
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const milestones = await github.paginate(github.rest.issues.listMilestones, {
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ });
+ const names = milestones.map(milestone => milestone.title);
+ console.log(`milestones: ${names}`);
+
+ const milestone = milestones.find(milestone => milestone.title === "v${{ steps.bump.outputs.version }}");
+ if (milestone !== undefined) {
+ core.setFailed(`Found open milestone ${milestone.title} with ${milestone.open_issues} open and ${milestone.closed_issues} closed issues!`);
+ }
+ - name: Push release commit/tag
+ run: |
+ git push origin ${{ steps.find-branch.outputs.result }}
+ git push origin v${{ steps.bump.outputs.version }}
+ - name: Cherry-pick release commit
+ if: ${{ github.event.inputs.release_type == 'patch' }}
+ run: |
+ git checkout main
+ git cherry-pick -x v${{ steps.bump.outputs.version }}
+ git push origin main
+ git checkout v${{ steps.bump.outputs.version_x }}
+ - name: Create release branch
+ if: ${{ github.event.inputs.release_type != 'patch' }}
+ run: |
+ git checkout -b v${{ steps.bump.outputs.version_x }}
+ git push --set-upstream origin v${{ steps.bump.outputs.version_x }}
+ - name: Create GitHub draft release
+ id: create-release
+ uses: softprops/action-gh-release@v1
+ with:
+ tag_name: v${{ steps.bump.outputs.version }}
+ draft: true
+ body: "*Release artifacts for this release are currently being uploaded...*"
+ release:
+ strategy:
+ matrix:
+ include:
+ - os: macos-11
+ - os: windows-2019
+ - os: ubuntu-20.04
+ runs-on: "${{ matrix.os }}"
+ timeout-minutes: 45
+ needs: [prepare]
+ permissions:
+ contents: write # To upload release artifacts
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: v${{ needs.prepare.outputs.version }}
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: ${{ github.event.inputs.python_version }}
+ - name: Import GPG Key
+ if: ${{ startsWith(matrix.os, 'ubuntu-') }}
+ run: |
+ gpg --import <<< "${{ secrets.QUTEBROWSER_BOT_GPGKEY }}"
+ # Needed because of the following import chain:
+ # - scripts/dev/build_release.py
+ # - scripts/dev/update_3rdparty.py
+ # - scripts/dictcli.py
+ # - qutebrowser/browser/webengine/spell.py
+ # - utils.message -> utils.usertypes -> utils.qtutils -> qt.gui
+ # - PyQt6.QtGui
+ # Some additional packages are needed for a2x to build manpage
+ - name: Install apt dependencies
+ if: ${{ startsWith(matrix.os, 'ubuntu-') }}
+ run: |
+ sudo apt-get update
+ sudo apt-get install --no-install-recommends libegl1-mesa libxml2-utils docbook-xml xsltproc docbook-xsl
+ - name: Install dependencies
+ run: |
+ python -m pip install -U pip
+ python -m pip install -U -r misc/requirements/requirements-tox.txt
+ # FIXME consider switching to trusted publishers:
+ # https://blog.pypi.org/posts/2023-04-20-introducing-trusted-publishers/
+ - name: Build and upload release
+ run: "tox -e build-release -- --upload --no-confirm"
+ env:
+ TWINE_USERNAME: __token__
+ TWINE_PASSWORD: ${{ secrets.QUTEBROWSER_BOT_PYPI_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ finalize:
+ runs-on: ubuntu-20.04
+ timeout-minutes: 5
+ needs: [prepare, release]
+ permissions:
+ contents: write # To change release
+ steps:
+ - name: Publish final release
+ uses: actions/github-script@v7
+ with:
+ script: |
+ await github.rest.repos.updateRelease({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ release_id: "${{ needs.prepare.outputs.release_id }}",
+ draft: false,
+ body: "Check the [changelog](https://github.com/qutebrowser/qutebrowser/blob/main/doc/changelog.asciidoc) for changes in this release.",
+ })
+ irc:
+ timeout-minutes: 2
+ continue-on-error: true
+ runs-on: ubuntu-20.04
+ needs: [prepare, release, finalize]
+ if: "${{ always() }}"
+ steps:
+ - name: Send success IRC notification
+ uses: Gottox/irc-message-action@v2
+ if: "${{ needs.finalize.result == 'success' }}"
+ with:
+ server: irc.libera.chat
+ channel: '#qutebrowser-bots'
+ nickname: qutebrowser-bot
+ message: "[${{ github.workflow }}] \u00033Success:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})"
+ - name: Send main channel IRC notification
+ uses: Gottox/irc-message-action@v2
+ if: "${{ needs.finalize.result == 'success' && github.repository == 'qutebrowser/qutebrowser' }}"
+ with:
+ server: irc.libera.chat
+ channel: '#qutebrowser'
+ nickname: qutebrowser-bot
+ message: "qutebrowser v${{ needs.prepare.outputs.version }} has been released! https://github.com/${{ github.repository }}/releases/tag/v${{ needs.prepare.outputs.version }}"
+ - name: Send non-success IRC notification
+ uses: Gottox/irc-message-action@v2
+ if: "${{ needs.finalize.result != 'success' }}"
+ with:
+ server: irc.libera.chat
+ channel: '#qutebrowser-bots'
+ nickname: qutebrowser-bot
+ message: "[${{ github.workflow }}] \u00034FAIL:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})\n
+ prepare: ${{ needs.prepare.result }}, release: ${{ needs.release.result}}, finalize: ${{ needs.finalize.result }}"
diff --git a/.pylintrc b/.pylintrc
index f89e3fa504d..a6784c0e4b6 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -1,9 +1,8 @@
[MASTER]
ignore=resources.py
-extension-pkg-whitelist=PyQt5,sip
+extension-pkg-whitelist=PyQt5,PyQt6,sip
load-plugins=qute_pylint.config,
pylint.extensions.docstyle,
- pylint.extensions.emptystring,
pylint.extensions.overlapping_exceptions,
pylint.extensions.code_style,
pylint.extensions.comparison_placement,
@@ -58,8 +57,9 @@ disable=locally-disabled,
missing-type-doc,
missing-param-doc,
useless-param-doc,
- wrong-import-order, # FIXME:qt6 (lint)
- ungrouped-imports, # FIXME:qt6 (lint)
+ wrong-import-order, # doesn't work with qutebrowser.qt, even with known-third-party set
+ ungrouped-imports, # ditto
+ use-implicit-booleaness-not-comparison-to-zero,
[BASIC]
function-rgx=[a-z_][a-z0-9_]{2,50}$
@@ -76,7 +76,7 @@ class-const-naming-style = snake_case
[FORMAT]
# FIXME:v4 (lint) down to 88 again once we use black
max-line-length=190
-ignore-long-lines=( `cmd-set-text`
+ * `repeat` -> `cmd-repeat`
+ * `repeat-command` -> `cmd-repeat-last`
+ * `later` -> `cmd-later`
+ * `edit-command` -> `cmd-edit`
+ * `run-with-count` -> `cmd-run-with-count`
+ The old names continue to work for the time being, but are deprecated and
+ show a warning.
+- Releases are now automated on CI, and GPG signed by
+ `qutebrowser bot `, fingerprint
+ `27F3 BB4F C217 EECB 8585 78AE EF7E E4D0 3969 0B7B`.
+ The key is available as follows:
+ * On https://qutebrowser.org/pubkey.gpg
+ * Via keys.openpgp.org
+ * Via WKD for bot@qutebrowser.org
+- Support for old Qt versions (< 5.15), old Python versions (< 3.8) and old
+ macOS (< 11)/Windows (< 10) versions were dropped. See the "Removed" section
+ below for details.
+
Added
~~~~~
@@ -27,7 +178,6 @@ Added
- New `:prompt-fileselect-external` command which can be used to spawn an
external file selector (`fileselect.folder.command`) from download filename
prompts (bound to `` by default).
-- New `clock` value for `statusbar.widgets`, displaying the current time.
- New `qute://start` built-in start page (not set as the default start page yet).
- New `content.javascript.log_message.levels` setting, allowing to surface JS log
messages as qutebrowser messages (rather than only logging them). By default,
@@ -50,19 +200,25 @@ Added
* `qutedmenu` gained new `window` and `private` options.
* `qute-keepassxc` now supports unlock-on-demand, multiple account
selection via rofi, and inserting TOTP-codes (experimental).
+ * `qute-pass` will now try looking up candidate pass entries based on the
+ calling tab's verbatim netloc (hostname including port and username) if it
+ can't find a match with an earlier candidate (FQDN, IPv4 etc).
- New `qt.chromium.experimental_web_platform_features` setting, which is enabled
on Qt 5 by default, to maximize compatibility with websites despite an aging
Chromium backend.
- New `colors.webpage.darkmode.increase_text_contrast` setting for Qt 6.3+
- New `fonts.tooltip`, `colors.tooltip.bg` and `colors.tooltip.fg` settings.
- New `log-qt-events` debug flag for `-D`
+- New `--all` flags for `:bookmark-del` and `:quickmark-del` to delete all
+ quickmarks/bookmarks.
Removed
~~~~~~~
- Python 3.8.0 or newer is now required.
- Support for Python 3.6 and 3.7 is dropped, as they both reached
- their [end of life] in December 2021 and June 2023, respectively.
+ their https://endoflife.date/python[end of life] in December 2021 and June
+ 2023, respectively.
- 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
@@ -70,14 +226,17 @@ Removed
- The `--enable-webengine-inspector` flag is now dropped. It used to be ignored
but still accepted, to allow doing a `:restart` from versions older than v2.0.0.
Thus, switching from v1.x.x directly to v3.0.0 via `:restart` will not be possible.
-- It's planned to drop support for various legacy platforms and libraries which
- are unsupported upstream, such as:
- * The QtWebKit backend
- * macOS 10.14 (via Homebrew)
- * 32-bit Windows (via Qt)
- * Windows 8 (via Qt)
- * Windows 10 before 1809 (via Qt)
- * Possibly other more minor dependency changes
+- Support for macOS 10.14 and 10.15 is now dropped, raising the minimum
+ required macOS version to macOS 11 Big Sur.
+ * Qt 6.4 was the latest version to support macOS 10.14 and 10.15.
+ * It should be possible to build a custom .dmg with Qt 6.4, but this is
+ unsupported and not recommended.
+- Support for Windows 8 and for Windows 10 before 1607 is now dropped.
+ * Support for older Windows 10 versions might still be present in Qt 6.0/6.1/6.2
+ * Support for Windows 8.1 is still present in Qt 5.15
+ * It should be possible to build a custom .exe with those versions, but this
+ is unsupported and not recommended.
+- Support for 32-bit Windows is now dropped.
Changed
~~~~~~~
@@ -116,11 +275,10 @@ Changed
the ones produced by `:download --mhtml`.
- The "... called unimplemented GM_..." messages are now logged as info JS
messages instead of errors.
-- JS errors in internal qutebrowser scripts are now shown as errors in the UI.
- For QtNetwork downloads (e.g. `:adblock-update`), various changes were done
for how redirects work:
- Insecure redirects (HTTPS -> HTTP) now fail the download.
- - 20 redirects are now allowed before the download fails rather than only 10
+ - 20 redirects are now allowed before the download fails rather than only 10.
- A redirect to the same URL will now fail the download with too many
redirects instead of being ignored.
- When a download fails in a way it'd leave an empty file around, the empty
@@ -131,7 +289,7 @@ Changed
should make certain operations happen when the page has started loading rather
when it fully finished.
- `mkvenv.py` has a new `--pyqt-snapshot` flag, allowing to install certain packages
- from the https://www.riverbankcomputing.com/pypi/[Riverbank development snapshots server]
+ from the https://www.riverbankcomputing.com/pypi/[Riverbank development snapshots server].
- When `QUTE_QTWEBENGINE_VERSION_OVERRIDE` is set, it now always wins, no matter how
the version would otherwise have been determined. Note setting this value can break
things (if set to a wrong value), and usually isn't needed.
@@ -139,8 +297,8 @@ Changed
launch, it now prints an error before starting (which causes the underlying
Chromium to remove all browsing data such as cookies).
- The keys "" and "" are now named ""
- and "", respeectively.
-- The `tox.ini` now requires at least tox 3.20 (was tox 3.15 previously)
+ and "", respectively.
+- The `tox.ini` now requires at least tox 3.20 (was tox 3.15 previously).
- `:config-diff` now has an `--include-hidden` flag, which also shows
internally-set settings.
- Improved error messages when `:spawn` can't find an executable.
@@ -148,17 +306,18 @@ Changed
the correct PID (rather than always showing the latest process, which might not
be the failing one)
- When a process got killed with `SIGTERM`, no error message is now displayed
- anymore (unless started with `:spawn --verbose`).
+ anymore (unless started with `:spawn --verbose`).
- When a process got killed by a signal, the signal name is now displayed in
the message.
-- The qute-pass will now try looking up candidate pass entries based on the
- calling tab's verbatim netloc (hostname including port and username) if it
- can't find a match with an earlier candidate (FQDN, IPv4 etc).
- The `js-string-replaceall` quirk is now removed from the default
`content.site_specific_quirks.skip`, so that `String.replaceAll` is now
polyfilled on QtWebEngine < 5.15.3, hopefully improving website
compaitibility.
- Hints are now displayed for elements setting an `aria-haspopup` attribute.
+- qutebrowser now uses SPDX license identifiers in its files. Full support for
+ the https://reuse.software/[REUSE specification] (license provided in a
+ machine-readable way for every single file) is not done yet, but planned for
+ a future release.
Fixed
~~~~~
@@ -177,12 +336,24 @@ Fixed
- Multiple rare crashes when quitting qutebrowser.
- The `asciidoc2html.py` script now correctly uses the virtualenv-installed
asciidoc rather than requiring a system-wide installation.
+- "Package would be ignored" deprecation warnings when running `setup.py`.
+- ResourceWarning when using `:restart`.
+- Crash when shutting down before fully initialized.
- Crash with some notification servers when the server is quitting.
- Crash when using QtWebKit with PAC and the file has an invalid encoding.
- Crash with the "tiramisu" notification server.
- Crash when the "herbe" notification presenter doesn't start correctly.
+- Crash when no notification server is installed/available.
+- Warning with recent versions of the "deadd" (aka "linux notification center") notification server.
- Crash when using `:print --pdf` with a directory where its parent directory
did not exist.
+- The `PyQt{5,6}.sip` version is now shown correctly in the `:version`/`--version`
+ output. Previously that showed the version from the standalone `sip` module
+ which was only set for PyQt5. (#7805)
+- When a `config.py` calls `.redirect()` via a request interceptor (which is
+ unsupported) and supplies an invalid redirect target URL, an exception is now
+ raised for the `.redirect()` call instead of later inside qutebrowser.
+- Crash when loading invalid history items from a session file.
[[v2.5.4]]
v2.5.4 (2023-03-13)
@@ -1152,7 +1323,7 @@ Changed
It also has compatibility issues with various websites (GitHub, Twitch, Android
Developer documentation, YouTube, ...). Since no newer Debian Stable is released
at the time of writing, it's recommended to
- https://github.com/qutebrowser/qutebrowser/blob/master/doc/install.asciidoc#installing-qutebrowser-with-virtualenv[install qutebrowser in a virtualenv]
+ https://github.com/qutebrowser/qutebrowser/blob/main/doc/install.asciidoc#installing-qutebrowser-with-virtualenv[install qutebrowser in a virtualenv]
with a newer version of Qt/PyQt.
- New optional dependency on the Python `adblock` library (see above for details).
- The (formerly optional) `cssutils` dependency is now removed. It was only
@@ -3303,7 +3474,7 @@ Major changes
completion is too slow on your machine, try setting it to a few 1000 items.
- Up/Down now navigates through the command history instead of selecting
completion items. Either use Tab to cycle through the completion, or
- https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc#migrating-older-configurations[restore the old behavior].
+ https://github.com/qutebrowser/qutebrowser/blob/main/doc/help/configuring.asciidoc#migrating-older-configurations[restore the old behavior].
Added
~~~~~
diff --git a/doc/contributing.asciidoc b/doc/contributing.asciidoc
index 50773f54488..144117677a0 100644
--- a/doc/contributing.asciidoc
+++ b/doc/contributing.asciidoc
@@ -84,9 +84,9 @@ If you prefer to send a patch to the mailinglist, you can generate a patch
based on your changes like this:
----
-git format-patch origin/master <1>
+git format-patch origin/main <1>
----
-<1> Replace `master` by the branch your work was based on, e.g.,
+<1> Replace `main` by the branch your work was based on, e.g.,
`origin/develop`.
Running qutebrowser
@@ -575,35 +575,46 @@ Chrome URLs
~~~~~~~~~~~
With the QtWebEngine backend, qutebrowser supports several chrome:// urls which
-can be useful for debugging:
+can be useful for debugging.
-- chrome://accessibility/
-- chrome://appcache-internals/
-- chrome://blob-internals/
-- chrome://conversion-internals/ (QtWebEngine 5.15.3+)
-- chrome://crash/ (crashes the current renderer process!)
+Info pages:
+
+- chrome://device-log/ (QtWebEngine >= 6.3)
- chrome://gpu/
-- chrome://gpuclean/ (crashes the current renderer process!)
-- chrome://gpucrash/ (crashes qutebrowser!)
-- chrome://gpuhang/ (hangs qutebrowser!)
+- chrome://sandbox/ (Linux only)
+
+Misc. / Debugging pages:
+
+- chrome://dino/
- chrome://histograms/
+- chrome://network-errors/
+- chrome://tracing/ (QtWebEngine >= 5.15.3)
+- chrome://ukm/ (QtWebEngine >= 5.15.3)
+- chrome://user-actions/ (QtWebEngine >= 5.15.3)
+- chrome://webrtc-logs/ (QtWebEngine >= 5.15.3)
+
+Internals pages:
+
+- chrome://accessibility/
+- chrome://appcache-internals/ (QtWebEngine < 6.4)
+- chrome://attribution-internals/ (QtWebEngine >= 6.4)
+- chrome://blob-internals/
+- chrome://conversion-internals/ (QtWebEngine >= 5.15.3 and < 6.4)
- chrome://indexeddb-internals/
-- chrome://kill/ (kills the current renderer process!)
- chrome://media-internals/
-- chrome://net-internals/ (QtWebEngine 5.15.4+)
-- chrome://network-errors/
-- chrome://ppapiflashcrash/
-- chrome://ppapiflashhang/
+- chrome://net-internals/ (QtWebEngine >= 5.15.4)
- chrome://process-internals/
- chrome://quota-internals/
-- chrome://sandbox/ (Linux only)
- chrome://serviceworker-internals/
-- chrome://taskscheduler-internals/ (removed in QtWebEngine 5.14)
-- chrome://tracing/ (QtWebEngine 5.15.3+)
-- chrome://ukm/ (QtWebEngine 5.15.3+)
-- chrome://user-actions/ (QtWebEngine 5.15.3+)
- chrome://webrtc-internals/
-- chrome://webrtc-logs/ (QtWebEngine 5.15.3+)
+
+Crash/hang pages:
+
+- chrome://crash/ (crashes the current renderer process!)
+- chrome://gpuclean/ (crashes the current renderer process!)
+- chrome://gpucrash/ (crashes qutebrowser!)
+- chrome://gpuhang/ (hangs qutebrowser!)
+- chrome://kill/ (kills the current renderer process!)
QtWebEngine internals
~~~~~~~~~~~~~~~~~~~~~
@@ -758,18 +769,30 @@ qutebrowser release
* Make sure there are no unstaged changes and the tests are green.
* Make sure all issues with the related milestone are closed.
+* Mark the https://github.com/qutebrowser/qutebrowser/milestones[milestone] as closed.
* Consider updating the completions for `content.headers.user_agent` in `configdata.yml`.
-* Minor release: Consider updating some files from master:
+* Minor release: Consider updating some files from main:
- `misc/requirements/` and `requirements.txt`
- `scripts/`
+* Update changelog in main branch and ensure the correct version number has `(unreleased)`
+* If necessary: Update changelog in release branch from main.
+
+**Automatic release via GitHub Actions (starting with v3.0.0):**
+
+* Double check Python version in `.github/workflows/release.yml`
+* Run the `release` workflow on the `main` branch, e.g. via `gh workflow run release -f release_type=major` (`release_type` can be `major`, `minor` or `patch`; you can also override `python_version`)
+
+**Manual release:**
+
* Make sure Python is up-to-date on build machines.
-* Mark the milestone at https://github.com/qutebrowser/qutebrowser/milestones as closed.
-* Update changelog in master branch
-* If necessary: Update changelog in release branch from master.
* Run `./.venv/bin/python3 scripts/dev/update_version.py {major,minor,patch}`.
* Run the printed instructions accordingly.
+
+**Post release:**
+
* Update `qutebrowser-git` PKGBUILD if dependencies/install changed.
* Add unreleased future versions to changelog
* Update IRC topic
* Announce to qutebrowser and qutebrowser-announce mailinglist.
* Post announcement mail to subreddit
+* Post on the website formerly known as Twitter
diff --git a/doc/faq.asciidoc b/doc/faq.asciidoc
index 61f787d3d21..b5edb364696 100644
--- a/doc/faq.asciidoc
+++ b/doc/faq.asciidoc
@@ -255,7 +255,7 @@ Why does it take longer to open a URL in qutebrowser than in chromium?::
loaded until it is detected that there is an instance running
to which the URL is then passed. This takes some time.
One workaround is to use this
- https://github.com/qutebrowser/qutebrowser/blob/master/scripts/open_url_in_instance.sh[script]
+ https://github.com/qutebrowser/qutebrowser/blob/main/scripts/open_url_in_instance.sh[script]
and place it in your $PATH with the name "qutebrowser". This
script passes the URL via a unix socket to qutebrowser (if its
running already) using socat which is much faster and starts a new
diff --git a/doc/help/commands.asciidoc b/doc/help/commands.asciidoc
index 43df2a768ec..1c4c47e7f92 100644
--- a/doc/help/commands.asciidoc
+++ b/doc/help/commands.asciidoc
@@ -40,6 +40,12 @@ possible to run or bind multiple commands by separating them with `;;`.
|<>|Clear all message notifications.
|<>|Click the element matching the given filter.
|<>|Close the current window.
+|<>|Open an editor to modify the current command.
+|<>|Execute a command after some time.
+|<>|Repeat a given command.
+|<>|Repeat the last executed command.
+|<>|Run a command with the given count.
+|<>|Preset the statusbar to some text.
|<>|Set all settings back to their default.
|<>|Cycle an option between multiple values.
|<>|Add a key/value pair to a dictionary option.
@@ -60,7 +66,6 @@ possible to run or bind multiple commands by separating them with `;;`.
|<>|Open the last/[count]th download.
|<>|Remove the last/[count]th download from the list.
|<>|Retry the first failed/[count]th download.
-|<>|Open an editor to modify the current command.
|<>|Open an external editor with the currently selected form field.
|<>|Navigate to a url formed in an external editor.
|<>|Send a fake keypress or key string to the website or qutebrowser.
@@ -75,7 +80,6 @@ possible to run or bind multiple commands by separating them with `;;`.
|<>|Insert text at cursor position.
|<>|Evaluate a JavaScript string.
|<>|Jump to the mark named by `key`.
-|<>|Execute a command after some time.
|<>|Start or stop recording a macro.
|<>|Run a recorded macro.
|<>|Show an error message in the statusbar.
@@ -94,11 +98,8 @@ possible to run or bind multiple commands by separating them with `;;`.
|<>|Save the current page as a quickmark.
|<>|Quit qutebrowser.
|<>|Reload the current/[count]th tab.
-|<>|Repeat a given command.
-|<>|Repeat the last executed command.
|<>|Report a bug in qutebrowser.
|<>|Restart qutebrowser while keeping existing tabs open.
-|<>|Run a command with the given count.
|<>|Save configs and state.
|<>|Take a screenshot of the currently shown part of the page.
|<>|Scroll the current tab in the given direction.
@@ -114,7 +115,6 @@ possible to run or bind multiple commands by separating them with `;;`.
|<>|Load a session.
|<>|Save a session.
|<>|Set an option.
-|<>|Preset the statusbar to some text.
|<>|Set a mark at the current scroll position in the current tab.
|<>|Spawn an external command.
|<>|Stop loading in the current/[count]th tab.
@@ -210,7 +210,7 @@ If no url and title are provided, then save the current page as a bookmark. If a
[[bookmark-del]]
=== bookmark-del
-Syntax: +:bookmark-del ['url']+
+Syntax: +:bookmark-del [*--all*] ['url']+
Delete a bookmark.
@@ -218,6 +218,9 @@ Delete a bookmark.
* +'url'+: The url of the bookmark to delete. If not given, use the current page's url.
+==== optional arguments
+* +*-a*+, +*--all*+: If given, delete all bookmarks.
+
==== note
* This command does not split arguments after the last argument and handles quotes literally.
@@ -287,6 +290,96 @@ The given filter needs to result in exactly one element, otherwise, an error is
=== close
Close the current window.
+[[cmd-edit]]
+=== cmd-edit
+Syntax: +:cmd-edit [*--run*]+
+
+Open an editor to modify the current command.
+
+==== optional arguments
+* +*-r*+, +*--run*+: Run the command if the editor exits successfully.
+
+[[cmd-later]]
+=== cmd-later
+Syntax: +:cmd-later 'duration' 'command'+
+
+Execute a command after some time.
+
+==== positional arguments
+* +'duration'+: Duration to wait in format XhYmZs or a number for milliseconds.
+* +'command'+: The command to run, with optional args.
+
+==== note
+* This command does not split arguments after the last argument and handles quotes literally.
+* With this command, +;;+ is interpreted literally instead of splitting off a second command.
+* This command does not replace variables like +\{url\}+.
+
+[[cmd-repeat]]
+=== cmd-repeat
+Syntax: +:cmd-repeat 'times' 'command'+
+
+Repeat a given command.
+
+==== positional arguments
+* +'times'+: How many times to repeat.
+* +'command'+: The command to run, with optional args.
+
+==== count
+Multiplies with 'times' when given.
+
+==== note
+* This command does not split arguments after the last argument and handles quotes literally.
+* With this command, +;;+ is interpreted literally instead of splitting off a second command.
+* This command does not replace variables like +\{url\}+.
+
+[[cmd-repeat-last]]
+=== cmd-repeat-last
+Repeat the last executed command.
+
+==== count
+Which count to pass the command.
+
+[[cmd-run-with-count]]
+=== cmd-run-with-count
+Syntax: +:cmd-run-with-count 'count-arg' 'command'+
+
+Run a command with the given count.
+
+If cmd_run_with_count itself is run with a count, it multiplies count_arg.
+
+==== positional arguments
+* +'count-arg'+: The count to pass to the command.
+* +'command'+: The command to run, with optional args.
+
+==== count
+The count that run_with_count itself received.
+
+==== note
+* This command does not split arguments after the last argument and handles quotes literally.
+* With this command, +;;+ is interpreted literally instead of splitting off a second command.
+* This command does not replace variables like +\{url\}+.
+
+[[cmd-set-text]]
+=== cmd-set-text
+Syntax: +:cmd-set-text [*--space*] [*--append*] [*--run-on-count*] 'text'+
+
+Preset the statusbar to some text.
+
+==== positional arguments
+* +'text'+: The commandline to set.
+
+==== optional arguments
+* +*-s*+, +*--space*+: If given, a space is added to the end.
+* +*-a*+, +*--append*+: If given, the text is appended to the current text.
+* +*-r*+, +*--run-on-count*+: If given with a count, the command is run with the given count rather than setting the command text.
+
+
+==== count
+The count if given.
+
+==== note
+* This command does not split arguments after the last argument and handles quotes literally.
+
[[config-clear]]
=== config-clear
Syntax: +:config-clear [*--save*]+
@@ -518,15 +611,6 @@ Retry the first failed/[count]th download.
==== count
The index of the download to retry.
-[[edit-command]]
-=== edit-command
-Syntax: +:edit-command [*--run*]+
-
-Open an editor to modify the current command.
-
-==== optional arguments
-* +*-r*+, +*--run*+: Run the command if the editor exits successfully.
-
[[edit-text]]
=== edit-text
Open an external editor with the currently selected form field.
@@ -786,21 +870,6 @@ Jump to the mark named by `key`.
==== positional arguments
* +'key'+: mark identifier; capital indicates a global mark
-[[later]]
-=== later
-Syntax: +:later 'duration' 'command'+
-
-Execute a command after some time.
-
-==== positional arguments
-* +'duration'+: Duration to wait in format XhYmZs or a number for milliseconds.
-* +'command'+: The command to run, with optional args.
-
-==== note
-* This command does not split arguments after the last argument and handles quotes literally.
-* With this command, +;;+ is interpreted literally instead of splitting off a second command.
-* This command does not replace variables like +\{url\}+.
-
[[macro-record]]
=== macro-record
Syntax: +:macro-record ['register']+
@@ -1006,7 +1075,7 @@ You can view all saved quickmarks on the link:qute://bookmarks[bookmarks page].
[[quickmark-del]]
=== quickmark-del
-Syntax: +:quickmark-del ['name']+
+Syntax: +:quickmark-del [*--all*] ['name']+
Delete a quickmark.
@@ -1015,6 +1084,9 @@ Delete a quickmark.
if there are more than one).
+==== optional arguments
+* +*-a*+, +*--all*+: Delete all quickmarks.
+
==== note
* This command does not split arguments after the last argument and handles quotes literally.
@@ -1064,31 +1136,6 @@ Reload the current/[count]th tab.
==== count
The tab index to reload.
-[[repeat]]
-=== repeat
-Syntax: +:repeat 'times' 'command'+
-
-Repeat a given command.
-
-==== positional arguments
-* +'times'+: How many times to repeat.
-* +'command'+: The command to run, with optional args.
-
-==== count
-Multiplies with 'times' when given.
-
-==== note
-* This command does not split arguments after the last argument and handles quotes literally.
-* With this command, +;;+ is interpreted literally instead of splitting off a second command.
-* This command does not replace variables like +\{url\}+.
-
-[[repeat-command]]
-=== repeat-command
-Repeat the last executed command.
-
-==== count
-Which count to pass the command.
-
[[report]]
=== report
Syntax: +:report ['info'] ['contact']+
@@ -1104,26 +1151,6 @@ Report a bug in qutebrowser.
=== restart
Restart qutebrowser while keeping existing tabs open.
-[[run-with-count]]
-=== run-with-count
-Syntax: +:run-with-count 'count-arg' 'command'+
-
-Run a command with the given count.
-
-If run_with_count itself is run with a count, it multiplies count_arg.
-
-==== positional arguments
-* +'count-arg'+: The count to pass to the command.
-* +'command'+: The command to run, with optional args.
-
-==== count
-The count that run_with_count itself received.
-
-==== note
-* This command does not split arguments after the last argument and handles quotes literally.
-* With this command, +;;+ is interpreted literally instead of splitting off a second command.
-* This command does not replace variables like +\{url\}+.
-
[[save]]
=== save
Syntax: +:save ['what' ...]+
@@ -1155,7 +1182,7 @@ Syntax: +:scroll 'direction'+
Scroll the current tab in the given direction.
-Note you can use `:run-with-count` to have a keybinding with a bigger scroll increment.
+Note you can use `:cmd-run-with-count` to have a keybinding with a bigger scroll increment.
==== positional arguments
* +'direction'+: In which direction to scroll (up/down/left/right/top/bottom).
@@ -1322,27 +1349,6 @@ If the option name ends with '?' or no value is provided, the value of the optio
* +*-p*+, +*--print*+: Print the value after setting.
* +*-u*+, +*--pattern*+: The link:configuring{outfilesuffix}#patterns[URL pattern] to use.
-[[set-cmd-text]]
-=== set-cmd-text
-Syntax: +:set-cmd-text [*--space*] [*--append*] [*--run-on-count*] 'text'+
-
-Preset the statusbar to some text.
-
-==== positional arguments
-* +'text'+: The commandline to set.
-
-==== optional arguments
-* +*-s*+, +*--space*+: If given, a space is added to the end.
-* +*-a*+, +*--append*+: If given, the text is appended to the current text.
-* +*-r*+, +*--run-on-count*+: If given with a count, the command is run with the given count rather than setting the command text.
-
-
-==== count
-The count if given.
-
-==== note
-* This command does not split arguments after the last argument and handles quotes literally.
-
[[set-mark]]
=== set-mark
Syntax: +:set-mark 'key'+
diff --git a/doc/help/index.asciidoc b/doc/help/index.asciidoc
index 127cc5d864b..4f2b009c757 100644
--- a/doc/help/index.asciidoc
+++ b/doc/help/index.asciidoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
qutebrowser help
================
@@ -6,7 +8,7 @@ Documentation
The following help pages are currently available:
-* link:https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/cheatsheet-big.png[Key binding cheatsheet]
+* link:https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/cheatsheet-big.png[Key binding cheatsheet]
* link:../quickstart{outfilesuffix}[Quick start guide]
* link:../faq{outfilesuffix}[Frequently asked questions]
* link:../changelog{outfilesuffix}[Change Log]
diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc
index 9547cf24c3c..611f2f98b1d 100644
--- a/doc/help/settings.asciidoc
+++ b/doc/help/settings.asciidoc
@@ -118,13 +118,10 @@
|<>|Which algorithm to use for modifying how colors are rendered with darkmode.
|<>|Contrast for dark mode.
|<>|Render all web contents using a dark theme.
-|<>|Render all colors as grayscale.
-|<>|Desaturation factor for images in dark mode.
-|<>|Increase text contrast by drawing an outline of the uninverted color.
|<>|Which images to apply dark mode to.
|<>|Which pages to apply dark mode to.
|<>|Threshold for inverting background elements with dark mode.
-|<>|Threshold for inverting text with dark mode.
+|<>|Threshold for inverting text with dark mode.
|<>|Value to use for `prefers-color-scheme:` for websites.
|<>|Number of commands to save in the command history.
|<>|Delay (in milliseconds) before updating completions after typing a character.
@@ -174,6 +171,7 @@
|<>|Allow JavaScript to open new tabs without user interaction.
|<>|Allow JavaScript to read from or write to the clipboard.
|<>|Enable JavaScript.
+|<>|Enables the legacy touch event feature.
|<>|Log levels to use for JavaScript console logging messages.
|<>|Javascript messages to *not* show in the UI, despite a corresponding `content.javascript.log_message.levels` setting.
|<>|Javascript message sources/levels to show in the qutebrowser UI.
@@ -303,6 +301,7 @@
|<>|Force a Qt platformtheme to use.
|<>|Force software rendering for QtWebEngine.
|<>|Turn on Qt HighDPI scaling.
+|<>|Disable accelerated 2d canvas to avoid graphical glitches.
|<>|Work around locale parsing issues in QtWebEngine 5.15.3.
|<>|Delete the QtWebEngine Service Worker directory on every start.
|<>|When/how to show the scrollbar.
@@ -570,9 +569,9 @@ Default:
* +pass:[']+: +pass:[mode-enter jump_mark]+
* +pass:[+]+: +pass:[zoom-in]+
* +pass:[-]+: +pass:[zoom-out]+
-* +pass:[.]+: +pass:[repeat-command]+
-* +pass:[/]+: +pass:[set-cmd-text /]+
-* +pass:[:]+: +pass:[set-cmd-text :]+
+* +pass:[.]+: +pass:[cmd-repeat-last]+
+* +pass:[/]+: +pass:[cmd-set-text /]+
+* +pass:[:]+: +pass:[cmd-set-text :]+
* +pass:[;I]+: +pass:[hint images tab]+
* +pass:[;O]+: +pass:[hint links fill :open -t -r {hint-url}]+
* +pass:[;R]+: +pass:[hint --rapid links window]+
@@ -628,9 +627,9 @@ Default:
* +pass:[<back>]+: +pass:[back]+
* +pass:[<forward>]+: +pass:[forward]+
* +pass:[=]+: +pass:[zoom]+
-* +pass:[?]+: +pass:[set-cmd-text ?]+
+* +pass:[?]+: +pass:[cmd-set-text ?]+
* +pass:[@]+: +pass:[macro-run]+
-* +pass:[B]+: +pass:[set-cmd-text -s :quickmark-load -t]+
+* +pass:[B]+: +pass:[cmd-set-text -s :quickmark-load -t]+
* +pass:[D]+: +pass:[tab-close -o]+
* +pass:[F]+: +pass:[hint all tab]+
* +pass:[G]+: +pass:[scroll-to-perc]+
@@ -640,7 +639,7 @@ Default:
* +pass:[L]+: +pass:[forward]+
* +pass:[M]+: +pass:[bookmark-add]+
* +pass:[N]+: +pass:[search-prev]+
-* +pass:[O]+: +pass:[set-cmd-text -s :open -t]+
+* +pass:[O]+: +pass:[cmd-set-text -s :open -t]+
* +pass:[PP]+: +pass:[open -t -- {primary}]+
* +pass:[Pp]+: +pass:[open -t -- {clipboard}]+
* +pass:[R]+: +pass:[reload -f]+
@@ -648,7 +647,7 @@ Default:
* +pass:[Sh]+: +pass:[history]+
* +pass:[Sq]+: +pass:[bookmark-list]+
* +pass:[Ss]+: +pass:[set]+
-* +pass:[T]+: +pass:[set-cmd-text -sr :tab-focus]+
+* +pass:[T]+: +pass:[cmd-set-text -sr :tab-focus]+
* +pass:[U]+: +pass:[undo -w]+
* +pass:[V]+: +pass:[mode-enter caret ;; selection-toggle --line]+
* +pass:[ZQ]+: +pass:[quit]+
@@ -657,30 +656,30 @@ Default:
* +pass:[\]\]]+: +pass:[navigate next]+
* +pass:[`]+: +pass:[mode-enter set_mark]+
* +pass:[ad]+: +pass:[download-cancel]+
-* +pass:[b]+: +pass:[set-cmd-text -s :quickmark-load]+
+* +pass:[b]+: +pass:[cmd-set-text -s :quickmark-load]+
* +pass:[cd]+: +pass:[download-clear]+
* +pass:[co]+: +pass:[tab-only]+
* +pass:[d]+: +pass:[tab-close]+
* +pass:[f]+: +pass:[hint]+
* +pass:[g$]+: +pass:[tab-focus -1]+
* +pass:[g0]+: +pass:[tab-focus 1]+
-* +pass:[gB]+: +pass:[set-cmd-text -s :bookmark-load -t]+
+* +pass:[gB]+: +pass:[cmd-set-text -s :bookmark-load -t]+
* +pass:[gC]+: +pass:[tab-clone]+
* +pass:[gD]+: +pass:[tab-give]+
* +pass:[gJ]+: +pass:[tab-move +]+
* +pass:[gK]+: +pass:[tab-move -]+
-* +pass:[gO]+: +pass:[set-cmd-text :open -t -r {url:pretty}]+
+* +pass:[gO]+: +pass:[cmd-set-text :open -t -r {url:pretty}]+
* +pass:[gU]+: +pass:[navigate up -t]+
* +pass:[g^]+: +pass:[tab-focus 1]+
* +pass:[ga]+: +pass:[open -t]+
-* +pass:[gb]+: +pass:[set-cmd-text -s :bookmark-load]+
+* +pass:[gb]+: +pass:[cmd-set-text -s :bookmark-load]+
* +pass:[gd]+: +pass:[download]+
* +pass:[gf]+: +pass:[view-source]+
* +pass:[gg]+: +pass:[scroll-to-perc 0]+
* +pass:[gi]+: +pass:[hint inputs --first]+
* +pass:[gm]+: +pass:[tab-move]+
-* +pass:[go]+: +pass:[set-cmd-text :open {url:pretty}]+
-* +pass:[gt]+: +pass:[set-cmd-text -s :tab-select]+
+* +pass:[go]+: +pass:[cmd-set-text :open {url:pretty}]+
+* +pass:[gt]+: +pass:[cmd-set-text -s :tab-select]+
* +pass:[gu]+: +pass:[navigate up]+
* +pass:[h]+: +pass:[scroll left]+
* +pass:[i]+: +pass:[mode-enter insert]+
@@ -689,15 +688,15 @@ Default:
* +pass:[l]+: +pass:[scroll right]+
* +pass:[m]+: +pass:[quickmark-save]+
* +pass:[n]+: +pass:[search-next]+
-* +pass:[o]+: +pass:[set-cmd-text -s :open]+
+* +pass:[o]+: +pass:[cmd-set-text -s :open]+
* +pass:[pP]+: +pass:[open -- {primary}]+
* +pass:[pp]+: +pass:[open -- {clipboard}]+
* +pass:[q]+: +pass:[macro-record]+
* +pass:[r]+: +pass:[reload]+
* +pass:[sf]+: +pass:[save]+
-* +pass:[sk]+: +pass:[set-cmd-text -s :bind]+
-* +pass:[sl]+: +pass:[set-cmd-text -s :set -t]+
-* +pass:[ss]+: +pass:[set-cmd-text -s :set]+
+* +pass:[sk]+: +pass:[cmd-set-text -s :bind]+
+* +pass:[sl]+: +pass:[cmd-set-text -s :set -t]+
+* +pass:[ss]+: +pass:[cmd-set-text -s :set]+
* +pass:[tCH]+: +pass:[config-cycle -p -u *://*.{url:host}/* content.cookies.accept all no-3rdparty never ;; reload]+
* +pass:[tCh]+: +pass:[config-cycle -p -u *://{url:host}/* content.cookies.accept all no-3rdparty never ;; reload]+
* +pass:[tCu]+: +pass:[config-cycle -p -u {url} content.cookies.accept all no-3rdparty never ;; reload]+
@@ -726,24 +725,24 @@ Default:
* +pass:[tsu]+: +pass:[config-cycle -p -t -u {url} content.javascript.enabled ;; reload]+
* +pass:[u]+: +pass:[undo]+
* +pass:[v]+: +pass:[mode-enter caret]+
-* +pass:[wB]+: +pass:[set-cmd-text -s :bookmark-load -w]+
+* +pass:[wB]+: +pass:[cmd-set-text -s :bookmark-load -w]+
* +pass:[wIf]+: +pass:[devtools-focus]+
* +pass:[wIh]+: +pass:[devtools left]+
* +pass:[wIj]+: +pass:[devtools bottom]+
* +pass:[wIk]+: +pass:[devtools top]+
* +pass:[wIl]+: +pass:[devtools right]+
* +pass:[wIw]+: +pass:[devtools window]+
-* +pass:[wO]+: +pass:[set-cmd-text :open -w {url:pretty}]+
+* +pass:[wO]+: +pass:[cmd-set-text :open -w {url:pretty}]+
* +pass:[wP]+: +pass:[open -w -- {primary}]+
-* +pass:[wb]+: +pass:[set-cmd-text -s :quickmark-load -w]+
+* +pass:[wb]+: +pass:[cmd-set-text -s :quickmark-load -w]+
* +pass:[wf]+: +pass:[hint all window]+
* +pass:[wh]+: +pass:[back -w]+
* +pass:[wi]+: +pass:[devtools]+
* +pass:[wl]+: +pass:[forward -w]+
-* +pass:[wo]+: +pass:[set-cmd-text -s :open -w]+
+* +pass:[wo]+: +pass:[cmd-set-text -s :open -w]+
* +pass:[wp]+: +pass:[open -w -- {clipboard}]+
-* +pass:[xO]+: +pass:[set-cmd-text :open -b -r {url:pretty}]+
-* +pass:[xo]+: +pass:[set-cmd-text -s :open -b]+
+* +pass:[xO]+: +pass:[cmd-set-text :open -b -r {url:pretty}]+
+* +pass:[xo]+: +pass:[cmd-set-text -s :open -b]+
* +pass:[yD]+: +pass:[yank domain -s]+
* +pass:[yM]+: +pass:[yank inline [{title}\]({url}) -s]+
* +pass:[yP]+: +pass:[yank pretty-url -s]+
@@ -1696,22 +1695,11 @@ Default: +pass:[0.0]+
=== colors.webpage.darkmode.enabled
Render all web contents using a dark theme.
Example configurations from Chromium's `chrome://flags`:
-
- "With simple HSL/CIELAB/RGB-based inversion": Set
- `colors.webpage.darkmode.algorithm` accordingly.
-
-- "With selective image inversion": Set
- `colors.webpage.darkmode.policy.images` to `smart`.
-
-- "With selective inversion of non-image elements": Set
- `colors.webpage.darkmode.threshold.text` to 150 and
- `colors.webpage.darkmode.threshold.background` to 205.
-
-- "With selective inversion of everything": Combines the two variants
- above.
+ `colors.webpage.darkmode.algorithm` accordingly, and
+ set `colors.webpage.darkmode.policy.images` to `never`.
-- "With increased text contrast": Set
- `colors.webpage.darkmode.increase_text_contrast` (QtWebEngine 6.3+)
+- "With selective image inversion": qutebrowser default settings.
This setting requires a restart.
@@ -1721,50 +1709,9 @@ Type: <>
Default: +pass:[false]+
-[[colors.webpage.darkmode.grayscale.all]]
-=== colors.webpage.darkmode.grayscale.all
-Render all colors as grayscale.
-This only has an effect when `colors.webpage.darkmode.algorithm` is set to `lightness-hsl` or `brightness-rgb`.
-
-This setting requires a restart.
-
-This setting is only available with the QtWebEngine backend.
-
-Type: <>
-
-Default: +pass:[false]+
-
-[[colors.webpage.darkmode.grayscale.images]]
-=== colors.webpage.darkmode.grayscale.images
-Desaturation factor for images in dark mode.
-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.
-
-This setting requires a restart.
-
-This setting is only available with the QtWebEngine backend.
-
-Type: <>
-
-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: <>
-
-Default: +pass:[false]+
-
[[colors.webpage.darkmode.policy.images]]
=== colors.webpage.darkmode.policy.images
Which images to apply dark mode to.
-With QtWebEngine 5.15.0, this setting can cause frequent renderer process crashes due to a https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/304211[bug in Qt].
This setting requires a restart.
@@ -1777,6 +1724,7 @@ Valid values:
* +always+: Apply dark mode filter to all images.
* +never+: Never apply dark mode filter to any images.
* +smart+: Apply dark mode based on image content. Not available with Qt 5.15.0.
+ * +smart-simple+: On QtWebEngine 6.6, use a simpler algorithm for smart mode (based on numbers of colors and transparency), rather than an ML-based model. Same as 'smart' on older QtWebEnigne versions.
Default: +pass:[smart]+
@@ -1802,7 +1750,7 @@ Default: +pass:[smart]+
=== colors.webpage.darkmode.threshold.background
Threshold for inverting background elements with dark mode.
Background elements with brightness above this threshold will be inverted, and below it will be left as in the original, non-dark-mode page. Set to 256 to never invert the color or to 0 to always invert it.
-Note: This behavior is the opposite of `colors.webpage.darkmode.threshold.text`!
+Note: This behavior is the opposite of `colors.webpage.darkmode.threshold.foreground`!
This setting requires a restart.
@@ -1812,8 +1760,8 @@ Type: <>
Default: +pass:[0]+
-[[colors.webpage.darkmode.threshold.text]]
-=== colors.webpage.darkmode.threshold.text
+[[colors.webpage.darkmode.threshold.foreground]]
+=== colors.webpage.darkmode.threshold.foreground
Threshold for inverting text with dark mode.
Text colors with brightness below this threshold will be inverted, and 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.
@@ -2154,8 +2102,9 @@ Default: empty
=== content.canvas_reading
Allow websites to read canvas elements.
Note this is needed for some websites to work properly.
+On QtWebEngine < 6.6, this setting requires a restart and does not support URL patterns, only the global setting is applied.
-This setting requires a restart.
+This setting supports link:configuring{outfilesuffix}#patterns[URL patterns].
This setting is only available with the QtWebEngine backend.
@@ -2433,6 +2382,27 @@ Type: <>
Default: +pass:[true]+
+[[content.javascript.legacy_touch_events]]
+=== content.javascript.legacy_touch_events
+Enables the legacy touch event feature.
+This affects JS APIs such as:
+- ontouch* members on window, document, Element - document.createTouch, document.createTouchList - document.createEvent("TouchEvent")
+Newer Chromium versions have those disabled by default: https://bugs.chromium.org/p/chromium/issues/detail?id=392584 https://groups.google.com/a/chromium.org/g/blink-dev/c/KV6kqDJpYiE
+
+This setting requires a restart.
+
+This setting is only available with the QtWebEngine backend.
+
+Type: <>
+
+Valid values:
+
+ * +always+: Legacy touch events are always enabled. This might cause some websites to assume a mobile device.
+ * +auto+: Legacy touch events are only enabled if a touch screen was detected on startup.
+ * +never+: Legacy touch events are always disabled.
+
+Default: +pass:[never]+
+
[[content.javascript.log]]
=== content.javascript.log
Log levels to use for JavaScript console logging messages.
@@ -4017,6 +3987,26 @@ Type: <>
Default: +pass:[false]+
+[[qt.workarounds.disable_accelerated_2d_canvas]]
+=== qt.workarounds.disable_accelerated_2d_canvas
+Disable accelerated 2d canvas to avoid graphical glitches.
+On some setups graphical issues can occur on sites like Google sheets and PDF.js. These don't occur when accelerated 2d canvas is turned off, so we do that by default.
+So far these glitches only occur on some Intel graphics devices.
+
+This setting requires a restart.
+
+This setting is only available with the QtWebEngine backend.
+
+Type: <>
+
+Valid values:
+
+ * +always+: Disable accelerated 2d canvas
+ * +auto+: Disable on Qt6 < 6.6.0, enable otherwise
+ * +never+: Enable accelerated 2d canvas
+
+Default: +pass:[auto]+
+
[[qt.workarounds.locale]]
=== qt.workarounds.locale
Work around locale parsing issues in QtWebEngine 5.15.3.
diff --git a/doc/install.asciidoc b/doc/install.asciidoc
index 63c6e95fc7f..ec53e2fb50c 100644
--- a/doc/install.asciidoc
+++ b/doc/install.asciidoc
@@ -21,73 +21,50 @@ some distributions (notably, Debian Stable and Ubuntu) do only update
qutebrowser and the underlying QtWebEngine when there's a new release of the
distribution, typically once all couple of months to years.
-On Debian / Ubuntu
-------------------
+[[debian]]
+On Debian / Ubuntu / Linux Mint / ...
+-------------------------------------
-How to install qutebrowser depends a lot on the version of Debian/Ubuntu you're
-running.
-
-[[ubuntu1604]]
-Debian Stretch / Ubuntu 16.04 LTS / Linux Mint 18
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Debian Stretch does have QtWebEngine packaged, but only in a very old and insecure
-version (Qt 5.7, based on a Chromium from March 2016). Furthermore, it packages Python
-3.5 which is not supported anymore since qutebrowser v2.0.0.
-
-Ubuntu 16.04 doesn't come with an up-to-date engine (a new enough QtWebKit, or
-QtWebEngine) and also comes with Python 3.5.
-
-You should be able to install a newer Python (3.8+) using the
-https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa[deadsnakes PPA] or
-https://github.com/pyenv/pyenv[pyenv], and then proceed to
-<>. However, this is currently untested. If you
-got this setup to work successfully, please submit a pull request to adjust these
-instructions!
-
-Note you'll need some basic libraries to use the virtualenv-installed PyQt:
+With those distributions, qutebrowser is in the official repositories, and you
+can install it with `apt install qutebrowser`.
-----
-# apt install --no-install-recommends git ca-certificates python3 python3-venv libglib2.0-0 libgl1 libfontconfig1 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 libxkbcommon-x11-0 libdbus-1-3 libyaml-dev gcc python3-dev libnss3 libasound2
-----
+However, when using a stable variant (e.g. Debian Stable / Ubuntu LTS / Linux
+Mint), note that your versions of qutebrowser and the underlying QtWebEngine
+will only be updated when there's a new release of your distribution (e.g.
+upgrading from Ubuntu 22.04 to 24.04):
-// FIXME not needed anymore?
-// libxi6 libxrender1 libegl1-mesa
+- Ubuntu 20.04, Linux Mint 20: qutebrowser 1.10.1, QtWebEngine 5.12.8 (based on Chromium 69 from 2018)
+- Ubuntu 22.04, Linux Mint 21: qutebrowser 2.5.0, QtWebEngine 5.15.9 (based on Chromium 87 from 2020)
+- Debian Bookworm: qutebrowser 2.5.3, QtWebEngine 5.15.13 (based on Chromium 87 from 2020)
-Debian Buster / Ubuntu 18.04 LTS / Linux Mint 19
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The old versions of the underlying Chromium will lead to various compatibility
+issues. Additionally, QtWebEngine on all Debian-based distributions is
+https://www.debian.org/releases/bookworm/amd64/release-notes/ch-information.en.html#browser-security[not covered]
+by Debian's security support.
-Debian Buster packages qutebrowser, but ships a very old version (v1.6.1 from March
-2019). The QtWebEngine library used for rendering web contents is also very old (Qt
-5.11, based on a Chromium from March 2018) and insecure. It is
-https://www.debian.org/releases/buster/amd64/release-notes/ch-information.en.html#browser-security[not covered]
-by Debian's security patches. It's recommended to <> with a newer PyQt/Qt binary instead.
+It's recommended to <> with a newer PyQt/Qt binary instead.
+If you need proprietary codec support or use an architecture not supported by Qt
+binaries, starting with Ubuntu 22.04 and Debian Bookworm, it's possible to
+install Qt 6 via apt. By using `mkvenv.py` with `--pyqt-type link` you get a
+newer qutebrowser running with:
-With Ubuntu 18.04, the situation looks similar (but worse): There, qutebrowser v1.1.1
-from January 2018 is packaged, with QtWebEngine 5.9 based on a Chromium from January
-2017. It's recommended to either upgrade to Ubuntu 20.04 LTS or <> with a newer PyQt/Qt binary instead.
+- Ubuntu 22.04, Linux Mint 21: QtWebEngine 6.2.4 (based on Chromium 90 from mid-2021)
+- Debian Bookworm: QtWebEngine 6.4.2 (based on Chromium 102 from mid-2022)
Note you'll need some basic libraries to use the virtualenv-installed PyQt:
----
-# apt install --no-install-recommends git ca-certificates python3 python3-venv libglib2.0-0 libgl1 libfontconfig1 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 libxkbcommon-x11-0 libdbus-1-3 libyaml-dev gcc python3-dev libnss3 libasound2
-----
-
-Ubuntu 20.04 LTS / Linux Mint 20 (or newer)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-With those distributions, qutebrowser is in the official repositories, and you
-can install it with apt:
-
-----
-# apt install qutebrowser
+# apt install --no-install-recommends git ca-certificates python3 python3-venv libgl1 libxkbcommon-x11-0 libegl1-mesa libfontconfig1 libglib2.0-0 libdbus-1-3 libxcb-cursor0 libxcb-icccm4 libxcb-keysyms1 libxcb-shape0 libnss3 libxcomposite1 libxdamage1 libxrender1 libxrandr2 libxtst6 libxi6 libasound2
----
Additional hints
~~~~~~~~~~~~~~~~
+- On Ubuntu 20.04 / Linux Mint 20 / Debian Bullseye, no OpenSSL 3 is available.
+ However, Qt 6.5 https://www.qt.io/blog/moving-to-openssl-3-in-binary-builds-starting-from-qt-6.5-beta-2[moved to OpenSSL 3]
+ for its binary builds. Thus, you will either need to live with
+ `:adblock-update` and `:download` being broken, or use `--pyqt-version 6.4` for
+ the `mkvenv.py` script to get an older Qt.
- If running from git, run the following to generate the documentation for the
`:help` command (the `mkvenv.py` script used with a virtualenv install already does
this for you):
@@ -98,7 +75,7 @@ $ python3 scripts/asciidoc2html.py
----
- If you prefer using QtWebKit, there's QtWebKit 5.212 available in
- Ubuntu 18.04 / Debian Buster or newer. Note however that it is based on an upstream
+ those distributions. Note however that it is based on an upstream
WebKit from September 2016 with known security issues and no sandboxing or process
isolation.
- If video or sound don't work with QtWebKit, try installing the gstreamer plugins:
@@ -130,6 +107,8 @@ For more information see https://rpmfusion.org/Configuration.
# dnf install qt5-qtwebengine-freeworld
-----
+It's currently unknown what the Qt 6 equivalent of this is.
+
On Archlinux
------------
@@ -388,7 +367,7 @@ qutebrowser from source.
==== Homebrew
----
-$ brew install pyqt@5
+$ brew install pyqt@6
$ pip3 install qutebrowser
----
@@ -396,7 +375,7 @@ Packagers
---------
qutebrowser ships with a
-https://github.com/qutebrowser/qutebrowser/blob/master/misc/Makefile[Makefile]
+https://github.com/qutebrowser/qutebrowser/blob/main/misc/Makefile[Makefile]
intended for packagers. This installs system-wide files in a proper locations,
so it should be preferred to the usual `setup.py install` or `pip install`
invocation.
@@ -436,7 +415,7 @@ Installing dependencies (including Qt)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using a Qt installed via virtualenv needs a couple of system-wide libraries.
-See the <> for details about which libraries
+See the <> for details about which libraries
are required.
Then run the install script:
diff --git a/doc/quickstart.asciidoc b/doc/quickstart.asciidoc
index 1b513a371d0..733ef7ad4df 100644
--- a/doc/quickstart.asciidoc
+++ b/doc/quickstart.asciidoc
@@ -23,9 +23,9 @@ Basic keybindings to get you started
What to do now
--------------
-* View the link:https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/cheatsheet-big.png[key binding cheatsheet]
+* View the link:https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/cheatsheet-big.png[key binding cheatsheet]
to make yourself familiar with the key bindings: +
-image:https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/cheatsheet-small.png["qutebrowser key binding cheatsheet",link="https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/cheatsheet-big.png"]
+image:https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/cheatsheet-small.png["qutebrowser key binding cheatsheet",link="https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/cheatsheet-big.png"]
* There's also a https://www.shortcutfoo.com/app/dojos/qutebrowser[free training
course] on shortcutfoo for the keybindings - note that you need to be in
insert mode (i) for it to work.
@@ -63,11 +63,11 @@ qutebrowser, funded by donations.
To sustain this for a long time, your help is needed! Check the
https://github.com/sponsors/The-Compiler/[GitHub Sponsors page] or
-https://github.com/qutebrowser/qutebrowser/blob/master/README.asciidoc#donating[alternative
+https://github.com/qutebrowser/qutebrowser/blob/main/README.asciidoc#donating[alternative
donation methods] for more information. Depending on your sign-up date and how
long you keep a certain level, you can get qutebrowser t-shirts, stickers and
more!
Alternatively, there are also various options available for one-time donations, see the
-https://github.com/qutebrowser/qutebrowser/blob/master/README.asciidoc#donating[donation section]
+https://github.com/qutebrowser/qutebrowser/blob/main/README.asciidoc#donating[donation section]
in the README for details.
diff --git a/doc/qutebrowser.1.asciidoc b/doc/qutebrowser.1.asciidoc
index 1a340f7e957..c96f7673fb3 100644
--- a/doc/qutebrowser.1.asciidoc
+++ b/doc/qutebrowser.1.asciidoc
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// Note some sections in this file (everything between QUTE_*_START and
// QUTE_*_END) are autogenerated by scripts/src2asciidoc.sh. DO NOT edit them
// by hand.
diff --git a/misc/Makefile b/misc/Makefile
index 62294ba6151..39a7e005f73 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -4,6 +4,7 @@ ICONSIZES = 16 24 32 48 64 128 256 512
DATAROOTDIR = $(PREFIX)/share
DATADIR ?= $(DATAROOTDIR)
MANDIR ?= $(DATAROOTDIR)/man
+A2X ?= a2x
ifdef DESTDIR
SETUPTOOLSOPTS = --root="$(DESTDIR)"
@@ -14,7 +15,7 @@ all: man
man: doc/qutebrowser.1
doc/qutebrowser.1: doc/qutebrowser.1.asciidoc
- a2x -f manpage $<
+ $(A2X) -f manpage $<
install: man
$(PYTHON) setup.py install --prefix="$(PREFIX)" --optimize=1 $(SETUPTOOLSOPTS)
diff --git a/misc/nsis/install.nsh b/misc/nsis/install.nsh
index 8233ab5f09b..282a254ebe7 100755
--- a/misc/nsis/install.nsh
+++ b/misc/nsis/install.nsh
@@ -1,19 +1,6 @@
-# Copyright 2018 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# NSIS installer header. Uses NsisMultiUser plugin and contains portions of
# its demo code, copyright 2017 Richard Drizin, Alex Mitev.
@@ -443,8 +430,37 @@ SectionEnd
; Callbacks
Function .onInit
StrCpy $KeepReg 1
- !insertmacro CheckPlatform ${PLATFORM}
- !insertmacro CheckMinWinVer ${MIN_WIN_VER}
+
+; OS version check
+ ${If} ${RunningX64}
+ ; https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoa#remarks
+ GetWinVer $R0 Major
+ !if "${QT5}" == "True"
+ IntCmpU $R0 6 0 _os_check_fail _os_check_pass
+ GetWinVer $R1 Minor
+ IntCmpU $R1 2 _os_check_pass _os_check_fail _os_check_pass
+ !else
+ IntCmpU $R0 10 0 _os_check_fail _os_check_pass
+ GetWinVer $R1 Build
+ ${If} $R1 >= 22000 ; Windows 11 21H2
+ Goto _os_check_pass
+ ${ElseIf} $R1 >= 14393 ; Windows 10 1607
+ ${AndIf} ${IsNativeAMD64} ; Windows 10 has no x86_64 emulation on arm64
+ Goto _os_check_pass
+ ${EndIf}
+ !endif
+ ${EndIf}
+ _os_check_fail:
+ !if "${QT5}" == "True"
+ MessageBox MB_OK|MB_ICONSTOP "This version of ${PRODUCT_NAME} requires a 64-bit$\r$\n\
+ version of Windows 8 or later."
+ !else
+ MessageBox MB_OK|MB_ICONSTOP "This version of ${PRODUCT_NAME} requires a 64-bit$\r$\n\
+ version of Windows 10 1607 or later."
+ !endif
+ Abort
+ _os_check_pass:
+
${ifnot} ${UAC_IsInnerInstance}
!insertmacro CheckSingleInstance "Setup" "Global" "${SETUP_MUTEX}"
!insertmacro CheckSingleInstance "Application" "Local" "${APP_MUTEX}"
diff --git a/misc/nsis/install_pages.nsh b/misc/nsis/install_pages.nsh
index c3cf973dfa5..ecea32fe5e6 100755
--- a/misc/nsis/install_pages.nsh
+++ b/misc/nsis/install_pages.nsh
@@ -1,19 +1,6 @@
-# Copyright 2018 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# NSIS pages header. Uses NsisMultiUser plugin and contains portions of
# its demo code, copyright 2017 Richard Drizin, Alex Mitev.
diff --git a/misc/nsis/qutebrowser.nsi b/misc/nsis/qutebrowser.nsi
index 7623d8cb271..bd5156e8313 100755
--- a/misc/nsis/qutebrowser.nsi
+++ b/misc/nsis/qutebrowser.nsi
@@ -1,20 +1,7 @@
-# Copyright 2018 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
# encoding: iso-8859-1
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# NSIS installer script. Uses NsisMultiUser plugin and contains portions of
# its demo code, copyright 2017 Richard Drizin, Alex Mitev.
@@ -137,13 +124,16 @@ ShowUninstDetails hide
; If not defined, get VERSION from PROGEXE. Set DIST_DIR accordingly.
!ifndef VERSION
- !define /ifndef DIST_DIR ".\..\..\dist\${PRODUCT_NAME}-${ARCH}"
+ !define /ifndef DIST_DIR ".\..\..\dist\${PRODUCT_NAME}"
!getdllversion "${DIST_DIR}\${PROGEXE}" expv_
!define VERSION "${expv_1}.${expv_2}.${expv_3}"
!else
- !define /ifndef DIST_DIR ".\..\..\dist\${PRODUCT_NAME}-${VERSION}-${ARCH}"
+ !define /ifndef DIST_DIR ".\..\..\dist\${PRODUCT_NAME}-${VERSION}"
!endif
+; If not defined, assume Qt6 (requires a more recent windows version)
+!define /ifndef QT5 "False"
+
; Pack the exe header with upx if UPX is defined.
!ifdef UPX
!packhdr "$%TEMP%\exehead.tmp" '"upx" "--ultra-brute" "$%TEMP%\exehead.tmp"'
diff --git a/misc/nsis/uninstall.nsh b/misc/nsis/uninstall.nsh
index fc33b7aeeae..55bad591b54 100755
--- a/misc/nsis/uninstall.nsh
+++ b/misc/nsis/uninstall.nsh
@@ -1,19 +1,6 @@
-# Copyright 2018 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# NSIS uninstaller header. Uses NsisMultiUser plugin and contains portions of
# its demo code, copyright 2017 Richard Drizin, Alex Mitev.
diff --git a/misc/nsis/uninstall_pages.nsh b/misc/nsis/uninstall_pages.nsh
index 10bc3048446..5548db3ed5e 100755
--- a/misc/nsis/uninstall_pages.nsh
+++ b/misc/nsis/uninstall_pages.nsh
@@ -1,19 +1,6 @@
-# Copyright 2018 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# NSIS pages header. Uses NsisMultiUser plugin and contains portions of
# its demo code, copyright 2017 Richard Drizin, Alex Mitev.
diff --git a/misc/org.qutebrowser.qutebrowser.appdata.xml b/misc/org.qutebrowser.qutebrowser.appdata.xml
index e75709d0c1d..01730334528 100644
--- a/misc/org.qutebrowser.qutebrowser.appdata.xml
+++ b/misc/org.qutebrowser.qutebrowser.appdata.xml
@@ -1,5 +1,5 @@
-
+
org.qutebrowser.qutebrowser
CC-BY-SA-3.0
@@ -23,16 +23,16 @@
org.qutebrowser.qutebrowser.desktop
- https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/main.png
+ https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/main.png
- https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/downloads.png
+ https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/downloads.png
- https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/completion.png
+ https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/completion.png
- https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/hints.png
+ https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/hints.png
https://www.qutebrowser.org
@@ -44,6 +44,10 @@
+
+
+
+
diff --git a/misc/qutebrowser.spec b/misc/qutebrowser.spec
index 467994bab0d..652f69bfb9f 100644
--- a/misc/qutebrowser.spec
+++ b/misc/qutebrowser.spec
@@ -64,17 +64,17 @@ INFO_PLIST_UPDATES = {
def get_data_files():
data_files = [
- ('../qutebrowser/html', 'html'),
- ('../qutebrowser/img', 'img'),
- ('../qutebrowser/icons', 'icons'),
- ('../qutebrowser/javascript', 'javascript'),
- ('../qutebrowser/html/doc', 'html/doc'),
- ('../qutebrowser/git-commit-id', '.'),
- ('../qutebrowser/config/configdata.yml', 'config'),
+ ('../qutebrowser/html', 'qutebrowser/html'),
+ ('../qutebrowser/img', 'qutebrowser/img'),
+ ('../qutebrowser/icons', 'qutebrowser/icons'),
+ ('../qutebrowser/javascript', 'qutebrowser/javascript'),
+ ('../qutebrowser/html/doc', 'qutebrowser/html/doc'),
+ ('../qutebrowser/git-commit-id', 'qutebrowser/git-commit-id'),
+ ('../qutebrowser/config/configdata.yml', 'qutebrowser/config'),
]
if os.path.exists(os.path.join('qutebrowser', '3rdparty', 'pdfjs')):
- data_files.append(('../qutebrowser/3rdparty/pdfjs', '3rdparty/pdfjs'))
+ data_files.append(('../qutebrowser/3rdparty/pdfjs', 'qutebrowser/3rdparty/pdfjs'))
else:
print("Warning: excluding pdfjs as it's not present!")
@@ -82,7 +82,7 @@ def get_data_files():
def get_hidden_imports():
- imports = [] if "PYINSTALLER_QT6" in os.environ else ['PyQt5.QtOpenGL']
+ imports = ["PyQt5.QtOpenGL"] if "PYINSTALLER_QT5" in os.environ else []
for info in loader.walk_components():
imports.append(info.name)
return imports
@@ -100,6 +100,11 @@ else:
DEBUG = os.environ.get('PYINSTALLER_DEBUG', '').lower() in ['1', 'true']
+if DEBUG:
+ options = options = [('v', None, 'OPTION')]
+else:
+ options = []
+
a = Analysis(['../qutebrowser/__main__.py'],
@@ -117,6 +122,7 @@ pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
+ options,
exclude_binaries=True,
name='qutebrowser',
icon=icon,
@@ -137,5 +143,4 @@ app = BUNDLE(coll,
name='qutebrowser.app',
icon=icon,
info_plist=INFO_PLIST_UPDATES,
- # https://github.com/pyinstaller/pyinstaller/blob/b78bfe530cdc2904f65ce098bdf2de08c9037abb/PyInstaller/hooks/hook-PyQt5.QtWebEngineWidgets.py#L24
- bundle_identifier='org.qt-project.Qt.QtWebEngineCore')
+ bundle_identifier='org.qutebrowser.qutebrowser')
diff --git a/misc/requirements/requirements-check-manifest.txt b/misc/requirements/requirements-check-manifest.txt
index e02724e1232..0d250cf3c5a 100644
--- a/misc/requirements/requirements-check-manifest.txt
+++ b/misc/requirements/requirements-check-manifest.txt
@@ -1,7 +1,9 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-build==0.10.0
+build==1.0.3
check-manifest==0.49
-packaging==23.1
+importlib-metadata==7.0.1
+packaging==23.2
pyproject_hooks==1.0.0
tomli==2.0.1
+zipp==3.17.0
diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt
index ed13e40ebb5..5e7f67489ef 100644
--- a/misc/requirements/requirements-dev.txt
+++ b/misc/requirements/requirements-dev.txt
@@ -1,47 +1,45 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-bleach==6.0.0
-build==0.10.0
+build==1.0.3
bump2version==1.0.1
-certifi==2023.5.7
-cffi==1.15.1
-charset-normalizer==3.1.0
-cryptography==41.0.1
+certifi==2023.11.17
+cffi==1.16.0
+charset-normalizer==3.3.2
+cryptography==41.0.7
docutils==0.20.1
github3.py==4.0.1
hunter==3.6.1
-idna==3.4
-importlib-metadata==6.7.0
-importlib-resources==5.12.0
-jaraco.classes==3.2.3
+idna==3.6
+importlib-metadata==7.0.1
+importlib-resources==6.1.1
+jaraco.classes==3.3.0
jeepney==0.8.0
-keyring==24.2.0
+keyring==24.3.0
manhole==1.8.0
markdown-it-py==3.0.0
mdurl==0.1.2
-more-itertools==9.1.0
-packaging==23.1
+more-itertools==10.1.0
+nh3==0.2.15
+packaging==23.2
pkginfo==1.9.6
-ply==3.11
pycparser==2.21
-Pygments==2.15.1
-PyJWT==2.7.0
+Pygments==2.17.2
+PyJWT==2.8.0
Pympler==1.0.1
pyproject_hooks==1.0.0
-PyQt-builder==1.15.1
+PyQt-builder==1.15.4
python-dateutil==2.8.2
-readme-renderer==40.0
+readme-renderer==42.0
requests==2.31.0
requests-toolbelt==1.0.0
rfc3986==2.0.0
-rich==13.4.2
+rich==13.7.0
SecretStorage==3.3.3
-sip==6.7.9
+sip==6.8.1
six==1.16.0
tomli==2.0.1
twine==4.0.2
-typing_extensions==4.7.1
+typing_extensions==4.9.0
uritemplate==4.1.1
-# urllib3==2.0.3
-webencodings==0.5.1
-zipp==3.15.0
+# urllib3==2.1.0
+zipp==3.17.0
diff --git a/misc/requirements/requirements-flake8.txt b/misc/requirements/requirements-flake8.txt
index f008093204b..41b9e6c3e59 100644
--- a/misc/requirements/requirements-flake8.txt
+++ b/misc/requirements/requirements-flake8.txt
@@ -1,23 +1,23 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-attrs==23.1.0
-flake8==6.0.0
-flake8-bugbear==23.6.5
-flake8-builtins==2.1.0
-flake8-comprehensions==3.13.0
+attrs==23.2.0
+flake8==7.0.0
+flake8-bugbear==23.12.2
+flake8-builtins==2.2.0
+flake8-comprehensions==3.14.0
flake8-debugger==4.1.2
-flake8-deprecated==2.0.1
+flake8-deprecated==2.2.1
flake8-docstrings==1.7.0
flake8-future-import==0.4.7
flake8-plugin-utils==1.3.3
flake8-pytest-style==1.7.2
flake8-string-format==0.3.0
-flake8-tidy-imports==4.9.0
+flake8-tidy-imports==4.10.0
flake8-tuple==0.4.1
mccabe==0.7.0
pep8-naming==0.13.3
-pycodestyle==2.10.0
+pycodestyle==2.11.1
pydocstyle==6.3.0
-pyflakes==3.0.1
+pyflakes==3.2.0
six==1.16.0
snowballstemmer==2.2.0
diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt
index 82b80bc015b..b31bb7722d5 100644
--- a/misc/requirements/requirements-mypy.txt
+++ b/misc/requirements/requirements-mypy.txt
@@ -1,22 +1,21 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-chardet==5.1.0
-diff-cover==7.6.0
-importlib-resources==5.12.0
+chardet==5.2.0
+diff_cover==8.0.2
+importlib-resources==6.1.1
Jinja2==3.1.2
-lxml==4.9.2
+lxml==5.0.1
MarkupSafe==2.1.3
-mypy==1.4.1
+mypy==1.8.0
mypy-extensions==1.0.0
-pluggy==1.2.0
-Pygments==2.15.1
+pluggy==1.3.0
+Pygments==2.17.2
PyQt5-stubs==5.15.6.0
-PyQt6-stubs @ git+https://github.com/python-qt-tools/PyQt6-stubs.git@f623a641cd5cdff53342177e4fbbf9cae8172336
tomli==2.0.1
-types-colorama==0.4.15.11
-types-docutils==0.20.0.1
-types-Pygments==2.15.0.1
-types-PyYAML==6.0.12.10
-types-setuptools==68.0.0.0
-typing_extensions==4.7.1
-zipp==3.15.0
+types-colorama==0.4.15.20240106
+types-docutils==0.20.0.20240106
+types-Pygments==2.17.0.20240106
+types-PyYAML==6.0.12.12
+types-setuptools==69.0.0.20240106
+typing_extensions==4.9.0
+zipp==3.17.0
diff --git a/misc/requirements/requirements-mypy.txt-raw b/misc/requirements/requirements-mypy.txt-raw
index 487d30ca69c..027f4fef613 100644
--- a/misc/requirements/requirements-mypy.txt-raw
+++ b/misc/requirements/requirements-mypy.txt-raw
@@ -3,7 +3,6 @@ lxml # For HTML reports
diff-cover
PyQt5-stubs
-git+https://github.com/python-qt-tools/PyQt6-stubs.git
types-PyYAML
types-colorama
types-Pygments
diff --git a/misc/requirements/requirements-pyinstaller.txt b/misc/requirements/requirements-pyinstaller.txt
index 7934bec0d79..af7a329fd03 100644
--- a/misc/requirements/requirements-pyinstaller.txt
+++ b/misc/requirements/requirements-pyinstaller.txt
@@ -1,5 +1,8 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-altgraph==0.17.3
-pyinstaller==5.13.0
-pyinstaller-hooks-contrib==2023.4
+altgraph==0.17.4
+importlib-metadata==7.0.1
+packaging==23.2
+pyinstaller==6.3.0
+pyinstaller-hooks-contrib==2023.12
+zipp==3.17.0
diff --git a/misc/requirements/requirements-pyinstaller.txt-raw b/misc/requirements/requirements-pyinstaller.txt-raw
index c313980b089..ef376ca83a9 100644
--- a/misc/requirements/requirements-pyinstaller.txt-raw
+++ b/misc/requirements/requirements-pyinstaller.txt-raw
@@ -1 +1 @@
-PyInstaller
+pyinstaller
diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt
index c210631e3be..b3a5198b4c4 100644
--- a/misc/requirements/requirements-pylint.txt
+++ b/misc/requirements/requirements-pylint.txt
@@ -1,28 +1,26 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-astroid==2.15.5
-certifi==2023.5.7
-cffi==1.15.1
-charset-normalizer==3.1.0
-cryptography==41.0.1
-dill==0.3.6
+astroid==3.0.2
+certifi==2023.11.17
+cffi==1.16.0
+charset-normalizer==3.3.2
+cryptography==41.0.7
+dill==0.3.7
github3.py==4.0.1
-idna==3.4
-isort==5.12.0
-lazy-object-proxy==1.9.0
+idna==3.6
+isort==5.13.2
mccabe==0.7.0
pefile==2023.2.7
-platformdirs==3.8.0
+platformdirs==4.1.0
pycparser==2.21
-PyJWT==2.7.0
-pylint==2.17.4
+PyJWT==2.8.0
+pylint==3.0.3
python-dateutil==2.8.2
./scripts/dev/pylint_checkers
requests==2.31.0
six==1.16.0
tomli==2.0.1
-tomlkit==0.11.8
-typing_extensions==4.7.1
+tomlkit==0.12.3
+typing_extensions==4.9.0
uritemplate==4.1.1
-# urllib3==2.0.3
-wrapt==1.15.0
+# urllib3==2.1.0
diff --git a/misc/requirements/requirements-pylint.txt-raw b/misc/requirements/requirements-pylint.txt-raw
index 0873be8d5b3..99a2cf02faf 100644
--- a/misc/requirements/requirements-pylint.txt-raw
+++ b/misc/requirements/requirements-pylint.txt-raw
@@ -6,7 +6,7 @@ github3.py
pefile
# fix qute-pylint location
-#@ replace: qute-pylint.* ./scripts/dev/pylint_checkers
+#@ replace: qute[_-]pylint.* ./scripts/dev/pylint_checkers
#@ markers: typed-ast python_version<"3.8"
# Already included via test requirements
diff --git a/misc/requirements/requirements-pyqt-5.15.2.txt b/misc/requirements/requirements-pyqt-5.15.2.txt
index e63960d1e42..41f75871eab 100644
--- a/misc/requirements/requirements-pyqt-5.15.2.txt
+++ b/misc/requirements/requirements-pyqt-5.15.2.txt
@@ -1,5 +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.12.1
+PyQt5-sip==12.13.0
PyQtWebEngine==5.15.2 # rq.filter: == 5.15.2
diff --git a/misc/requirements/requirements-pyqt-5.15.txt b/misc/requirements/requirements-pyqt-5.15.txt
index d03c3ac01a2..5f9e4828eb3 100644
--- a/misc/requirements/requirements-pyqt-5.15.txt
+++ b/misc/requirements/requirements-pyqt-5.15.txt
@@ -1,7 +1,7 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-PyQt5==5.15.9 # rq.filter: < 5.16
+PyQt5==5.15.10 # rq.filter: < 5.16
PyQt5-Qt5==5.15.2
-PyQt5-sip==12.12.1
+PyQt5-sip==12.13.0
PyQtWebEngine==5.15.6 # rq.filter: < 5.16
PyQtWebEngine-Qt5==5.15.2
diff --git a/misc/requirements/requirements-pyqt-5.txt b/misc/requirements/requirements-pyqt-5.txt
index 029fb4a6b77..e8ee2b9c7c5 100644
--- a/misc/requirements/requirements-pyqt-5.txt
+++ b/misc/requirements/requirements-pyqt-5.txt
@@ -1,7 +1,7 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-PyQt5==5.15.9
+PyQt5==5.15.10
PyQt5-Qt5==5.15.2
-PyQt5-sip==12.12.1
+PyQt5-sip==12.13.0
PyQtWebEngine==5.15.6
PyQtWebEngine-Qt5==5.15.2
diff --git a/misc/requirements/requirements-pyqt-6.2.txt b/misc/requirements/requirements-pyqt-6.2.txt
index 06614aba28f..e90769dddca 100644
--- a/misc/requirements/requirements-pyqt-6.2.txt
+++ b/misc/requirements/requirements-pyqt-6.2.txt
@@ -2,6 +2,6 @@
PyQt6==6.2.3
PyQt6-Qt6==6.2.4
-PyQt6-sip==13.5.1
+PyQt6-sip==13.6.0
PyQt6-WebEngine==6.2.1
PyQt6-WebEngine-Qt6==6.2.4
diff --git a/misc/requirements/requirements-pyqt-6.3.txt b/misc/requirements/requirements-pyqt-6.3.txt
index 66af2e861a7..d82c623c326 100644
--- a/misc/requirements/requirements-pyqt-6.3.txt
+++ b/misc/requirements/requirements-pyqt-6.3.txt
@@ -2,6 +2,6 @@
PyQt6==6.3.1
PyQt6-Qt6==6.3.2
-PyQt6-sip==13.5.1
+PyQt6-sip==13.6.0
PyQt6-WebEngine==6.3.1
PyQt6-WebEngine-Qt6==6.3.2
diff --git a/misc/requirements/requirements-pyqt-6.4.txt b/misc/requirements/requirements-pyqt-6.4.txt
index 3a534a4db8c..b52e8a5117a 100644
--- a/misc/requirements/requirements-pyqt-6.4.txt
+++ b/misc/requirements/requirements-pyqt-6.4.txt
@@ -2,6 +2,6 @@
PyQt6==6.4.2
PyQt6-Qt6==6.4.3
-PyQt6-sip==13.5.1
+PyQt6-sip==13.6.0
PyQt6-WebEngine==6.4.0
PyQt6-WebEngine-Qt6==6.4.3
diff --git a/misc/requirements/requirements-pyqt-6.5.txt b/misc/requirements/requirements-pyqt-6.5.txt
index 26f81ab23ad..5dca9ab7496 100644
--- a/misc/requirements/requirements-pyqt-6.5.txt
+++ b/misc/requirements/requirements-pyqt-6.5.txt
@@ -1,7 +1,7 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-PyQt6==6.5.1
-PyQt6-Qt6==6.5.1
-PyQt6-sip==13.5.1
+PyQt6==6.5.3
+PyQt6-Qt6==6.5.3
+PyQt6-sip==13.6.0
PyQt6-WebEngine==6.5.0
-PyQt6-WebEngine-Qt6==6.5.1
+PyQt6-WebEngine-Qt6==6.5.3
diff --git a/misc/requirements/requirements-pyqt-6.6.txt b/misc/requirements/requirements-pyqt-6.6.txt
new file mode 100644
index 00000000000..914422a3815
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-6.6.txt
@@ -0,0 +1,7 @@
+# This file is automatically generated by scripts/dev/recompile_requirements.py
+
+PyQt6==6.6.1
+PyQt6-Qt6==6.6.1
+PyQt6-sip==13.6.0
+PyQt6-WebEngine==6.6.0
+PyQt6-WebEngine-Qt6==6.6.1
diff --git a/misc/requirements/requirements-pyqt-6.6.txt-raw b/misc/requirements/requirements-pyqt-6.6.txt-raw
new file mode 100644
index 00000000000..7cfe6d34c5e
--- /dev/null
+++ b/misc/requirements/requirements-pyqt-6.6.txt-raw
@@ -0,0 +1,4 @@
+PyQt6 >= 6.6, < 6.7
+PyQt6-Qt6 >= 6.6, < 6.7
+PyQt6-WebEngine >= 6.6, < 6.7
+PyQt6-WebEngine-Qt6 >= 6.6, < 6.7
diff --git a/misc/requirements/requirements-pyqt-6.txt b/misc/requirements/requirements-pyqt-6.txt
index 26f81ab23ad..914422a3815 100644
--- a/misc/requirements/requirements-pyqt-6.txt
+++ b/misc/requirements/requirements-pyqt-6.txt
@@ -1,7 +1,7 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-PyQt6==6.5.1
-PyQt6-Qt6==6.5.1
-PyQt6-sip==13.5.1
-PyQt6-WebEngine==6.5.0
-PyQt6-WebEngine-Qt6==6.5.1
+PyQt6==6.6.1
+PyQt6-Qt6==6.6.1
+PyQt6-sip==13.6.0
+PyQt6-WebEngine==6.6.0
+PyQt6-WebEngine-Qt6==6.6.1
diff --git a/misc/requirements/requirements-pyqt.txt b/misc/requirements/requirements-pyqt.txt
index 029fb4a6b77..914422a3815 100644
--- a/misc/requirements/requirements-pyqt.txt
+++ b/misc/requirements/requirements-pyqt.txt
@@ -1,7 +1,7 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-PyQt5==5.15.9
-PyQt5-Qt5==5.15.2
-PyQt5-sip==12.12.1
-PyQtWebEngine==5.15.6
-PyQtWebEngine-Qt5==5.15.2
+PyQt6==6.6.1
+PyQt6-Qt6==6.6.1
+PyQt6-sip==13.6.0
+PyQt6-WebEngine==6.6.0
+PyQt6-WebEngine-Qt6==6.6.1
diff --git a/misc/requirements/requirements-pyqt.txt-raw b/misc/requirements/requirements-pyqt.txt-raw
index 9c6afbf1618..68a5db68521 100644
--- a/misc/requirements/requirements-pyqt.txt-raw
+++ b/misc/requirements/requirements-pyqt.txt-raw
@@ -1,2 +1,4 @@
-PyQt5
-PyQtWebEngine
+PyQt6
+PyQt6-Qt6
+PyQt6-WebEngine
+PyQt6-WebEngine-Qt6
diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt
index e0d7fe58507..b93fb2be562 100644
--- a/misc/requirements/requirements-pyroma.txt
+++ b/misc/requirements/requirements-pyroma.txt
@@ -1,15 +1,17 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-build==0.10.0
-certifi==2023.5.7
-charset-normalizer==3.1.0
+build==1.0.3
+certifi==2023.11.17
+charset-normalizer==3.3.2
docutils==0.20.1
-idna==3.4
-packaging==23.1
-Pygments==2.15.1
+idna==3.6
+importlib-metadata==7.0.1
+packaging==23.2
+Pygments==2.17.2
pyproject_hooks==1.0.0
pyroma==4.2
requests==2.31.0
tomli==2.0.1
-trove-classifiers==2023.5.24
-urllib3==2.0.3
+trove-classifiers==2023.11.29
+urllib3==2.1.0
+zipp==3.17.0
diff --git a/misc/requirements/requirements-sphinx.txt b/misc/requirements/requirements-sphinx.txt
index e92e41b8caf..8d7cc145c60 100644
--- a/misc/requirements/requirements-sphinx.txt
+++ b/misc/requirements/requirements-sphinx.txt
@@ -1,26 +1,26 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
alabaster==0.7.13
-Babel==2.12.1
-certifi==2023.5.7
-charset-normalizer==3.1.0
+Babel==2.14.0
+certifi==2023.11.17
+charset-normalizer==3.3.2
docutils==0.20.1
-idna==3.4
+idna==3.6
imagesize==1.4.1
-importlib-metadata==6.7.0
+importlib-metadata==7.0.1
Jinja2==3.1.2
MarkupSafe==2.1.3
-packaging==23.1
-Pygments==2.15.1
-pytz==2023.3
+packaging==23.2
+Pygments==2.17.2
+pytz==2023.3.post1
requests==2.31.0
snowballstemmer==2.2.0
-Sphinx==7.0.1
+Sphinx==7.1.2
sphinxcontrib-applehelp==1.0.4
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
-urllib3==2.0.3
-zipp==3.15.0
+urllib3==2.1.0
+zipp==3.17.0
diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt
index 28b9e6f5d93..744abbcfc1f 100644
--- a/misc/requirements/requirements-tests.txt
+++ b/misc/requirements/requirements-tests.txt
@@ -1,57 +1,57 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-attrs==23.1.0
+attrs==23.2.0
beautifulsoup4==4.12.2
-blinker==1.6.2
-certifi==2023.5.7
-charset-normalizer==3.1.0
+blinker==1.7.0
+certifi==2023.11.17
+charset-normalizer==3.3.2
cheroot==10.0.0
-click==8.1.3
-coverage==7.2.7
-exceptiongroup==1.1.1
-execnet==1.9.0
-filelock==3.12.2
-Flask==2.3.2
+click==8.1.7
+coverage==7.4.0
+exceptiongroup==1.2.0
+execnet==2.0.2
+filelock==3.13.1
+Flask==3.0.0
hunter==3.6.1
-hypothesis==6.80.0
-idna==3.4
-importlib-metadata==6.7.0
+hypothesis==6.92.3
+idna==3.6
+importlib-metadata==7.0.1
iniconfig==2.0.0
itsdangerous==2.1.2
-jaraco.functools==3.8.0
+jaraco.functools==4.0.0
# Jinja2==3.1.2
-Mako==1.2.4
+Mako==1.3.0
manhole==1.8.0
# MarkupSafe==2.1.3
-more-itertools==9.1.0
-packaging==23.1
-parse==1.19.1
-parse-type==0.6.1
-pluggy==1.2.0
+more-itertools==10.1.0
+packaging==23.2
+parse==1.20.0
+parse-type==0.6.2
+pluggy==1.3.0
py-cpuinfo==9.0.0
-Pygments==2.15.1
-pytest==7.4.0
-pytest-bdd==6.1.1
+Pygments==2.17.2
+pytest==7.4.4
+pytest-bdd==7.0.1
pytest-benchmark==4.0.0
pytest-cov==4.1.0
pytest-instafail==0.5.0
-pytest-mock==3.11.1
-pytest-qt==4.2.0
-pytest-repeat==0.9.1
-pytest-rerunfailures==11.1.2
-pytest-xdist==3.3.1
+pytest-mock==3.12.0
+pytest-qt==4.3.1
+pytest-repeat==0.9.3
+pytest-rerunfailures==13.0
+pytest-xdist==3.5.0
pytest-xvfb==3.0.0
PyVirtualDisplay==3.0
requests==2.31.0
requests-file==1.5.1
six==1.16.0
sortedcontainers==2.4.0
-soupsieve==2.4.1
-tldextract==3.4.4
+soupsieve==2.5
+tldextract==5.1.1
toml==0.10.2
tomli==2.0.1
-typing_extensions==4.7.1
-urllib3==2.0.3
-vulture==2.7
-Werkzeug==2.3.6
-zipp==3.15.0
+typing_extensions==4.9.0
+urllib3==2.1.0
+vulture==2.10
+Werkzeug==3.0.1
+zipp==3.17.0
diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt
index e68e79d4696..79f770342dc 100644
--- a/misc/requirements/requirements-tox.txt
+++ b/misc/requirements/requirements-tox.txt
@@ -1,17 +1,17 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-cachetools==5.3.1
-chardet==5.1.0
+cachetools==5.3.2
+chardet==5.2.0
colorama==0.4.6
-distlib==0.3.6
-filelock==3.12.2
-packaging==23.1
-pip==23.1.2
-platformdirs==3.8.0
-pluggy==1.2.0
-pyproject-api==1.5.2
-setuptools==68.0.0
+distlib==0.3.8
+filelock==3.13.1
+packaging==23.2
+pip==23.3.2
+platformdirs==4.1.0
+pluggy==1.3.0
+pyproject-api==1.6.1
+setuptools==69.0.3
tomli==2.0.1
-tox==4.6.3
-virtualenv==20.23.1
-wheel==0.40.0
+tox==4.11.4
+virtualenv==20.25.0
+wheel==0.42.0
diff --git a/misc/requirements/requirements-vulture.txt b/misc/requirements/requirements-vulture.txt
index f72d24a67bd..9bceeb7b1ce 100644
--- a/misc/requirements/requirements-vulture.txt
+++ b/misc/requirements/requirements-vulture.txt
@@ -1,4 +1,4 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
toml==0.10.2
-vulture==2.7
+vulture==2.10
diff --git a/misc/requirements/requirements-yamllint.txt b/misc/requirements/requirements-yamllint.txt
index 718012a4e5b..8ecdcd50871 100644
--- a/misc/requirements/requirements-yamllint.txt
+++ b/misc/requirements/requirements-yamllint.txt
@@ -1,5 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-pathspec==0.11.1
-PyYAML==6.0
-yamllint==1.32.0
+pathspec==0.12.1
+PyYAML==6.0.1
+yamllint==1.33.0
diff --git a/misc/userscripts/add-nextcloud-bookmarks b/misc/userscripts/add-nextcloud-bookmarks
index 86f4f5bc7be..2a480ccffdf 100755
--- a/misc/userscripts/add-nextcloud-bookmarks
+++ b/misc/userscripts/add-nextcloud-bookmarks
@@ -41,7 +41,7 @@ from json import dumps
from os import environ, path
from sys import argv, exit
-from PyQt5.QtWidgets import QApplication, QInputDialog, QLineEdit
+from PyQt6.QtWidgets import QApplication, QInputDialog, QLineEdit
from requests import get, post
from requests.auth import HTTPBasicAuth
@@ -54,7 +54,7 @@ def get_text(name, info):
None,
"add-nextcloud-bookmarks userscript",
"Please enter {}".format(info),
- QLineEdit.Password,
+ QLineEdit.EchoMode.Password,
)
else:
text, ok = QInputDialog.getText(
diff --git a/misc/userscripts/add-nextcloud-cookbook b/misc/userscripts/add-nextcloud-cookbook
index 3952bb16f6f..151090785fa 100755
--- a/misc/userscripts/add-nextcloud-cookbook
+++ b/misc/userscripts/add-nextcloud-cookbook
@@ -37,7 +37,7 @@ import configparser
from os import environ, path
from sys import argv, exit
-from PyQt5.QtWidgets import QApplication, QInputDialog, QLineEdit
+from PyQt6.QtWidgets import QApplication, QInputDialog, QLineEdit
from requests import post
from requests.auth import HTTPBasicAuth
@@ -50,7 +50,7 @@ def get_text(name, info):
None,
"add-nextcloud-cookbook userscript",
"Please enter {}".format(info),
- QLineEdit.Password,
+ QLineEdit.EchoMode.Password,
)
else:
text, ok = QInputDialog.getText(
diff --git a/misc/userscripts/dmenu_qutebrowser b/misc/userscripts/dmenu_qutebrowser
index 309736200b6..f481d00a55e 100755
--- a/misc/userscripts/dmenu_qutebrowser
+++ b/misc/userscripts/dmenu_qutebrowser
@@ -1,22 +1,9 @@
#!/usr/bin/env bash
-# Copyright 2015-2021 Florian Bruhin (The Compiler)
-# Copyright 2015 Zach-Button
+# SPDX-FileCopyrightText: Zach-Button
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# Pipes history, quickmarks, and URL into dmenu.
#
diff --git a/misc/userscripts/openfeeds b/misc/userscripts/openfeeds
index 7cd5b86a868..cfe765e42d6 100755
--- a/misc/userscripts/openfeeds
+++ b/misc/userscripts/openfeeds
@@ -1,23 +1,10 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
-# Copyright 2015 jnphilipp
+# SPDX-FileCopyrightText: jnphilipp
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# Opens all links to feeds defined in the head of a site
#
diff --git a/misc/userscripts/qute-1pass b/misc/userscripts/qute-1pass
index 091f841fc96..19e5414a581 100755
--- a/misc/userscripts/qute-1pass
+++ b/misc/userscripts/qute-1pass
@@ -2,7 +2,7 @@
set +e
-# JS field injection code from https://github.com/qutebrowser/qutebrowser/blob/master/misc/userscripts/password_fill
+# JS field injection code from https://github.com/qutebrowser/qutebrowser/blob/main/misc/userscripts/password_fill
javascript_escape() {
# print the first argument in an escaped way, such that it can safely
# be used within javascripts double quotes
diff --git a/misc/userscripts/qute-bitwarden b/misc/userscripts/qute-bitwarden
index a30f734f243..f9637bae94c 100755
--- a/misc/userscripts/qute-bitwarden
+++ b/misc/userscripts/qute-bitwarden
@@ -1,22 +1,8 @@
#!/usr/bin/env python3
-# Copyright 2017 Chris Braun (cryzed)
-# Adapted for Bitwarden by Jonathan Haylett (JonnyHaystack)
+# SPDX-FileCopyrightText: Chris Braun (cryzed)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""
Insert login information using Bitwarden CLI and a dmenu-compatible application
diff --git a/misc/userscripts/qute-keepass b/misc/userscripts/qute-keepass
index 285377ffca5..445d308d5c3 100755
--- a/misc/userscripts/qute-keepass
+++ b/misc/userscripts/qute-keepass
@@ -1,21 +1,8 @@
#!/usr/bin/env python3
-# Copyright 2018-2021 Jay Kamat
+# SPDX-FileCopyrightText: Jay Kamat
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""This userscript allows for insertion of usernames and passwords from keepass
databases using pykeepass. Since it is a userscript, it must be run from
@@ -42,7 +29,7 @@ you do not do this, you will get 'element not editable' errors.
If keepass takes a while to open the DB, you might want to consider reducing
the number of transform rounds in your database settings.
-Dependencies: pykeepass (in python3), PyQt5. Without pykeepass, you will get an
+Dependencies: pykeepass (in python3), PyQt6. Without pykeepass, you will get an
exit code of 100.
********************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!******************
@@ -64,8 +51,8 @@ import shlex
import subprocess
import sys
-from PyQt5.QtCore import QUrl
-from PyQt5.QtWidgets import QApplication, QInputDialog, QLineEdit
+from PyQt6.QtCore import QUrl
+from PyQt6.QtWidgets import QApplication, QInputDialog, QLineEdit
try:
import pykeepass
@@ -152,7 +139,7 @@ def get_password():
text, ok = QInputDialog.getText(
None, "KeePass DB Password",
"Please enter your KeePass Master Password",
- QLineEdit.Password)
+ QLineEdit.EchoMode.Password)
if not ok:
stderr('Password Prompt Rejected.')
sys.exit(ExitCodes.USER_QUIT)
@@ -247,10 +234,10 @@ def run(args):
# into insert-mode, so the form can be directly submitted by hitting
# enter afterwards. It doesn't matter when we go into insert mode, but
# the other commands need to be be executed sequentially, so we add
- # delays with later.
+ # delays with cmd-later.
qute_command('insert-text {} ;;'
- 'later {} fake-key ;;'
- 'later {} insert-text {}{}'
+ 'cmd-later {} fake-key ;;'
+ 'cmd-later {} insert-text {}{}'
.format(username, CMD_DELAY,
CMD_DELAY * 2, password, insert_mode))
diff --git a/misc/userscripts/qute-keepassxc b/misc/userscripts/qute-keepassxc
index 61a6c7bceb8..d5970cfedee 100755
--- a/misc/userscripts/qute-keepassxc
+++ b/misc/userscripts/qute-keepassxc
@@ -2,20 +2,7 @@
# Copyright (c) 2018-2021 Markus Blöchl
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""
# Introduction
@@ -91,7 +78,7 @@ insert mode if you prefer that).
[2]: https://qutebrowser.org/
[3]: https://gnupg.org/
[4]: https://github.com/keepassxreboot/keepassxc-browser/blob/develop/keepassxc-protocol.md
-[5]: https://github.com/qutebrowser/qutebrowser/blob/master/doc/userscripts.asciidoc
+[5]: https://github.com/qutebrowser/qutebrowser/blob/main/doc/userscripts.asciidoc
[6]: https://keepassxc.org/docs/KeePassXC_GettingStarted.html#_setup_browser_integration
"""
diff --git a/misc/userscripts/qute-lastpass b/misc/userscripts/qute-lastpass
index e99a51a0f64..d79ef658a53 100755
--- a/misc/userscripts/qute-lastpass
+++ b/misc/userscripts/qute-lastpass
@@ -1,22 +1,8 @@
#!/usr/bin/env python3
-# Copyright 2017 Chris Braun (cryzed)
-# Adapted for LastPass by Wayne Cheng (welps)
+# SPDX-FileCopyrightText: Chris Braun (cryzed)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""
Insert login information using lastpass CLI and a dmenu-compatible application (e.g. dmenu, rofi -dmenu, ...).
diff --git a/misc/userscripts/qute-pass b/misc/userscripts/qute-pass
index e3215e12487..70a497b63a5 100755
--- a/misc/userscripts/qute-pass
+++ b/misc/userscripts/qute-pass
@@ -1,21 +1,8 @@
#!/usr/bin/env python3
-# Copyright 2017 Chris Braun (cryzed)
+# SPDX-FileCopyrightText: Chris Braun (cryzed)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""
Insert login information using pass and a dmenu-compatible application (e.g. dmenu, rofi -dmenu, ...). A short
diff --git a/misc/userscripts/rss b/misc/userscripts/rss
index 3c52d1f276d..fab57fef654 100755
--- a/misc/userscripts/rss
+++ b/misc/userscripts/rss
@@ -1,21 +1,8 @@
#!/bin/sh
-# Copyright 2016 Jan Verbeek (blyxxyz)
+# SPDX-FileCopyrightText: Jan Verbeek (blyxxyz)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# This script keeps track of URLs in RSS feeds and opens new ones.
# New feeds can be added with ':spawn -u /path/to/userscripts/rss add' or
diff --git a/misc/userscripts/taskadd b/misc/userscripts/taskadd
index 3f5368b92d4..222592f79cb 100755
--- a/misc/userscripts/taskadd
+++ b/misc/userscripts/taskadd
@@ -11,7 +11,7 @@
# :spawn --userscript taskadd due:eod pri:H
#
# To enable passing along extra args, I suggest using a mapping like:
-# :bind set-cmd-text -s :spawn --userscript taskadd
+# :bind cmd-set-text -s :spawn --userscript taskadd
#
# If run from hint mode, it uses the selected hint text as the description
# and the selected hint url as the annotation.
diff --git a/misc/userscripts/tor_identity b/misc/userscripts/tor_identity
index a6cd73db95b..6b3828ed4f1 100755
--- a/misc/userscripts/tor_identity
+++ b/misc/userscripts/tor_identity
@@ -1,22 +1,9 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-# Copyright 2018-2021 J. Nathanael Philipp (jnphilipp)
+# SPDX-FileCopyrightText: J. Nathanael Philipp (jnphilipp)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# Change your tor identity.
#
diff --git a/misc/userscripts/view_in_mpv b/misc/userscripts/view_in_mpv
index 4729204338c..4f371c6b53d 100755
--- a/misc/userscripts/view_in_mpv
+++ b/misc/userscripts/view_in_mpv
@@ -49,7 +49,7 @@ msg() {
MPV_COMMAND=${MPV_COMMAND:-mpv}
# Warning: spaces in single flags are not supported
-MPV_FLAGS=${MPV_FLAGS:- --force-window --no-terminal --keep-open=yes --ytdl}
+MPV_FLAGS=${MPV_FLAGS:- --force-window --quiet --keep-open=yes --ytdl}
IFS=" " read -r -a video_command <<< "$MPV_COMMAND $MPV_FLAGS"
js() {
@@ -94,9 +94,9 @@ cat <click here.
";
@@ -119,7 +119,6 @@ cat <> "$QUTE_FIFO"
+echo "jseval -q -w main $(printjs)" >> "$QUTE_FIFO"
msg info "Opening $QUTE_URL with mpv"
"${video_command[@]}" "$@" "$QUTE_URL"
diff --git a/pytest.ini b/pytest.ini
index 8d7cf2e95b4..f2f74628449 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -59,6 +59,8 @@ qt_log_ignore =
^QObject::connect: Connecting from COMPAT signal \(QSocketNotifier::activated\(int\)\)$
# Randomly started showing up on Qt 5.15.2
^QBackingStore::endPaint\(\) called with active painter; did you forget to destroy it or call QPainter::end\(\) on it\?$
+ # Qt 6.5 after system update, from qt-qt.accessibility.atspi
+ Error in contacting registry: "org\.freedesktop\.DBus\.Error\.Disconnected" "Not connected to D-Bus server"
xfail_strict = true
filterwarnings =
error
@@ -66,5 +68,5 @@ filterwarnings =
# Python 3.12: https://github.com/jendrikseipp/vulture/issues/314
ignore:ast\.Str is deprecated and will be removed in Python 3\.14; use ast\.Constant instead:DeprecationWarning:vulture\.core
# Python 3.12: https://github.com/ionelmc/pytest-benchmark/issues/240
- ignore:datetime\.utcnow\(\) is deprecated and scheduled for removal in a future version\. Use timezone-aware objects to represent datetimes in UTC. datetime\.now\(datetime\.UTC\)\.:DeprecationWarning:pytest_benchmark\.utils
+ ignore:(datetime\.)?datetime\.utcnow\(\) is deprecated and scheduled for removal in a future version\. Use timezone-aware objects to represent datetimes in UTC. (datetime\.)?datetime\.now\(datetime\.UTC\)\.:DeprecationWarning:pytest_benchmark\.utils
faulthandler_timeout = 90
diff --git a/qutebrowser.py b/qutebrowser.py
index be31f12550e..bdd5e574f80 100755
--- a/qutebrowser.py
+++ b/qutebrowser.py
@@ -1,20 +1,8 @@
#!/usr/bin/env python3
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
-#
-# 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.
+
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# You should have received a copy of the GNU General Public License
-# along with qutebrowser. If not, see .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Simple launcher for qutebrowser."""
diff --git a/qutebrowser/__init__.py b/qutebrowser/__init__.py
index b972ddf08a7..5df8d7a31af 100644
--- a/qutebrowser/__init__.py
+++ b/qutebrowser/__init__.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""A keyboard-driven, vim-like browser based on Python and Qt."""
@@ -24,7 +11,7 @@
__license__ = "GPL"
__maintainer__ = __author__
__email__ = "mail@qutebrowser.org"
-__version__ = "2.5.4"
+__version__ = "3.1.0"
__version_info__ = tuple(int(part) for part in __version__.split('.'))
__description__ = "A keyboard-driven, vim-like browser based on Python and Qt."
diff --git a/qutebrowser/__main__.py b/qutebrowser/__main__.py
index be31f12550e..bdd5e574f80 100644
--- a/qutebrowser/__main__.py
+++ b/qutebrowser/__main__.py
@@ -1,20 +1,8 @@
#!/usr/bin/env python3
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
-#
-# 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.
+
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# You should have received a copy of the GNU General Public License
-# along with qutebrowser. If not, see .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Simple launcher for qutebrowser."""
diff --git a/qutebrowser/api/__init__.py b/qutebrowser/api/__init__.py
index 3c002352c8f..cd511f2fcc7 100644
--- a/qutebrowser/api/__init__.py
+++ b/qutebrowser/api/__init__.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""API for extensions.
diff --git a/qutebrowser/api/apitypes.py b/qutebrowser/api/apitypes.py
index a0d305ec749..5aacf80b4b9 100644
--- a/qutebrowser/api/apitypes.py
+++ b/qutebrowser/api/apitypes.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""A single tab."""
diff --git a/qutebrowser/api/cmdutils.py b/qutebrowser/api/cmdutils.py
index 15dfcb310f8..e5466f072ac 100644
--- a/qutebrowser/api/cmdutils.py
+++ b/qutebrowser/api/cmdutils.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""qutebrowser has the concept of functions, exposed to the user as commands.
@@ -48,7 +35,7 @@ def foo(bar: int, baz=True):
import inspect
-from typing import Any, Callable, Iterable
+from typing import Any, Callable, Iterable, Protocol, Optional, Dict, cast
from qutebrowser.utils import qtutils
from qutebrowser.commands import command, cmdexc
@@ -103,7 +90,21 @@ def check_exclusive(flags: Iterable[bool], names: Iterable[str]) -> None:
raise CommandError("Only one of {} can be given!".format(argstr))
-_CmdHandlerType = Callable[..., Any]
+_CmdHandlerFunc = Callable[..., Any]
+
+
+class _CmdHandlerType(Protocol):
+
+ """A qutebrowser command function, which had qute_args patched on it.
+
+ Applying @cmdutils.argument to a function will patch it with a qute_args attribute.
+ Below, we cast the decorated function to _CmdHandlerType to make mypy aware of this.
+ """
+
+ qute_args: Optional[Dict[str, 'command.ArgInfo']]
+
+ def __call__(self, *args: Any, **kwargs: Any) -> Any:
+ ...
class register: # noqa: N801,N806 pylint: disable=invalid-name
@@ -131,7 +132,7 @@ def __init__(self, *,
# The arguments to pass to Command.
self._kwargs = kwargs
- def __call__(self, func: _CmdHandlerType) -> _CmdHandlerType:
+ def __call__(self, func: _CmdHandlerFunc) -> _CmdHandlerType:
"""Register the command before running the function.
Gets called when a function should be decorated.
@@ -171,7 +172,8 @@ def __call__(self, func: _CmdHandlerType) -> _CmdHandlerType:
# This is checked by future @cmdutils.argument calls so they fail
# (as they'd be silently ignored otherwise)
- func.qute_args = None # type: ignore[attr-defined]
+ func = cast(_CmdHandlerType, func)
+ func.qute_args = None
return func
@@ -223,19 +225,21 @@ def __init__(self, argname: str, **kwargs: Any) -> None:
self._argname = argname # The name of the argument to handle.
self._kwargs = kwargs # Valid ArgInfo members.
- def __call__(self, func: _CmdHandlerType) -> _CmdHandlerType:
+ def __call__(self, func: _CmdHandlerFunc) -> _CmdHandlerType:
funcname = func.__name__
if self._argname not in inspect.signature(func).parameters:
raise ValueError("{} has no argument {}!".format(funcname,
self._argname))
+
+ func = cast(_CmdHandlerType, func)
if not hasattr(func, 'qute_args'):
- func.qute_args = {} # type: ignore[attr-defined]
+ func.qute_args = {}
elif func.qute_args is None:
raise ValueError("@cmdutils.argument got called above (after) "
"@cmdutils.register for {}!".format(funcname))
arginfo = command.ArgInfo(**self._kwargs)
- func.qute_args[self._argname] = arginfo # type: ignore[attr-defined]
+ func.qute_args[self._argname] = arginfo
return func
diff --git a/qutebrowser/api/config.py b/qutebrowser/api/config.py
index c156c9c58cc..201f95c1462 100644
--- a/qutebrowser/api/config.py
+++ b/qutebrowser/api/config.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Access to the qutebrowser configuration."""
diff --git a/qutebrowser/api/downloads.py b/qutebrowser/api/downloads.py
index 8d69bfc9122..391a4c13ef5 100644
--- a/qutebrowser/api/downloads.py
+++ b/qutebrowser/api/downloads.py
@@ -1,20 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
-
+# SPDX-License-Identifier: GPL-3.0-or-later
"""APIs related to downloading files."""
diff --git a/qutebrowser/api/hook.py b/qutebrowser/api/hook.py
index b17d9492a88..9a1a7bc9cc5 100644
--- a/qutebrowser/api/hook.py
+++ b/qutebrowser/api/hook.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# pylint: disable=invalid-name
diff --git a/qutebrowser/api/interceptor.py b/qutebrowser/api/interceptor.py
index 30334eeecdf..e0dbf66ec63 100644
--- a/qutebrowser/api/interceptor.py
+++ b/qutebrowser/api/interceptor.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""APIs related to intercepting/blocking requests."""
diff --git a/qutebrowser/api/message.py b/qutebrowser/api/message.py
index 87f60be9cf9..3e1dd646956 100644
--- a/qutebrowser/api/message.py
+++ b/qutebrowser/api/message.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Utilities to display messages above the status bar."""
diff --git a/qutebrowser/api/qtutils.py b/qutebrowser/api/qtutils.py
index 2ca3c524478..ee1dc2f368e 100644
--- a/qutebrowser/api/qtutils.py
+++ b/qutebrowser/api/qtutils.py
@@ -1,19 +1,6 @@
-# Copyright 2019-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Utilities related to Qt classes."""
diff --git a/qutebrowser/app.py b/qutebrowser/app.py
index bb2ff56e776..015715eef95 100644
--- a/qutebrowser/app.py
+++ b/qutebrowser/app.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Initialization of qutebrowser and application-wide things.
@@ -42,7 +29,7 @@
import pathlib
import datetime
import argparse
-from typing import Iterable, Optional
+from typing import Iterable, Optional, List, Tuple
from qutebrowser.qt import machinery
from qutebrowser.qt.widgets import QApplication, QWidget
@@ -340,7 +327,7 @@ def _open_special_pages(args):
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window='last-focused')
- pages = [
+ pages: List[Tuple[str, bool, str]] = [
# state, condition, URL
('quickstart-done',
True,
@@ -359,14 +346,17 @@ def _open_special_pages(args):
True,
'qute://warning/sessions'),
- ('sandboxing-warning-shown',
+ ('qt5-warning-shown',
(
- hasattr(sys, "frozen") and
- utils.is_mac and
- machinery.IS_QT6 and
- os.environ.get("QTWEBENGINE_DISABLE_SANDBOX") == "1"
+ machinery.IS_QT5 and
+ machinery.INFO.reason == machinery.SelectionReason.auto and
+ objects.backend != usertypes.Backend.QtWebKit
),
- 'qute://warning/sandboxing'),
+ 'qute://warning/qt5'),
+
+ ('birthday-2023-shown',
+ datetime.date.today() == datetime.date(2023, 12, 14),
+ 'https://qutebrowser.org/birthday.html'),
]
if 'quickstart-done' not in general_sect:
@@ -575,7 +565,7 @@ def _on_new_window(self, window):
@pyqtSlot(QObject)
def on_focus_object_changed(self, obj):
"""Log when the focus object changed."""
- output = repr(obj)
+ output = qtutils.qobj_repr(obj)
if self._last_focus_object != output:
log.misc.debug("Focus object changed: {}".format(output))
self._last_focus_object = output
diff --git a/qutebrowser/browser/__init__.py b/qutebrowser/browser/__init__.py
index e736eafd93e..acdd9b4a9aa 100644
--- a/qutebrowser/browser/__init__.py
+++ b/qutebrowser/browser/__init__.py
@@ -1,18 +1,5 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Classes related to the browser widgets."""
diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py
index 5630dc8cf18..3d5003254fa 100644
--- a/qutebrowser/browser/browsertab.py
+++ b/qutebrowser/browser/browsertab.py
@@ -1,21 +1,8 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
-"""Base class for a wrapper over QWebView/QWebEngineView."""
+"""Base class for a wrapper over WebView/WebEngineView."""
import enum
import pathlib
@@ -35,15 +22,14 @@
if TYPE_CHECKING:
from qutebrowser.qt.webkit import QWebHistory, QWebHistoryItem
- from qutebrowser.qt.webkitwidgets import QWebPage, QWebView
+ from qutebrowser.qt.webkitwidgets import QWebPage
from qutebrowser.qt.webenginecore import (
QWebEngineHistory, QWebEngineHistoryItem, QWebEnginePage)
- from qutebrowser.qt.webenginewidgets import QWebEngineView
from qutebrowser.keyinput import modeman
from qutebrowser.config import config, websettings
from qutebrowser.utils import (utils, objreg, usertypes, log, qtutils,
- urlutils, message, jinja)
+ urlutils, message, jinja, version)
from qutebrowser.misc import miscwidgets, objects, sessions
from qutebrowser.browser import eventfilter, inspector
from qutebrowser.qt import sip
@@ -51,12 +37,14 @@
if TYPE_CHECKING:
from qutebrowser.browser import webelem
from qutebrowser.browser.inspector import AbstractWebInspector
+ from qutebrowser.browser.webengine.webview import WebEngineView
+ from qutebrowser.browser.webkit.webview import WebView
from qutebrowser.mainwindow.treetabwidget import TreeTabWidget
from qutebrowser.misc.notree import Node
tab_id_gen = itertools.count(0)
-_WidgetType = Union["QWebView", "QWebEngineView"]
+_WidgetType = Union["WebView", "WebEngineView"]
def create(win_id: int,
@@ -288,10 +276,16 @@ def to_printer(self, printer: QPrinter) -> None:
"""
raise NotImplementedError
+ def _do_print(self) -> None:
+ assert self._dialog is not None
+ printer = self._dialog.printer()
+ assert printer is not None
+ self.to_printer(printer)
+
def show_dialog(self) -> None:
"""Print with a QPrintDialog."""
- self._dialog = dialog = QPrintDialog(self._tab)
- self._dialog.open(lambda: self.to_printer(dialog.printer()))
+ self._dialog = QPrintDialog(self._tab)
+ self._dialog.open(self._do_print)
# Gets cleaned up in on_printing_finished
@@ -973,7 +967,7 @@ def _init_inspector(self, splitter: 'miscwidgets.InspectorSplitter',
class AbstractTab(QWidget):
- """An adapter for QWebView/QWebEngineView representing a single tab."""
+ """An adapter for WebView/WebEngineView representing a single tab."""
#: Signal emitted when a website requests to close this tab.
window_close_requested = pyqtSignal()
@@ -1072,7 +1066,7 @@ def __init__(self, *, win_id: int,
self.before_load_started.connect(self._on_before_load_started)
- def _set_widget(self, widget: Union["QWebView", "QWebEngineView"]) -> None:
+ def _set_widget(self, widget: _WidgetType) -> None:
# pylint: disable=protected-access
self._widget = widget
# FIXME:v4 ignore needed for QtWebKit
@@ -1162,10 +1156,11 @@ def _on_navigation_request(
) -> None:
"""Handle common acceptNavigationRequest code."""
url = utils.elide(navigation.url.toDisplayString(), 100)
- log.webview.debug("navigation request: url {}, type {}, is_main_frame "
- "{}".format(url,
- navigation.navigation_type,
- navigation.is_main_frame))
+ log.webview.debug(
+ f"navigation request: url {url} (current {self.url().toDisplayString()}), "
+ f"type {navigation.navigation_type.name}, "
+ f"is_main_frame {navigation.is_main_frame}"
+ )
if navigation.is_main_frame:
self.data.last_navigation = navigation
@@ -1183,6 +1178,37 @@ def _on_navigation_request(
navigation.url.errorString()))
navigation.accepted = False
+ # WORKAROUND for QtWebEngine >= 6.2 not allowing form requests from
+ # qute:// to outside domains.
+ needs_load_workarounds = (
+ objects.backend == usertypes.Backend.QtWebEngine and
+ version.qtwebengine_versions().webengine >= utils.VersionNumber(6, 2)
+ )
+ if (
+ needs_load_workarounds and
+ self.url() == QUrl("qute://start/") and
+ navigation.navigation_type == navigation.Type.form_submitted and
+ navigation.url.matches(
+ QUrl(config.val.url.searchengines['DEFAULT']),
+ urlutils.FormatOption.REMOVE_QUERY)
+ ):
+ log.webview.debug(
+ "Working around qute://start loading issue for "
+ f"{navigation.url.toDisplayString()}")
+ navigation.accepted = False
+ self.load_url(navigation.url)
+
+ if (
+ needs_load_workarounds and
+ self.url() == QUrl("qute://bookmarks/") and
+ navigation.navigation_type == navigation.Type.back_forward
+ ):
+ log.webview.debug(
+ "Working around qute://bookmarks loading issue for "
+ f"{navigation.url.toDisplayString()}")
+ navigation.accepted = False
+ self.load_url(navigation.url)
+
@pyqtSlot(bool)
def _on_load_finished(self, ok: bool) -> None:
assert self._widget is not None
diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py
index 09f83450325..d7212d6ceca 100644
--- a/qutebrowser/browser/commands.py
+++ b/qutebrowser/browser/commands.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Command dispatcher for TabbedBrowser."""
@@ -1420,21 +1407,31 @@ def quickmark_load(self, name, tab=False, bg=False, window=False):
@cmdutils.register(instance='command-dispatcher', scope='window',
maxsplit=0)
@cmdutils.argument('name', completion=miscmodels.quickmark)
- def quickmark_del(self, name=None):
+ def quickmark_del(self, name=None, all_=False):
"""Delete a quickmark.
Args:
name: The name of the quickmark to delete. If not given, delete the
quickmark for the current page (choosing one arbitrarily
if there are more than one).
+ all_: Delete all quickmarks.
"""
quickmark_manager = objreg.get('quickmark-manager')
+
+ if all_:
+ if name is not None:
+ raise cmdutils.CommandError("Cannot specify name and --all")
+ quickmark_manager.clear()
+ message.info("Quickmarks cleared.")
+ return
+
if name is None:
url = self._current_url()
try:
name = quickmark_manager.get_by_qurl(url)
except urlmarks.DoesNotExistError as e:
raise cmdutils.CommandError(str(e))
+
try:
quickmark_manager.delete(name)
except KeyError:
@@ -1505,18 +1502,28 @@ def bookmark_load(self, url, tab=False, bg=False, window=False,
@cmdutils.register(instance='command-dispatcher', scope='window',
maxsplit=0)
@cmdutils.argument('url', completion=miscmodels.bookmark)
- def bookmark_del(self, url=None):
+ def bookmark_del(self, url=None, all_=False):
"""Delete a bookmark.
Args:
url: The url of the bookmark to delete. If not given, use the
current page's url.
+ all_: If given, delete all bookmarks.
"""
+ bookmark_manager = objreg.get('bookmark-manager')
+ if all_:
+ if url is not None:
+ raise cmdutils.CommandError("Cannot specify url and --all")
+ bookmark_manager.clear()
+ message.info("Bookmarks cleared.")
+ return
+
if url is None:
url = self._current_url().toString(QUrl.UrlFormattingOption.RemovePassword |
QUrl.ComponentFormattingOption.FullyEncoded)
+
try:
- objreg.get('bookmark-manager').delete(url)
+ bookmark_manager.delete(url)
except KeyError:
raise cmdutils.CommandError("Bookmark '{}' not found!".format(url))
message.info("Removed bookmark {}".format(url))
@@ -1769,8 +1776,7 @@ def _search_cb(self, found, *, text):
def _search_navigation_cb(self, result):
"""Callback called from :search-prev/next."""
if result == browsertab.SearchNavigationResult.not_found:
- # FIXME check if this actually can happen...
- message.warning("Search result vanished...")
+ self._search_cb(found=False, text=self._tabbed_browser.search_text)
return
elif result == browsertab.SearchNavigationResult.found:
return
diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py
index e7e53c33ae7..28f20b0ef85 100644
--- a/qutebrowser/browser/downloads.py
+++ b/qutebrowser/browser/downloads.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Shared QtWebKit/QtWebEngine code for downloads."""
@@ -830,8 +817,13 @@ def cancel_for_origin(self) -> bool:
- file:// downloads from file:// URLs (open the file instead)
- http:// downloads from https:// URLs (mixed content)
"""
- origin = self.origin()
url = self.url()
+ if url.scheme() not in ["file", "http"]:
+ # WORKAROUND to avoid calling self.origin() if unneeded:
+ # https://github.com/qutebrowser/qutebrowser/issues/7854
+ return False
+
+ origin = self.origin()
if not origin.isValid():
return False
@@ -841,7 +833,7 @@ def cancel_for_origin(self) -> bool:
return True
if (url.scheme() == "http" and
- origin.isValid() and origin.scheme() == "https" and
+ origin.scheme() == "https" and
config.instance.get("downloads.prevent_mixed_content", url=origin)):
self._die("Aborting insecure download from secure page "
"(see downloads.prevent_mixed_content).")
diff --git a/qutebrowser/browser/downloadview.py b/qutebrowser/browser/downloadview.py
index f4790bc9fbd..4b6a8b2c89e 100644
--- a/qutebrowser/browser/downloadview.py
+++ b/qutebrowser/browser/downloadview.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""The ListView to display downloads in."""
@@ -48,6 +35,7 @@ class DownloadView(QListView):
QListView {
background-color: {{ conf.colors.downloads.bar.bg }};
font: {{ conf.fonts.downloads }};
+ border: 0;
}
QListView::item {
@@ -77,9 +65,10 @@ def __init__(self, model, parent=None):
self.clicked.connect(self.on_clicked)
def __repr__(self):
- model = self.model()
+ model = qtutils.add_optional(self.model())
+ count: Union[int, str]
if model is None:
- count = 'None' # type: ignore[unreachable]
+ count = 'None'
else:
count = model.rowCount()
return utils.get_repr(self, count=count)
@@ -173,9 +162,12 @@ def show_context_menu(self, point):
assert name is not None
assert handler is not None
action = self._menu.addAction(name)
+ assert action is not None
action.triggered.connect(handler)
if actions:
- self._menu.popup(self.viewport().mapToGlobal(point))
+ viewport = self.viewport()
+ assert viewport is not None
+ self._menu.popup(viewport.mapToGlobal(point))
def minimumSizeHint(self):
"""Override minimumSizeHint so the size is correct in a layout."""
diff --git a/qutebrowser/browser/eventfilter.py b/qutebrowser/browser/eventfilter.py
index a76ccd6d5c0..1cff11ac4a8 100644
--- a/qutebrowser/browser/eventfilter.py
+++ b/qutebrowser/browser/eventfilter.py
@@ -1,27 +1,15 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Event handling for a browser tab."""
from qutebrowser.qt import machinery
from qutebrowser.qt.core import QObject, QEvent, Qt, QTimer
+from qutebrowser.qt.widgets import QWidget
from qutebrowser.config import config
-from qutebrowser.utils import log, message, usertypes
+from qutebrowser.utils import log, message, usertypes, qtutils
from qutebrowser.keyinput import modeman
@@ -48,17 +36,42 @@ def eventFilter(self, obj, event):
"""Act on ChildAdded events."""
if event.type() == QEvent.Type.ChildAdded:
child = event.child()
- log.misc.debug("{} got new child {}, installing filter"
- .format(obj, child))
+ if not isinstance(child, QWidget):
+ # Can e.g. happen when dragging text
+ log.misc.debug(f"Ignoring new child {qtutils.qobj_repr(child)}")
+ return False
+
+ log.misc.debug(
+ f"{qtutils.qobj_repr(obj)} got new child {qtutils.qobj_repr(child)}, "
+ "installing filter")
# Additional sanity check, but optional
if self._widget is not None:
assert obj is self._widget
+ # WORKAROUND for unknown Qt bug losing focus on child change
+ # Carry on keyboard focus to the new child if:
+ # - 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)
+ 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"
+ ]
+ if children:
+ log.misc.debug("Focusing new child")
+ child.setFocus()
+
child.installEventFilter(self._filter)
elif event.type() == QEvent.Type.ChildRemoved:
child = event.child()
- log.misc.debug("{}: removed child {}".format(obj, child))
+ log.misc.debug(
+ f"{qtutils.qobj_repr(obj)}: removed child {qtutils.qobj_repr(child)}")
return False
diff --git a/qutebrowser/browser/greasemonkey.py b/qutebrowser/browser/greasemonkey.py
index 2c8aebbdc97..d41d463614a 100644
--- a/qutebrowser/browser/greasemonkey.py
+++ b/qutebrowser/browser/greasemonkey.py
@@ -1,19 +1,6 @@
-# Copyright 2017-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Load, parse and make available Greasemonkey scripts."""
diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py
index 8e4ae7987be..e32567e4dfa 100644
--- a/qutebrowser/browser/hints.py
+++ b/qutebrowser/browser/hints.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""A HintManager to draw hints over links."""
@@ -288,7 +275,7 @@ def preset_cmd_text(self, url: QUrl, context: HintContext) -> None:
raise HintingError("Invalid command text '{}'.".format(text))
cmd = objreg.get('status-command', scope='window', window=self._win_id)
- cmd.set_cmd_text(text)
+ cmd.cmd_set_text(text)
def download(self, elem: webelem.AbstractWebElement,
context: HintContext) -> None:
diff --git a/qutebrowser/browser/history.py b/qutebrowser/browser/history.py
index c0b23040cf9..45bfeddbfdd 100644
--- a/qutebrowser/browser/history.py
+++ b/qutebrowser/browser/history.py
@@ -1,19 +1,6 @@
-# Copyright 2015-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Simple history which gets written to disk."""
@@ -23,8 +10,9 @@
import pathlib
from typing import cast, Mapping, MutableSequence, Optional
+from qutebrowser.qt import machinery
from qutebrowser.qt.core import pyqtSlot, QUrl, QObject, pyqtSignal
-from qutebrowser.qt.widgets import QProgressDialog, QApplication
+from qutebrowser.qt.widgets import QProgressDialog, QApplication, QPushButton
from qutebrowser.config import config
from qutebrowser.api import cmdutils
@@ -54,7 +42,13 @@ def start(self, text):
self._progress.setMaximum(0) # unknown
self._progress.setMinimumDuration(0)
self._progress.setLabelText(text)
- self._progress.setCancelButton(None)
+
+ no_button = None
+ if machinery.IS_QT6:
+ # FIXME:mypy PyQt6 stubs issue
+ no_button = cast(QPushButton, None)
+
+ self._progress.setCancelButton(no_button)
self._progress.setAutoClose(False)
self._progress.show()
QApplication.processEvents()
diff --git a/qutebrowser/browser/inspector.py b/qutebrowser/browser/inspector.py
index a2ce67750b8..e60e4a2b801 100644
--- a/qutebrowser/browser/inspector.py
+++ b/qutebrowser/browser/inspector.py
@@ -1,19 +1,6 @@
-# Copyright 2015-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Base class for a QtWebKit/QtWebEngine web inspector."""
@@ -28,7 +15,7 @@
from qutebrowser.browser import eventfilter
from qutebrowser.config import configfiles, config
-from qutebrowser.utils import log, usertypes
+from qutebrowser.utils import log, usertypes, qtutils
from qutebrowser.keyinput import modeman
from qutebrowser.misc import miscwidgets
@@ -70,8 +57,9 @@ class _EventFilter(QObject):
clicked = pyqtSignal()
- def eventFilter(self, _obj: QObject, event: QEvent) -> bool:
+ def eventFilter(self, _obj: Optional[QObject], event: Optional[QEvent]) -> bool:
"""Translate mouse presses to a clicked signal."""
+ assert event is not None
if event.type() == QEvent.Type.MouseButtonPress:
self.clicked.emit()
return False
@@ -162,7 +150,7 @@ def set_position(self, position: Optional[Position]) -> None:
self.shutdown()
return
elif position == Position.window:
- self.setParent(None) # type: ignore[call-overload]
+ self.setParent(qtutils.QT_NONE)
self._load_state_geometry()
else:
self._splitter.set_inspector(self, position)
@@ -195,7 +183,7 @@ def _load_state_geometry(self) -> None:
if not ok:
log.init.warning("Error while loading geometry.")
- def closeEvent(self, _e: QCloseEvent) -> None:
+ def closeEvent(self, _e: Optional[QCloseEvent]) -> None:
"""Save the geometry when closed."""
data = self._widget.saveGeometry().data()
geom = base64.b64encode(data).decode('ASCII')
diff --git a/qutebrowser/browser/navigate.py b/qutebrowser/browser/navigate.py
index b73e36e8df5..e75365bcdab 100644
--- a/qutebrowser/browser/navigate.py
+++ b/qutebrowser/browser/navigate.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Implementation of :navigate."""
diff --git a/qutebrowser/browser/network/pac.py b/qutebrowser/browser/network/pac.py
index c66b6bc03ed..656c620db66 100644
--- a/qutebrowser/browser/network/pac.py
+++ b/qutebrowser/browser/network/pac.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Evaluation of PAC scripts."""
@@ -28,7 +15,7 @@
QHostAddress)
from qutebrowser.qt.qml import QJSEngine, QJSValue
-from qutebrowser.utils import log, utils, qtutils, resources, urlutils
+from qutebrowser.utils import log, qtlog, utils, qtutils, resources, urlutils
class ParseProxyError(Exception):
@@ -65,7 +52,8 @@ def new_method(self, *args, **kwargs):
return self._error_con.callAsConstructor([e])
# pylint: enable=protected-access
- deco = pyqtSlot(*args, result=QJSValue)
+ # FIXME:mypy PyQt6 stubs issue, passing type should work too
+ deco = pyqtSlot(*args, result="QJSValue")
return deco(new_method)
return _decorator
@@ -257,7 +245,7 @@ def __init__(self, url, parent=None):
url.setScheme(url.scheme()[len(pac_prefix):])
self._pac_url = url
- with log.disable_qt_msghandler():
+ with qtlog.disable_qt_msghandler():
# WORKAROUND for a hang when messages are printed, see our
# NetworkAccessManager subclass for details.
self._manager: Optional[QNetworkAccessManager] = QNetworkAccessManager()
@@ -276,6 +264,7 @@ def fetch(self):
"""Fetch the proxy from the remote URL."""
assert self._manager is not None
self._reply = self._manager.get(QNetworkRequest(self._pac_url))
+ assert self._reply is not None
self._reply.finished.connect(self._finish)
@pyqtSlot()
diff --git a/qutebrowser/browser/network/proxy.py b/qutebrowser/browser/network/proxy.py
index 714823d2cf8..f0c51185310 100644
--- a/qutebrowser/browser/network/proxy.py
+++ b/qutebrowser/browser/network/proxy.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Handling of proxies."""
@@ -21,7 +8,7 @@
from qutebrowser.qt.network import QNetworkProxy, QNetworkProxyFactory
from qutebrowser.config import config, configtypes
-from qutebrowser.utils import message, usertypes, urlutils, utils
+from qutebrowser.utils import message, usertypes, urlutils, utils, qtutils
from qutebrowser.misc import objects
from qutebrowser.browser.network import pac
@@ -51,7 +38,7 @@ def _warn_for_pac():
@pyqtSlot()
def shutdown():
QNetworkProxyFactory.setApplicationProxyFactory(
- None) # type: ignore[arg-type]
+ qtutils.QT_NONE)
class ProxyFactory(QNetworkProxyFactory):
diff --git a/qutebrowser/browser/pdfjs.py b/qutebrowser/browser/pdfjs.py
index fdece9a9e05..841285deb83 100644
--- a/qutebrowser/browser/pdfjs.py
+++ b/qutebrowser/browser/pdfjs.py
@@ -1,20 +1,7 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
-# Copyright 2015 Daniel Schadt
+# SPDX-FileCopyrightText: Daniel Schadt
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""pdf.js integration for qutebrowser."""
@@ -74,11 +61,11 @@ def generate_pdfjs_page(filename, url):
html = html.replace('',
''.format(script))
# WORKAROUND for the fact that PDF.js tries to use the Fetch API even with
- # qute:// URLs.
- pdfjs_script = ''
- html = html.replace(pdfjs_script,
- '\n' +
- pdfjs_script)
+ # qute:// URLs, this is probably no longer needed in PDFjs 4+. See #4235
+ html = html.replace(
+ '
',
+ '
\n\n'
+ )
return html
@@ -215,10 +202,24 @@ def _read_from_system(system_path, names):
return (None, None)
+def get_pdfjs_js_path():
+ """Checks for pdf.js main module availability and returns the path if available."""
+ paths = ['build/pdf.js', 'build/pdf.mjs']
+ for path in paths:
+ try:
+ get_pdfjs_res(path)
+ except PDFJSNotFound:
+ pass
+ else:
+ return path
+
+ raise PDFJSNotFound(" or ".join(paths))
+
+
def is_available():
- """Return true if a pdfjs installation is available."""
+ """Return true if certain parts of a pdfjs installation are available."""
try:
- get_pdfjs_res('build/pdf.js')
+ get_pdfjs_js_path()
get_pdfjs_res('web/viewer.html')
except PDFJSNotFound:
return False
diff --git a/qutebrowser/browser/qtnetworkdownloads.py b/qutebrowser/browser/qtnetworkdownloads.py
index cd4a75351de..9dd507ab593 100644
--- a/qutebrowser/browser/qtnetworkdownloads.py
+++ b/qutebrowser/browser/qtnetworkdownloads.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Download manager."""
@@ -29,7 +16,7 @@
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
+from qutebrowser.utils import message, usertypes, log, urlutils, utils, debug, objreg, qtlog
from qutebrowser.misc import quitter
from qutebrowser.browser import downloads
from qutebrowser.browser.webkit import http
@@ -121,7 +108,7 @@ def _do_die(self):
self._reply.errorOccurred.disconnect()
self._reply.readyRead.disconnect()
- with log.hide_qt_warning('QNetworkReplyImplPrivate::error: Internal '
+ with qtlog.hide_qt_warning('QNetworkReplyImplPrivate::error: Internal '
'problem, this method must only be called '
'once.'):
# See https://codereview.qt-project.org/#/c/107863/
diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py
index 15e4bc769e4..f1c6711fd72 100644
--- a/qutebrowser/browser/qutescheme.py
+++ b/qutebrowser/browser/qutescheme.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Backend-independent qute://* code.
@@ -22,6 +9,7 @@
_HANDLERS: The handlers registered via decorators.
"""
+import sys
import html
import json
import os
@@ -580,9 +568,12 @@ 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')
+ elif path == '/qt5':
+ is_venv = hasattr(sys, 'real_prefix') or sys.base_prefix != sys.prefix
+ src = jinja.render('warning-qt5.html',
+ title='Switch to Qt 6',
+ is_venv=is_venv,
+ prefix=sys.prefix)
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 6e87bc1a51d..358af6d9506 100644
--- a/qutebrowser/browser/shared.py
+++ b/qutebrowser/browser/shared.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Various utilities shared between webpage/webview subclasses."""
diff --git a/qutebrowser/browser/signalfilter.py b/qutebrowser/browser/signalfilter.py
index e1584bd1b89..3ca0f89dba9 100644
--- a/qutebrowser/browser/signalfilter.py
+++ b/qutebrowser/browser/signalfilter.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""A filter for signals which either filters or passes them."""
diff --git a/qutebrowser/browser/urlmarks.py b/qutebrowser/browser/urlmarks.py
index 2ae8fbbe13c..2d2563a1a4f 100644
--- a/qutebrowser/browser/urlmarks.py
+++ b/qutebrowser/browser/urlmarks.py
@@ -1,20 +1,7 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
-# Copyright 2015-2018 Antoni Boucher
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Antoni Boucher
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Managers for bookmarks and quickmarks.
@@ -111,6 +98,11 @@ def delete(self, key):
del self.marks[key]
self.changed.emit()
+ def clear(self):
+ """Delete all marks."""
+ self.marks.clear()
+ self.changed.emit()
+
class QuickmarkManager(UrlMarkManager):
diff --git a/qutebrowser/browser/webelem.py b/qutebrowser/browser/webelem.py
index 8d1d61b8008..2356ad08694 100644
--- a/qutebrowser/browser/webelem.py
+++ b/qutebrowser/browser/webelem.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Generic web element related code."""
diff --git a/qutebrowser/browser/webengine/__init__.py b/qutebrowser/browser/webengine/__init__.py
index 385f7f89c84..913596a8562 100644
--- a/qutebrowser/browser/webengine/__init__.py
+++ b/qutebrowser/browser/webengine/__init__.py
@@ -1,18 +1,5 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Classes related to the browser widgets for QtWebEngine."""
diff --git a/qutebrowser/browser/webengine/certificateerror.py b/qutebrowser/browser/webengine/certificateerror.py
index 2201492c998..3403941fa6a 100644
--- a/qutebrowser/browser/webengine/certificateerror.py
+++ b/qutebrowser/browser/webengine/certificateerror.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Wrapper over a QWebEngineCertificateError."""
diff --git a/qutebrowser/browser/webengine/cookies.py b/qutebrowser/browser/webengine/cookies.py
index 49af750cb56..9d0e0f33af5 100644
--- a/qutebrowser/browser/webengine/cookies.py
+++ b/qutebrowser/browser/webengine/cookies.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Filter for QtWebEngine cookies."""
diff --git a/qutebrowser/browser/webengine/darkmode.py b/qutebrowser/browser/webengine/darkmode.py
index d67aa1d29a1..b1b81c61e2a 100644
--- a/qutebrowser/browser/webengine/darkmode.py
+++ b/qutebrowser/browser/webengine/darkmode.py
@@ -1,19 +1,6 @@
-# Copyright 2020-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Get darkmode arguments to pass to Qt.
@@ -98,7 +85,34 @@
------
- New IncreaseTextContrast:
-https://chromium-review.googlesource.com/c/chromium/src/+/2893236
+ https://chromium-review.googlesource.com/c/chromium/src/+/2893236
+ (UNSUPPORTED because dropped in 6.5)
+
+Qt 6.4
+------
+
+- Renamed TextBrightnessThreshold to ForegroundBrightnessThreshold
+
+ "Correct brightness threshold of darkmode color classifier"
+ https://chromium-review.googlesource.com/c/chromium/src/+/3344100
+
+ "Rename text_classifier to foreground_classifier"
+ https://chromium-review.googlesource.com/c/chromium/src/+/3226389
+
+- Grayscale darkmode support removed:
+ https://chromium-review.googlesource.com/c/chromium/src/+/3238985
+
+Qt 6.5
+------
+
+- IncreaseTextContrast removed:
+ https://chromium-review.googlesource.com/c/chromium/src/+/3821841
+
+Qt 6.6
+------
+
+- New alternative image classifier:
+ https://chromium-review.googlesource.com/c/chromium/src/+/3987823
"""
import os
@@ -122,7 +136,8 @@ class Variant(enum.Enum):
qt_515_2 = enum.auto()
qt_515_3 = enum.auto()
- qt_63 = enum.auto()
+ qt_64 = enum.auto()
+ qt_66 = enum.auto()
# Mapping from a colors.webpage.darkmode.algorithm setting value to
@@ -149,6 +164,15 @@ class Variant(enum.Enum):
'always': 0, # kFilterAll
'never': 1, # kFilterNone
'smart': 2, # kFilterSmart
+ 'smart-simple': 2, # kFilterSmart
+}
+
+# Using the colors.webpage.darkmode.policy.images setting, shared with _IMAGE_POLICIES
+_IMAGE_CLASSIFIERS = {
+ 'always': None,
+ 'never': None,
+ 'smart': 0, # kNumColorsWithMlFallback
+ 'smart-simple': 1, # kTransparencyAndNumColors
}
# Mapping from a colors.webpage.darkmode.policy.page setting value to
@@ -176,14 +200,17 @@ class _Setting:
option: str
chromium_key: str
- mapping: Optional[Mapping[Any, Union[str, int]]] = None
+ mapping: Optional[Mapping[Any, Union[str, int, None]]] = None
def _value_str(self, value: Any) -> str:
if self.mapping is None:
return str(value)
return str(self.mapping[value])
- def chromium_tuple(self, value: Any) -> Tuple[str, str]:
+ def chromium_tuple(self, value: Any) -> Optional[Tuple[str, str]]:
+ """Get the Chromium key and value, or None if no value should be set."""
+ if self.mapping is not None and self.mapping[value] is None:
+ return None
return self.chromium_key, self._value_str(value)
def with_prefix(self, prefix: str) -> '_Setting':
@@ -249,6 +276,20 @@ def copy_add_setting(self, setting: _Setting) -> '_Definition':
new._settings = self._settings + (setting,) # pylint: disable=protected-access
return new
+ def copy_replace_setting(self, option: str, chromium_key: str) -> '_Definition':
+ """Get a new _Definition object with `old` replaced by `new`.
+
+ If `old` is not in the settings list, return the old _Definition object.
+ """
+ new = copy.deepcopy(self)
+
+ for setting in new._settings: # pylint: disable=protected-access
+ if setting.option == option:
+ setting.chromium_key = chromium_key
+ return new
+
+ raise ValueError(f"Setting {option} not found in {self}")
+
# Our defaults for policy.images are different from Chromium's, so we mark it as
# mandatory setting.
@@ -260,12 +301,10 @@ def copy_add_setting(self, setting: _Setting) -> '_Definition':
_Setting('policy.images', 'ImagePolicy', _IMAGE_POLICIES),
_Setting('contrast', 'Contrast'),
- _Setting('grayscale.all', 'Grayscale', _BOOLS),
_Setting('policy.page', 'PagePolicy', _PAGE_POLICIES),
- _Setting('threshold.text', 'TextBrightnessThreshold'),
+ _Setting('threshold.foreground', 'TextBrightnessThreshold'),
_Setting('threshold.background', 'BackgroundBrightnessThreshold'),
- _Setting('grayscale.images', 'ImageGrayscale'),
mandatory={'enabled', 'policy.images'},
prefix='forceDarkMode',
@@ -278,24 +317,25 @@ def copy_add_setting(self, setting: _Setting) -> '_Definition':
_Setting('policy.images', 'ImagePolicy', _IMAGE_POLICIES),
_Setting('contrast', 'ContrastPercent'),
- _Setting('grayscale.all', 'IsGrayScale', _BOOLS),
- _Setting('threshold.text', 'TextBrightnessThreshold'),
+ _Setting('threshold.foreground', 'TextBrightnessThreshold'),
_Setting('threshold.background', 'BackgroundBrightnessThreshold'),
- _Setting('grayscale.images', 'ImageGrayScalePercent'),
mandatory={'enabled', 'policy.images'},
prefix='',
switch_names={'enabled': _BLINK_SETTINGS, None: 'dark-mode-settings'},
),
}
-_DEFINITIONS[Variant.qt_63] = _DEFINITIONS[Variant.qt_515_3].copy_add_setting(
- _Setting('increase_text_contrast', 'IncreaseTextContrast', _INT_BOOLS),
+_DEFINITIONS[Variant.qt_64] = _DEFINITIONS[Variant.qt_515_3].copy_replace_setting(
+ 'threshold.foreground', 'ForegroundBrightnessThreshold',
+)
+_DEFINITIONS[Variant.qt_66] = _DEFINITIONS[Variant.qt_64].copy_add_setting(
+ _Setting('policy.images', 'ImageClassifierPolicy', _IMAGE_CLASSIFIERS),
)
_SettingValType = Union[str, usertypes.Unset]
-_PREFERRED_COLOR_SCHEME_DEFINITIONS: Mapping[Variant, Mapping[_SettingValType, str]] = {
+_PREFERRED_COLOR_SCHEME_DEFINITIONS: MutableMapping[Variant, Mapping[_SettingValType, str]] = {
Variant.qt_515_2: {
# 0: no-preference (not exposed)
"dark": "1",
@@ -311,12 +351,11 @@ def copy_add_setting(self, setting: _Setting) -> '_Definition':
"dark": "0",
"light": "1",
},
-
- Variant.qt_63: {
- "dark": "0",
- "light": "1",
- }
}
+for darkmode_variant in Variant:
+ if darkmode_variant not in _PREFERRED_COLOR_SCHEME_DEFINITIONS:
+ _PREFERRED_COLOR_SCHEME_DEFINITIONS[darkmode_variant] = \
+ _PREFERRED_COLOR_SCHEME_DEFINITIONS[Variant.qt_515_3]
def _variant(versions: version.WebEngineVersions) -> Variant:
@@ -328,8 +367,10 @@ def _variant(versions: version.WebEngineVersions) -> Variant:
except KeyError:
log.init.warning(f"Ignoring invalid QUTE_DARKMODE_VARIANT={env_var}")
- if versions.webengine >= utils.VersionNumber(6, 3):
- return Variant.qt_63
+ if versions.webengine >= utils.VersionNumber(6, 6):
+ return Variant.qt_66
+ elif versions.webengine >= utils.VersionNumber(6, 4):
+ return Variant.qt_64
elif (versions.webengine == utils.VersionNumber(5, 15, 2) and
versions.chromium_major == 87):
# WORKAROUND for Gentoo packaging something newer as 5.15.2...
@@ -391,6 +432,8 @@ def settings(
if isinstance(value, usertypes.Unset):
continue
- result[switch_name].append(setting.chromium_tuple(value))
+ chromium_tuple = setting.chromium_tuple(value)
+ if chromium_tuple is not None:
+ result[switch_name].append(chromium_tuple)
return result
diff --git a/qutebrowser/browser/webengine/interceptor.py b/qutebrowser/browser/webengine/interceptor.py
index 75acb3252eb..161f5ffabc7 100644
--- a/qutebrowser/browser/webengine/interceptor.py
+++ b/qutebrowser/browser/webengine/interceptor.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""A request interceptor taking care of adblocking and custom headers."""
@@ -23,7 +10,7 @@
from qutebrowser.config import websettings, config
from qutebrowser.browser import shared
-from qutebrowser.utils import debug, log
+from qutebrowser.utils import debug, log, qtutils
from qutebrowser.extensions import interceptors
from qutebrowser.misc import objects
@@ -33,9 +20,8 @@ class WebEngineRequest(interceptors.Request):
"""QtWebEngine-specific request interceptor functionality."""
_WHITELISTED_REQUEST_METHODS = {
- # FIXME:mypy PyQt6-stubs issue?
- QByteArray(b'GET'), # type: ignore[call-overload,unused-ignore]
- QByteArray(b'HEAD'), # type: ignore[call-overload,unused-ignore]
+ QByteArray(b'GET'),
+ QByteArray(b'HEAD'),
}
def __init__(self, *args, webengine_info, **kwargs):
@@ -49,6 +35,11 @@ def redirect(self, url: QUrl, *, ignore_unsupported: bool = False) -> None:
if self._webengine_info is None:
raise interceptors.RedirectException("Request improperly initialized.")
+ try:
+ qtutils.ensure_valid(url)
+ except qtutils.QtValueError as e:
+ raise interceptors.RedirectException(f"Redirect to invalid URL: {e}")
+
# Redirecting a request that contains payload data is not allowed.
# To be safe, abort on any request not in a whitelist.
verb = self._webengine_info.requestMethod()
diff --git a/qutebrowser/browser/webengine/notification.py b/qutebrowser/browser/webengine/notification.py
index d140a8c61fa..e8b2e27f156 100644
--- a/qutebrowser/browser/webengine/notification.py
+++ b/qutebrowser/browser/webengine/notification.py
@@ -1,19 +1,6 @@
-# Copyright 2020 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Different ways of showing notifications to the user.
@@ -126,6 +113,9 @@ class DBusError(Error):
# https://crashes.qutebrowser.org/view/de62220a
# after "Notification daemon did quit!"
"org.freedesktop.DBus.Error.UnknownObject",
+
+ # notmuch-sha1-ef7b6e9e79e5f2f6cba90224122288895c1fe0d8
+ "org.freedesktop.DBus.Error.ServiceUnknown",
}
def __init__(self, msg: QDBusMessage) -> None:
@@ -869,12 +859,15 @@ def _get_server_info(self) -> None:
log.misc.debug(f"Enabling quirks {quirks}")
self._quirks = quirks
- expected_spec_version = self._quirks.spec_version or self.SPEC_VERSION
- if spec_version != expected_spec_version:
+ expected_spec_versions = [self.SPEC_VERSION]
+ if self._quirks.spec_version is not None:
+ expected_spec_versions.append(self._quirks.spec_version)
+
+ if spec_version not in expected_spec_versions:
log.misc.warning(
f"Notification server ({name} {ver} by {vendor}) implements "
- f"spec {spec_version}, but {expected_spec_version} was expected. "
- f"If {name} is up to date, please report a qutebrowser bug.")
+ f"spec {spec_version}, but {'/'.join(expected_spec_versions)} was "
+ f"expected. If {name} is up to date, please report a qutebrowser bug.")
# https://specifications.freedesktop.org/notification-spec/latest/ar01s08.html
icon_key_overrides = {
@@ -1108,9 +1101,10 @@ def _convert_image(self, qimage: QImage) -> Optional[QDBusArgument]:
if padding and self._quirks.no_padded_images:
return None
- bits = qimage.constBits().asstring(size)
- # FIXME:mypy PyQt6-stubs issue
- image_data.add(QByteArray(bits)) # type: ignore[call-overload,unused-ignore]
+ bits_ptr = qimage.constBits()
+ assert bits_ptr is not None
+ bits = bits_ptr.asstring(size)
+ image_data.add(QByteArray(bits))
image_data.endStructure()
return image_data
diff --git a/qutebrowser/browser/webengine/spell.py b/qutebrowser/browser/webengine/spell.py
index 09913a9277b..d1e9214324d 100644
--- a/qutebrowser/browser/webengine/spell.py
+++ b/qutebrowser/browser/webengine/spell.py
@@ -1,20 +1,8 @@
-# Copyright 2017-2021 Florian Bruhin (The Compiler)
-# Copyright 2017-2018 Michal Siedlaczek
-
-# 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.
+# SPDX-FileCopyrightText: Michal Siedlaczek
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
+
"""Installing and configuring spell-checking for QtWebEngine."""
diff --git a/qutebrowser/browser/webengine/tabhistory.py b/qutebrowser/browser/webengine/tabhistory.py
index 30f3facdb94..340fab5505c 100644
--- a/qutebrowser/browser/webengine/tabhistory.py
+++ b/qutebrowser/browser/webengine/tabhistory.py
@@ -1,19 +1,6 @@
-# Copyright 2015-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""QWebHistory serializer for QtWebEngine."""
@@ -153,6 +140,8 @@ def serialize(items):
for item in items:
_serialize_item(item, stream)
- stream.device().reset()
+ dev = stream.device()
+ assert dev is not None
+ dev.reset()
qtutils.check_qdatastream(stream)
return stream, data, cur_user_data
diff --git a/qutebrowser/browser/webengine/webenginedownloads.py b/qutebrowser/browser/webengine/webenginedownloads.py
index eb4f1c9a1b0..e8e6418e0b6 100644
--- a/qutebrowser/browser/webengine/webenginedownloads.py
+++ b/qutebrowser/browser/webengine/webenginedownloads.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""QtWebEngine specific code for downloads."""
diff --git a/qutebrowser/browser/webengine/webengineelem.py b/qutebrowser/browser/webengine/webengineelem.py
index 7e5da7b8bf2..c387ebbcf96 100644
--- a/qutebrowser/browser/webengine/webengineelem.py
+++ b/qutebrowser/browser/webengine/webengineelem.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""QtWebEngine specific part of the web element API."""
@@ -24,7 +11,7 @@
from qutebrowser.qt.widgets import QApplication
from qutebrowser.qt.webenginecore import QWebEngineSettings
-from qutebrowser.utils import log, javascript, urlutils, usertypes, utils
+from qutebrowser.utils import log, javascript, urlutils, usertypes, utils, version
from qutebrowser.browser import webelem
if TYPE_CHECKING:
@@ -226,6 +213,19 @@ def _requires_user_interaction(self) -> bool:
return True
if baseurl.scheme() == url.scheme(): # e.g. a qute:// link
return False
+
+ # Qt 6.3+ needs a user interaction to allow navigations from qute:// to
+ # outside qute:// (like e.g. on qute://bookmarks), as well as from file:// to
+ # outside of file:// (e.g. users having a local bookmarks.html).
+ versions = version.qtwebengine_versions()
+ for scheme in ["qute", "file"]:
+ if (
+ baseurl.scheme() == scheme and
+ url.scheme() != scheme and
+ versions.webengine >= utils.VersionNumber(6, 3)
+ ):
+ return True
+
return url.scheme() not in urlutils.WEBENGINE_SCHEMES
def _click_editable(self, click_target: usertypes.ClickTarget) -> None:
diff --git a/qutebrowser/browser/webengine/webengineinspector.py b/qutebrowser/browser/webengine/webengineinspector.py
index 640d35d6c82..d37f41ba5b0 100644
--- a/qutebrowser/browser/webengine/webengineinspector.py
+++ b/qutebrowser/browser/webengine/webengineinspector.py
@@ -1,19 +1,6 @@
-# Copyright 2015-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Customized QWebInspector for QtWebEngine."""
@@ -48,14 +35,19 @@ def createWindow(self,
See WebEngineView.createWindow for details.
"""
- inspected_page = self.page().inspectedPage()
+ our_page = self.page()
+ assert our_page is not None
+ inspected_page = our_page.inspectedPage()
+ assert inspected_page is not None
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)
+ ret = webview.WebEngineView.forPage(newpage)
+ assert ret is not None
+ return ret
class WebEngineInspector(inspector.AbstractWebInspector):
@@ -101,16 +93,17 @@ def _check_devtools_resources(self) -> None:
def inspect(self, page: QWebEnginePage) -> None:
if not self._widget:
view = WebEngineInspectorView()
- inspector_page = QWebEnginePage(
+ new_page = QWebEnginePage(
page.profile(),
self
)
- inspector_page.windowCloseRequested.connect(self._on_window_close_requested)
- view.setPage(inspector_page)
+ new_page.windowCloseRequested.connect(self._on_window_close_requested)
+ view.setPage(new_page)
self._settings = webenginesettings.WebEngineSettings(view.settings())
self._set_widget(view)
inspector_page = self._widget.page()
+ assert inspector_page is not None
assert inspector_page.profile() == page.profile()
inspector_page.setInspectedPage(page)
diff --git a/qutebrowser/browser/webengine/webenginequtescheme.py b/qutebrowser/browser/webengine/webenginequtescheme.py
index 4a09c81fbc3..5d617f87ba4 100644
--- a/qutebrowser/browser/webengine/webenginequtescheme.py
+++ b/qutebrowser/browser/webengine/webenginequtescheme.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""QtWebEngine specific qute://* handlers and glue code."""
@@ -25,8 +12,7 @@
from qutebrowser.browser import qutescheme
from qutebrowser.utils import log, qtutils
-# FIXME:mypy PyQt6-stubs issue?
-_QUTE = QByteArray(b'qute') # type: ignore[call-overload,unused-ignore]
+_QUTE = QByteArray(b'qute')
class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
diff --git a/qutebrowser/browser/webengine/webenginesettings.py b/qutebrowser/browser/webengine/webenginesettings.py
index 5e83935ca4e..2b375a7b08b 100644
--- a/qutebrowser/browser/webengine/webenginesettings.py
+++ b/qutebrowser/browser/webengine/webenginesettings.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Bridge from QWebEngineSettings to our own settings.
@@ -37,6 +24,7 @@
webenginedownloads, notification)
from qutebrowser.config import config, websettings
from qutebrowser.config.websettings import AttributeInfo as Attr
+from qutebrowser.misc import pakjoy
from qutebrowser.utils import (standarddir, qtutils, message, log,
urlmatch, usertypes, objreg, version)
if TYPE_CHECKING:
@@ -63,8 +51,12 @@ class _SettingsWrapper:
For read operations, the default profile value is always used.
"""
+ def _default_profile_settings(self):
+ assert default_profile is not None
+ return default_profile.settings()
+
def _settings(self):
- yield default_profile.settings()
+ yield self._default_profile_settings()
if private_profile:
yield private_profile.settings()
@@ -89,19 +81,19 @@ def setUnknownUrlSchemePolicy(self, policy):
settings.setUnknownUrlSchemePolicy(policy)
def testAttribute(self, attribute):
- return default_profile.settings().testAttribute(attribute)
+ return self._default_profile_settings().testAttribute(attribute)
def fontSize(self, fonttype):
- return default_profile.settings().fontSize(fonttype)
+ return self._default_profile_settings().fontSize(fonttype)
def fontFamily(self, which):
- return default_profile.settings().fontFamily(which)
+ return self._default_profile_settings().fontFamily(which)
def defaultTextEncoding(self):
- return default_profile.settings().defaultTextEncoding()
+ return self._default_profile_settings().defaultTextEncoding()
def unknownUrlSchemePolicy(self):
- return default_profile.settings().unknownUrlSchemePolicy()
+ return self._default_profile_settings().unknownUrlSchemePolicy()
class WebEngineSettings(websettings.AbstractSettings):
@@ -156,6 +148,12 @@ class WebEngineSettings(websettings.AbstractSettings):
Attr(QWebEngineSettings.WebAttribute.AutoLoadIconsForPage,
converter=lambda val: val != 'never'),
}
+ try:
+ _ATTRIBUTES['content.canvas_reading'] = Attr(
+ QWebEngineSettings.WebAttribute.ReadingFromCanvasEnabled) # type: ignore[attr-defined,unused-ignore]
+ except AttributeError:
+ # Added in QtWebEngine 6.6
+ pass
_FONT_SIZES = {
'fonts.web.size.minimum':
@@ -354,7 +352,10 @@ def _init_user_agent_str(ua):
def init_user_agent():
- _init_user_agent_str(QWebEngineProfile.defaultProfile().httpUserAgent())
+ """Make the default WebEngine user agent available via parsed_user_agent."""
+ actual_default_profile = QWebEngineProfile.defaultProfile()
+ assert actual_default_profile is not None
+ _init_user_agent_str(actual_default_profile.httpUserAgent())
def _init_profile(profile: QWebEngineProfile) -> None:
@@ -443,12 +444,21 @@ def _init_site_specific_quirks():
"AppleWebKit/{webkit_version} (KHTML, like Gecko) "
"{upstream_browser_key}/{upstream_browser_version} "
"Safari/{webkit_version}")
- new_chrome_ua = ("Mozilla/5.0 ({os_info}) "
- "AppleWebKit/537.36 (KHTML, like Gecko) "
- "Chrome/99 "
- "Safari/537.36")
firefox_ua = "Mozilla/5.0 ({os_info}; rv:90.0) Gecko/20100101 Firefox/90.0"
+ def maybe_newer_chrome_ua(at_least_version):
+ """Return a new UA if our current chrome version isn't at least at_least_version."""
+ current_chome_version = version.qtwebengine_versions().chromium_major
+ if current_chome_version >= at_least_version:
+ return None
+
+ return (
+ "Mozilla/5.0 ({os_info}) "
+ "AppleWebKit/537.36 (KHTML, like Gecko) "
+ f"Chrome/{at_least_version} "
+ "Safari/537.36"
+ )
+
user_agents = [
# Needed to avoid a ""WhatsApp works with Google Chrome 36+" error
# page which doesn't allow to use WhatsApp Web at all. Also see the
@@ -463,13 +473,14 @@ 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),
+ # October 2023: Slack claims they only support 112+. On #7951 at least
+ # one user claims it still works fine on 108 based Qt versions.
+ ("ua-slack", 'https://*.slack.com/*', maybe_newer_chrome_ua(112)),
]
for name, pattern, ua in user_agents:
+ if not ua:
+ continue
if name not in config.val.content.site_specific_quirks.skip:
config.instance.set_obj('content.headers.user_agent', ua,
pattern=urlmatch.UrlPattern(pattern),
@@ -549,7 +560,11 @@ def init():
_global_settings = WebEngineSettings(_SettingsWrapper())
log.init.debug("Initializing profiles...")
- _init_default_profile()
+
+ # Apply potential resource patches while initializing profiles.
+ with pakjoy.patch_webengine():
+ _init_default_profile()
+
init_private_profile()
config.instance.changed.connect(_update_settings)
diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py
index e55d75ecd13..1c712db5e80 100644
--- a/qutebrowser/browser/webengine/webenginetab.py
+++ b/qutebrowser/browser/webengine/webenginetab.py
@@ -1,23 +1,11 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
-"""Wrapper over a QWebEngineView."""
+"""Wrapper over a WebEngineView."""
import math
+import struct
import functools
import dataclasses
import re
@@ -25,9 +13,8 @@
from typing import cast, Union, Optional
from qutebrowser.qt.core import (pyqtSignal, pyqtSlot, Qt, QPoint, QPointF, QTimer, QUrl,
- QObject)
+ QObject, QByteArray)
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
@@ -400,7 +387,8 @@ def selection(self, callback):
# 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?
+ # With Qt 6.2-6.5, there still seem to be issues (especially with
+ # multi-line text)
self._tab.run_js_async(javascript.assemble('caret', 'getSelection'),
callback)
@@ -624,8 +612,16 @@ def __init__(self, tab: 'WebEngineTab') -> None:
self._tab = tab
self._history = cast(QWebEngineHistory, None)
+ def _serialize_data(self, stream_version, count, current_index):
+ return struct.pack(">IIi", stream_version, count, current_index)
+
def serialize(self):
- return qtutils.serialize(self._history)
+ data = qtutils.serialize(self._history)
+ # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-117489
+ if data == self._serialize_data(stream_version=4, count=1, current_index=0):
+ fixed = self._serialize_data(stream_version=4, count=0, current_index=-1)
+ return QByteArray(fixed)
+ return data
def deserialize(self, data):
qtutils.deserialize(data, self._history)
@@ -828,6 +824,8 @@ def _connect_signals(self):
page.recentlyAudibleChanged.connect(self._delayed_recently_audible_changed)
self._tab.url_changed.connect(self._on_url_changed)
config.instance.changed.connect(self._on_config_changed)
+ self._silence_timer.timeout.connect(functools.partial(
+ self.recently_audible_changed.emit, False))
# WORKAROUND for recentlyAudibleChanged being emitted without delay from the moment
# that audio is dropped.
@@ -843,8 +841,6 @@ def _delayed_recently_audible_changed(self, recently_audible):
# Ignore all subsequent calls while the tab is muted with an active timer
if timer.isActive():
return
- timer.timeout.connect(
- functools.partial(self.recently_audible_changed.emit, recently_audible))
timer.start()
def set_muted(self, muted: bool, override: bool = False) -> None:
@@ -1270,7 +1266,7 @@ class WebEngineTab(browsertab.AbstractTab):
abort_questions = pyqtSignal()
- _widget: QWebEngineView
+ _widget: webview.WebEngineView
search: WebEngineSearch
audio: WebEngineAudio
printing: WebEnginePrinting
diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py
index 9d58c037947..a6f2ae11338 100644
--- a/qutebrowser/browser/webengine/webview.py
+++ b/qutebrowser/browser/webengine/webview.py
@@ -1,34 +1,25 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""The main browser widget for QtWebEngine."""
-from typing import List, Iterable
+import mimetypes
+from typing import List, Iterable, Optional
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.qt.webenginecore import (
+ QWebEnginePage, QWebEngineCertificateError, QWebEngineSettings,
+ QWebEngineHistory,
+)
from qutebrowser.browser import shared
from qutebrowser.browser.webengine import webenginesettings, certificateerror
from qutebrowser.config import config
-from qutebrowser.utils import log, debug, usertypes
+from qutebrowser.utils import log, debug, usertypes, qtutils
_QB_FILESELECTION_MODES = {
@@ -54,7 +45,9 @@ def __init__(self, *, tabdata, win_id, private, parent=None):
self._win_id = win_id
self._tabdata = tabdata
- theme_color = self.style().standardPalette().color(QPalette.ColorRole.Base)
+ style = self.style()
+ assert style is not None
+ theme_color = style.standardPalette().color(QPalette.ColorRole.Base)
if private:
assert webenginesettings.private_profile is not None
profile = webenginesettings.private_profile
@@ -139,6 +132,57 @@ def contextMenuEvent(self, ev):
return
super().contextMenuEvent(ev)
+ def page(self) -> "WebEnginePage":
+ """Return the page for this view."""
+ maybe_page = super().page()
+ assert maybe_page is not None
+ assert isinstance(maybe_page, WebEnginePage)
+ return maybe_page
+
+ def settings(self) -> "QWebEngineSettings":
+ """Return the settings for this view."""
+ maybe_settings = super().settings()
+ assert maybe_settings is not None
+ return maybe_settings
+
+ def history(self) -> "QWebEngineHistory":
+ """Return the history for this view."""
+ maybe_history = super().history()
+ assert maybe_history is not None
+ return maybe_history
+
+
+def extra_suffixes_workaround(upstream_mimetypes):
+ """Return any extra suffixes for mimetypes in upstream_mimetypes.
+
+ Return any file extensions (aka suffixes) for mimetypes listed in
+ upstream_mimetypes that are not already contained in there.
+
+ WORKAROUND: for https://bugreports.qt.io/browse/QTBUG-116905
+ Affected Qt versions > 6.2.2 (probably) < 6.7.0
+ """
+ if not (
+ qtutils.version_check("6.2.3", compiled=False)
+ and not qtutils.version_check("6.7.0", compiled=False)
+ ):
+ return set()
+
+ suffixes = {entry for entry in upstream_mimetypes if entry.startswith(".")}
+ mimes = {entry for entry in upstream_mimetypes if "/" in entry}
+ python_suffixes = set()
+ for mime in mimes:
+ if mime.endswith("/*"):
+ python_suffixes.update(
+ [
+ suffix
+ for suffix, mimetype in mimetypes.types_map.items()
+ if mimetype.startswith(mime[:-1])
+ ]
+ )
+ else:
+ python_suffixes.update(mimetypes.guess_all_extensions(mime))
+ return python_suffixes - suffixes
+
class WebEnginePage(QWebEnginePage):
@@ -272,13 +316,28 @@ def acceptNavigationRequest(self,
def chooseFiles(
self,
mode: QWebEnginePage.FileSelectionMode,
- old_files: Iterable[str],
- accepted_mimetypes: Iterable[str],
+ old_files: Iterable[Optional[str]],
+ accepted_mimetypes: Iterable[Optional[str]],
) -> List[str]:
"""Override chooseFiles to (optionally) invoke custom file uploader."""
+ accepted_mimetypes_filtered = [m for m in accepted_mimetypes if m is not None]
+ old_files_filtered = [f for f in old_files if f is not None]
+ extra_suffixes = extra_suffixes_workaround(accepted_mimetypes_filtered)
+ if extra_suffixes:
+ log.webview.debug(
+ "adding extra suffixes to filepicker: "
+ f"before={accepted_mimetypes_filtered} "
+ f"added={extra_suffixes}",
+ )
+ accepted_mimetypes_filtered = list(
+ accepted_mimetypes_filtered
+ ) + list(extra_suffixes)
+
handler = config.val.fileselect.handler
if handler == "default":
- return super().chooseFiles(mode, old_files, accepted_mimetypes)
+ return super().chooseFiles(
+ mode, old_files_filtered, accepted_mimetypes_filtered,
+ )
assert handler == "external", handler
try:
qb_mode = _QB_FILESELECTION_MODES[mode]
@@ -286,6 +345,8 @@ def chooseFiles(
log.webview.warning(
f"Got file selection mode {mode}, but we don't support that!"
)
- return super().chooseFiles(mode, old_files, accepted_mimetypes)
+ return super().chooseFiles(
+ mode, old_files_filtered, accepted_mimetypes_filtered,
+ )
return shared.choose_file(qb_mode=qb_mode)
diff --git a/qutebrowser/browser/webkit/__init__.py b/qutebrowser/browser/webkit/__init__.py
index f790ea02e41..05274d2ffab 100644
--- a/qutebrowser/browser/webkit/__init__.py
+++ b/qutebrowser/browser/webkit/__init__.py
@@ -1,18 +1,5 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Classes related to the browser widgets for QtWebKit."""
diff --git a/qutebrowser/browser/webkit/cache.py b/qutebrowser/browser/webkit/cache.py
index 2f6d1a46c43..7654ea83b55 100644
--- a/qutebrowser/browser/webkit/cache.py
+++ b/qutebrowser/browser/webkit/cache.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""HTTP network cache."""
diff --git a/qutebrowser/browser/webkit/certificateerror.py b/qutebrowser/browser/webkit/certificateerror.py
index fc7e1b6523e..59d9cc89775 100644
--- a/qutebrowser/browser/webkit/certificateerror.py
+++ b/qutebrowser/browser/webkit/certificateerror.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""A wrapper over a list of QSslErrors."""
diff --git a/qutebrowser/browser/webkit/cookies.py b/qutebrowser/browser/webkit/cookies.py
index fae546e9665..9e6ae2f1b14 100644
--- a/qutebrowser/browser/webkit/cookies.py
+++ b/qutebrowser/browser/webkit/cookies.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Handling of HTTP cookies."""
diff --git a/qutebrowser/browser/webkit/http.py b/qutebrowser/browser/webkit/http.py
index c829cb551fb..95b7b7104b5 100644
--- a/qutebrowser/browser/webkit/http.py
+++ b/qutebrowser/browser/webkit/http.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Parsing functions for various HTTP headers."""
diff --git a/qutebrowser/browser/webkit/mhtml.py b/qutebrowser/browser/webkit/mhtml.py
index f9d2607939e..692689b0a17 100644
--- a/qutebrowser/browser/webkit/mhtml.py
+++ b/qutebrowser/browser/webkit/mhtml.py
@@ -1,20 +1,7 @@
-# Copyright 2015-2021 Florian Bruhin (The Compiler)
-# Copyright 2015-2018 Daniel Schadt
+# SPDX-FileCopyrightText: Daniel Schadt
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Utils for writing an MHTML file."""
diff --git a/qutebrowser/browser/webkit/network/filescheme.py b/qutebrowser/browser/webkit/network/filescheme.py
index e6eef197da6..61f361623dd 100644
--- a/qutebrowser/browser/webkit/network/filescheme.py
+++ b/qutebrowser/browser/webkit/network/filescheme.py
@@ -1,23 +1,7 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
-# Copyright 2015-2018 Antoni Boucher (antoyo)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Antoni Boucher (antoyo)
#
-# 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 .
-#
-# pylint complains when using .render() on jinja templates, so we make it shut
-# up for this whole module.
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Handler functions for file:... pages."""
diff --git a/qutebrowser/browser/webkit/network/networkmanager.py b/qutebrowser/browser/webkit/network/networkmanager.py
index 91e6094560e..06402a547ac 100644
--- a/qutebrowser/browser/webkit/network/networkmanager.py
+++ b/qutebrowser/browser/webkit/network/networkmanager.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Our own QNetworkAccessManager."""
@@ -28,7 +15,7 @@
from qutebrowser.config import config
from qutebrowser.utils import (message, log, usertypes, utils, objreg,
- urlutils, debug)
+ urlutils, debug, qtlog)
from qutebrowser.browser import shared
from qutebrowser.browser.network import proxy as proxymod
from qutebrowser.extensions import interceptors
@@ -156,7 +143,7 @@ class NetworkManager(QNetworkAccessManager):
def __init__(self, *, win_id, tab_id, private, parent=None):
log.init.debug("Initializing NetworkManager")
- with log.disable_qt_msghandler():
+ with qtlog.disable_qt_msghandler():
# WORKAROUND for a hang when a message is printed - See:
# https://www.riverbankcomputing.com/pipermail/pyqt/2014-November/035045.html
#
diff --git a/qutebrowser/browser/webkit/network/networkreply.py b/qutebrowser/browser/webkit/network/networkreply.py
index 1994226881d..0ccaabd0e71 100644
--- a/qutebrowser/browser/webkit/network/networkreply.py
+++ b/qutebrowser/browser/webkit/network/networkreply.py
@@ -1,26 +1,9 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
#
# Based on the Eric5 helpviewer,
# Copyright (c) 2009 - 2014 Detlev Offenbach
-#
-# 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 .
-#
-# For some reason, a segfault will be triggered if the unnecessary lambdas in
-# this file aren't there.
-# pylint: disable=unnecessary-lambda
"""Special network replies.."""
@@ -115,6 +98,7 @@ def __init__(self, req, errorstring, error, parent=None):
self.setOpenMode(QIODevice.OpenModeFlag.ReadOnly)
self.setError(error, errorstring)
QTimer.singleShot(0, lambda: self.errorOccurred.emit(error))
+ # pylint: disable-next=unnecessary-lambda
QTimer.singleShot(0, lambda: self.finished.emit())
def abort(self):
@@ -142,6 +126,7 @@ class RedirectNetworkReply(QNetworkReply):
def __init__(self, new_url, parent=None):
super().__init__(parent)
self.setAttribute(QNetworkRequest.Attribute.RedirectionTargetAttribute, new_url)
+ # pylint: disable-next=unnecessary-lambda
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 98e76c808ae..f461ed9301d 100644
--- a/qutebrowser/browser/webkit/network/webkitqutescheme.py
+++ b/qutebrowser/browser/webkit/network/webkitqutescheme.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""QtWebKit specific qute://* handlers and glue code."""
diff --git a/qutebrowser/browser/webkit/tabhistory.py b/qutebrowser/browser/webkit/tabhistory.py
index c46feb6a1d4..80a57238560 100644
--- a/qutebrowser/browser/webkit/tabhistory.py
+++ b/qutebrowser/browser/webkit/tabhistory.py
@@ -1,19 +1,6 @@
-# Copyright 2015-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Utilities related to QWebHistory."""
diff --git a/qutebrowser/browser/webkit/webkitelem.py b/qutebrowser/browser/webkit/webkitelem.py
index ef3e3bea509..0400358afaf 100644
--- a/qutebrowser/browser/webkit/webkitelem.py
+++ b/qutebrowser/browser/webkit/webkitelem.py
@@ -1,30 +1,16 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
-
-# FIXME:qt6 (lint)
-# pylint: disable=no-name-in-module
+# SPDX-License-Identifier: GPL-3.0-or-later
"""QtWebKit specific part of the web element API."""
from typing import cast, TYPE_CHECKING, Iterator, List, Optional, Set
from qutebrowser.qt.core import QRect, Qt
+# pylint: disable=no-name-in-module
from qutebrowser.qt.webkit import QWebElement, QWebSettings
from qutebrowser.qt.webkitwidgets import QWebFrame
+# pylint: enable=no-name-in-module
from qutebrowser.config import config
from qutebrowser.utils import log, utils, javascript, usertypes
diff --git a/qutebrowser/browser/webkit/webkithistory.py b/qutebrowser/browser/webkit/webkithistory.py
index aea6483615b..1a4b57fabf7 100644
--- a/qutebrowser/browser/webkit/webkithistory.py
+++ b/qutebrowser/browser/webkit/webkithistory.py
@@ -1,28 +1,14 @@
-# Copyright 2015-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
-
-# FIXME:qt6 (lint)
-# pylint: disable=no-name-in-module
+# SPDX-License-Identifier: GPL-3.0-or-later
"""QtWebKit specific part of history."""
import functools
+# pylint: disable=no-name-in-module
from qutebrowser.qt.webkit import QWebHistoryInterface
+# pylint: enable=no-name-in-module
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 cb9cb5615fb..69cdd185386 100644
--- a/qutebrowser/browser/webkit/webkitinspector.py
+++ b/qutebrowser/browser/webkit/webkitinspector.py
@@ -1,27 +1,13 @@
-# Copyright 2015-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
-
-# FIXME:qt6 (lint)
-# pylint: disable=no-name-in-module
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Customized QWebInspector for QtWebKit."""
+# pylint: disable=no-name-in-module
from qutebrowser.qt.webkit import QWebSettings
from qutebrowser.qt.webkitwidgets import QWebInspector, QWebPage
+# pylint: enable=no-name-in-module
from qutebrowser.qt.widgets import QWidget
from qutebrowser.browser import inspector
diff --git a/qutebrowser/browser/webkit/webkitsettings.py b/qutebrowser/browser/webkit/webkitsettings.py
index bd65be65b50..0ce3d0bf774 100644
--- a/qutebrowser/browser/webkit/webkitsettings.py
+++ b/qutebrowser/browser/webkit/webkitsettings.py
@@ -1,22 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
-
-# FIXME:qt6 (lint)
-# pylint: disable=no-name-in-module
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Bridge from QWebSettings to our own settings.
@@ -30,8 +14,10 @@
from qutebrowser.qt.core import QUrl
from qutebrowser.qt.gui import QFont
+# pylint: disable=no-name-in-module
from qutebrowser.qt.webkit import QWebSettings
from qutebrowser.qt.webkitwidgets import QWebPage
+# pylint: enable=no-name-in-module
from qutebrowser.config import config, websettings
from qutebrowser.config.websettings import AttributeInfo as Attr
diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py
index a756e1a3d90..1ae976bead3 100644
--- a/qutebrowser/browser/webkit/webkittab.py
+++ b/qutebrowser/browser/webkit/webkittab.py
@@ -1,22 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
-
-# FIXME:qt6 (lint)
-# pylint: disable=no-name-in-module
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Wrapper over our (QtWebKit) WebView."""
@@ -28,8 +12,10 @@
from qutebrowser.qt.core import pyqtSlot, Qt, QUrl, QPoint, QTimer, QSizeF, QSize
from qutebrowser.qt.gui import QIcon
from qutebrowser.qt.widgets import QWidget
+# pylint: disable=no-name-in-module
from qutebrowser.qt.webkitwidgets import QWebPage, QWebFrame
from qutebrowser.qt.webkit import QWebSettings, QWebHistory, QWebElement
+# pylint: enable=no-name-in-module
from qutebrowser.qt.printsupport import QPrinter
from qutebrowser.browser import browsertab, shared
diff --git a/qutebrowser/browser/webkit/webpage.py b/qutebrowser/browser/webkit/webpage.py
index 27429f33105..ea19174ec0a 100644
--- a/qutebrowser/browser/webkit/webpage.py
+++ b/qutebrowser/browser/webkit/webpage.py
@@ -1,22 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
-
-# FIXME:qt6 (lint)
-# pylint: disable=no-name-in-module
+# SPDX-License-Identifier: GPL-3.0-or-later
"""The main browser widgets."""
@@ -28,7 +12,9 @@
from qutebrowser.qt.network import QNetworkReply, QNetworkRequest
from qutebrowser.qt.widgets import QFileDialog
from qutebrowser.qt.printsupport import QPrintDialog
+# pylint: disable=no-name-in-module
from qutebrowser.qt.webkitwidgets import QWebPage, QWebFrame
+# pylint: enable=no-name-in-module
from qutebrowser.config import websettings, config
from qutebrowser.browser import pdfjs, shared, downloads, greasemonkey
diff --git a/qutebrowser/browser/webkit/webview.py b/qutebrowser/browser/webkit/webview.py
index 7a08a07364c..688b70fae1c 100644
--- a/qutebrowser/browser/webkit/webview.py
+++ b/qutebrowser/browser/webkit/webview.py
@@ -1,28 +1,14 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
-
-# FIXME:qt6 (lint)
-# pylint: disable=no-name-in-module
+# SPDX-License-Identifier: GPL-3.0-or-later
"""The main browser widgets."""
from qutebrowser.qt.core import pyqtSignal, Qt
+# pylint: disable=no-name-in-module
from qutebrowser.qt.webkit import QWebSettings
from qutebrowser.qt.webkitwidgets import QWebView, QWebPage
+# pylint: enable=no-name-in-module
from qutebrowser.config import config, stylesheet
from qutebrowser.keyinput import modeman
diff --git a/qutebrowser/commands/__init__.py b/qutebrowser/commands/__init__.py
index f1ff911e269..7c624937116 100644
--- a/qutebrowser/commands/__init__.py
+++ b/qutebrowser/commands/__init__.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""In qutebrowser, all keybindings are mapped to commands.
diff --git a/qutebrowser/commands/argparser.py b/qutebrowser/commands/argparser.py
index 95a90b801fe..0d4bd7ca7f8 100644
--- a/qutebrowser/commands/argparser.py
+++ b/qutebrowser/commands/argparser.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""argparse.ArgumentParser subclass to parse qutebrowser commands."""
diff --git a/qutebrowser/commands/cmdexc.py b/qutebrowser/commands/cmdexc.py
index b1b7b9a4f92..4335a10e6c1 100644
--- a/qutebrowser/commands/cmdexc.py
+++ b/qutebrowser/commands/cmdexc.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Exception classes for commands modules.
diff --git a/qutebrowser/commands/command.py b/qutebrowser/commands/command.py
index 76a44934e97..aaf1763e298 100644
--- a/qutebrowser/commands/command.py
+++ b/qutebrowser/commands/command.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Contains the Command class, a skeleton for a command."""
@@ -76,10 +63,12 @@ class Command:
COUNT_COMMAND_VALUES = [usertypes.CommandValue.count,
usertypes.CommandValue.count_tab]
- def __init__(self, *, handler, name, instance=None, maxsplit=None,
- modes=None, not_modes=None, debug=False, deprecated=False,
- no_cmd_split=False, star_args_optional=False, scope='global',
- backend=None, no_replace_variables=False, tree_tab=False):
+ def __init__(
+ self, *, handler, name, instance=None, maxsplit=None,
+ modes=None, not_modes=None, debug=False, deprecated=False,
+ no_cmd_split=False, star_args_optional=False, scope='global',
+ backend=None, no_replace_variables=False, tree_tab=False,
+ ): # pylint: disable=too-many-arguments
if modes is not None and not_modes is not None:
raise ValueError("Only modes or not_modes can be given!")
if modes is not None:
diff --git a/qutebrowser/commands/parser.py b/qutebrowser/commands/parser.py
index 8fb107d01ca..d45a18aea74 100644
--- a/qutebrowser/commands/parser.py
+++ b/qutebrowser/commands/parser.py
@@ -1,19 +1,6 @@
-# Copyright 2021 Ryan Roden-Corrent (rcorre)
+# SPDX-FileCopyrightText: Ryan Roden-Corrent (rcorre)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Module for parsing commands entered into the browser."""
diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py
index c9d1db7d05c..1ad563c5d18 100644
--- a/qutebrowser/commands/runners.py
+++ b/qutebrowser/commands/runners.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Module containing command managers (SearchRunner and CommandRunner)."""
@@ -185,10 +172,10 @@ def run(self, text, count=None, *, safely=False):
result.cmd.run(self._win_id, args, count=count)
- if result.cmdline[0] == 'repeat-command':
+ if result.cmdline[0] in ['repeat-command', 'cmd-repeat-last']:
record_last_command = False
- if result.cmdline[0] in ['macro-record', 'macro-run', 'set-cmd-text']:
+ if result.cmdline[0] in ['macro-record', 'macro-run', 'set-cmd-text', 'cmd-set-text']:
record_macro = False
if record_last_command:
diff --git a/qutebrowser/commands/userscripts.py b/qutebrowser/commands/userscripts.py
index d41f2a87681..f4ddd2bf441 100644
--- a/qutebrowser/commands/userscripts.py
+++ b/qutebrowser/commands/userscripts.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Functions to execute a userscript."""
diff --git a/qutebrowser/completion/__init__.py b/qutebrowser/completion/__init__.py
index cbd0eb37c6b..41e5c7f6879 100644
--- a/qutebrowser/completion/__init__.py
+++ b/qutebrowser/completion/__init__.py
@@ -1,18 +1,5 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Modules related to the command completion."""
diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py
index 62e89ef46b0..49a97c9cb42 100644
--- a/qutebrowser/completion/completer.py
+++ b/qutebrowser/completion/completer.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Completer attached to a CompletionView."""
diff --git a/qutebrowser/completion/completiondelegate.py b/qutebrowser/completion/completiondelegate.py
index e497e1204ad..821a0a81e94 100644
--- a/qutebrowser/completion/completiondelegate.py
+++ b/qutebrowser/completion/completiondelegate.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Completion item delegate for CompletionView.
@@ -291,6 +278,7 @@ def sizeHint(self, option, index):
self._opt = QStyleOptionViewItem(option)
self.initStyleOption(self._opt, index)
self._style = self._opt.widget.style()
+ assert self._style is not None
self._get_textdoc(index)
assert self._doc is not None
diff --git a/qutebrowser/completion/completionwidget.py b/qutebrowser/completion/completionwidget.py
index 01527e76376..f042be0a1c3 100644
--- a/qutebrowser/completion/completionwidget.py
+++ b/qutebrowser/completion/completionwidget.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Completion view for statusbar command section.
@@ -156,6 +143,15 @@ def _model(self) -> completionmodel.CompletionModel:
assert isinstance(model, completionmodel.CompletionModel), model
return model
+ def _selection_model(self) -> QItemSelectionModel:
+ """Get the current selection model.
+
+ Ensures the model is not None.
+ """
+ model = self.selectionModel()
+ assert model is not None
+ return model
+
@pyqtSlot(str)
def _on_config_changed(self, option):
if option in ['completion.height', 'completion.shrink']:
@@ -169,7 +165,9 @@ def _resize_columns(self):
column_widths = self._model().column_widths
pixel_widths = [(width * perc // 100) for perc in column_widths]
- delta = self.verticalScrollBar().sizeHint().width()
+ bar = self.verticalScrollBar()
+ assert bar is not None
+ delta = bar.sizeHint().width()
for i, width in reversed(list(enumerate(pixel_widths))):
if width > delta:
pixel_widths[i] -= delta
@@ -191,7 +189,7 @@ def _next_idx(self, upwards):
A QModelIndex.
"""
model = self._model()
- idx = self.selectionModel().currentIndex()
+ idx = self._selection_model().currentIndex()
if not idx.isValid():
# No item selected yet
if upwards:
@@ -223,7 +221,7 @@ def _next_page(self, upwards):
Return:
A QModelIndex.
"""
- old_idx = self.selectionModel().currentIndex()
+ old_idx = self._selection_model().currentIndex()
idx = old_idx
model = self._model()
@@ -267,7 +265,7 @@ def _next_category_idx(self, upwards):
Return:
A QModelIndex.
"""
- idx = self.selectionModel().currentIndex()
+ idx = self._selection_model().currentIndex()
model = self._model()
if not idx.isValid():
return self._next_idx(upwards).sibling(0, 0)
@@ -323,7 +321,7 @@ def completion_item_focus(self, which, history=False):
if not self._active:
return
- selmodel = self.selectionModel()
+ selmodel = self._selection_model()
indices = {
'next': lambda: self._next_idx(upwards=False),
'prev': lambda: self._next_idx(upwards=True),
@@ -363,9 +361,10 @@ def set_model(self, model):
Args:
model: The model to use.
"""
- if self.model() is not None and model is not self.model():
- self.model().deleteLater()
- self.selectionModel().deleteLater()
+ old_model = self.model()
+ if old_model is not None and model is not old_model:
+ old_model.deleteLater()
+ self._selection_model().deleteLater()
self.setModel(model)
@@ -395,7 +394,7 @@ def set_pattern(self, pattern: str) -> None:
self.pattern = pattern
with debug.log_time(log.completion, 'Set pattern {}'.format(pattern)):
self._model().set_pattern(pattern)
- self.selectionModel().clear()
+ self._selection_model().clear()
self._maybe_update_geometry()
self._maybe_show()
@@ -415,7 +414,7 @@ def _maybe_update_geometry(self):
def on_clear_completion_selection(self):
"""Clear the selection model when an item is activated."""
self.hide()
- selmod = self.selectionModel()
+ selmod = self._selection_model()
if selmod is not None:
selmod.clearSelection()
selmod.clearCurrentIndex()
@@ -426,14 +425,18 @@ def sizeHint(self):
confheight = str(config.val.completion.height)
if confheight.endswith('%'):
perc = int(confheight.rstrip('%'))
- height = self.window().height() * perc // 100
+ window = self.window()
+ assert window is not None
+ height = window.height() * perc // 100
else:
height = int(confheight)
# Shrink to content size if needed and shrinking is enabled
if config.val.completion.shrink:
+ bar = self.horizontalScrollBar()
+ assert bar is not None
contents_height = (
self.viewportSizeHint().height() +
- self.horizontalScrollBar().sizeHint().height())
+ bar.sizeHint().height())
if contents_height <= height:
height = contents_height
# The width isn't really relevant as we're expanding anyways.
diff --git a/qutebrowser/completion/models/__init__.py b/qutebrowser/completion/models/__init__.py
index 6bfa5dcc966..5a19f438f79 100644
--- a/qutebrowser/completion/models/__init__.py
+++ b/qutebrowser/completion/models/__init__.py
@@ -1,18 +1,5 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Models for the command completion."""
diff --git a/qutebrowser/completion/models/completionmodel.py b/qutebrowser/completion/models/completionmodel.py
index 411140917b9..6ddf27dcf4a 100644
--- a/qutebrowser/completion/models/completionmodel.py
+++ b/qutebrowser/completion/models/completionmodel.py
@@ -1,19 +1,6 @@
-# Copyright 2017-2021 Ryan Roden-Corrent (rcorre)
+# SPDX-FileCopyrightText: Ryan Roden-Corrent (rcorre)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""A model that proxies access to one or more completion categories."""
diff --git a/qutebrowser/completion/models/configmodel.py b/qutebrowser/completion/models/configmodel.py
index f863a1b76e9..bc7cfb07883 100644
--- a/qutebrowser/completion/models/configmodel.py
+++ b/qutebrowser/completion/models/configmodel.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Functions that return config-related completion models."""
diff --git a/qutebrowser/completion/models/filepathcategory.py b/qutebrowser/completion/models/filepathcategory.py
index 8f1006cdff3..1f4c04dea27 100644
--- a/qutebrowser/completion/models/filepathcategory.py
+++ b/qutebrowser/completion/models/filepathcategory.py
@@ -1,19 +1,6 @@
-# Copyright 2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Completion category for filesystem paths.
diff --git a/qutebrowser/completion/models/histcategory.py b/qutebrowser/completion/models/histcategory.py
index cb231e76da3..2e54eae9118 100644
--- a/qutebrowser/completion/models/histcategory.py
+++ b/qutebrowser/completion/models/histcategory.py
@@ -1,19 +1,6 @@
-# Copyright 2017-2021 Ryan Roden-Corrent (rcorre)
+# SPDX-FileCopyrightText: Ryan Roden-Corrent (rcorre)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""A completion category that queries the SQL history store."""
diff --git a/qutebrowser/completion/models/listcategory.py b/qutebrowser/completion/models/listcategory.py
index 1ca81cf5ec4..f92679cc698 100644
--- a/qutebrowser/completion/models/listcategory.py
+++ b/qutebrowser/completion/models/listcategory.py
@@ -1,19 +1,6 @@
-# Copyright 2017-2021 Ryan Roden-Corrent (rcorre)
+# SPDX-FileCopyrightText: Ryan Roden-Corrent (rcorre)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Completion category that uses a list of tuples as a data source."""
@@ -61,10 +48,13 @@ def set_pattern(self, val):
log.completion.warning(f"Trimming {len(val)}-char pattern to 5000")
val = val[:5000]
self._pattern = val
- val = re.sub(r' +', r' ', val) # See #1919
- val = re.escape(val)
- val = val.replace(r'\ ', '.*')
- rx = QRegularExpression(val, QRegularExpression.PatternOption.CaseInsensitiveOption)
+
+ # Positive lookahead per search term. This means that all search terms must
+ # be matched but they can be matched anywhere in the string, so they can be
+ # in any order. For example "foo bar" -> "(?=.*foo)(?=.*bar)"
+ re_pattern = "^" + "".join(f"(?=.*{re.escape(term)})" for term in val.split())
+
+ rx = QRegularExpression(re_pattern, QRegularExpression.PatternOption.CaseInsensitiveOption)
qtutils.ensure_valid(rx)
self.setFilterRegularExpression(rx)
self.invalidate()
diff --git a/qutebrowser/completion/models/miscmodels.py b/qutebrowser/completion/models/miscmodels.py
index 1f38990b757..ea3febe4d4f 100644
--- a/qutebrowser/completion/models/miscmodels.py
+++ b/qutebrowser/completion/models/miscmodels.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Functions that return miscellaneous completion models."""
diff --git a/qutebrowser/completion/models/urlmodel.py b/qutebrowser/completion/models/urlmodel.py
index ef1326b5735..0d642834858 100644
--- a/qutebrowser/completion/models/urlmodel.py
+++ b/qutebrowser/completion/models/urlmodel.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Function to return the url completion model for the `open` command."""
diff --git a/qutebrowser/completion/models/util.py b/qutebrowser/completion/models/util.py
index 16452d7b571..4957dc6c9f9 100644
--- a/qutebrowser/completion/models/util.py
+++ b/qutebrowser/completion/models/util.py
@@ -1,19 +1,6 @@
-# Copyright 2017-2021 Ryan Roden-Corrent (rcorre)
+# SPDX-FileCopyrightText: Ryan Roden-Corrent (rcorre)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Utility functions for completion models."""
diff --git a/qutebrowser/components/__init__.py b/qutebrowser/components/__init__.py
index c2b80359741..0c4d0c91b88 100644
--- a/qutebrowser/components/__init__.py
+++ b/qutebrowser/components/__init__.py
@@ -1,18 +1,5 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""qutebrowser "extensions" which only use the qutebrowser.api API."""
diff --git a/qutebrowser/components/adblockcommands.py b/qutebrowser/components/adblockcommands.py
index f29e382ebba..065500bdd86 100644
--- a/qutebrowser/components/adblockcommands.py
+++ b/qutebrowser/components/adblockcommands.py
@@ -1,19 +1,6 @@
-# Copyright 2020-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Commands relating to ad blocking."""
diff --git a/qutebrowser/components/braveadblock.py b/qutebrowser/components/braveadblock.py
index f3c7fda4cfc..a827eb54677 100644
--- a/qutebrowser/components/braveadblock.py
+++ b/qutebrowser/components/braveadblock.py
@@ -1,19 +1,6 @@
-# Copyright 2020-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Functions related to the Brave adblocker."""
diff --git a/qutebrowser/components/caretcommands.py b/qutebrowser/components/caretcommands.py
index 9f6532d4733..15eb1938d16 100644
--- a/qutebrowser/components/caretcommands.py
+++ b/qutebrowser/components/caretcommands.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Commands related to caret browsing."""
diff --git a/qutebrowser/components/hostblock.py b/qutebrowser/components/hostblock.py
index 44f80db5060..672a530df4f 100644
--- a/qutebrowser/components/hostblock.py
+++ b/qutebrowser/components/hostblock.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Functions related to host blocking."""
diff --git a/qutebrowser/components/misccommands.py b/qutebrowser/components/misccommands.py
index 229e7ee8041..e3ffb82d098 100644
--- a/qutebrowser/components/misccommands.py
+++ b/qutebrowser/components/misccommands.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
# To allow count being documented
# pylint: disable=differing-param-doc
diff --git a/qutebrowser/components/readlinecommands.py b/qutebrowser/components/readlinecommands.py
index 05ccc66623f..a9626637dd4 100644
--- a/qutebrowser/components/readlinecommands.py
+++ b/qutebrowser/components/readlinecommands.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Bridge to provide readline-like shortcuts for QLineEdits."""
diff --git a/qutebrowser/components/scrollcommands.py b/qutebrowser/components/scrollcommands.py
index 4efbc33993d..3ee5255351a 100644
--- a/qutebrowser/components/scrollcommands.py
+++ b/qutebrowser/components/scrollcommands.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Scrolling-related commands."""
@@ -45,7 +32,7 @@ def scroll_px(tab: apitypes.Tab, dx: int, dy: int, count: int = 1) -> None:
def scroll(tab: apitypes.Tab, direction: str, count: int = 1) -> None:
"""Scroll the current tab in the given direction.
- Note you can use `:run-with-count` to have a keybinding with a bigger
+ Note you can use `:cmd-run-with-count` to have a keybinding with a bigger
scroll increment.
Args:
diff --git a/qutebrowser/components/utils/blockutils.py b/qutebrowser/components/utils/blockutils.py
index fd26593c9bc..369b0eee5e5 100644
--- a/qutebrowser/components/utils/blockutils.py
+++ b/qutebrowser/components/utils/blockutils.py
@@ -1,20 +1,6 @@
-# Copyright 2020-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
-
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Code that is shared between the host blocker and Brave ad blocker."""
diff --git a/qutebrowser/components/zoomcommands.py b/qutebrowser/components/zoomcommands.py
index 177cd5675a4..05e2bebaa26 100644
--- a/qutebrowser/components/zoomcommands.py
+++ b/qutebrowser/components/zoomcommands.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Zooming-related commands."""
diff --git a/qutebrowser/config/__init__.py b/qutebrowser/config/__init__.py
index 5f3354ac740..4688cc75818 100644
--- a/qutebrowser/config/__init__.py
+++ b/qutebrowser/config/__init__.py
@@ -1,18 +1,5 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Modules related to the configuration."""
diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py
index fb3fc7647c1..573f25fa12c 100644
--- a/qutebrowser/config/config.py
+++ b/qutebrowser/config/config.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Configuration storage and config-related utilities."""
@@ -167,14 +154,14 @@ def get_bindings_for(self, mode: str) -> Dict[keyutils.KeySequence, str]:
return bindings
def _implied_cmd(self, cmdline: str) -> Optional[str]:
- """Return cmdline, or the implied cmd if cmdline is a set-cmd-text."""
+ """Return cmdline, or the implied cmd if cmdline is a cmd-set-text."""
try:
results = parser.CommandParser().parse_all(cmdline)
except cmdexc.NoSuchCommandError:
return None
result = results[0]
- if result.cmd.name != "set-cmd-text":
+ if result.cmd.name not in ["set-cmd-text", "cmd-set-text"]:
return cmdline
if not result.args:
return None # doesn't look like this sets a command
diff --git a/qutebrowser/config/configcache.py b/qutebrowser/config/configcache.py
index 94f4dfff980..9e76466d9a6 100644
--- a/qutebrowser/config/configcache.py
+++ b/qutebrowser/config/configcache.py
@@ -1,20 +1,6 @@
-# Copyright 2018-2021 Jay Kamat
+# SPDX-FileCopyrightText: Jay Kamat
#
-# 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 .
-
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Implementation of a basic config cache."""
diff --git a/qutebrowser/config/configcommands.py b/qutebrowser/config/configcommands.py
index a196f5d6858..c4065ceb9a2 100644
--- a/qutebrowser/config/configcommands.py
+++ b/qutebrowser/config/configcommands.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Commands related to the configuration."""
diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py
index 827630fb3f2..9535dd7272e 100644
--- a/qutebrowser/config/configdata.py
+++ b/qutebrowser/config/configdata.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Configuration data for config.py.
diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index 05526260e02..d1b883ff2ec 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -385,6 +385,25 @@ qt.workarounds.locale:
However, It is expected that distributions shipping QtWebEngine 5.15.3
follow up with a proper fix soon, so it is disabled by default.
+qt.workarounds.disable_accelerated_2d_canvas:
+ type:
+ name: String
+ valid_values:
+ - always: Disable accelerated 2d canvas
+ - auto: Disable on Qt6 < 6.6.0, enable otherwise
+ - never: Enable accelerated 2d canvas
+ default: auto
+ backend: QtWebEngine
+ restart: true
+ desc: >-
+ Disable accelerated 2d canvas to avoid graphical glitches.
+
+ On some setups graphical issues can occur on sites like Google sheets
+ and PDF.js. These don't occur when accelerated 2d canvas is turned off,
+ so we do that by default.
+
+ So far these glitches only occur on some Intel graphics devices.
+
## auto_save
auto_save.interval:
@@ -435,12 +454,15 @@ content.canvas_reading:
default: true
type: Bool
backend: QtWebEngine
- restart: true
+ supports_pattern: true
desc: >-
Allow websites to read canvas elements.
Note this is needed for some websites to work properly.
+ On QtWebEngine < 6.6, this setting requires a restart and does not support
+ URL patterns, only the global setting is applied.
+
# Defaults from QWebSettings::QWebSettings() in
# qtwebkit/Source/WebKit/qt/Api/qwebsettings.cpp
@@ -732,15 +754,15 @@ content.headers.user_agent:
# 'ua_fetch.py'
# Vim-protip: Place your cursor below this comment and run
# :r!python scripts/dev/ua_fetch.py
- - - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
- like Gecko) Chrome/110.0.0.0 Safari/537.36"
- - Chrome 110 Win10
- - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
- (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"
- - Chrome 110 macOS
+ (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
+ - Chrome 117 macOS
+ - - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
+ like Gecko) Chrome/117.0.0.0 Safari/537.36"
+ - Chrome 117 Win10
- - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like
- Gecko) Chrome/110.0.0.0 Safari/537.36"
- - Chrome 110 Linux
+ Gecko) Chrome/117.0.0.0 Safari/537.36"
+ - Chrome 117 Linux
supports_pattern: true
desc: |
User agent to send.
@@ -1009,6 +1031,31 @@ content.javascript.prompt:
type: Bool
desc: Show javascript prompts.
+content.javascript.legacy_touch_events:
+ type:
+ name: String
+ valid_values:
+ - always: Legacy touch events are always enabled. This might cause some
+ websites to assume a mobile device.
+ - auto: Legacy touch events are only enabled if a touch screen was
+ detected on startup.
+ - never: Legacy touch events are always disabled.
+ default: never
+ backend: QtWebEngine
+ restart: true
+ desc: >-
+ Enables the legacy touch event feature.
+
+ This affects JS APIs such as:
+
+ - ontouch* members on window, document, Element
+ - document.createTouch, document.createTouchList
+ - document.createEvent("TouchEvent")
+
+ Newer Chromium versions have those disabled by default:
+ https://bugs.chromium.org/p/chromium/issues/detail?id=392584
+ https://groups.google.com/a/chromium.org/g/blink-dev/c/KV6kqDJpYiE
+
content.local_content_can_access_remote_urls:
default: false
type: Bool
@@ -3272,22 +3319,11 @@ colors.webpage.darkmode.enabled:
Example configurations from Chromium's `chrome://flags`:
-
- "With simple HSL/CIELAB/RGB-based inversion": Set
- `colors.webpage.darkmode.algorithm` accordingly.
-
- - "With selective image inversion": Set
- `colors.webpage.darkmode.policy.images` to `smart`.
-
- - "With selective inversion of non-image elements": Set
- `colors.webpage.darkmode.threshold.text` to 150 and
- `colors.webpage.darkmode.threshold.background` to 205.
+ `colors.webpage.darkmode.algorithm` accordingly, and
+ set `colors.webpage.darkmode.policy.images` to `never`.
- - "With selective inversion of everything": Combines the two variants
- above.
-
- - "With increased text contrast": Set
- `colors.webpage.darkmode.increase_text_contrast` (QtWebEngine 6.3+)
+ - "With selective image inversion": qutebrowser default settings.
restart: true
backend: QtWebEngine
@@ -3336,13 +3372,11 @@ colors.webpage.darkmode.policy.images:
- never: Never apply dark mode filter to any images.
- smart: "Apply dark mode based on image content. Not available with Qt
5.15.0."
+ - smart-simple: "On QtWebEngine 6.6, use a simpler algorithm for smart mode (based
+ on numbers of colors and transparency), rather than an ML-based model.
+ Same as 'smart' on older QtWebEnigne versions."
desc: >-
Which images to apply dark mode to.
-
- With QtWebEngine 5.15.0, this setting can cause frequent renderer process
- crashes due to a
- https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/304211[bug
- in Qt].
restart: true
backend: QtWebEngine
@@ -3362,6 +3396,9 @@ colors.webpage.darkmode.policy.page:
backend: QtWebEngine
colors.webpage.darkmode.threshold.text:
+ renamed: colors.webpage.darkmode.threshold.foreground
+
+colors.webpage.darkmode.threshold.foreground:
default: 256
type:
name: Int
@@ -3390,45 +3427,10 @@ colors.webpage.darkmode.threshold.background:
256 to never invert the color or to 0 to always invert it.
Note: This behavior is the opposite of
- `colors.webpage.darkmode.threshold.text`!
- restart: true
- backend: QtWebEngine
-
-colors.webpage.darkmode.grayscale.all:
- default: false
- type: Bool
- desc: >-
- Render all colors as grayscale.
-
- This only has an effect when `colors.webpage.darkmode.algorithm` is set to
- `lightness-hsl` or `brightness-rgb`.
+ `colors.webpage.darkmode.threshold.foreground`!
restart: true
backend: QtWebEngine
-colors.webpage.darkmode.grayscale.images:
- default: 0.0
- type:
- name: Float
- minval: 0.0
- maxval: 1.0
- desc: >-
- Desaturation factor for images in dark mode.
-
- 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 6.3
- QtWebKit: false
-
# emacs: '
## fonts
@@ -3679,17 +3681,17 @@ bindings.default:
default:
normal:
: clear-keychain ;; search ;; fullscreen --leave
- o: set-cmd-text -s :open
- go: set-cmd-text :open {url:pretty}
- O: set-cmd-text -s :open -t
- gO: set-cmd-text :open -t -r {url:pretty}
- xo: set-cmd-text -s :open -b
- xO: set-cmd-text :open -b -r {url:pretty}
- wo: set-cmd-text -s :open -w
- wO: set-cmd-text :open -w {url:pretty}
- /: set-cmd-text /
- ?: set-cmd-text ?
- ":": "set-cmd-text :"
+ o: cmd-set-text -s :open
+ go: cmd-set-text :open {url:pretty}
+ O: cmd-set-text -s :open -t
+ gO: cmd-set-text :open -t -r {url:pretty}
+ xo: cmd-set-text -s :open -b
+ xO: cmd-set-text :open -b -r {url:pretty}
+ wo: cmd-set-text -s :open -w
+ wO: cmd-set-text :open -w {url:pretty}
+ /: cmd-set-text /
+ ?: cmd-set-text ?
+ ":": "cmd-set-text :"
ga: open -t
: open -t
: open -w
@@ -3699,7 +3701,7 @@ bindings.default:
: close
D: tab-close -o
co: tab-only
- T: set-cmd-text -sr :tab-focus
+ T: cmd-set-text -sr :tab-focus
gm: tab-move
gK: tab-move -
gJ: tab-move +
@@ -3771,17 +3773,17 @@ bindings.default:
wp: open -w -- {clipboard}
wP: open -w -- {primary}
m: quickmark-save
- b: set-cmd-text -s :quickmark-load
- B: set-cmd-text -s :quickmark-load -t
- wb: set-cmd-text -s :quickmark-load -w
+ b: cmd-set-text -s :quickmark-load
+ B: cmd-set-text -s :quickmark-load -t
+ wb: cmd-set-text -s :quickmark-load -w
M: bookmark-add
- gb: set-cmd-text -s :bookmark-load
- gB: set-cmd-text -s :bookmark-load -t
- wB: set-cmd-text -s :bookmark-load -w
+ gb: cmd-set-text -s :bookmark-load
+ gB: cmd-set-text -s :bookmark-load -t
+ wB: cmd-set-text -s :bookmark-load -w
sf: save
- ss: set-cmd-text -s :set
- sl: set-cmd-text -s :set -t
- sk: set-cmd-text -s :bind
+ ss: cmd-set-text -s :set
+ sl: cmd-set-text -s :set -t
+ sk: cmd-set-text -s :bind
-: zoom-out
+: zoom-in
=: zoom
@@ -3804,7 +3806,7 @@ bindings.default:
ad: download-cancel
cd: download-clear
gf: view-source
- gt: set-cmd-text -s :tab-select
+ gt: cmd-set-text -s :tab-select
: tab-focus last
: nop
: tab-focus last
@@ -3837,7 +3839,7 @@ bindings.default:
Sh: history
: selection-follow
: selection-follow -t
- .: repeat-command
+ .: cmd-repeat-last
: tab-pin
: tab-mute
gD: tab-give
diff --git a/qutebrowser/config/configexc.py b/qutebrowser/config/configexc.py
index 75ab46d0f39..4c8291580f8 100644
--- a/qutebrowser/config/configexc.py
+++ b/qutebrowser/config/configexc.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Exceptions related to config parsing."""
diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py
index 2a13133ae39..0680cd0e733 100644
--- a/qutebrowser/config/configfiles.py
+++ b/qutebrowser/config/configfiles.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Configuration files residing on disk."""
@@ -108,7 +95,9 @@ def __init__(self) -> None:
for sect, key in deleted_keys:
self[sect].pop(key, None)
- self['general']['qt_version'] = qVersion()
+ qt_version = qVersion()
+ assert qt_version is not None
+ self['general']['qt_version'] = qt_version
self['general']['qtwe_version'] = self._qtwe_version_str()
self['general']['chromium_version'] = self._chromium_version_str()
self['general']['version'] = qutebrowser.__version__
@@ -304,7 +293,7 @@ def _save(self) -> None:
f.write(textwrap.dedent("""
# If a config.py file exists, this file is ignored unless it's explicitly loaded
# via config.load_autoconfig(). For more information, see:
- # https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc#loading-autoconfigyml
+ # https://github.com/qutebrowser/qutebrowser/blob/main/doc/help/configuring.asciidoc#loading-autoconfigyml
# DO NOT edit this file by hand, qutebrowser will overwrite it.
# Instead, create a config.py - see :help for details.
diff --git a/qutebrowser/config/configinit.py b/qutebrowser/config/configinit.py
index 46cd5f42991..5d000c3ec8e 100644
--- a/qutebrowser/config/configinit.py
+++ b/qutebrowser/config/configinit.py
@@ -1,19 +1,6 @@
-# Copyright 2017-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Initialization of the configuration."""
diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py
index a10f4aa3bb5..41f139e14ca 100644
--- a/qutebrowser/config/configtypes.py
+++ b/qutebrowser/config/configtypes.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Types for options in qutebrowser's configuration.
diff --git a/qutebrowser/config/configutils.py b/qutebrowser/config/configutils.py
index 3598676a325..fda9552ddea 100644
--- a/qutebrowser/config/configutils.py
+++ b/qutebrowser/config/configutils.py
@@ -1,20 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
-
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Utilities and data structures used by various config code."""
diff --git a/qutebrowser/config/qtargs.py b/qutebrowser/config/qtargs.py
index 5c91b321e06..3a648524e4a 100644
--- a/qutebrowser/config/qtargs.py
+++ b/qutebrowser/config/qtargs.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Get arguments to pass to Qt."""
@@ -21,7 +8,7 @@
import sys
import argparse
import pathlib
-from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple
+from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple, Union, Callable
from qutebrowser.qt import machinery
from qutebrowser.qt.core import QLocale
@@ -286,10 +273,19 @@ def _qtwebengine_args(
if disabled_features:
yield _DISABLE_FEATURES + ','.join(disabled_features)
- yield from _qtwebengine_settings_args()
+ yield from _qtwebengine_settings_args(versions)
-_WEBENGINE_SETTINGS: Dict[str, Dict[Any, Optional[str]]] = {
+_SettingValueType = Union[
+ str,
+ Callable[
+ [
+ version.WebEngineVersions,
+ ],
+ Optional[str],
+ ],
+]
+_WEBENGINE_SETTINGS: Dict[str, Dict[Any, Optional[_SettingValueType]]] = {
'qt.force_software_rendering': {
'software-opengl': None,
'qt-quick': None,
@@ -298,6 +294,7 @@ def _qtwebengine_args(
},
'content.canvas_reading': {
True: None,
+ # might be overridden in webenginesettings.py
False: '--disable-reading-from-canvas',
},
'content.webrtc_ip_handling_policy': {
@@ -312,6 +309,11 @@ def _qtwebengine_args(
'--force-webrtc-ip-handling-policy='
'disable_non_proxied_udp',
},
+ 'content.javascript.legacy_touch_events': {
+ 'always': '--touch-events=enabled',
+ 'auto': '--touch-events=auto',
+ 'never': '--touch-events=disabled',
+ },
'qt.chromium.process_model': {
'process-per-site-instance': None,
'process-per-site': '--process-per-site',
@@ -337,13 +339,25 @@ def _qtwebengine_args(
'auto':
'--enable-experimental-web-platform-features' if machinery.IS_QT5 else None,
},
+ 'qt.workarounds.disable_accelerated_2d_canvas': {
+ 'always': '--disable-accelerated-2d-canvas',
+ 'never': None,
+ 'auto': lambda _versions: '--disable-accelerated-2d-canvas' if machinery.IS_QT6 else None,
+ },
}
-def _qtwebengine_settings_args() -> Iterator[str]:
+def _qtwebengine_settings_args(versions: version.WebEngineVersions) -> Iterator[str]:
for setting, args in sorted(_WEBENGINE_SETTINGS.items()):
arg = args[config.instance.get(setting)]
- if arg is not None:
+ if callable(arg):
+ result = arg(versions)
+ if result is not None:
+ assert isinstance(
+ result, str
+ ), f"qt.settings feature detection returned an invalid type: {type(result)} for {setting}"
+ yield result
+ elif arg is not None:
yield arg
diff --git a/qutebrowser/config/stylesheet.py b/qutebrowser/config/stylesheet.py
index 3dede5252a7..d9032e2a93d 100644
--- a/qutebrowser/config/stylesheet.py
+++ b/qutebrowser/config/stylesheet.py
@@ -1,19 +1,6 @@
-# Copyright 2019-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Handling of Qt qss stylesheets."""
diff --git a/qutebrowser/config/websettings.py b/qutebrowser/config/websettings.py
index 11bcbffa26c..9f5bf92d02e 100644
--- a/qutebrowser/config/websettings.py
+++ b/qutebrowser/config/websettings.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Bridge from QWeb(Engine)Settings to our own settings."""
diff --git a/qutebrowser/extensions/interceptors.py b/qutebrowser/extensions/interceptors.py
index 5d2e7f79f18..8aaa9b28c31 100644
--- a/qutebrowser/extensions/interceptors.py
+++ b/qutebrowser/extensions/interceptors.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Infrastructure for intercepting requests."""
diff --git a/qutebrowser/extensions/loader.py b/qutebrowser/extensions/loader.py
index 19691fc2bc9..b5b232c5a25 100644
--- a/qutebrowser/extensions/loader.py
+++ b/qutebrowser/extensions/loader.py
@@ -1,19 +1,6 @@
-# Copyright 2018-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Loader for qutebrowser extensions."""
diff --git a/qutebrowser/html/license.html b/qutebrowser/html/license.html
index 3cbc6c74bf7..3b2a1a9d3fa 100644
--- a/qutebrowser/html/license.html
+++ b/qutebrowser/html/license.html
@@ -1,3 +1,7 @@
+
+
diff --git a/qutebrowser/html/version.html b/qutebrowser/html/version.html
index 27fa4eb4c83..6439290889d 100644
--- a/qutebrowser/html/version.html
+++ b/qutebrowser/html/version.html
@@ -1,3 +1,7 @@
+
+
{% extends "base.html" %}
{% block script %}
diff --git a/qutebrowser/html/warning-qt5.html b/qutebrowser/html/warning-qt5.html
new file mode 100644
index 00000000000..17af2f72c40
--- /dev/null
+++ b/qutebrowser/html/warning-qt5.html
@@ -0,0 +1,28 @@
+{% extends "styled.html" %}
+
+{% block content %}
+{{ title }}
+Note this warning will only appear once. Use :open
+qute://warning/qt5 to show it again at a later time.
+
+
+ qutebrowser now supports Qt 6.
+
+
+ However, in your environment, Qt 6 is not installed. Thus, qutebrowser is still using Qt 5 instead.
+
+ Qt 5.15 based on a very old Chromium version (83 or 87, from mid/late 2020).
+
+{% if is_venv %}
+
+ You are using a virtualenv. If you want to use Qt 6, you need to create a new
+ virtualenv with PyQt6 installed.
+
+ If using mkvenv.py, rerun the script to create a
+ new virtualenv with Qt 6.
+
+{% endif %}
+
+ Python installation prefix: {{ prefix }}
+
+{% endblock %}
diff --git a/qutebrowser/html/warning-sandboxing.html b/qutebrowser/html/warning-sandboxing.html
deleted file mode 100644
index 186d938e7ce..00000000000
--- a/qutebrowser/html/warning-sandboxing.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends "styled.html" %}
-
-{% block content %}
-{{ title }}
-Note this warning will only appear once. Use :open
-qute://warning/sandboxing to show it again at a later time.
-
-
- Due to a PyInstaller issue,
- Chromium's sandboxing
- 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
- not use this build in production. Hopefully, this situation will be
- resolved before the final 3.0.0 release.
-
-{% endblock %}
diff --git a/qutebrowser/javascript/caret.js b/qutebrowser/javascript/caret.js
index 7c157142cb7..b16a15348b9 100644
--- a/qutebrowser/javascript/caret.js
+++ b/qutebrowser/javascript/caret.js
@@ -1,51 +1,17 @@
/* eslint-disable max-len, max-statements, complexity,
default-case */
-// Copyright 2014 The Chromium Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* Copyright 2014 The Chromium Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ * https://source.chromium.org/chromium/chromium/src/+/main:LICENSE
+ */
+
/**
- * Copyright 2018-2021 Florian Bruhin (The Compiler)
- *
- * 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.
+ * SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
*
- * You should have received a copy of the GNU General Public License
- * along with qutebrowser. If not, see .
+ * SPDX-License-Identifier: GPL-3.0-or-later
*/
/**
diff --git a/qutebrowser/javascript/history.js b/qutebrowser/javascript/history.js
index a50e42d6b4b..428adae3388 100644
--- a/qutebrowser/javascript/history.js
+++ b/qutebrowser/javascript/history.js
@@ -1,22 +1,7 @@
-/**
- * Copyright 2017-2021 Florian Bruhin (The-Compiler)
- * Copyright 2017 Imran Sobir
- *
- * 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 .
- */
+// SPDX-FileCopyrightText: Imran Sobir
+// SPDX-FileCopyrightText: Florian Bruhin (The-Compiler)
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
"use strict";
diff --git a/qutebrowser/javascript/position_caret.js b/qutebrowser/javascript/position_caret.js
index 7b53008faba..ba66c6d889a 100644
--- a/qutebrowser/javascript/position_caret.js
+++ b/qutebrowser/javascript/position_caret.js
@@ -1,22 +1,7 @@
-/**
-* Copyright 2015-2021 Florian Bruhin (The Compiler)
-* Copyright 2015 Artur Shaik
-*
-* 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 .
-*/
+// SPDX-FileCopyrightText: Artur Shaik
+// SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
/**
* Snippet to position caret at top of the page when caret mode is enabled.
diff --git a/qutebrowser/javascript/scroll.js b/qutebrowser/javascript/scroll.js
index 8bb904c56e5..39b1f55dbcf 100644
--- a/qutebrowser/javascript/scroll.js
+++ b/qutebrowser/javascript/scroll.js
@@ -1,21 +1,6 @@
-/**
- * Copyright 2016-2021 Florian Bruhin (The Compiler)
- *
- * 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 .
- */
+// SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
"use strict";
diff --git a/qutebrowser/javascript/stylesheet.js b/qutebrowser/javascript/stylesheet.js
index e91e338e1d9..bf818356c73 100644
--- a/qutebrowser/javascript/stylesheet.js
+++ b/qutebrowser/javascript/stylesheet.js
@@ -1,22 +1,7 @@
-/**
- * Copyright 2017-2021 Florian Bruhin (The Compiler)
- * Copyright 2017 Ulrik de Muelenaere
- *
- * 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 .
- */
+// SPDX-FileCopyrightText: Ulrik de Muelenaere
+// SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
"use strict";
diff --git a/qutebrowser/javascript/webelem.js b/qutebrowser/javascript/webelem.js
index 1a753c38031..5ea84c4971f 100644
--- a/qutebrowser/javascript/webelem.js
+++ b/qutebrowser/javascript/webelem.js
@@ -1,21 +1,6 @@
-/**
- * Copyright 2016-2021 Florian Bruhin (The Compiler)
- *
- * 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 .
- */
+// SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
/**
* The connection for web elements between Python and Javascript works like
diff --git a/qutebrowser/keyinput/__init__.py b/qutebrowser/keyinput/__init__.py
index ed51a380656..307e67788f0 100644
--- a/qutebrowser/keyinput/__init__.py
+++ b/qutebrowser/keyinput/__init__.py
@@ -1,18 +1,5 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Modules related to keyboard input and mode handling."""
diff --git a/qutebrowser/keyinput/basekeyparser.py b/qutebrowser/keyinput/basekeyparser.py
index 42aad02801d..df6b66f7f85 100644
--- a/qutebrowser/keyinput/basekeyparser.py
+++ b/qutebrowser/keyinput/basekeyparser.py
@@ -1,32 +1,20 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Base class for vim-like key sequence parser."""
import string
import types
import dataclasses
+import traceback
from typing import Mapping, MutableMapping, Optional, Sequence
from qutebrowser.qt.core import QObject, pyqtSignal
from qutebrowser.qt.gui import QKeySequence, QKeyEvent
from qutebrowser.config import config
-from qutebrowser.utils import log, usertypes, utils
+from qutebrowser.utils import log, usertypes, utils, message
from qutebrowser.keyinput import keyutils
@@ -202,7 +190,7 @@ def __repr__(self) -> str:
passthrough=self.passthrough,
supports_count=self._supports_count)
- def _debug_log(self, message: str) -> None:
+ def _debug_log(self, msg: str) -> None:
"""Log a message to the debug log if logging is active.
Args:
@@ -211,7 +199,7 @@ def _debug_log(self, message: str) -> None:
if self._do_log:
prefix = '{} for mode {}: '.format(self.__class__.__name__,
self._mode.name)
- log.keyboard.debug(prefix + message)
+ log.keyboard.debug(prefix + msg)
def _match_key(self, sequence: keyutils.KeySequence) -> MatchResult:
"""Try to match a given keystring with any bound keychain.
@@ -328,7 +316,15 @@ def _handle_result(self, info: keyutils.KeyInfo, result: MatchResult) -> None:
assert result.command is not None
self._debug_log("Definitive match for '{}'.".format(
result.sequence))
- count = int(self._count) if self._count else None
+
+ try:
+ count = int(self._count) if self._count else None
+ except ValueError as err:
+ message.error(f"Failed to parse count: {err}",
+ stack=traceback.format_exc())
+ self.clear_keystring()
+ return
+
self.clear_keystring()
self.execute(result.command, count)
elif result.match_type == QKeySequence.SequenceMatch.PartialMatch:
diff --git a/qutebrowser/keyinput/eventfilter.py b/qutebrowser/keyinput/eventfilter.py
index 007be6d15df..a9e7e78aaca 100644
--- a/qutebrowser/keyinput/eventfilter.py
+++ b/qutebrowser/keyinput/eventfilter.py
@@ -1,31 +1,17 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Global Qt event filter which dispatches key events."""
-from typing import cast
+from typing import cast, Optional
-from qutebrowser.qt import machinery
-from qutebrowser.qt.core import pyqtSlot, QObject, QEvent
+from qutebrowser.qt.core import pyqtSlot, QObject, QEvent, qVersion
from qutebrowser.qt.gui import QKeyEvent, QWindow
from qutebrowser.keyinput import modeman
from qutebrowser.misc import quitter, objects
-from qutebrowser.utils import objreg, debug, log
+from qutebrowser.utils import objreg, debug, log, qtutils
class EventFilter(QObject):
@@ -76,7 +62,7 @@ def _handle_key_event(self, event: QKeyEvent) -> bool:
# No window available yet, or not a MainWindow
return False
- def eventFilter(self, obj: QObject, event: QEvent) -> bool:
+ def eventFilter(self, obj: Optional[QObject], event: Optional[QEvent]) -> bool:
"""Handle an event.
Args:
@@ -86,9 +72,8 @@ def eventFilter(self, obj: QObject, event: QEvent) -> bool:
Return:
True if the event should be filtered, False if it's passed through.
"""
+ assert event is not None
ev_type = event.type()
- if machinery.IS_QT6:
- ev_type = cast(QEvent.Type, ev_type)
if self._log_qt_events:
try:
@@ -99,6 +84,19 @@ def eventFilter(self, obj: QObject, event: QEvent) -> bool:
ev_type_str = debug.qenum_key(QEvent, ev_type)
log.misc.debug(f"{source} got event: {ev_type_str}")
+ if (
+ ev_type == QEvent.Type.DragEnter and
+ qtutils.is_wayland() and
+ qVersion() == "6.5.2"
+ ):
+ # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-115757
+ # Fixed in Qt 6.5.3
+ # Can't do this via self._handlers since handling it for QWindow
+ # seems to be too late.
+ log.mouse.warning("Ignoring drag event to prevent Qt crash")
+ event.ignore()
+ return True
+
if not isinstance(obj, QWindow):
# We already handled this same event at some point earlier, so
# we're not interested in it anymore.
diff --git a/qutebrowser/keyinput/keyutils.py b/qutebrowser/keyinput/keyutils.py
index e2a15b2c078..af19bb61c59 100644
--- a/qutebrowser/keyinput/keyutils.py
+++ b/qutebrowser/keyinput/keyutils.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Our own QKeySequence-like class and related utilities.
@@ -37,9 +24,7 @@
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
+ from qutebrowser.qt.core import QKeyCombination
else:
QKeyCombination = None # QKeyCombination was added in Qt 6
@@ -349,7 +334,7 @@ def _unset_modifier_bits(
https://github.com/python/cpython/issues/105497
"""
if machinery.IS_QT5:
- return cast(_ModifierType, modifiers & ~mask)
+ return Qt.KeyboardModifiers(modifiers & ~mask) # can lose type if it's 0
else:
return Qt.KeyboardModifier(modifiers.value & ~mask.value)
@@ -369,11 +354,14 @@ class KeyInfo:
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
+ # This changed with Qt 6, and e.g. to_qt() relies on this.
+ if machinery.IS_QT5:
+ modifier_classes = (Qt.KeyboardModifier, Qt.KeyboardModifiers)
+ elif machinery.IS_QT6:
+ modifier_classes = Qt.KeyboardModifier
+ assert isinstance(self.key, Qt.Key), self.key
+ assert isinstance(self.modifiers, modifier_classes), self.modifiers
+
_assert_plain_key(self.key)
_assert_plain_modifier(self.modifiers)
@@ -488,16 +476,7 @@ def to_qt(self) -> _KeyInfoType:
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)
+ return QKeyCombination(self.modifiers, self.key)
def with_stripped_modifiers(self, modifiers: Qt.KeyboardModifier) -> "KeyInfo":
mods = _unset_modifier_bits(self.modifiers, modifiers)
diff --git a/qutebrowser/keyinput/macros.py b/qutebrowser/keyinput/macros.py
index 9c5282d3df9..69198ecfbad 100644
--- a/qutebrowser/keyinput/macros.py
+++ b/qutebrowser/keyinput/macros.py
@@ -1,20 +1,7 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
-# Copyright 2016-2018 Jan Verbeek (blyxxyz)
+# SPDX-FileCopyrightText: Jan Verbeek (blyxxyz)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Keyboard macro system."""
diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py
index fe3650a2c62..f0337ec8856 100644
--- a/qutebrowser/keyinput/modeman.py
+++ b/qutebrowser/keyinput/modeman.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Mode manager (per window) which handles the current keyboard mode."""
@@ -29,7 +16,7 @@
from qutebrowser.keyinput import modeparsers, basekeyparser
from qutebrowser.config import config
from qutebrowser.api import cmdutils
-from qutebrowser.utils import usertypes, log, objreg, utils
+from qutebrowser.utils import usertypes, log, objreg, utils, qtutils
from qutebrowser.browser import hints
from qutebrowser.misc import objects
@@ -321,10 +308,10 @@ def _handle_keypress(self, event: QKeyEvent, *,
focus_widget = objects.qapp.focusWidget()
log.modes.debug("match: {}, forward_unbound_keys: {}, "
"passthrough: {}, is_non_alnum: {}, dry_run: {} "
- "--> filter: {} (focused: {!r})".format(
+ "--> filter: {} (focused: {})".format(
match, forward_unbound_keys,
parser.passthrough, is_non_alnum, dry_run,
- filter_this, focus_widget))
+ filter_this, qtutils.qobj_repr(focus_widget)))
return filter_this
def _handle_keyrelease(self, event: QKeyEvent) -> bool:
@@ -474,11 +461,7 @@ def handle_event(self, event: QEvent) -> bool:
QEvent.Type.ShortcutOverride:
functools.partial(self._handle_keypress, dry_run=True),
}
- ev_type = event.type()
- if machinery.IS_QT6:
- ev_type = cast(QEvent.Type, ev_type)
-
- handler = handlers[ev_type]
+ handler = handlers[event.type()]
return handler(cast(QKeyEvent, event))
@cmdutils.register(instance='mode-manager', scope='window')
diff --git a/qutebrowser/keyinput/modeparsers.py b/qutebrowser/keyinput/modeparsers.py
index 7a2576f5d58..05e560111b3 100644
--- a/qutebrowser/keyinput/modeparsers.py
+++ b/qutebrowser/keyinput/modeparsers.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""KeyChainParser for "hint" and "normal" modes.
@@ -97,6 +84,7 @@ def __init__(self, *, win_id: int,
self._inhibited = False
self._inhibited_timer = usertypes.Timer(self, 'normal-inhibited')
self._inhibited_timer.setSingleShot(True)
+ self._inhibited_timer.timeout.connect(self._clear_inhibited)
def __repr__(self) -> str:
return utils.get_repr(self)
@@ -126,7 +114,6 @@ def set_inhibited_timeout(self, timeout: int) -> None:
timeout))
self._inhibited = True
self._inhibited_timer.setInterval(timeout)
- self._inhibited_timer.timeout.connect(self._clear_inhibited)
self._inhibited_timer.start()
@pyqtSlot()
@@ -267,8 +254,10 @@ def __init__(self, *, win_id: int,
mode: usertypes.KeyMode,
commandrunner: 'runners.CommandRunner',
parent: QObject = None) -> None:
- super().__init__(mode=usertypes.KeyMode.register, win_id=win_id,
- commandrunner=commandrunner, parent=parent,
+ super().__init__(mode=usertypes.KeyMode.register,
+ win_id=win_id,
+ commandrunner=commandrunner,
+ parent=parent,
supports_count=False)
self._register_mode = mode
diff --git a/qutebrowser/mainwindow/__init__.py b/qutebrowser/mainwindow/__init__.py
index 65381731f9b..c69ac44ba1c 100644
--- a/qutebrowser/mainwindow/__init__.py
+++ b/qutebrowser/mainwindow/__init__.py
@@ -1,18 +1,5 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Widgets needed for the main window."""
diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py
index 405e9fd285b..9251131e349 100644
--- a/qutebrowser/mainwindow/mainwindow.py
+++ b/qutebrowser/mainwindow/mainwindow.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""The main window of qutebrowser."""
@@ -502,6 +489,8 @@ def _connect_signals(self):
mode_manager = modeman.instance(self.win_id)
# misc
+ self._prompt_container.release_focus.connect(
+ self.tabbed_browser.on_release_focus)
self.tabbed_browser.close_window.connect(self.close)
mode_manager.entered.connect(hints.on_mode_entered)
@@ -580,6 +569,7 @@ def _connect_signals(self):
self._completion.on_clear_completion_selection)
self.status.cmd.hide_completion.connect(
self._completion.hide)
+ self.status.cmd.hide_cmd.connect(self.tabbed_browser.on_release_focus)
def _set_decoration(self, hidden):
"""Set the visibility of the window decoration via Qt."""
diff --git a/qutebrowser/mainwindow/messageview.py b/qutebrowser/mainwindow/messageview.py
index e3b01646e22..38d2a2f9e4c 100644
--- a/qutebrowser/mainwindow/messageview.py
+++ b/qutebrowser/mainwindow/messageview.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Showing messages above the statusbar."""
diff --git a/qutebrowser/mainwindow/prompt.py b/qutebrowser/mainwindow/prompt.py
index 26a2ae88699..92d3cc2ea08 100644
--- a/qutebrowser/mainwindow/prompt.py
+++ b/qutebrowser/mainwindow/prompt.py
@@ -1,19 +1,6 @@
-# Copyright 2016-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Showing prompts above the statusbar."""
@@ -28,8 +15,8 @@
QItemSelectionModel, QObject, QEventLoop)
from qutebrowser.qt.widgets import (QWidget, QGridLayout, QVBoxLayout, QLineEdit,
QLabel, QTreeView, QSizePolicy,
- QSpacerItem)
-from qutebrowser.qt.gui import QFileSystemModel
+ QSpacerItem, QFileIconProvider)
+from qutebrowser.qt.gui import (QFileSystemModel, QIcon)
from qutebrowser.browser import downloads
from qutebrowser.config import config, configtypes, configexc, stylesheet
@@ -215,6 +202,7 @@ def _on_mode_left(self, mode):
log.prompt.debug("Left mode {}, hiding {}".format(
mode, self._question))
self.show_prompts.emit(None)
+
if self._question.answer is None and not self._question.is_aborted:
log.prompt.debug("Cancelling {} because {} was left".format(
self._question, mode))
@@ -274,6 +262,7 @@ class PromptContainer(QWidget):
}
"""
update_geometry = pyqtSignal()
+ release_focus = pyqtSignal()
def __init__(self, win_id, parent=None):
super().__init__(parent)
@@ -300,18 +289,26 @@ def _on_show_prompts(self, question):
Args:
question: A Question object or None.
"""
- item = self._layout.takeAt(0)
- if item is not None:
+ item = qtutils.add_optional(self._layout.takeAt(0))
+ if item is None:
+ widget = None
+ else:
widget = item.widget()
- log.prompt.debug("Deleting old prompt {}".format(widget))
- widget.hide()
+ assert widget is not None
+ log.prompt.debug(f"Deleting old prompt {widget!r}")
widget.deleteLater()
if question is None:
log.prompt.debug("No prompts left, hiding prompt container.")
self._prompt = None
+ self.release_focus.emit()
self.hide()
return
+ elif widget is not None:
+ # We have more prompts to show, just hide the old one.
+ # This needs to happen *after* we possibly hid the entire prompt container,
+ # so that keyboard focus can be reassigned properly via release_focus.
+ widget.hide()
classes = {
usertypes.PromptMode.yesno: YesNoPrompt,
@@ -366,6 +363,7 @@ def _on_global_mode_left(self, mode):
item = self._layout.takeAt(0)
if item is not None:
widget = item.widget()
+ assert widget is not None
log.prompt.debug("Deleting prompt {}".format(widget))
widget.hide()
widget.deleteLater()
@@ -635,6 +633,21 @@ def _allowed_commands(self):
return [('prompt-accept', 'Accept'), ('mode-leave', 'Abort')]
+class NullIconProvider(QFileIconProvider):
+
+ """Returns empty icon for everything."""
+
+ def __init__(self):
+ super().__init__()
+ self.null_icon = QIcon()
+
+ def icon(self, _t):
+ return self.null_icon
+
+ def type(self, _info):
+ return 'unknown'
+
+
class FilenamePrompt(_BasePrompt):
"""A prompt for a filename."""
@@ -736,6 +749,10 @@ def _insert_path(self, index, *, clicked=True):
def _init_fileview(self):
self._file_view = QTreeView(self)
self._file_model = QFileSystemModel(self)
+
+ # avoid icon and mime type lookups, they are slow in Qt6
+ self._file_model.setIconProvider(NullIconProvider())
+
self._file_view.setModel(self._file_model)
self._file_view.clicked.connect(self._insert_path)
@@ -780,6 +797,7 @@ def item_focus(self, which):
# This duplicates some completion code, but I don't see a nicer way...
assert which in ['prev', 'next'], which
selmodel = self._file_view.selectionModel()
+ assert selmodel is not None
parent = self._file_view.rootIndex()
first_index = self._file_model.index(0, 0, parent)
diff --git a/qutebrowser/mainwindow/statusbar/__init__.py b/qutebrowser/mainwindow/statusbar/__init__.py
index 92dbe3590e5..ecc318265e6 100644
--- a/qutebrowser/mainwindow/statusbar/__init__.py
+++ b/qutebrowser/mainwindow/statusbar/__init__.py
@@ -1,18 +1,5 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Widgets needed for the statusbar."""
diff --git a/qutebrowser/mainwindow/statusbar/backforward.py b/qutebrowser/mainwindow/statusbar/backforward.py
index 6fcf61500b2..5e4dd98ed06 100644
--- a/qutebrowser/mainwindow/statusbar/backforward.py
+++ b/qutebrowser/mainwindow/statusbar/backforward.py
@@ -1,19 +1,6 @@
-# Copyright 2017-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Navigation (back/forward) indicator displayed in the statusbar."""
diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py
index 9abfe7152fa..b628a03cc8f 100644
--- a/qutebrowser/mainwindow/statusbar/bar.py
+++ b/qutebrowser/mainwindow/statusbar/bar.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""The main statusbar widget."""
@@ -390,9 +377,11 @@ def set_text(self, text):
@pyqtSlot(usertypes.KeyMode)
def on_mode_entered(self, mode):
"""Mark certain modes in the commandline."""
- mode_manager = modeman.instance(self._win_id)
- if config.val.statusbar.show == 'in-mode':
+ if config.val.statusbar.show == 'in-mode' and mode != usertypes.KeyMode.command:
+ # Showing in command mode is handled via _show_cmd_widget()
self.show()
+
+ mode_manager = modeman.instance(self._win_id)
if mode_manager.parsers[mode].passthrough:
self._set_mode_text(mode.name)
if mode in [usertypes.KeyMode.insert,
@@ -406,9 +395,11 @@ def on_mode_entered(self, mode):
@pyqtSlot(usertypes.KeyMode, usertypes.KeyMode)
def on_mode_left(self, old_mode, new_mode):
"""Clear marked mode."""
- mode_manager = modeman.instance(self._win_id)
- if config.val.statusbar.show == 'in-mode':
+ if config.val.statusbar.show == 'in-mode' and old_mode != usertypes.KeyMode.command:
+ # Hiding in command mode is handled via _hide_cmd_widget()
self.hide()
+
+ mode_manager = modeman.instance(self._win_id)
if mode_manager.parsers[old_mode].passthrough:
if mode_manager.parsers[new_mode].passthrough:
self._set_mode_text(new_mode.name)
diff --git a/qutebrowser/mainwindow/statusbar/clock.py b/qutebrowser/mainwindow/statusbar/clock.py
index 088e28a4a58..aa2afe8a01f 100644
--- a/qutebrowser/mainwindow/statusbar/clock.py
+++ b/qutebrowser/mainwindow/statusbar/clock.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Clock displayed in the statusbar."""
from datetime import datetime
diff --git a/qutebrowser/mainwindow/statusbar/command.py b/qutebrowser/mainwindow/statusbar/command.py
index 4332316a362..988eed4a0d0 100644
--- a/qutebrowser/mainwindow/statusbar/command.py
+++ b/qutebrowser/mainwindow/statusbar/command.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""The commandline in the statusbar."""
@@ -111,7 +98,7 @@ def prefix(self) -> str:
else:
return ''
- def set_cmd_text(self, text: str) -> None:
+ def cmd_set_text(self, text: str) -> None:
"""Preset the statusbar to some text.
Args:
@@ -123,10 +110,10 @@ def set_cmd_text(self, text: str) -> None:
self.setFocus()
self.show_cmd.emit()
- @cmdutils.register(instance='status-command', name='set-cmd-text',
- scope='window', maxsplit=0)
+ @cmdutils.register(instance='status-command', name='cmd-set-text',
+ scope='window', maxsplit=0, deprecated_name='set-cmd-text')
@cmdutils.argument('count', value=cmdutils.Value.count)
- def set_cmd_text_command(self, text: str,
+ def cmd_set_text_command(self, text: str,
count: int = None,
space: bool = False,
append: bool = False,
@@ -135,7 +122,7 @@ def set_cmd_text_command(self, text: str,
//
- Wrapper for set_cmd_text to check the arguments and allow multiple
+ Wrapper for cmd_set_text to check the arguments and allow multiple
strings which will get joined.
Args:
@@ -159,7 +146,7 @@ def set_cmd_text_command(self, text: str,
if run_on_count and count is not None:
self.got_cmd[str, int].emit(text, count)
else:
- self.set_cmd_text(text)
+ self.cmd_set_text(text)
@cmdutils.register(instance='status-command',
modes=[usertypes.KeyMode.command], scope='window')
@@ -174,7 +161,7 @@ def command_history_prev(self) -> None:
cmdhistory.HistoryEndReachedError):
return
if item:
- self.set_cmd_text(item)
+ self.cmd_set_text(item)
@cmdutils.register(instance='status-command',
modes=[usertypes.KeyMode.command], scope='window')
@@ -187,7 +174,7 @@ def command_history_next(self) -> None:
except cmdhistory.HistoryEndReachedError:
return
if item:
- self.set_cmd_text(item)
+ self.cmd_set_text(item)
@cmdutils.register(instance='status-command',
modes=[usertypes.KeyMode.command], scope='window')
@@ -210,8 +197,9 @@ def command_accept(self, rapid: bool = False) -> None:
if not was_search:
self.got_cmd[str].emit(text[1:])
- @cmdutils.register(instance='status-command', scope='window')
- def edit_command(self, run: bool = False) -> None:
+ @cmdutils.register(instance='status-command', scope='window',
+ deprecated_name='edit-command')
+ def cmd_edit(self, run: bool = False) -> None:
"""Open an editor to modify the current command.
Args:
@@ -225,7 +213,7 @@ def callback(text: str) -> None:
message.error('command must start with one of {}'
.format(modeparsers.STARTCHARS))
return
- self.set_cmd_text(text)
+ self.cmd_set_text(text)
if run:
self.command_accept()
@@ -259,15 +247,19 @@ def setText(self, text: Optional[str]) -> None:
else:
raise utils.Unreachable("setText got called with invalid text "
"'{}'!".format(text))
+ # FIXME:mypy PyQt6 stubs issue
+ if machinery.IS_QT6:
+ text = cast(str, text)
super().setText(text)
- def keyPressEvent(self, e: QKeyEvent) -> None:
+ def keyPressEvent(self, e: Optional[QKeyEvent]) -> None:
"""Override keyPressEvent to ignore Return key presses, and add Shift-Ins.
If this widget is focused, we are in passthrough key mode, and
Enter/Shift+Enter/etc. will cause QLineEdit to think it's finished
without command_accept to be called.
"""
+ assert e is not None
if machinery.IS_QT5: # FIXME:v4 needed for Qt 5 typing
shift = cast(Qt.KeyboardModifiers, Qt.KeyboardModifier.ShiftModifier)
else:
diff --git a/qutebrowser/mainwindow/statusbar/keystring.py b/qutebrowser/mainwindow/statusbar/keystring.py
index 133364acc68..9be36dc3aec 100644
--- a/qutebrowser/mainwindow/statusbar/keystring.py
+++ b/qutebrowser/mainwindow/statusbar/keystring.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Keychain string displayed in the statusbar."""
diff --git a/qutebrowser/mainwindow/statusbar/percentage.py b/qutebrowser/mainwindow/statusbar/percentage.py
index a8428dcbea5..d727a03dded 100644
--- a/qutebrowser/mainwindow/statusbar/percentage.py
+++ b/qutebrowser/mainwindow/statusbar/percentage.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Scroll percentage displayed in the statusbar."""
diff --git a/qutebrowser/mainwindow/statusbar/progress.py b/qutebrowser/mainwindow/statusbar/progress.py
index d04e30d09dd..3bc8cdf4a13 100644
--- a/qutebrowser/mainwindow/statusbar/progress.py
+++ b/qutebrowser/mainwindow/statusbar/progress.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""The progress bar in the statusbar."""
diff --git a/qutebrowser/mainwindow/statusbar/searchmatch.py b/qutebrowser/mainwindow/statusbar/searchmatch.py
index 88684a6c31b..aaee5aed921 100644
--- a/qutebrowser/mainwindow/statusbar/searchmatch.py
+++ b/qutebrowser/mainwindow/statusbar/searchmatch.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""The search match indicator in the statusbar."""
diff --git a/qutebrowser/mainwindow/statusbar/tabindex.py b/qutebrowser/mainwindow/statusbar/tabindex.py
index 3f4c6ce4313..59dadfb1ed4 100644
--- a/qutebrowser/mainwindow/statusbar/tabindex.py
+++ b/qutebrowser/mainwindow/statusbar/tabindex.py
@@ -1,19 +1,6 @@
-# Copyright 2015-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""TabIndex displayed in the statusbar."""
diff --git a/qutebrowser/mainwindow/statusbar/textbase.py b/qutebrowser/mainwindow/statusbar/textbase.py
index 3cd138bdfd7..734073df258 100644
--- a/qutebrowser/mainwindow/statusbar/textbase.py
+++ b/qutebrowser/mainwindow/statusbar/textbase.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""Base text widgets for statusbar."""
diff --git a/qutebrowser/mainwindow/statusbar/url.py b/qutebrowser/mainwindow/statusbar/url.py
index 54faf232d8b..0debabcd60a 100644
--- a/qutebrowser/mainwindow/statusbar/url.py
+++ b/qutebrowser/mainwindow/statusbar/url.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""URL displayed in the statusbar."""
@@ -116,7 +103,9 @@ def _update_url(self):
if old_urltype != self._urltype:
# We can avoid doing an unpolish here because the new style will
# always override the old one.
- self.style().polish(self)
+ style = self.style()
+ assert style is not None
+ style.polish(self)
@pyqtSlot(usertypes.LoadStatus)
def on_load_status_changed(self, status):
diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py
index 61f75c2b5a1..89b43285d83 100644
--- a/qutebrowser/mainwindow/tabbedbrowser.py
+++ b/qutebrowser/mainwindow/tabbedbrowser.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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 .
+# SPDX-License-Identifier: GPL-3.0-or-later
"""The main tabbed browser widget."""
@@ -250,7 +237,7 @@ def __init__(self, *, win_id, private, parent=None):
self.search_options: Mapping[str, Any] = {}
self._local_marks: MutableMapping[QUrl, MutableMapping[str, QPoint]] = {}
self._global_marks: MutableMapping[str, Tuple[QPoint, QUrl]] = {}
- self.default_window_icon = self.widget.window().windowIcon()
+ self.default_window_icon = self._window().windowIcon()
self.is_private = private
self.tab_deque = TabDeque()
config.instance.changed.connect(self._on_config_changed)
@@ -302,10 +289,9 @@ def widgets(self):
"""
widgets = []
for i in range(self.widget.count()):
- widget = self.widget.widget(i)
+ widget = qtutils.add_optional(self.widget.widget(i))
if widget is None:
- log.webview.debug( # type: ignore[unreachable]
- "Got None-widget in tabbedbrowser!")
+ log.webview.debug("Got None-widget in tabbedbrowser!")
else:
widgets.append(widget)
return widgets
@@ -331,7 +317,10 @@ def _update_window_title(self, field=None):
fields['id'] = self._win_id
title = title_format.format(**fields)
- self.widget.window().setWindowTitle(title)
+ # prevent hanging WMs and similar issues with giant URLs
+ title = utils.elide(title, 1024)
+
+ self._window().setWindowTitle(title)
def _connect_tab_signals(self, tab):
"""Set up the needed signals for tab."""
@@ -397,6 +386,15 @@ def _current_tab(self) -> browsertab.AbstractTab:
assert isinstance(tab, browsertab.AbstractTab), tab
return tab
+ def _window(self) -> QWidget:
+ """Get the current window widget.
+
+ Note: This asserts if there is no window.
+ """
+ window = self.widget.window()
+ assert window is not None
+ return window
+
def _tab_by_idx(self, idx: int) -> Optional[browsertab.AbstractTab]:
"""Get a browser tab by index.
@@ -673,11 +671,12 @@ def tabopen(
# Make sure the background tab has the correct initial size.
# With a foreground tab, it's going to be resized correctly by the
# layout anyways.
- tab.resize(self.widget.currentWidget().size())
+ current_widget = self._current_tab()
+ tab.resize(current_widget.size())
self.widget.tab_index_changed.emit(self.widget.currentIndex(),
self.widget.count())
# Refocus webview in case we lost it by spawning a bg tab
- self.widget.currentWidget().setFocus()
+ current_widget.setFocus()
else:
self.widget.setCurrentWidget(tab)
@@ -750,7 +749,7 @@ def _on_load_started(self, tab):
tab.data.keep_icon = False
elif (config.cache['tabs.tabs_are_windows'] and
tab.data.should_show_icon()):
- self.widget.window().setWindowIcon(self.default_window_icon)
+ self._window().setWindowIcon(self.default_window_icon)
@pyqtSlot()
def _on_load_status_changed(self, tab):
@@ -870,19 +869,34 @@ def on_mode_entered(self, mode):
assert isinstance(tab, browsertab.AbstractTab), tab
tab.data.input_mode = mode
- @pyqtSlot(usertypes.KeyMode)
- def on_mode_left(self, mode):
- """Give focus to current tab if command mode was left."""
- widget = self.widget.currentWidget()
+ @pyqtSlot()
+ def on_release_focus(self):
+ """Give keyboard focus to the current tab when requested by statusbar/prompt.
+
+ This gets emitted by the statusbar and prompt container before they call .hide()
+ on themselves, with the idea that we can explicitly reassign the focus,
+ instead of Qt implicitly calling its QWidget::focusNextPrevChild() method,
+ finding a new widget to give keyboard focus to.
+ """
+ widget = qtutils.add_optional(self.widget.currentWidget())
+ if widget is None:
+ return
+
+ log.modes.debug(f"Focus released, focusing {widget!r}")
+ widget.setFocus()
+
+ @pyqtSlot()
+ def on_mode_left(self):
+ """Save input mode for restoring if needed."""
+ if config.val.tabs.mode_on_change != 'restore':
+ return
+
+ widget = qtutils.add_optional(self.widget.currentWidget())
if widget is None:
- return # type: ignore[unreachable]
- if mode in [usertypes.KeyMode.command] + modeman.PROMPT_MODES:
- log.modes.debug("Left status-input mode, focusing {!r}".format(
- widget))
- widget.setFocus()
- if config.val.tabs.mode_on_change == 'restore':
- assert isinstance(widget, browsertab.AbstractTab), widget
- widget.data.input_mode = usertypes.KeyMode.normal
+ return
+
+ assert isinstance(widget, browsertab.AbstractTab), widget
+ widget.data.input_mode = usertypes.KeyMode.normal
@pyqtSlot(int)
def _on_current_changed(self, idx):
diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py
index 2ac7cb6d4a7..be1c696cfc8 100644
--- a/qutebrowser/mainwindow/tabwidget.py
+++ b/qutebrowser/mainwindow/tabwidget.py
@@ -1,19 +1,6 @@
-# Copyright 2014-2021 Florian Bruhin (The Compiler)
+# SPDX-FileCopyrightText: Florian Bruhin (The Compiler)
#
-# 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