A keyboard-driven, vim-like browser based on Python and Qt.
adblock
library is available, it is now used to integrate Brave's Rust adblocker library for improved adblocking based on ABP-like filter lists (such as EasyList).
If it is unavailable, qutebrowser falls back to host-blocking, i.e. the same blocking technique it used before this release. As part of this, various settings got renamed, see "Changed" below.
Note: If the adblock
dependency is available, qutebrowser will ignore custom host blocking via the blocked-hosts
config file or file:///
URLs supplied as host blocking lists. You will need to either migrate those to ABP-like lists, or set content.blocking.method
to both
.adblock
library (if packaged - if not, consider packaging it, albeit optional it's very useful for users).cssutils
optional dependency (if present).attrs
(attr
) dependency.pypeg2
dependency (and perhaps consider dropping the package if not used elsewhere - it's inactive upstream and the repository was removed by Bitbucket).pygments
dependency from required to optional.setuptools
dependency from runtime (for pkg_resources
) to build-time.importlib_resources
backport.dataclasses
backport.--enable-webengine-inspector
flag (which was only needed for Qt 5.10 and below) is now dropped. With Qt 5.11 and newer, the inspector/devtools are enabled unconditionally.--old
flag for :config-diff
has been removed. It used to show customized options for the old pre-v1.0 config files (in order to aid migration to v1.0).:inspector
command which was deprecated in v1.13.0 (in favor of :devtools
) is now removed.run-macro
-> macro-run
record-macro
-> macro-record
buffer
-> tab-select
open-editor
-> edit-text
toggle-selection
-> selection-toggle
drop-selection
-> selection-drop
reverse-selection
-> selection-reverse
follow-selected
-> selection-follow
follow-hint
-> hint-follow
enter-mode
-> mode-enter
leave-mode
-> mode-leave
content.blocking.method
to decide which blocker(s) should be used.content.blocking.adblock.lists
to configure ABP-like lists to use.qt.environ
setting which makes it easier to set/unset environment variables for qutebrowser.fileselect.handler
(default
or external
)fileselect.multiple_files.command
fileselect.single_file.command
QUTE_DARKMODE_VARIANT=qt_515_2
environment variable which can be set to get the correct behavior in (transitive) situations like this.--desktop-file-name
commandline argument, which can be used to customize the desktop filename passed to Qt (which is used to set the app_id
on Wayland).:open
completion now also completes local file paths and file://
URLs, via a new filesystem
entry in completion.open_categories
. Also, a new completion.favorite_paths
setting was added which can be used to add paths to show when :open
is used without any input.QUTE_VERSION
variable for userscripts, which can be used to read qutebrowser's version.:bookmark-list
command which lists all bookmarks/quickmarks. The corresponding qute://bookmarks
URL already existed since v0.8.0, but it was never exposed as a command.qt.workarounds.remove_service_workers
setting which can be used to remove the "Service Workers" directory on every start. Usage of this option is generally discouraged, except in situations where the underlying QtWebEngine bug is a known cause for crashes.changelog_after_upgrade
setting.kodi
to play videos in Kodiqr
to generate a QR code of the current URLadd-nextcloud-bookmarks
to create bookmarks in Nextcloud's Bookmarks appadd-nextcloud-cookbook
to add recipes to Nextcloud's Cookbook appconfig.py
files now are required to have either config.load_autoconfig(False)
(don't load autoconfig.yml
) or config.load_autoconfig()
(do load autoconfig.yml
) in them.content.host_blocking.enabled
-> content.blocking.enabled
(controlling both blockers)content.host_blocking.whitelist
-> content.blocking.whitelist
(controlling both blockers)content.host_blocking.lists
-> content.blocking.hosts.lists
tabs.background
is now true
by default, so that new tabs get opened in the background.input.partial_timeout
is now set to 0 by default, so that partially typed key strings are never cleared.hints.leave_on_load
is now false
by default, so that hint mode doesn't get left when a page finishes loading. This can lead to stale hints persisting in rare circumstances, but is better than leaving hint mode when the user entered it before loading was completed.tabs.width
(tab bar width if vertical) is now 15% of the window width rather than 20%.tab-move -
and tab-move +
) were changed from gl
and gr
to gK
and gJ
, to be consistent with the tab switching bindings.qute://pdfjs
URLs). This might take a couple of minutes, but is a one-time operation. This should result in a performance improvement for the completion for affected users.adblock
library (see above for details).cssutils
dependency is now removed. It was only needed for improved behavior in corner cases when using :download --mhtml
with the (non-default) QtWebKit backend, and as such it's unlikely anyone is still relying on it. The cssutils
project is also dead upstream, with its repository being gone after Bitbucket removed Mercurial support.pygments
dependency is now optional. It is only used when using :view-source
with QtWebKit, or when forcing it via :view-source --pygments
on QtWebEngine. If it is unavailable, an unhighlighted fallback version of the page's source is shown.pkg_resources
module (part of the setuptools
project) got dropped. Note that setuptools
is still required to run setup.py
.importlib_resources
module got introduced for Python versions up to and including 3.8. Note that the stdlib importlib.resources
module for Python 3.7 and 3.8 is missing the needed APIs, thus requiring the backports for those versions as well.attrs
/attr
package is now dropped in favour of dataclasses
in the Python standard library. On Python 3.6, a new dependency on the dataclasses
backport is now required.pypeg2
package is now dropped. This might cause some changes for certain corner-cases for suggested filenames when downloading files with the QtWebKit backend.colors.webpage.darkmode.*
settings are now also supported with older Qt versions (Qt 5.12 and 5.13) rather than just with Qt 5.14 and above.hints.{prev,next}_regexes
), certain patterns which will change meanings in future Python versions are now disallowed. This is the case for character sets starting with a literal [
or containing literal character sequences --
, &&
, ~~
, or ||
. To avoid a warning, remove the duplicate characters or escape them with a backslash.prompt(..., "default")
is used via JS, the default text is now pre-selected in the prompt shown by qutebrowser.::1/foo
are now handled as a search term or local file rather than IPv6. Use [::1]/foo
to force parsing as IPv6 instead.mkvenv.py
script now runs a "smoke test" after setting up the virtual environment to ensure it's working as expected. If necessary, the test can be skipped via a new --skip-smoke-test
flag.userscripts
and greasemonkey
subdirectories of e.g. ~/.config/qutebrowser/
) rather than only the data directory (the same subdirectories of e.g. ~/.local/share/qutebrowser/
).:later
command now understands a time specification like 5m
or 1h5m2s
, rather than just taking milliseconds.importer.py
script doesn't use a browser argument anymore; instead its --input-format
switch can be used to configure the input format. The help also was expanded to explain how to use it properly.tabs.tabs_are_windows
is set, the tabs.last_close
setting is now ignored and the window is always closed when using :close
(d
).accept
header is set via content.headers.custom
, the custom value is now ignored for XHR (XMLHttpRequest
) requests. Instead, the sent value is now */*
or the header set from JavaScript, as it would be if content.headers.custom
wasn't set.:tab-select
completion now shows the underlying renderer process PID if doing so is supported (on QtWebEngine 5.15).tabs.favicons.show
is set to never
, favicons aren't unnecessarily downloaded anymore. Thus, disabling favicons can help with a possible fingerprinting vector.colors.tabs.indicator.*
and colors.downloads.*
), the alpha channel is now handled correctly.format_json
now uses env
in its shebang, making it work correctly on systems where bash
isn't located in /bin
.qute-pass
now handles the MIME output format introduced in gopass 1.10.0.qute-lastpass
now types multiple <
or >
characters correctly.:undo
completion now sorts its entries correctly (by the numerical index rather than lexicographically).completion.web_history.ignore
setting now works properly when set in config.py
(rather than via :set
). Additionally, a :config-source
will not result in a history rebuild if the value wasn't actually changed.data:
URL, the suggested filename is now improved and contains a proper extension. Before this fix, qutebrowser would use the URL's data contents as filename with QtWebEngine; or "binary blob" with the Qt network stack.:tab-only
is run before a tab is available, an error is now shown instead of crashing.qute://pdfjs
URLs) are now not added to the history database anymore.String.replaceAll
which was only added to Chromium recently (Chrome 85), so won't work with current QtWebEngine versions. This release includes a workaround (a polyfill as a site-specific-quirk).-w
option. To avoid those
issues for people who are not using transparency, the default behavior is
reverted to versions before v1.14.0 in this release. A new window.transparent
setting can be set to true
to restore the behavior of v1.14.0.content.cookies.accept
not working properlydatabases-incognito
in
the home directory[A]
)content.headers.referer
setting to same-domain
(the default)
was supposed to truncate referers to only the host with QtWebEngine.
Unfortunately, this functionality broke in Qt 5.14. It works properly again
with this release, including a test so this won't happen again.content.headers.referer
setting to
never
did still send referers. This is now fixed as well.Object.fromEntries
JavaScript API is unavailable (it was
introduced in Chromium 73, while Qt 5.12 is based on 69). This caused
https://www.vr.fi/en and possibly other websites to break when accessed with Qt
5.12. A suitable polyfill is now included with qutebrowser if
content.site_specific_quirks
is enabled (which is the default).dmenu_qutebrowser
and qutedmenu
userscripts now correctly read the
qutebrowser sqlite history which has been in use since v1.0.0.:adblock-update
now doesn't
cache the HTTP response anymore.content.headers
set to same-domain
(the
default), origins with the same domain but different schemes or ports were
treated as the same domain. They now are correctly treated as different domains.https://example.com/embedded%2Fpath
), using :navigate up
would treat the
%2F
as a path separator and replace any remaining percent escapes by their
unescaped equivalents. Those are now handled correctly.libxcb-utils
version (notably, Debian Stable, but not Ubuntu since
16.04 LTS) results in a setup which fails to start. This also affects the
mkvenv.py
script, which now includes a workaround for this case.open_url_instance.sh
userscript now complains when socat
is not
installed, rather than silencing the error.misc/
was outdated and written for the
older QtWebKit backend. It is now updated to serve as an useful starting
point with QtWebEngine.:devtools
on Fedora without the needed (optional) dependency
installed, it was suggested to install qt5-webengine-devtools
, which does
not, in fact, exist. It's now correctly suggested to install
qt5-qtwebengine-devtools
instead.readability-js
userscript
were invisible. This is now fixed by changing the border color to grey (with all
Qt versions).colors.webpage.prefers_color_scheme_dark
setting broke with Qt 5.15.2. It now
works properly again.pkg_resources
module used by qutebrowser caused deprecation
warnings to appear on start with Python 3.9 on some setups. Those are now
hidden.content.javascript.enabled
Note: The QtWebEngine version bundled with the Windows/macOS releases is still based on Qt 5.15.0 (like with qutebrowser v1.12.0 and v1.13.0) rather than Qt 5.15.1 because of a Qt bug causing frequent renderer process crashes. When Qt 5.15.2 is released (planned for November 3rd, 2020), a qutebrowser v1.14.x patch release with an updated QtWebEngine will be released.
Furthermore, this release still only contains partial session support for QtWebEngine 5.15. It's still recommended to run against Qt 5.15 due to the security patches contained in it -- for most users, the added workarounds seem to work out fine. A rewritten session support will be part of qutebrowser v2.0.0, tentatively planned for the end of the year or early 2021.
content.media_capture
setting got split up into three more fine-grained
settings, content.media.audio_capture
, .video_capture
and
.audio_video_capture
. Before this change, answering "always" to a prompt
about e.g. audio capturing would set the content.media_capture
setting,
which would also allow the same website to capture video on a future visit.
Now every prompt will set the appropriate setting, though existing
content.media_capture
settings in autoconfig.yml
will be migrated to set
all three settings. To review/change previously granted permissions, use
:config-diff
and e.g.
:config-unset -u example.org content.media.video_capture
.:undo
is used with a count, it now reopens the count-th to last tab
instead of the last one. The depth can instead be passed as an argument,
which is also completed.completion.timestamp_format
now also shows the time.:back
and :forward
now take an optional index which is completed using
the current tab's history.:completion-item-focus
now understands next-page
and prev-page
with
corresponding <PgDown>
/ <PgUp>
default bindings.config.source(...)
is used with a --config-py
argument given,
qutebrowser used to search relative files in the config basedir, leading to them
not being found when using a shared config.py
for different basedirs. Instead,
they are now searched relative to the given config.py
file.navigate prev
([[
) and navigate next
(]]
) now recognize links with
nav-prev
and nav-next
classes, such as those used by the Hugo static site
generator.tabs.favicons
is disabled but tabs.tabs_are_windows
is set, the
window icon is still set to the page's favicon now.--asciidoc
argument to src2asciidoc.py
and build_release.py
now
only takes the path to asciidoc.py
, using the current Python interpreter by
default. To configure the Python interpreter as well, use
--asciidoc-python path/to/python --asciidoc path/to/asciidoc.py
instead of the former
--asciidoc path/to/python path/to/asciidoc.py
.colors.webpage.darkmode.*
) is now supported with Qt 5.15.2 (which
is not released yet).policy.images
setting is now set to smart
which fixes issues with e.g. formulas on Wikipedia.readability-js
userscript now adds some CSS to improve the reader mode
styling in various scenarios:
readability-js
userscript now supports hint userscript mode.strip
for :navigate
which removes queries and
fragments from the current URL.:undo
now has a new -w
/ --window
argument, which can be used to
restore closed windows (rather than tabs). This is bound to U
by default.:jseval
can now take javascript:...
URLs via a new --url
flag.{aligned_index}
for tabs.title.format
and format_pinned
which behaves like {index}
, but space-pads the index based on the total
numbers of tabs. This can be used to get aligned tab texts with vertical
tabs.:devtools-focus
(bound to wIf
) to toggle keyboard focus
between the devtools and web page.--target
argument to qutebrowser now understands a new private-window
value, which can be used to open a private window in an existing instance
from the commandline.:download-open
command now has a new --dir
flag, which can be used to
open the directory containing the downloaded file. An entry to do the same
was also added to the context menu.--debug-flag
values:
wait-renderer-process
waits for a SIGUSR1
in the renderer process so a
debugger can be attached.avoid-chromium-init
allows using --version
without needing a working
QtWebEngine/Chromium.*.
host was considered valid and matched all hosts.
Due to keybindings like tsH
toggling scripts for *://*.{url:host}/*
,
invoking them on pages without a host (e.g. about:blank
) could result in
accidentally allowing/blocking JavaScript for all pages. Such patterns are
now considered invalid, with existing patterns being automatically removed
from autoconfig.yml
.scrolling.bar
was set to overlay
(the default), qutebrowser would
internally override any enable-features=...
flags passed via qt.args
or
--qt-flag
. It now correctly combines existing enable-feature
flags with
internal ones.contenteditable
attribute now trigger insert
mode and get hints assigned correctly.-m
with the qute-lastpass
userscript, it accidentally matched
URLs containing the match as substring. This is now fixed.:enter-mode register
crashed since v1.13.0, it now displays an error
instead.:config-edit
is used but no config.py
exists yet, the file is now
created (and watched for changes properly) before spawning the external
editor.fV
), the statusbar
could end up in a confusing state. This is now fixed.web.whatsapp.com
has been updated to work after recent
changes in WhatsApp.:undo
is used to re-open a tab, but tabs.tabs_are_windows
was set between
closing and undoing the close, qutebrowser crashed. This is now fixed.smart
leads to
renderer process crashes. The offending setting value is now ignored with a
warning.qute-pass
userscript:
gopass
versions, a deprecation notice was copied as
password due to qute-pass
using it in a deprecated way.--password-store
argument didn't actually set
PASSWORD_STORE_DIR
for pass
, resulting in qute-pass
finding matches but the
underlying pass
not finding matching passwords.:back
was used before saving a session.autoconfig.yml
with an invalid structure could lead to crashes,
which are now fixed.asciidoc2html.py
(e.g. via mkvenv.py
) now works
correctly without Pygments being installed system-wide.input.mouse.rocker_gestures
was enabled, the
context menu still was shown when clicking the right mouse button, thus
preventing the rocker gestures. This is now fixed.:help
was called with a deprecated command (e.g. :help :inspector
),
the help page would show despite deprecated commands not being documented.
This now shows an error instead.qute-lastpass
userscript now filters out duplicate entries with
--merge-candidates
.:inspector
command is deprecated and has been replaced by a new
:devtools
command (see below).:debug-log-level
command was removed as it's replaced by the new
logging.level.console
setting.qute://plainlog
special page got replaced by qute://log?plain
- the
names of those pages is considered an implementation detail, and
:messages --plain
should be used instead.:config-write-py
now adds a note about config.py
files being targeted at
advanced users.:report
now takes two optional arguments for bug/contact information, so
that it can be used without the report window popping up.:message
now takes a --logfilter
/ -f
argument, which is a list of
logging categories to show.:debug-log-filter
now understands the full logfilter syntax.fonts.tabs
has been split into fonts.tabs.{selected,unselected}
(see
below).statusbar.hide
has been renamed to statusbar.show
with the possible
values being always
(hide = False
), never
(hide = True
) or
in-mode
(new, only show statusbar outside of normal mode.QtFont
config type formerly used for fonts.tabs
and
fonts.debug_console
is now removed and entirely replaced by Font
. The
former distinction was mainly an implementation detail, and the accepted
values shouldn't have changed.input.rocker_gestures
has been renamed to input.mouse.rocker_gestures
.content.dns_prefetch
is now enabled by default again, since the crashes
it caused are now fixed (Qt 5.15) or worked around.scrolling.bar
supports a new overlay
value to show an overlay
scrollbar, which is now the default. On unsupported configurations (on Qt <
5.11, with QtWebKit or on macOS), the value falls back to when-searching
or never
(QtWebKit).url.auto_search
supports a new schemeless
value which always opens a
search unless the given URL includes an explicit scheme.t[Cc][Hh]
default bindings which work similarly to the t[Ss][Hh]
bindings for JavaScript but toggle cookie permissions.tor_identity
userscript now takes the password via a -p
flag and has
a new -c
flag to customize the Tor control port.logging.level.ram
and logging.level.console
to configure the default
logging levels via the config.fonts.tabs.selected
and fonts.tabs.unselected
to set the font of the
selected tab independently from unselected tabs (e.g. to make it bold).input.mouse.back_forward_buttons
which can be set to false
to disable
back/forward mouse buttons.:devtools
command (replacing :inspector
) with various improved
functionality:
:devtools left
(wIh
), bottom
(wIj
), top
(wIk
) or right
(wIl
). To show them in a new window, use :devtools window
(wIw
).
Using :devtools
(wi
) will open them at the last used position.qt5-webengine-devtools
package is missing, an error
is now shown instead of a blank inspector window.tabs.focus_stack_size
is set to -1.pdf.js
file for PDF.js exists, but viewer.html
does not.:completion-item-yank --sel
is used on a platform without
primary selection support (e.g. Windows/macOS).:config-write-py
now works with paths starting with ~/...
again.globalThis
in Qt <= 5.12 on Reddit
and Spotify.;
is added to hints.chars
, using hint labels containing ;;
now
works properly.bindings.key_mappings
is used with hints, it now works properly with
letters outside of ASCII as well.content.headers.user_agent
) exposed
to JS now requires a restart. The corresponding HTTP header is not affected.tox -e mkvenv
which was deprecated in qutebrowser v1.10.0 is now
removed. Use the mkvenv.py
script instead.config.bind(key, None)
in config.py
to unbind a
key was deprecated in v1.8.2 and is now removed. Use
config.unbind(key)
instead.:yank markdown
was deprecated in v1.7.0 and is now removed. Use
:yank inline [{title}]({url})
instead.:debug-keytester
command, which shows a "key tester" widget.
Previously, that was only available as a separate application via python3 -m scripts.keytester
.:config-diff
command which opens the qute://configdiff
page.--debug-flag log-cookies
to log cookies to the debug log.colors.contextmenu.disabled.{fg,bg}
settings to customize colors for
disabled items in the context menu.:toggle-selection --line
), bound to Shift-V
in caret mode.colors.webpage.darkmode.*
settings to control Chromium's dark mode.
Note that those settings only work with QtWebEngine on Qt >= 5.14 and require
a restart of qutebrowser.content.cookies.accept
setting now accepts URL patterns.misc/requirements/requirements-tests.txt{,-raw}
is supported.:tab-focus
command now has completion for tabs in the current window.bindings.key_mappings
setting now maps <Ctrl+I>
to the tab key by default.:tab-give --private
now detaches a tab into a new private window.:open -s
now only rewrites http://
in URLs to https://
, not other
schemes like qute://
.:inspector
now works correctly when cookies are disabled globally.QWebEngineFindTextResult
handling added in v1.11.0.v, v
) very early before a page is
loaded, an error is now shown instead of a crash happening.sessions.lazy_restore
so that the saved page is loaded instead of the
"stub" page with no possibility to get to the web page.colors.statusbar.url.warn.fg
). However, when the affected website was subsequently loaded again, the URL was mistakenly displayed as green (colors.statusbar.url.success_https
). While the user already has seen a certificate error prompt at this point (or set content.ssl_strict
to false
which is not recommended), this could still provide a false sense of security. This is now fixed.Note: The original source release accidentally contained a Python virtual environment in misc/requirements/testenv
as well as some other files (doc/changelog.html
, doc/faq.html
, misc/requirements/requirements-pyqt-5.15.txt-raw
). In the post1
release, those files are deleted, with no other changes.
search.wrap
which can be set to false to prevent wrapping around the page
when searching. With QtWebEngine, Qt 5.14 or newer is required.content.unknown_url_scheme_policy
which allows controlling when an
external application is opened for external links (never, from user
interaction, always).content.fullscreen.overlay_timeout
to configure how long the fullscreen
overlay should be displayed. If set to 0
, no overlay is displayed.hints.padding
to add additional padding for hints.hints.radius
to set a border radius for hints (set to 3
by default).url.searchengines
values:
{unquoted}
inserts the search term without any quoting.{semiquoted}
(same as {}
) quotes most special characters, but slashes
remain unquoted.{quoted}
(same as {}
in earlier releases) also quotes slashes.search.wrap
to false
to restore the old behavior.{}
placeholder for search engines (the url.searchengines
setting) now
does not quote slashes anymore, but other characters typically encoded in
URLs still get encoded. This matches the behavior of search engines in
Chromium. To revert to the old behavior, use {quoted}
instead.content.windowed_fullscreen
setting got renamed to
content.fullscreen.window
.qute-bitwarden
now has an optional --totp
flag which can be used
to copy TOTP codes to clipboard (requires the pyperclip
module).readability-js
now opens readability tabs next to the original
tab (using the :open --related
flag).readability-js
now displays a favicon for readability tabs.password_fill
now triggers a change
JavaScript event after filling the
data.dictcli.py
script now shows better error messages.mkvenv.py
script (mainly useful for development).unsafeWindow
is now defined for Greasemonkey scripts with QtWebKit.window
global is now shared between different
Greasemonkey scripts (but still separate from the page's window
), to
match the original Greasemonkey implementation.--output-messages
(-m
) flag added in v1.9.0 now also works correctly
when using :spawn --userscript
.:version
and --version
now don't crash if there's an (invalid)
/etc/os-release
file which has non-comment lines without a =
character.scripts/
now report errors to stderr
correctly, instead of
using stdout
.fonts.tabs
or fonts.debug_console
is
set to a value including default_size
.state
file contains invalid UTF-8 data, a proper error is now
displayed.webengine/Service Worker-bak
in qutebrowser's data
directory.mkvenv.py
now ensures the latest versions of setuptools
and wheel
are installed in the virtual environment, which should speed up installation
and fix install issues.colors.statusbar.command.private.bg
has been changed to a
slightly different gray, as a workaround for a Qt issue where the cursor was
invisible in that case.