nixos-config/users/simon/modules/qutebrowser/default.nix

307 lines
10 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{ config, lib, nixosConfig, pkgs, ... }:
let
inherit ((import ../common.nix).colorschemes) solarized;
setOptionForeachPattern = option: value: patterns:
let
formatValue = value:
if lib.isBool value
then (if value then "True" else "False")
else
(if lib.isString value
then "r\"${value}\""
else (toString value));
in
lib.concatMapStringsSep
"\n"
(pattern: "config.set(\"${option}\", ${formatValue value}, \"${pattern}\")")
patterns;
permissionVideo = [
"https://chat.sbruder.de"
"https://meet.jalr.de"
];
permissionAudio = [
"https://app.sipgate.com"
] ++ permissionVideo; # capturing video almost always also requires capturing audio
permissionNotifications = [
"https://app.sipgate.com"
"https://chat.sbruder.de"
];
cookieExceptions = [
];
in
lib.mkIf nixosConfig.sbruder.gui.enable
{
programs.qutebrowser = {
enable = true;
package = pkgs.qutebrowser-qt6;
aliases = {
q = "tab-close"; # one tab
qa = "close"; # one window
"qa!" = "quit"; # everything
};
keyBindings = {
normal = {
",rm" = "spawn -u readability";
# reasonable tab cycling
J = "tab-prev";
K = "tab-next";
gJ = "tab-move -";
gK = "tab-move +";
# mpv
",mv" = "spawn mpv --profile=clear-speed {url}";
",ma" = "spawn mpv --player-operation-mode=pseudo-gui --ytdl-format=251/bestaudio/best {url}";
",mq" = "spawn umpv {url}";
",Mv" = "hint links spawn mpv --profile=clear-speed {hint-url}";
",Ma" = "hint links spawn mpv --player-operation-mode=pseudo-gui --ytdl-format=251/bestaudio/best {hint-url}";
",Mq" = "hint links spawn umpv {hint-url}";
};
};
searchEngines = {
DEFAULT = "https://bangs.sbruder.de/eval?engine=https://duckduckgo.com/?q=%25s&query={}";
};
settings = {
colors =
let
fgbg = fg: bg: { inherit fg bg; };
topbottom = colour: { top = colour; bottom = colour; };
in
with solarized; {
completion = rec {
fg = base1;
odd.bg = base02;
even.bg = base03;
match.fg = green;
scrollbar = fgbg base1 base03;
category = {
inherit (fgbg yellow base03) fg bg;
border = topbottom base03;
};
item.selected = {
inherit (fgbg base1 base01) fg bg;
border = topbottom base01;
inherit match;
};
};
contextmenu = {
disabled = fgbg base0 base02;
menu = fgbg base1 base03;
selected = fgbg base1 base01;
};
downloads = {
bar.bg = base03;
start = fgbg base03 blue;
stop = fgbg base03 cyan;
error.fg = red;
};
hints = {
inherit (fgbg base03 yellow) fg bg;
match.fg = base1;
};
keyhint = {
inherit (fgbg base1 base03) fg bg;
suffix.fg = base1;
};
messages = {
error = {
inherit (fgbg base03 red) fg bg;
border = red;
};
warning = {
inherit (fgbg base03 violet) fg bg;
border = violet;
};
info = {
inherit (fgbg base1 base03) fg bg;
border = base03;
};
};
prompts = {
inherit (fgbg base1 base03) fg bg;
border = base03;
selected = fgbg base1 base01;
};
statusbar = {
normal = fgbg green base03;
insert = fgbg base03 blue;
passthrough = fgbg base03 cyan;
private = fgbg base03 base02;
command = {
inherit (fgbg base1 base03) fg bg;
private = fgbg base1 base03;
};
caret = {
inherit (fgbg base03 violet) fg bg;
selection = fgbg base03 blue;
};
progress.bg = blue;
url.fg = base1;
url.error.fg = red;
url.hover.fg = base1;
url.success.http.fg = cyan;
url.success.https.fg = green;
url.warn.fg = violet;
};
tabs = rec {
bar.bg = base03;
even = fgbg base1 base03;
odd = even;
indicator = {
start = blue;
stop = cyan;
error = red;
};
selected = rec {
even = fgbg base02 green;
odd = even;
};
pinned = {
inherit even odd selected;
};
};
};
# UI
scrolling.smooth = true;
completion.web_history.max_items = 0; # no history
# Fonts
fonts = {
web = {
family = rec {
serif = "Georgia";
sans_serif = "PT Sans";
standard = sans_serif;
};
};
};
# Behaviour
auto_save.session = true;
session.lazy_restore = true;
content.autoplay = false;
downloads = {
location.directory = "/tmp";
open_dispatcher = "${pkgs.xdg-utils}/bin/xdg-open"; # QDesktopServices.openUrl always opens Firefox
};
editor.command = [ "foot" "-e" "nvim" "-f" "{file}" "-c" "normal {line}G{column0}l" ];
spellcheck.languages = [ "de-DE" "en-GB" ];
url.default_page = "about:blank";
url.start_pages = [ "about:blank" ];
# Privacy
content.cookies.accept = "no-3rdparty";
content.headers.user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0";
content.headers.accept_language = "en-US,en;q=0.5";
# Filtering (many dont get used yet due to lack of cosmetic filtering)
# https://github.com/gorhill/uBlock/blob/master/assets/assets.json
# EasyList is using a mirror because upstreams servers are slow
content.blocking.adblock.lists = [
"https://secure.fanboy.co.nz/easylist.txt"
"https://secure.fanboy.co.nz/easyprivacy.txt"
"https://secure.fanboy.co.nz/fanboy-social.txt"
"https://easylist-downloads.adblockplus.org/easylistgermany.txt"
"https://filters.adtidy.org/extension/ublock/filters/17.txt"
"https://filters.adtidy.org/extension/ublock/filters/3.txt"
"https://filters.adtidy.org/extension/ublock/filters/4.txt"
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/annoyances.txt"
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/badlists.txt"
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/badware.txt"
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters.txt"
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/privacy.txt"
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/resource-abuse.txt"
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/unbreak.txt"
"https://secure.fanboy.co.nz/fanboy-annoyance.txt"
"https://secure.fanboy.co.nz/fanboy-antifacebook.txt"
"https://secure.fanboy.co.nz/fanboy-cookiemonster.txt"
];
};
extraConfig = /* python */ ''
import glob
c.content.user_stylesheets = glob.glob("${config.xdg.configHome}/qutebrowser/userstyles/*.css")
c.qt.environ = {
# otherwise results in severe banding (https://github.com/qutebrowser/qutebrowser/issues/5528)
"QT_WAYLAND_DISABLE_WINDOWDECORATION": "0",
}
c.content.headers.custom = {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
}
c.tabs.padding["top"] = 3
c.tabs.padding["bottom"] = 3
# Permissions
${setOptionForeachPattern "content.media.audio_capture" true permissionAudio}
${setOptionForeachPattern "content.media.audio_video_capture" true permissionVideo}
${setOptionForeachPattern "content.media.video_capture" true permissionVideo}
${setOptionForeachPattern "content.notifications.enabled" true permissionNotifications}
# Cookie exceptions
${setOptionForeachPattern "content.cookies.accept" "all" cookieExceptions}
'';
};
xdg.configFile =
let
replaceExtension = newExtension: filename: "${lib.concatStringsSep "." (lib.init (lib.splitString "." filename))}.${newExtension}";
regularFilesIn = dir: lib.filterAttrs
(_: v: v == "regular")
(builtins.readDir (./. + "/${dir}"));
compileScss = name: file: pkgs.runCommand (replaceExtension "css" name) { } ''
${pkgs.sassc}/bin/sassc ${file} $out
'';
in
{
"qutebrowser/bookmarks/urls".source = config.lib.file.mkOutOfStoreSymlink "${config.xdg.dataHome}/qutebrowser/synced-bookmarks/bookmarks";
"qutebrowser/quickmarks".source = config.lib.file.mkOutOfStoreSymlink "${config.xdg.dataHome}/qutebrowser/synced-bookmarks/quickmarks";
} // (lib.mapAttrs'
(k: _: lib.nameValuePair "qutebrowser/greasemonkey/${k}" { source = ./userscripts + "/${k}"; })
(regularFilesIn "userscripts")) // (lib.mapAttrs'
(k: _: lib.nameValuePair "qutebrowser/userstyles/${replaceExtension "css" k}" { source = compileScss k (./userstyles + "/${k}"); })
(regularFilesIn "userstyles"));
xdg.dataFile = lib.mapAttrs'
(dict: sha256: lib.nameValuePair
"qutebrowser/qtwebengine_dictionaries/${dict}.bdic"
{
source = (pkgs.fetchurl {
url = "https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries/+/18e09b9197a3b1d771c077c530d1a4ebad04c167/${dict}.bdic?format=TEXT";
inherit sha256;
postFetch = ''
base64 -d "$out" > "$TMPDIR/decoded"
mv "$TMPDIR/decoded" "$out"
'';
});
})
{
"de-DE-3-0" = "sha256-B2pHBwDb0Kpiu4s9JMNOE0C9/oPLvPwDXOly8jwUBAA=";
"en-GB-9-0" = "sha256-c8eaQQ+AkgwpsFX3upB9k0A7BajBfQDo5wVO22L3Maw=";
};
home.packages = [
(pkgs.writeShellScriptBin "qbmarks" /* bash */ ''
set -euo pipefail
git() {
echo "[$] git $@"
command git -C "${config.xdg.dataHome}/qutebrowser/synced-bookmarks" "$@"
}
git commit --no-gpg-sign -a -m "Sync on $(hostname)" || true
git pull --rebase --no-gpg-sign
git push
'')
];
}