Frequently asked questions
==========================
:title: Frequently asked questions
The Compiler <mail@qutebrowser.org>

[qanda]
What is qutebrowser based on?::
    qutebrowser uses https://www.python.org/[Python], https://www.qt.io/[Qt] and
    https://www.riverbankcomputing.com/software/pyqt/intro[PyQt].
+
The concept of it is largely inspired by https://bitbucket.org/portix/dwb/[dwb]
and http://www.vimperator.org/vimperator[Vimperator]. Many actions and
key bindings are similar to dwb.

Why another browser?::
    It might be hard to believe, but I didn't find any browser which I was
    happy with, so I started to write my own. Also, I needed a project to get
    into writing GUI applications with Python and
    link:https://www.qt.io/[Qt]/link:https://www.riverbankcomputing.com/software/pyqt/intro[PyQt].
+
Read the next few questions to find out why I was unhappy with existing
software.

What's wrong with link:https://bitbucket.org/portix/dwb/[dwb]/link:https://sourceforge.net/projects/vimprobable/[vimprobable]/link:https://mason-larobina.github.io/luakit/[luakit]/jumanji/... (projects based on WebKitGTK)?::
    Most of them are based on the https://webkitgtk.org/[WebKitGTK+]
    https://webkitgtk.org/reference/webkitgtk/stable/index.html[WebKit1] API,
    which causes a lot of crashes. As the GTK API using WebKit1 is
    https://lists.webkit.org/pipermail/webkit-gtk/2014-March/001821.html[deprecated],
    these bugs are never going to be fixed.
+
When qutebrowser was created, the newer
https://webkitgtk.org/reference/webkit2gtk/stable/index.html[WebKit2 API] lacked
basic features like proxy support, and almost no projects have started porting
to WebKit2. In the meantime, this situation has improved a bit, but there are
still only a few projects which have some kind of WebKit2 support (see the
https://github.com/qutebrowser/qutebrowser#similar-projects[list of
alternatives]).
+
qutebrowser uses https://www.qt.io/[Qt] and
https://wiki.qt.io/QtWebEngine[QtWebEngine] by default (and supports
https://wiki.qt.io/QtWebKit[QtWebKit] optionally). QtWebEngine is based on
Google's https://www.chromium.org/Home[Chromium]. With an up-to-date Qt, it has
much more man-power behind it than WebKitGTK+ has, and thus supports more modern
web features - it's also arguably more secure.

What's wrong with https://www.mozilla.org/en-US/firefox/new/[Firefox] and link:http://bug.5digits.org/pentadactyl/[Pentadactyl]/link:http://www.vimperator.org/vimperator[Vimperator]?::
    Firefox likes to break compatibility with addons on each upgrade, gets
    slower and more bloated with every upgrade, and has some
    https://blog.mozilla.org/advancingcontent/2014/02/11/publisher-transformation-with-users-at-the-center/[horrible
    ideas] lately.
+
Also, developing addons for it is a nightmare.

What's wrong with https://www.chromium.org/Home[Chromium] and https://vimium.github.io/[Vimium]?::
    The Chrome plugin API doesn't seem to allow much freedom for plugin
    writers, which results in Vimium not really having all the features you'd
    expect from a proper minimal, vim-like browser.

Why Python?::
    I enjoy writing Python since 2011, which made it one of the possible
    choices. I wanted to use https://www.qt.io/[Qt] because of
    https://wiki.qt.io/QtWebKit[QtWebKit] so I didn't have
    https://wiki.qt.io/Category:LanguageBindings[many other choices]. I don't
    like C++ and can't write it very well, so that wasn't an alternative.

But isn't Python too slow for a browser?::
    https://www.infoworld.com/d/application-development/van-rossum-python-not-too-slow-188715[No.]
    I believe efficiency while coding is a lot more important than efficiency
    while running. Also, most of the heavy lifting of qutebrowser is done by Qt
    and WebKit in C++, with the
    https://wiki.python.org/moin/GlobalInterpreterLock[GIL] released.

Is qutebrowser secure?::
    Most security issues are in the backend (which handles networking,
    rendering, JavaScript, etc.) and not qutebrowser itself.
+
qutebrowser uses https://wiki.qt.io/QtWebEngine[QtWebEngine] by default.
QtWebEngine is based on Google's https://www.chromium.org/Home[Chromium]. While
Qt only updates to a new Chromium release on every minor Qt release (all ~6
months), every patch release backports security fixes from newer Chromium
versions. In other words: As long as you're using an up-to-date Qt, you should
be recieving security updates on a regular basis, without qutebrowser having to
do anything. Chromium's process isolation and
https://chromium.googlesource.com/chromium/src/+/master/docs/design/sandbox.md[sandboxing]
features are also enabled as a second line of defense.
+
https://wiki.qt.io/QtWebKit[QtWebKit] is also supported as an alternative
backend, but hasn't seen new releases
https://github.com/annulen/webkit/releases[in a while]. It also doesn't have any
process isolation or sandboxing. See
https://github.com/qutebrowser/qutebrowser/issues/4039[#4039] for more details.
+
Security issues in qutebrowser's code happen very rarely (as per July 2018,
there have been three security issues caused by qutebrowser in over 4.5 years).
Those were handled appropriately
(http://seclists.org/oss-sec/2018/q3/29[example]) and fixed timely. To report
security bugs, please contact me directly at mail@qutebrowser.org, GPG ID
https://www.the-compiler.org/pubkey.asc[0x916eb0c8fd55a072].

Is there an adblocker?::
    There is a host-based adblocker which takes /etc/hosts-like lists. A "real"
    adblocker has a
    https://www.reddit.com/r/programming/comments/25j41u/adblock_pluss_effect_on_firefoxs_memory_usage/chhpomw[big
    impact] on browsing speed and
    https://blog.mozilla.org/nnethercote/2014/05/14/adblock-pluss-effect-on-firefoxs-memory-usage/[RAM
    usage], so implementing support for AdBlockPlus-like lists is currently not
    a priority.

How can I get No-Script-like behavior?::
    To disable JavaScript by default:
+
----
:set content.javascript.enabled false
----
+
The basic command for enabling JavaScript for the current host is `tsh`.
This will allow JavaScript execution for the current session.
Use `S` instead of `s` to make the exception permanent.
With `H` instead of `h`, subdomains are included.
With `u` instead of `h`, only the current URL is whitelisted (not the whole host).

How do I play Youtube videos with mpv?::
    You can easily add a key binding to play youtube videos inside a real video
    player - optionally even with hinting for links:
+
----
:bind m spawn mpv {url}
:bind M hint links spawn mpv {hint-url}
----
+
Note that you might need an additional package (e.g.
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"
functionality. This way you can add links to the mpv playlist instead of
playing them all at once.
+
You can find the script here: https://github.com/mpv-player/mpv/blob/master/TOOLS/umpv
+
It also works nicely with rapid hints:
+
----
:bind m spawn umpv {url}
:bind M hint links spawn umpv {hint-url}
:bind ;M hint --rapid links spawn umpv {hint-url}
----

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]
    for details. You can do this in your `mailcap` file to get a proper
    extension:
+
----
    text/html; qutebrowser %s; nametemplate=%s.html
----

What is the difference between bookmarks and quickmarks?::
    Bookmarks will always use the title of the website as their name, but with quickmarks
    you can set your own title.
+
For example, if you bookmark multiple food recipe websites and use `:open`,
you have to type the title or address of the website.
+
When using quickmark, you can give them all names, like
`foodrecipes1`, `foodrecipes2` and so on. When you type
`:open foodrecipes`, you will see a list of all the food recipe sites,
without having to remember the exact website title or address.

How do I use spell checking?::
	Configuring spell checking in qutebrowser depends on the backend in use
    (see https://github.com/qutebrowser/qutebrowser/issues/700[#700] for
	a more detailed discussion).
+
For QtWebKit:

. Install https://github.com/QupZilla/qtwebkit-plugins[qtwebkit-plugins].
  . Note: with QtWebKit reloaded you may experience some issues. See
    https://github.com/QupZilla/qtwebkit-plugins/issues/10[#10].
. The dictionary to use is taken from the `DICTIONARY` environment variable.
  The default is `en_US`. For example to use Dutch spell check set `DICTIONARY`
  to `nl_NL`; you can't use multiple dictionaries or change them at runtime at
  the moment.
  (also see the README file for `qtwebkit-plugins`).
. Remember to install the hunspell dictionaries if you don't have them already
  (most distros should have packages for this).

+
For QtWebEngine:

. Make sure your versions of PyQt and Qt are 5.8 or higher.
. Use `dictcli.py` script to install dictionaries.
  Run the script with `-h` for the parameter description.
. Set `spellcheck.languages` to the desired list of languages, e.g.:
  `:set spellcheck.languages "['en-US', 'pl-PL']"`

How do I use Tor with qutebrowser?::
    Start tor on your machine, and do `:set content.proxy socks://localhost:9050/`
    in qutebrowser. Note this won't give you the same amount of fingerprinting
    protection that the Tor Browser does, but it's useful to be able to access
    `.onion` sites.

Why does J move to the next (right) tab, and K to the previous (left) one?::
    One reason is because https://bitbucket.org/portix/dwb[dwb] did it that way,
    and qutebrowser's keybindings are designed to be compatible with dwb's.
    The rationale behind it is that J is "down" in vim, and K is "up", which
    corresponds nicely to "next"/"previous". It also makes much more sense with
    vertical tabs (e.g. `:set tabs.position left`).

What's the difference between insert and passthrough mode?::
    They are quite similar, but insert mode has some bindings (like `Ctrl-e` to
    open an editor) while passthrough mode only has escape bound. It might also
    be useful to rebind escape to something else in passthrough mode only, to be
    able to send an escape keypress to the website.

Why takes it longer to open an URL in qutebrowser than in chromium?::
    When opening an URL in an existing instance the normal qutebrowser
    Python script is started and a few PyQt libraries need to be
    loaded until it is detected that there is an instance running
    where the URL is then passed to. This takes some time.
    One workaround is to use this
    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 an unix socket to qutebrowser (if its
    running already) using socat which is much faster and starts a new
    qutebrowser if it is not running already. Also check if you want
    to use webengine as backend in line 17 and change it to your
    needs.

How do I make qutebrowser use greasemonkey scripts?::
    There is currently no UI elements to handle managing greasemonkey scripts.
    All management of what scripts are installed or disabled is done in the
    filesystem by you. qutebrowser reads all files that have an extension of
    `.js` from the `<data>/greasemonkey/` folder and attempts to load them.
    Where `<data>` is the qutebrowser data directory shown in the `Paths`
    section of the page displayed by `:version`. If you want to disable a
    script just rename it, for example, to have `.disabled` on the end, after
    the `.js` extension. To reload scripts from that directory run the command
    `:greasemonkey-reload`.
+
Troubleshooting: to check that your script is being loaded when
`:greasemonkey-reload` runs you can start qutebrowser with the arguments
`--debug --logfilter greasemonkey,js` and check the messages on the
program's standard output for errors parsing or loading your script.
You may also see javascript errors if your script is expecting an environment
that we fail to provide.
+
Note that there are some missing features which you may run into:

. Some scripts expect `GM_xmlhttpRequest` to ignore Cross Origin Resource
  Sharing restrictions, this is currently not supported, so scripts making
  requests to third party sites will often fail to function correctly.
. If your backend is a QtWebEngine version 5.8, 5.9 or 5.10 then regular
  expressions are not supported in `@include` or `@exclude` rules. If your
  script uses them you can re-write them to use glob expressions or convert
  them to `@match` rules.
  See https://wiki.greasespot.net/Metadata_Block[the wiki] for more info.
. Any greasemonkey API function to do with adding UI elements is not currently
  supported. That means context menu extentensions and background pages.

== Troubleshooting

Unable to view flash content.::
    If you have flash installed for on your system, it's necessary to enable plugins
    to use the flash plugin. Using the command `:set content.plugins true`
    in qutebrowser will enable plugins. Packages for flash should
    be provided for your platform or it can be obtained from
    https://get.adobe.com/flashplayer/[Adobe].

Experiencing freezing on sites like duckduckgo and youtube.::
    This issue could be caused by stale plugin files installed by `mozplugger`
    if mozplugger was subsequently removed.
    Try exiting qutebrowser and removing `~/.mozilla/plugins/mozplugger*.so`.
    See https://github.com/qutebrowser/qutebrowser/issues/357[Issue #357]
    for more details.

When using QtWebEngine, qutebrowser reports "Render Process Crashed" and the console prints a traceback on Gentoo Linux or another Source-Based Distro::
    As stated in https://gcc.gnu.org/gcc-6/changes.html[GCC's Website] GCC 6 has introduced some optimizations that could break non-conforming codebases, like QtWebEngine. +
    As a workaround, you can disable the nullpointer check optimization by adding the -fno-delete-null-pointer-checks flag while compiling. +
    On gentoo, you just need to add it into your make.conf, like this: +

    CFLAGS="... -fno-delete-null-pointer-checks"
    CXXFLAGS="... -fno-delete-null-pointer-checks"
+
And then re-emerging qtwebengine with: +

    emerge -1 qtwebengine

Unable to view DRM content (Netflix, Spotify, etc.).::
    You will need to install `widevine` and set `qt.args` to point to it.
    Qt 5.9 currently only supports widevine up to Chrome version 61.
+
On Arch, simply install `qt5-webengine-widevine` from the AUR and run:
+
----
:set qt.args '["ppapi-widevine-path=/usr/lib/qt/plugins/ppapi/libwidevinecdmadapter.so"]'
:restart
----
+
For other distributions, download the chromium tarball and widevine-cdm zip from
https://aur.archlinux.org/packages/qt5-webengine-widevine/[the AUR page],
extract `libwidevinecdmadapter.so` and `libwidevinecdm.so` files, respectively,
and move them to the `ppapi` plugin directory in your Qt library directory (create it if it does not exist).
+
Lastly, set your `qt.args` to point to that directory and restart qutebrowser:
+
----
:set qt.args '["ppapi-widevine-path=/usr/lib64/qt5/plugins/ppapi/libwidevinecdmadapter.so"]'
:restart
----

Unable to use `spawn` on MacOS.::
When running qutebrowser from the prebuilt binary (`qutebrowser.app`) it *will
not* read any files that would alter your `$PATH` (e.g. `.profile`, `.bashrc`,
etc). This is not a bug, just that `.profile` is not propogated to GUI
applications in MacOS.
+
See https://github.com/qutebrowser/qutebrowser/issues/4273[Issue #4273] for
details and potential workarounds.

My issue is not listed.::
    If you experience any segfaults or crashes, you can report the issue in
    https://github.com/qutebrowser/qutebrowser/issues[the issue tracker] or
    using the `:report` command.
    If you are reporting a segfault, make sure you read the
    link:stacktrace{outfilesuffix}[guide] on how to report them with all needed
    information.
