Compare commits

..

26 Commits
main ... v2.2.1

Author SHA1 Message Date
Florian Bruhin 469bca1777 Release v2.2.1 2021-04-29 13:32:59 +02:00
Florian Bruhin f80ce9a325 Update changelog from master 2021-04-29 13:32:37 +02:00
Florian Bruhin dcb1ca35ae scripts: Add --no-confirm to build_release
(cherry picked from commit 9aa8740ec9)
2021-04-29 09:36:23 +02:00
Florian Bruhin c6ebf26223 ci: Fix CodeQL
(cherry picked from commit 4751890acb)
2021-04-29 09:35:17 +02:00
Florian Bruhin ab566cdb03 ci: Lock down workflows
Closes #6430

(cherry picked from commit 8023b8c8fe)
2021-04-29 09:35:09 +02:00
Florian Bruhin 1167b5c3e8 Add QUTE_QTWEBENGINE_VERSION_OVERRIDE
See https://github.com/NixOS/nixpkgs/pull/119376#issuecomment-820073044

(cherry picked from commit febb921040)
2021-04-29 09:34:51 +02:00
Florian Bruhin 7d93098fd0 tests: Fix test_version with git's init.defaultBranch
(cherry picked from commit 32604a6651)
2021-04-29 09:34:51 +02:00
afreakk 73ce4ef9e1 qute-pass: dont run pass twice when otp-only
(cherry picked from commit b04f99bcfc)
2021-04-28 08:19:48 +02:00
Nicholas Schwab a44ac66ede Improved readability of statusbar.widgets documentation.
(cherry picked from commit 38c5eba3e1)
2021-04-28 08:19:45 +02:00
Nicholas Schwab 14a152f246 Added text: to valid values of statusbar.widgets, making the
documentation more uniform.

(cherry picked from commit a083728168)
2021-04-28 08:19:43 +02:00
Florian Bruhin c684e5fd3a Add a site-specific quirk for Discord
Closes #4379

(cherry picked from commit be37524f47)
2021-04-28 08:19:37 +02:00
Florian Bruhin f675a958e5 Revert "Set print resolution to 300dpi"
This reverts commit 1e5184bc71.
2021-04-23 11:45:22 +02:00
Florian Bruhin 1e5184bc71 Set print resolution to 300dpi
See https://codereview.qt-project.org/c/qt/qtwebengine/+/344042

(cherry picked from commit 2e4ca779c6)
2021-04-23 11:22:33 +02:00
Florian Bruhin d19375b664 Fix tests on Windows
(cherry picked from commit 0ee169e497)
2021-04-23 11:11:00 +02:00
Florian Bruhin 55a2f68d95 Fix :spawn -u -o
Fixes #6407

(cherry picked from commit c7b3559d82)
2021-04-23 10:43:15 +02:00
Florian Bruhin 57a8f13393 Update PE checksum patching after PyInstaller update
(cherry picked from commit b1265cbeff)
2021-04-22 20:47:31 +02:00
Florian Bruhin 02619e3c84 Update PyInstaller from master 2021-04-22 20:47:07 +02:00
Florian Bruhin 078f1920a1 ci: Pin Python 3.10 to Alpha 7
See https://github.com/actions/setup-python/issues/207

pytest isn't ready yet:
https://github.com/pytest-dev/pytest/issues/8539

(cherry picked from commit 0c1414c6aa)
2021-04-19 11:45:42 +02:00
afreakk fcb483d36f qute-pass: extract username/pw only when needed
(cherry picked from commit efcb379872)
2021-04-19 11:28:05 +02:00
frank shin d64d59502a address PR comment
(cherry picked from commit 49e858e7d4)
2021-04-19 11:28:05 +02:00
frank shin 951ab7902e Check bitwarden CLI tool return code instead of stderr to check for error
(cherry picked from commit 909230a8ac)
2021-04-19 11:28:05 +02:00
Florian Bruhin 44ee8272d8 requirements: Fully remove python_version marker for adblock
See https://github.com/ArniDagur/python-adblock/issues/28

Follow-up to de4fff3866
(cherry picked from commit ffdee8534d)
Also updates adblock from 3b76a0d4b9
2021-04-19 11:27:13 +02:00
Florian Bruhin 19c01aa772 mkvenv: Handle failing ldconfig
(cherry picked from commit 1b4daf7c37)
2021-04-17 10:44:35 +02:00
Florian Bruhin bdf9f121ee notifications: Ignore KDE's ExcessNotificationGeneration
(cherry picked from commit 9fdfd3b4c0)
2021-04-17 10:44:35 +02:00
Florian Bruhin 292337fbdd notifications: Show adapter errors to users
Otherwise their notifications could suddenly stop working or otherwise
change apperance.

(cherry picked from commit ebf9619583)
2021-04-13 17:39:42 +02:00
Florian Bruhin 8232d38492 notifications: Handle MaxNotificationsExceeded error from GNOME Flashback
(cherry picked from commit 2cfc64579a)
2021-04-13 17:39:42 +02:00
699 changed files with 23647 additions and 36372 deletions

19
.bumpversion.cfg Normal file
View File

@ -0,0 +1,19 @@
[bumpversion]
current_version = 2.2.1
commit = True
message = Release v{new_version}
tag = True
sign_tags = True
tag_name = v{new_version}
[bumpversion:file:qutebrowser/__init__.py]
parse = __version__ = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
[bumpversion:file:misc/org.qutebrowser.qutebrowser.appdata.xml]
search = <!-- Add new releases here -->
replace = <!-- Add new releases here -->
<release version="{new_version}" date="{now:%Y-%m-%d}"/>
[bumpversion:file:doc/changelog.asciidoc]
search = (unreleased)
replace = ({now:%Y-%m-%d})

View File

@ -1,26 +0,0 @@
[tool.bumpversion]
current_version = "3.6.3"
commit = true
message = "Release v{new_version}"
tag = true
sign_tags = true
tag_name = "v{new_version}"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
serialize = ["{major}.{minor}.{patch}"]
allow_dirty = false
[[tool.bumpversion.files]]
filename = "qutebrowser/__init__.py"
search = "__version__ = \"{current_version}\""
replace = "__version__ = \"{new_version}\""
[[tool.bumpversion.files]]
filename = "misc/org.qutebrowser.qutebrowser.appdata.xml"
search = "<!-- Add new releases here -->"
replace = """<!-- Add new releases here -->
<release version='{new_version}' date='{now:%Y-%m-%d}'/>"""
[[tool.bumpversion.files]]
filename = "doc/changelog.asciidoc"
search = "(unreleased)"
replace = "({now:%Y-%m-%d})"

View File

@ -1,11 +1,7 @@
coverage:
status:
project:
default:
informational: true
patch:
default:
informational: true
project: false
patch: false
changes: false
comment: false

View File

@ -4,7 +4,6 @@ include =
tests/*
scripts/*
branch = true
patch = subprocess
omit =
qutebrowser/__main__.py
*/__init__.py

23
.flake8
View File

@ -4,7 +4,6 @@ exclude = .*,__pycache__,resources.py
# B008: Do not perform calls in argument defaults. (fine with some Qt stuff)
# B011: Do not call assert False since python -O removes these calls. Instead
# callers should raise AssertionError().
# B028: Missing stacklevel= for warnings
# B305: .next() (false-positives)
# E128: continuation line under-indented for visual indent
# E226: missing whitespace around arithmetic operator
@ -17,7 +16,6 @@ exclude = .*,__pycache__,resources.py
# (for pytest's __tracebackhide__)
# F401: Unused import
# N802: function name should be lowercase
# N818: exception name '...' should be named with an Error suffix
# N806: variable in function should be lowercase
# P101: format string does contain unindexed parameters
# P102: docstring does contain unindexed parameters
@ -41,34 +39,25 @@ exclude = .*,__pycache__,resources.py
# A003: Builtin name for class attribute (needed for overridden methods)
# W503: like break before binary operator
# W504: line break after binary operator
# FI18: __future__ import "annotations" missing
# FI58: __future__ import "annotations" present
# PT004: fixture '{name}' does not return anything, add leading underscore
# PT011: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
# PT012: pytest.raises() block should contain a single simple statement
# FI15: __future__ import "generator_stop" missing
ignore =
B001,B008,B305,
E128,E226,E265,E501,E402,E266,E722,E731,
F401,
N802,N818,
N802,
P101,P102,P103,
D102,D103,D106,D107,D104,D105,D209,D211,D401,D402,D403,D412,D413,
A003,
W503, W504,
FI18,FI58,
PT004,
PT011,
PT012
min-version = 3.9.0
W503, W504
FI15
min-version = 3.6.1
max-complexity = 12
per-file-ignores =
qutebrowser/api/hook.py : N801
qutebrowser/qt/*.py : F403
tests/* : B011,B028,D100,D101
tests/* : B011,D100,D101
tests/unit/browser/test_history.py : D100,D101,N806
tests/helpers/fixtures.py : D100,D101,N806
tests/unit/browser/webkit/http/test_content_disposition.py : D100,D101,D400
copyright-check = True
copyright-regexp = # Copyright [\d-]+ .*
copyright-min-file-size = 110
pytest-parametrize-names-type = csv

View File

@ -5,11 +5,11 @@ open pull requests.
- Before you start to work on something, please leave a comment on the relevant
issue (or open one). This makes sure there is no duplicate work done.
- Either run the testsuite locally, or keep an eye on the CI at the end of the
pull request page after pushing changes.
- Either run the testsuite locally, or keep an eye on Travis CI / AppVeyor
after pushing changes.
- If you are stuck somewhere or have questions,
https://github.com/qutebrowser/qutebrowser/blob/main/doc/help/index.asciidoc#getting-help[please ask]!
https://github.com/qutebrowser/qutebrowser#getting-help[please ask]!
See the link:../doc/contributing.asciidoc[full contribution documentation] for
details and other useful hints.

2
.github/FUNDING.yml vendored
View File

@ -1,2 +1,2 @@
github: The-Compiler
custom: https://github.com/qutebrowser/qutebrowser/blob/main/README.asciidoc#donating
custom: https://github.com/qutebrowser/qutebrowser/blob/master/README.asciidoc#donating

3
.github/SECURITY.md vendored
View File

@ -1,4 +1 @@
Please report security bugs to [security@qutebrowser.org](mailto:security@qutebrowser.org).
(or if GPG encryption is desired, contact me@the-compiler.org with GPG ID [0x916EB0C8FD55A072](https://www.the-compiler.org/pubkey.asc)).
Alternatively, [report a vulnerability](https://github.com/qutebrowser/qutebrowser/security/advisories/new) via GitHub's [private reporting feature](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability).

View File

@ -1,6 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

View File

@ -10,72 +10,104 @@ on:
jobs:
tests:
if: "github.repository == 'qutebrowser/qutebrowser'"
runs-on: ubuntu-24.04
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
include:
- testenv: bleeding
image: "archlinux-webengine-unstable"
runs-on: ubuntu-20.04
timeout-minutes: 30
container:
image: "qutebrowser/ci:${{ matrix.image }}"
image: "qutebrowser/ci:archlinux-webengine-unstable"
env:
FORCE_COLOR: "1"
PY_COLORS: "1"
DOCKER: "${{ matrix.image }}"
DOCKER: "archlinux-webengine-unstable"
CI: true
TMPDIR: "${{ runner.temp }}"
PYTEST_ADDOPTS: "--color=yes"
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@v6
- uses: actions/checkout@v2
with:
persist-credentials: false
- name: Set up problem matchers
run: "python scripts/dev/ci/problemmatchers.py py3 ${{ runner.temp }}"
- name: Upgrade 3rd party assets
run: "tox exec -e ${{ matrix.testenv }} -- python scripts/dev/update_3rdparty.py --gh-token ${{ secrets.GITHUB_TOKEN }} --modern-pdfjs"
- name: Run tox
run: dbus-run-session tox -e ${{ matrix.testenv }}
- name: Gather info
id: info
run: |
echo "date=$(date +'%Y-%m-%d')" >> "$GITHUB_OUTPUT"
echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
shell: bash
if: failure()
- name: Upload screenshots
uses: actions/upload-artifact@v6
run: dbus-run-session tox -e bleeding
pyinstaller:
if: "github.repository == 'qutebrowser/qutebrowser'"
strategy:
fail-fast: false
matrix:
include:
- os: macos-10.15
- os: windows-2019
args: --64bit
- os: windows-2019
args: --32bit
- os: macos-10.15
args: --debug
- os: windows-2019
args: --64bit --debug
- os: windows-2019
args: --32bit --debug
runs-on: "${{ matrix.os }}"
timeout-minutes: 30
steps:
- uses: actions/checkout@v2
with:
name: "end2end-screenshots-${{ steps.info.outputs.date }}-${{ steps.info.outputs.sha_short }}-${{ matrix.image }}"
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Get asciidoc
uses: actions/checkout@v2
with:
repository: asciidoc-py/asciidoc-py
ref: '9.x'
path: asciidoc
persist-credentials: false
- name: Move asciidoc out of the repo
run: mv asciidoc ..
- name: Install dependencies
run: |
python -m pip install -U pip
python -m pip install -U -r misc/requirements/requirements-tox.txt
- name: Patch qutebrowser for debugging
if: "contains(matrix.args, '--debug')"
run: |
sed -i '' '/.-d., .--debug.,/s/$/ default=True,/' qutebrowser/qutebrowser.py
- name: Run tox
run: "tox -e build-release -- --asciidoc ../asciidoc/asciidoc.py --gh-token ${{ secrets.GITHUB_TOKEN }} ${{ matrix.args }}"
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: "qutebrowser-nightly-${{ github.sha }}"
path: |
${{ runner.temp }}/pytest-of-user/pytest-current/pytest-screenshots/*.png
if-no-files-found: ignore
if: failure()
dist/qutebrowser-*.dmg
dist/qutebrowser-*-windows-standalone-*.zip
dist/qutebrowser-*-*.exe
irc:
timeout-minutes: 2
continue-on-error: true
runs-on: ubuntu-24.04
needs: [tests]
runs-on: ubuntu-20.04
needs: [tests, pyinstaller]
if: "always() && github.repository == 'qutebrowser/qutebrowser'"
steps:
- name: Send success IRC notification
uses: Gottox/irc-message-action@v2
if: "needs.tests.result == 'success'"
uses: Gottox/irc-message-action@v1
if: "needs.tests.result == 'success' && needs.pyinstaller.result == 'success'"
with:
server: irc.libera.chat
channel: '#qutebrowser-bots'
server: chat.freenode.net
channel: '#qutebrowser-dev'
nickname: qutebrowser-bot
message: "[${{ github.workflow }}] \u00033Success:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})"
- name: Send non-success IRC notification
uses: Gottox/irc-message-action@v2
if: "needs.tests.result != 'success'"
uses: Gottox/irc-message-action@v1
if: "needs.tests.result != 'success' || needs.pyinstaller.result != 'success'"
with:
server: irc.libera.chat
channel: '#qutebrowser-bots'
server: chat.freenode.net
channel: '#qutebrowser-dev'
nickname: qutebrowser-bot
message: "[${{ github.workflow }}] \u00034FAIL:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})\n
tests: ${{ needs.tests.result }}"
tests: ${{ needs.tests.result }}, pyinstaller: ${{ needs.pyinstaller.result }}"

View File

@ -6,7 +6,6 @@ on:
- 'dependabot/*'
pull_request:
env:
FORCE_COLOR: "1"
PY_COLORS: "1"
MYPY_FORCE_TERMINAL_WIDTH: "180"
@ -14,50 +13,47 @@ jobs:
linters:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
timeout-minutes: 10
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
include:
- testenv: pylint
- testenv: flake8
- testenv: mypy-pyqt6
- testenv: mypy-pyqt5
- testenv: mypy
- testenv: docs
- testenv: vulture
- testenv: misc
- testenv: pyroma
- testenv: check-manifest
- testenv: eslint
- testenv: shellcheck
args: "-f gcc" # For problem matchers
- testenv: yamllint
- testenv: actionlint
- testenv: package
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v2
with:
persist-credentials: false
- uses: actions/cache@v5
- uses: actions/cache@v2
with:
path: |
.mypy_cache
.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@v6
- uses: actions/setup-python@v2
with:
python-version: '3.10'
- uses: actions/setup-node@v6
python-version: '3.8'
- uses: actions/setup-node@v2-beta
with:
node-version: '22.x'
node-version: '12.x'
if: "matrix.testenv == 'eslint'"
- name: Set up problem matchers
run: "python scripts/dev/ci/problemmatchers.py ${{ matrix.testenv }} ${{ runner.temp }}"
- name: Install dependencies
run: |
[[ ${{ matrix.testenv }} == eslint ]] && npm install -g 'eslint@<9.0.0'
[[ ${{ matrix.testenv }} == docs ]] && sudo apt-get update && sudo apt-get install --no-install-recommends asciidoc libegl1
[[ ${{ matrix.testenv }} == vulture || ${{ matrix.testenv }} == pylint ]] && sudo apt-get update && sudo apt-get install --no-install-recommends libegl1
[[ ${{ matrix.testenv }} == eslint ]] && npm install -g eslint
[[ ${{ matrix.testenv }} == docs ]] && sudo apt-get install --no-install-recommends asciidoc
if [[ ${{ matrix.testenv }} == shellcheck ]]; then
scversion="stable"
bindir="$HOME/.local/bin"
@ -65,162 +61,94 @@ jobs:
wget -qO- "https://github.com/koalaman/shellcheck/releases/download/$scversion/shellcheck-$scversion.linux.x86_64.tar.xz" | tar -xJv --strip-components 1 -C "$bindir" shellcheck-$scversion/shellcheck
echo "$bindir" >> "$GITHUB_PATH"
fi
if [[ ${{ matrix.testenv }} == actionlint ]]; then
bindir="$HOME/.local/bin"
mkdir -p "$bindir"
wget -q https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash
bash download-actionlint.bash latest "$bindir"
echo "$bindir" >> "$GITHUB_PATH"
fi
python -m pip install -U pip
python -m pip install -U -r misc/requirements/requirements-tox.txt
- name: "Run ${{ matrix.testenv }}"
run: |
if [[ -z "${{ matrix.args }}" ]]; then
dbus-run-session -- tox -e ${{ matrix.testenv }}
else
dbus-run-session -- tox -e ${{ matrix.testenv }} -- ${{ matrix.args }}
fi
run: "dbus-run-session -- tox -e ${{ matrix.testenv}} -- ${{ matrix.args }}"
tests-docker:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
timeout-minutes: 45
runs-on: ubuntu-22.04 # not 24.04 because sandboxing fails by default (#8424)
timeout-minutes: 30
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
include:
- testenv: py
image: archlinux-webengine
- testenv: py
image: archlinux-webengine-unstable
image:
- archlinux-webkit
- archlinux-webengine
# - archlinux-webengine-unstable
container:
image: "qutebrowser/ci:${{ matrix.image }}"
env:
QUTE_BDD_WEBENGINE: "${{ matrix.image != 'archlinux-webkit' }}"
DOCKER: "${{ matrix.image }}"
CI: true
PYTEST_ADDOPTS: "--color=yes"
TMPDIR: "${{ runner.temp }}"
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@v6
- uses: actions/checkout@v2
with:
persist-credentials: false
- name: Set up problem matchers
run: "python scripts/dev/ci/problemmatchers.py tests ${{ runner.temp }}"
run: "python scripts/dev/ci/problemmatchers.py py38 ${{ runner.temp }}"
- name: Run tox
run: "dbus-run-session -- tox -e ${{ matrix.testenv }}"
- name: Gather info
id: info
run: |
echo "date=$(date +'%Y-%m-%d')" >> "$GITHUB_OUTPUT"
echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
shell: bash
if: failure()
- name: Upload screenshots
uses: actions/upload-artifact@v6
with:
name: "end2end-screenshots-${{ steps.info.outputs.date }}-${{ steps.info.outputs.sha_short }}-${{ matrix.image }}"
path: |
${{ runner.temp }}/pytest-of-user/pytest-current/pytest-screenshots/*.png
if-no-files-found: ignore
if: failure()
run: dbus-run-session tox -e py
tests:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
timeout-minutes: 45
# continue-on-error: "${{ matrix.experimental == true }}"
continue-on-error: "${{ matrix.experimental == true }}"
strategy:
fail-fast: false
matrix:
include:
### PyQt 5.15.2 (Python 3.9)
- testenv: py39-pyqt5152
os: ubuntu-22.04
python: "3.9"
### PyQt 5.15 (Python 3.10, with coverage)
# FIXME:qt6
# - testenv: py310-pyqt515-cov
# os: ubuntu-22.04
# python: "3.10"
### PyQt 5.15 (Python 3.11)
- testenv: py311-pyqt515
os: ubuntu-22.04
python: "3.11"
### PyQt 6.2 (Python 3.9)
- testenv: py39-pyqt62
os: ubuntu-22.04
python: "3.9"
### PyQt 6.3 (Python 3.9)
- testenv: py39-pyqt63
os: ubuntu-22.04
python: "3.9"
## PyQt 6.4 (Python 3.9)
- testenv: py39-pyqt64
os: ubuntu-22.04
python: "3.9"
### PyQt 6.5 (Python 3.10)
- testenv: py310-pyqt65
os: ubuntu-22.04
python: "3.10"
### PyQt 6.6 (Python 3.11)
- testenv: py311-pyqt66
os: ubuntu-22.04
python: "3.11"
### PyQt 6.6 (Python 3.12)
- testenv: py312-pyqt66
os: ubuntu-22.04
python: "3.12"
### PyQt 6.7 (Python 3.11)
- testenv: py311-pyqt67
os: ubuntu-22.04
python: "3.11"
### PyQt 6.7 (Python 3.12)
- testenv: py312-pyqt67
os: ubuntu-22.04
python: "3.12"
### PyQt 6.8 (Python 3.13)
- testenv: py313-pyqt68
os: ubuntu-24.04
python: "3.13"
### PyQt 6.8 (Python 3.13)
- testenv: py313-pyqt68
os: ubuntu-24.04
python: "3.13"
### PyQt 6.9 (Python 3.14)
- testenv: py314-pyqt69
os: ubuntu-24.04
python: "3.14"
### PyQt 6.10 (Python 3.14)
- testenv: py314-pyqt610
os: ubuntu-24.04
python: "3.14"
### macOS Sonoma (M1 runner)
- testenv: py314-pyqt610
os: macos-14
python: "3.14"
### PyQt 5.12 (Python 3.6)
- testenv: py36-pyqt512
os: ubuntu-18.04
python: 3.6
### PyQt 5.13 (Python 3.7)
- testenv: py37-pyqt513
os: ubuntu-20.04
python: 3.7
### PyQt 5.14 (Python 3.8)
- testenv: py38-pyqt514
os: ubuntu-20.04
python: 3.8
### PyQt 5.15.0 (Python 3.9)
- testenv: py39-pyqt5150
os: ubuntu-20.04
python: 3.9
### PyQt 5.15 (Python 3.9, with coverage)
- testenv: py39-pyqt515-cov
os: ubuntu-20.04
python: 3.9
### PyQt 5.15 (Python 3.10)
- testenv: py310-pyqt515
os: ubuntu-20.04
python: 3.10.0-alpha.7
### macOS: PyQt 5.15 (Python 3.9 to match PyInstaller env)
- testenv: py39-pyqt515
os: macos-10.15
python: 3.7
args: "tests/unit" # Only run unit tests on macOS
### macOS Sequoia (Intel runner)
- testenv: py314-pyqt610
os: macos-15-intel
python: "3.14"
args: "tests/unit" # Only run unit tests on macOS
### Windows
- testenv: py314-pyqt610
os: windows-2022
python: "3.14"
- testenv: py314-pyqt610
os: windows-2025
python: "3.14"
### macOS Big Sur
# - testenv: py39-pyqt515
# os: macos-11.0
# python: 3.9
# args: "tests/unit" # Only run unit tests on macOS
### Windows: PyQt 5.15 (Python 3.9 to match PyInstaller env)
- testenv: py39-pyqt515
os: windows-2019
python: 3.9
runs-on: "${{ matrix.os }}"
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v2
with:
persist-credentials: false
- uses: actions/cache@v5
- uses: actions/cache@v2
with:
path: |
.mypy_cache
@ -228,7 +156,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@v6
uses: actions/setup-python@v2
with:
python-version: "${{ matrix.python }}"
- name: Set up problem matchers
@ -236,17 +164,12 @@ jobs:
- name: Install apt dependencies
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends libyaml-dev libegl1 libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 libjpeg-dev
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
if: "startsWith(matrix.os, 'ubuntu-')"
- name: Install dependencies
run: |
python -m pip install -U pip
python -m pip install -U -r misc/requirements/requirements-tox.txt
- name: Upgrade 3rd party assets
run: "tox exec -e ${{ matrix.testenv }} -- python scripts/dev/update_3rdparty.py --gh-token ${{ secrets.GITHUB_TOKEN }}"
if: "startsWith(matrix.os, 'windows-')"
- name: "Set TMPDIR for pytest"
run: 'echo "TMPDIR=${{ runner.temp }}" >> "$GITHUB_ENV"'
- name: "Run ${{ matrix.testenv }}"
run: "dbus-run-session -- tox -e ${{ matrix.testenv }} -- ${{ matrix.args }}"
if: "startsWith(matrix.os, 'ubuntu-')"
@ -258,82 +181,67 @@ jobs:
if: "failure()"
- name: Upload coverage
if: "endsWith(matrix.testenv, '-cov')"
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v1
with:
name: "${{ matrix.testenv }}"
- name: Gather info
id: info
run: |
echo "date=$(date +'%Y-%m-%d')" >> "$GITHUB_OUTPUT"
echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
shell: bash
if: failure()
- name: Upload screenshots
uses: actions/upload-artifact@v6
with:
name: "end2end-screenshots-${{ steps.info.outputs.date }}-${{ steps.info.outputs.sha_short }}-${{ matrix.testenv }}-${{ matrix.os }}"
path: |
${{ runner.temp }}/pytest-of-runner/pytest-current/pytest-screenshots/*.png
if-no-files-found: ignore
if: failure()
codeql:
if: "!contains(github.event.head_commit.message, '[ci skip]')"
permissions:
security-events: write
timeout-minutes: 15
runs-on: ubuntu-24.04
timeout-minutes: 30
runs-on: ubuntu-20.04
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v2
with:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
uses: github/codeql-action/init@v1
with:
languages: javascript, python
queries: +security-extended
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
uses: github/codeql-action/analyze@v1
irc:
timeout-minutes: 2
continue-on-error: true
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
needs: [linters, tests, tests-docker, codeql]
if: "always() && github.repository_owner == 'qutebrowser'"
steps:
- name: Send success IRC notification
uses: Gottox/irc-message-action@v2
uses: Gottox/irc-message-action@v1
if: "needs.linters.result == 'success' && needs.tests.result == 'success' && needs.tests-docker.result == 'success' && needs.codeql.result == 'success'"
with:
server: irc.libera.chat
channel: '#qutebrowser-bots'
server: chat.freenode.net
channel: '#qutebrowser-dev'
nickname: qutebrowser-bot
message: "[${{ github.workflow }}] \u00033Success:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})"
- name: Send failure IRC notification
uses: Gottox/irc-message-action@v2
uses: Gottox/irc-message-action@v1
if: "needs.linters.result == 'failure' || needs.tests.result == 'failure' || needs.tests-docker.result == 'failure' || needs.codeql.result == 'failure'"
with:
server: irc.libera.chat
channel: '#qutebrowser-bots'
server: chat.freenode.net
channel: '#qutebrowser-dev'
nickname: qutebrowser-bot
message: "[${{ github.workflow }}] \u00034FAIL:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})\n
linters: ${{ needs.linters.result }}, tests: ${{ needs.tests.result }}, tests-docker: ${{ needs.tests-docker.result }}, codeql: ${{ needs.codeql.result }}"
- name: Send skipped IRC notification
uses: Gottox/irc-message-action@v2
uses: Gottox/irc-message-action@v1
if: "needs.linters.result == 'skipped' || needs.tests.result == 'skipped' || needs.tests-docker.result == 'skipped' || needs.codeql.result == 'skipped'"
with:
server: irc.libera.chat
channel: '#qutebrowser-bots'
server: chat.freenode.net
channel: '#qutebrowser-dev'
nickname: qutebrowser-bot
message: "[${{ github.workflow }}] \u00038Skipped:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})"
- name: Send cancelled IRC notification
uses: Gottox/irc-message-action@v2
uses: Gottox/irc-message-action@v1
if: "needs.linters.result == 'cancelled' || needs.tests.result == 'cancelled' || needs.tests-docker.result == 'cancelled' || needs.codeql.result == 'cancelled'"
with:
server: irc.libera.chat
channel: '#qutebrowser-bots'
server: chat.freenode.net
channel: '#qutebrowser-dev'
nickname: qutebrowser-bot
message: "[${{ github.workflow }}] \u000314Cancelled:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})\n
linters: ${{ needs.linters.result }}, tests: ${{ needs.tests.result }}, tests-docker: ${{ needs.tests-docker.result }}, codeql: ${{ needs.codeql.result }}"

View File

@ -8,54 +8,54 @@ on:
jobs:
docker:
if: "github.repository == 'qutebrowser/qutebrowser'"
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
image:
- archlinux-webkit
- archlinux-webengine
- archlinux-webengine-unstable
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
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@v3
- uses: docker/login-action@v3
- uses: docker/setup-buildx-action@v1
- uses: docker/login-action@v1
with:
username: qutebrowser
password: ${{ secrets.DOCKER_TOKEN }}
- uses: docker/build-push-action@v6
- uses: docker/build-push-action@v2
with:
file: scripts/dev/ci/docker/Dockerfile
context: .
tags: "qutebrowser/ci:${{ matrix.image }}"
push: ${{ github.ref == 'refs/heads/main' }}
push: ${{ github.ref == 'refs/heads/master' }}
irc:
timeout-minutes: 2
continue-on-error: true
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
needs: [docker]
if: "always() && github.repository == 'qutebrowser/qutebrowser'"
steps:
- name: Send success IRC notification
uses: Gottox/irc-message-action@v2
uses: Gottox/irc-message-action@v1
if: "needs.docker.result == 'success'"
with:
server: irc.libera.chat
channel: '#qutebrowser-bots'
server: chat.freenode.net
channel: '#qutebrowser-dev'
nickname: qutebrowser-bot
message: "[${{ github.workflow }}] \u00033Success:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})"
- name: Send non-success IRC notification
uses: Gottox/irc-message-action@v2
uses: Gottox/irc-message-action@v1
if: "needs.docker.result != 'success'"
with:
server: irc.libera.chat
channel: '#qutebrowser-bots'
server: chat.freenode.net
channel: '#qutebrowser-dev'
nickname: qutebrowser-bot
message: "[${{ github.workflow }}] \u00034FAIL:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})"

View File

@ -1,107 +0,0 @@
name: Nightly builds
on:
workflow_dispatch:
schedule:
# Every day at 04:05 UTC
# https://crontab.guru/#05_04_*_*_*
- cron: '05 04 * * *'
jobs:
pyinstaller:
if: "github.repository == 'qutebrowser/qutebrowser'"
strategy:
fail-fast: false
matrix:
include:
- os: macos-15-intel
toxenv: build-release
name: macos-intel
- os: macos-14
toxenv: build-release
name: macos-apple-silicon
- os: windows-latest
toxenv: build-release
name: windows
- os: macos-15-intel
args: --debug
toxenv: build-release
name: macos-debug-intel
- os: macos-14
toxenv: build-release
name: macos-debug-apple-silicon
- os: windows-latest
args: --debug
toxenv: build-release
name: windows-debug
runs-on: "${{ matrix.os }}"
timeout-minutes: 45
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Install nsis
if: "matrix.os == 'windows-latest'"
run: |
irm get.scoop.sh | iex
scoop update
scoop bucket add extras
scoop install nsis
Add-Content $env:GITHUB_PATH "C:\Users\runneradmin\scoop\shims"
shell: pwsh
- name: Install dependencies
run: |
python -m pip install -U pip
python -m pip install -U -r misc/requirements/requirements-tox.txt
- name: Patch qutebrowser for debugging
if: "contains(matrix.args, '--debug')"
run: |
sed '/.-d., .--debug.,/s/$/ default=True,/' qutebrowser/qutebrowser.py > qutebrowser/qutebrowser.py.tmp
cp qutebrowser/qutebrowser.py.tmp qutebrowser/qutebrowser.py
rm qutebrowser/qutebrowser.py.tmp
- name: Run tox
run: "tox -e ${{ matrix.toxenv }} -- --gh-token ${{ secrets.GITHUB_TOKEN }} ${{ matrix.args }}"
- name: Gather info
id: info
run: |
echo "date=$(date +'%Y-%m-%d')" >> "$GITHUB_OUTPUT"
echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
shell: bash
- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
name: "qutebrowser-nightly-${{ steps.info.outputs.date }}-${{ steps.info.outputs.sha_short }}-${{ matrix.name }}"
path: |
dist/qutebrowser-*.dmg
dist/qutebrowser-*-windows-standalone-*.zip
dist/qutebrowser-*-*.exe
if-no-files-found: error
irc:
timeout-minutes: 2
continue-on-error: true
runs-on: ubuntu-24.04
needs: [pyinstaller]
if: "always() && github.repository == 'qutebrowser/qutebrowser'"
steps:
- name: Send success IRC notification
uses: Gottox/irc-message-action@v2
if: "needs.pyinstaller.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 non-success IRC notification
uses: Gottox/irc-message-action@v2
if: "needs.pyinstaller.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
pyinstaller: ${{ needs.pyinstaller.result }}"

View File

@ -7,8 +7,8 @@ on:
- cron: '05 04 * * 1'
workflow_dispatch:
inputs:
environments:
description: 'Test environments to update'
environment:
descriptions: 'Test environments to update'
required: false
default: ''
@ -18,20 +18,24 @@ jobs:
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v2
with:
persist-credentials: false
- name: Set up Python 3.9
uses: actions/setup-python@v6
- name: Set up Python 3.7
uses: actions/setup-python@v2
with:
python-version: '3.9'
python-version: '3.7'
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: '3.8'
- name: Recompile requirements
run: "python3 scripts/dev/recompile_requirements.py ${{ github.event.input.environments }}"
run: "python3 scripts/dev/recompile_requirements.py ${{ github.events.input.environments }}"
id: requirements
- name: Install apt dependencies
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends libyaml-dev libegl1 libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 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 asciidoc python3-venv xvfb
- name: Install dependencies
run: |
python -m pip install -U pip
@ -41,7 +45,7 @@ jobs:
- name: Run qutebrowser smoke test
run: "xvfb-run .venv/bin/python3 -m qutebrowser --no-err-windows --nowindow --temp-basedir about:blank ':later 500 quit'"
- name: Create pull request
uses: peter-evans/create-pull-request@v8
uses: peter-evans/create-pull-request@v3
with:
committer: qutebrowser bot <bot@qutebrowser.org>
author: qutebrowser bot <bot@qutebrowser.org>
@ -70,18 +74,19 @@ jobs:
if: "always() && github.repository == 'qutebrowser/qutebrowser'"
steps:
- name: Send success IRC notification
uses: Gottox/irc-message-action@v2
uses: Gottox/irc-message-action@v1
if: "needs.update.result == 'success'"
with:
server: irc.libera.chat
channel: '#qutebrowser-bots'
server: chat.freenode.net
channel: '#qutebrowser-dev'
nickname: qutebrowser-bot
message: "[${{ github.workflow }}] \u00033Success:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})"
- name: Send non-success IRC notification
uses: Gottox/irc-message-action@v2
uses: Gottox/irc-message-action@v1
if: "needs.update.result != 'success'"
with:
server: irc.libera.chat
channel: '#qutebrowser-bots'
server: chat.freenode.net
channel: '#qutebrowser-dev'
nickname: qutebrowser-bot
message: "[${{ github.workflow }}] \u00034FAIL:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})"
message: "[${{ github.workflow }}] \u00034FAIL:\u0003 ${{ github.ref }} https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} (@${{ github.actor }})\n
linters: ${{ needs.linters.result }}, tests: ${{ needs.tests.result }}, tests-docker: ${{ needs.tests-docker.result }}, codeql: ${{ needs.codeql.result }}"

View File

@ -1,252 +0,0 @@
name: Release
on:
workflow_dispatch:
inputs:
release_type:
description: 'Release type'
required: true
default: 'patch'
type: choice
options:
- 'patch'
- 'minor'
- 'major'
- 'reupload' # reupload last release
# FIXME do we want a possibility to do prereleases here?
python_version:
description: 'Python version'
required: true
default: '3.14'
type: choice
options:
- '3.9'
- '3.10'
- '3.11'
- '3.12'
- '3.13'
- '3.14'
jobs:
prepare:
runs-on: ubuntu-24.04
timeout-minutes: 5
outputs:
version: ${{ steps.bump.outputs.version }}
version_x: ${{ steps.bump.outputs.version_x }}
release_id: ${{ inputs.release_type == 'reupload' && steps.find-release.outputs.result || steps.create-release.outputs.id }}
permissions:
contents: write # To push release commit/tag
steps:
- name: Find release branch
uses: actions/github-script@v8
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@v6
- name: Set up Python
uses: actions/setup-python@v6
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@v6
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 -- ${{ inputs.release_type }}"
- name: Check milestone
uses: actions/github-script@v8
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
if: ${{ inputs.release_type != 'reupload' }}
run: |
git push origin ${{ steps.find-branch.outputs.result }}
git push origin v${{ steps.bump.outputs.version }}
- name: Cherry-pick release commit
if: ${{ inputs.release_type == 'patch' }}
run: |
git fetch origin main
git checkout main
git cherry-pick -x v${{ steps.bump.outputs.version }}
git push origin main
git checkout v${{ steps.bump.outputs.version_x }}
- name: Create release branch
if: ${{ inputs.release_type == 'minor' || inputs.release_type == 'major' }}
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
if: ${{ inputs.release_type != 'reupload' }}
id: create-release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.bump.outputs.version }}
draft: true
body: "*Release artifacts for this release are currently being uploaded...*"
- name: Find GitHub draft release
if: ${{ inputs.release_type == 'reupload' }}
id: find-release
uses: actions/github-script@v8
with:
script: |
const releases = await github.paginate(github.rest.repos.listReleases, {
owner: context.repo.owner,
repo: context.repo.repo,
});
const names = releases.map(release => release.name);
console.log(`releases: ${names}`);
const release = releases.find(release => release.tag_name === "v${{ steps.bump.outputs.version }}");
if (release === undefined) {
core.setFailed(`No release found with tag v${{ steps.bump.outputs.version }}!`);
}
if (!release.draft) {
core.setFailed(`Release ${release.tag_name} is not a draft release!`);
}
return release.id;
result-encoding: string
release:
strategy:
matrix:
include:
- os: macos-14-large # Intel
- os: macos-14 # Apple Silicon
- os: windows-2022
- os: ubuntu-24.04
runs-on: "${{ matrix.os }}"
timeout-minutes: 45
needs: [prepare]
permissions:
contents: write # To upload release artifacts
steps:
- uses: actions/checkout@v6
with:
ref: v${{ inputs.release_type == 'reupload' && needs.prepare.outputs.version_x || needs.prepare.outputs.version }}
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ 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 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 ${{ inputs.release_type == 'reupload' && '--reupload' || '' }}"
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.QUTEBROWSER_BOT_PYPI_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
finalize:
runs-on: ubuntu-24.04
timeout-minutes: 5
needs: [prepare, release]
permissions:
contents: write # To change release
steps:
- name: Publish final release
uses: actions/github-script@v8
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-24.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 }}"

1
.gitignore vendored
View File

@ -49,7 +49,6 @@ TODO
/scripts/testbrowser/cpp/webengine/testbrowser
/scripts/testbrowser/cpp/webengine/.qmake.stash
/scripts/dev/pylint_checkers/qute_pylint.egg-info
/scripts/dev/pylint_checkers/build
/misc/file_version_info.txt
/doc/extapi/_build
/misc/nsis/include

281
.mypy.ini
View File

@ -1,15 +1,16 @@
[mypy]
python_version = 3.9
python_version = 3.6
### --strict
warn_unused_configs = True
disallow_any_generics = True
# disallow_any_generics = True
disallow_subclassing_any = True
# disallow_untyped_calls = True
disallow_untyped_defs = True
# disallow_untyped_defs = True
disallow_incomplete_defs = True
check_untyped_defs = True
disallow_untyped_decorators = True
# no_implicit_optional = True
warn_redundant_casts = True
warn_unused_ignores = True
# warn_return_any = True
@ -19,255 +20,101 @@ strict_equality = True
### Other strictness flags
warn_unreachable = True
disallow_any_unimported = True
enable_error_code = ignore-without-code
strict_bytes = True
### Output
show_error_codes = True
show_error_context = True
pretty = True
### FIXME:v4 get rid of this
no_implicit_optional = False
### Future default behavior
local_partial_types = True
[mypy-colorama]
# https://github.com/tartley/colorama/issues/206
ignore_missing_imports = True
[mypy-hunter]
# https://github.com/ionelmc/python-hunter/issues/43
ignore_missing_imports = True
[mypy-objc]
# https://github.com/ronaldoussoren/pyobjc/issues/417
[mypy-pygments.*]
# https://github.com/pygments/pygments/issues/1189
ignore_missing_imports = True
[mypy-AppKit]
# https://github.com/ronaldoussoren/pyobjc/issues/417
ignore_missing_imports = True
[mypy-qutebrowser.browser.browsertab]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.webkit.*]
ignore_errors = True
[mypy-qutebrowser.browser.hints]
disallow_untyped_defs = True
[mypy-qutebrowser.config.configtypes]
# Needs some major work to use specific generics
disallow_any_generics = False
[mypy-qutebrowser.browser.inspector]
disallow_untyped_defs = True
# Modules that are not fully typed yet
[mypy-qutebrowser.app]
disallow_untyped_defs = False
[mypy-qutebrowser.browser.webkit.webkitinspector]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.commands]
disallow_untyped_defs = False
[mypy-qutebrowser.browser.webengine.webengineinspector]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.downloads]
disallow_untyped_defs = False
[mypy-qutebrowser.browser.webengine.notification]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.downloadview]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.guiprocess]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.eventfilter]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.objects]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.greasemonkey]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.quitter]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.history]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.debugcachestats]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.navigate]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.elf]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.network.pac]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.utilcmds]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.network.proxy]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.throttle]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.pdfjs]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.backendproblem]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.qtnetworkdownloads]
disallow_untyped_defs = False
[mypy-qutebrowser.config.*]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.shared]
disallow_untyped_defs = False
[mypy-qutebrowser.api.*]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.signalfilter]
disallow_untyped_defs = False
[mypy-qutebrowser.components.*]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.urlmarks]
disallow_untyped_defs = False
[mypy-qutebrowser.extensions.*]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.webengine.cookies]
disallow_untyped_defs = False
[mypy-qutebrowser.browser.webelem]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.webengine.interceptor]
disallow_untyped_defs = False
[mypy-qutebrowser.browser.webkit.webkitelem]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.webengine.spell]
disallow_untyped_defs = False
[mypy-qutebrowser.browser.webengine.webengineelem]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.webengine.tabhistory]
disallow_untyped_defs = False
[mypy-qutebrowser.browser.webengine.darkmode]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.webengine.webenginedownloads]
disallow_untyped_defs = False
[mypy-qutebrowser.keyinput.*]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.webengine.webenginequtescheme]
disallow_untyped_defs = False
[mypy-qutebrowser.utils.*]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.webengine.webenginesettings]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.statusbar.command]
disallow_untyped_defs = True
[mypy-qutebrowser.browser.webengine.webenginetab]
disallow_untyped_defs = False
[mypy-qutebrowser.browser.webengine.webview]
disallow_untyped_defs = False
[mypy-qutebrowser.commands.argparser]
disallow_untyped_defs = False
[mypy-qutebrowser.commands.cmdexc]
disallow_untyped_defs = False
[mypy-qutebrowser.commands.command]
disallow_untyped_defs = False
[mypy-qutebrowser.commands.runners]
disallow_untyped_defs = False
[mypy-qutebrowser.commands.userscripts]
disallow_untyped_defs = False
[mypy-qutebrowser.completion.completer]
disallow_untyped_defs = False
[mypy-qutebrowser.completion.completiondelegate]
disallow_untyped_defs = False
[mypy-qutebrowser.completion.completionwidget]
disallow_untyped_defs = False
[mypy-qutebrowser.completion.models.completionmodel]
disallow_untyped_defs = False
[mypy-qutebrowser.completion.models.configmodel]
disallow_untyped_defs = False
[mypy-qutebrowser.completion.models.histcategory]
disallow_untyped_defs = False
[mypy-qutebrowser.completion.models.listcategory]
disallow_untyped_defs = False
[mypy-qutebrowser.completion.models.miscmodels]
disallow_untyped_defs = False
[mypy-qutebrowser.completion.models.urlmodel]
disallow_untyped_defs = False
[mypy-qutebrowser.completion.models.util]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.mainwindow]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.messageview]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.prompt]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.statusbar.backforward]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.statusbar.bar]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.statusbar.clock]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.statusbar.keystring]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.statusbar.percentage]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.statusbar.progress]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.statusbar.tabindex]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.statusbar.textbase]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.statusbar.url]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.tabbedbrowser]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.tabwidget]
disallow_untyped_defs = False
[mypy-qutebrowser.mainwindow.windowundo]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.autoupdate]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.checkpyver]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.cmdhistory]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.consolewidget]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.crashdialog]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.crashsignal]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.earlyinit]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.editor]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.httpclient]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.ipc]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.keyhintwidget]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.lineparser]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.miscwidgets]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.msgbox]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.pastebin]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.savemanager]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.sessions]
disallow_untyped_defs = False
[mypy-qutebrowser.misc.split]
disallow_untyped_defs = False
[mypy-qutebrowser.qutebrowser]
disallow_untyped_defs = False
[mypy-qutebrowser.browser.qutescheme]
disallow_untyped_defs = True
[mypy-qutebrowser.completion.models.filepathcategory]
disallow_untyped_defs = True

View File

@ -1,28 +1,27 @@
# vim: ft=dosini fileencoding=utf-8:
[MASTER]
ignore=resources.py
extension-pkg-whitelist=PyQt5,PyQt6,sip
extension-pkg-whitelist=PyQt5,sip
load-plugins=qute_pylint.config,
qute_pylint.modeline,
qute_pylint.openencoding,
pylint.extensions.docstyle,
pylint.extensions.emptystring,
pylint.extensions.broad_try_clause,
pylint.extensions.overlapping_exceptions,
pylint.extensions.code_style,
pylint.extensions.comparison_placement,
pylint.extensions.for_any_all,
pylint.extensions.docstyle,
pylint.extensions.check_elif,
pylint.extensions.typing,
pylint.extensions.docparams,
pylint.extensions.private_import,
pylint.extensions.dict_init_mutate,
pylint.extensions.dunder
persistent=n
py-version=3.9
[broad_try_clause]
max-try-statements=7
[MESSAGES CONTROL]
enable=all
disable=locally-disabled,
locally-enabled,
suppressed-message,
fixme,
no-self-use,
cyclic-import,
blacklisted-name,
logging-format-interpolation,
@ -47,19 +46,7 @@ disable=locally-disabled,
too-many-statements,
too-few-public-methods,
import-outside-toplevel,
consider-using-f-string,
consider-using-assignment-expr,
logging-fstring-interpolation,
raise-missing-from,
consider-using-tuple,
consider-using-namedtuple-or-dataclass,
missing-raises-doc,
missing-type-doc,
missing-param-doc,
useless-param-doc,
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,
bad-continuation # This lint disagrees with Black
[BASIC]
function-rgx=[a-z_][a-z0-9_]{2,50}$
@ -71,13 +58,10 @@ argument-rgx=[a-z_][a-z0-9_]{0,30}$
variable-rgx=[a-z_][a-z0-9_]{0,30}$
docstring-min-length=3
no-docstring-rgx=(^_|^main$)
class-const-naming-style=snake_case
max-positional-arguments=7
[FORMAT]
# FIXME:v4 (lint) down to 88 again once we use black
max-line-length=190
ignore-long-lines=(<?https?://|file://|link:)
max-line-length=88
ignore-long-lines=(<?https?://|file://|^# Copyright 201\d|link:)
expected-line-ending-format=LF
[VARIABLES]

View File

@ -4,7 +4,7 @@ recursive-include qutebrowser/javascript *.js
graft tests
graft qutebrowser/html
graft qutebrowser/3rdparty
graft qutebrowser/icons
graft icons
graft doc/img
graft misc/apparmor
graft misc/userscripts
@ -32,7 +32,6 @@ include doc/qutebrowser.1.asciidoc
include doc/changelog.asciidoc
prune qutebrowser/3rdparty
exclude mypy.ini
exclude pyrightconfig.json
exclude tox.ini
exclude qutebrowser/javascript/.eslintrc.yaml
exclude qutebrowser/javascript/.eslintignore

View File

@ -1,24 +1,22 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// If you are reading this in plaintext or on PyPi:
//
// A rendered version is available at:
// https://github.com/qutebrowser/qutebrowser/blob/main/README.asciidoc
// https://github.com/qutebrowser/qutebrowser/blob/master/README.asciidoc
qutebrowser
===========
// QUTE_WEB_HIDE
image:qutebrowser/icons/qutebrowser-64x64.png[qutebrowser logo] *A keyboard-driven, vim-like browser based on Python and Qt.*
image:icons/qutebrowser-64x64.png[qutebrowser logo] *A keyboard-driven, vim-like browser based on PyQt5 and Qt.*
image:https://github.com/qutebrowser/qutebrowser/workflows/CI/badge.svg["Build Status", link="https://github.com/qutebrowser/qutebrowser/actions?query=workflow%3ACI"]
image:https://codecov.io/github/qutebrowser/qutebrowser/coverage.svg?branch=main["coverage badge",link="https://codecov.io/github/qutebrowser/qutebrowser?branch=main"]
image:https://codecov.io/github/qutebrowser/qutebrowser/coverage.svg?branch=master["coverage badge",link="https://codecov.io/github/qutebrowser/qutebrowser?branch=master"]
link:https://www.qutebrowser.org[website] | link:https://blog.qutebrowser.org[blog] | https://github.com/qutebrowser/qutebrowser/blob/main/doc/faq.asciidoc[FAQ] | https://www.qutebrowser.org/doc/contributing.html[contributing] | link:https://github.com/qutebrowser/qutebrowser/releases[releases] | https://github.com/qutebrowser/qutebrowser/blob/main/doc/install.asciidoc[installing]
link:https://www.qutebrowser.org[website] | link:https://blog.qutebrowser.org[blog] | https://github.com/qutebrowser/qutebrowser/blob/master/doc/faq.asciidoc[FAQ] | https://www.qutebrowser.org/doc/contributing.html[contributing] | link:https://github.com/qutebrowser/qutebrowser/releases[releases] | https://github.com/qutebrowser/qutebrowser/blob/master/doc/install.asciidoc[installing]
// QUTE_WEB_HIDE_END
qutebrowser is a keyboard-focused browser with a minimal GUI. It's based
on Python and Qt and free software, licensed under the GPL.
on Python and PyQt5 and free software, licensed under the GPL.
It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl.
@ -26,11 +24,9 @@ It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl.
**qutebrowser's primary maintainer, The-Compiler, is currently working
part-time on qutebrowser, funded by donations.** To sustain this for a long
time, your help is needed! See the
https://github.com/sponsors/The-Compiler/[GitHub Sponsors page] or
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!
https://github.com/sponsors/The-Compiler/[GitHub Sponsors page] 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!
// QUTE_WEB_HIDE_END
Screenshots
@ -44,7 +40,7 @@ image:doc/img/hints.png["screenshot 4",width=300,link="doc/img/hints.png"]
Downloads
---------
See the https://github.com/qutebrowser/qutebrowser/releases[GitHub releases
See the https://github.com/qutebrowser/qutebrowser/releases[github releases
page] for available downloads and the link:doc/install.asciidoc[INSTALL] file for
detailed instructions on how to get qutebrowser running on various platforms.
@ -67,32 +63,27 @@ ways:
* Use the built-in `:report` command or the automatic crash dialog.
* Open an issue in the Github issue tracker.
* Write a mail to the
https://listi.jpberlin.de/mailman/listinfo/qutebrowser[mailinglist] at
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[mailinglist] at
mailto:qutebrowser@lists.qutebrowser.org[].
Please report security bugs to security@qutebrowser.org
(or if GPG encryption is desired, contact me@the-compiler.org with GPG ID
https://www.the-compiler.org/pubkey.asc[0x916EB0C8FD55A072]).
Alternatively,
https://github.com/qutebrowser/qutebrowser/security/advisories/new[report a vulnerability]
via GitHub's
https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability[private reporting feature].
For security bugs, please contact me directly at mail@qutebrowser.org, GPG ID
https://www.the-compiler.org/pubkey.asc[0x916eb0c8fd55a072].
Requirements
------------
The following software and libraries are required to run qutebrowser:
* https://www.python.org/[Python] 3.9 or newer
* https://www.qt.io/[Qt], either 6.2.0 or newer, or 5.15.0 or newer, with the following modules:
* https://www.python.org/[Python] 3.6.1 or newer
* https://www.qt.io/[Qt] 5.12.0 or newer (5.12 LTS or 5.15 recommended)
with the following modules:
- QtCore / qtbase
- QtQuick (part of qtbase or qtdeclarative in some distributions)
- QtSQL (part of qtbase in some distributions)
- QtDBus (part of qtbase in some distributions; note that a connection to DBus at
runtime is optional)
- QtOpenGL
- QtWebEngine (if using Qt 5, 5.15.2 or newer), or
- QtWebEngine, or
- alternatively QtWebKit (5.212) - **This is not recommended** due to known security
issues in QtWebKit, you most likely want to use qutebrowser with the
default QtWebEngine backend (based on Chromium) instead. Quoting the
@ -100,14 +91,15 @@ The following software and libraries are required to run qutebrowser:
_[The latest QtWebKit] release is based on [an] old WebKit revision with known
unpatched vulnerabilities. Please use it carefully and avoid visiting untrusted
websites and using it for transmission of sensitive data._
* https://www.riverbankcomputing.com/software/pyqt/intro[PyQt] 6.2.2 or newer
(Qt 6) or 5.15.0 or newer (Qt 5)
* https://www.riverbankcomputing.com/software/pyqt/intro[PyQt] 5.12.0 or newer
for Python 3
* https://palletsprojects.com/p/jinja/[jinja2]
* https://github.com/yaml/pyyaml[PyYAML]
On macOS, the following libraries are also required:
On older Python versions (3.6/3.7/3.8), the following backports are also required:
* https://pyobjc.readthedocs.io/en/latest/[pyobjc-core and pyobjc-framework-Cocoa]
* https://importlib-resources.readthedocs.io/[importlib_resources] (Python 3.8 or older)
* https://github.com/ericvsmith/dataclasses[dataclasses] (Python 3.6 only)
The following libraries are optional:
@ -117,6 +109,10 @@ The following libraries are optional:
QtWebEngine backend.
* On Windows, https://pypi.python.org/pypi/colorama/[colorama] for colored log
output.
* https://importlib-metadata.readthedocs.io/[importlib_resources] on Python 3.7
or older, to improve QtWebEngine version detection when PyQtWebEngine is
installed via pip (thus, this dependency usually isn't relevant for
packagers).
* https://asciidoc.org/[asciidoc] to generate the documentation for the `:help`
command, when using the git repository (rather than a release).
@ -136,16 +132,13 @@ level, you can get qutebrowser t-shirts, stickers and more!
GitHub Sponsors allows for one-time donations (using the buttons next to "Select a
tier") as well as custom amounts. **For currencies other than Euro or Swiss Francs, this
is the preferred donation method.** GitHub uses https://stripe.com/[Stripe] to accept
payment via credit cards without any fees. Billing via PayPal is available as well, with
payment via credit carts without any fees. Billing via PayPal is available as well, with
less fees than a direct PayPal transaction.
Alternatively, the following donation methods are available -- note that
eligibility for swag (shirts/stickers/etc.) is handled on a case-by-case basis
for those, please mailto:mail@qutebrowser.org[get in touch] for details.
* https://liberapay.com/The-Compiler[Liberapay], which can handle payments
via Credit Card, SEPA bank transfers, or Paypal. Payment fees are paid by me,
but they are https://liberapay.com/about/faq#fees[relatively low].
* SEPA bank transfer inside Europe (**no fees**):
- Account holder: Florian Bruhin
- Country: Switzerland
@ -153,16 +146,13 @@ for those, please mailto:mail@qutebrowser.org[get in touch] for details.
- IBAN (other): CH80 0900 0000 8711 8587 3
- Bank: PostFinance AG, Mingerstrasse 20, 3030 Bern, Switzerland (BIC: POFICHBEXXX)
- If you need any other information: Contact me at mail@qutebrowser.org.
- If possible, **please consider yearly or semi-yearly donations**, because
of the additional overhead from many individual transactions for
bookkeeping/tax purposes.
* PayPal:
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=me%40the-compiler.org&item_name=qutebrowser&currency_code=CHF&source=url[CHF],
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=me%40the-compiler.org&item_name=qutebrowser&currency_code=EUR&source=url[EUR],
https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=me%40the-compiler.org&item_name=qutebrowser&currency_code=USD&source=url[USD].
**Note: Fees can be very high (around 5-40%, depending on the donated amounts)** - consider
using GitHub Sponsors (credit card), Liberapay (credit cards, PayPal, or bank
transfer) or SEPA bank transfers instead.
using GitHub Sponsors (accepts credit cards or PayPal!) or SEPA bank transfers
instead.
* Cryptocurrencies:
- Bitcoin: link:bitcoin:bc1q3ptyw8hxrcfz6ucfgmglphfvhqpy8xr6k25p00[bc1q3ptyw8hxrcfz6ucfgmglphfvhqpy8xr6k25p00]
- Bitcoin Cash: link:bitcoincash:1BnxUbnJ5MrEPeh5nuUMx83tbiRAvqJV3N[1BnxUbnJ5MrEPeh5nuUMx83tbiRAvqJV3N]
@ -212,20 +202,23 @@ Active
~~~~~~
* https://fanglingsu.github.io/vimb/[vimb] (C, GTK+ with WebKit2)
* https://luakit.github.io/[luakit] (C/Lua, GTK+ with WebKit2)
* https://nyxt.atlas.engineer/[Nyxt browser] (formerly "Next browser", Lisp, Emacs-like but also offers Vim bindings, QtWebEngine or GTK+/WebKit2 - note there was a https://jgkamat.gitlab.io/blog/next-rce.html[critical remote code execution in 2019] which was handled quite badly)
* https://luakit.github.io/luakit/[luakit] (C/Lua, GTK+ with WebKit2)
* https://nyxt.atlas.engineer/[Nyxt browser] (formerly "Next browser", Lisp, Emacs-like but also offers Vim bindings, QtWebKit or GTK+/WebKit2 - note there was a https://jgkamat.gitlab.io/blog/next-rce.html[critical remote code execution] which was handled quite badly)
* https://vieb.dev/[Vieb] (JavaScript, Electron)
* https://surf.suckless.org/[surf] (C, GTK+ with WebKit1/WebKit2)
* https://github.com/jun7/wyeb[wyeb] (C, GTK+ with WebKit2)
* Chrome/Chromium addons:
https://vimium.github.io/[Vimium]
https://vimium.github.io/[Vimium],
https://github.com/dcchambers/vb4c[vb4c] (fork of cVim)
* Firefox addons (based on WebExtensions):
https://tridactyl.xyz/[Tridactyl],
https://addons.mozilla.org/en-GB/firefox/addon/vimium-ff/[Vimium-FF]
https://github.com/tridactyl/tridactyl[Tridactyl],
https://addons.mozilla.org/en-GB/firefox/addon/vimium-ff/[Vimium-FF] (experimental),
https://github.com/ueokande/vim-vixen[Vim Vixen],
https://github.com/amedama41/vvimpulation[VVimpulation]
* Addons for Firefox and Chrome:
https://github.com/brookhong/Surfingkeys[Surfingkeys] (https://github.com/brookhong/Surfingkeys/issues/1796[somewhat sketchy]...),
https://lydell.github.io/LinkHints/[Link Hints] (hinting only),
https://github.com/ueokande/vimmatic[Vimmatic]
https://github.com/brookhong/Surfingkeys[Surfingkeys],
https://krabby.netlify.com/[Krabby],
https://lydell.github.io/LinkHints/[Link Hints] (hinting only)
* Addons for Safari:
https://televator.net/vimari/[Vimari]
Inactive
~~~~~~~~
@ -237,29 +230,25 @@ main inspiration for qutebrowser)
QtWebEngine, https://github.com/parkouss/webmacs/issues/137[unmaintained])
* https://sourceforge.net/p/vimprobable/wiki/Home/[vimprobable] (C, GTK+ with
WebKit1)
* https://pwmt.org/projects/jumanji/[jumanji] (C, GTK+ with WebKit1)
* https://wiki.archlinux.org/index.php?title=Jumanji[jumanji] (C, GTK+ with WebKit1,
original site is gone but the Arch Linux wiki has some data)
* http://conkeror.org/[conkeror] (Javascript, Emacs-like, XULRunner/Gecko)
* https://www.uzbl.org/[uzbl] (C, GTK+ with WebKit1/WebKit2)
* https://github.com/conformal/xombrero[xombrero] (C, GTK+ with WebKit1)
* https://github.com/linkdd/cream-browser[Cream Browser] (C, GTK+ with WebKit1)
* https://surf.suckless.org/[surf] (C, GTK+ with WebKit1/WebKit2)
* Firefox addons (not based on WebExtensions or no recent activity):
http://www.vimperator.org/[Vimperator],
http://bug.5digits.org/pentadactyl/index[Pentadactyl],
https://github.com/akhodakivskiy/VimFx[VimFx] (seems to offer a
https://gir.st/blog/legacyfox.htm[hack] to run on modern Firefox releases),
https://github.com/shinglyu/QuantumVim[QuantumVim],
https://github.com/ueokande/vim-vixen[Vim Vixen],
https://github.com/amedama41/vvimpulation[VVimpulation],
https://krabby.netlify.app/[Krabby]
https://github.com/shinglyu/QuantumVim[QuantumVim]
* Chrome/Chromium addons:
https://github.com/k2nr/ViChrome/[ViChrome],
https://github.com/jinzhu/vrome[Vrome],
https://github.com/lusakasa/saka-key[Saka Key] (https://github.com/lusakasa/saka-key/issues/171[unmaintained]),
https://github.com/1995eaton/chromium-vim[cVim],
https://github.com/dcchambers/vb4c[vb4c] (fork of cVim, https://github.com/dcchambers/vb4c/issues/23#issuecomment-810694017[unmaintained]),
https://glee.github.io/[GleeBox]
* Addons for Safari:
https://televator.net/vimari/[Vimari]
License
-------

View File

@ -1,14 +1,6 @@
Crowdfunding backers
====================
2019+
-----
Since late 2019, qutebrowser is taking recurring donations via
https://github.com/sponsors/The-Compiler/[GitHub Sponsors] and
https://liberapay.com/The-Compiler/[Liberapay]. You can find Sponsors/Patrons
who opted to be listed as public on the respective pages. **Thank you!**
2017
----

File diff suppressed because it is too large Load Diff

View File

@ -24,11 +24,11 @@ several ways:
* Send a mail to the mailing list at mailto:qutebrowser@lists.qutebrowser.org[]
(optionally
https://listi.jpberlin.de/mailman/listinfo/qutebrowser[subscribe]
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[subscribe]
first).
* Join the IRC channel link:ircs://irc.libera.chat:6697/#qutebrowser[`#qutebrowser`] on
https://libera.chat/[Libera Chat] (https://web.libera.chat/#qutebrowser[webchat],
https://matrix.to/#qutebrowser:libera.chat[via Matrix]).
* Join the IRC channel irc://irc.freenode.org/#qutebrowser[`#qutebrowser`] on
https://freenode.net/[Freenode]
(https://webchat.freenode.net/?channels=#qutebrowser[webchat]).
Finding something to work on
----------------------------
@ -41,7 +41,7 @@ If you want to find something useful to do, check the
https://github.com/qutebrowser/qutebrowser/issues[issue tracker]. Some
pointers:
* https://github.com/qutebrowser/qutebrowser/contribute[Issues which should
* https://github.com/qutebrowser/qutebrowser/labels/easy[Issues which should
be easy to solve]
* https://github.com/qutebrowser/qutebrowser/labels/component%3A%20docs[Documentation issues which require little/no coding]
@ -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/main <1>
git format-patch origin/master <1>
----
<1> Replace `main` by the branch your work was based on, e.g.,
<1> Replace `master` by the branch your work was based on, e.g.,
`origin/develop`.
Running qutebrowser
@ -111,9 +111,9 @@ unittests and several linters/checkers.
Currently, the following tox environments are available:
* Tests using https://www.pytest.org[pytest]:
- `py39`, `py310`, ...: Run pytest for python 3.9/3.10/... with the system-wide PyQt.
- `py39-pyqt515`, ..., `py39-pyqt65`: Run pytest with the given PyQt version (`py310-*` etc. also works).
- `py39-pyqt515-cov`: Run with coverage support (other Python/PyQt versions work too).
- `py36`, `py37`, ...: Run pytest for python 3.6/3.7/... with the system-wide PyQt.
- `py36-pyqt512`, ..., `py36-pyqt515`: Run pytest with the given PyQt version (`py35-*` also works).
- `py36-pyqt515-cov`: Run with coverage support (other Python/PyQt versions work too).
* `flake8`: Run various linting checks via https://pypi.python.org/pypi/flake8[flake8].
* `vulture`: Run https://pypi.python.org/pypi/vulture[vulture] to find
unused code portions.
@ -121,14 +121,13 @@ Currently, the following tox environments are available:
* `pyroma`: Check packaging practices with
https://pypi.python.org/pypi/pyroma/[pyroma].
* `eslint`: Run https://eslint.org/[ESLint] javascript checker.
* `check-manifest`: Check MANIFEST.in completeness with
https://github.com/mgedmin/check-manifest[check-manifest].
* `mkvenv`: Bootstrap a virtualenv for testing.
* `misc`: Run `scripts/misc_checks.py` to check for:
- untracked git files
- VCS conflict markers
- common spelling mistakes
* http://mypy-lang.org/[mypy] for static type checking:
- `mypy-pyqt5` run mypy with PyQt5 installed
- `mypy-pyqt6` run mypy with PyQt6 installed
The default test suite is run with `tox`; the list of default
environments is obtained with `tox -l`.
@ -154,7 +153,7 @@ smallest scope which makes sense. Most of the time, this will be line scope.
false-positives, let me know! I'm still tweaking the parameters.
Running specific tests
Running Specific Tests
~~~~~~~~~~~~~~~~~~~~~~
While you are developing you often don't want to run the full test
@ -169,47 +168,16 @@ Examples:
----
# run only pytest tests which failed in last run:
tox -e py39 -- --lf
tox -e py35 -- --lf
# run only the end2end feature tests:
tox -e py39 -- tests/end2end/features
tox -e py35 -- tests/end2end/features
# run everything with undo in the generated name, based on the scenario text
tox -e py39 -- tests/end2end/features/test_tabs_bdd.py -k undo
tox -e py35 -- tests/end2end/features/test_tabs_bdd.py -k undo
# run coverage test for specific file (updates htmlcov/index.html)
tox -e py39-cov -- tests/unit/browser/test_webelem.py
----
Specifying the backend for tests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tests automatically pick the backend based on what they manage to import. If
you have both backends available and you would like the tests to be run with a
specific one you can set either of a) the environment variable QUTE_TESTS_BACKEND
, or b) the command line argument --qute-backend, to the desired backend
(webkit/webengine).
If you need an environment with webkit installed to do testing while we still
support it (see #4039) you can re-use the docker container used for the CI
test runs which has PyQt5Webkit installed from the archlinux package archives.
Examples:
----
# Get a bash shell in the docker container with
# a) the current directory mounted at /work in the container
# b) the container using the X11 display :27 (for example, a Xephyr instance) from the host
# c) the tox and hypothesis dirs set to somewhere in the container that it can write to
# d) the system site packages available in the tox venv so you can use PyQt
# from the OS without having to run the link_pyqt script
docker run -it -v $PWD:/work:ro -w /work -e QUTE_TESTS_BACKEND=webkit -e DISPLAY=:27 -v /tmp/.X11-unix:/tmp/.X11-unix -e TOX_WORK_DIR="/home/user/.tox" -e HYPOTHESIS_EXAMPLES_DIR="/home/user/.hypothesis/examples" -e VIRTUALENV_SYSTEM_SITE_PACKAGES=True qutebrowser/ci:archlinux-webkit bash
# Start a qutebrowser temporary basedir in the appropriate tox environment to
# play with
tox exec -e py-qt5 -- python3 -m qutebrowser -T --backend webkit
# Run tests, passing positional args through to pytest.
tox -e py-qt5 -- tests/unit
tox -e py35-cov -- tests/unit/browser/test_webelem.py
----
Profiling
@ -251,8 +219,7 @@ Useful websites
Some resources which might be handy:
* https://doc.qt.io/qt-6/classes.html[The Qt 6 reference]
* https://doc.qt.io/qt-5/classes.html[The Qt 5 reference]
* https://doc.qt.io/qt-5/classes.html[The Qt5 reference]
* https://docs.python.org/3/library/index.html[The Python reference]
* https://httpbin.org/[httpbin, a test service for HTTP requests/responses]
* https://requestbin.com/[RequestBin, a service to inspect HTTP requests]
@ -307,7 +274,7 @@ Other
Languages] (https://www.rfc-editor.org/errata_search.php?rfc=5646[Errata])
* https://www.w3.org/TR/CSS2/[Cascading Style Sheets Level 2 Revision 1 (CSS
2.1) Specification]
* https://doc.qt.io/qt-6/stylesheet-reference.html[Qt Style Sheets Reference]
* https://doc.qt.io/qt-5/stylesheet-reference.html[Qt Style Sheets Reference]
* https://mimesniff.spec.whatwg.org/[MIME Sniffing Standard]
* https://spec.whatwg.org/[WHATWG specifications]
* https://www.w3.org/html/wg/drafts/html/master/Overview.html[HTML 5.1 Nightly]
@ -386,7 +353,7 @@ All objects can be printed by starting with the `--debug` flag and using the
The registry is mainly used for <<commands,command handlers>>, but it can
also be useful in places where using Qt's
https://doc.qt.io/qt-6/signalsandslots.html[signals and slots] mechanism would
https://doc.qt.io/qt-5/signalsandslots.html[signals and slots] mechanism would
be difficult.
Logging
@ -577,8 +544,11 @@ ____
Setting up a Windows Development Environment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Install https://www.python.org/downloads/release/python-3911/[Python 3.9].
* Install https://www.python.org/downloads/release/python-362/[Python 3.6].
* Install PyQt via `pip install PyQt5`.
* Create a file at `C:\Windows\system32\python3.bat` with the following content (adjust the path as necessary):
`@C:\Python36\python %*`.
This will make the Python 3.6 interpreter available as `python3`, which is used by various development scripts.
* Install git from the https://git-scm.com/download/win[git-scm downloads page].
Try not to enable `core.autocrlf`, since that will cause `flake8` to complain a lot. Use an editor that can deal with plain line feeds instead.
* Clone your favourite qutebrowser repository.
@ -595,48 +565,27 @@ Chrome URLs
~~~~~~~~~~~
With the QtWebEngine backend, qutebrowser supports several chrome:// urls which
can be useful for debugging.
can be useful for debugging:
Info pages:
- chrome://device-log/ (QtWebEngine >= 6.3)
- chrome://gpu/
- chrome://sandbox/ (Linux only)
- chrome://qt/ (QtWebEngine >= 6.7)
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)
- chrome://extensions/ (QtWebEngine >= 6.10)
Internals pages:
- chrome://accessibility/
- chrome://appcache-internals/ (QtWebEngine < 6.4)
- chrome://attribution-internals/ (QtWebEngine >= 6.4)
- chrome://appcache-internals/
- chrome://blob-internals/
- chrome://conversion-internals/ (QtWebEngine >= 5.15.3 and < 6.4)
- chrome://gpu/
- chrome://histograms/
- chrome://indexeddb-internals/
- chrome://media-internals/
- chrome://net-internals/ (QtWebEngine >= 5.15.4)
- chrome://process-internals/
- chrome://quota-internals/
- chrome://network-errors/
- chrome://serviceworker-internals/
- chrome://webrtc-internals/
Crash/hang pages:
- chrome://crash/ (crashes the current renderer process!)
- chrome://gpuclean/ (crashes the current renderer process!)
- chrome://kill/ (kills the current renderer process!)
- chrome://gpucrash/ (crashes qutebrowser!)
- chrome://gpuhang/ (hangs qutebrowser!)
- chrome://kill/ (kills the current renderer process!)
- chrome://gpuclean/ (crashes the current renderer process!)
- chrome://ppapiflashcrash/
- chrome://ppapiflashhang/
- chrome://quota-internals/
- chrome://taskscheduler-internals/
- chrome://sandbox/ (Linux only)
QtWebEngine internals
~~~~~~~~~~~~~~~~~~~~~
@ -646,14 +595,11 @@ This is mostly useful for qutebrowser maintainers to work around issues in Qt -
The hierarchy of widgets when QtWebEngine is involved looks like this:
- qutebrowser has a `WebEngineTab` object, which is its abstraction over QtWebKit/QtWebEngine.
- The `WebEngineTab` has a `_widget` attribute, which is the https://doc.qt.io/qt-6/qwebengineview.html[QWebEngineView]
- That view has a https://doc.qt.io/qt-6/qwebenginepage.html[QWebEnginePage] for everything which doesn't require rendering.
- The view also has a layout with exactly one element (which also is its `focusProxy()`).
- Qt 5: That element is the https://code.qt.io/cgit/qt/qtwebengine.git/tree/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp?h=5.15[RenderWidgetHostViewQtDelegateWidget] (it inherits https://doc.qt.io/qt-6/qquickwidget.html[QQuickWidget]) - also often referred to as RWHV or RWHVQDW.
It can be obtained via `sip.cast(tab._widget.focusProxy(), QQuickWidget)`.
- Qt 6: That element is the https://code.qt.io/cgit/qt/qtwebengine.git/tree/src/webenginewidgets/api/qwebengineview.cpp[WebEngineQuickWidget] (it inherits https://doc.qt.io/qt-6/qquickwidget.html[QQuickWidget]).
It can be obtained via `tab._widget.focusProxy()`.
- Calling `rootObject()` on that gives us the https://doc.qt.io/qt-6/qquickitem.html[QQuickItem] where Chromium renders into (?). With it, we can do things like `.setRotation(20)`.
- The `WebEngineTab` has a `_widget` attribute, which is the https://doc.qt.io/qt-5/qwebengineview.html[QWebEngineView]
- That view has a https://doc.qt.io/qt-5/qwebenginepage.html[QWebEnginePage] for everything which doesn't require rendering.
- The view also has a layout with exactly one element (which also is its `focusProxy()`)
- That element is the https://code.qt.io/cgit/qt/qtwebengine.git/tree/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp[RenderWidgetHostViewQtDelegateWidget] (it inherits https://doc.qt.io/qt-5/qquickwidget.html[QQuickWidget]) - also often referred to as RWHV or RWHVQDW. It can be obtained via `sip.cast(tab._widget.focusProxy(), QQuickWidget)`.
- Calling `rootObject()` on that gives us the https://doc.qt.io/qt-5/qquickitem.html[QQuickItem] where Chromium renders into (?). With it, we can do things like `.setRotation(20)`.
Style conventions
-----------------
@ -711,6 +657,7 @@ Return:
+
* The layout of a module should be roughly like this:
- Shebang (`#!/usr/bin/python`, if needed)
- vim-modeline (`# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et`)
- Copyright
- GPL boilerplate
- Module docstring
@ -724,41 +671,6 @@ Return:
- `__magic__` methods
- other methods
- overrides of Qt methods
* Type hinting: the qutebrowser codebase uses type hints liberally to enable
static type checking and autocompletion in editors.
- We use http://mypy-lang.org/[mypy] in CI jobs to perform static type
checking.
- Not all of the codebase is covered by type hints currently. We encourage
including type hints on all new code and even adding type hints to
existing code if you find yourself working on some that isn't already
covered. There are some module specific rules in the mypy config file,
`.mypy.ini`, to make type hints strictly required in some areas.
- More often than not mypy is correct when it raises issues. But don't be
afraid to add `# type: ignore[...]` statements or casts if you need to.
As an optional part of the language not all type information from third
parties is always correct. Mypy will raise a new issue if it spots an
"ignore" statement which is no longer needed because the underlying
issue has been resolved.
- One area where we have to take particular care is in code that deals
with differences between PyQt5 and PyQt6. We try to write most code in a
way that will work with either backend but when you need to deal with
differences you should use a pattern like:
+
[source,python]
----
if machinery.IS_QT5:
... # do PyQt5 specific implementation
else:
# PyQt6
... # do PyQt6 specific implementation
----
+
then you have to https://mypy.readthedocs.io/en/latest/command_line.html#cmdoption-mypy-always-true[tell]
mypy to treat `machinery.IS_QT5` as a constant value then run mypy twice to
cover both branches. There are a handful of variables in
`qutebrowser/qt/machinery.py` that mypy needs to know about. There are tox
jobs (`mypy-pyqt5` and `mypy-pyqt6`) that take care of telling mypy to use
them as constants.
Checklists
----------
@ -789,35 +701,20 @@ New PyQt release
qutebrowser release
~~~~~~~~~~~~~~~~~~~
* Make sure there are no unstaged or unpushed changes.
* Make sure CI is reasonably green.
* 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`
and the Firefox UA in `qutebrowser/browser/webengine/webenginesettings.py`.
* Minor release: Consider updating some files from main:
* Consider updating the completions for `content.headers.user_agent` in `configdata.yml`.
* Minor release: Consider updating some files from master:
- `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=minor` (`release_type` can be `major`, `minor` or `patch`; you can also override `python_version`)
* Consider running `gh run watch` or `gh run view --web` to watch the progress
**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

View File

@ -61,7 +61,7 @@ Why Python?::
point, I wasn't comfortable with C++ so that wasn't an alternative.
But isn't Python too slow for a browser?::
https://www.infoworld.com/article/2303031/van-rossum-python-is-not-too-slow-2.html[It's generally less of a problem than one would expect.]
https://www.infoworld.com/d/application-development/van-rossum-python-not-too-slow-188715[It's generally less of a problem than one would expect.]
Most of the heavy lifting of qutebrowser is done by Qt and
QtWebKit/QtWebEngine in C++, with the
https://wiki.python.org/moin/GlobalInterpreterLock[GIL] released.
@ -141,7 +141,7 @@ The comma prefix is used to make sure user-defined bindings don't conflict with
the built-in ones.
+
Note that you might need an additional package (e.g.
https://archlinux.org/packages/extra/any/yt-dlp/[yt-dlp] on
https://www.archlinux.org/packages/community/any/youtube-dl/[youtube-dl] on
Archlinux) to play web videos with mpv.
+
There is a very useful script for mpv, which emulates "unique application"
@ -158,7 +158,7 @@ It also works nicely with rapid hints:
:bind ;M hint --rapid links spawn umpv {hint-url}
----
How do I use qutebrowser with mutt/neomutt or other mail clients?::
How do I use qutebrowser with mutt?::
For security reasons, local files without `.html` extensions aren't
rendered as HTML, see
https://bugs.chromium.org/p/chromium/issues/detail?id=777737[this Chromium issue]
@ -166,29 +166,8 @@ How do I use qutebrowser with mutt/neomutt or other mail clients?::
extension:
+
----
text/html; qutebrowser %s; needsterminal; nametemplate=%s.html
text/html; qutebrowser %s; needsterminal; nametemplate=%s.html
----
+
Note that you might want to add additional options to qutebrowser, so that it
runs as a separate instance configured to disable JavaScript and avoid network
requests, in order to avoid privacy leaks when reading mails. The easiest way
to do so is by specifying a non-existent proxy server, e.g.:
+
----
qutebrowser --temp-basedir -s content.proxy http://localhost:666 -s content.dns_prefetch false -s content.javascript.enabled false %s
----
+
With Qt 6, using something like:
+
----
qutebrowser --temp-basedir -s content.dns_prefetch false -s content.javascript.enabled false %s
----
+
should lead to a similar result, due to a more restrictive implementation of
the `content.local_content_can_access_remote_urls` setting (`false` by default
already). However, it's advised to use a page like
https://www.emailprivacytester.com/[Email Privacy Tester] to verify your
configuration.
What is the difference between bookmarks and quickmarks?::
Bookmarks will always use the title of the website as their name, but with quickmarks
@ -255,7 +234,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/main/scripts/open_url_in_instance.sh[script]
https://github.com/qutebrowser/qutebrowser/blob/master/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
@ -375,9 +354,9 @@ There is a total of four possible approaches to get dark websites:
of the Dark Reader extension. This is mostly untested, though.
How do I make copy to clipboard buttons work?::
You can `:set content.javascript.clipboard access` to allow this globally (not
recommended!), or `:set -u some.domain content.javascript.clipboard access` if
you want to limit the setting to `some.domain`.
You can `:set content.javascript.can_access_clipboard true`, or
`:set -u some.domain content.javascript.can_access_clipboard true` if you want to limit
the setting to `some.domain`.
== Troubleshooting
@ -430,7 +409,7 @@ allowing him to work part-time on qutebrowser. If you keep your donation level
for long enough, you can get some qutebrowser stickers!
Why GitHub Sponsors?::
GitHub Sponsors is a crowdfunding platform nicely integrated with
GitHub Sponsors is a crowdfundign platform nicely integrated with
qutebrowser's existing GitHub page and a better offering than alternatives such
as Patreon or Liberapay.
+

View File

@ -15,10 +15,8 @@ For command arguments, there are also some variables you can use:
- `{url}` expands to the URL of the current page
- `{url:pretty}` expands to the URL in decoded format
- `{url:host}`, `{url:domain}`, `{url:auth}`, `{url:scheme}`, `{url:username}`,
`{url:password}`, `{url:port}`, `{url:path}` and `{url:query}`
`{url:password}`, `{url:host}`, `{url:port}`, `{url:path}` and `{url:query}`
expand to the respective parts of the current URL
- `{url:yank}` expands to the URL of the current page but strips all the query
parameters in the `url.yank_ignored_parameters` setting.
- `{title}` expands to the current page's title
- `{clipboard}` expands to the clipboard contents
- `{primary}` expands to the primary selection contents
@ -42,12 +40,6 @@ possible to run or bind multiple commands by separating them with `;;`.
|<<clear-messages,clear-messages>>|Clear all message notifications.
|<<click-element,click-element>>|Click the element matching the given filter.
|<<close,close>>|Close the current window.
|<<cmd-edit,cmd-edit>>|Open an editor to modify the current command.
|<<cmd-later,cmd-later>>|Execute a command after some time.
|<<cmd-repeat,cmd-repeat>>|Repeat a given command.
|<<cmd-repeat-last,cmd-repeat-last>>|Repeat the last executed command.
|<<cmd-run-with-count,cmd-run-with-count>>|Run a command with the given count.
|<<cmd-set-text,cmd-set-text>>|Preset the statusbar to some text.
|<<config-clear,config-clear>>|Set all settings back to their default.
|<<config-cycle,config-cycle>>|Cycle an option between multiple values.
|<<config-dict-add,config-dict-add>>|Add a key/value pair to a dictionary option.
@ -68,6 +60,7 @@ possible to run or bind multiple commands by separating them with `;;`.
|<<download-open,download-open>>|Open the last/[count]th download.
|<<download-remove,download-remove>>|Remove the last/[count]th download from the list.
|<<download-retry,download-retry>>|Retry the first failed/[count]th download.
|<<edit-command,edit-command>>|Open an editor to modify the current command.
|<<edit-text,edit-text>>|Open an external editor with the currently selected form field.
|<<edit-url,edit-url>>|Navigate to a url formed in an external editor.
|<<fake-key,fake-key>>|Send a fake keypress or key string to the website or qutebrowser.
@ -82,6 +75,7 @@ possible to run or bind multiple commands by separating them with `;;`.
|<<insert-text,insert-text>>|Insert text at cursor position.
|<<jseval,jseval>>|Evaluate a JavaScript string.
|<<jump-mark,jump-mark>>|Jump to the mark named by `key`.
|<<later,later>>|Execute a command after some time.
|<<macro-record,macro-record>>|Start or stop recording a macro.
|<<macro-run,macro-run>>|Run a recorded macro.
|<<message-error,message-error>>|Show an error message in the statusbar.
@ -100,8 +94,11 @@ possible to run or bind multiple commands by separating them with `;;`.
|<<quickmark-save,quickmark-save>>|Save the current page as a quickmark.
|<<quit,quit>>|Quit qutebrowser.
|<<reload,reload>>|Reload the current/[count]th tab.
|<<repeat,repeat>>|Repeat a given command.
|<<repeat-command,repeat-command>>|Repeat the last executed command.
|<<report,report>>|Report a bug in qutebrowser.
|<<restart,restart>>|Restart qutebrowser while keeping existing tabs open.
|<<run-with-count,run-with-count>>|Run a command with the given count.
|<<save,save>>|Save configs and state.
|<<screenshot,screenshot>>|Take a screenshot of the currently shown part of the page.
|<<scroll,scroll>>|Scroll the current tab in the given direction.
@ -117,6 +114,7 @@ possible to run or bind multiple commands by separating them with `;;`.
|<<session-load,session-load>>|Load a session.
|<<session-save,session-save>>|Save a session.
|<<set,set>>|Set an option.
|<<set-cmd-text,set-cmd-text>>|Preset the statusbar to some text.
|<<set-mark,set-mark>>|Set a mark at the current scroll position in the current tab.
|<<spawn,spawn>>|Spawn an external command.
|<<stop,stop>>|Stop loading in the current/[count]th tab.
@ -148,7 +146,7 @@ Update block lists for both the host- and the Brave ad blocker.
[[back]]
=== back
Syntax: +:back [*--tab*] [*--bg*] [*--window*] [*--quiet*] ['index']+
Syntax: +:back [*--tab*] [*--bg*] [*--window*] ['index']+
Go back in the history of the current tab.
@ -159,7 +157,6 @@ Go back in the history of the current tab.
* +*-t*+, +*--tab*+: Go back in a new tab.
* +*-b*+, +*--bg*+: Go back in a background tab.
* +*-w*+, +*--window*+: Go back in a new window.
* +*-q*+, +*--quiet*+: Don't show an error if already at the beginning of history.
==== count
How many pages to go back.
@ -206,7 +203,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 [*--all*] ['url']+
Syntax: +:bookmark-del ['url']+
Delete a bookmark.
@ -214,9 +211,6 @@ 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.
@ -260,122 +254,25 @@ Clear all message notifications.
[[click-element]]
=== click-element
Syntax: +:click-element [*--target* 'target'] [*--force-event*] [*--select-first*] 'filter' ['value']+
Syntax: +:click-element [*--target* 'target'] [*--force-event*] 'filter' 'value'+
Click the element matching the given filter.
The given filter needs to result in exactly one element, otherwise, an error is shown.
==== positional arguments
* +'filter'+: How to filter the elements.
* +'filter'+: How to filter the elements. id: Get an element based on its ID.
- id: Get an element based on its ID.
- css: Filter by a CSS selector.
- position: Click the element at specified position.
Specify `value` as 'x,y'.
- focused: Click the currently focused element.
* +'value'+: The value to filter for. Optional for 'focused' filter.
* +'value'+: The value to filter for.
==== optional arguments
* +*-t*+, +*--target*+: How to open the clicked element (normal/tab/tab-bg/window).
* +*-f*+, +*--force-event*+: Force generating a fake click event.
* +*-s*+, +*--select-first*+: Select first matching element if there are multiple.
[[close]]
=== 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*]+
@ -397,7 +294,7 @@ Cycle an option between multiple values.
* +'values'+: The values to cycle through.
==== optional arguments
* +*-u*+, +*--pattern*+: The link:configuring{outfilesuffix}#patterns[URL pattern] to use.
* +*-u*+, +*--pattern*+: The URL pattern to use.
* +*-t*+, +*--temp*+: Set value temporarily until qutebrowser is closed.
* +*-p*+, +*--print*+: Print the value after setting.
@ -432,13 +329,8 @@ Remove a key from a dict.
[[config-diff]]
=== config-diff
Syntax: +:config-diff [*--include-hidden*]+
Show all customized options.
==== optional arguments
* +*-i*+, +*--include-hidden*+: Also include internal qutebrowser settings.
[[config-edit]]
=== config-edit
Syntax: +:config-edit [*--no-source*]+
@ -499,7 +391,7 @@ This sets an option back to its default and removes it from autoconfig.yml.
* +'option'+: The name of the option.
==== optional arguments
* +*-u*+, +*--pattern*+: The link:configuring{outfilesuffix}#patterns[URL pattern] to use.
* +*-u*+, +*--pattern*+: The URL pattern to use.
* +*-t*+, +*--temp*+: Set value temporarily until qutebrowser is closed.
[[config-write-py]]
@ -607,6 +499,15 @@ 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.
@ -648,7 +549,7 @@ Send a fake keypress or key string to the website or qutebrowser.
[[forward]]
=== forward
Syntax: +:forward [*--tab*] [*--bg*] [*--window*] [*--quiet*] ['index']+
Syntax: +:forward [*--tab*] [*--bg*] [*--window*] ['index']+
Go forward in the history of the current tab.
@ -659,7 +560,6 @@ Go forward in the history of the current tab.
* +*-t*+, +*--tab*+: Go forward in a new tab.
* +*-b*+, +*--bg*+: Go forward in a background tab.
* +*-w*+, +*--window*+: Go forward in a new window.
* +*-q*+, +*--quiet*+: Don't show an error if already at the end of history.
==== count
How many pages to go forward.
@ -677,7 +577,7 @@ Toggle fullscreen mode.
[[greasemonkey-reload]]
=== greasemonkey-reload
Syntax: +:greasemonkey-reload [*--force*] [*--quiet*]+
Syntax: +:greasemonkey-reload [*--force*]+
Re-read Greasemonkey scripts from disk.
@ -686,7 +586,6 @@ The scripts are read from a 'greasemonkey' subdirectory in qutebrowser's data or
==== optional arguments
* +*-f*+, +*--force*+: For any scripts that have required dependencies, re-download them.
* +*-q*+, +*--quiet*+: Suppress message after loading scripts.
[[help]]
=== help
@ -779,8 +678,9 @@ Start hinting.
* +*-a*+, +*--add-history*+: Whether to add the spawned or yanked link to the browsing history.
* +*-r*+, +*--rapid*+: Whether to do rapid hinting. With rapid hinting, the hint mode isn't left after a hint is followed, so you can easily
open multiple links. Note this won't work with targets
`tab-fg`, `fill`, `delete` and `right-click`.
open multiple links. This is only possible with targets
`tab` (with `tabs.background=true`), `tab-bg`,
`window`, `run`, `hover`, `userscript` and `spawn`.
* +*-f*+, +*--first*+: Click the first hinted element without prompting.
@ -866,6 +766,21 @@ 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']+
@ -889,46 +804,34 @@ How many times to run the macro.
[[message-error]]
=== message-error
Syntax: +:message-error [*--rich*] 'text'+
Syntax: +:message-error 'text'+
Show an error message in the statusbar.
==== positional arguments
* +'text'+: The text to show.
==== optional arguments
* +*-r*+, +*--rich*+: Render the given text as https://doc.qt.io/qt-6/richtext-html-subset.html[Qt Rich Text].
[[message-info]]
=== message-info
Syntax: +:message-info [*--rich*] 'text'+
Syntax: +:message-info 'text'+
Show an info message in the statusbar.
==== positional arguments
* +'text'+: The text to show.
==== optional arguments
* +*-r*+, +*--rich*+: Render the given text as https://doc.qt.io/qt-6/richtext-html-subset.html[Qt Rich Text].
==== count
How many times to show the message.
How many times to show the message
[[message-warning]]
=== message-warning
Syntax: +:message-warning [*--rich*] 'text'+
Syntax: +:message-warning 'text'+
Show a warning message in the statusbar.
==== positional arguments
* +'text'+: The text to show.
==== optional arguments
* +*-r*+, +*--rich*+: Render the given text as https://doc.qt.io/qt-6/richtext-html-subset.html[Qt Rich Text].
[[messages]]
=== messages
Syntax: +:messages [*--plain*] [*--tab*] [*--bg*] [*--window*] [*--logfilter* 'logfilter'] ['level']+
@ -1069,7 +972,7 @@ You can view all saved quickmarks on the link:qute://bookmarks[bookmarks page].
[[quickmark-del]]
=== quickmark-del
Syntax: +:quickmark-del [*--all*] ['name']+
Syntax: +:quickmark-del ['name']+
Delete a quickmark.
@ -1078,9 +981,6 @@ 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.
@ -1130,6 +1030,31 @@ 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']+
@ -1145,6 +1070,26 @@ 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' ...]+
@ -1176,7 +1121,7 @@ Syntax: +:scroll 'direction'+
Scroll the current tab in the given direction.
Note you can use `:cmd-run-with-count` to have a keybinding with a bigger scroll increment.
Note you can use `: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).
@ -1310,7 +1255,7 @@ Load a session.
[[session-save]]
=== session-save
Syntax: +:session-save [*--current*] [*--quiet*] [*--force*] [*--only-active-window*] [*--with-private*] [*--no-history*] ['name']+
Syntax: +:session-save [*--current*] [*--quiet*] [*--force*] [*--only-active-window*] [*--with-private*] ['name']+
Save a session.
@ -1324,7 +1269,6 @@ Save a session.
* +*-f*+, +*--force*+: Force saving internal sessions (starting with an underline).
* +*-o*+, +*--only-active-window*+: Saves only tabs of the currently active window.
* +*-p*+, +*--with-private*+: Include private windows.
* +*-n*+, +*--no-history*+: Don't store tab history.
[[set]]
=== set
@ -1341,7 +1285,28 @@ If the option name ends with '?' or no value is provided, the value of the optio
==== optional arguments
* +*-t*+, +*--temp*+: Set value temporarily until qutebrowser is closed.
* +*-p*+, +*--print*+: Print the value after setting.
* +*-u*+, +*--pattern*+: The link:configuring{outfilesuffix}#patterns[URL pattern] to use.
* +*-u*+, +*--pattern*+: The 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
@ -1391,14 +1356,13 @@ The tab index to stop.
[[tab-clone]]
=== tab-clone
Syntax: +:tab-clone [*--bg*] [*--window*] [*--private*]+
Syntax: +:tab-clone [*--bg*] [*--window*]+
Duplicate the current tab.
==== optional arguments
* +*-b*+, +*--bg*+: Open in a background tab.
* +*-w*+, +*--window*+: Open in a new window.
* +*-p*+, +*--private*+: Open in a new private window.
[[tab-close]]
=== tab-close
@ -1466,7 +1430,6 @@ If neither is given, move it to the first position.
==== positional arguments
* +'index'+: `+` or `-` to move relative to the current tab by count, or a default of 1 space.
A tab index to move to that index.
`start` and `end` to move to the start and the end.
==== count
@ -1706,7 +1669,6 @@ How many steps to zoom out.
|<<move-to-start-of-next-block,move-to-start-of-next-block>>|Move the cursor or selection to the start of next block.
|<<move-to-start-of-prev-block,move-to-start-of-prev-block>>|Move the cursor or selection to the start of previous block.
|<<prompt-accept,prompt-accept>>|Accept the current prompt.
|<<prompt-fileselect-external,prompt-fileselect-external>>|Choose a location using a configured external picker.
|<<prompt-item-focus,prompt-item-focus>>|Shift the focus of the prompt file completion menu to another item.
|<<prompt-open-download,prompt-open-download>>|Immediately open a download.
|<<prompt-yank,prompt-yank>>|Yank URL to clipboard or primary selection.
@ -1717,13 +1679,13 @@ How many steps to zoom out.
|<<rl-beginning-of-line,rl-beginning-of-line>>|Move to the start of the line.
|<<rl-delete-char,rl-delete-char>>|Delete the character after the cursor.
|<<rl-end-of-line,rl-end-of-line>>|Move to the end of the line.
|<<rl-filename-rubout,rl-filename-rubout>>|Delete backwards using the OS path separator as boundary.
|<<rl-forward-char,rl-forward-char>>|Move forward a character.
|<<rl-forward-word,rl-forward-word>>|Move forward to the end of the next word.
|<<rl-kill-line,rl-kill-line>>|Remove chars from the cursor to the end of the line.
|<<rl-kill-word,rl-kill-word>>|Remove chars from the cursor to the end of the current word.
|<<rl-rubout,rl-rubout>>|Delete backwards using the given characters as boundaries.
|<<rl-unix-filename-rubout,rl-unix-filename-rubout>>|Remove chars from the cursor to the previous path separator.
|<<rl-unix-line-discard,rl-unix-line-discard>>|Remove chars backward from the cursor to the beginning of the line.
|<<rl-unix-word-rubout,rl-unix-word-rubout>>|Remove chars from the cursor to the beginning of the word.
|<<rl-yank,rl-yank>>|Paste the most recently deleted text.
|<<selection-drop,selection-drop>>|Drop selection and keep selection mode enabled.
|<<selection-reverse,selection-reverse>>|Swap the stationary and moving end of the current selection.
@ -1895,12 +1857,6 @@ Accept the current prompt.
==== optional arguments
* +*-s*+, +*--save*+: Save the value to the config.
[[prompt-fileselect-external]]
=== prompt-fileselect-external
Choose a location using a configured external picker.
This spawns the external fileselector configured via `fileselect.folder.command`.
[[prompt-item-focus]]
=== prompt-item-focus
Syntax: +:prompt-item-focus 'which'+
@ -1981,12 +1937,6 @@ Move to the end of the line.
This acts like readline's end-of-line.
[[rl-filename-rubout]]
=== rl-filename-rubout
Delete backwards using the OS path separator as boundary.
For behavior that matches readline's `unix-filename-rubout` exactly, use `:rl-rubout "/ "` instead. This command uses the OS path separator (i.e. `\` on Windows) and ignores spaces.
[[rl-forward-char]]
=== rl-forward-char
Move forward a character.
@ -2011,17 +1961,11 @@ Remove chars from the cursor to the end of the current word.
This acts like readline's kill-word.
[[rl-rubout]]
=== rl-rubout
Syntax: +:rl-rubout 'delim'+
Delete backwards using the given characters as boundaries.
With " ", this acts like readline's `unix-word-rubout`. With " /", this acts like readline's `unix-filename-rubout`, but consider using `:rl-filename-rubout` instead: It uses the OS path separator (i.e. `\` on Windows) and ignores spaces.
==== positional arguments
* +'delim'+: A string of characters (or a single character) until which text will be deleted.
[[rl-unix-filename-rubout]]
=== rl-unix-filename-rubout
Remove chars from the cursor to the previous path separator.
This acts like readline's unix-filename-rubout.
[[rl-unix-line-discard]]
=== rl-unix-line-discard
@ -2029,6 +1973,12 @@ Remove chars backward from the cursor to the beginning of the line.
This acts like readline's unix-line-discard.
[[rl-unix-word-rubout]]
=== rl-unix-word-rubout
Remove chars from the cursor to the beginning of the word.
This acts like readline's unix-word-rubout. Whitespace is used as a word delimiter.
[[rl-yank]]
=== rl-yank
Paste the most recently deleted text.
@ -2189,7 +2139,7 @@ Syntax: +:debug-webaction 'action'+
Execute a webaction.
Available actions: https://doc.qt.io/archives/qt-5.5/qwebpage.html#WebAction-enum (WebKit) https://doc.qt.io/qt-6/qwebenginepage.html#WebAction-enum (WebEngine)
Available actions: https://doc.qt.io/archives/qt-5.5/qwebpage.html#WebAction-enum (WebKit) https://doc.qt.io/qt-5/qwebenginepage.html#WebAction-enum (WebEngine)
==== positional arguments
* +'action'+: The action to execute, e.g. MoveToNextChar.

View File

@ -22,19 +22,6 @@ exists, the `autoconfig.yml` file **is not read anymore** by default. You need
to <<configpy-autoconfig,load it from `config.py`>> if you want settings changed via
`:set`/`:bind` to persist between restarts.
[[patterns]]
URL pattern support
-------------------
Many settings are customizable depending on the page being visited by using URL
patterns. The link:settings{outfilesuffix}[settings documentation] marks such
settings with "This setting supports URL patterns.
The syntax is based on Chromium's
https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns/[URL pattern syntax].
As an extension, the scheme and path can be left off as a short-hand syntax, so
`example.com` is equivalent to `*://example.com/*`.
[[autoconfig]]
Configuring qutebrowser via the user interface
----------------------------------------------
@ -58,10 +45,9 @@ customizable.
Using the link:commands{outfilesuffix}#set[`:set`] command and command completion, you
can quickly set settings interactively, for example `:set tabs.position left`.
<<patterns,URL patterns>> can be used via
`:set --pattern *://example.com/* content.images false`, or with shorthand
syntax for both argument and pattern, `:set -u example.com content.images
false`.
Some settings are also customizable for a given
https://developer.chrome.com/apps/match_patterns[URL pattern] by doing e.g.
`:set --pattern=*://example.com/ content.images false`.
To get more help about a setting, use e.g. `:help tabs.position`.
@ -174,12 +160,12 @@ color = config.get('colors.completion.fg')
Per-domain settings
~~~~~~~~~~~~~~~~~~~
Using `config.set` instead of the `c.` shorthand, many settings are also
customizable for a given <<patterns,URL patterns>>.
Using `config.set`, some settings are also customizable for a given
https://developer.chrome.com/apps/match_patterns[URL pattern]:
[source,python]
----
config.set('content.images', False, '*://example.com/*')
config.set('content.images', False, '*://example.com/')
----
Alternatively, you can use `with config.pattern(...) as p:` to get a shortcut
@ -187,7 +173,7 @@ similar to `c.` which is scoped to the given domain:
[source,python]
----
with config.pattern('*://example.com/*') as p:
with config.pattern('*://example.com/') as p:
p.content.images = False
----
@ -391,8 +377,8 @@ import subprocess
def read_xresources(prefix):
props = {}
x = subprocess.run(['xrdb', '-query'], capture_output=True, check=True, text=True)
lines = x.stdout.split('\n')
x = subprocess.run(['xrdb', '-query'], stdout=subprocess.PIPE)
lines = x.stdout.decode().split('\n')
for line in filter(lambda l : l.startswith(prefix), lines):
prop, _, value = line.partition(':\t')
props[prop] = value
@ -406,18 +392,11 @@ Pre-built colorschemes
^^^^^^^^^^^^^^^^^^^^^^
- A collection of https://github.com/chriskempson/base16[base16] color-schemes can be found in https://github.com/theova/base16-qutebrowser[base16-qutebrowser] and used with https://github.com/AuditeMarlow/base16-manager[base16-manager].
- Another collection: https://github.com/leosolid/qutebrowser-themes[qutebrowser-themes]
- Pywal integration: https://gitlab.com/jjzmajic/qutewal[qutewal], https://github.com/makman12/pywalQute[pywalQute]
- https://gitlab.com/jjzmajic/qutewal[Pywal integration]
- https://github.com/arcticicestudio/nord[Nord]: https://github.com/Linuus/nord-qutebrowser[Linuus], https://github.com/KnownAsDon/QuteBrowser-Nord-Theme[KnownAsDon]
- https://github.com/dracula/qutebrowser-dracula-theme[Dracula]
- https://gitlab.com/lovetocode999/selenized-qutebrowser[Selenized]
- https://github.com/The-Compiler/dotfiles/blob/master/qutebrowser/gruvbox.py[gruvbox]
- https://www.opencode.net/wakellor957/qb-breath/-/blob/main/qb-breath.py[Manjaro Breath-like]
- https://github.com/gicrisf/qute-city-lights[City Lights (matte dark)]
- https://github.com/catppuccin/qutebrowser[Catppuccin]
- https://github.com/iruzo/matrix-qutebrowser[Matrix]
- https://github.com/harmtemolder/qutebrowser-solarized[Solarized]
- https://github.com/Rehpotsirhc-z/qutebrowser-doom-one[Doom One]
- https://github.com/morhetz/gruvbox[gruvbox]: https://github.com/The-Compiler/dotfiles/blob/master/qutebrowser/gruvbox.py[The-Compiler], https://gitlab.com/shaneyost/dots-popos-september-2020/-/blob/master/qutebrowser/config.py[Shane Yost]
Avoiding flake8 errors
^^^^^^^^^^^^^^^^^^^^^^
@ -452,16 +431,9 @@ Various emacs/conkeror-like keybinding configs exist:
- https://gitlab.com/jgkamat/qutemacs/blob/master/qutemacs.py[jgkamat]
- https://gitlab.com/Kaligule/qutebrowser-emacs-config/blob/master/config.py[Kaligule]
- https://web.archive.org/web/20210512185023/https://me0w.net/pit/1540882719[nm0i]
- https://me0w.net/pit/1540882719[nm0i]
- https://www.reddit.com/r/qutebrowser/comments/eh10i7/config_share_qute_with_emacs_keybindings/[jasonsun0310]
- https://git.sr.ht/~willvaughn/dots/tree/main/item/.config/qutebrowser/qutemacs.py[willvaughn]
It's also mostly possible to get rid of modal keybindings by setting
`input.insert_mode.auto_enter` to `false`, and `input.forward_unbound_keys` to
`all`.
Other resources
^^^^^^^^^^^^^^^
- https://www.ii.com/qutebrowser-tips-fragments/[Infinite Ink: qutebrowser Tips and Fragments]
- https://www.ii.com/qutebrowser-configpy/[Infinite Ink: qutebrowsers Template config.py]

View File

@ -1,5 +1,3 @@
// SPDX-License-Identifier: GPL-3.0-or-later
qutebrowser help
================
@ -8,7 +6,7 @@ Documentation
The following help pages are currently available:
* link:https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/cheatsheet-big.png[Key binding cheatsheet]
* link:https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/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]
@ -24,14 +22,14 @@ Getting help
------------
You can get help in the IRC channel
link:ircs://irc.libera.chat:6697/#qutebrowser[`#qutebrowser`] on
https://libera.chat/[Libera Chat]
(https://web.libera.chat/#qutebrowser[webchat]),
or by writing a message to the
https://listi.jpberlin.de/mailman/listinfo/qutebrowser[mailinglist] at
irc://irc.freenode.org/#qutebrowser[`#qutebrowser`] on
http://freenode.net/[Freenode]
(https://webchat.freenode.net/?channels=#qutebrowser[webchat]), or by writing a
message to the
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[mailinglist] at
mailto:qutebrowser@lists.qutebrowser.org[].
There's also an https://listi.jpberlin.de/mailman/listinfo/qutebrowser-announce[announce-only mailinglist]
There's also an https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce[announce-only mailinglist]
at mailto:qutebrowser-announce@lists.qutebrowser.org[] (the announcements also
get sent to the general qutebrowser@ list).
@ -51,19 +49,9 @@ ways:
* Use the built-in `:report` command or the automatic crash dialog.
* Open an issue in the Github issue tracker.
* Write a mail to the
https://listi.jpberlin.de/mailman/listinfo/qutebrowser[mailinglist] at
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[mailinglist] at
mailto:qutebrowser@lists.qutebrowser.org[].
Other resources
---------------
- https://blog.qutebrowser.org/[Development blog]
- https://twitter.com/qutebrowser[Twitter account],
https://fosstodon.org/@qutebrowser[Mastodon account]
- Infinite Ink: https://www.ii.com/qutebrowser-getting-started/[Getting Started
with qutebrowser] and https://www.ii.com/portal/qutebrowser/[other
qutebrowser articles]
License
-------

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 692 KiB

After

Width:  |  Height:  |  Size: 763 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -21,61 +21,78 @@ 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.
[[debian]]
On Debian / Ubuntu / Linux Mint / ...
-------------------------------------
On Debian / Ubuntu
------------------
With those distributions, qutebrowser is in the official repositories, and you
can install it with `apt install qutebrowser`.
How to install qutebrowser depends a lot on the version of Debian/Ubuntu you're
running.
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):
[[ubuntu1604]]
Debian Stretch / Ubuntu 16.04 LTS / Linux Mint 18
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 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 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.
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.
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.
It's recommended to <<tox,install qutebrowser in a virtualenv>> 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 `scripts/mkvenv.py` with `--pyqt-type link` you get a
newer qutebrowser running with:
- 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)
You should be able to install a newer Python (3.6+) using the
https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa[deadsnakes PPA] or
https://github.com/pyenv/pyenv[pyenv], and then proceed to
<<tox,install qutebrowser in a virtualenv>>. 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:
----
# apt install --no-install-recommends git ca-certificates python3 python3-venv libgl1 libxkbcommon-x11-0 libegl1 libfontconfig1 libglib2.0-0 libdbus-1-3 libxcb-cursor0 libxcb-icccm4 libxcb-keysyms1 libxcb-shape0 libnss3 libxcomposite1 libxdamage1 libxrender1 libxrandr2 libxtst6 libxi6 libasound2
# apt install --no-install-recommends git ca-certificates python3 python3-venv asciidoc 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
----
// FIXME not needed anymore?
// libxi6 libxrender1 libegl1-mesa
Debian Buster / Ubuntu 18.04 LTS / Linux Mint 19
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 <<tox,install qutebrowser in a
virtualenv>> with a newer PyQt/Qt binary instead.
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 <<tox,install
qutebrowser in a virtualenv>> with a newer PyQt/Qt binary instead.
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
----
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 `scripts/mkvenv.py` script to get an older Qt.
- If running from git, run the following to generate the documentation for the
`:help` command (the `scripts/mkvenv.py` script used with a virtualenv install already does
`:help` command (the `mkvenv.py` script used with a virtualenv install already does
this for you):
+
----
$ pip install -r misc/requirements/requirements-docs.txt # or install asciidoc manually
# apt install --no-install-recommends asciidoc
$ python3 scripts/asciidoc2html.py
----
- If you prefer using QtWebKit, there's QtWebKit 5.212 available in
those distributions. Note however that it is based on an upstream
Ubuntu 18.04 / Debian Buster or newer. 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:
@ -103,14 +120,6 @@ To be able to play videos with proprietary codecs with QtWebEngine, you will
need to install an additional package from the RPM Fusion Free repository.
For more information see https://rpmfusion.org/Configuration.
With Qt 6 (recommended):
-----
# dnf install libavcodec-freeworld
-----
With Qt 5:
-----
# dnf install qt5-qtwebengine-freeworld
-----
@ -168,13 +177,6 @@ need to turn off the `bindist` flag for `dev-qt/qtwebengine`.
See the https://wiki.gentoo.org/wiki/Qutebrowser#USE_flags[Gentoo Wiki] for
more information.
To be able to use Kerberos authentication, you will need to turn on the
`kerberos` USE-flag system-wide and re-emerge `dev-qt/qtwebengine` after that.
See the
https://wiki.gentoo.org/wiki/Qutebrowser#Kerberos_authentication_does_not_work[
Troubleshooting section in Gentoo Wiki] for more information.
On Void Linux
-------------
@ -235,9 +237,14 @@ Via Flatpak
qutebrowser is available
https://flathub.org/apps/details/org.qutebrowser.qutebrowser[on Flathub]
as `org.qutebrowser.qutebrowser`. See the
https://github.com/flathub/org.qutebrowser.qutebrowser/wiki[qutebrowser Flatpak documentation]
for more information about setting up certain features with the Flatpak sandbox.
as `org.qutebrowser.qutebrowser`.
NOTE: The Flatpak package is
https://github.com/flathub/org.qutebrowser.qutebrowser/issues/8#issuecomment-799579975[looking for (co-)maintainers].
The package recently was updated after being out of date for multiple years. It
currently (March 2021) is up to date again. If that situation changes, consider
to <<tox,install qutebrowser in a virtualenv>> instead, which is one of the
officially maintained options and will always be up-to-date.
On FreeBSD
----------
@ -257,10 +264,6 @@ and QtWebEngine backend is also not available.
On Windows
----------
NOTE: As an additional resource, see
https://www.ii.com/installing-qutebrowser-on-windows/[Infinite Ink: Installing
qutebrowser on Windows].
There are different ways to install qutebrowser on Windows:
Prebuilt binaries
@ -271,7 +274,7 @@ https://github.com/qutebrowser/qutebrowser/releases[are built] for every
release.
Note that you'll need to upgrade to new versions manually (subscribe to the
https://listi.jpberlin.de/mailman/listinfo/qutebrowser-announce[qutebrowser-announce
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce[qutebrowser-announce
mailinglist] to get notified on new releases). You can install a newer version
without uninstalling the older one.
@ -283,24 +286,23 @@ Nightly builds
~~~~~~~~~~~~~~
If you want to test out new features before an official qutebrowser release, automated
https://github.com/qutebrowser/qutebrowser/actions/workflows/nightly.yml[nightly
builds] are available. To download them, open the latest run (usually the first one),
then download the archive at the bottom of the page.
https://github.com/qutebrowser/qutebrowser/actions/workflows/bleeding.yml[nightly
builds] are available. To download them, open the lastest run (usually the first one),
then download the archive at the bottom of the page. Note that due to GitHub
limitations, all variants (Windows/macOS, 32/64 bit, debug/non-debug) are contained in a
single archive.
Those builds also include variants with debug logging enabled, which can be useful to
track down issues.
NOTE: Due to GitHub limitations, you need to be signed in with a GitHub account
to download the files.
Package managers
~~~~~~~~~~~~~~~~
https://chocolatey.org/packages/qutebrowser[Chocolatey package]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* PackageManagement PowerShell module
----
PS C:\> Install-Package qutebrowser
----
* https://chocolatey.org/packages/qutebrowser[Chocolatey package] with `choco`:
* Chocolatey's client
----
C:\> choco install qutebrowser
----
@ -329,47 +331,33 @@ files from the
https://github.com/qutebrowser/qutebrowser/releases[release page].
Note that you'll need to upgrade to new versions manually (subscribe to the
https://listi.jpberlin.de/mailman/listinfo/qutebrowser-announce[qutebrowser-announce
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce[qutebrowser-announce
mailinglist] to get notified on new releases).
The binary release ships with a QtWebEngine built without proprietary codec
support. To get support for e.g. h264/mp4 videos, you'll need to build
QtWebEngine from source yourself with support for that enabled.
NOTE: Currently, qutebrowser
https://github.com/qutebrowser/qutebrowser/issues/5020[does not use] macOS'
https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution[Notarization],
due to https://github.com/pyinstaller/pyinstaller/issues/6612[PyInstaller issues]
(as well as the requirement to
https://developer.apple.com/support/compare-memberships/[pay USD 100 per year to Apple]).
Depending on your system settings, this might lead to errors such as
"qutebrowser.app can't be opened because Apple cannot check it for malicious
software." or "can't be opened because it is from an unidentified developer".
You should be able to open the .app by right-clicking it and selecting "Open", see the
https://support.apple.com/guide/mac-help/open-a-mac-app-from-an-unidentified-developer-mh40616/mac[macOS documentation]
for details.
This binary is also available through the https://brew.sh/[Homebrew] package
manager as a https://github.com/Homebrew/homebrew-cask[cask]:
This binary is also available through the
https://caskroom.github.io/[Homebrew Cask] package manager:
----
$ brew install qutebrowser
$ brew install qutebrowser --cask
----
Nightly builds
~~~~~~~~~~~~~~
If you want to test out new features before an official qutebrowser release, automated
https://github.com/qutebrowser/qutebrowser/actions/workflows/nightly.yml[nightly
builds] are available. To download them, open the latest run (usually the first one),
then download the archive at the bottom of the page.
https://github.com/qutebrowser/qutebrowser/actions/workflows/bleeding.yml[nightly
builds] are available. To download them, open the lastest run (usually the first one),
then download the archive at the bottom of the page. Note that due to GitHub
limitations, all variants (Windows/macOS, 32/64 bit, debug/non-debug) are contained in a
single archive.
Those builds also include variants with debug logging enabled, which can be useful to
track down issues.
NOTE: Due to GitHub limitations, you need to be signed in with a GitHub account
to download the files.
Manual Install
~~~~~~~~~~~~~~
@ -380,15 +368,26 @@ qutebrowser from source.
==== Homebrew
----
$ brew install pyqt@6
$ brew install qt
(build PyQt and PyQtWebEngine from source)
$ pip3 install qutebrowser
----
NOTE: Homebrew does not package PyQtWebEngine (Python wrappers for
QtWebEngine), so you will need to build that from sources manually.
Since the v1.0 release, qutebrowser uses QtWebEngine by default.
Homebrew's builds of Qt and PyQt don't come with QtWebKit (and `--with-qtwebkit`
uses an old version of QtWebKit which qutebrowser doesn't support anymore). If
you want QtWebKit support, you'll need to build an up-to-date QtWebKit
https://github.com/annulen/webkit/wiki/Building-QtWebKit-on-OS-X[manually].
Packagers
---------
qutebrowser ships with a
https://github.com/qutebrowser/qutebrowser/blob/main/misc/Makefile[Makefile]
https://github.com/qutebrowser/qutebrowser/blob/master/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.
@ -411,7 +410,7 @@ location for a particular application, rather than being installed globally.
The `scripts/mkvenv.py` script in this repository can be used to create a
virtualenv for qutebrowser and install it (including all dependencies) there.
The next couple of sections will explain the most common use-cases - run
`scripts/mkvenv.py` with `--help` to see all available options.
`mkvenv.py` with `--help` to see all available options.
Getting the repository
~~~~~~~~~~~~~~~~~~~~~~
@ -428,7 +427,7 @@ Installing dependencies (including Qt)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using a Qt installed via virtualenv needs a couple of system-wide libraries.
See the <<debian,Debian-based distributions section>> for details about which libraries
See the <<ubuntu1604,Ubuntu 16.04 section>> for details about which libraries
are required.
Then run the install script:
@ -444,7 +443,7 @@ This installs all needed Python dependencies in a `.venv` subfolder
This comes with an up-to-date Qt/PyQt including a pre-compiled QtWebEngine
binary, but has a few caveats:
- Make sure your `python3` is Python 3.9 or newer, otherwise you'll get a "No
- Make sure your `python3` is Python 3.6 or newer, otherwise you'll get a "No
matching distribution found" error and/or qutebrowser will not run.
- It only works on 64-bit x86 systems, with other architectures you'll get the
same error.
@ -455,8 +454,8 @@ See the next section for an alternative install method which might help with
those issues but result in an older Qt version.
You can specify a Qt/PyQt version with the `--pyqt-version` flag, see
`scripts/mkvenv.py --help` for a list of available versions. By default, the
latest version which plays well with qutebrowser is used.
`mkvenv.py --help` for a list of available versions. By default, the latest
version which plays well with qutebrowser is used.
NOTE: If the Qt smoke test fails with a _"This application failed to start
because no Qt platform plugin could be initialized."_ message, most likely a
@ -466,24 +465,22 @@ failed on ..._ line for details.
Installing dependencies (system-wide Qt)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Alternatively, you can use `scripts/mkvenv.py --pyqt-type link` to symlink
your local PyQt/Qt install instead of installing PyQt in the virtualenv.
However, unless you have a new QtWebKit or QtWebEngine available, qutebrowser
will not work. It also typically means you'll be using an older release of
QtWebEngine.
Alternatively, you can use `mkvenv.py --pyqt-type link` to symlink your local
PyQt/Qt install instead of installing PyQt in the virtualenv. However, unless
you have a new QtWebKit or QtWebEngine available, qutebrowser will not work. It
also typically means you'll be using an older release of QtWebEngine.
On Windows, run `set PYTHON=C:\path\to\python.exe` (CMD) or `$Env:PYTHON =
On Windows, run `set PYTHON=C:\path\to\python.exe` (CMD) or ``$Env:PYTHON =
"..."` (Powershell) first.
There is a third mode, `scripts/mkvenv.py --pyqt-type source` which uses a
system-wide Qt but builds PyQt from source. In most scenarios, this shouldn't
be needed.
There is a third mode, `mkvenv.py --pyqt-type source` which uses a system-wide
Qt but builds PyQt from source. In most scenarios, this shouldn't be needed.
Creating a wrapper script
~~~~~~~~~~~~~~~~~~~~~~~~~
Running `scripts/mkvenv.py` does not install a system-wide `qutebrowser`
script. You can launch qutebrowser by doing:
Running `mkvenv.py` does not install a system-wide `qutebrowser` script. You can
launch qutebrowser by doing:
----
.venv/bin/python3 -m qutebrowser
@ -497,12 +494,24 @@ You can create a simple wrapper script to start qutebrowser somewhere in your
~/path/to/qutebrowser/.venv/bin/python3 -m qutebrowser "$@"
----
Building the docs
~~~~~~~~~~~~~~~~~
To build the documentation, install `asciidoc` (note that LaTeX which comes as
optional/recommended dependency with some distributions is not required).
Then, run:
----
$ python3 scripts/asciidoc2html.py
----
Updating
~~~~~~~~
If you cloned the git repository, run `scripts/mkvenv.py --update` which will
take care of updating the code (via `git pull`) and recreating the environment
with the newest dependencies.
If you cloned the git repository, run `mkvenv.py --update` which will take care
of updating the code (via `git pull`) and recreating the environment with the
newest dependencies.
Alternatively, you can update your local copy of the code (e.g. by pulling the
git repo, or extracting a new version) and the virtualenv should automatically

View File

@ -9,7 +9,6 @@ Basic keybindings to get you started
------------------------------------
* Use the arrow keys or `hjkl` to move around a webpage (vim-like syntax is used in quite a few places)
* To zoom in or out of a webpage, use the `+` or `-` keys respectively
* To go to a new webpage, press `o`, then type a url, then press Enter (Use `O` to open the url in a new tab, `go` to edit the current URL)
* If what you've typed isn't a url, then a search engine will be used instead (DuckDuckGo, by default)
* To switch between tabs, use `J` (next tab) and `K` (previous tab), or press `<Alt-num>`, where `num` is the position of the tab to switch to
@ -23,9 +22,9 @@ Basic keybindings to get you started
What to do now
--------------
* View the link:https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/cheatsheet-big.png[key binding cheatsheet]
* View the link:https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/cheatsheet-big.png[key binding cheatsheet]
to make yourself familiar with the key bindings: +
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"]
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"]
* 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.
@ -34,8 +33,8 @@ image:https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/che
`scripts/asciidoc2html.py` to generate the documentation.
* Go to the link:qute://settings[settings page] to set up qutebrowser the way you want it.
* Subscribe to
https://listi.jpberlin.de/mailman/listinfo/qutebrowser[the mailinglist] or
https://listi.jpberlin.de/mailman/listinfo/qutebrowser-announce[the announce-only mailinglist].
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[the mailinglist] or
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce[the announce-only mailinglist].
* Let me know what features you are missing or things that need (even small!)
improvements.
@ -47,13 +46,13 @@ If you get stuck, you can get help in multiple ways:
* The `:help` command inside qutebrowser shows the built-in documentation.
Additionally, each command can be started with a `--help` flag to show its
help.
* Chat via the IRC channel: link:ircs://irc.libera.chat:6697/#qutebrowser[`#qutebrowser`] on
https://libera.chat/[Libera Chat] (https://web.libera.chat/#qutebrowser[webchat],
or https://matrix.to/#qutebrowser:libera.chat[via Matrix])
* Chat via the IRC channel: irc://irc.freenode.org/#qutebrowser[`#qutebrowser`] on
https://freenode.net/[Freenode]
(https://webchat.freenode.net/?channels=#qutebrowser[webchat])
* On Reddit: https://www.reddit.com/r/qutebrowser/[/r/qutebrowser]
* Via https://github.com/qutebrowser/qutebrowser/discussions[GitHub Discussions]
* Using the mailinglist: mailto:qutebrowser@lists.qutebrowser.org[]
(https://listi.jpberlin.de/mailman/listinfo/qutebrowser[subscribe])
(https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[subscribe])
Donating
--------
@ -62,12 +61,10 @@ qutebrowser's primary maintainer, The-Compiler, is currently working part-time o
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/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!
https://github.com/sponsors/The-Compiler/[GitHub Sponsors page] 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/main/README.asciidoc#donating[donation section]
https://github.com/qutebrowser/qutebrowser/blob/master/README.asciidoc#donating[donation section]
in the README for details.

View File

@ -1,5 +1,3 @@
// 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.
@ -12,14 +10,14 @@
:homepage: https://www.qutebrowser.org/
== NAME
qutebrowser - a keyboard-driven, vim-like browser based on Python and Qt.
qutebrowser - a keyboard-driven, vim-like browser based on PyQt5.
== SYNOPSIS
*qutebrowser* ['-OPTION' ['...']] [':COMMAND' ['...']] ['URL' ['...']]
== DESCRIPTION
qutebrowser is a keyboard-focused browser with a minimal GUI. It's based
on Python and Qt and is free software, licensed under the GPL.
on Python and Qt5 and is free software, licensed under the GPL.
It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl.
@ -36,7 +34,7 @@ show it.
*'URL'*::
URLs to open on startup (empty as a window separator).
=== options
=== optional arguments
*-h*, *--help*::
show this help message and exit
@ -64,14 +62,8 @@ show it.
*--backend* '{webkit,webengine}'::
Which backend to use.
*--qt-wrapper* '{PyQt6,PyQt5}'::
Which Qt wrapper to use. This can also be set via the QUTE_QT_WRAPPER environment variable. If both are set, the command line argument takes precedence.
*--desktop-file-name* 'DESKTOP_FILE_NAME'::
Set the base name of the desktop entry for this application. Used to set the app_id under Wayland. See https://doc.qt.io/qt-6/qguiapplication.html#desktopFileName-prop
*--untrusted-args*::
Mark all following arguments as untrusted, which enforces that they are URLs/search terms (and not flags or commands)
Set the base name of the desktop entry for this application. Used to set the app_id under Wayland. See https://doc.qt.io/qt-5/qguiapplication.html#desktopFileName-prop
=== debug arguments
*-l* '{critical,error,warning,info,debug,vdebug}', *--loglevel* '{critical,error,warning,info,debug,vdebug}'::
@ -128,24 +120,18 @@ environment, the directories configured there are used instead of the above
defaults.
== BUGS
Bugs are tracked in the Github issue tracker at
Bugs are tracked in the Github issue tracker at
https://github.com/qutebrowser/qutebrowser/issues.
If you found a bug, use the built-in ':report' command to create a bug report
with all information needed.
If you prefer, you can also write to the
https://listi.jpberlin.de/mailman/listinfo/qutebrowser[mailinglist] at
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[mailinglist] at
mailto:qutebrowser@lists.qutebrowser.org[] instead.
For security bugs, please contact security@qutebrowser.org (or if GPG
encryption is desired, contact me@the-compiler.org with GPG ID
https://www.the-compiler.org/pubkey.asc[0x916EB0C8FD55A072]).
Alternatively,
https://github.com/qutebrowser/qutebrowser/security/advisories/new[report a vulnerability]
via GitHub's
https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability[private reporting feature].
For security bugs, please contact me directly at me@the-compiler.org, GPG ID
https://www.the-compiler.org/pubkey.asc[0xFD55A072].
== COPYRIGHT
This program is free software: you can redistribute it and/or modify it under
@ -163,12 +149,11 @@ this program. If not, see <https://www.gnu.org/licenses/>.
== RESOURCES
* Website: https://www.qutebrowser.org/
* Mailinglist: mailto:qutebrowser@lists.qutebrowser.org[] /
https://listi.jpberlin.de/mailman/listinfo/qutebrowser
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser
* Announce-only mailinglist: mailto:qutebrowser-announce@lists.qutebrowser.org[] /
https://listi.jpberlin.de/mailman/listinfo/qutebrowser-announce
* IRC: link:ircs://irc.libera.chat:6697/#qutebrowser[`#qutebrowser`] on
https://libera.chat/[Libera Chat] (https://web.libera.chat/#qutebrowser[webchat],
https://matrix.to/#qutebrowser:libera.chat[via Matrix])
https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce
* IRC: irc://irc.freenode.org/#qutebrowser[`#qutebrowser`] on
https://freenode.net/[Freenode]
* Github: https://github.com/qutebrowser/qutebrowser
== AUTHOR

View File

@ -68,13 +68,55 @@ Then install the needed debuginfo packages:
Archlinux
^^^^^^^^^
For Archlinux, debug information is provided via their https://wiki.archlinux.org/title/Debuginfod[Debuginfod instance]. To use it, set the following in your environment:
For Archlinux, no debug information is provided. You can either compile Qt
yourself (which will take a few hours even on a modern machine) or use
debugging symbols compiled/packaged by me (x86_64 only).
To install my pre-built packages
++++++++++++++++++++++++++++++++
First download and sign the key:
----
DEBUGINFOD_URLS="https://debuginfod.archlinux.org/"
# pacman-key -r 0xD6A1C70FE80A0C82
$ pacman-key -f 0xD6A1C70FE80A0C82
Key fingerprint = 14AF EC28 70C6 4863 C5C7 ACCB D6A1 C70F E80A 0C82
# pacman-key --lsign-key 0xD6A1C70FE80A0C82
----
(Until early 2021, there was a custom [`qt-debug` repository](https://github.com/qutebrowser/qt-debug-pkgbuild). This is now archived.)
Then edit your `/etc/pacman.conf` to add the repository to the bottom:
----
[qt-debug]
Server = https://qutebrowser.org/qt-debug/$arch
----
Then install the packages:
----
# pacman -Suy python-pyqt5-debug qt5-base-debug qt5-webkit-debug qt5-webengine-debug
----
The `-debug` packages conflict with the non-debug variants - it's safe to
remove them.
To compile by yourself
++++++++++++++++++++++
Note that building Qt will likely take multiple hours, even on a recent system.
I'd also expect it to take around 6 GB of RAM and 30 GB of disk space for a
successful compile run.
----
$ git clone https://github.com/qutebrowser/qt-debug-pkgbuild.git
$ cd qt-debug-pkgbuild
$ export DEBUG_CFLAGS='-ggdb3 -fvar-tracking-assignments -Og'
$ export DEBUG_CXXFLAGS='-ggdb3 -fvar-tracking-assignments -Og'
$ cd qt5
$ makepkg -si --pkg qt5-base-debug,qt5-webkit-debug,qt5-webengine-debug
$ cd ../pyqt5
$ makepkg -si --pkg python-pyqt5-debug
----
Getting the stack trace
~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -22,10 +22,7 @@ To call a userscript, it needs to be stored in your config or data directory und
`userscripts` (for example: `~/.local/share/qutebrowser/userscripts/myscript`),
or just use an absolute path.
NOTE: On Windows, only userscripts with `com`, `bat`, or `exe` extensions will
be launched. As an additional resource, see
https://www.ii.com/qutebrowser-userscripts-on-windows/[Infinite Ink:
qutebrowser Userscripts on Windows].
NOTE: On Windows, only userscripts with `com`, `bat`, or `exe` extensions will be launched.
Getting information
-------------------
@ -52,16 +49,14 @@ The following environment variables will be set when a userscript is launched:
In `command` mode:
- `QUTE_URL`: The current page URL.
- `QUTE_URL`: The current URL.
- `QUTE_TITLE`: The title of the current page.
- `QUTE_SELECTED_TEXT`: The text currently selected on the page.
- `QUTE_COUNT`: The `count` from the spawn command running the userscript.
- `QUTE_TAB_INDEX`: The current tab's index.
In `hints` mode:
- `QUTE_URL`: The URL selected via hints.
- `QUTE_CURRENT_URL`: The current page URL.
- `QUTE_SELECTED_TEXT`: The plain text of the element selected via hints.
- `QUTE_SELECTED_HTML`: The HTML of the element selected via hints.

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 856 B

After

Width:  |  Height:  |  Size: 856 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -4,7 +4,6 @@ ICONSIZES = 16 24 32 48 64 128 256 512
DATAROOTDIR = $(PREFIX)/share
DATADIR ?= $(DATAROOTDIR)
MANDIR ?= $(DATAROOTDIR)/man
A2X ?= a2x
ifdef DESTDIR
SETUPTOOLSOPTS = --root="$(DESTDIR)"
@ -15,7 +14,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)
@ -25,9 +24,9 @@ install: man
"$(DESTDIR)$(MANDIR)/man1/qutebrowser.1"
install -Dm644 misc/org.qutebrowser.qutebrowser.desktop \
"$(DESTDIR)$(DATADIR)/applications/org.qutebrowser.qutebrowser.desktop"
$(foreach i,$(ICONSIZES),install -Dm644 "qutebrowser/icons/qutebrowser-$(i)x$(i).png" \
$(foreach i,$(ICONSIZES),install -Dm644 "icons/qutebrowser-$(i)x$(i).png" \
"$(DESTDIR)$(DATADIR)/icons/hicolor/$(i)x$(i)/apps/qutebrowser.png";)
install -Dm644 qutebrowser/icons/qutebrowser.svg \
install -Dm644 icons/qutebrowser.svg \
"$(DESTDIR)$(DATADIR)/icons/hicolor/scalable/apps/qutebrowser.svg"
install -Dm755 -t "$(DESTDIR)$(DATADIR)/qutebrowser/userscripts/" \
$(filter-out misc/userscripts/__pycache__,$(wildcard misc/userscripts/*))

View File

@ -2570,7 +2570,7 @@
id="flowPara5604"
style="font-size:13.8667px;line-height:1.25;font-family:sans-serif;stroke-width:1.06667">Website: https://www.qutebrowser.org/ </flowPara><flowPara
id="flowPara5595"
style="font-size:13.8667px;line-height:1.25;font-family:sans-serif;stroke-width:1.06667">IRC: #qutebrowser on Libera Chat (irc.libera.chat)</flowPara><flowPara
style="font-size:13.8667px;line-height:1.25;font-family:sans-serif;stroke-width:1.06667">IRC: #qutebrowser on Freenode</flowPara><flowPara
id="flowPara5597"
style="font-size:13.8667px;line-height:1.25;font-family:sans-serif;stroke-width:1.06667">Mailinglist: qutebrowser@lists.qutebrowser.org</flowPara></flowRoot>
<text

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 175 KiB

View File

@ -1,6 +1,19 @@
# SPDX-FileCopyrightText: Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2018 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
# NSIS installer header. Uses NsisMultiUser plugin and contains portions of
# its demo code, copyright 2017 Richard Drizin, Alex Mitev.
@ -137,7 +150,7 @@ var KeepReg
; Functions
Function CheckInstallation
; if there's an installed version, uninstall it first (I chose not to start the uninstaller silently, so that user sees what failed)
; if both per-user and per-machine versions are installed, uninstall the one that matches $MultiUser.InstallMode
; if both per-user and per-machine versions are installed, unistall the one that matches $MultiUser.InstallMode
StrCpy $0 ""
${if} $HasCurrentModeInstallation = 1
StrCpy $0 "$MultiUser.InstallMode"
@ -338,12 +351,13 @@ Section "Register with Windows" SectionWindowsRegister
!insertmacro UpdateRegDWORD SHCTX "SOFTWARE\Classes\$2" "EditFlags" 0x00000002
!insertmacro UpdateRegStr SHCTX "SOFTWARE\Classes\$2\DefaultIcon" "" "$1,0"
!insertmacro UpdateRegStr SHCTX "SOFTWARE\Classes\$2\shell" "" "open"
!insertmacro UpdateRegStr SHCTX "SOFTWARE\Classes\$2\shell\open\command" "" "$\"$1$\" --untrusted-args $\"%1$\""
!insertmacro UpdateRegStr SHCTX "SOFTWARE\Classes\$2\shell\open\command" "" "$\"$1$\" $\"%1$\""
!insertmacro UpdateRegStr SHCTX "SOFTWARE\Classes\$2\shell\open\ddeexec" "" ""
StrCmp $2 "${PRODUCT_NAME}HTML" 0 +4
StrCpy $2 "${PRODUCT_NAME}URL"
StrCpy $3 "${PRODUCT_NAME} URL"
Goto WriteRegHandler
!insertmacro UpdateRegStr SHCTX "SOFTWARE\Classes\$2" "URL Protocol" ""
${endif}
SectionEnd
@ -430,23 +444,8 @@ SectionEnd
; Callbacks
Function .onInit
StrCpy $KeepReg 1
; OS version check
; https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoa#remarks
; https://learn.microsoft.com/en-us/windows/release-health/release-information
; https://learn.microsoft.com/en-us/windows/release-health/windows11-release-information
${If} ${AtLeastWin11}
Goto _os_check_pass
${ElseIf} ${IsNativeAMD64} ; Windows 10 has no x86_64 emulation on arm64
${AndIf} ${AtLeastWin10}
${AndIf} ${AtLeastBuild} 17763 ; Windows 10 1809 (also in error message below)
Goto _os_check_pass
${EndIf}
MessageBox MB_OK|MB_ICONSTOP "This version of ${PRODUCT_NAME} requires a 64-bit$\r$\n\
version of Windows 10 1809 or later."
Abort
_os_check_pass:
!insertmacro CheckPlatform ${PLATFORM}
!insertmacro CheckMinWinVer ${MIN_WIN_VER}
${ifnot} ${UAC_IsInnerInstance}
!insertmacro CheckSingleInstance "Setup" "Global" "${SETUP_MUTEX}"
!insertmacro CheckSingleInstance "Application" "Local" "${APP_MUTEX}"
@ -544,16 +543,8 @@ Function PageInstallModeChangeMode
FunctionEnd
Function PageComponentsPre
SendMessage $mui.Button.Next ${BCM_SETSHIELD} 0 0
StrCmpS $HasCurrentModeInstallation 0 +9
IfFileExists "$DESKTOP\${PRODUCT_NAME}.lnk" +4
SectionGetFlags ${SectionDesktopIcon} $1
IntOp $1 $1 & 0xFFFFFFFE
SectionSetFlags ${SectionDesktopIcon} $1
IfFileExists "$STARTMENU\${PRODUCT_NAME}.lnk" +4
SectionGetFlags ${SectionStartMenuIcon} $1
IntOp $1 $1 & 0xFFFFFFFE
SectionSetFlags ${SectionStartMenuIcon} $1
GetDlgItem $0 $HWNDPARENT 1
SendMessage $0 ${BCM_SETSHIELD} 0 0 ; hide SHIELD (Windows Vista and above)
FunctionEnd
Function PageDirectoryPre

View File

@ -1,6 +1,19 @@
# SPDX-FileCopyrightText: Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2018 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
# NSIS pages header. Uses NsisMultiUser plugin and contains portions of
# its demo code, copyright 2017 Richard Drizin, Alex Mitev.
@ -9,7 +22,7 @@
; NsisMultiUser optional defines
!define MULTIUSER_INSTALLMODE_ALLOW_BOTH_INSTALLATIONS 0
!define MULTIUSER_INSTALLMODE_ALLOW_ELEVATION 1
!define MULTIUSER_INSTALLMODE_ALLOW_ELEVATION_IF_SILENT 1
!define MULTIUSER_INSTALLMODE_ALLOW_ELEVATION_IF_SILENT 0
!define MULTIUSER_INSTALLMODE_DEFAULT_ALLUSERS 1
!if ${PLATFORM} == "win64"
!define MULTIUSER_INSTALLMODE_64_BIT 1

View File

@ -1,7 +1,20 @@
# SPDX-FileCopyrightText: Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2018 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# encoding: iso-8859-1
#
# SPDX-License-Identifier: GPL-3.0-or-later
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
# NSIS installer script. Uses NsisMultiUser plugin and contains portions of
# its demo code, copyright 2017 Richard Drizin, Alex Mitev.
@ -30,9 +43,6 @@ ShowUninstDetails hide
!addplugindir /x86-unicode ".\plugins\x86-unicode"
!addincludedir ".\include"
!define MUI_BGCOLOR "SYSCLR:Window"
!define MUI_TEXTCOLOR "SYSCLR:WindowText"
!include MUI2.nsh
!include NsisMultiUser.nsh
!include StdUtils.nsh
@ -47,9 +57,9 @@ ShowUninstDetails hide
!define URL_UPDATE "https://qutebrowser.org/doc/install.html"
!define HELP_LINK "https://qutebrowser.org/doc/help/"
!define CONTACT "mail@qutebrowser.org"
!define COMMENTS "A keyboard-driven, vim-like browser based on Python and Qt."
!define COMMENTS "A keyboard-driven, vim-like browser based on PyQt5."
!define LANGID "1033" ; U.S. English
!define MIN_WIN_VER "8"
!define MIN_WIN_VER "XP"
!define SETUP_MUTEX "${PRODUCT_NAME} Setup Mutex" ; do not change this between program versions!
!define APP_MUTEX "${PRODUCT_NAME} App Mutex" ; do not change this between program versions!
!define REG_UN "Software\Microsoft\Windows\CurrentVersion\Uninstall"
@ -124,11 +134,11 @@ ShowUninstDetails hide
; If not defined, get VERSION from PROGEXE. Set DIST_DIR accordingly.
!ifndef VERSION
!define /ifndef DIST_DIR ".\..\..\dist\${PRODUCT_NAME}"
!define /ifndef DIST_DIR ".\..\..\dist\${PRODUCT_NAME}-${ARCH}"
!getdllversion "${DIST_DIR}\${PROGEXE}" expv_
!define VERSION "${expv_1}.${expv_2}.${expv_3}"
!else
!define /ifndef DIST_DIR ".\..\..\dist\${PRODUCT_NAME}-${VERSION}"
!define /ifndef DIST_DIR ".\..\..\dist\${PRODUCT_NAME}-${VERSION}-${ARCH}"
!endif
; Pack the exe header with upx if UPX is defined.

View File

@ -1,6 +1,19 @@
# SPDX-FileCopyrightText: Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2018 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
# NSIS uninstaller header. Uses NsisMultiUser plugin and contains portions of
# its demo code, copyright 2017 Richard Drizin, Alex Mitev.

View File

@ -1,6 +1,19 @@
# SPDX-FileCopyrightText: Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2018 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later
# This file is part of qutebrowser.
#
# qutebrowser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# qutebrowser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
# NSIS pages header. Uses NsisMultiUser plugin and contains portions of
# its demo code, copyright 2017 Richard Drizin, Alex Mitev.

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- SPDX-FileCopyrightText: suve <veg@svgames.pl> -->
<!-- Copyright 2017 suve <veg@svgames.pl> -->
<component type="desktop">
<id>org.qutebrowser.qutebrowser</id>
<metadata_license>CC-BY-SA-3.0</metadata_license>
@ -23,16 +23,16 @@
<launchable type="desktop-id">org.qutebrowser.qutebrowser.desktop</launchable>
<screenshots>
<screenshot type="default">
<image>https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/main.png</image>
<image>https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/main.png</image>
</screenshot>
<screenshot>
<image>https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/downloads.png</image>
<image>https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/downloads.png</image>
</screenshot>
<screenshot>
<image>https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/completion.png</image>
<image>https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/completion.png</image>
</screenshot>
<screenshot>
<image>https://raw.githubusercontent.com/qutebrowser/qutebrowser/main/doc/img/hints.png</image>
<image>https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/hints.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://www.qutebrowser.org</url>
@ -44,31 +44,6 @@
</content_rating>
<releases>
<!-- Add new releases here -->
<release version='3.6.3' date='2025-11-30'/>
<release version='3.6.2' date='2025-11-27'/>
<release version='3.6.1' date='2025-11-03'/>
<release version='3.6.0' date='2025-10-24'/>
<release version='3.5.1' date='2025-06-05'/>
<release version='3.5.0' date='2025-04-12'/>
<release version="3.4.0" date="2024-12-14"/>
<release version="3.3.1" date="2024-10-12"/>
<release version="3.3.0" date="2024-10-12"/>
<release version="3.2.1" date="2024-06-25"/>
<release version="3.2.0" date="2024-06-03"/>
<release version="3.1.0" date="2023-12-08"/>
<release version="3.0.2" date="2023-10-19"/>
<release version="3.0.1" date="2023-10-19"/>
<release version="3.0.0" date="2023-08-18"/>
<release version="2.5.4" date="2023-03-13"/>
<release version="2.5.3" date="2023-02-17"/>
<release version="2.5.2" date="2022-06-22"/>
<release version="2.5.1" date="2022-05-26"/>
<release version="2.5.0" date="2022-04-01"/>
<release version="2.4.0" date="2021-10-21"/>
<release version="2.3.1" date="2021-07-28"/>
<release version="2.3.0" date="2021-06-28"/>
<release version="2.2.3" date="2021-06-01"/>
<release version="2.2.2" date="2021-05-20"/>
<release version="2.2.1" date="2021-04-29"/>
<release version="2.2.0" date="2021-04-13"/>
<release version="2.1.1" date="2021-04-01"/>

View File

@ -39,16 +39,16 @@ GenericName[ta]=இணைய உலாவி
GenericName[th]=
GenericName[tr]=Web Tarayıcı
GenericName[uk]=Навігатор Тенет
Comment=A keyboard-driven, vim-like browser based on Python and Qt
Comment[de]=Ein Tastatur-gesteuerter, vim-ähnlicher Browser basierend auf Python und Qt
Comment[it]= Un browser web vim-like utilizzabile da tastiera basato su Python e Qt
Comment=A keyboard-driven, vim-like browser based on PyQt5
Comment[de]=Ein Tastatur-gesteuerter, vim-ähnlicher Browser basierend auf PyQt5
Comment[it]= Un browser web vim-like utilizzabile da tastiera basato su PyQt5
Icon=qutebrowser
Type=Application
Categories=Network;WebBrowser;
Exec=qutebrowser --untrusted-args %u
Exec=qutebrowser %u
Terminal=false
StartupNotify=true
MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/rdf+xml;image/gif;image/webp;image/jpeg;image/png;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/qute;
MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/rdf+xml;image/gif;image/jpeg;image/png;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/qute;
Keywords=Browser
Actions=new-window;preferences;

13
misc/qutebrowser.rcc Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>icons/qutebrowser-16x16.png</file>
<file>icons/qutebrowser-24x24.png</file>
<file>icons/qutebrowser-32x32.png</file>
<file>icons/qutebrowser-48x48.png</file>
<file>icons/qutebrowser-64x64.png</file>
<file>icons/qutebrowser-96x96.png</file>
<file>icons/qutebrowser-128x128.png</file>
<file>icons/qutebrowser-256x256.png</file>
<file>icons/qutebrowser-512x512.png</file>
</qresource>
</RCC>

View File

@ -6,117 +6,23 @@ import os
sys.path.insert(0, os.getcwd())
from scripts import setupcommon
import qutebrowser
from qutebrowser.extensions import loader
block_cipher = None
INFO_PLIST_UPDATES = {
'CFBundleVersion': qutebrowser.__version__,
'CFBundleShortVersionString': qutebrowser.__version__,
'NSSupportsAutomaticGraphicsSwitching': True,
'NSHighResolutionCapable': True,
'NSRequiresAquaSystemAppearance': False,
'CFBundleURLTypes': [{
"CFBundleURLName": "http(s) URL",
"CFBundleURLSchemes": ["http", "https"]
}, {
"CFBundleURLName": "local file URL",
"CFBundleURLSchemes": ["file"]
}],
'CFBundleDocumentTypes': [
{
"CFBundleTypeIconFile": "document.icns",
"CFBundleTypeName": name,
"CFBundleTypeRole": "Viewer",
"LSItemContentTypes": [content_type],
}
for name, content_type in [
("GIF image", "com.compuserve.gif"),
("HTML document", "public.html"),
("XHTML document", "public.xhtml"),
("JavaScript script", "com.netscape.javascript-source"),
("JPEG image", "public.jpeg"),
("MHTML document", "org.ietf.mhtml"),
("HTML5 Audio (Ogg)", "org.xiph.ogg-audio"),
("HTML5 Video (Ogg)", "org.xiph.oggv"),
("PNG image", "public.png"),
("SVG document", "public.svg-image"),
("Plain text document", "public.text"),
("HTML5 Video (WebM)", "org.webmproject.webm"),
("WebP image", "org.webmproject.webp"),
("PDF Document", "com.adobe.pdf"),
]
],
'UTImportedTypeDeclarations': [
{
"UTTypeConformsTo": ["public.data", "public.content"],
"UTTypeDescription": "MIME HTML document",
"UTTypeIconFile": "document.icns",
"UTTypeIdentifier": "org.ietf.mhtml",
"UTTypeReferenceURL": "https://www.ietf.org/rfc/rfc2557",
"UTTypeTagSpecification": {
"com.apple.ostype": "MHTM",
"public.filename-extension": ["mht", "mhtml"],
"public.mime-type": ["multipart/related", "application/x-mimearchive"],
},
},
{
"UTTypeConformsTo": ["public.audio"],
"UTTypeDescription": "Ogg Audio",
"UTTypeIconFile": "document.icns",
"UTTypeIdentifier": "org.xiph.ogg-audio",
"UTTypeReferenceURL": "https://xiph.org/ogg/",
"UTTypeTagSpecification": {
"public.filename-extension": ["ogg", "oga"],
"public.mime-type": ["audio/ogg"],
},
},
{
"UTTypeConformsTo": ["public.movie"],
"UTTypeDescription": "Ogg Video",
"UTTypeIconFile": "document.icns",
"UTTypeIdentifier": "org.xiph.ogv",
"UTTypeReferenceURL": "https://xiph.org/ogg/",
"UTTypeTagSpecification": {
"public.filename-extension": ["ogm", "ogv"],
"public.mime-type": ["video/ogg"],
},
},
],
# https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_macos
#
# Keys based on Google Chrome's .app, except Bluetooth keys which seem to
# be iOS-only.
#
# If we don't do this, we get a SIGABRT from macOS when those permissions
# are used, and even in some other situations (like logging into Google
# accounts)...
'NSCameraUsageDescription':
'A website in qutebrowser wants to use the camera.',
'NSLocationUsageDescription':
'A website in qutebrowser wants to use your location information.',
'NSMicrophoneUsageDescription':
'A website in qutebrowser wants to use your microphone.',
'NSBluetoothAlwaysUsageDescription':
'A website in qutebrowser wants to access Bluetooth.',
}
def get_data_files():
data_files = [
('../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'),
('../qutebrowser/html', 'html'),
('../qutebrowser/img', 'img'),
('../qutebrowser/javascript', 'javascript'),
('../qutebrowser/html/doc', 'html/doc'),
('../qutebrowser/git-commit-id', '.'),
('../qutebrowser/config/configdata.yml', 'config'),
]
if os.path.exists(os.path.join('qutebrowser', '3rdparty', 'pdfjs')):
data_files.append(('../qutebrowser/3rdparty/pdfjs', 'qutebrowser/3rdparty/pdfjs'))
data_files.append(('../qutebrowser/3rdparty/pdfjs', '3rdparty/pdfjs'))
else:
print("Warning: excluding pdfjs as it's not present!")
@ -124,7 +30,7 @@ def get_data_files():
def get_hidden_imports():
imports = ["PyQt5.QtOpenGL"] if "PYINSTALLER_QT5" in os.environ else []
imports = ['PyQt5.QtOpenGL', 'PyQt5._QOpenGLFunctions_2_0']
for info in loader.walk_components():
imports.append(info.name)
return imports
@ -134,19 +40,14 @@ setupcommon.write_git_file()
if os.name == 'nt':
icon = '../qutebrowser/icons/qutebrowser.ico'
icon = '../icons/qutebrowser.ico'
elif sys.platform == 'darwin':
icon = '../qutebrowser/icons/qutebrowser.icns'
icon = '../icons/qutebrowser.icns'
else:
icon = None
DEBUG = os.environ.get('PYINSTALLER_DEBUG', '').lower() in ['1', 'true']
if DEBUG:
options = options = [('v', None, 'OPTION')]
else:
options = []
a = Analysis(['../qutebrowser/__main__.py'],
@ -164,7 +65,6 @@ pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
options,
exclude_binaries=True,
name='qutebrowser',
icon=icon,
@ -184,5 +84,5 @@ coll = COLLECT(exe,
app = BUNDLE(coll,
name='qutebrowser.app',
icon=icon,
info_plist=INFO_PLIST_UPDATES,
bundle_identifier='org.qutebrowser.qutebrowser')
# https://github.com/pyinstaller/pyinstaller/blob/b78bfe530cdc2904f65ce098bdf2de08c9037abb/PyInstaller/hooks/hook-PyQt5.QtWebEngineWidgets.py#L24
bundle_identifier='org.qt-project.Qt.QtWebEngineCore')

View File

@ -19,11 +19,4 @@ Some examples:
#@ filter: mypkg != 1.0.0
#@ ignore: mypkg, otherpkg
#@ replace: foo bar
## Use the marker line to restrict the unpinned Flask requirement to python
## 3.7. For python 3.7 add a specific version into the output.
Flask
# Python 3.7
#@ markers: Flask python_version>="3.7"
#@ add: Flask==2.2.5 ; python_version=="3.7.*"
```

View File

@ -0,0 +1,8 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
build==0.3.1.post1
check-manifest==0.46
packaging==20.9
pep517==0.10.0
pyparsing==2.4.7
toml==0.10.2

View File

@ -0,0 +1 @@
check-manifest

View File

@ -1,73 +1,24 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
annotated-types==0.7.0
anyio==4.12.0
autocommand==2.2.2
backports.tarfile==1.2.0
bracex==2.6
build==1.3.0
bump-my-version==1.2.5
certifi==2025.11.12
cffi==2.0.0
charset-normalizer==3.4.4
click==8.1.8
cryptography==46.0.3
docutils==0.22.3
exceptiongroup==1.3.1
github3.py==4.0.1
h11==0.16.0
httpcore==1.0.9
httpx==0.28.1
hunter==3.9.0
id==1.5.0
idna==3.11
importlib_metadata==8.7.0
importlib_resources==6.5.2
inflect==7.3.1
jaraco.classes==3.4.0
jaraco.collections==5.1.0
jaraco.context==6.0.1
jaraco.functools==4.0.1
jaraco.text==3.12.1
jeepney==0.9.0
keyring==25.7.0
manhole==1.8.1
markdown-it-py==3.0.0
mdurl==0.1.2
more-itertools==10.8.0
nh3==0.3.2
packaging==25.0
platformdirs==4.4.0
prompt_toolkit==3.0.52
pycparser==2.23
pydantic==2.12.5
pydantic-settings==2.11.0
pydantic_core==2.41.5
Pygments==2.19.2
PyJWT==2.10.1
Pympler==1.1
pyproject_hooks==1.2.0
PyQt-builder==1.19.1
python-dateutil==2.9.0.post0
python-dotenv==1.2.1
questionary==2.1.1
readme_renderer==44.0
requests==2.32.5
requests-toolbelt==1.0.0
rfc3986==2.0.0
rich==14.2.0
rich-click==1.9.4
SecretStorage==3.3.3
sip==6.14.0
six==1.17.0
tomli==2.3.0
tomlkit==0.13.3
twine==6.2.0
typeguard==4.3.0
typing-inspection==0.4.2
typing_extensions==4.15.0
uritemplate==4.2.0
# urllib3==2.6.2
wcmatch==10.1
wcwidth==0.2.14
zipp==3.23.0
bump2version==1.0.1
certifi==2020.12.5
cffi==1.14.5
chardet==4.0.0
cryptography==3.4.7
github3.py==2.0.0
hunter==3.3.2
idna==2.10
jwcrypto==0.8
manhole==1.8.0
packaging==20.9
pycparser==2.20
Pympler==0.9
pyparsing==2.4.7
PyQt-builder==1.9.1
python-dateutil==2.8.1
requests==2.25.1
sip==6.0.3
six==1.15.0
toml==0.10.2
uritemplate==3.0.1
# urllib3==1.26.4

View File

@ -1,16 +1,9 @@
hunter
pympler
github3.py
bump-my-version
bump2version
requests
pyqt-builder
build
twine
# Included to override setuptools' vendored version that is being included in
# the lock file by pip freeze.
importlib_resources
platformdirs
# Already included via test requirements
#@ ignore: urllib3

View File

@ -1,3 +0,0 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
asciidoc==10.2.1

View File

@ -1 +0,0 @@
asciidoc

View File

@ -1,23 +1,24 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
attrs==25.4.0
flake8==7.3.0
flake8-bugbear==24.12.12
flake8-builtins==3.0.0
flake8-comprehensions==3.17.0
flake8-debugger==4.1.2
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==2.1.0
attrs==20.3.0
flake8==3.9.0
flake8-bugbear==21.4.3
flake8-builtins==1.5.3
flake8-comprehensions==3.4.0
flake8-copyright==0.2.2
flake8-debugger==4.0.0
flake8-deprecated==1.3
flake8-docstrings==1.6.0
flake8-future-import==0.4.6
flake8-mock==0.3
flake8-polyfill==1.0.2
flake8-string-format==0.3.0
flake8-tidy-imports==4.12.0
flake8-tidy-imports==4.2.1
flake8-tuple==0.4.1
mccabe==0.7.0
pep8-naming==0.15.1
pycodestyle==2.14.0
pydocstyle==6.3.0
pyflakes==3.4.0
six==1.17.0
snowballstemmer==3.0.1
mccabe==0.6.1
pep8-naming==0.11.1
pycodestyle==2.7.0
pydocstyle==6.0.0
pyflakes==2.3.1
six==1.15.0
snowballstemmer==2.1.0

View File

@ -2,18 +2,15 @@ flake8
flake8-bugbear
flake8-builtins
flake8-comprehensions
flake8-copyright
flake8-debugger
flake8-deprecated!=2.0.0
flake8-deprecated
flake8-docstrings
# https://github.com/savoirfairelinux/flake8-copyright/issues/19
# flake8-copyright
flake8-future-import
# https://github.com/aleGpereira/flake8-mock/issues/10
# flake8-mock
flake8-mock
flake8-string-format
flake8-tidy-imports
flake8-tuple
flake8-pytest-style
pep8-naming
pydocstyle
pyflakes

View File

@ -1,20 +1,19 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
chardet==5.2.0
diff_cover==10.0.0
Jinja2==3.1.6
librt==0.7.3
lxml==6.0.2
MarkupSafe==3.0.3
mypy==1.19.0
mypy_extensions==1.1.0
pathspec==0.12.1
pluggy==1.6.0
Pygments==2.19.2
PyQt5-stubs==5.15.6.0
tomli==2.3.0
types-colorama==0.4.15.20250801
types-docutils==0.22.3.20251115
types-Pygments==2.19.0.20251121
types-PyYAML==6.0.12.20250915
typing_extensions==4.15.0
chardet==4.0.0
diff-cover==5.0.1
importlib-metadata==3.10.0
importlib-resources==5.1.2
inflect==5.3.0
Jinja2==2.11.3
jinja2-pluralize==0.3.0
lxml==4.6.3
MarkupSafe==1.1.1
mypy==0.812
mypy-extensions==0.4.3
pluggy==0.13.1
Pygments==2.8.1
PyQt5-stubs==5.15.2.0
typed-ast==1.4.3
typing-extensions==3.7.4.3
zipp==3.4.1

View File

@ -1,8 +1,8 @@
mypy
lxml # For HTML reports
diff-cover
PyQt5-stubs
types-PyYAML
types-colorama
types-Pygments
# So stubs are available even on newer Python versions
importlib_resources
importlib_metadata

View File

@ -0,0 +1,8 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
appdirs==1.4.4
packaging==20.4
pyparsing==2.4.7
setuptools==47.3.1
six==1.15.0
wheel==0.34.2

View File

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

View File

@ -1 +1 @@
pyinstaller
PyInstaller

View File

@ -1,28 +1,25 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
astroid==3.3.11
certifi==2025.11.12
cffi==2.0.0
charset-normalizer==3.4.4
cryptography==46.0.3
dill==0.4.0
github3.py==4.0.1
idna==3.11
importlib_metadata==8.7.0
isort==6.1.0
mccabe==0.7.0
pefile==2024.8.26
platformdirs==4.4.0
pycparser==2.23
PyJWT==2.10.1
pylint==3.3.9
python-dateutil==2.9.0.post0
astroid==2.3.3 # rq.filter: < 2.4
certifi==2020.12.5
cffi==1.14.5
chardet==4.0.0
cryptography==3.4.7
future==0.18.2
github3.py==2.0.0
idna==2.10
isort==4.3.21
jwcrypto==0.8
lazy-object-proxy==1.4.3
mccabe==0.6.1
pefile==2019.4.18
pycparser==2.20
pylint==2.4.4 # rq.filter: < 2.5
python-dateutil==2.8.1
./scripts/dev/pylint_checkers
requests==2.32.5
six==1.17.0
tomli==2.3.0
tomlkit==0.13.3
typing_extensions==4.15.0
uritemplate==4.2.0
# urllib3==2.6.2
zipp==3.23.0
requests==2.25.1
six==1.15.0
typed-ast==1.4.3 ; python_version<"3.8"
uritemplate==3.0.1
# urllib3==1.26.4
wrapt==1.11.2

View File

@ -1,12 +1,14 @@
pylint
astroid
pylint<2.5
./scripts/dev/pylint_checkers
requests
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"
#@ filter: pylint < 2.5
#@ filter: astroid < 2.4
# Already included via test requirements
#@ ignore: urllib3

View File

@ -0,0 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt5==5.12.3 # rq.filter: < 5.13
PyQt5-sip==12.8.1
PyQtWebEngine==5.12.1 # rq.filter: < 5.13

View File

@ -0,0 +1,4 @@
#@ filter: PyQt5 < 5.13
#@ filter: PyQtWebEngine < 5.13
PyQt5 >= 5.12, < 5.13
PyQtWebEngine >= 5.12, < 5.13

View File

@ -0,0 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt5==5.13.2 # rq.filter: < 5.14
PyQt5-sip==12.8.1
PyQtWebEngine==5.13.2 # rq.filter: < 5.14

View File

@ -0,0 +1,4 @@
#@ filter: PyQt5 < 5.14
#@ filter: PyQtWebEngine < 5.14
PyQt5 >= 5.13, < 5.14
PyQtWebEngine >= 5.13, < 5.14

View File

@ -0,0 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt5==5.14.2 # rq.filter: < 5.15
PyQt5-sip==12.8.1
PyQtWebEngine==5.14.0 # rq.filter: < 5.15

View File

@ -0,0 +1,4 @@
#@ filter: PyQt5 < 5.15
#@ filter: PyQtWebEngine < 5.15
PyQt5 >= 5.14, < 5.15
PyQtWebEngine >= 5.14, < 5.15

View File

@ -0,0 +1,5 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt5==5.15.0 # rq.filter: == 5.15.0
PyQt5-sip==12.8.1
PyQtWebEngine==5.15.0 # rq.filter: == 5.15.0

View File

@ -0,0 +1,4 @@
#@ filter: PyQt5 == 5.15.0
#@ filter: PyQtWebEngine == 5.15.0
PyQt5 == 5.15.0
PyQtWebEngine == 5.15.0

View File

@ -1,5 +0,0 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt5==5.15.2 # rq.filter: == 5.15.2
PyQt5_sip==12.17.1
PyQtWebEngine==5.15.2 # rq.filter: == 5.15.2

View File

@ -1,4 +0,0 @@
#@ filter: PyQt5 == 5.15.2
#@ filter: PyQtWebEngine == 5.15.2
PyQt5 == 5.15.2
PyQtWebEngine == 5.15.2

View File

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

View File

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

View File

@ -1,2 +0,0 @@
PyQt5
PyQtWebEngine

View File

@ -1,8 +0,0 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt6==6.10.1
PyQt6-Qt6==6.10.1
PyQt6-WebEngine==6.10.0
PyQt6-WebEngine-Qt6==6.10.1
PyQt6_sip==13.10.2
--extra-index-url https://www.riverbankcomputing.com/pypi/simple/

View File

@ -1,8 +0,0 @@
PyQt6 >= 6.10, < 6.11
PyQt6-Qt6 >= 6.10, < 6.11
PyQt6-WebEngine >= 6.10, < 6.11
PyQt6-WebEngine-Qt6 >= 6.10, < 6.11
# WORKAROUND for https://www.riverbankcomputing.com/pipermail/pyqt/2025-October/046347.html
#@ add: --extra-index-url https://www.riverbankcomputing.com/pypi/simple/
--extra-index-url https://www.riverbankcomputing.com/pypi/simple/

View File

@ -1,7 +0,0 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt6==6.2.3
PyQt6-Qt6==6.2.4
PyQt6-WebEngine==6.2.1
PyQt6-WebEngine-Qt6==6.2.4
PyQt6_sip==13.10.2

View File

@ -1,4 +0,0 @@
PyQt6 >= 6.2, < 6.3
PyQt6-Qt6 >= 6.2, < 6.3
PyQt6-WebEngine >= 6.2, < 6.3
PyQt6-WebEngine-Qt6 >= 6.2, < 6.3

View File

@ -1,7 +0,0 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt6==6.3.1
PyQt6-Qt6==6.3.2
PyQt6-WebEngine==6.3.1
PyQt6-WebEngine-Qt6==6.3.2
PyQt6_sip==13.10.2

View File

@ -1,4 +0,0 @@
PyQt6 >= 6.3, < 6.4
PyQt6-Qt6 >= 6.3, < 6.4
PyQt6-WebEngine >= 6.3, < 6.4
PyQt6-WebEngine-Qt6 >= 6.3, < 6.4

View File

@ -1,7 +0,0 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt6==6.4.2
PyQt6-Qt6==6.4.3
PyQt6-WebEngine==6.4.0
PyQt6-WebEngine-Qt6==6.4.3
PyQt6_sip==13.10.2

View File

@ -1,4 +0,0 @@
PyQt6 >= 6.4, < 6.5
PyQt6-Qt6 >= 6.4, < 6.5
PyQt6-WebEngine >= 6.4, < 6.5
PyQt6-WebEngine-Qt6 >= 6.4, < 6.5

View File

@ -1,7 +0,0 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
PyQt6==6.5.3
PyQt6-Qt6==6.5.3
PyQt6-WebEngine==6.5.0
PyQt6-WebEngine-Qt6==6.5.3
PyQt6_sip==13.10.2

View File

@ -1,4 +0,0 @@
PyQt6 >= 6.5, < 6.6
PyQt6-Qt6 >= 6.5, < 6.6
PyQt6-WebEngine >= 6.5, < 6.6
PyQt6-WebEngine-Qt6 >= 6.5, < 6.6

Some files were not shown because too many files have changed in this diff Show More