/r/qutebrowser

Photograph via snooOG

A subreddit for qutebrowser - a keyboard-driven, vim-like browser based on Python and Qt.

A keyboard-driven browser.

Rules:

  1. Be polite and considerate, follow qutebrowser's Code of Conduct

  2. No spam allowed

  3. Posts must be related to qutebrowser

Official website

Github repository

Cheatsheet

Frequently asked questions

/r/qutebrowser

3,778 Subscribers

2

Cosmetic word filtering?

I use an extension to censor OCD trigger words on webpages in firefox. I know I can’t install extensions, but could something similar be achieved in qute?

Here’s the extension for those curious https://addons.mozilla.org/en-US/firefox/addon/advanced_profanity_filter/

2 Comments
2024/10/29
10:41 UTC

4

I made a userscript that sorts and rearranges tabs (manual or automatic sorting)

This userscript rearranges tabs in qutebrowser. Feel free to use it and if you have improvements they are very welcome.

I made it as response to this post:

I think it works well, although it is not extensively tested and I am sure there are cases I have not thought of where it breaks.

So it uses this userscript (zsh) which calls a python script (tried doing it in zsh at first but it was too complicated for me, in python it was easy).

notes

  • In this version it does not close the non-rearranged window. THis is because I don't trust the script yet, and I want to see the diff.
  • it uses linux
  • the manual sorting method uses your $EDITOR for the rearranging
  • fzfmenu.sh is just my wrapper around fzf (basically it spawns a terminal with fzf that takes input from the pipe) - you can use dmenu or whatever you like instead. the if statement just below is because my script adds an empty line at the beginning of the output, so I remove it. If you use another menu you do not need this.

#!/bin/zsh

# Define file paths
input_file="$HOME/.local/share/qutebrowser/sessions/tab-rearrange-input.yml"
temp_file="/tmp/tab-reorder.md"
output_file="$HOME/.local/share/qutebrowser/sessions/tab-rearrange-output.yml"

# remove input  and output
rm -f "$input_file" "$output_file"

qutebrowser ":session-save --only-active $input_file"

sleep 1s 

# Extract titles and URLs with indices to handle duplicates
yq -r '.windows[].tabs[].history[] | "\(.title) - \(.url)"' "$input_file" | nl -ba -w1 -s' ' > "$temp_file"
# make it zero-based index without looing the original index

choice1=$(echo -e 'sort how:\nmanual\nsort title\nsort title (reverse)\nsort url sort url (reverse)' | fzfmenu.sh --header-lines --popup) 
if [ ! "$(printf %s "$choice1" | sed -n '$=')" -eq 1 ]; then choice1=$(echo "$choice1" | tail -n +2); fi
if [ -z "$choice1" ]; then exit; fi
# echo "$choice1"

case "$choice1" in
    manual)
    # Open the extracted data in the editor
    alacritty --title 'qutebrowser tab-reorder popup' -e $EDITOR "$temp_file"
    ;;
    sort\ title)
    # Sort the extracted data by title
    cat "$temp_file" | sort -k2 
    sort\ title\ \(reverse\)
    echo 'yes'
esac

# remove empty lines
sed -i '/^$/d' "$temp_file"

python  $HOME/Dropbox/share/qutebrowser/in-use/userscripts/qutebrowser-rearrange-tabs-helper.py

sleep 1s

# Read the edited file
qutebrowser ":session-load $output_file"

and here's the helper script:


#!/usr/bin/env python3
import yaml

input_file = '$HOME/.local/share/qutebrowser/sessions/tab-rearrange-input.yml'
temp_file = '/tmp/tab-reorder.md'
output_file = '$HOME/.local/share/qutebrowser/sessions/tab-rearrange-output.yml'
# replace $HOME with the actual path
import os
input_file = os.path.expandvars(input_file)
output_file = os.path.expandvars(output_file)

# Read the new order of indices from the temp file
new_order_indices = []
with open(temp_file, 'r') as f:
    for line in f:
        index_str = line.strip().split()[0]
        if index_str.isdigit():
            new_order_indices.append(int(index_str))

# Read the original session data
with open(input_file, 'r') as f:
    data = yaml.safe_load(f)

# Process each window in the session
for window in data.get('windows', []):
    tabs = window.get('tabs', [])
    num_tabs = len(tabs)
    original_indices = set(range(num_tabs))
    remaining_indices = original_indices - set(new_order_indices)
    
    # Rearrange the tabs based on the new indices
    new_tabs = [tabs[i] for i in new_order_indices if i < num_tabs]
    # Append any tabs not in the edited list to the end
    new_tabs.extend([tabs[i] for i in sorted(remaining_indices)])
    window['tabs'] = new_tabs

# Write the modified session data to the output file
with open(output_file, 'w') as f:
    yaml.safe_dump(data, f)

print(f"Session data rearranged and saved to {output_file}")
0 Comments
2024/10/27
09:36 UTC

2

How do i set brave search as default ctrl+t?

1 Comment
2024/10/26
13:59 UTC

1

Move location of the config folder

Hi ! My config folder for qutebrowser is located at ~/.qutebrowser but I would love to move it to another location where I have all my config files for other softwares. I checked all the help pages but found nothing ..

2 Comments
2024/10/25
13:35 UTC

0

Is qutebrowser really worth to use in 2024?

it barely works in a Google docs and such as.

For today websites, the ad blocker is absolutely useless.

Is anybody using this browser as a daily driver?

37 Comments
2024/10/21
20:56 UTC

4

[Userscript] archive web pages to waybackmachine, archive.ph, and ghostarchive.org

You can find the post here: https://gist.github.com/YasserKa/9a02bc50e75e7239f6f0c8f04fe4cfb1

I submitted this post a week ago [1], and the post is visible on my end, but for some reason other users can't view it, so I am re-posting it again using a gist.

[1] https://www.reddit.com/r/qutebrowser/comments/1g1zbel/userscript_archive_web_pages_to_waybackmachine/

Edit: It's the reddit post is visible thanks to the compiler

1 Comment
2024/10/21
09:25 UTC

4

¿Sorting currently open tabs?

(Windows 10)

I'd like to be able to access my currently open tabs programmatically in order to sort them.

As I understand it, batch userscripts can't continuously interface with qutebrowser, they're just given variables, allowed one final command to pass onto qb, and this then ends the script.

As per ww7k3v, if you're willing to reload all the tabs after modifying the session file, there may be a hack. But I just wanna sort them as if I've used tab-move multiple times.

6 Comments
2024/10/19
05:16 UTC

1

Arrow keys don't work in kagi.

Hello, i've been using qutebrowser the past few days and i love it, problem is, i've encountered a really frustrating problem with the search engine i use, kagi.

Kagi has a function that allows the user to scroll through the search results with the arrow (and j/k) keys but qutebrowser just won't let me do that.

When i try to use the arrow keys i just scroll through the page normally, and the kagi's search function doesn't work which is really frustrating.

It works fine on other browsers like firefox and looking online i can't find anyone facing the same problem.

3 Comments
2024/10/16
19:09 UTC

3

Yellow url in status bar

For some reason, links of www.reddit.com started showing as yellow in the status bar, which looking at the documentation means there's a warning.

But how can i find out what the actual warning is? There's not anything on :messages

3 Comments
2024/10/14
20:55 UTC

1

Userscript + IPC

I am trying to use the userscript functions with IPC commands to achieve the following behavior.

In a page with a list of links---such as a search result---, I call hints and forward them to a userscript. The first time, the userscript creates a new window and opens the URL on it without giving focus to it. The second time and later, the userscript finds the previous window and opens the URL in a new tab.

I cannot use the "last-focused" window because it is the one I am using. I pretend to open the windows using the "ipc" module from qutebrowser, which I already use to open new windows. The problem is that I do not find how to get a list of windows and how to specify a particular window through IPC.

If anybody has a suggestion on how to proceed to achieve the behavior I mention, please let me know. Thank you very much.

10 Comments
2024/10/14
03:58 UTC

42

qutebrowser v3.3.0/.1 released

I'm happy to announce that I just released qutebrowser v3.3.0, followed by v3.3.1 due to a few accidentally unpushed commits.

A short overview of future release plans:

  • v3.4.0 is coming very soon already (as soon as PyQt 6.8 is out and everything is ready from qutebrowser's side). Might be looking at a week or so potentially, but I decided to cut a release right away to get Qt 6.7.3 security fixes out to macOS/Windows binary users.
  • There might be a v3.4.1 with Qt 6.8.1 if timing permits (currently scheduled for November 21st; but GitHub drops macOS 12 support on December 3rd)
  • The next release after that will be v3.5.0, and it will remove support for macOS 12 Monterey and Python 3.8 (the latter might already be dropped in v3.4.0 if upstream dependencies require doing so).

Here is the combined changelog (.0 is missing the "Updated the workaround for Google sign-in issues." commit):

Added

  • Added the qt.workarounds.disable_hangouts_extension setting, for disabling the Google Hangouts extension built into Chromium/QtWebEngine.

Removed

  • Support for macOS 11 Big Sur is dropped. Binaries are now built on macOS 12 Monterey and are unlikely to still run on older macOS versions.
  • Failed end2end tests will now save screenshots of the browser window when run under xvfb (the default on linux). Screenshots will be under $TEMP/pytest-current/pytest-screenshots/ or attached to the GitHub actions run as an artifact. (#7625)

Changed

  • The qute-pass userscript now has better support for internationalized domain names when using the pass backend - both domain names and secret paths are normalized before comparing (#8133)
  • Ignored URL query parameters (via url.yank_ignored_parameters) are now respected when yanking any URL (for example, through hints with hint links yank). The {url:yank} substitution has also been added as a version of {url} that respects ignored URL query parameters. (#7879)
  • Windows and macOS releases now bundle Qt 6.7.3, which includes security fixes up to Chromium 129.0.6668.58.

Fixed

  • A minor memory leak of QItemSelectionModels triggered by closing the completion dialog has been resolved. (#7950)
  • The link to the chrome URL match pattern documentation in our settings docs now loads a live page again. (#8268)
  • A rare crash when on Qt 6, a renderer process terminates with an unknown termination reason.
  • Updated the workaround for Google sign-in issues.
0 Comments
2024/10/12
20:02 UTC

1

[Userscript] archive web pages to waybackmachine, archive.ph, and ghostarchive.org

With the following script, you can archive web pages on:

Setup:

Dependencies: selenium, requests python libraries

Script:

#!/usr/bin/env python
#
# Archive a web page to web.archive.org, archive.ph, and ghostarchive.org

import sys
import os

from requests import get
from requests.exceptions import HTTPError, RequestException

import threading
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


executable_path = f"{os.environ['XDG_CONFIG_HOME']}/google-chrome/chromedriver"


def archive_to_waybackmachine(url, tries=0):
    TIMEOUT = 30
    MAX_TRIES = 3
    api_url = f"http://web.archive.org/save/{url}"
    available_api_url = f"http://archive.org/wayback/available?url={url}"

    try:
        # Attempt to archive the page
        response = get(api_url, timeout=TIMEOUT)
        response.raise_for_status()

        # Check if the page was archived
        response = get(available_api_url, timeout=TIMEOUT)
        response.raise_for_status()

        if response.status_code == 200:
            snapshots = response.json().get("archived_snapshots", {})
            if not snapshots:
                show_message("Page not archived, trying again")
                if tries < MAX_TRIES:
                    return archive_to_waybackmachine(url, tries + 1)
                else:
                    show_message(
                        f"Max retries reached. Couldn't archive {url} to waybackmachine"
                    )

        show_message("Archived to waybackmachine")

    except (RequestException, HTTPError) as e:
        if tries < MAX_TRIES:
            show_message(f"Error: {e}. Retrying {tries+1}/{MAX_TRIES}")
            return archive_to_waybackmachine(url, tries + 1)
        show_message(
            f"Failed to archive {url} to waybackmachine after {MAX_TRIES} attempts."
        )


def show_message(message):
    # Show message in Qutebrowser
    if "QUTE_FIFO" in os.environ:
        with open(os.environ["QUTE_FIFO"], "w") as fifo:
            fifo.write(f"message-info '{message}'" + "\n")
            fifo.flush()
    else:
        print(message)


def archive_to_today(driver, link):
    driver.get("https://archive.ph/")
    WebDriverWait(driver, 10).until(
        lambda x: len(x.find_elements(By.CSS_SELECTOR, "#submiturl")) > 0
    )

    driver.find_element(By.CSS_SELECTOR, "#submiturl  input[id=url]").send_keys(link)
    driver.find_element(By.CSS_SELECTOR, "#submiturl  input[type=submit]").click()

    WebDriverWait(driver, 5 * 60).until(
        lambda x: len(x.find_elements(By.ID, "HEADER")) > 0
    )

    # If it's archived, archive it again
    if len(driver.find_elements(By.ID, "DIVALREADY2")) >= 1:
        driver.find_element(By.CSS_SELECTOR, "#DIVALREADY2 input[type=submit]").click()
        WebDriverWait(driver, 5 * 60).until(
            lambda x: len(x.find_elements(By.ID, "HEADER")) > 0
        )

    if len(driver.find_elements(By.ID, "HEADER")) == 0:
        show_message("Page not archived to archive.ph")

    show_message("archived to archive today")


def archive_to_ghost(driver, link):
    driver.get("https://ghostarchive.org/")
    WebDriverWait(driver, 10).until(
        lambda x: len(x.find_elements(By.ID, "archive")) > 0
    )

    driver.find_element(By.ID, "archive").send_keys(link)
    driver.find_element(By.CSS_SELECTOR, "#archive ~ input[type=submit]").click()

    WebDriverWait(driver, 5 * 60).until(
        lambda x: len(x.find_elements(By.XPATH, ".//noscript")) > 0
    )
    show_message("Archived to ghostarchive")
    driver.close()


def main(link):
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=new")
    options.add_argument("binary_location=/bin/google-chrome-stable")

    driver1 = webdriver.Chrome(
        service=Service(executable_path=executable_path), options=options
    )
    driver2 = webdriver.Chrome(
        service=Service(executable_path=executable_path), options=options
    )
    threads_args = [
        [archive_to_today, [driver1, link]],
        [archive_to_ghost, [driver2, link]],
        [archive_to_waybackmachine, [link]],
    ]

    for args in threads_args:
        threading.Thread(target=args[0], args=(args[1])).start()


if len(sys.argv) < 2:
    print("Usage: python archive.py <url>")
    sys.exit(1)

main(sys.argv[1])

In config.py for qutebrowser, add the following to archive web pages and go to them.

c.aliases = {
    "archive_page": "spawn --userscript /path/to/archive_web_page {url}",
    "goto_archive_page": "open -t https://web.archive.org/{url}",
    "goto_archive_page_today": "open -t https://archive.ph/newest/{url}",
    "goto_archive_page_ghost": "open -t https://ghostarchive.org/search?term={url}",
}

Could also be used outside of Qutebrowser archive_web_page <url>

If you know of other public free services for archiving web pages, let me know, and I will support it in the script.

0 Comments
2024/10/12
12:44 UTC

3

spotify not loading

I get this error when trying to run spotify:

"

Playback of protected content is not enabled.

Visit Spotify Support to learn how to enable playback in your browser.

"

according to spotify, in chrome you should set:

"Under Protected content, switch on Allow site to play protected content."

3 Comments
2024/10/07
10:09 UTC

3

Where is the bookmarks file/folder in Windows?

Hi all! So I've been using qutebrowser for the past month or so and I've been really liking it so far. I have it installed on both my Arch linux machine, as well as my Windows machine. I wanted to sync my bookmarks between the two machines using SyncThing, however, I'm having some trouble finding where the bookmarks file is saved in Windows. Does anyone know where the default location of it is?

4 Comments
2024/10/04
08:22 UTC

3

Canvas: Software only. Hardware acceleration disabled

First of all, great work on qutebrowser. I've been using it as my main browser in the last few days and it has reignited my passion for simply browsing the web. It's amazing.

With that said, I can't find a way to enable canvas hardware acceleration.

If I open chrome://gpu in qutebrowser, this is what I get:

https://preview.redd.it/te53ttyk1zrd1.png?width=836&format=png&auto=webp&s=7dc7559f8f5057f214d38c94bc4342e93b9ee5f9

this is what I have in my config.py and didn't make a difference:

https://preview.redd.it/2s7s0k3p1zrd1.png?width=655&format=png&auto=webp&s=4a311848dfd22f957e23acbd84c56194cb7cc45e

this is when I open chrome://gpu in the same computer using brave:

https://preview.redd.it/ygzl4vwr1zrd1.png?width=651&format=png&auto=webp&s=bad3ef03476c6a41089bad54811dcf9bc67aa675

Any hints?

4 Comments
2024/09/30
16:17 UTC

3

Reverse-search history

Hi,

is it possible to reverse-search the history of visited websites? I feel like this open Issue wanted to go into a similar direction (But in the end didnt ...)

I am thinking of something similar to Ctrl-R in a modern terminal, where I e.g. know that I am interested in the most recent "Stack Overflow" page I visited but I would have to press Shift-H 10 times to get there, so a "<Ctrl-R>stack<Enter>" would get me there.

I know that I could do it by pressing "Sh" and select it from the history manually, but that would require far more effort, and using <Ctrl-R> would be quite intuitive as it already has an analogous function in the terminal.

Thanks for coming to my TED Talk

2 Comments
2024/09/30
16:08 UTC

5

Yank hinted URL visible text

Hi! is it possible to hint urls and yank its visible text?

0 Comments
2024/09/30
14:14 UTC

2

Can't load https://docs.amd.com. Any workarounds?

I'm new to qutebrowser. What a great browser! However, one of my go-to sites won't load:

https://docs.amd.com

Does anybody know of any workarounds that I can try to get this to work?

5 Comments
2024/09/21
07:45 UTC

12

whaddya think about my qutebrowser config?

7 Comments
2024/09/21
03:45 UTC

2

NSS error code: -8018 - can't handle windy.com

Platform: Linux on an inovato Quadra mini-pc.

When qutebrowser is opened in Terminal it shows this error: NSS error code: -8018

qutebrowser opens but can't handle windy.com - 1. The time is wrong in windy.com but shows correct on the desktop, 2. In a partial-screen window - dragging the map bounces back, 3. Switching to full screen fails - only the content of the smaller window is shown - the rest is black, 4. Closing and re-opening full screen works but there are odd rectangular artifacts all over the screen and it's constantly flashing them - a few then many then a few. I'm not finding much info about this error. Anyone have any ideas, please? Thanks.

5 Comments
2024/09/19
22:00 UTC

11

How to fix missing hints on reddit ?

6 Comments
2024/09/16
14:10 UTC

5

How can I enable touchpad gestures such as pinch to zoom and forward/back navigation in wayland

I've tried setting c.qt.args = ["ozone-platform-hint=wayland"] and c.qt.force_platform = "wayland"

Neither seem to work.

0 Comments
2024/09/13
16:02 UTC

2

Youtube Music - Search Issue

4 Comments
2024/09/12
13:08 UTC

1

is it possible to change the color of the url in the insert mode?

i use gruvbox theme for qutebrowser, and its blue color for "insert mode" line at the bottom looks really ugly with the grey page URL. is it possible to configure the color of the url when entering a mode (such as visual, caret or insert)?

3 Comments
2024/09/10
19:11 UTC

4

Qutebrowser on framebuffer for embedded systems

I'm working on a project that would require Qutebrowser to run on the linux frame buffer and and be controlled by a keyboard.

So far I've found that I can get Qutebrowser to load by setting the environmental arguments QT_QPA_PLATFRORM="linuxfb:fb=/dev/fb0"

but, I cannot interact with the browser or underlying system as the keyboard inputs are no longer captured.

I've been reading the Qt docs here and here, and have tried setting QT_QPA_KEYBOARD_PARAMETERS="grab=1:/dev/input/event0" and QT_QPA_FB_DISABLE_INPUT="1"

in an attempt to force the use of Qt's evdev tools as apposed to libinput and specifically use the keyboard.

So far no luck, and I have to hard boot the system to get back to a terminal.

0 Comments
2024/09/10
06:54 UTC

2

Is there any way to set a solo picture as startpage ?

I really need to set a picture .jpg as a startpage?

4 Comments
2024/09/10
00:58 UTC

2

The keepass userscripts

So i use keepassXC and i was looking into making the experience of logging in easier, so there's two userscripts on the qutebrowser repo:

https://github.com/qutebrowser/qutebrowser/blob/main/misc/userscripts/qute-keepass
https://github.com/qutebrowser/qutebrowser/blob/main/misc/userscripts/qute-keepassxc

Now obviously one would think that it's the keepassxc userscript, but i'm wondering if the other one works too with keepassxc?
Because the first one looks like all you have to do is to install pykeepass while the other has a lot of steps to get it ready.

I wouldn't feel the need for this if i didn't get logged out from some websites because it's a bit weird, like reddit NEVER logs out, or whatsapp web, or my ISP site to watch TV, but if it's like a shop that i don't visit that often, i can login and a couple of hours later the session expired and i don't know why it happens.

0 Comments
2024/09/09
22:20 UTC

2

[Userscript] Youtube transcribe

Humans extract info from text faster than from video, especially when the info I care about are spread out. I wrote a userscript that opens a free service [1] that transcribes the video, able to follow the timestamp, and has limited AI summarizing feature. I was thinking of using youtube-transcript-api · PyPI and open the text in a text editor; this makes searching text better, but it will lack following timestamps and AI summarization features (you can use another AI service for this).

Sometimes, you need to refresh the page because they get flagged as a bot.

#!/usr/bin/env bash
#
# Use video transcription service on youtube video

URL_ROOT="$(echo "$QUTE_URL" | awk -F '/' '{print $3}')"

[[ "$URL_ROOT" != "www.youtube.com" ]] \
  && echo "message-info 'Not youtube video'" >> "$QUTE_FIFO" \
  && exit 0

ID="$(echo "$QUTE_URL" | tr "?&#" "\n" | grep "^v=" | cut -d "=" -f 2)"

echo "open -t https://www.youtube-transcript.io/videos/$ID" >>"$QUTE_FIFO"

P.S. if you know of a better YouTube transcript service, let me know.

[1] Free YouTube Transcript Extractor - Download Subtitles & Captions Easily

2 Comments
2024/09/08
13:50 UTC

5

how to create a key binding for ":tab-give" and have the window list open

I am trying to make moving tabs from one window to another a bit easier. I find it too slow and cumbersome to type ":tab-give " an then type the win_id of the window I want to current tab to be moved to.

What I want to do is to create two key-bindings, gT and tT.

gT

  • behave as if I typed ":tab-give" followed by "space", which brings up the window list

tT

  • behave as if I typed ":tab-take" followed by "space", which brings up the tab list

I don't know the syntax of the keybinding to make this work.

4 Comments
2024/09/05
07:24 UTC

1

broken css stylesheets in qutebrowser

o/

i decided to install custom css (solarized-light) via:

c.content.user_stylesheets = ['~/clonebay/solarized-everything-css/css/solarized-light/solarized-light-all-sites.css']

but it looks horrible. i even disabled the dark mode, but its still ugly.

my system: Fedora 40, i use i3wm. tried multiple solutions at this point but they all failed.
here's my config.py: https://pastebin.com/tjLNpEM6

https://preview.redd.it/uhgxhnyi4rmd1.png?width=964&format=png&auto=webp&s=e41dfcfcb697ed72f82031e5d4b145ba6b57647a

2 Comments
2024/09/04
08:21 UTC

Back To Top