commit fd07491bbd29b11f7ede88d90d0e3e41619f1294 Author: Ricard Illa Date: Tue Jan 18 09:32:55 2022 +0100 initial commit diff --git a/capibara.nix b/capibara.nix new file mode 100644 index 0000000..2cb94ea --- /dev/null +++ b/capibara.nix @@ -0,0 +1,151 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page +# and in the NixOS manual (accessible by running ‘nixos-help’). + +{ config, pkgs, ... }: + +let + impermanence = builtins.fetchTarball { + url = "https://github.com/nix-community/impermanence/archive/master.tar.gz"; + }; +in { + imports = [ # Include the results of the hardware scan. + ./nixos/hardware-configuration/capibara.nix + ./nixos/common.nix + "${impermanence}/nixos.nix" + ]; + + fileSystems = { + "/" = { + device = "tmpfs"; + fsType = "tmpfs"; + options = [ "defaults" "size=2G" "mode=755" ]; + }; + + "/persist/system" = { + device = "/dev/mapper/system"; + fsType = "btrfs"; + options = [ "subvol=persist" "compress=zstd" ]; + neededForBoot = true; + }; + + "/persist/user" = { + device = "/dev/mapper/user"; + fsType = "btrfs"; + options = [ "subvol=persist" "compress=zstd" ]; + neededForBoot = true; + }; + + "/nix" = { + device = "/dev/mapper/system"; + fsType = "btrfs"; + options = [ "subvol=nix" "compress=zstd" ]; + }; + + "/boot" = { + device = "/dev/mapper/system"; + fsType = "btrfs"; + options = [ "subvol=boot" "compress=zstd" ]; + }; + + "/swap" = { + device = "/dev/mapper/system"; + fsType = "btrfs"; + options = [ "subvol=swap" ]; + }; + + }; + + swapDevices = [{ device = "/swap/swapfile"; }]; + + environment.persistence."/persist/system" = { + directories = [ + "/var/log" + "/var/lib/bluetooth" + "/var/lib/systemd/coredump" + "/var/lib/docker" + ]; + files = [ + "/etc/machine-id" + #"/etc/nix/id_rsa" + "/etc/ssh/ssh_host_ed25519_key" + "/etc/ssh/ssh_host_ed25519_key.pub" + "/etc/ssh/ssh_host_rsa_key" + "/etc/ssh/ssh_host_rsa_key.pub" + "/etc/wireguard/wg0" + ]; + }; + + environment.persistence."/persist/user" = { + directories = [ + "/etc/NetworkManager/system-connections" + "/etc/nixos" + "/var/lib/libvirt" + ]; + files = [ + "/etc/wireguard/wg0" + ]; + }; + + networking.networkmanager.wifi.macAddress = "CC:AF:78:75:29:32"; + + nixpkgs.config.allowUnfree = true; + programs.steam.enable = true; + + boot = { + + loader = { + grub = { + efiSupport = false; + efiInstallAsRemovable = false; + enable = true; + version = 2; + device = "/dev/disk/by-id/ata-KINGSTON_SKC600MS512G_50026B7783FC3D2F"; + enableCryptodisk = true; + }; + }; + initrd = { + luks.devices = { + system = { + device = "/dev/disk/by-uuid/a5837435-d55e-4506-b256-e5c707d205c3"; + keyFile = "/root_keyfile.bin"; + }; + user = { + device = "/dev/disk/by-uuid/0fdb839e-dee8-4374-81e6-4455cfc3ae39"; + keyFile = "/data_keyfile.bin"; + }; + }; + secrets = { + "/root_keyfile.bin" = "/boot/root_keyfile.bin"; + "/data_keyfile.bin" = "/boot/data_keyfile.bin"; + }; + }; + }; + + networking = { + hostName = "capibara"; + interfaces = { + eno0.useDHCP = true; + wlp2s0.useDHCP = true; + }; + }; + + services.udev.extraRules = '' + # UDEV rules for Teensy USB devices + ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1" + ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1" + SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666" + KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666" + ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE="664", GROUP="plugdev" + ''; + + hardware.opengl.enable = true; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "21.05"; # Did you read the comment? +} diff --git a/echidna.nix b/echidna.nix new file mode 100644 index 0000000..717fd15 --- /dev/null +++ b/echidna.nix @@ -0,0 +1,210 @@ +{ config, pkgs, ... }: + +let + home-manager = builtins.fetchTarball { + url = "https://github.com/nix-community/home-manager/archive/master.tar.gz"; + }; + choose-pass = + pkgs.callPackage ./macos/choose-pass.nix { inherit config pkgs; }; +in { + imports = [ "${home-manager}/nix-darwin" ]; + + # List packages installed in system profile. To search by name, run: + # $ nix-env -qaP | grep wget + # environment.systemPackages = [ ]; + environment.systemPackages = [ + choose-pass + pkgs.coreutils-full + pkgs.curl + pkgs.fzf + pkgs.gnupg + pkgs.google-cloud-sdk + pkgs.htop + pkgs.jq + pkgs.mosh + pkgs.pass + pkgs.ripgrep + pkgs.terraform + pkgs.wireguard + pkgs.yubikey-personalization + ]; + + # Use a custom configuration.nix location. + # $ darwin-rebuild switch -I darwin-config=$HOME/.config/nixpkgs/darwin/configuration.nix + # environment.darwinConfig = "$HOME/configs/nix/darwin-configuration.nix"; + + # Auto upgrade nix package and the daemon service. + services.nix-daemon.enable = true; + # nix.package = pkgs.nix; + + # Create /etc/bashrc that loads the nix-darwin environment. + programs.zsh.enable = true; # default shell on catalina + # programs.fish.enable = true; + + # Used for backwards compatibility, please read the changelog before changing. + # $ darwin-rebuild changelog + + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + + homebrew = { + enable = true; + autoUpdate = true; + cleanup = "zap"; + global = { + brewfile = true; + noLock = true; + }; + casks = [ "kmbmpdc" "librewolf" ]; + brews = [ "mpd" "choose-gui" "vitetris" ]; + taps = + [ "homebrew/bundle" "homebrew/cask" "homebrew/core" "homebrew/services" ]; + }; + + fonts = { + enableFontDir = true; + fonts = [ + (pkgs.nerdfonts.override { fonts = [ "Hack" "MPlus" ]; }) + pkgs.inter + pkgs.hack-font + pkgs.libertinus + ]; + }; + + users.users.rilla = { + name = "rilla"; + home = "/Users/rilla"; + }; + + services.yabai = { + enable = true; + package = pkgs.yabai; + # enableScriptingAddition = true; + enableScriptingAddition = false; + config = { + external_bar = "all:28:0"; + layout = "bsp"; + auto_balance = "off"; + mouse_modifier = "fn"; + mouse_action1 = "move"; + mouse_action2 = "resize"; + mouse_follows_focus = "on"; + focus_follows_mouse = "autoraise"; + window_topmost = "on"; # floating windows always on top + window_shadow = "float"; + window_opacity = "on"; + active_window_opacity = "1.0"; + normal_window_opacity = "1.0"; + window_border = "on"; + window_border_width = 8; + active_window_border_color = "0xff458588"; + normal_window_border_color = "0xff504945"; + }; + extraConfig = '' + yabai -m rule --add app="^choose" manage=off + ''; + }; + + services.skhd = { + enable = true; + package = pkgs.skhd; + skhdConfig = '' + # ctrl + alt - return : osascript /Users/rilla/configs/scripts/osascripts/iterm.scpt + ctrl + alt - return : ${pkgs.alacritty}/bin/alacritty + + ctrl + alt - 1 : yabai -m space --focus 1 + ctrl + alt - 2 : yabai -m space --focus 2 + ctrl + alt - 3 : yabai -m space --focus 3 + ctrl + alt - 4 : yabai -m space --focus 4 + ctrl + alt - 5 : yabai -m space --focus 5 + ctrl + alt - 6 : yabai -m space --focus 6 + ctrl + alt - 7 : yabai -m space --focus 7 + ctrl + alt - 8 : yabai -m space --focus 8 + ctrl + alt - 9 : yabai -m space --focus 9 + ctrl + alt - 0 : yabai -m space --focus 10 + + ctrl + alt - n : yabai -m window --focus next || yabai -m window --focus first + ctrl + alt - p : yabai -m window --focus prev || yabai -m window --focus last + + ctrl + alt + shift - r : yabai -m space --rotate 90 + + ctrl + alt + shift - 1 : yabai -m window --space 1 + ctrl + alt + shift - 2 : yabai -m window --space 2 + ctrl + alt + shift - 3 : yabai -m window --space 3 + ctrl + alt + shift - 4 : yabai -m window --space 4 + ctrl + alt + shift - 5 : yabai -m window --space 5 + ctrl + alt + shift - 6 : yabai -m window --space 6 + ctrl + alt + shift - 7 : yabai -m window --space 7 + ctrl + alt + shift - 8 : yabai -m window --space 8 + ctrl + alt + shift - 9 : yabai -m window --space 9 + + # ctrl + alt + shift - space : yabai -m space --balance + ctrl + alt - space : yabai -m space --layout $(yabai -m query --spaces --space | jq -r 'if .["type"] == "bsp" then "float" else "bsp" end') + ctrl + alt - b : yabai -m space --balance + ctrl + alt + shift - space : yabai -m space --layout bsp + + # ctrl + alt + shift - c : yabai -m window --close + + ctrl + alt - right : yabai -m space --focus next || yabai -m space --focus first + ctrl + alt - left : yabai -m space --focus prev || yabai -m space --focus last + + ctrl + alt - h : yabai -m window --focus west + ctrl + alt - l : yabai -m window --focus east + ctrl + alt - j : yabai -m window --focus south + ctrl + alt - k : yabai -m window --focus north + + ctrl + alt + shift - h : yabai -m window --swap west + ctrl + alt + shift - l : yabai -m window --swap east + ctrl + alt + shift - j : yabai -m window --swap south + ctrl + alt + shift - k : yabai -m window --swap north + + ctrl + alt - e : yabai -m display --focus 1 + ctrl + alt - w : yabai -m display --focus 2 + + ctrl + alt - g : yabai -m space --toggle gap && yabai -m space --toggle padding + + ctrl + alt - x : yabai -m space --mirror y-axis + ctrl + alt - y : yabai -m space --mirror x-axis + + ctrl + alt - m : yabai -m window --toggle zoom-fullscreen + ctrl + alt - t : yabai -m window --toggle float + + :: choose + ctrl + alt - a ; choose + choose < p : skhd -k 'escape'; ${choose-pass}/bin/choose-pass + choose < escape ; default + + play : ${pkgs.mpc_cli}/bin/mpc toggle + ''; + }; + + services.spacebar = { + enable = true; + package = pkgs.spacebar; + config = { + position = "top"; + height = 28; + spacing_left = 25; + spacing_right = 25; + text_font = ''"Inter:Regular:12.0"''; + icon_font = ''"Font Awesome 5 Free:Solid:12.0"''; + background_color = "0xff282828"; + foreground_color = "0xffebdbb2"; + + space_icon_color = "0xff83a598"; + space_icon = "•"; + space_icon_strip = "1 2 3 4 5 6 7 8 9 10"; + + power_icon_strip = " "; + + clock_icon = ""; + clock_format = ''"%d/%m/%y %R"''; + }; + }; + + home-manager.users.rilla = import ./home/macos.nix; + + system.stateVersion = 4; +} diff --git a/home/alacritty/common.nix b/home/alacritty/common.nix new file mode 100644 index 0000000..7ee1f71 --- /dev/null +++ b/home/alacritty/common.nix @@ -0,0 +1,55 @@ +{ config, pkgs, ... }: + +{ + programs.alacritty = { + enable = true; + settings = { + background_opacity = 0.9; + colors = { + primary = { + background = "#282828"; + foreground = "#ebdbb2"; + }; + normal = { + black = "#282828"; + red = "#cc241d"; + green = "#98971a"; + yellow = "#d79921"; + blue = "#458588"; + magenta = "#b16286"; + cyan = "#689d6a"; + white = "#ebdbb2"; + }; + bright = { + black = "#928374"; + red = "#fb4934"; + green = "#b8bb26"; + yellow = "#fabd2f"; + blue = "#83a598"; + magenta = "#d3869b"; + cyan = "#8ec07c"; + white = "#ebdbb2"; + }; + }; + font = { + normal = { + family = "Hack Nerd Font"; + style = "Regular"; + }; + bold = { + family = "Hack Nerd Font"; + style = "Bold"; + }; + italic = { + family = "Hack Nerd Font"; + style = "Italic"; + }; + }; + selection = { save_to_clipboard = true; }; + shell = { + program = "${pkgs.tmux}/bin/tmux"; + args = [ "-u" ]; + }; + }; + }; +} diff --git a/home/alacritty/default.nix b/home/alacritty/default.nix new file mode 100644 index 0000000..d413926 --- /dev/null +++ b/home/alacritty/default.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + programs.alacritty = { + settings = { + font = { + offset = { + x = 0; + y = 0; + }; + size = 7; + }; + }; + }; +} diff --git a/home/alacritty/macos.nix b/home/alacritty/macos.nix new file mode 100644 index 0000000..1f728a4 --- /dev/null +++ b/home/alacritty/macos.nix @@ -0,0 +1,135 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + programs.alacritty = { + settings = { + font = { + offset = { + x = 1; + y = 0; + }; + size = 13; + + }; + window = { + padding = { + x = 5; + y = 5; + }; + decorations = "none"; + }; + + key_bindings = [ + {key = "Key0"; mods = "Command"; action = "ResetFontSize";} + {key = "Key0"; mods = "Control"; action = "ResetFontSize";} + {key = "Equals"; mods = "Command"; action = "IncreaseFontSize";} + {key = "Equals"; mods = "Control"; action = "IncreaseFontSize";} + {key = "Minus"; mods = "Control"; action = "DecreaseFontSize";} + {key = "A"; mods = "Control"; chars = "\\x01";} + {key = "B"; mods = "Control"; chars = "\\x02";} + {key = "C"; mods = "Control"; chars = "\\x03";} + {key = "D"; mods = "Control"; chars = "\\x04";} + {key = "E"; mods = "Control"; chars = "\\x05";} + {key = "F"; mods = "Control"; chars = "\\x06";} + {key = "G"; mods = "Control"; chars = "\\x07";} + {key = "H"; mods = "Control"; chars = "\\x08";} + {key = "I"; mods = "Control"; chars = "\\x09";} + {key = "J"; mods = "Control"; chars = "\\x0A";} + {key = "K"; mods = "Control"; chars = "\\x0B";} + {key = "L"; mods = "Control"; chars = "\\x0C";} + {key = "M"; mods = "Control"; chars = "\\x0D";} + {key = "N"; mods = "Control"; chars = "\\x0E";} + {key = "O"; mods = "Control"; chars = "\\x0F";} + {key = "P"; mods = "Control"; chars = "\\x10";} + {key = "Q"; mods = "Control"; chars = "\\x11";} + {key = "R"; mods = "Control"; chars = "\\x12";} + {key = "S"; mods = "Control"; chars = "\\x13";} + {key = "T"; mods = "Control"; chars = "\\x14";} + {key = "U"; mods = "Control"; chars = "\\x15";} + {key = "V"; mods = "Control"; chars = "\\x16";} + {key = "W"; mods = "Control"; chars = "\\x17";} + {key = "X"; mods = "Control"; chars = "\\x18";} + {key = "Y"; mods = "Control"; chars = "\\x19";} + {key = "Z"; mods = "Control"; chars = "\\x1A";} + {key = "Key6"; mods = "Control|Shift"; chars = "\\x1E";} # Control + ^ + {key = "Minus"; mods = "Control|Shift"; chars = "\\x1F";} # Control + _ + {key = "A"; mods = "Alt"; chars = "\\x1ba";} + {key = "B"; mods = "Alt"; chars = "\\x1bb";} + {key = "C"; mods = "Alt"; chars = "\\x1bc";} + {key = "D"; mods = "Alt"; chars = "\\x1bd";} + {key = "E"; mods = "Alt"; chars = "\\x1be";} + {key = "F"; mods = "Alt"; chars = "\\x1bf";} + {key = "G"; mods = "Alt"; chars = "\\x1bg";} + {key = "H"; mods = "Alt"; chars = "\\x1bh";} + {key = "I"; mods = "Alt"; chars = "\\x1bi";} + {key = "J"; mods = "Alt"; chars = "\\x1bj";} + {key = "K"; mods = "Alt"; chars = "\\x1bk";} + {key = "L"; mods = "Alt"; chars = "\\x1bl";} + {key = "M"; mods = "Alt"; chars = "\\x1bm";} + {key = "N"; mods = "Alt"; chars = "\\x1bn";} + {key = "O"; mods = "Alt"; chars = "\\x1bo";} + {key = "P"; mods = "Alt"; chars = "\\x1bp";} + {key = "Q"; mods = "Alt"; chars = "\\x1bq";} + {key = "R"; mods = "Alt"; chars = "\\x1br";} + {key = "S"; mods = "Alt"; chars = "\\x1bs";} + {key = "T"; mods = "Alt"; chars = "\\x1bt";} + {key = "U"; mods = "Alt"; chars = "\\x1bu";} + {key = "V"; mods = "Alt"; chars = "\\x1bv";} + {key = "W"; mods = "Alt"; chars = "\\x1bw";} + {key = "X"; mods = "Alt"; chars = "\\x1bx";} + {key = "Y"; mods = "Alt"; chars = "\\x1by";} + {key = "Z"; mods = "Alt"; chars = "\\x1bz";} + {key = "A"; mods = "Alt|Shift"; chars = "\\x1bA";} + {key = "B"; mods = "Alt|Shift"; chars = "\\x1bB";} + {key = "C"; mods = "Alt|Shift"; chars = "\\x1bC";} + {key = "D"; mods = "Alt|Shift"; chars = "\\x1bD";} + {key = "E"; mods = "Alt|Shift"; chars = "\\x1bE";} + {key = "F"; mods = "Alt|Shift"; chars = "\\x1bF";} + {key = "G"; mods = "Alt|Shift"; chars = "\\x1bG";} + {key = "H"; mods = "Alt|Shift"; chars = "\\x1bH";} + {key = "I"; mods = "Alt|Shift"; chars = "\\x1bI";} + {key = "J"; mods = "Alt|Shift"; chars = "\\x1bJ";} + {key = "K"; mods = "Alt|Shift"; chars = "\\x1bK";} + {key = "L"; mods = "Alt|Shift"; chars = "\\x1bL";} + {key = "M"; mods = "Alt|Shift"; chars = "\\x1bM";} + {key = "N"; mods = "Alt|Shift"; chars = "\\x1bN";} + {key = "O"; mods = "Alt|Shift"; chars = "\\x1bO";} + {key = "P"; mods = "Alt|Shift"; chars = "\\x1bP";} + {key = "Q"; mods = "Alt|Shift"; chars = "\\x1bQ";} + {key = "R"; mods = "Alt|Shift"; chars = "\\x1bR";} + {key = "S"; mods = "Alt|Shift"; chars = "\\x1bS";} + {key = "T"; mods = "Alt|Shift"; chars = "\\x1bT";} + {key = "U"; mods = "Alt|Shift"; chars = "\\x1bU";} + {key = "V"; mods = "Alt|Shift"; chars = "\\x1bV";} + {key = "W"; mods = "Alt|Shift"; chars = "\\x1bW";} + {key = "X"; mods = "Alt|Shift"; chars = "\\x1bX";} + {key = "Y"; mods = "Alt|Shift"; chars = "\\x1bY";} + {key = "Z"; mods = "Alt|Shift"; chars = "\\x1bZ";} + {key = "Key1"; mods = "Alt"; chars = "\\x1b1";} + {key = "Key2"; mods = "Alt"; chars = "\\x1b2";} + {key = "Key3"; mods = "Alt"; chars = "\\x1b3";} + {key = "Key4"; mods = "Alt"; chars = "\\x1b4";} + {key = "Key5"; mods = "Alt"; chars = "\\x1b5";} + {key = "Key6"; mods = "Alt"; chars = "\\x1b6";} + {key = "Key7"; mods = "Alt"; chars = "\\x1b7";} + {key = "Key8"; mods = "Alt"; chars = "\\x1b8";} + {key = "Key9"; mods = "Alt"; chars = "\\x1b9";} + {key = "Key0"; mods = "Alt"; chars = "\\x1b0";} + {key = "Space"; mods = "Control"; chars = "\\x00";} # Ctrl + Space + {key = "Grave"; mods = "Alt"; chars = "\\x1b`";} # Alt + ` + {key = "Grave"; mods = "Alt|Shift"; chars = "\\x1b~";} # Alt + ~ + {key = "Period"; mods = "Alt"; chars = "\\x1b.";} # Alt + . + {key = "Key8"; mods = "Alt|Shift"; chars = "\\x1b*";} # Alt + * + {key = "Key3"; mods = "Alt|Shift"; chars = "\\x1b#";} # Alt + # + {key = "Period"; mods = "Alt|Shift"; chars = "\\x1b>";} # Alt + > + {key = "Comma"; mods = "Alt|Shift"; chars = "\\x1b<";} # Alt + < + {key = "Minus"; mods = "Alt|Shift"; chars = "\\x1b_";} # Alt + _ + {key = "Key5"; mods = "Alt|Shift"; chars = "\\x1b%";} # Alt + % + {key = "Key6"; mods = "Alt|Shift"; chars = "\\x1b^";} # Alt + ^ + {key = "Backslash"; mods = "Alt"; chars = "\\x1b";} # Alt + \ + {key = "Backslash"; mods = "Alt|Shift"; chars = "\\x1b|";} # Alt + | + ]; + }; + }; +} diff --git a/home/arduino/default.nix b/home/arduino/default.nix new file mode 100644 index 0000000..ab7db62 --- /dev/null +++ b/home/arduino/default.nix @@ -0,0 +1,5 @@ +{ config, pkgs, ... }: + +{ + home.packages = [pkgs.arduino]; +} diff --git a/home/barrier/default.nix b/home/barrier/default.nix new file mode 100644 index 0000000..3381ae5 --- /dev/null +++ b/home/barrier/default.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +let + fingerprint = "CE:A0:28:27:D8:4E:43:4B:63:3A:A0:B3:00:F4:14:5B:DA:E2:17:3D"; +in +{ + services.barrier.client = { + enable = true; + # enableDragDrop = true; + enableCrypto = true; + name = "capibara"; + server = "echidna"; + }; + + home.file.".local/share/barrier/SSL/Fingerprints/TrustedServers.txt".text = "${fingerprint}\n"; +} diff --git a/home/browsers/default.nix b/home/browsers/default.nix new file mode 100644 index 0000000..ecbb60e --- /dev/null +++ b/home/browsers/default.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./firefox ]; + + home.packages = [ + pkgs.icecat-bin + ]; + + programs.chromium = { + enable = true; + package = pkgs.ungoogled-chromium; + }; +} diff --git a/home/browsers/firefox/arkenfox/0000.nix b/home/browsers/firefox/arkenfox/0000.nix new file mode 100644 index 0000000..a2d5838 --- /dev/null +++ b/home/browsers/firefox/arkenfox/0000.nix @@ -0,0 +1,6 @@ +/* 0000: disable about:config warning + * FF73-86: chrome://global/content/config.xhtml ***/ + { + "general.warnOnAboutConfig" = false; # XHTML version + "browser.aboutConfig.showWarning" = false; # HTML version [FF71+] +} diff --git a/home/browsers/firefox/arkenfox/0100.nix b/home/browsers/firefox/arkenfox/0100.nix new file mode 100644 index 0000000..0e8778d --- /dev/null +++ b/home/browsers/firefox/arkenfox/0100.nix @@ -0,0 +1,51 @@ +# [SECTION 0100]: STARTUP +{ + /* 0101: disable default browser check + * [SETTING] General>Startup>Always check if Firefox is your default browser ***/ + "browser.shell.checkDefaultBrowser" = false; + /* 0102: set startup page [SETUP-CHROME] + * 0=blank, 1=home, 2=last visited page, 3=resume previous session + * [NOTE] Session Restore is not used in PB mode (0110) and is cleared with history (2803, 2804) + * [SETTING] General>Startup>Restore previous session ***/ + "browser.startup.page" = 0; + /* 0103: set HOME+NEWWINDOW page + * about:home=Activity Stream (default, see 0105), custom URL, about:blank + * [SETTING] Home>New Windows and Tabs>Homepage and new windows ***/ + "browser.startup.homepage" = "about:blank"; + /* 0104: set NEWTAB page + * true=Activity Stream (default, see 0105), false=blank page + * [SETTING] Home>New Windows and Tabs>New tabs ***/ + "browser.newtabpage.enabled" = false; + "browser.newtab.preload" = false; + /* 0105: disable Activity Stream stuff (AS) + * AS is the default homepage/newtab in FF57+, based on metadata and browsing behavior. + * **NOT LISTING ALL OF THESE: USE THE PREFERENCES UI** + * [SETTING] Home>Firefox Home Content>... to show/hide what you want ***/ + /* 0105a: disable Activity Stream telemetry ***/ + "browser.newtabpage.activity-stream.feeds.telemetry" = false; + "browser.newtabpage.activity-stream.telemetry" = false; + /* 0105b: disable Activity Stream Snippets + * Runs code received from a server (aka Remote Code Execution) and sends information back to a metrics server + * [1] https://abouthome-snippets-service.readthedocs.io/ ***/ + "browser.newtabpage.activity-stream.feeds.snippets" = false; # [DEFAULT: false FF89+] + /* 0105c: disable Activity Stream Top Stories, Pocket-based and/or sponsored content ***/ + "browser.newtabpage.activity-stream.feeds.section.topstories" = false; + "browser.newtabpage.activity-stream.section.highlights.includePocket" = false; + "browser.newtabpage.activity-stream.showSponsored" = false; + "browser.newtabpage.activity-stream.feeds.discoverystreamfeed" = false; # [FF66+] + "browser.newtabpage.activity-stream.showSponsoredTopSites" = false; # [FF83+] + /* 0105e: clear default topsites + * [NOTE] This does not block you from adding your own ***/ + "browser.newtabpage.activity-stream.default.sites" = ""; + /* 0110: start Firefox in PB (Private Browsing) mode + * [NOTE] In this mode *all* windows are "private windows" and the PB mode icon is not displayed + * [WARNING] The P in PB mode is misleading: it means no "persistent" disk storage such as history, + * caches, searches, cookies, localStorage, IndexedDB etc (which you can achieve in normal mode). + * In fact, PB mode limits or removes the ability to control some of these, and you need to quit + * Firefox to clear them. PB is best used as a one off window (File>New Private Window) to provide + * a temporary self-contained new session. Close all Private Windows to clear the PB mode session. + * [SETTING] Privacy & Security>History>Custom Settings>Always use private browsing mode + * [1] https://wiki.mozilla.org/Private_Browsing + * [2] https://spreadprivacy.com/is-private-browsing-really-private/ ***/ + "browser.privatebrowsing.autostart" = true; + } diff --git a/home/browsers/firefox/arkenfox/0200.nix b/home/browsers/firefox/arkenfox/0200.nix new file mode 100644 index 0000000..422cdcb --- /dev/null +++ b/home/browsers/firefox/arkenfox/0200.nix @@ -0,0 +1,38 @@ +/*** [SECTION 0200]: GEOLOCATION / LANGUAGE / LOCALE ***/ +{ + /** GEOLOCATION ***/ + /* 0201: disable Location-Aware Browsing + * [NOTE] Best left at default "true", fingerprintable, already behind a prompt (see 0202) + * [1] https://www.mozilla.org/firefox/geolocation/ ***/ + # user_pref("geo.enabled", false); + /* 0202: set a default permission for Location (see 0201) [FF58+] + * 0=always ask (default), 1=allow, 2=block + * [NOTE] Best left at default "always ask", fingerprintable via Permissions API + * [SETTING] to add site exceptions: Ctrl+I>Permissions>Access Your Location + * [SETTING] to manage site exceptions: Options>Privacy & Security>Permissions>Location>Settings ***/ + # user_pref("permissions.default.geo", 2); + /* 0203: use Mozilla geolocation service instead of Google when geolocation is enabled [FF74+] + * Optionally enable logging to the console (defaults to false) ***/ + "geo.provider.network.url" = "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%"; + # user_pref("geo.provider.network.logging.enabled", true); // [HIDDEN PREF] + /* 0204: disable using the OS's geolocation service ***/ + "geo.provider.ms-windows-location" = false; # [WINDOWS] + "geo.provider.use_corelocation" = false; # [MAC] + "geo.provider.use_gpsd" = false; # [LINUX] + /* 0207: disable region updates + * [1] https://firefox-source-docs.mozilla.org/toolkit/modules/toolkit_modules/Region.html ***/ + "browser.region.network.url" = ""; # [FF78+] + "browser.region.update.enabled" = false; # [FF79+] + /* 0208: set search region + * [NOTE] May not be hidden if Firefox has changed your settings due to your region (see 0207) ***/ + # user_pref("browser.search.region", "US"); // [HIDDEN PREF] + + /** LANGUAGE / LOCALE ***/ + /* 0210: set preferred language for displaying web pages + * [TEST] https://addons.mozilla.org/about ***/ + "intl.accept_languages" = "en-US, en"; + /* 0211: use US English locale regardless of the system locale + * [SETUP-WEB] May break some input methods e.g xim/ibus for CJK languages [1] + * [1] https://bugzilla.mozilla.org/buglist.cgi?bug_id=867501,1629630 ***/ + "javascript.use_us_english_locale" = true; # [HIDDEN PREF] +} diff --git a/home/browsers/firefox/arkenfox/0300.nix b/home/browsers/firefox/arkenfox/0300.nix new file mode 100644 index 0000000..dee6159 --- /dev/null +++ b/home/browsers/firefox/arkenfox/0300.nix @@ -0,0 +1,87 @@ +/*** [SECTION 0300]: QUIET FOX + We only disable the auto-INSTALL of Firefox (app) updates. You still get prompts to update, + and it only takes one click. We highly discourage disabling auto-CHECKING for updates. + + Legitimate reasons to disable auto-INSTALLS include hijacked/monetized extensions, time + constraints, legacy issues, dev/testing, and fear of breakage/bugs. It is still important + to do updates for security reasons, please do so manually if you make changes. +***/ +{ + /* 0301: disable auto-INSTALLING Firefox updates [NON-WINDOWS FF65+] + * [NOTE] In FF65+ on Windows this SETTING (below) is now stored in a file and the pref was removed + * [SETTING] General>Firefox Updates>Check for updates but let you choose to install them ***/ + "app.update.auto" = false; + /* 0302: disable auto-INSTALLING Firefox updates via a background service [FF90+] [WINDOWS] + * [SETTING] General>Firefox Updates>Automatically install updates>When Firefox is not running + * [1] https://support.mozilla.org/kb/enable-background-updates-firefox-windows ***/ + "app.update.background.scheduling.enabled" = false; + /* 0303: disable auto-CHECKING for extension and theme updates ***/ + # user_pref("extensions.update.enabled", false); + /* 0304: disable auto-INSTALLING extension and theme updates (after the check in 0303) + * [SETTING] about:addons>Extensions>[cog-wheel-icon]>Update Add-ons Automatically (toggle) ***/ + # user_pref("extensions.update.autoUpdateDefault", false); + /* 0306: disable extension metadata + * used when installing/updating an extension, and in daily background update checks: + * when false, extension detail tabs will have no description ***/ + # user_pref("extensions.getAddons.cache.enabled", false); + /* 0308: disable search engine updates (e.g. OpenSearch) + * [NOTE] This does not affect Mozilla's built-in or Web Extension search engines ***/ + "browser.search.update" = false; + /* 0320: disable about:addons' Recommendations pane (uses Google Analytics) ***/ + "extensions.getAddons.showPane" = false; # [HIDDEN PREF] + /* 0321: disable recommendations in about:addons' Extensions and Themes panes [FF68+] ***/ + "extensions.htmlaboutaddons.recommendations.enabled" = false; + /* 0330: disable telemetry + * the pref (.unified) affects the behaviour of the pref (.enabled) + * IF unified=false then .enabled controls the telemetry module + * IF unified=true then .enabled ONLY controls whether to record extended data + * so make sure to have both set as false + * [NOTE] FF58+ 'toolkit.telemetry.enabled' is now LOCKED to reflect prerelease + * or release builds (true and false respectively) [2] + * [1] https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/internals/preferences.html + * [2] https://medium.com/georg-fritzsche/data-preference-changes-in-firefox-58-2d5df9c428b5 ***/ + "toolkit.telemetry.unified" = false; + "toolkit.telemetry.enabled" = false; # see [NOTE] + "toolkit.telemetry.server" = "data:,"; + "toolkit.telemetry.archive.enabled" = false; + "toolkit.telemetry.newProfilePing.enabled" = false; # [FF55+] + "toolkit.telemetry.shutdownPingSender.enabled" = false; # [FF55+] + "toolkit.telemetry.updatePing.enabled" = false; # [FF56+] + "toolkit.telemetry.bhrPing.enabled" = false; # [FF57+] Background Hang Reporter + "toolkit.telemetry.firstShutdownPing.enabled" = false; # [FF57+] + /* 0331: disable Telemetry Coverage + * [1] https://blog.mozilla.org/data/2018/08/20/effectively-measuring-search-in-firefox/ ***/ + "toolkit.telemetry.coverage.opt-out" = true; # [HIDDEN PREF] + "toolkit.coverage.opt-out" = true; # [FF64+] [HIDDEN PREF] + "toolkit.coverage.endpoint.base" = ""; + /* 0340: disable Health Reports + * [SETTING] Privacy & Security>Firefox Data Collection & Use>Allow Firefox to send technical... data ***/ + "datareporting.healthreport.uploadEnabled" = false; + /* 0341: disable new data submission, master kill switch [FF41+] + * If disabled, no policy is shown or upload takes place, ever + * [1] https://bugzilla.mozilla.org/1195552 ***/ + "datareporting.policy.dataSubmissionEnabled" = false; + /* 0342: disable Studies (see 0503) + * [SETTING] Privacy & Security>Firefox Data Collection & Use>Allow Firefox to install and run studies ***/ + "app.shield.optoutstudies.enabled" = false; + /* 0343: disable personalized Extension Recommendations in about:addons and AMO [FF65+] + * [NOTE] This pref has no effect when Health Reports (0340) are disabled + * [SETTING] Privacy & Security>Firefox Data Collection & Use>Allow Firefox to make personalized extension recommendations + * [1] https://support.mozilla.org/kb/personalized-extension-recommendations ***/ + "browser.discovery.enabled" = false; + /* 0350: disable Crash Reports ***/ + "breakpad.reportURL" = ""; + "browser.tabs.crashReporting.sendReport" = false; # [FF44+] + # user_pref("browser.crashReports.unsubmittedCheck.enabled", false); // [FF51+] [DEFAULT: false] + /* 0351: enforce no submission of backlogged Crash Reports [FF58+] + * [SETTING] Privacy & Security>Firefox Data Collection & Use>Allow Firefox to send backlogged crash reports ***/ + "browser.crashReports.unsubmittedCheck.autoSubmit2" = false; # [DEFAULT: false] + /* 0390: disable Captive Portal detection + * [1] https://www.eff.org/deeplinks/2017/08/how-captive-portals-interfere-wireless-security-and-privacy + * [2] https://wiki.mozilla.org/Necko/CaptivePortal ***/ + "captivedetect.canonicalURL" = ""; + "network.captive-portal-service.enabled" = false; # [FF52+] + /* 0391: disable Network Connectivity checks [FF65+] + * [1] https://bugzilla.mozilla.org/1460537 ***/ + "network.connectivity-service.enabled" = false; +} diff --git a/home/browsers/firefox/arkenfox/0400.nix b/home/browsers/firefox/arkenfox/0400.nix new file mode 100644 index 0000000..0379509 --- /dev/null +++ b/home/browsers/firefox/arkenfox/0400.nix @@ -0,0 +1,45 @@ +{ + /*** [SECTION 0400]: BLOCKLISTS / SAFE BROWSING (SB) ***/ + /** BLOCKLISTS ***/ + /* 0401: enforce Firefox blocklist + * [NOTE] It includes updates for "revoked certificates" + * [1] https://blog.mozilla.org/security/2015/03/03/revoking-intermediate-certificates-introducing-onecrl/ ***/ + "extensions.blocklist.enabled" = true; # [DEFAULT: true] + + /** SAFE BROWSING (SB) + Safe Browsing has taken many steps to preserve privacy. *IF* required, a full url is never + sent to Google, only a PART-hash of the prefix, and this is hidden with noise of other real + PART-hashes. Google also swear it is anonymized and only used to flag malicious sites. + Firefox also takes measures such as striping out identifying parameters and since SBv4 (FF57+) + doesn't even use cookies. (#Turn on browser.safebrowsing.debug to monitor this activity) + + [1] https://feeding.cloud.geek.nz/posts/how-safe-browsing-works-in-firefox/ + [2] https://wiki.mozilla.org/Security/Safe_Browsing + [3] https://support.mozilla.org/kb/how-does-phishing-and-malware-protection-work + ***/ + /* 0410: disable SB (Safe Browsing) + * [WARNING] Do this at your own risk! These are the master switches. + * [SETTING] Privacy & Security>Security>... "Block dangerous and deceptive content" ***/ + # // user_pref("browser.safebrowsing.malware.enabled", false); + # // user_pref("browser.safebrowsing.phishing.enabled", false); + /* 0411: disable SB checks for downloads (both local lookups + remote) + * This is the master switch for the safebrowsing.downloads* prefs (0412, 0413) + * [SETTING] Privacy & Security>Security>... "Block dangerous downloads" ***/ + # // user_pref("browser.safebrowsing.downloads.enabled", false); + /* 0412: disable SB checks for downloads (remote) + * To verify the safety of certain executable files, Firefox may submit some information about the + * file, including the name, origin, size and a cryptographic hash of the contents, to the Google + * Safe Browsing service which helps Firefox determine whether or not the file should be blocked + * [SETUP-SECURITY] If you do not understand this, or you want this protection, then override it ***/ + "browser.safebrowsing.downloads.remote.enabled" = false; + "browser.safebrowsing.downloads.remote.url" = ""; + /* 0413: disable SB checks for unwanted software + * [SETTING] Privacy & Security>Security>... "Warn you about unwanted and uncommon software" ***/ + # // user_pref("browser.safebrowsing.downloads.remote.block_potentially_unwanted", false); + # // user_pref("browser.safebrowsing.downloads.remote.block_uncommon", false); + /* 0419: disable 'ignore this warning' on SB warnings [FF45+] + * If clicked, it bypasses the block for that session. This is a means for admins to enforce SB + * [TEST] see github wiki APPENDIX A: Test Sites: Section 5 + * [1] https://bugzilla.mozilla.org/1226490 ***/ + # // user_pref("browser.safebrowsing.allowOverride", false); +} diff --git a/home/browsers/firefox/arkenfox/0500.nix b/home/browsers/firefox/arkenfox/0500.nix new file mode 100644 index 0000000..63d9151 --- /dev/null +++ b/home/browsers/firefox/arkenfox/0500.nix @@ -0,0 +1,43 @@ +{ + /*** [SECTION 0500]: SYSTEM ADD-ONS / EXPERIMENTS + System Add-ons are a method for shipping extensions, considered to be + built-in features to Firefox, that are hidden from the about:addons UI. + To view your System Add-ons go to about:support, they are listed under "Firefox Features" + + * Portable: "...\App\Firefox64\browser\features\" (or "App\Firefox\etc" for 32bit) + * Windows: "...\Program Files\Mozilla\browser\features" (or "Program Files (X86)\etc" for 32bit) + * Mac: "...\Applications\Firefox\Contents\Resources\browser\features\" + [NOTE] On Mac you can right-click on the application and select "Show Package Contents" + * Linux: "/usr/lib/firefox/browser/features" (or similar) + + [1] https://firefox-source-docs.mozilla.org/toolkit/mozapps/extensions/addon-manager/SystemAddons.html + [2] https://searchfox.org/mozilla-central/source/browser/extensions + ***/ + /* 0503: disable Normandy/Shield [FF60+] + * Shield is an telemetry system (including Heartbeat) that can also push and test "recipes" + * [1] https://wiki.mozilla.org/Firefox/Shield + * [2] https://github.com/mozilla/normandy ***/ + "app.normandy.enabled" = false; + "app.normandy.api_url" = ""; + /* 0505: disable System Add-on updates ***/ + "extensions.systemAddon.update.enabled" = false; # [FF62+] + "extensions.systemAddon.update.url" = ""; # [FF44+] + /* 0506: disable PingCentre telemetry (used in several System Add-ons) [FF57+] + * Currently blocked by 'datareporting.healthreport.uploadEnabled' (see 0340) ***/ + "browser.ping-centre.telemetry" = false; + /* 0515: disable Screenshots ***/ + # // user_pref("extensions.screenshots.disabled", true); // [FF55+] + /* 0517: disable Form Autofill + * [NOTE] Stored data is NOT secure (uses a JSON file) + * [NOTE] Heuristics controls Form Autofill on forms without @autocomplete attributes + * [SETTING] Privacy & Security>Forms and Autofill>Autofill addresses + * [1] https://wiki.mozilla.org/Firefox/Features/Form_Autofill ***/ + "extensions.formautofill.addresses.enabled" = false; # [FF55+] + "extensions.formautofill.available" = "off"; # [FF56+] + "extensions.formautofill.creditCards.available" = false; # [FF57+] + "extensions.formautofill.creditCards.enabled" = false; # [FF56+] + "extensions.formautofill.heuristics.enabled" = false; # [FF55+] + /* 0518: enforce disabling of Web Compatibility Reporter [FF56+] + * Web Compatibility Reporter adds a "Report Site Issue" button to send data to Mozilla ***/ + "extensions.webcompat-reporter.enabled" = false; # [DEFAULT: false] +} diff --git a/home/browsers/firefox/arkenfox/0600.nix b/home/browsers/firefox/arkenfox/0600.nix new file mode 100644 index 0000000..92a1258 --- /dev/null +++ b/home/browsers/firefox/arkenfox/0600.nix @@ -0,0 +1,19 @@ +{ + /*** [SECTION 0600]: BLOCK IMPLICIT OUTBOUND [not explicitly asked for - e.g. clicked on] ***/ + /* 0601: disable link prefetching + * [1] https://developer.mozilla.org/docs/Web/HTTP/Link_prefetching_FAQ ***/ + "network.prefetch-next" = false; + /* 0602: disable DNS prefetching + * [1] https://developer.mozilla.org/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control ***/ + "network.dns.disablePrefetch" = true; + # // user_pref("network.dns.disablePrefetchFromHTTPS", true); // [DEFAULT: true] + /* 0603: disable predictor / prefetching ***/ + "network.predictor.enabled" = false; + # // user_pref("network.predictor.enable-prefetch", false); // [FF48+] [DEFAULT: false] + /* 0605: disable link-mouseover opening connection to linked server + * [1] https://news.slashdot.org/story/15/08/14/2321202/how-to-quash-firefoxs-silent-requests ***/ + "network.http.speculative-parallel-limit" = 0; + /* 0606: enforce no "Hyperlink Auditing" (click tracking) + * [1] https://www.bleepingcomputer.com/news/software/major-browsers-to-prevent-disabling-of-click-tracking-privacy-risk/ ***/ + # // user_pref("browser.send_pings", false); // [DEFAULT: false] +} diff --git a/home/browsers/firefox/arkenfox/0700.nix b/home/browsers/firefox/arkenfox/0700.nix new file mode 100644 index 0000000..1878aaa --- /dev/null +++ b/home/browsers/firefox/arkenfox/0700.nix @@ -0,0 +1,53 @@ +{ + /*** [SECTION 0700]: HTTP* / TCP/IP / DNS / PROXY / SOCKS etc ***/ + /* 0701: disable IPv6 + * IPv6 can be abused, especially with MAC addresses, and can leak with VPNs. That's even + * assuming your ISP and/or router and/or website can handle it. Sites will fall back to IPv4 + * [STATS] Firefox telemetry (July 2021) shows ~10% of all connections are IPv6 + * [NOTE] This is just an application level fallback. Disabling IPv6 is best done at an + * OS/network level, and/or configured properly in VPN setups. If you are not masking your IP, + * then this won't make much difference. If you are masking your IP, then it can only help. + * [NOTE] PHP defaults to IPv6 with "localhost". Use "php -S 127.0.0.1:PORT" + * [TEST] https://ipleak.org/ + * [1] https://www.internetsociety.org/tag/ipv6-security/ (see Myths 2,4,5,6) ***/ + "network.dns.disableIPv6" = true; + /* 0702: disable HTTP2 + * HTTP2 raises concerns with "multiplexing" and "server push", does nothing to + * enhance privacy, and opens up a number of server-side fingerprinting opportunities. + * [WARNING] Don't disable HTTP2. Don't be that one person using HTTP1.1 on HTTP2 sites + * [STATS] ~46% of sites (July 2021) [5] + * [1] https://http2.github.io/faq/ + * [2] https://blog.scottlogic.com/2014/11/07/http-2-a-quick-look.html + * [3] https://http2.github.io/http2-spec/#rfc.section.10.8 + * [4] https://queue.acm.org/detail.cfm?id=2716278 + * [5] https://w3techs.com/technologies/details/ce-http2/all/all ***/ + # // user_pref("network.http.spdy.enabled", false); + # // user_pref("network.http.spdy.enabled.deps", false); + # // user_pref("network.http.spdy.enabled.http2", false); + # // user_pref("network.http.spdy.websockets", false); // [FF65+] + /* 0703: disable HTTP Alternative Services [FF37+] + * [SETUP-PERF] Relax this if you have FPI enabled (see 4000) *AND* you understand the + * consequences. FPI isolates these, but it was designed with the Tor protocol in mind, + * and the Tor Browser has extra protection, including enhanced sanitizing per Identity. + * [1] https://tools.ietf.org/html/rfc7838#section-9 + * [2] https://www.mnot.net/blog/2016/03/09/alt-svc ***/ + "network.http.altsvc.enabled" = false; + "network.http.altsvc.oe" = false; + /* 0704: set the proxy server to do any DNS lookups when using SOCKS + * e.g. in Tor, this stops your local DNS server from knowing your Tor destination + * as a remote Tor node will handle the DNS request + * [1] https://trac.torproject.org/projects/tor/wiki/doc/TorifyHOWTO/WebBrowsers ***/ + "network.proxy.socks_remote_dns" = true; + /* 0709: disable using UNC (Uniform Naming Convention) paths [FF61+] + * [SETUP-CHROME] Can break extensions for profiles on network shares + * [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/26424 ***/ + "network.file.disable_unc_paths" = true; # [HIDDEN PREF] + /* 0710: disable GIO as a potential proxy bypass vector + * Gvfs/GIO has a set of supported protocols like obex, network, archive, computer, dav, cdda, + * gphoto2, trash, etc. By default only smb and sftp protocols are accepted so far (as of FF64) + * [1] https://bugzilla.mozilla.org/1433507 + * [2] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/23044 + * [3] https://en.wikipedia.org/wiki/GVfs + * [4] https://en.wikipedia.org/wiki/GIO_(software) ***/ + "network.gio.supported-protocols" = ""; # [HIDDEN PREF] +} diff --git a/home/browsers/firefox/arkenfox/0800.nix b/home/browsers/firefox/arkenfox/0800.nix new file mode 100644 index 0000000..1e8e3f1 --- /dev/null +++ b/home/browsers/firefox/arkenfox/0800.nix @@ -0,0 +1,86 @@ +{ + /*** [SECTION 0800]: LOCATION BAR / SEARCH BAR / SUGGESTIONS / HISTORY / FORMS + Change items 0850 and above to suit for privacy vs convenience and functionality. Consider + your environment (no unwanted eyeballs), your device (restricted access), your device's + unattended state (locked, encrypted, forensic hardened). Likewise, you may want to check + the items cleared on shutdown in section 2800. + [1] https://xkcd.com/538/ + ***/ + /* 0801: disable location bar using search + * Don't leak URL typos to a search engine, give an error message instead. + * Examples: "secretplace,com", "secretplace/com", "secretplace com", "secret place.com" + * [NOTE] This does **not** affect explicit user action such as using search buttons in the + * dropdown, or using keyword search shortcuts you configure in options (e.g. 'd' for DuckDuckGo) + * [SETUP-CHROME] If you don't, or rarely, type URLs, or you use a default search + * engine that respects privacy, then you probably don't need this ***/ + "keyword.enabled" = false; + /* 0802: disable location bar domain guessing + * domain guessing intercepts DNS "hostname not found errors" and resends a + * request (e.g. by adding www or .com). This is inconsistent use (e.g. FQDNs), does not work + * via Proxy Servers (different error), is a flawed use of DNS (TLDs: why treat .com + * as the 411 for DNS errors?), privacy issues (why connect to sites you didn't + * intend to), can leak sensitive data (e.g. query strings: e.g. Princeton attack), + * and is a security risk (e.g. common typos & malicious sites set up to exploit this) ***/ + "browser.fixup.alternate.enabled" = false; + /* 0803: display all parts of the url in the location bar ***/ + "browser.urlbar.trimURLs" = false; + /* 0805: disable coloring of visited links - CSS history leak + * [SETUP-HARDEN] Bulk rapid history sniffing was mitigated in 2010 [1][2]. Slower and more expensive + * redraw timing attacks were largely mitigated in FF77+ [3]. Using RFP (4501) further hampers timing + * attacks. Don't forget clearing history on close (2803). However, social engineering [2#limits][4][5] + * and advanced targeted timing attacks could still produce usable results + * [1] https://developer.mozilla.org/docs/Web/CSS/Privacy_and_the_:visited_selector + * [2] https://dbaron.org/mozilla/visited-privacy + * [3] https://bugzilla.mozilla.org/1632765 + * [4] https://earthlng.github.io/testpages/visited_links.html (see github wiki APPENDIX A on how to use) + * [5] https://lcamtuf.blogspot.com/2016/08/css-mix-blend-mode-is-bad-for-keeping.html ***/ + # // user_pref("layout.css.visited_links_enabled", false); + /* 0807: disable live search suggestions + /* [NOTE] Both must be true for the location bar to work + * [SETUP-CHROME] Change these if you trust and use a privacy respecting search engine + * [SETTING] Search>Provide search suggestions | Show search suggestions in address bar results ***/ + "browser.search.suggest.enabled" = false; + "browser.urlbar.suggest.searches" = false; + /* 0810: disable location bar making speculative connections [FF56+] + * [1] https://bugzilla.mozilla.org/1348275 ***/ + "browser.urlbar.speculativeConnect.enabled" = false; + /* 0811: disable location bar leaking single words to a DNS provider **after searching** [FF78+] + * 0=never resolve single words, 1=heuristic (default), 2=always resolve + * [NOTE] For FF78 value 1 and 2 are the same and always resolve but that will change in future versions + * [1] https://bugzilla.mozilla.org/1642623 ***/ + "browser.urlbar.dnsResolveSingleWordsAfterSearch" = 0; + /* 0850a: disable location bar suggestion types + * [SETTING] Privacy & Security>Address Bar>When using the address bar, suggest ***/ + # // user_pref("browser.urlbar.suggest.history", false); + # // user_pref("browser.urlbar.suggest.bookmark", false); + # // user_pref("browser.urlbar.suggest.openpage", false); + # // user_pref("browser.urlbar.suggest.topsites", false); // [FF78+] + /* 0850b: disable tab-to-search [FF85+] + * Alternatively, you can exclude on a per-engine basis by unchecking them in Options>Search + * [SETTING] Privacy & Security>Address Bar>When using the address bar, suggest>Search engines ***/ + # // user_pref("browser.urlbar.suggest.engines", false); + /* 0850c: disable location bar dropdown + * This value controls the total number of entries to appear in the location bar dropdown ***/ + # // user_pref("browser.urlbar.maxRichResults", 0); + /* 0850d: disable location bar autofill + * [1] https://support.mozilla.org/kb/address-bar-autocomplete-firefox#w_url-autocomplete ***/ + # // user_pref("browser.urlbar.autoFill", false); + /* 0860: disable search and form history + * [SETUP-WEB] Be aware that autocomplete form data can be read by third parties [1][2] + * [NOTE] We also clear formdata on exit (see 2803) + * [SETTING] Privacy & Security>History>Custom Settings>Remember search and form history + * [1] https://blog.mindedsecurity.com/2011/10/autocompleteagain.html + * [2] https://bugzilla.mozilla.org/381681 ***/ + "browser.formfill.enable" = false; + /* 0862: disable browsing and download history + * [NOTE] We also clear history and downloads on exiting Firefox (see 2803) + * [SETTING] Privacy & Security>History>Custom Settings>Remember browsing and download history ***/ + # // user_pref("places.history.enabled", false); + /* 0870: disable Windows jumplist [WINDOWS] ***/ + "browser.taskbar.lists.enabled" = false; + "browser.taskbar.lists.frequent.enabled" = false; + "browser.taskbar.lists.recent.enabled" = false; + "browser.taskbar.lists.tasks.enabled" = false; + /* 0871: disable Windows taskbar preview [WINDOWS] ***/ + # // user_pref("browser.taskbar.previews.enable", false); // [DEFAULT: false] +} diff --git a/home/browsers/firefox/arkenfox/0900.nix b/home/browsers/firefox/arkenfox/0900.nix new file mode 100644 index 0000000..91ef34f --- /dev/null +++ b/home/browsers/firefox/arkenfox/0900.nix @@ -0,0 +1,35 @@ +{ + /*** [SECTION 0900]: PASSWORDS ***/ + /* 0901: disable saving passwords + * [NOTE] This does not clear any passwords already saved + * [SETTING] Privacy & Security>Logins and Passwords>Ask to save logins and passwords for websites ***/ + # // user_pref("signon.rememberSignons", false); + /* 0902: use a primary password + * There are no preferences for this. It is all handled internally. + * [SETTING] Privacy & Security>Logins and Passwords>Use a Primary Password + * [1] https://support.mozilla.org/kb/use-primary-password-protect-stored-logins-and-pas ***/ + /* 0903: set how often Firefox should ask for the primary password + * 0=the first time (default), 1=every time it's needed, 2=every n minutes (see 0904) ***/ + "security.ask_for_password" = 2; + /* 0904: set how often in minutes Firefox should ask for the primary password (see 0903) + * in minutes, default is 30 ***/ + "security.password_lifetime" = 5; + /* 0905: disable auto-filling username & password form fields + * can leak in cross-site forms *and* be spoofed + * [NOTE] Username & password is still available when you enter the field + * [SETTING] Privacy & Security>Logins and Passwords>Autofill logins and passwords + * [1] https://freedom-to-tinker.com/2017/12/27/no-boundaries-for-user-identities-web-trackers-exploit-browser-login-managers/ ***/ + "signon.autofillForms" = false; + /* 0909: disable formless login capture for Password Manager [FF51+] ***/ + "signon.formlessCapture.enabled" = false; + /* 0912: limit (or disable) HTTP authentication credentials dialogs triggered by sub-resources [FF41+] + * hardens against potential credentials phishing + * 0=don't allow sub-resources to open HTTP authentication credentials dialogs + * 1=don't allow cross-origin sub-resources to open HTTP authentication credentials dialogs + * 2=allow sub-resources to open HTTP authentication credentials dialogs (default) ***/ + "network.auth.subresource-http-auth-allow" = 1; + /* 0913: disable automatic authentication on Microsoft sites [FF91+] [WINDOWS 10+] + * [SETTING] Privacy & Security>Logins and Passwords>Allow Windows single sign-on for... + * [1] https://support.mozilla.org/kb/windows-sso ***/ + "network.http.windows-sso.enabled" = false; +} diff --git a/home/browsers/firefox/arkenfox/1000.nix b/home/browsers/firefox/arkenfox/1000.nix new file mode 100644 index 0000000..6c7d68e --- /dev/null +++ b/home/browsers/firefox/arkenfox/1000.nix @@ -0,0 +1,73 @@ +{ + /*** [SECTION 1000]: CACHE / SESSION (RE)STORE / FAVICONS + Cache tracking/fingerprinting techniques [1][2][3] require a cache. Disabling disk (1001) + *and* memory (1003) caches is one solution; but that's extreme and fingerprintable. A hardened + Temporary Containers configuration can effectively do the same thing, by isolating every tab [4]. + + We consider avoiding disk cache (1001) so cache is session/memory only (like Private Browsing + mode), and isolating cache to first party (4001) is sufficient and a good balance between + risk and performance. ETAGs can also be neutralized by modifying response headers [5], and + you can clear the cache manually or on a regular basis with an extension. + + [1] https://en.wikipedia.org/wiki/HTTP_ETag#Tracking_using_ETags + [2] https://robertheaton.com/2014/01/20/cookieless-user-tracking-for-douchebags/ + [3] https://www.grepular.com/Preventing_Web_Tracking_via_the_Browser_Cache + [4] https://medium.com/@stoically/enhance-your-privacy-in-firefox-with-temporary-containers-33925cd6cd21 + [5] https://github.com/arkenfox/user.js/wiki/4.2.4-Header-Editor + ***/ + /** CACHE ***/ + /* 1001: disable disk cache + * [SETUP-PERF] If you think disk cache may help (heavy tab user, high-res video), + * or you use a hardened Temporary Containers, then feel free to override this + * [NOTE] We also clear cache on exiting Firefox (see 2803) ***/ + "browser.cache.disk.enable" = false; + /* 1003: disable memory cache + * capacity: -1=determine dynamically (default), 0=none, n=memory capacity in kibibytes ***/ + # // user_pref("browser.cache.memory.enable", false); + # // user_pref("browser.cache.memory.capacity", 0); + /* 1006: disable permissions manager from writing to disk [RESTART] + * [NOTE] This means any permission changes are session only + * [1] https://bugzilla.mozilla.org/967812 ***/ + # // user_pref("permissions.memory_only", true); // [HIDDEN PREF] + /* 1007: disable media cache from writing to disk in Private Browsing + * [NOTE] MSE (Media Source Extensions) are already stored in-memory in PB + * [SETUP-WEB] ESR78: playback might break on subsequent loading (1650281) ***/ + "browser.privatebrowsing.forceMediaMemoryCache" = true; # [FF75+] + "media.memory_cache_max_size" = 65536; + + /** SESSIONS & SESSION RESTORE ***/ + /* 1020: exclude "Undo Closed Tabs" in Session Restore ***/ + # // user_pref("browser.sessionstore.max_tabs_undo", 0); + /* 1021: disable storing extra session data [SETUP-CHROME] + * define on which sites to save extra session data such as form content, cookies and POST data + * 0=everywhere, 1=unencrypted sites, 2=nowhere ***/ + "browser.sessionstore.privacy_level" = 2; + /* 1022: disable resuming session from crash ***/ + # // user_pref("browser.sessionstore.resume_from_crash", false); + /* 1023: set the minimum interval between session save operations + * Increasing this can help on older machines and some websites, as well as reducing writes [1] + * Default is 15000 (15 secs). Try 30000 (30 secs), 60000 (1 min) etc + * [SETUP-CHROME] This can also affect entries in the "Recently Closed Tabs" feature: + * i.e. the longer the interval the more chance a quick tab open/close won't be captured. + * This longer interval *may* affect history but we cannot replicate any history not recorded + * [1] https://bugzilla.mozilla.org/1304389 ***/ + "browser.sessionstore.interval" = 30000; + /* 1024: disable automatic Firefox start and session restore after reboot [FF62+] [WINDOWS] + * [1] https://bugzilla.mozilla.org/603903 ***/ + "toolkit.winRegisterApplicationRestart" = false; + + /** FAVICONS ***/ + /* 1030: disable favicons in shortcuts + * URL shortcuts use a cached randomly named .ico file which is stored in your + * profile/shortcutCache directory. The .ico remains after the shortcut is deleted. + * If set to false then the shortcuts use a generic Firefox icon ***/ + "browser.shell.shortcutFavicons" = false; + /* 1031: disable favicons in history and bookmarks + * Stored as data blobs in favicons.sqlite, these don't reveal anything that your + * actual history (and bookmarks) already do. Your history is more detailed, so + * control that instead; e.g. disable history, clear history on close, use PB mode + * [NOTE] favicons.sqlite is sanitized on Firefox close, not in-session ***/ + # // user_pref("browser.chrome.site_icons", false); + /* 1032: disable favicons in web notifications ***/ + # // user_pref("alerts.showFavicons", false); // [DEFAULT: false] +} diff --git a/home/browsers/firefox/arkenfox/1200.nix b/home/browsers/firefox/arkenfox/1200.nix new file mode 100644 index 0000000..829afcc --- /dev/null +++ b/home/browsers/firefox/arkenfox/1200.nix @@ -0,0 +1,168 @@ +{ + /*** [SECTION 1200]: HTTPS (SSL/TLS / OCSP / CERTS / HPKP / CIPHERS) + Your cipher and other settings can be used in server side fingerprinting + [TEST] https://www.ssllabs.com/ssltest/viewMyClient.html + [TEST] https://browserleaks.com/ssl + [TEST] https://ja3er.com/ + [1] https://www.securityartwork.es/2017/02/02/tls-client-fingerprinting-with-bro/ + ***/ + /** SSL (Secure Sockets Layer) / TLS (Transport Layer Security) ***/ + /* 1201: require safe negotiation + * Blocks connections (SSL_ERROR_UNSAFE_NEGOTIATION) to servers that don't support RFC 5746 [2] + * as they're potentially vulnerable to a MiTM attack [3]. A server without RFC 5746 can be + * safe from the attack if it disables renegotiations but the problem is that the browser can't + * know that. Setting this pref to true is the only way for the browser to ensure there will be + * no unsafe renegotiations on the channel between the browser and the server. + * [STATS] SSL Labs (July 2021) reports over 99% of sites have secure renegotiation [4] + * [1] https://wiki.mozilla.org/Security:Renegotiation + * [2] https://tools.ietf.org/html/rfc5746 + * [3] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3555 + * [4] https://www.ssllabs.com/ssl-pulse/ ***/ + "security.ssl.require_safe_negotiation" = true; + /* 1202: control TLS versions with min and max + * 1=TLS 1.0, 2=TLS 1.1, 3=TLS 1.2, 4=TLS 1.3 + * [WARNING] Leave these at default, otherwise you alter your TLS fingerprint. + * [1] https://www.ssllabs.com/ssl-pulse/ ***/ + # // user_pref("security.tls.version.min", 3); // [DEFAULT: 3] + # // user_pref("security.tls.version.max", 4); + /* 1203: enforce TLS 1.0 and 1.1 downgrades as session only ***/ + "security.tls.version.enable-deprecated" = false; # [DEFAULT: false] + /* 1204: disable SSL session tracking [FF36+] + * SSL Session IDs are unique and last up to 24hrs in Firefox (or longer with prolongation attacks) + * [NOTE] These are not used in PB mode. In normal windows they are isolated when using FPI (4001) + * and/or containers. In FF85+ they are isolated by default (privacy.partition.network_state) + * [WARNING] There are perf and passive fingerprinting costs, for little to no gain. Preventing + * tracking via this method does not address IPs, nor handle any sanitizing of current identifiers + * [1] https://tools.ietf.org/html/rfc5077 + * [2] https://bugzilla.mozilla.org/967977 + * [3] https://arxiv.org/abs/1810.07304 ***/ + # // user_pref("security.ssl.disable_session_identifiers", true); // [HIDDEN PREF] + /* 1206: disable TLS1.3 0-RTT (round-trip time) [FF51+] + * [1] https://github.com/tlswg/tls13-spec/issues/1001 + * [2] https://blog.cloudflare.com/tls-1-3-overview-and-q-and-a/ ***/ + "security.tls.enable_0rtt_data" = false; + + /** OCSP (Online Certificate Status Protocol) + [1] https://scotthelme.co.uk/revocation-is-broken/ + [2] https://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/ + ***/ + /* 1211: control when to use OCSP fetching (to confirm current validity of certificates) + * 0=disabled, 1=enabled (default), 2=enabled for EV certificates only + * OCSP (non-stapled) leaks information about the sites you visit to the CA (cert authority) + * It's a trade-off between security (checking) and privacy (leaking info to the CA) + * [NOTE] This pref only controls OCSP fetching and does not affect OCSP stapling + * [1] https://en.wikipedia.org/wiki/Ocsp ***/ + "security.OCSP.enabled" = 1; + /* 1212: set OCSP fetch failures (non-stapled, see 1211) to hard-fail [SETUP-WEB] + * When a CA cannot be reached to validate a cert, Firefox just continues the connection (=soft-fail) + * Setting this pref to true tells Firefox to instead terminate the connection (=hard-fail) + * It is pointless to soft-fail when an OCSP fetch fails: you cannot confirm a cert is still valid (it + * could have been revoked) and/or you could be under attack (e.g. malicious blocking of OCSP servers) + * [1] https://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/ + * [2] https://www.imperialviolet.org/2014/04/19/revchecking.html ***/ + "security.OCSP.require" = true; + + /** CERTS / HPKP (HTTP Public Key Pinning) ***/ + /* 1220: disable or limit SHA-1 certificates + * 0=all SHA1 certs are allowed + * 1=all SHA1 certs are blocked + * 2=deprecated option that now maps to 1 + * 3=only allowed for locally-added roots (e.g. anti-virus) + * 4=only allowed for locally-added roots or for certs in 2015 and earlier + * [SETUP-CHROME] When disabled, some man-in-the-middle devices (e.g. security scanners and + * antivirus products, may fail to connect to HTTPS sites. SHA-1 is *almost* obsolete. + * [1] https://blog.mozilla.org/security/2016/10/18/phasing-out-sha-1-on-the-public-web/ ***/ + "security.pki.sha1_enforcement_level" = 1; + /* 1221: disable Windows 8.1's Microsoft Family Safety cert [FF50+] [WINDOWS] + * 0=disable detecting Family Safety mode and importing the root + * 1=only attempt to detect Family Safety mode (don't import the root) + * 2=detect Family Safety mode and import the root + * [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/21686 ***/ + "security.family_safety.mode" = 0; + /* 1222: disable intermediate certificate caching (fingerprinting attack vector) [FF41+] [RESTART] + * [NOTE] This affects login/cert/key dbs. The effect is all credentials are session-only. + * Saved logins and passwords are not available. Reset the pref and restart to return them. + * [1] https://shiftordie.de/blog/2017/02/21/fingerprinting-firefox-users-with-cached-intermediate-ca-certificates-fiprinca/ ***/ + # // user_pref("security.nocertdb", true); // [HIDDEN PREF] + /* 1223: enable strict pinning + * PKP (Public Key Pinning) 0=disabled 1=allow user MiTM (such as your antivirus), 2=strict + * [SETUP-WEB] If you rely on an AV (antivirus) to protect your web browsing + * by inspecting ALL your web traffic, then leave at current default=1 + * [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/16206 ***/ + "security.cert_pinning.enforcement_level" = 2; + /* 1224: enable CRLite [FF73+] + * In FF84+ it covers valid certs and in mode 2 doesn't fall back to OCSP + * [1] https://bugzilla.mozilla.org/buglist.cgi?bug_id=1429800,1670985 + * [2] https://blog.mozilla.org/security/tag/crlite/ ***/ + "security.remote_settings.crlite_filters.enabled" = true; + "security.pki.crlite_mode" = 2; + + /** MIXED CONTENT ***/ + /* 1240: enforce no insecure active content on https pages + * [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/21323 ***/ + "security.mixed_content.block_active_content" = true; # [DEFAULT: true] + /* 1241: disable insecure passive content (such as images) on https pages [SETUP-WEB] ***/ + "security.mixed_content.block_display_content" = true; + /* 1244: enable HTTPS-Only mode [FF76+] + * When "https_only_mode" (all windows) is true, "https_only_mode_pbm" (private windows only) is ignored + * [SETTING] to add site exceptions: Padlock>HTTPS-Only mode>On/Off/Off temporarily + * [SETTING] Privacy & Security>HTTPS-Only Mode + * [TEST] http://example.com [upgrade] + * [TEST] http://neverssl.org/ [no upgrade] + * [1] https://bugzilla.mozilla.org/1613063 [META] ***/ + "dom.security.https_only_mode" = true; # [FF76+] + # // user_pref("dom.security.https_only_mode_pbm", true); // [FF80+] + /* 1245: enable HTTPS-Only mode for local resources [FF77+] ***/ + # // user_pref("dom.security.https_only_mode.upgrade_local", true); + /* 1246: disable HTTP background requests [FF82+] + * When attempting to upgrade, if the server doesn't respond within 3 seconds, firefox + * sends HTTP requests in order to check if the server supports HTTPS or not. + * This is done to avoid waiting for a timeout which takes 90 seconds + * [1] https://bugzilla.mozilla.org/buglist.cgi?bug_id=1642387,1660945 ***/ + "dom.security.https_only_mode_send_http_background_request" = false; + /* 1247: treat .onion as a secure context [FF60+] [TOR] + * [NOTE] Firefox cannot access .onion sites by default: it is strongly recommended you just use Tor Browser + * [1] https://bugzilla.mozilla.org/1382359 ***/ + # // user_pref("dom.securecontext.whitelist_onions", true); + + /** CIPHERS [WARNING: do not meddle with your cipher suite: see the section 1200 intro] + * These are the ciphers listed under "Cipher Suites" [1] that are either still using SHA-1 and CBC, + * and/or are missing Perfect Forward Secrecy [3] and/or have other weaknesses like key sizes of 128 + * [1] https://browserleaks.com/ssl + * [2] https://en.wikipedia.org/wiki/Key_size + * [3] https://en.wikipedia.org/wiki/Forward_secrecy + ***/ + /* 1261: disable 3DES (effective key size < 128 and no PFS) + * [1] https://en.wikipedia.org/wiki/3des#Security + * [2] https://en.wikipedia.org/wiki/Meet-in-the-middle_attack + * [3] https://www-archive.mozilla.org/projects/security/pki/nss/ssl/fips-ssl-ciphersuites.html ***/ + # // user_pref("security.ssl3.rsa_des_ede3_sha", false); + /* 1264: disable the remaining non-modern cipher suites as of FF78 (in order of preferred by FF) ***/ + # // user_pref("security.ssl3.ecdhe_ecdsa_aes_256_sha", false); + # // user_pref("security.ssl3.ecdhe_ecdsa_aes_128_sha", false); + # // user_pref("security.ssl3.ecdhe_rsa_aes_128_sha", false); + # // user_pref("security.ssl3.ecdhe_rsa_aes_256_sha", false); + # // user_pref("security.ssl3.rsa_aes_128_gcm_sha256", false); // no PFS + # // user_pref("security.ssl3.rsa_aes_256_gcm_sha384", false); // no PFS + # // user_pref("security.ssl3.rsa_aes_128_sha", false); // no PFS + # // user_pref("security.ssl3.rsa_aes_256_sha", false); // no PFS + + /** UI (User Interface) ***/ + /* 1270: display warning on the padlock for "broken security" (if 1201 is false) + * Bug: warning padlock not indicated for subresources on a secure page! [2] + * [1] https://wiki.mozilla.org/Security:Renegotiation + * [2] https://bugzilla.mozilla.org/1353705 ***/ + "security.ssl.treat_unsafe_negotiation_as_broken" = true; + /* 1271: control "Add Security Exception" dialog on SSL warnings + * 0=do neither 1=pre-populate url 2=pre-populate url + pre-fetch cert (default) + * [1] https://github.com/pyllyukko/user.js/issues/210 ***/ + "browser.ssl_override_behavior" = 1; + /* 1272: display advanced information on Insecure Connection warning pages + * only works when it's possible to add an exception + * i.e. it doesn't work for HSTS discrepancies (https://subdomain.preloaded-hsts.badssl.com/) + * [TEST] https://expired.badssl.com/ ***/ + "browser.xul.error_pages.expert_bad_cert" = true; + /* 1273: display "insecure" icon and "Not Secure" text on HTTP sites ***/ + # // user_pref("security.insecure_connection_icon.enabled", true); // [FF59+] [DEFAULT: true] + "security.insecure_connection_text.enabled" = true; # [FF60+] +} diff --git a/home/browsers/firefox/arkenfox/1400.nix b/home/browsers/firefox/arkenfox/1400.nix new file mode 100644 index 0000000..267db35 --- /dev/null +++ b/home/browsers/firefox/arkenfox/1400.nix @@ -0,0 +1,27 @@ +{ + /*** [SECTION 1400]: FONTS ***/ + /* 1401: disable websites choosing fonts (0=block, 1=allow) + * This can limit most (but not all) JS font enumeration which is a high entropy fingerprinting vector + * [WARNING] DO NOT USE: in FF80+ RFP covers this, and non-RFP users should use font vis (4620) + * [SETTING] General>Language and Appearance>Fonts & Colors>Advanced>Allow pages to choose... ***/ + # // user_pref("browser.display.use_document_fonts", 0); + /* 1403: disable icon fonts (glyphs) and local fallback rendering + * [1] https://bugzilla.mozilla.org/789788 + * [2] https://gitlab.torproject.org/legacy/trac/-/issues/8455 ***/ + # // user_pref("gfx.downloadable_fonts.enabled", false); // [FF41+] + # // user_pref("gfx.downloadable_fonts.fallback_delay", -1); + /* 1404: disable rendering of SVG OpenType fonts + * [1] https://wiki.mozilla.org/SVGOpenTypeFonts - iSECPartnersReport recommends to disable this ***/ + "gfx.font_rendering.opentype_svg.enabled" = false; + /* 1408: disable graphite + * Graphite has had many critical security issues in the past [1] + * [1] https://www.mozilla.org/security/advisories/mfsa2017-15/#CVE-2017-7778 + * [2] https://en.wikipedia.org/wiki/Graphite_(SIL) ***/ + "gfx.font_rendering.graphite.enabled" = false; + /* 1409: limit system font exposure to a whitelist [FF52+] [RESTART] + * If the whitelist is empty, then whitelisting is considered disabled and all fonts are allowed + * [NOTE] In FF81+ the whitelist **overrides** RFP's font visibility (see 4620) + * [WARNING] DO NOT USE: in FF80+ RFP covers this, and non-RFP users should use font vis (4620) + * [1] https://bugzilla.mozilla.org/1121643 ***/ + # // user_pref("font.system.whitelist", ""); // [HIDDEN PREF] +} diff --git a/home/browsers/firefox/arkenfox/1600.nix b/home/browsers/firefox/arkenfox/1600.nix new file mode 100644 index 0000000..cec275f --- /dev/null +++ b/home/browsers/firefox/arkenfox/1600.nix @@ -0,0 +1,47 @@ +{ + /*** [SECTION 1600]: HEADERS / REFERERS + Only *cross domain* referers need controlling: leave 1601, 1602, 1605 and 1606 alone + --- + Expect some breakage: Use an extension if you need precise control + --- + full URI: https://example.com:8888/foo/bar.html?id=1234 + scheme+host+port+path: https://example.com:8888/foo/bar.html + scheme+host+port: https://example.com:8888 + --- + [1] https://feeding.cloud.geek.nz/posts/tweaking-referrer-for-privacy-in-firefox/ + ***/ + /* 1601: ALL: control when images/links send a referer + * 0=never, 1=send only when links are clicked, 2=for links and images (default) ***/ + # // user_pref("network.http.sendRefererHeader", 2); + /* 1602: ALL: control the amount of information to send + * 0=send full URI (default), 1=scheme+host+port+path, 2=scheme+host+port ***/ + # // user_pref("network.http.referer.trimmingPolicy", 0); + /* 1603: CROSS ORIGIN: control when to send a referer + * 0=always (default), 1=only if base domains match, 2=only if hosts match + * [SETUP-WEB] Known to cause issues with older modems/routers and some sites e.g vimeo, icloud, instagram ***/ + "network.http.referer.XOriginPolicy" = 2; + /* 1604: CROSS ORIGIN: control the amount of information to send [FF52+] + * 0=send full URI (default), 1=scheme+host+port+path, 2=scheme+host+port ***/ + "network.http.referer.XOriginTrimmingPolicy" = 2; + /* 1605: ALL: disable spoofing a referer + * [WARNING] Do not set this to true, as spoofing effectively disables the anti-CSRF + * (Cross-Site Request Forgery) protections that some sites may rely on ***/ + # // user_pref("network.http.referer.spoofSource", false); // [DEFAULT: false] + /* 1606: ALL: set the default Referrer Policy [FF59+] + * 0=no-referer, 1=same-origin, 2=strict-origin-when-cross-origin, 3=no-referrer-when-downgrade + * [NOTE] This is only a default, it can be overridden by a site-controlled Referrer Policy + * [1] https://www.w3.org/TR/referrer-policy/ + * [2] https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy + * [3] https://blog.mozilla.org/security/2018/01/31/preventing-data-leaks-by-stripping-path-information-in-http-referrers/ + * [4] https://blog.mozilla.org/security/2021/03/22/firefox-87-trims-http-referrers-by-default-to-protect-user-privacy/ ***/ + # // user_pref("network.http.referer.defaultPolicy", 2); // [DEFAULT: 2 FF87+] + # // user_pref("network.http.referer.defaultPolicy.pbmode", 2); // [DEFAULT: 2] + /* 1607: hide (not spoof) referrer when leaving a .onion domain [FF54+] [TOR] + * [NOTE] Firefox cannot access .onion sites by default: it is strongly recommended you just use Tor Browser + * [1] https://bugzilla.mozilla.org/1305144 ***/ + # // user_pref("network.http.referer.hideOnionSource", true); + /* 1610: ALL: enable the DNT (Do Not Track) HTTP header + * [NOTE] DNT is enforced with Enhanced Tracking Protection regardless of this pref + * [SETTING] Privacy & Security>Enhanced Tracking Protection>Send websites a "Do Not Track" signal... ***/ + "privacy.donottrackheader.enabled" = true; +} diff --git a/home/browsers/firefox/arkenfox/1700.nix b/home/browsers/firefox/arkenfox/1700.nix new file mode 100644 index 0000000..830a319 --- /dev/null +++ b/home/browsers/firefox/arkenfox/1700.nix @@ -0,0 +1,20 @@ +{ + /*** [SECTION 1700]: CONTAINERS + If you want to *really* leverage containers, we highly recommend Temporary Containers [2]. + Read the article by the extension author [3], and check out the github wiki/repo [4]. + [1] https://wiki.mozilla.org/Security/Contextual_Identity_Project/Containers + [2] https://addons.mozilla.org/firefox/addon/temporary-containers/ + [3] https://medium.com/@stoically/enhance-your-privacy-in-firefox-with-temporary-containers-33925cd6cd21 + [4] https://github.com/stoically/temporary-containers/wiki + ***/ + /* 1701: enable Container Tabs setting in preferences (see 1702) [FF50+] + * [1] https://bugzilla.mozilla.org/1279029 ***/ + "privacy.userContext.ui.enabled" = true; + /* 1702: enable Container Tabs [FF50+] + * [SETTING] General>Tabs>Enable Container Tabs ***/ + "privacy.userContext.enabled" = true; + /* 1703: set behaviour on "+ Tab" button to display container menu on left click [FF74+] + * [NOTE] The menu is always shown on long press and right click + * [SETTING] General>Tabs>Enable Container Tabs>Settings>Select a container for each new tab ***/ + # // user_pref("privacy.userContext.newTabContainerOnLeftClick.enabled", true); +} diff --git a/home/browsers/firefox/arkenfox/1800.nix b/home/browsers/firefox/arkenfox/1800.nix new file mode 100644 index 0000000..5395848 --- /dev/null +++ b/home/browsers/firefox/arkenfox/1800.nix @@ -0,0 +1,15 @@ +{ + /*** [SECTION 1800]: PLUGINS ***/ + /* 1820: disable GMP (Gecko Media Plugins) + * [1] https://wiki.mozilla.org/GeckoMediaPlugins ***/ + # // user_pref("media.gmp-provider.enabled", false); + /* 1825: disable widevine CDM (Content Decryption Module) + * [NOTE] This is covered by the EME master switch (1830) ***/ + # // user_pref("media.gmp-widevinecdm.enabled", false); + /* 1830: disable all DRM content (EME: Encryption Media Extension) + * [SETUP-WEB] e.g. Netflix, Amazon Prime, Hulu, HBO, Disney+, Showtime, Starz, DirectTV + * [SETTING] General>DRM Content>Play DRM-controlled content + * [TEST] https://bitmovin.com/demos/drm + * [1] https://www.eff.org/deeplinks/2017/10/drms-dead-canary-how-we-just-lost-web-what-we-learned-it-and-what-we-need-do-next ***/ + "media.eme.enabled" = false; +} diff --git a/home/browsers/firefox/arkenfox/2000.nix b/home/browsers/firefox/arkenfox/2000.nix new file mode 100644 index 0000000..59471dc --- /dev/null +++ b/home/browsers/firefox/arkenfox/2000.nix @@ -0,0 +1,38 @@ +{ + /*** [SECTION 2000]: MEDIA / CAMERA / MIC ***/ + /* 2001: disable WebRTC (Web Real-Time Communication) + * [SETUP-WEB] WebRTC can leak your IP address from behind your VPN, but if this is not + * in your threat model, and you want Real-Time Communication, this is the pref for you + * [1] https://www.privacytools.io/#webrtc ***/ + "media.peerconnection.enabled" = false; + /* 2002: limit WebRTC IP leaks if using WebRTC + * In FF70+ these settings match Mode 4 (Mode 3 in older versions) [3] + * [TEST] https://browserleaks.com/webrtc + * [1] https://bugzilla.mozilla.org/buglist.cgi?bug_id=1189041,1297416,1452713 + * [2] https://wiki.mozilla.org/Media/WebRTC/Privacy + * [3] https://tools.ietf.org/html/draft-ietf-rtcweb-ip-handling-12#section-5.2 ***/ + "media.peerconnection.ice.default_address_only" = true; + "media.peerconnection.ice.no_host" = true; # [FF51+] + "media.peerconnection.ice.proxy_only_if_behind_proxy" = true; # [FF70+] + /* 2022: disable screensharing ***/ + "media.getusermedia.screensharing.enabled" = false; + "media.getusermedia.browser.enabled" = false; + "media.getusermedia.audiocapture.enabled" = false; + /* 2024: set a default permission for Camera/Microphone [FF58+] + * 0=always ask (default), 1=allow, 2=block + * [SETTING] to add site exceptions: Ctrl+I>Permissions>Use the Camera/Microphone + * [SETTING] to manage site exceptions: Options>Privacy & Security>Permissions>Camera/Microphone>Settings ***/ + # // user_pref("permissions.default.camera", 2); + # // user_pref("permissions.default.microphone", 2); + /* 2030: disable autoplay of HTML5 media [FF63+] + * 0=Allow all, 1=Block non-muted media (default in FF67+), 2=Prompt (removed in FF66), 5=Block all (FF69+) + * [NOTE] You can set exceptions under site permissions + * [SETTING] Privacy & Security>Permissions>Autoplay>Settings>Default for all websites ***/ + # // user_pref("media.autoplay.default", 5); + /* 2031: disable autoplay of HTML5 media if you interacted with the site [FF78+] + * 0=sticky (default), 1=transient, 2=user + * Firefox's Autoplay Policy Documentation [PDF] is linked below via SUMO + * [NOTE] If you have trouble with some video sites, then add an exception (see 2030) + * [1] https://support.mozilla.org/questions/1293231 ***/ + "media.autoplay.blocking_policy" = 2; +} diff --git a/home/browsers/firefox/arkenfox/2200.nix b/home/browsers/firefox/arkenfox/2200.nix new file mode 100644 index 0000000..5293cc3 --- /dev/null +++ b/home/browsers/firefox/arkenfox/2200.nix @@ -0,0 +1,23 @@ +{ + /*** [SECTION 2200]: WINDOW MEDDLING & LEAKS / POPUPS ***/ + /* 2202: prevent scripts from moving and resizing open windows ***/ + "dom.disable_window_move_resize" = true; + /* 2203: open links targeting new windows in a new tab instead + * This stops malicious window sizes and some screen resolution leaks. + * You can still right-click a link and open in a new window. + * [TEST] https://arkenfox.github.io/TZP/tzp.html#screen + * [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/9881 ***/ + "browser.link.open_newwindow" = 3; # 1=most recent window or tab 2=new window, 3=new tab + "browser.link.open_newwindow.restriction" = 0; + /* 2204: disable Fullscreen API (requires user interaction) to prevent screen-resolution leaks + * [NOTE] You can still manually toggle the browser's fullscreen state (F11), + * but this pref will disable embedded video/game fullscreen controls, e.g. youtube + * [TEST] https://arkenfox.github.io/TZP/tzp.html#screen ***/ + # // user_pref("full-screen-api.enabled", false); + /* 2210: block popup windows + * [SETTING] Privacy & Security>Permissions>Block pop-up windows ***/ + "dom.disable_open_during_load" = true; + /* 2212: limit events that can cause a popup [SETUP-WEB] + * default FF86+: "change click dblclick auxclick mousedown mouseup pointerdown pointerup notificationclick reset submit touchend contextmenu ***/ + "dom.popup_allowed_events" = "click dblclick mousedown pointerdown"; +} diff --git a/home/browsers/firefox/arkenfox/2300.nix b/home/browsers/firefox/arkenfox/2300.nix new file mode 100644 index 0000000..e6aab3f --- /dev/null +++ b/home/browsers/firefox/arkenfox/2300.nix @@ -0,0 +1,47 @@ +{ + /*** [SECTION 2300]: WEB WORKERS + A worker is a JS "background task" running in a global context, i.e. it is different from + the current window. Workers can spawn new workers (must be the same origin & scheme), + including service and shared workers. Shared workers can be utilized by multiple scripts and + communicate between browsing contexts (windows/tabs/iframes) and can even control your cache. + + [1] Web Workers: https://developer.mozilla.org/docs/Web/API/Web_Workers_API + [2] Worker: https://developer.mozilla.org/docs/Web/API/Worker + [3] Service Worker: https://developer.mozilla.org/docs/Web/API/Service_Worker_API + [4] SharedWorker: https://developer.mozilla.org/docs/Web/API/SharedWorker + [5] ChromeWorker: https://developer.mozilla.org/docs/Web/API/ChromeWorker + [6] Notifications: https://support.mozilla.org/questions/1165867#answer-981820 + ***/ + /* 2302: disable service workers [FF32, FF44-compat] + * Service workers essentially act as proxy servers that sit between web apps, and the + * browser and network, are event driven, and can control the web page/site it is associated + * with, intercepting and modifying navigation and resource requests, and caching resources. + * [NOTE] Service worker APIs are hidden (in Firefox) and cannot be used when in PB mode. + * [NOTE] Service workers only run over HTTPS. Service workers have no DOM access. + * [SETUP-WEB] Disabling service workers will break some sites. This pref is required true for + * service worker notifications (2304), push notifications (disabled, 2305) and service worker + * cache (2740). If you enable this pref, then check those settings as well ***/ + "dom.serviceWorkers.enabled" = false; + /* 2304: disable Web Notifications + * [NOTE] Web Notifications can also use service workers (2302) and are behind a prompt (2306) + * [1] https://developer.mozilla.org/docs/Web/API/Notifications_API ***/ + # // user_pref("dom.webnotifications.enabled", false); // [FF22+] + # // user_pref("dom.webnotifications.serviceworker.enabled", false); // [FF44+] + /* 2305: disable Push Notifications [FF44+] + * Push is an API that allows websites to send you (subscribed) messages even when the site + * isn't loaded, by pushing messages to your userAgentID through Mozilla's Push Server. + * [NOTE] Push requires service workers (2302) to subscribe to and display, and is behind + * a prompt (2306). Disabling service workers alone doesn't stop Firefox polling the + * Mozilla Push Server. To remove all subscriptions, reset your userAgentID (in about:config + * or on start), and you will get a new one within a few seconds. + * [1] https://support.mozilla.org/kb/push-notifications-firefox + * [2] https://developer.mozilla.org/docs/Web/API/Push_API ***/ + "dom.push.enabled" = false; + # // user_pref("dom.push.userAgentID", ""); + /* 2306: set a default permission for Notifications (both 2304 and 2305) [FF58+] + * 0=always ask (default), 1=allow, 2=block + * [NOTE] Best left at default "always ask", fingerprintable via Permissions API + * [SETTING] to add site exceptions: Ctrl+I>Permissions>Receive Notifications + * [SETTING] to manage site exceptions: Options>Privacy & Security>Permissions>Notifications>Settings ***/ + # // user_pref("permissions.default.desktop-notification", 2); +} diff --git a/home/browsers/firefox/arkenfox/2400.nix b/home/browsers/firefox/arkenfox/2400.nix new file mode 100644 index 0000000..0d5f599 --- /dev/null +++ b/home/browsers/firefox/arkenfox/2400.nix @@ -0,0 +1,52 @@ +{ + /*** [SECTION 2400]: DOM (DOCUMENT OBJECT MODEL) & JAVASCRIPT ***/ + /* 2401: disable website control over browser right-click context menu + * [NOTE] Shift-Right-Click will always bring up the browser right-click context menu ***/ + # // user_pref("dom.event.contextmenu.enabled", false); + /* 2402: disable website access to clipboard events/content [SETUP-HARDEN] + * [NOTE] This will break some sites' functionality e.g. Outlook, Twitter, Facebook, Wordpress + * This applies to onCut/onCopy/onPaste events - i.e. it requires interaction with the website + * [WARNING] In FF88 or lower, with clipboardevents enabled, if both 'middlemouse.paste' and + * 'general.autoScroll' are true (at least one is default false) then the clipboard can leak [1] + * [1] https://bugzilla.mozilla.org/1528289 ***/ + # // user_pref("dom.event.clipboardevents.enabled", false); + /* 2404: disable clipboard commands (cut/copy) from "non-privileged" content [FF41+] + * this disables document.execCommand("cut"/"copy") to protect your clipboard + * [1] https://bugzilla.mozilla.org/1170911 ***/ + "dom.allow_cut_copy" = false; + /* 2405: disable "Confirm you want to leave" dialog on page close + * Does not prevent JS leaks of the page close event. + * [1] https://developer.mozilla.org/docs/Web/Events/beforeunload + * [2] https://support.mozilla.org/questions/1043508 ***/ + "dom.disable_beforeunload" = true; + /* 2414: disable shaking the screen ***/ + "dom.vibrator.enabled" = false; + /* 2420: disable asm.js [FF22+] [SETUP-PERF] + * [1] http://asmjs.org/ + * [2] https://www.mozilla.org/security/advisories/mfsa2015-29/ + * [3] https://www.mozilla.org/security/advisories/mfsa2015-50/ + * [4] https://www.mozilla.org/security/advisories/mfsa2017-01/#CVE-2017-5375 + * [5] https://www.mozilla.org/security/advisories/mfsa2017-05/#CVE-2017-5400 + * [6] https://rh0dev.github.io/blog/2017/the-return-of-the-jit/ ***/ + "javascript.options.asmjs" = false; + /* 2421: disable Ion and baseline JIT to harden against JS exploits [SETUP-HARDEN] + * [NOTE] In FF75+, when **both** Ion and JIT are disabled, **and** the new + * hidden pref is enabled, then Ion can still be used by extensions (1599226) + * [WARNING] Disabling Ion/JIT can cause some site issues and performance loss + * [1] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0817 ***/ + # // user_pref("javascript.options.ion", false); + # // user_pref("javascript.options.baselinejit", false); + # // user_pref("javascript.options.jit_trustedprincipals", true); // [FF75+] [HIDDEN PREF] + /* 2422: disable WebAssembly [FF52+] + * Vulnerabilities have increasingly been found, including those known and fixed + * in native programs years ago [2]. WASM has powerful low-level access, making + * certain attacks (brute-force) and vulnerabilities more possible + * [STATS] ~0.2% of websites, about half of which are for crytopmining / malvertising [2][3] + * [1] https://developer.mozilla.org/docs/WebAssembly + * [2] https://spectrum.ieee.org/tech-talk/telecom/security/more-worries-over-the-security-of-web-assembly + * [3] https://www.zdnet.com/article/half-of-the-websites-using-webassembly-use-it-for-malicious-purposes ***/ + "javascript.options.wasm" = false; + /* 2429: enable (limited but sufficient) window.opener protection [FF65+] + * Makes rel=noopener implicit for target=_blank in anchor and area elements when no rel attribute is set ***/ + "dom.targetBlankNoOpener.enabled" = true; # [DEFAULT: true FF79+] +} diff --git a/home/browsers/firefox/arkenfox/2500.nix b/home/browsers/firefox/arkenfox/2500.nix new file mode 100644 index 0000000..163a67f --- /dev/null +++ b/home/browsers/firefox/arkenfox/2500.nix @@ -0,0 +1,39 @@ +{ + /*** [SECTION 2500]: HARDWARE FINGERPRINTING ***/ + /* 2502: disable Battery Status API + * Initially a Linux issue (high precision readout) that was fixed. + * However, it is still another metric for fingerprinting, used to raise entropy. + * e.g. do you have a battery or not, current charging status, charge level, times remaining etc + * [NOTE] From FF52+ Battery Status API is only available in chrome/privileged code [1] + * [1] https://bugzilla.mozilla.org/1313580 ***/ + # // user_pref("dom.battery.enabled", false); + /* 2508: disable hardware acceleration to reduce graphics fingerprinting [SETUP-HARDEN] + * [WARNING] Affects text rendering (fonts will look different), impacts video performance, + * and parts of Quantum that utilize the GPU will also be affected as they are rolled out + * [SETTING] General>Performance>Custom>Use hardware acceleration when available + * [1] https://wiki.mozilla.org/Platform/GFX/HardwareAcceleration ***/ + # // user_pref("gfx.direct2d.disabled", true); // [WINDOWS] + # // user_pref("layers.acceleration.disabled", true); + /* 2517: disable Media Capabilities API [FF63+] + * [WARNING] This *may* affect media performance if disabled, no one is sure + * [1] https://github.com/WICG/media-capabilities + * [2] https://wicg.github.io/media-capabilities/#security-privacy-considerations ***/ + # // user_pref("media.media-capabilities.enabled", false); + /* 2520: disable virtual reality devices + * Optional protection depending on your connected devices + * [1] https://developer.mozilla.org/docs/Web/API/WebVR_API ***/ + # // user_pref("dom.vr.enabled", false); + /* 2521: set a default permission for Virtual Reality (see 2520) [FF73+] + * 0=always ask (default), 1=allow, 2=block + * [SETTING] to add site exceptions: Ctrl+I>Permissions>Access Virtual Reality Devices + * [SETTING] to manage site exceptions: Options>Privacy & Security>Permissions>Virtual Reality>Settings ***/ + # // user_pref("permissions.default.xr", 2); + /* 2522: disable/limit WebGL (Web Graphics Library) + * [SETUP-WEB] When disabled, will break some websites. When enabled, provides high entropy, + * especially with readPixels(). Some of the other entropy is lessened with RFP (see 4501) + * [1] https://www.contextis.com/resources/blog/webgl-new-dimension-browser-exploitation/ + * [2] https://security.stackexchange.com/questions/13799/is-webgl-a-security-concern ***/ + "webgl.disabled" = true; + "webgl.enable-webgl2" = false; + "webgl.disable-fail-if-major-performance-caveat" = true; # [DEFAULT: true FF86+] +} diff --git a/home/browsers/firefox/arkenfox/2600.nix b/home/browsers/firefox/arkenfox/2600.nix new file mode 100644 index 0000000..64e61a1 --- /dev/null +++ b/home/browsers/firefox/arkenfox/2600.nix @@ -0,0 +1,130 @@ +{ + /*** [SECTION 2600]: MISCELLANEOUS ***/ + /* 2601: prevent accessibility services from accessing your browser [RESTART] + * [SETTING] Privacy & Security>Permissions>Prevent accessibility services from accessing your browser (FF80 or lower) + * [1] https://support.mozilla.org/kb/accessibility-services ***/ + "accessibility.force_disabled" = 1; + /* 2602: disable sending additional analytics to web servers + * [1] https://developer.mozilla.org/docs/Web/API/Navigator/sendBeacon ***/ + "beacon.enabled" = false; + /* 2603: remove temp files opened with an external application + * [1] https://bugzilla.mozilla.org/302433 ***/ + "browser.helperApps.deleteTempFileOnExit" = true; + /* 2604: disable page thumbnail collection ***/ + "browser.pagethumbnails.capturing_disabled" = true; # [HIDDEN PREF] + /* 2606: disable UITour backend so there is no chance that a remote page can use it ***/ + "browser.uitour.enabled" = false; + "browser.uitour.url" = ""; + /* 2607: disable various developer tools in browser context + * [SETTING] Devtools>Advanced Settings>Enable browser chrome and add-on debugging toolboxes + * [1] https://github.com/pyllyukko/user.js/issues/179#issuecomment-246468676 ***/ + "devtools.chrome.enabled" = false; + /* 2608: reset remote debugging to disabled + * [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/16222 ***/ + "devtools.debugger.remote-enabled" = false; # [DEFAULT: false] + /* 2609: disable MathML (Mathematical Markup Language) [FF51+] [SETUP-HARDEN] + * [TEST] https://arkenfox.github.io/TZP/tzp.html#misc + * [1] https://bugzilla.mozilla.org/1173199 ***/ + # // user_pref("mathml.disabled", true); + /* 2610: disable in-content SVG (Scalable Vector Graphics) [FF53+] + * [WARNING] Expect breakage incl. youtube player controls. Best left for a "hardened" profile. + * [1] https://bugzilla.mozilla.org/1216893 ***/ + # // user_pref("svg.disabled", true); + /* 2611: disable middle mouse click opening links from clipboard + * [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/10089 ***/ + "middlemouse.contentLoadURL" = false; + /* 2615: disable websites overriding Firefox's keyboard shortcuts [FF58+] + * 0 (default) or 1=allow, 2=block + * [SETTING] to add site exceptions: Ctrl+I>Permissions>Override Keyboard Shortcuts ***/ + # // user_pref("permissions.default.shortcuts", 2); + /* 2616: remove special permissions for certain mozilla domains [FF35+] + * [1] resource://app/defaults/permissions ***/ + "permissions.manager.defaultsUrl" = ""; + /* 2617: remove webchannel whitelist ***/ + "webchannel.allowObject.urlWhitelist" = ""; + /* 2619: use Punycode in Internationalized Domain Names to eliminate possible spoofing + * Firefox has *some* protections, but it is better to be safe than sorry + * [SETUP-WEB] Might be undesirable for non-latin alphabet users since legitimate IDN's are also punycoded + * [TEST] https://www.xn--80ak6aa92e.com/ (www.apple.com) + * [1] https://wiki.mozilla.org/IDN_Display_Algorithm + * [2] https://en.wikipedia.org/wiki/IDN_homograph_attack + * [3] CVE-2017-5383: https://www.mozilla.org/security/advisories/mfsa2017-02/ + * [4] https://www.xudongz.com/blog/2017/idn-phishing/ ***/ + "network.IDN_show_punycode" = true; + /* 2620: enforce PDFJS, disable PDFJS scripting [SETUP-CHROME] + * This setting controls if the option "Display in Firefox" is available in the setting below + * and by effect controls whether PDFs are handled in-browser or externally ("Ask" or "Open With") + * PROS: pdfjs is lightweight, open source, and as secure/vetted as any pdf reader out there (more than most) + * Exploits are rare (one serious case in seven years), treated seriously and patched quickly. + * It doesn't break "state separation" of browser content (by not sharing with OS, independent apps). + * It maintains disk avoidance and application data isolation. It's convenient. You can still save to disk. + * CONS: You may prefer a different pdf reader for security reasons + * CAVEAT: JS can still force a pdf to open in-browser by bundling its own code (rare) + * [SETTING] General>Applications>Portable Document Format (PDF) ***/ + "pdfjs.disabled" = false; # [DEFAULT: false] + "pdfjs.enableScripting" = false; # [FF86+] + /* 2621: disable links launching Windows Store on Windows 8/8.1/10 [WINDOWS] ***/ + "network.protocol-handler.external.ms-windows-store" = false; + /* 2622: enforce no system colors; they can be fingerprinted + * [SETTING] General>Language and Appearance>Fonts and Colors>Colors>Use system colors ***/ + "browser.display.use_system_colors" = false; # [DEFAULT: false] + /* 2623: disable permissions delegation [FF73+] + * Currently applies to cross-origin geolocation, camera, mic and screen-sharing + * permissions, and fullscreen requests. Disabling delegation means any prompts + * for these will show/use their correct 3rd party origin + * [1] https://groups.google.com/forum/#!topic/mozilla.dev.platform/BdFOMAuCGW8/discussion ***/ + "permissions.delegation.enabled" = false; + /* 2624: enable "window.name" protection [FF82+] + * If a new page from another domain is loaded into a tab, then window.name is set to an empty string. The original + * string is restored if the tab reverts back to the original page. This change prevents some cross-site attacks + * [TEST] https://arkenfox.github.io/TZP/tests/windownamea.html ***/ + "privacy.window.name.update.enabled" = true; # [DEFAULT: true FF86+] + /* 2625: disable bypassing 3rd party extension install prompts [FF82+] + * [1] https://bugzilla.mozilla.org/buglist.cgi?bug_id=1659530,1681331 ***/ + "extensions.postDownloadThirdPartyPrompt" = false; + /* 2626: enforce non-native widget theme + * Security: removes/reduces system API calls, e.g. win32k API [1] + * Fingerprinting: provides a uniform look and feel across platforms [2] + * [1] https://bugzilla.mozilla.org/1381938 + * [2] https://bugzilla.mozilla.org/1411425 ***/ + "widget.non-native-theme.enabled" = true; # [DEFAULT: true FF89+] + + /** DOWNLOADS ***/ + /* 2650: discourage downloading to desktop + * 0=desktop, 1=downloads (default), 2=last used + * [SETTING] To set your default "downloads": General>Downloads>Save files to ***/ + # // user_pref("browser.download.folderList", 2); + /* 2651: enable user interaction for security by always asking where to download + * [SETUP-CHROME] On Android this blocks longtapping and saving images + * [SETTING] General>Downloads>Always ask you where to save files ***/ + "browser.download.useDownloadDir" = false; + /* 2652: disable adding downloads to the system's "recent documents" list ***/ + "browser.download.manager.addToRecentDocs" = false; + /* 2654: disable "open with" in download dialog [FF50+] [SETUP-HARDEN] + * This is very useful to enable when the browser is sandboxed (e.g. via AppArmor) + * in such a way that it is forbidden to run external applications. + * [WARNING] This may interfere with some users' workflow or methods + * [1] https://bugzilla.mozilla.org/1281959 ***/ + # // user_pref("browser.download.forbid_open_with", true); + + /** EXTENSIONS ***/ + /* 2660: lock down allowed extension directories + * [SETUP-CHROME] This will break extensions, language packs, themes and any other + * XPI files which are installed outside of profile and application directories + * [1] https://mike.kaply.com/2012/02/21/understanding-add-on-scopes/ + * [1] archived: https://archive.is/DYjAM ***/ + "extensions.enabledScopes" = 5; # [HIDDEN PREF] + "extensions.autoDisableScopes" = 15; # [DEFAULT: 15] + /* 2662: disable webextension restrictions on certain mozilla domains (you also need 4503) [FF60+] + * [1] https://bugzilla.mozilla.org/buglist.cgi?bug_id=1384330,1406795,1415644,1453988 ***/ + # // user_pref("extensions.webextensions.restrictedDomains", ""); + + /** SECURITY ***/ + /* 2680: enforce CSP (Content Security Policy) + * [NOTE] CSP is a very important and widespread security feature. Don't disable it! + * [1] https://developer.mozilla.org/docs/Web/HTTP/CSP ***/ + "security.csp.enable" = true; # [DEFAULT: true] + /* 2684: enforce a security delay on some confirmation dialogs such as install, open/save + * [1] https://www.squarefree.com/2004/07/01/race-conditions-in-security-dialogs/ ***/ + "security.dialog_enable_delay" = 1000; # [DEFAULT: 1000] +} diff --git a/home/browsers/firefox/arkenfox/2700.nix b/home/browsers/firefox/arkenfox/2700.nix new file mode 100644 index 0000000..6e00d20 --- /dev/null +++ b/home/browsers/firefox/arkenfox/2700.nix @@ -0,0 +1,75 @@ +{ + /*** [SECTION 2700]: PERSISTENT STORAGE + Data SET by websites including + cookies : profile\cookies.sqlite + localStorage : profile\webappsstore.sqlite + indexedDB : profile\storage\default + appCache : profile\OfflineCache + serviceWorkers : + + [NOTE] indexedDB and serviceWorkers are not available in Private Browsing Mode + [NOTE] Blocking cookies also blocks websites access to: localStorage (incl. sessionStorage), + indexedDB, sharedWorker, and serviceWorker (and therefore service worker cache and notifications) + If you set a site exception for cookies (either "Allow" or "Allow for Session") then they become + accessible to websites except shared/service workers where the cookie setting *must* be "Allow" + ***/ + /* 2701: disable or isolate 3rd-party cookies and site-data [SETUP-WEB] + * 0 = Accept cookies and site data + * 1 = (Block) All third-party cookies + * 2 = (Block) All cookies + * 3 = (Block) Cookies from unvisited websites + * 4 = (Block) Cross-site tracking cookies (default) + * 5 = (Isolate All) Cross-site cookies (TCP: Total Cookie Protection / dFPI: dynamic FPI) [1] (FF86+) + * Option 5 with FPI enabled (4001) is ignored and not shown, and option 4 used instead + * [NOTE] You can set cookie exceptions under site permissions or use an extension + * [NOTE] Enforcing category to custom ensures ETP related prefs are always honored + * [SETTING] Privacy & Security>Enhanced Tracking Protection>Custom>Cookies + * [1] https://blog.mozilla.org/security/2021/02/23/total-cookie-protection/ ***/ + "network.cookie.cookieBehavior" = 1; + "browser.contentblocking.category" = "custom"; + /* 2702: set third-party cookies (if enabled, see 2701) to session-only + * [NOTE] .sessionOnly overrides .nonsecureSessionOnly except when .sessionOnly=false and + * .nonsecureSessionOnly=true. This allows you to keep HTTPS cookies, but session-only HTTP ones + * [1] https://feeding.cloud.geek.nz/posts/tweaking-cookies-for-privacy-in-firefox/ ***/ + "network.cookie.thirdparty.sessionOnly" = true; + "network.cookie.thirdparty.nonsecureSessionOnly" = true; # [FF58+] + /* 2703: delete cookies and site data on close + * 0=keep until they expire (default), 2=keep until you close Firefox + * [NOTE] The setting below is disabled (but not changed) if you block all cookies (2701 = 2) + * [SETTING] Privacy & Security>Cookies and Site Data>Delete cookies and site data when Firefox is closed ***/ + # // user_pref("network.cookie.lifetimePolicy", 2); + /* 2710: enable Enhanced Tracking Protection (ETP) in all windows + * [SETTING] Privacy & Security>Enhanced Tracking Protection>Custom>Tracking content + * [SETTING] to add site exceptions: Urlbar>ETP Shield + * [SETTING] to manage site exceptions: Options>Privacy & Security>Enhanced Tracking Protection>Manage Exceptions ***/ + "privacy.trackingprotection.enabled" = true; + /* 2711: enable various ETP lists ***/ + "privacy.trackingprotection.socialtracking.enabled" = true; + # // user_pref("privacy.trackingprotection.cryptomining.enabled", true); // [DEFAULT: true] + # // user_pref("privacy.trackingprotection.fingerprinting.enabled", true); // [DEFAULT: true] + /* 2720: disable DOM (Document Object Model) Storage + * [WARNING] This will break a LOT of sites' functionality AND extensions! + * You are better off using an extension for more granular control ***/ + # // user_pref("dom.storage.enabled", false); + /* 2730: disable offline cache (appCache) + * [NOTE] In FF90+ the storage capability has been removed (1694662). For FF78-89 see the 2730 deprecated pref + * [WARNING] The API is easily fingerprinted, do not disable ***/ + # // user_pref("browser.cache.offline.enable", false); + /* 2740: disable service worker cache and cache storage + * [NOTE] We clear service worker cache on exiting Firefox (see 2803) + * [1] https://w3c.github.io/ServiceWorker/#privacy ***/ + # // user_pref("dom.caches.enabled", false); + /* 2750: disable Storage API [FF51+] + * The API gives sites the ability to find out how much space they can use, how much + * they are already using, and even control whether or not they need to be alerted + * before the user agent disposes of site data in order to make room for other things. + * [1] https://developer.mozilla.org/docs/Web/API/StorageManager + * [2] https://developer.mozilla.org/docs/Web/API/Storage_API + * [3] https://blog.mozilla.org/l10n/2017/03/07/firefox-l10n-report-aurora-54/ ***/ + # // user_pref("dom.storageManager.enabled", false); + /* 2755: disable Storage Access API [FF65+] + * [1] https://developer.mozilla.org/docs/Web/API/Storage_Access_API ***/ + # // user_pref("dom.storage_access.enabled", false); + /* 2760: enable Local Storage Next Generation (LSNG) [FF65+] ***/ + "dom.storage.next_gen" = true; +} diff --git a/home/browsers/firefox/arkenfox/2800.nix b/home/browsers/firefox/arkenfox/2800.nix new file mode 100644 index 0000000..f3b2e15 --- /dev/null +++ b/home/browsers/firefox/arkenfox/2800.nix @@ -0,0 +1,57 @@ +{ + /*** [SECTION 2800]: SHUTDOWN + - Sanitizing on shutdown is all or nothing. It does not use Managed Exceptions under + Privacy & Security>Delete cookies and site data when Firefox is closed (1681701) + - If you want to keep some sites' cookies (exception as "Allow") and optionally other site + data but clear all the rest on close, then you need to set the "cookie" and optionally the + "offlineApps" prefs below to false, and to set the cookie lifetime pref to 2 (2703) + - "Offline Website Data" includes appCache (2730), localStorage (2720), + service worker cache (2740), and QuotaManager (IndexedDB, asm-cache) + - In both 2803 + 2804, the 'download' and 'history' prefs are combined in the + Firefox interface as "Browsing & Download History" and their values will be synced + ***/ + /* 2802: enable Firefox to clear items on shutdown (see 2803) + * [SETTING] Privacy & Security>History>Custom Settings>Clear history when Firefox closes ***/ + "privacy.sanitize.sanitizeOnShutdown" = true; + /* 2803: set what items to clear on shutdown (if 2802 is true) [SETUP-CHROME] + * [NOTE] If 'history' is true, downloads will also be cleared regardless of the value + * but if 'history' is false, downloads can still be cleared independently + * However, this may not always be the case. The interface combines and syncs these + * prefs when set from there, and the sanitize code may change at any time + * [SETTING] Privacy & Security>History>Custom Settings>Clear history when Firefox closes>Settings ***/ + "privacy.clearOnShutdown.cache" = true; + "privacy.clearOnShutdown.cookies" = true; + "privacy.clearOnShutdown.downloads" = true; # see note above + "privacy.clearOnShutdown.formdata" = true; # Form & Search History + "privacy.clearOnShutdown.history" = true; # Browsing & Download History + "privacy.clearOnShutdown.offlineApps" = true; # Offline Website Data + "privacy.clearOnShutdown.sessions" = true; # Active Logins + "privacy.clearOnShutdown.siteSettings" = false; # Site Preferences + /* 2804: reset default items to clear with Ctrl-Shift-Del (to match 2803) [SETUP-CHROME] + * This dialog can also be accessed from the menu History>Clear Recent History + * Firefox remembers your last choices. This will reset them when you start Firefox. + * [NOTE] Regardless of what you set privacy.cpd.downloads to, as soon as the dialog + * for "Clear Recent History" is opened, it is synced to the same as 'history' ***/ + "privacy.cpd.cache" = true; + "privacy.cpd.cookies" = true; + # // user_pref("privacy.cpd.downloads", true); // not used, see note above + "privacy.cpd.formdata" = true; # Form & Search History + "privacy.cpd.history" = true; # Browsing & Download History + "privacy.cpd.offlineApps" = true; # Offline Website Data + "privacy.cpd.passwords" = false; # this is not listed + "privacy.cpd.sessions" = true; # Active Logins + "privacy.cpd.siteSettings" = false; # Site Preferences + /* 2805: clear Session Restore data when sanitizing on shutdown or manually [FF34+] + * [NOTE] Not needed if Session Restore is not used (see 0102) or is already cleared with history (see 2803) + * [NOTE] privacy.clearOnShutdown.openWindows prevents resuming from crashes (see 1022) + * [NOTE] privacy.cpd.openWindows has a bug that causes an additional window to open ***/ + # // user_pref("privacy.clearOnShutdown.openWindows", true); + # // user_pref("privacy.cpd.openWindows", true); + /* 2806: reset default 'Time range to clear' for 'Clear Recent History' (see 2804) + * Firefox remembers your last choice. This will reset the value when you start Firefox. + * 0=everything, 1=last hour, 2=last two hours, 3=last four hours, + * 4=today, 5=last five minutes, 6=last twenty-four hours + * [NOTE] The values 5 + 6 are not listed in the dropdown, which will display a + * blank value if they are used, but they do work as advertised ***/ + "privacy.sanitize.timeSpan" = 0; +} diff --git a/home/browsers/firefox/arkenfox/4000.nix b/home/browsers/firefox/arkenfox/4000.nix new file mode 100644 index 0000000..950aecf --- /dev/null +++ b/home/browsers/firefox/arkenfox/4000.nix @@ -0,0 +1,41 @@ +{ + /*** [SECTION 4000]: FPI (FIRST PARTY ISOLATION) + 1278037 - indexedDB (FF51+) + 1277803 - favicons (FF52+) + 1264562 - OCSP cache (FF52+) + 1268726 - Shared Workers (FF52+) + 1316283 - SSL session cache (FF52+) + 1317927 - media cache (FF53+) + 1323644 - HSTS and HPKP (FF54+) + 1334690 - HTTP Alternative Services (FF54+) + 1334693 - SPDY/HTTP2 (FF55+) + 1337893 - DNS cache (FF55+) + 1344170 - blob: URI (FF55+) + 1300671 - data:, about: URLs (FF55+) + 1473247 - IP addresses (FF63+) + 1492607 - postMessage with targetOrigin "*" (requires 4002) (FF65+) + 1542309 - top-level domain URLs when host is in the public suffix list (FF68+) + 1506693 - pdfjs range-based requests (FF68+) + 1330467 - site permissions (FF69+) + 1534339 - IPv6 (FF73+) + 1721858 - WebSocket (FF92+) + ***/ + /* 4001: enable First Party Isolation [FF51+] + * [SETUP-WEB] May break cross-domain logins and site functionality until perfected + * [1] https://bugzilla.mozilla.org/buglist.cgi?bug_id=1260931,1299996 ***/ + "privacy.firstparty.isolate" = true; + /* 4002: enforce FPI restriction for window.opener [FF54+] + * [NOTE] Setting this to false may reduce the breakage in 4001 + * FF65+ blocks postMessage with targetOrigin "*" if originAttributes don't match. But + * to reduce breakage it ignores the 1st-party domain (FPD) originAttribute [2][3] + * The 2nd pref removes that limitation and will only allow communication if FPDs also match. + * [1] https://bugzilla.mozilla.org/1319773#c22 + * [2] https://bugzilla.mozilla.org/1492607 + * [3] https://developer.mozilla.org/docs/Web/API/Window/postMessage ***/ + # // user_pref("privacy.firstparty.isolate.restrict_opener_access", true); // [DEFAULT: true] + # // user_pref("privacy.firstparty.isolate.block_post_message", true); + /* 4003: enable scheme with FPI [FF78+] + * [NOTE] Experimental: existing data and site permissions are incompatible + * and some site exceptions may not work e.g. HTTPS-only mode (see 1244) ***/ + # // user_pref("privacy.firstparty.isolate.use_site", true); +} diff --git a/home/browsers/firefox/arkenfox/4500.nix b/home/browsers/firefox/arkenfox/4500.nix new file mode 100644 index 0000000..e45c1fb --- /dev/null +++ b/home/browsers/firefox/arkenfox/4500.nix @@ -0,0 +1,104 @@ +{ + /*** [SECTION 4500]: RFP (RESIST FINGERPRINTING) + RFP covers a wide range of ongoing fingerprinting solutions. + It is an all-or-nothing buy in: you cannot pick and choose what parts you want + + [WARNING] DO NOT USE extensions to alter RFP protected metrics + [WARNING] DO NOT USE prefs in section 4600 with RFP as they can interfere + + FF41+ + 418986 - limit window.screen & CSS media queries leaking identifiable info + [TEST] https://arkenfox.github.io/TZP/tzp.html#screen + FF50+ + 1281949 - spoof screen orientation + 1281963 - hide the contents of navigator.plugins and navigator.mimeTypes (FF50+) + FF55+ + 1330890 - spoof timezone as UTC 0 + 1360039 - spoof navigator.hardwareConcurrency as 2 (see 4601) + 1217238 - reduce precision of time exposed by javascript + FF56+ + 1369303 - spoof/disable performance API (see 4602, 4603) + 1333651 - spoof User Agent & Navigator API (see section 4700) + JS: FF78+ the version is spoofed as ESR, and the OS as Windows 10, OS 10.15, Android 9 (FF91+ as 10), or Linux + HTTP Headers: spoofed as Windows or Android + 1369319 - disable device sensor API (see 4604) + 1369357 - disable site specific zoom (see 4605) + 1337161 - hide gamepads from content (see 4606) + 1372072 - spoof network information API as "unknown" when dom.netinfo.enabled = true (see 4607) + 1333641 - reduce fingerprinting in WebSpeech API (see 4608) + FF57+ + 1369309 - spoof media statistics (see 4610) + 1382499 - reduce screen co-ordinate fingerprinting in Touch API (see 4611) + 1217290 & 1409677 - enable some fingerprinting resistance for WebGL + 1382545 - reduce fingerprinting in Animation API + 1354633 - limit MediaError.message to a whitelist + 1382533 & 1697680 - enable fingerprinting resistance for Presentation API (FF57-87) + This blocks exposure of local IP Addresses via mDNS (Multicast DNS) + FF58+ + 967895 - spoof canvas and enable site permission prompt before allowing canvas data extraction + FF59+ + 1372073 - spoof/block fingerprinting in MediaDevices API + Spoof: enumerate devices reports one "Internal Camera" and one "Internal Microphone" if + media.navigator.enabled is true (see 4612) + Block: suppresses the ondevicechange event (see 4613) + 1039069 - warn when language prefs are set to non en-US (see 0210, 0211) + 1222285 & 1433592 - spoof keyboard events and suppress keyboard modifier events + Spoofing mimics the content language of the document. Currently it only supports en-US. + Modifier events suppressed are SHIFT and both ALT keys. Chrome is not affected. + FF60-67 + 1337157 - disable WebGL debug renderer info (see 4614) (FF60+) + 1459089 - disable OS locale in HTTP Accept-Language headers (ANDROID) (FF62+) + 1479239 - return "no-preference" with prefers-reduced-motion (see 4615) (FF63+) + 1363508 - spoof/suppress Pointer Events (see 4616) (FF64+) + FF65: pointerEvent.pointerid (1492766) + 1485266 - disable exposure of system colors to CSS or canvas (see 4617) (FF67+) + 1407366 - enable inner window letterboxing (see 4504) (FF67+) + 1494034 - return "light" with prefers-color-scheme (see 4618) (FF67+) + FF68-77 + 1564422 - spoof audioContext outputLatency (see 4619) (FF70+) + 1595823 - return audioContext sampleRate as 44100 (see 4619) (FF72+) + 1607316 - spoof pointer as coarse and hover as none (ANDROID) (FF74+) + FF78-90 + 1621433 - randomize canvas (previously FF58+ returned an all-white canvas) (FF78+) + 1653987 - limit font visibility to bundled and "Base Fonts" (see 4620) (Windows, Mac, some Linux) (FF80+) + 1461454 - spoof smooth=true and powerEfficient=false for supported media in MediaCapabilities (FF82+) + ***/ + /* 4501: enable privacy.resistFingerprinting [FF41+] + * [SETUP-WEB] RFP can cause the odd website to break in strange ways, and has a few side affects, + * but is largely robust nowadays. Give it a try. Your choice. Also see 4504 (letterboxing). + * [1] https://bugzilla.mozilla.org/418986 ***/ + "privacy.resistFingerprinting" = true; + /* 4502: set new window sizes to round to hundreds [FF55+] [SETUP-CHROME] + * Width will round down to multiples of 200s and height to 100s, to fit your screen. + * The override values are a starting point to round from if you want some control + * [1] https://bugzilla.mozilla.org/1330882 ***/ + # // user_pref("privacy.window.maxInnerWidth", 1000); + # // user_pref("privacy.window.maxInnerHeight", 1000); + /* 4503: disable mozAddonManager Web API [FF57+] + * [NOTE] To allow extensions to work on AMO, you also need 2662 + * [1] https://bugzilla.mozilla.org/buglist.cgi?bug_id=1384330,1406795,1415644,1453988 ***/ + "privacy.resistFingerprinting.block_mozAddonManager" = true; # [HIDDEN PREF] + /* 4504: enable RFP letterboxing [FF67+] + * Dynamically resizes the inner window by applying margins in stepped ranges [2] + * If you use the dimension pref, then it will only apply those resolutions. The format is + * "width1xheight1, width2xheight2, ..." (e.g. "800x600, 1000x1000, 1600x900") + * [SETUP-WEB] This does NOT require RFP (see 4501) **for now**, so if you're not using 4501, or you are but + * dislike margins being applied, then flip this pref, keeping in mind that it is effectively fingerprintable + * [WARNING] DO NOT USE: the dimension pref is only meant for testing + * [1] https://bugzilla.mozilla.org/1407366 + * [2] https://hg.mozilla.org/mozilla-central/rev/6d2d7856e468#l2.32 ***/ + "privacy.resistFingerprinting.letterboxing" = true; # [HIDDEN PREF] + # // user_pref("privacy.resistFingerprinting.letterboxing.dimensions", ""); // [HIDDEN PREF] + /* 4505: experimental RFP [FF91+] + * [WARNING] DO NOT USE unless testing, see [1] comment 12 + * [1] https://bugzilla.mozilla.org/1635603 ***/ + # // user_pref("privacy.resistFingerprinting.exemptedDomains", "*.example.invalid"); + # // user_pref("privacy.resistFingerprinting.testGranularityMask", 0); + /* 4510: disable showing about:blank as soon as possible during startup [FF60+] + * When default true this no longer masks the RFP chrome resizing activity + * [1] https://bugzilla.mozilla.org/1448423 ***/ + "browser.startup.blankWindow" = false; + /* 4520: disable chrome animations [FF77+] [RESTART] + * [NOTE] pref added in FF63, but applied to chrome in FF77. RFP spoofs this for web content ***/ + "ui.prefersReducedMotion" = 1; # [HIDDEN PREF] +} diff --git a/home/browsers/firefox/arkenfox/4600.nix b/home/browsers/firefox/arkenfox/4600.nix new file mode 100644 index 0000000..285bb39 --- /dev/null +++ b/home/browsers/firefox/arkenfox/4600.nix @@ -0,0 +1,101 @@ +{ + /*** [SECTION 4600]: RFP ALTERNATIVES + [WARNING] DO NOT USE prefs in this section with RFP as they can interfere + ***/ + /* [SETUP-non-RFP] Non-RFP users replace the * with a slash on this line to enable these + // FF55+ + // 4601: [2514] spoof number of CPU cores [FF48+] + // [1] https://bugzilla.mozilla.org/1008453 + // [2] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/21675 + // [3] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/22127 + // [4] https://html.spec.whatwg.org/multipage/workers.html#navigator.hardwareconcurrency + user_pref("dom.maxHardwareConcurrency", 2); + // FF56+ + // 4602: [2411] disable resource/navigation timing + user_pref("dom.enable_resource_timing", false); + // 4603: [2412] disable timing attacks + // [1] https://wiki.mozilla.org/Security/Reviews/Firefox/NavigationTimingAPI + // user_pref("dom.enable_performance", false); + // 4604: [2512] disable device sensor API + // Optional protection depending on your device + // [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/15758 + // [2] https://blog.lukaszolejnik.com/stealing-sensitive-browser-data-with-the-w3c-ambient-light-sensor-api/ + // [3] https://bugzilla.mozilla.org/buglist.cgi?bug_id=1357733,1292751 + // user_pref("device.sensors.enabled", false); + // 4605: [2515] disable site specific zoom + // Zoom levels affect screen res and are highly fingerprintable. This does not stop you using + // zoom, it will just not use/remember any site specific settings. Zoom levels on new tabs + // and new windows are reset to default and only the current tab retains the current zoom + user_pref("browser.zoom.siteSpecific", false); + // 4606: [2501] disable gamepad API - USB device ID enumeration + // Optional protection depending on your connected devices + // [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/13023 + // user_pref("dom.gamepad.enabled", false); + // 4607: [2503] disable giving away network info [FF31+] + // e.g. bluetooth, cellular, ethernet, wifi, wimax, other, mixed, unknown, none + // [1] https://developer.mozilla.org/docs/Web/API/Network_Information_API + // [2] https://wicg.github.io/netinfo/ + // [3] https://bugzilla.mozilla.org/960426 + user_pref("dom.netinfo.enabled", false); // [DEFAULT: true on Android] + // 4608: [2021] disable the SpeechSynthesis (Text-to-Speech) part of the Web Speech API + // [1] https://developer.mozilla.org/docs/Web/API/Web_Speech_API + // [2] https://developer.mozilla.org/docs/Web/API/SpeechSynthesis + // [3] https://wiki.mozilla.org/HTML5_Speech_API + user_pref("media.webspeech.synth.enabled", false); + // FF57+ + // 4610: [2506] disable video statistics - JS performance fingerprinting [FF25+] + // [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/15757 + // [2] https://bugzilla.mozilla.org/654550 + user_pref("media.video_stats.enabled", false); + // 4611: [2509] disable touch events + // fingerprinting attack vector - leaks screen res & actual screen coordinates + // 0=disabled, 1=enabled, 2=autodetect + // Optional protection depending on your device + // [1] https://developer.mozilla.org/docs/Web/API/Touch_events + // [2] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/10286 + // user_pref("dom.w3c_touch_events.enabled", 0); + // FF59+ + // 4612: [2505] disable media device enumeration [FF29+] + // [1] https://wiki.mozilla.org/Media/getUserMedia + // [2] https://developer.mozilla.org/docs/Web/API/MediaDevices/enumerateDevices + user_pref("media.navigator.enabled", false); + // 4613: [2511] disable MediaDevices change detection [FF51+] + // [1] https://developer.mozilla.org/docs/Web/Events/devicechange + // [2] https://developer.mozilla.org/docs/Web/API/MediaDevices/ondevicechange + user_pref("media.ondevicechange.enabled", false); + // FF60+ + // 4614: [2522] disable WebGL debug info being available to websites + // [1] https://bugzilla.mozilla.org/1171228 + // [2] https://developer.mozilla.org/docs/Web/API/WEBGL_debug_renderer_info + user_pref("webgl.enable-debug-renderer-info", false); + // FF63+ + // 4615: enforce prefers-reduced-motion as no-preference [FF63+] [RESTART] + // 0=no-preference, 1=reduce + user_pref("ui.prefersReducedMotion", 0); // [HIDDEN PREF] + // FF64+ + // 4616: [2516] disable PointerEvents [FF86 or lower] + // [1] https://developer.mozilla.org/docs/Web/API/PointerEvent + // [-] https://bugzilla.mozilla.org/1688105 + user_pref("dom.w3c_pointer_events.enabled", false); + // FF67+ + // 4617: [2618] disable exposure of system colors to CSS or canvas [FF44+] + // [NOTE] See second listed bug: may cause black on black for elements with undefined colors + // [SETUP-CHROME] Might affect CSS in themes and extensions + // [1] https://bugzilla.mozilla.org/buglist.cgi?bug_id=232227,1330876 + user_pref("ui.use_standins_for_native_colors", true); + // 4618: enforce prefers-color-scheme as light [FF67+] + // 0=light, 1=dark : This overrides your OS value + user_pref("ui.systemUsesDarkTheme", 0); // [HIDDEN PREF] + // FF72+ + // 4619: [2510] disable Web Audio API [FF51+] + // [1] https://bugzilla.mozilla.org/1288359 + // user_pref("dom.webaudio.enabled", false); + // FF80+ + // 4620: limit font visibility (Windows, Mac, some Linux) [FF79+] + // Uses hardcoded lists with two parts: kBaseFonts + kLangPackFonts [1] + // 1=only base system fonts, 2=also fonts from optional language packs, 3=also user-installed fonts + // [NOTE] Bundled fonts are auto-allowed + // [1] https://searchfox.org/mozilla-central/search?path=StandardFonts*.inc + user_pref("layout.css.font-visibility.level", 1); + // ***/ +} diff --git a/home/browsers/firefox/arkenfox/4700.nix b/home/browsers/firefox/arkenfox/4700.nix new file mode 100644 index 0000000..c56929f --- /dev/null +++ b/home/browsers/firefox/arkenfox/4700.nix @@ -0,0 +1,17 @@ +{ + /*** [SECTION 4700]: RFP ALTERNATIVES (USER AGENT SPOOFING) + These prefs are insufficient and leak. Use RFP and **nothing else** + - Many of the user agent components can be derived by other means. When those + values differ, you provide more bits and raise entropy. Examples include + workers, iframes, headers, tcp/ip attributes, feature detection, and many more + - Web extensions also lack APIs to fully protect spoofing + ***/ + /* 4701: navigator DOM object overrides + * [WARNING] DO NOT USE ***/ + # // user_pref("general.appname.override", ""); // [HIDDEN PREF] + # // user_pref("general.appversion.override", ""); // [HIDDEN PREF] + # // user_pref("general.buildID.override", ""); // [HIDDEN PREF] + # // user_pref("general.oscpu.override", ""); // [HIDDEN PREF] + # // user_pref("general.platform.override", ""); // [HIDDEN PREF] + # // user_pref("general.useragent.override", ""); // [HIDDEN PREF] +} diff --git a/home/browsers/firefox/arkenfox/5000.nix b/home/browsers/firefox/arkenfox/5000.nix new file mode 100644 index 0000000..503f7b0 --- /dev/null +++ b/home/browsers/firefox/arkenfox/5000.nix @@ -0,0 +1,45 @@ +{ + /*** [SECTION 5000]: PERSONAL + Non-project related but useful. If any of these interest you, add them to your overrides + To save some overrides, we've made a few active as they seem to be universally used ***/ + /* WELCOME & WHAT's NEW NOTICES ***/ + "browser.startup.homepage_override.mstone" = "ignore"; # master switch + # // user_pref("startup.homepage_welcome_url", ""); + # // user_pref("startup.homepage_welcome_url.additional", ""); + # // user_pref("startup.homepage_override_url", ""); // What's New page after updates + /* WARNINGS ***/ + # // user_pref("browser.tabs.warnOnClose", false); + # // user_pref("browser.tabs.warnOnCloseOtherTabs", false); + # // user_pref("browser.tabs.warnOnOpen", false); + # // user_pref("full-screen-api.warning.delay", 0); + # // user_pref("full-screen-api.warning.timeout", 0); + /* APPEARANCE ***/ + # // user_pref("browser.download.autohideButton", false); // [FF57+] + # // user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true); // [FF68+] allow userChrome/userContent + /* CONTENT BEHAVIOR ***/ + # // user_pref("accessibility.typeaheadfind", true); // enable "Find As You Type" + # // user_pref("clipboard.autocopy", false); // disable autocopy default [LINUX] + # // user_pref("layout.spellcheckDefault", 2); // 0=none, 1-multi-line, 2=multi-line & single-line + /* UX BEHAVIOR ***/ + # // user_pref("browser.backspace_action", 2); // 0=previous page, 1=scroll up, 2=do nothing + # // user_pref("browser.quitShortcut.disabled", true); // disable Ctrl-Q quit shortcut [LINUX] [MAC] [FF87+] + # // user_pref("browser.tabs.closeWindowWithLastTab", false); + # // user_pref("browser.tabs.loadBookmarksInTabs", true); // open bookmarks in a new tab [FF57+] + # // user_pref("browser.urlbar.decodeURLsOnCopy", true); // see bugzilla 1320061 [FF53+] + # // user_pref("general.autoScroll", false); // middle-click enabling auto-scrolling [DEFAULT: false on Linux] + # // user_pref("ui.key.menuAccessKey", 0); // disable alt key toggling the menu bar [RESTART] + # // user_pref("view_source.tab", false); // view "page/selection source" in a new window [FF68+, FF59 and under] + /* UX FEATURES: disable and hide the icons and menus ***/ + "browser.messaging-system.whatsNewPanel.enabled" = false; # What's New toolbar icon [FF69+] + # // user_pref("extensions.pocket.enabled", false); // Pocket Account [FF46+] + # // user_pref("identity.fxaccounts.enabled", false); // Firefox Accounts & Sync [FF60+] [RESTART] + # // user_pref("reader.parse-on-load.enabled", false); // Reader View + /* OTHER ***/ + # // user_pref("browser.bookmarks.max_backups", 2); + "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons" = false; # disable CFR [FF67+] + # // [SETTING] General>Browsing>Recommend extensions as you browse + "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features" = false; # disable CFR [FF67+] + # // [SETTING] General>Browsing>Recommend features as you browse + # // user_pref("network.manage-offline-status", false); // see bugzilla 620472 + # // user_pref("xpinstall.signatures.required", false); // enforced extension signing (Nightly/ESR) +} diff --git a/home/browsers/firefox/arkenfox/9999.nix b/home/browsers/firefox/arkenfox/9999.nix new file mode 100644 index 0000000..605285b --- /dev/null +++ b/home/browsers/firefox/arkenfox/9999.nix @@ -0,0 +1,62 @@ +{ + /*** [SECTION 9999]: DEPRECATED / REMOVED / LEGACY / RENAMED + Documentation denoted as [-]. Items deprecated in FF78 or earlier have been archived at [1], + which also provides a link-clickable, viewer-friendly version of the deprecated bugzilla tickets + [1] https://github.com/arkenfox/user.js/issues/123 + ***/ + /* ESR78.x still uses all the following prefs + // [NOTE] replace the * with a slash in the line above to re-enable them + // FF79 + // 0212: enforce fallback text encoding to match en-US + // When the content or server doesn't declare a charset the browser will + // fallback to the "Current locale" based on your application language + // [TEST] https://hsivonen.com/test/moz/check-charset.htm + // [1] https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/20025 + // [-] https://bugzilla.mozilla.org/1603712 + user_pref("intl.charset.fallback.override", "windows-1252"); + // FF82 + // 0206: disable geographically specific results/search engines e.g. "browser.search.*.US" + // i.e. ignore all of Mozilla's various search engines in multiple locales + // [-] https://bugzilla.mozilla.org/1619926 + user_pref("browser.search.geoSpecificDefaults", false); + user_pref("browser.search.geoSpecificDefaults.url", ""); + // FF86 + // 1205: disable SSL Error Reporting + // [1] https://firefox-source-docs.mozilla.org/browser/base/sslerrorreport/preferences.html + // [-] https://bugzilla.mozilla.org/1681839 + user_pref("security.ssl.errorReporting.automatic", false); + user_pref("security.ssl.errorReporting.enabled", false); + user_pref("security.ssl.errorReporting.url", ""); + // 2653: disable hiding mime types (Options>General>Applications) not associated with a plugin + // [-] https://bugzilla.mozilla.org/1581678 + user_pref("browser.download.hide_plugins_without_extensions", false); + // FF87 + // 0105d: disable Activity Stream recent Highlights in the Library [FF57+] + // [-] https://bugzilla.mozilla.org/1689405 + // user_pref("browser.library.activity-stream.enabled", false); + // FF89 + // 0309: disable sending Flash crash reports + // [-] https://bugzilla.mozilla.org/1682030 [underlying NPAPI code removed] + user_pref("dom.ipc.plugins.flash.subprocess.crashreporter.enabled", false); + // 0310: disable sending the URL of the website where a plugin crashed + // [-] https://bugzilla.mozilla.org/1682030 [underlying NPAPI code removed] + user_pref("dom.ipc.plugins.reportCrashURL", false); + // 1243: block unencrypted requests from Flash on encrypted pages to mitigate MitM attacks [FF59+] + // [1] https://bugzilla.mozilla.org/1190623 + // [-] https://bugzilla.mozilla.org/1682030 [underlying NPAPI code removed] + user_pref("security.mixed_content.block_object_subrequest", true); + // 1803: disable Flash plugin + // 0=deactivated, 1=ask, 2=enabled + // ESR52.x is the last branch to *fully* support NPAPI, FF52+ stable only supports Flash + // [NOTE] You can still override individual sites via site permissions + // [-] https://bugzilla.mozilla.org/1682030 [underlying NPAPI code removed] + user_pref("plugin.state.flash", 0); // [DEFAULT: 1] + // FF90 + // 0708: disable FTP [FF60+] + // [-] https://bugzilla.mozilla.org/1574475 + // user_pref("network.ftp.enabled", false); // [DEFAULT: false FF88+] + // 2730: enforce no offline cache storage (appCache) [FF71+] + // [-] https://bugzilla.mozilla.org/1694662 + user_pref("browser.cache.offline.storage.enable", false); // [DEFAULT: false FF84+] + // ***/ +} diff --git a/home/browsers/firefox/arkenfox/default.nix b/home/browsers/firefox/arkenfox/default.nix new file mode 100644 index 0000000..5b63751 --- /dev/null +++ b/home/browsers/firefox/arkenfox/default.nix @@ -0,0 +1,107 @@ +/****** +* name: arkenfox user.js +* date: 30 July 2021 +* version 91-alpha +* url: https://github.com/arkenfox/user.js +* license: MIT: https://github.com/arkenfox/user.js/blob/master/LICENSE.txt + +* README: + + 1. Consider using Tor Browser if it meets your needs or fits your threat model better + * https://www.torproject.org/about/torusers.html.en + 2. Required reading: Overview, Backing Up, Implementing, and Maintenance entries + * https://github.com/arkenfox/user.js/wiki + 3. If you skipped step 2, return to step 2 + 4. Make changes + * There are often trade-offs and conflicts between security vs privacy vs anti-fingerprinting + and these need to be balanced against functionality & convenience & breakage + * Some site breakage and unintended consequences will happen. Everyone's experience will differ + e.g. some user data is erased on close (section 2800), change this to suit your needs + * While not 100% definitive, search for "[SETUP" tags + e.g. third party images/videos not loading on some sites? check 1603 + * Take the wiki link in step 2 and read the Troubleshooting entry + 5. Some tag info + [SETUP-SECURITY] it's one item, read it + [SETUP-WEB] can cause some websites to break + [SETUP-CHROME] changes how Firefox itself behaves (i.e. not directly website related) + [SETUP-PERF] may impact performance + [WARNING] used on some commented out items, heed them + 6. Override Recipes: https://github.com/arkenfox/user.js/issues/1080 + +* RELEASES: https://github.com/arkenfox/user.js/releases + + * It is best to use the arkenfox release that is optimized for and matches your Firefox version + * EVERYONE: each release + - run prefsCleaner or reset deprecated prefs (9999s) and prefs made redundant by RPF (4600s) + - re-enable section 4600 if you don't use RFP + ESR78 + - If you are not using arkenfox v78... (not a definitive list) + - 1244: HTTPS-Only mode is enabled + - 1401: document fonts is inactive as it is now covered by RFP in FF80+ + - 2626: non-native widget theme is enforced + - 4600: some prefs may apply even if you use RFP + - 9999: switch the appropriate deprecated section(s) back on + +* INDEX: + + 0100: STARTUP + 0200: GEOLOCATION / LANGUAGE / LOCALE + 0300: QUIET FOX + 0400: BLOCKLISTS / SAFE BROWSING + 0500: SYSTEM ADD-ONS / EXPERIMENTS + 0600: BLOCK IMPLICIT OUTBOUND + 0700: HTTP* / TCP/IP / DNS / PROXY / SOCKS etc + 0800: LOCATION BAR / SEARCH BAR / SUGGESTIONS / HISTORY / FORMS + 0900: PASSWORDS + 1000: CACHE / SESSION (RE)STORE / FAVICONS + 1200: HTTPS (SSL/TLS / OCSP / CERTS / HPKP / CIPHERS) + 1400: FONTS + 1600: HEADERS / REFERERS + 1700: CONTAINERS + 1800: PLUGINS + 2000: MEDIA / CAMERA / MIC + 2200: WINDOW MEDDLING & LEAKS / POPUPS + 2300: WEB WORKERS + 2400: DOM (DOCUMENT OBJECT MODEL) & JAVASCRIPT + 2500: HARDWARE FINGERPRINTING + 2600: MISCELLANEOUS + 2700: PERSISTENT STORAGE + 2800: SHUTDOWN + 4000: FPI (FIRST PARTY ISOLATION) + 4500: RFP (RESIST FINGERPRINTING) + 4600: RFP ALTERNATIVES + 4700: RFP ALTERNATIVES (USER AGENT SPOOFING) + 5000: PERSONAL + 9999: DEPRECATED / REMOVED / LEGACY / RENAMED + +******/ + +import ./0000.nix // +import ./0100.nix // +import ./0200.nix // +import ./0300.nix // +import ./0400.nix // +import ./0500.nix // +import ./0600.nix // +import ./0700.nix // +import ./0800.nix // +import ./0900.nix // +import ./1000.nix // +import ./1400.nix // +import ./1600.nix // +import ./1700.nix // +import ./1800.nix // +import ./2000.nix // +import ./2200.nix // +import ./2300.nix // +import ./2400.nix // +import ./2500.nix // +import ./2600.nix // +import ./2700.nix // +import ./2800.nix // +import ./4000.nix // +# import ./4500.nix // +import ./4600.nix // +import ./4700.nix // +import ./5000.nix // +import ./9999.nix diff --git a/home/browsers/firefox/default.nix b/home/browsers/firefox/default.nix new file mode 100644 index 0000000..e3f7884 --- /dev/null +++ b/home/browsers/firefox/default.nix @@ -0,0 +1,71 @@ +{ config, pkgs, ... }: + + +{ + nixpkgs.config = { + packageOverrides = pkgs: { + nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") { + inherit pkgs; + }; + }; + }; + # nix-env -f '' -qaP -A nur.repos.rycee.firefox-addons + programs.firefox = { + enable = true; + # maybe enable tridactyl? + # nix-env -f '' -qaP -A nur.repos.rycee.firefox-addons + extensions = with pkgs.nur.repos.rycee.firefox-addons; [ + browserpass + canvasblocker + clearurls + cookie-autodelete + darkreader + floccus + foxyproxy-standard + https-everywhere + i-dont-care-about-cookies + localcdn + noscript + privacy-possum + privacy-redirect + ublock-origin + vimium + # todo: AdNauseam, wallabagger, DownThemAll! Wayback Machine + ]; + profiles = { + default = { + id = 0; + name = "default"; + isDefault = true; + # settings = import ./arkenfox // { + settings = { + # change some values from arkenfox's defaults + "privacy.resistFingerprinting" = false; # if true, this would the window size to rounded dimensions, which is too annoying on a tiling window manager + "extensions.pocket.enabled" = false; + "identity.fxaccounts.enabled" = false; + "browser.search.suggest.enabled" = true; + "browser.urlbar.suggest.searches" = true; + "keyword.enable" = true; + + # for Firefox-UI-Fix + "toolkit.legacyUserProfileCustomizations.stylesheets" = true; + "browser.proton.enabled" = true; + "svg.context-properties.content.enabled" = true; + "layout.css.backdrop-filter.enabled" = true; + "browser.compactmode.show" = true; + "browser.urlbar.suggest.calculator" = true; + + "browser.uidensity" = 1; + + # "browser.search.region" = "GB"; + # "browser.search.isUS" = false; + # "distribution.searchplugins.defaultLocale" = "en-GB"; + # "general.useragent.locale" = "en-GB"; + # "browser.bookmarks.showMobileBookmarks" = true; + }; + # userChrome = builtins.readFile ./lepton/userChrome.css; + # userContent = builtins.readFile ./lepton/userContent.css; + }; + }; + }; +} diff --git a/home/browsers/firefox/lepton/userChrome.css b/home/browsers/firefox/lepton/userChrome.css new file mode 100644 index 0000000..cf80843 --- /dev/null +++ b/home/browsers/firefox/lepton/userChrome.css @@ -0,0 +1,2179 @@ +@media (-moz-proton) { + /** Default Thme - Contrast *************************************************/ + /*= Lightmode - Color darker ===============================================*/ + :root[lwtheme-mozlightdark][lwthemetextcolor="dark"] { + --lwt-accent-color: rgb(229, 229, 235) !important; /* Original: rgb(240, 240, 244) */ + } + + /*= Darkmode - Color lighter ===============================================*/ + :root[lwtheme-mozlightdark][lwthemetextcolor="bright"] { + --toolbar-bgcolor: rgba(43, 42, 51, 5) !important; /* Original: rgba(43, 42, 51, 1) */ + } + + /** Theme - Compatibility ***************************************************/ + /*= Hotfix #98 =============================================================*/ + /* Hidden Tab Panel Padding */ + #allTabsMenu-hiddenTabsView .all-tabs-item { + margin-inline: 8px; + border-radius: 4px; + } + + /*= Light Weight Theme =====================================================*/ + /* Header Image */ + :root[lwtheme-image] { + background-image: var(--lwt-header-image) !important; /* Original: var(--lwt-header-image) */ + background-repeat: no-repeat !important; + background-position: right top !important; + } + :root[lwtheme-image] #navigator-toolbox:-moz-lwtheme { + background-image: var(--lwt-additional-images) !important; /* Original: var(--lwt-header-image), var(--lwt-additional-images); */ + background-repeat: var(--lwt-background-tiling) !important; + background-position: var(--lwt-background-alignment) !important; + background-color: unset !important; /* Original: var(--lwt-accent-color) */ + } + + /* Navbar Border */ + #navigator-toolbox:-moz-lwtheme { + --tabs-border-color: rgba(0,0,0,.3); + } + + /*= Windows 7 ==============================================================*/ + @media (-moz-os-version: windows-win7) { + /* Header Color */ + :root:not([lwtheme-image]) #navigator-toolbox:-moz-lwtheme { + background-color: var(--lwt-accent-color) !important; + } + #TabsToolbar:-moz-lwtheme { + color: var(--lwt-text-color) !important; + + /* Remove Aero */ + /* Original: radial-gradient(eclipse at bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.5) 80%, transparent) */ + background-image: unset !important; + } + } + + /** System Default Theme ****************************************************/ + /*= Common - URL Bar focus color ===========================================*/ + @media (-moz-windows-accent-color-in-titlebar), + (-moz-gtk-csd-available) { + /* URL Bar */ + :root[tabsintitlebar]:not(:-moz-window-inactive, :-moz-lwtheme), + :root[tabsintitlebar][lwt-default-theme-in-dark-mode]:not(:-moz-window-inactive) { + --focus-outline-color: -moz-accent-color !important; + } + + :root[tabsintitlebar]:not(:-moz-window-inactive, :-moz-lwtheme) #urlbar[open] > #urlbar-background, + :root[tabsintitlebar][lwt-default-theme-in-dark-mode]:not(:-moz-window-inactive) #urlbar[open] > #urlbar-background { + border-color: color-mix(in srgb, -moz-accent-color 50%, transparent) !important; /* Like: --toolbar-field-focus-border-color */ + } + } + + /*= Windows10 - Titlebar accent color ======================================*/ + @media (-moz-windows-accent-color-in-titlebar) { + /* Tab Bar */ + :root[tabsintitlebar]:not(:-moz-window-inactive, :-moz-lwtheme) .titlebar-color, + :root[tabsintitlebar][lwt-default-theme-in-dark-mode]:not(:-moz-window-inactive) .titlebar-color { + color: -moz-accent-color-foreground; + background-color: -moz-accent-color; + } + + :root[tabsintitlebar]:not(:-moz-window-inactive, :-moz-lwtheme) .toolbar-items, + :root[tabsintitlebar][lwt-default-theme-in-dark-mode]:not(:-moz-window-inactive) .toolbar-items { + --toolbarbutton-hover-background: color-mix(in srgb, -moz-accent-color-foreground 10%, transparent); + --toolbarbutton-active-background: color-mix(in srgb, -moz-accent-color-foreground 15%, transparent); + } + } + + /*= GTK - URL View url accent color ========================================*/ + @media (-moz-gtk-csd-available) { + :root:not(:-moz-lwtheme) .urlbarView-url { + --urlbar-popup-url-color: -moz-accent-color; + } + + /* Nightly Compatibility */ + :root:not(:-moz-lwtheme) #urlbar { + --toolbar-field-focus-color: var(--toolbar-field-color); /* Nightly: rgba(0, 0, 0, 1) */ + --toolbar-field-focus-background-color: var(--toolbar-field-background-color); /* Nightly: white */ + } + } + + /** Fully Theme Mode ********************************************************/ + /* Default Themes + https://github.com/mozilla/gecko-dev/blob/master/toolkit/mozapps/extensions/default-theme/manifest.json + https://github.com/mozilla/gecko-dev/blob/master/browser/themes/addons/light/manifest.json + https://github.com/mozilla/gecko-dev/blob/master/browser/themes/addons/dark/manifest.json + */ + + /*= Default Colors - Hardcorded ============================================*/ + /* Based on chrome://global/skin/in-content/common.css */ + :host, + :root { + --in-content-page-color: rgb(21, 20, 26); + --in-content-page-background: #fff; + --in-content-text-color: var(--in-content-page-color); + --in-content-deemphasized-text: rgb(91, 91, 102); + --in-content-box-background: #fff; + --in-content-box-background-odd: rgba(12, 12, 13, 0.05); /* grey 90 a05 */ + --in-content-box-border-color: color-mix(in srgb, currentColor 41%, transparent); + --in-content-box-info-background: #f0f0f4; + --in-content-item-hover: color-mix(in srgb, var(--in-content-primary-button-background) 20%, transparent); + --in-content-item-hover-text: var(--in-content-page-color); + --in-content-item-selected: var(--in-content-primary-button-background); + --in-content-item-selected-text: var(--in-content-primary-button-text-color); + --in-content-icon-color: rgb(91,91,102); + --in-content-accent-color: #0a84ff; + --in-content-accent-color-active: #0060df; + --in-content-border-hover: var(--grey-90-a50); + --in-content-border-invalid: var(--red-50); + --in-content-border-color: #d7d7db; + --in-content-error-text-color: #c50042; + --in-content-link-color: var(--blue-60); + --in-content-link-color-hover: var(--blue-70); + --in-content-link-color-active: var(--blue-80); + --in-content-link-color-visited: var(--blue-60); + /* button background states are also used for checkboxes and radiobuttons */ + --in-content-button-text-color: var(--in-content-text-color); + --in-content-button-text-color-hover: var(--in-content-text-color); + --in-content-button-background: rgba(207,207,216,.33); + --in-content-button-background-hover: rgba(207,207,216,.66); + --in-content-button-background-active: rgb(207,207,216); + --in-content-primary-button-text-color: rgb(251,251,254); + --in-content-primary-button-text-color-hover: var(--in-content-primary-button-text-color); + --in-content-primary-button-background: #0061e0; + --in-content-primary-button-background-hover: #0250bb; + --in-content-primary-button-background-active: #053e94; + --in-content-danger-button-background: #e22850; + --in-content-danger-button-background-hover: #c50042; + --in-content-danger-button-background-active: #810220; + --in-content-focus-outline-color: var(--in-content-primary-button-background); + + /* Note: 1px smaller than we want because we have a 1px transparent border. */ + /* Once proton ships, these can probably stop being variables. */ + --in-content-button-border-radius: 4px; + --in-content-button-horizontal-padding: 15px; + --in-content-button-vertical-padding: 7px; + + --in-content-table-background: #f8f8fa; + --in-content-table-border-dark-color: #d1d1d1; + --in-content-table-header-background: #0a84ff; + --in-content-table-header-color: #ffffff; + --in-content-sidebar-width: 240px; + + --dialog-warning-text-color: var(--red-60); + + --checkbox-border-color: var(--in-content-box-border-color); + --checkbox-unchecked-bgcolor: var(--in-content-button-background); + --checkbox-unchecked-hover-bgcolor: var(--in-content-button-background-hover); + --checkbox-unchecked-active-bgcolor: var(--in-content-button-background-active); + --checkbox-checked-bgcolor: var(--in-content-primary-button-background); + --checkbox-checked-color: var(--in-content-primary-button-text-color); + --checkbox-checked-border-color: transparent; + --checkbox-checked-hover-bgcolor: var(--in-content-primary-button-background-hover); + --checkbox-checked-active-bgcolor: var(--in-content-primary-button-background-active); + --blue-40: #45a1ff; + --blue-50: #0a84ff; + --blue-60: #0060df; + --blue-70: #003eaa; + --blue-80: #002275; + --grey-30: #d7d7db; + --grey-60: #4a4a4f; + --grey-90-a10: rgba(12, 12, 13, 0.1); + --grey-90-a20: rgba(12, 12, 13, 0.2); + --grey-90-a30: rgba(12, 12, 13, 0.3); + --grey-90-a50: rgba(12, 12, 13, 0.5); + --grey-90-a60: rgba(12, 12, 13, 0.6); + --green-50: #30e60b; + --green-60: #12bc00; + --green-70: #058b00; + --green-80: #006504; + --green-90: #003706; + --orange-50: #ff9400; + --red-40: #ff4f5e; + --red-50: #ff0039; + --red-60: #d70022; + --red-70: #a4000f; + --red-80: #5a0002; + --red-90: #3e0200; + --yellow-50: #ffe900; + --yellow-60: #d7b600; + --yellow-60-a30: rgba(215, 182, 0, 0.3); + --yellow-70: #a47f00; + --yellow-80: #715100; + --yellow-90: #3e2800; + + --shadow-10: 0 1px 4px var(--grey-90-a10); + --shadow-30: 0 4px 16px var(--grey-90-a10); + + --card-padding: 16px; + --card-shadow: var(--shadow-10); + --card-outline-color: var(--grey-30); + --card-shadow-hover: var(--card-shadow), 0 0 0 5px var(--card-outline-color); + } + + @media (-moz-toolbar-prefers-color-scheme: dark) { + :host, + :root { + /* Keep these in sync with layout/base/PresShell.cpp, and plaintext.css */ + --in-content-page-background: rgb(28,27,34); + --in-content-page-color: rgb(251,251,254); + --in-content-deemphasized-text: rgb(191,191,201); + + --in-content-box-background: rgb(35, 34, 43); + --in-content-box-background-odd: rgba(249,249,250,0.05); + --in-content-box-info-background: rgba(249,249,250,0.15); + + --in-content-border-color: rgba(249,249,250,0.2); + --in-content-border-hover: rgba(249,249,250,0.3); + --in-content-border-invalid: rgb(255,132,139); + + --in-content-error-text-color: #FF9AA2; + + --in-content-button-background: rgb(43,42,51); + --in-content-button-background-hover: rgb(82,82,94); + --in-content-button-background-active: rgb(91,91,102); + --in-content-icon-color: rgb(251,251,254); + + --in-content-primary-button-text-color: rgb(43,42,51); + --in-content-primary-button-background: rgb(0,221,255); + --in-content-primary-button-background-hover: rgb(128,235,255); + --in-content-primary-button-background-active: rgb(170,242,255); + + --in-content-danger-button-background: #ff848b; + --in-content-danger-button-background-hover: #ffbdc5; + --in-content-danger-button-background-active: #ffdfe7; + + --in-content-table-background: rgb(35, 34, 43); + --in-content-table-border-dark-color: rgba(249,249,250,0.2); + --in-content-table-header-background: rgb(5, 64, 150); + --in-content-table-header-color: var(--in-content-page-color); + + --in-content-accent-color: var(--in-content-primary-button-background); + --in-content-accent-color-active: var(--in-content-primary-button-background-hover); + --in-content-link-color: var(--in-content-primary-button-background); + --in-content-link-color-hover: var(--in-content-primary-button-background-hover); + --in-content-link-color-active: var(--in-content-primary-button-background-active); + --in-content-link-color-visited: var(--in-content-link-color); + + --card-outline-color: var(--grey-60); + + --dialog-warning-text-color: var(--red-40); + + scrollbar-color: rgba(249,249,250,.4) rgba(20,20,25,.3); + } + } + + /*== Menu color ===========================================================*/ + :root, + menupopup { + /* is same as toolbar color https://github.com/mozilla/gecko-dev/blob/master/toolkit/themes/windows/global/global.css#L17-L67 */ + --menu-color: var(--toolbar-color, var(--in-content-page-color)) !important; + --menu-background-color: var(--toolbar-bgcolor, var(--in-content-button-background)) !important; + + --menu-border-color: var(--toolbarbutton-active-background, var(--button-active-bgcolor, var(--card-outline-color))) !important; + --menuitem-hover-background-color: var(--toolbarbutton-hover-background, var(--button-hover-bgcolor, var(--in-content-button-background-hover))) !important; + + --menu-disabled-color: color-mix(in srgb, var(--menu-color) 40%, transparent) !important; + --menuitem-disabled-hover-background-color: color-mix(in srgb, var(--menuitem-hover-background-color) 40%, transparent) !important; + } + + /* Fallback background */ + menupopup { + background-color: var(--lwt-accent-color, var(--in-content-page-background)) !important; + } + + /* Fully Dark Mode **********************************************************/ + /*= Remove White Flash =====================================================*/ + #tabbrowser-tabbox, + #tabbrowser-tabpanels, + browser[type=content-primary], + browser[type=content] > html { + background: var(--in-content-page-background) !important; + } + + /*= Notification ===========================================================*/ + @-moz-document url("chrome://global/content/alerts/alert.xhtml") { + /* line below removes background from the notification "window" on linux */ + #alertNotification{ background: transparent !important; } + + #alertBox { + color: var(--menu-color, #15141a) !important; + background-color: var(--menu-background-color, #f9f9fb) !important; + border-color: var(--menu-border-color, #cfcfd8) !important; + border-radius: 6px !important; + -moz-window-shadow: cliprounded !important; + } + #alertSettings { + fill: currentColor !important; + color: inherit !important; + border-radius: 0 !important; + margin-inline: 0 !important; + margin-bottom: -4px !important; + } + + /* Shape */ + .close-icon > .toolbarbutton-icon, + #alertSettings > .button-box > .box-inherit { + border-radius: 4px !important; + padding: 2px !important; + margin: 2px 2px -2px 0 !important; + } + #alertSettings > .button-box > .box-inherit { + margin: -4px 4px 3px 0 !important; + } + #alertSettings > .button-box > .box-inherit > .button-icon { + padding: 1px; + } + + /* Color */ + .close-icon, + #alertSettings { + background: transparent !important + } + .close-icon:hover > .toolbarbutton-icon, + #alertSettings:is(:hover,[open]) > .button-box > .box-inherit { + background-color: var(--menuitem-hover-background-color, #e0e0e6) !important; + } + + @media (-moz-toolbar-prefers-color-scheme:dark) { + :root { + --menu-border-color: rgba(107,107,107,.3) !important; + } + + #alertBox { + color: var(--menu-color, #fbfbfe) !important; + background-color: var(--menu-background-color, #2b2a33) !important; + } + .close-icon:hover > .toolbarbutton-icon, + #alertSettings:is(:hover, [open]) > .button-box > .box-inherit { + background-color: var(--menuitem-hover-background-color, #52525e) !important; + } + + #alertSourceLabel { + color: rgb(5,209,241) !important; + } + } + } + + /*= Downloads ==============================================================*/ + @-moz-document url("chrome://mozapps/content/downloads/unknownContentType.xhtml") { + @media (-moz-toolbar-prefers-color-scheme:dark) { + :root { + --in-content-page-background: #42414d; + } + } + #unknownContentType { + color: var(--in-content-page-color) !important; + background-color: var(--in-content-page-background) !important; + } + + button { + -moz-appearance: none !important; + color: var(--in-content-button-text-color) !important; + background-color: var(--in-content-button-background) !important; + font: inherit; + font-size: 1em !important; + font-weight: 600 !important; + min-height: 32px !important; + border: 1px solid transparent !important; /* shows up in high-contrast mode */ + border-radius: var(--in-content-button-border-radius) !important; + padding: var(--in-content-button-vertical-padding) var(--in-content-button-horizontal-padding) !important; + + min-height: 32px !important; + /* Use the same margin of other elements for the alignment */ + margin-inline: 4px !important; + min-width: 6.3em !important; + } + button:-moz-focusring { + box-shadow: none !important; + outline: 2px solid var(--in-content-focus-outline-color) !important; + outline-offset: 2px !important; + } + button:not([disabled="true"]):hover { + background-color: var(--in-content-button-background-hover) !important; + color: var(--in-content-button-text-color-hover) !important; + border-color: transparent !important; + } + button[open], + button[open]:hover { + background-color: var(--in-content-button-background-active); + } + button[disabled="true"], + menulist[disabled="true"] { + opacity: 0.4; + } + } + + /** Reduce Padding **********************************************************/ + /*= Root - Reduce Padding ==================================================*/ + :root { + /* Tab Bar */ + --proton-tab-block-margin: 2px !important; /* Original: 4px */ + --tab-block-margin: 2px !important; /* New version of --proton-tab-block-margin */ + --inline-tab-padding: 6px !important; /* Original: 8px */ + + /* Panel */ + --arrowpanel-menuicon-padding: 8px; + --arrowpanel-menuitem-margin: 0 var(--arrowpanel-menuicon-padding) !important; /* Original: 0 8px */ + --arrowpanel-menuitem-padding: 5px !important; /* Original: 8px */ + --arrowpanel-padding: 0.8em !important; /* Original: 16px or .cui-widget-panel, .cui-widget-panel::part(arrowcontent) => 4px 0 */ + } + + :root[uidensity=compact] { + /* Tool Bar */ + --toolbarbutton-outer-padding: 2px !important; /* Original: 3px, General is 2px */ + + /* Panel */ + --arrowpanel-menuitem-padding: 3px !important; /* Original: 8px */ + } + + :root[uidensity=touch] { + /* Tab Bar - Like Original */ + --proton-tab-block-margin: 4px !important; /* Original: 4px */ + --tab-block-margin: 4px !important; /* New version of --proton-tab-block-margin */ + --inline-tab-padding: 8px !important; /* Original: 8px */ + + /* Panel - Like Original */ + --arrowpanel-menuitem-padding: 8px !important; /* Original: 8px */ + } + + /*= Tab Bar - Reduce Width, Show more tabs =================================*/ + .titlebar-spacer[type="pre-tabs"] { + width: 30px !important; /* Original: 40px */ + } + .titlebar-spacer[type="post-tabs"] { + width: 25px !important; /* Original: 40px */ + } + + :root { + --newtab-button-minus-width-padding: 2px; + --newtab-button-width-padding: calc(var(--toolbarbutton-inner-padding) - var(--newtab-button-minus-width-padding)); + } + #new-tab-button > .toolbarbutton-icon, + #alltabs-button > .toolbarbutton-badge-stack { + /* Original: calc(2 * var(--toolbarbutton-inner-padding) + 16px) */ + width: calc(2 * var(--newtab-button-width-padding) + 16px) !important; + + /* Original: --toolbarbutton-inner-padding */ + padding-left: var(--newtab-button-width-padding) !important; + padding-right: var(--newtab-button-width-padding) !important; + } + + #tabbrowser-tabs[haspinnedtabs]:not([positionpinnedtabs]) > #tabbrowser-arrowscrollbox > .tabbrowser-tab[first-visible-unpinned-tab] { + margin-inline-start: 1px !important; + } + + :root:not([uidensity=touch]) #tabbrowser-arrowscrollbox { + --scrollbtn-inner-padding: 1px; + --scrollbtn-outer-padding: 3px; + } + #scrollbutton-up { + padding-left: var(--scrollbtn-inner-padding, 4px) !important; /* Original: 4px */ + padding-right: var(--scrollbtn-outer-padding, 4px) !important; + } + #scrollbutton-down { + padding-left: var(--scrollbtn-outer-padding, 4px) !important; /* Original: 4px */ + padding-right: var(--scrollbtn-inner-padding, 4px) !important; + } + + :root:not([uidensity=touch]) #new-tab-button, #alltabs-button { + --toolbarbutton-outer-padding: 1px; /* Original: 2px*/ + } + + /* Tab - Max Size */ + .tabbrowser-tab[fadein]:not([pinned]):not([style*="max-width"]) { + max-width: 240px !important; /* Original: 225px */ + } + + /* neighbouring tabs should "pinch" together */ + .tabbrowser-tab { + padding-inline: 1px !important; + } + + .tabbrowser-tab:not([last-visible-tab]) { + margin-inline-end: -.5px !important; + } + + /*= Tab Bar - Reduce Height, Show more contents ============================*/ + /* Toolbar Height */ + :root:not([uidensity=touch]) #TabsToolbar { + --toolbarbutton-inner-padding: 9px; /* Original: calc((var(--tab-min-height) - 16px) / 2) = 10px */ + } + + .toolbar-items, .tabbrowser-tab { + max-height: 38px; + } + :root[uidensity=compact] .toolbar-items, .tabbrowser-tab { + max-height: 36px; + } + :root[uidensity=touch] .toolbar-items, .tabbrowser-tab { + max-height: 45px; + } + + /* Scroll Button - Size Fix */ + :root #tabbrowser-arrowscrollbox { + --scrollbtn-vertical-padding: 3px; + --scrollbtn-vertical-border: 2px; + --scrollbtn-border-radius: 7px; + } + #scrollbutton-up, + #scrollbutton-down { + /* Original: var(--toolbarbutton-inner-padding) calc(var(--toolbarbutton-inner-padding) - 6px) = 9px */ + /* https://github.com/mozilla/gecko-dev/blob/71b1259afd1cdaf41871ae675c2dadb967ea5b34/browser/themes/shared/toolbarbuttons.inc.css#L142 */ + padding-top: var(--scrollbtn-vertical-padding, var(--toolbarbutton-inner-padding)) !important; + padding-bottom: var(--scrollbtn-vertical-padding, var(--toolbarbutton-inner-padding)) !important; + + /* Original: 4px */ + border-top-width: var(--scrollbtn-vertical-border, 4px) !important; + border-bottom-width: var(--scrollbtn-vertical-border, 4px) !important; + /* Original: calc(var(--tab-border-radius) + 4px) = 8px */ + border-radius: var(--scrollbtn-border-radius, calc(var(--tab-border-radius) + 4px)) !important; + } + + :root[tabsintitlebar]:not([uidensity=compact]) #toolbar-menubar[autohide="true"] { + height: calc(var(--tab-min-height) - var(--tabs-navbar-shadow-size) - 2px); /* Compact: 28px, Normal: 33px, Touch: 38px */ + } + + /* Pinned Tab - Titlechanged Indicator position fix */ + :root:not([uidensity=touch]) .tabbrowser-tab:is([image], [pinned]) > .tab-stack > .tab-content[attention]:not([selected="true"]), + :root:not([uidensity=touch]) .tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([selected="true"]) { + /* Original: center bottom calc(6.5px + var(--tabs-navbar-shadow-size)); */ + background-position-y: bottom calc(4.5px + var(--tabs-navbar-shadow-size)) !important; + } + :root[uidensity=compact] .tabbrowser-tab:is([image], [pinned]) > .tab-stack > .tab-content[attention]:not([selected="true"]), + :root[uidensity=compact] .tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([selected="true"]) { + /* Original: center bottom calc(6.5px + var(--tabs-navbar-shadow-size)); */ + background-position-y: bottom calc(.5px + var(--tabs-navbar-shadow-size)) !important; + } + + /*= URL Bar - Reduce Padding ===============================================*/ + :root:not([uidensity=touch]) #urlbar-container, #search-container { + padding-block: 2px; /* Original: 4px */ + margin-inline: 5px; /* Original: 5px */ + } + + /* spread menu */ + :root:not([uidensity]) .urlbarView-row { + padding-block: 1px; /* Original: 2px */ + } + :root[uidensity=compact] .urlbarView-row { + padding-block: 0px; + } + + :root:not([uidensity]) #urlbar .search-one-offs:not([hidden]) { + padding-block: 8px; /* Original: 10px */ + } + :root[uidensity=compact] #urlbar .search-one-offs:not([hidden]) { + padding-block: 2px; + } + + /*= BookMark Bar - Reduce Height ===========================================*/ + :root[uidensity=compact] #PersonalToolbar toolbarbutton { + margin-top: 0px; /* Original: 2px */ + } + + /*= Info Bar - Reduce Padding ==============================================*/ + :root:not([uidensity]) #tab-notification-deck { + --infobar-message-margin: 0 4px 3px; + } + :root[uidensity=compact] #tab-notification-deck { + --infobar-message-margin: 0 4px 2px; + } + #tab-notification-deck notification-message[message-bar-type="infobar"] { + margin: var(--infobar-message-margin, 0 4px 4px) !important; + } + + :root:not([uidensity]) notification-message[message-bar-type="infobar"] { + --infobar-vertical-margin: 7px; + --infobar-button-vertical-margin: 3px; + } + :root[uidensity=compact] notification-message[message-bar-type="infobar"] { + --infobar-vertical-margin: 6px; + --infobar-button-vertical-margin: 2px; + } + .infobar > .icon { + margin-block: var(--infobar-vertical-margin, 8px) !important; /* Original: 8px */ + } + .notification-message { + padding-block: var(--infobar-vertical-margin, 8px) !important; /* Original: 8px */ + } + .notification-button-container > .notification-button { + margin-block: var(--infobar-button-vertical-margin, 4px) !important; /* Original: 4px */ + } + .notification-close { + margin: var(--infobar-button-vertical-margin, 4px) 8px !important; /* Original: 4px 8px */ + } + + /* Hard coded for compatibility - Disappearing phenomenon */ + .container.infobar::before { + content: ""; + display: block; + width: 2px; + position: absolute; + background-image: linear-gradient(0, #9059ff 0%, #ff4aa2 52.08%, #ffbd4f 100%); + top: 0; + inset-inline-start: 0; + height: 100%; + border-start-start-radius: 4px; + border-end-start-radius: 4px; + } + + /*= Menu - Reduce Padding ==================================================*/ + :root { + --menu-padding: 0.35em; + } + :root[uidensity=compact] { + --menu-padding: 0.25em; + } + :root[uidensity=touch] { + --menu-padding: 0.5em; + } + menupopup > menuitem, menupopup > menu { + /* Original: 0.5em */ + padding-block: var(--menu-padding) !important; + } + + @supports not -moz-bool-pref("layout.css.osx-font-smoothing.enabled") { + :root:not([uidensity=touch]) .menu-text, .menu-iconic-text { + padding-inline-end: 0 !important; /* Original: 2px */ + } + :root:not([uidensity=touch]) .menupopup-arrowscrollbox { + padding-block: 1px !important; /* Original: 4px*/ + } + :root:not([uidensity=touch]) #context-navigation:not([hidden]) { + padding: 0 0 1px !important; /* Original: 0 0 4px*/ + } + :root:not([uidensity=touch]) .menu-right { + margin-right: 6px !important; /* Original: 12px */ + } + } + + /*= Poup Panel - Reduce padding ============================================*/ + #protections-popup-main-header-label { + height: unset !important; /* Original: 37.6px */ + } + + #identity-popup, + #permission-popup, + #protections-popup { + --vertical-section-padding: 0.8em; /* Original: 0.9em */ + } + + .protections-popup-footer-button, + .protections-popup-category { + min-height: 24px; /* Original: 32px */ + height: unset !important; + } + + /** Popup panel - Compact mode */ + /* Footer Button Height */ + :root[uidensity=compact] .panel-footer.panel-footer-menulike > button { + padding: 3px 8px !important; + } + /* Footer Button Height */ + :root[uidensity=compact] #protections-popup-trackersView-settings-button { + margin: 4px 8px 0 !important; + } + /* not cut off for Protection popup Footer on windows */ + :root[uidensity=compact] #protections-popup-multiView #protections-popup-footer { + padding: 3px 0 20px !important; + } + /* Button and disabed category in Protection popup */ + :root[uidensity=compact] #protections-popup-multiView .protections-popup-footer-button, + :root[uidensity=compact] #protections-popup-multiView .protections-popup-category { + height: 20px !important; + min-height: 20px !important; + } + /* Footer Button in Tracking Content Panel */ + :root[uidensity=compact] #protections-popup-multiView .panel-footer.panel-footer-menulike { + margin: 0 0 3px !important; + } + /* Identity popup header padding */ + :root[uidensity=compact] #identity-popup-multiView #identity-popup-mainView-panel-header { + padding: 2px 5px !important; + } + /* Text When There is no trackers */ + :root[uidensity=compact] #protections-popup-no-trackers-found-description { + margin: 2em 4em !important; + } + /* Download Item margin */ + :root[uidensity=compact] #downloadsListBox { + margin: 0 !important; + } + + + /** Tab Bar - Connect to window *********************************************/ + .tab-background { + border-radius: var(--tab-border-radius) var(--tab-border-radius) 0px 0px !important; + margin-bottom: 0px !important; + } + + .tab-content { + margin-top: var(--tab-block-margin); + } + + .tab-stack { + margin-top: 0px !important; + margin-bottom: 0px !important; + } + + /* Remove line at Toolbar's top */ + #tabbrowser-tabs { + z-index: 1 !important; + } + #tabbrowser-arrowscrollbox[overflowing] .tabbrowser-tab[pinned]:is([visuallyselected], [multiselected]) { + overflow: hidden; + } + + /** Selected Tab - Color like toolbar ***************************************/ + :root:not(:-moz-lwtheme) { + /* Fix for windows's system default theme. Using --toolbar-bgcolor fallback */ + --tab-selected-bgcolor: unset !important; /* Original: rgb(255,255,255); */ + } +#tabbrowser-tabs:not([movingtab]) > #tabbrowser-arrowscrollbox > .tabbrowser-tab > .tab-stack > .tab-background[selected="true"]:-moz-lwtheme { + /* Original: linear-gradient(var(--lwt-selected-tab-background-color, transparent), var(--lwt-selected-tab-background-color, transparent)), linear-gradient(var(--toolbar-bgcolor), var(--toolbar-bgcolor)), var(--lwt-header-image, none) + */ + background-image: linear-gradient(transparent, transparent), + linear-gradient(var(--toolbar-bgcolor), var(--toolbar-bgcolor)), + var(--lwt-header-image, none) !important; + } + + /* Multi Selected Color */ + #tabbrowser-tabs:not([movingtab]) > #tabbrowser-arrowscrollbox > .tabbrowser-tab > .tab-stack > .tab-background[multiselected]:not([selected]):-moz-lwtheme { + background-image: linear-gradient(var(--toolbar-bgcolor, transparent), var(--toolbar-bgcolor, transparent)), + linear-gradient(var(--toolbar-bgcolor), var(--toolbar-bgcolor)), + var(--lwt-header-image, none) !important; + } + + .tab-background[multiselected="true"]:not([selected="true"]) > .tab-loading-burst:not([bursting]) { + background: color-mix(in srgb, currentColor 65%, transparent); + opacity: .3; + } + #TabsToolbar[brighttext] .tab-background[multiselected="true"]:not([selected="true"]) > .tab-loading-burst:not([bursting]) { + opacity: .15; + } + + /** Selected Tab - Box Shadow ***********************************************/ + #TabsToolbar[brighttext] #tabbrowser-tabs:not([noshadowfortests]) .tabbrowser-tab[visuallyselected="true"]:not(:focus) > .tab-stack > .tab-background:-moz-lwtheme { + /* Origina: 0 0 1px var(--tab-line-color, rgba(128,128,142,0.9)) + Bright: 0 0 1px var(--tab-line-color, rgba(128,128,142,0.9)), 0 0 4px rgba(128,128,142,0.5) */ + box-shadow: 0 0 1px var(--toolbar-color) !important; + } + #TabsToolbar[brighttext] #tabbrowser-tabs:not([noshadowfortests]) .tabbrowser-tab[multiselected]:not([visuallyselected]) > .tab-stack > .tab-background:-moz-lwtheme { + box-shadow: 0 0 1px color-mix(in srgb, var(--toolbar-color) 80%, transparent) !important; + } + + /* Pinned Tab - tabbrowser-arrowscrollbox overflowing */ + #tabbrowser-tabs[positionpinnedtabs] > #tabbrowser-arrowscrollbox > .tabbrowser-tab[pinned] { + z-index: 0 !important; + } + + /** Selected Tab - Bottom Rounded Corner ************************************/ + #tabbrowser-tabs { + --tab-corner-rounding: 4px; /* 10px looks about like chromium - 17px looks close to Australis tabs */ + --tab-corner-padding: 1px; + } + + :root[lwtheme="true"] tab[visuallyselected] > stack::before, + :root[lwtheme="true"] tab[visuallyselected] > stack::after { + /* Box */ + content: "" !important; + display: block !important; + position: absolute !important; + z-index: 1 !important; + + /* Shape */ + width: var(--tab-corner-rounding) !important; + height: 100% !important; + + /* Color */ + fill: var(--toolbar-bgcolor) !important; + stroke: var(--tabs-border-color, transparent) !important; + -moz-context-properties: fill, stroke !important; + + /* Image */ + background-size: var(--tab-corner-rounding); + background-repeat: no-repeat; + background-position-y: bottom; + } + + :root[lwtheme="true"] tab[visuallyselected] > stack::before { + left: calc(var(--tab-corner-padding) - var(--tab-corner-rounding)) !important; + background-image: url(./icons/tab-bottom-corner-left.svg); + } + :root[lwtheme="true"] tab[visuallyselected] > stack::after { + left: auto; + right: calc(var(--tab-corner-padding) - var(--tab-corner-rounding)); + background-image: url(./icons/tab-bottom-corner-right.svg); + } + + /** Unselected Tab - Divide line ********************************************/ + #tabbrowser-arrowscrollbox { + position: absolute; + } + + .tabbrowser-tab:not([visuallyselected], [multiselected], :hover, :first-child) .tab-background::before, + #tabs-newtab-button:not(:hover, [open])::before { + /* Box Model */ + content: ""; + display: block; + position: absolute; + + /* Position */ + top: 50%; + transform: translateX(-2.5px) translateY(calc(-50% + 1px)); + + /* Bar shape */ + width: 1px; + height: 20px; + + /* Bar Color */ + opacity: var(--tab-separator-opacity); + transition: opacity .2s var(--ease-basic); + background-color: color-mix(in srgb, currentColor 20%, transparent); /* Replace var(--toolbarseparator-color) - Hard coded for compatibility */ + } + #tabs-newtab-button:is(:hover, [open])::before { + content: ""; + position: absolute; + } + + #navigator-toolbox:not([movingtab]) .tabbrowser-tab:is([visuallyselected], [multiselected], :hover) + .tabbrowser-tab .tab-background::before, + #navigator-toolbox:not([movingtab]) .tabbrowser-tab:is([visuallyselected], [multiselected], :hover) ~ .tabbrowser-tab[afterhovered] .tab-background::before, + #navigator-toolbox:not([movingtab]) .tabbrowser-tab[last-visible-tab]:is([visuallyselected], [multiselected], :hover) ~ #tabs-newtab-button::before, + #navigator-toolbox:not([movingtab]) .tabbrowser-tab[first-visible-unpinned-tab]:is([visuallyselected], [multiselected], :hover) .tab-background::before, + #navigator-toolbox:not([movingtab]) #tabbrowser-arrowscrollbox[overflowing] tab.tabbrowser-tab[first-visible-unpinned-tab] .tab-background::before { + opacity: 0 !important; + } + + /* Latest Tab & New tab margin */ + #tabbrowser-arrowscrollbox:not([overflowing]) .tabbrowser-tab[last-visible-tab] { + margin-inline-end: 1px !important; + } + + /* New tab button - Looks like tab ******************************************/ + #tabs-newtab-button { + /* Original: + margin: 0 0 var(--tabs-navbar-shadow-size) !important + => Can't ovrride style. Therefore, we should approach it by bypass. + */ + --tabs-navbar-shadow-size: -1px; /* Original: 1px */ + --tabs-navbar-original-shadow-size: 1px; + + /* Size */ + -moz-box-align: stretch !important; + padding-top: var(--tab-block-margin) !important; + } + + #tabs-newtab-button > .toolbarbutton-icon { + border-radius: var(--tab-border-radius) var(--tab-border-radius) 0 0 !important; /* Original: var(--tab-border-radius) */ + } + + /* Coner Rounding */ + #tabs-newtab-button:hover { + /* Color */ + fill: color-mix(in srgb, currentColor 17%, transparent) !important; /* Replace var(--toolbarbutton-hover-background) - Hard coded for compatibility */ + -moz-context-properties: fill !important; + + /* Corner Image */ + --newtab-position: calc((var(--tab-corner-rounding) / 2) * -1); + background-image: url("./icons/tab-bottom-corner-left.svg"), url("./icons/tab-bottom-corner-right.svg"); + background-repeat: no-repeat; + background-position: left var(--newtab-position) bottom var(--tabs-navbar-original-shadow-size), right var(--newtab-position) bottom var(--tabs-navbar-original-shadow-size); + background-size: var(--tab-corner-rounding); + } + + #tabs-newtab-button .toolbarbutton-icon { + padding: calc(var(--toolbarbutton-inner-padding) - (var(--tab-block-margin) / 4)) var(--toolbarbutton-inner-padding) calc(var(--toolbarbutton-inner-padding) + (var(--tab-block-margin) / 4) + var(--tabs-navbar-original-shadow-size)) !important; + -moz-context-properties: fill, fill-opacity; + fill: var(--toolbarbutton-icon-fill); + fill-opacity: var(--toolbarbutton-icon-fill-opacity); + } + + /** Clipped tabs - Letters cleary *******************************************/ + #tabbrowser-tabs[closebuttons=activetab] .tab-content:not([pinned]) { + padding-inline-start: 8px !important; + } + + #tabbrowser-tabs[closebuttons=activetab] .tab-label-container[textoverflow][labeldirection="ltr"]:not([pinned]), + #tabbrowser-tabs[closebuttons=activetab] .tab-label-container[textoverflow]:not([labeldirection]):-moz-locale-dir(ltr):not([pinned]) { + mask-image: linear-gradient(to right, black 70%, transparent) !important; + } + + #tabbrowser-tabs[closebuttons=activetab] .tab-label-container[textoverflow][labeldirection="rtl"]:not([pinned]), + #tabbrowser-tabs[closebuttons=activetab] .tab-label-container[textoverflow]:not([labeldirection]):-moz-locale-dir(rtl):not([pinned]) { + mask-image: linear-gradient(to left, black 70%, transparent) !important; + } + + /** Clipped tabs - Show close button at hover *******************************/ + #tabbrowser-tabs[closebuttons="activetab"] > #tabbrowser-arrowscrollbox > .tabbrowser-tab:not([pinned]) > .tab-stack > .tab-content > .tab-close-button:not([selected="true"]) { + display: -moz-inline-box !important; + } + + #tabbrowser-tabs[closebuttons=activetab] .tabbrowser-tab:not([visuallyselected], :hover) .tab-close-button { + visibility: collapse !important; + } + + /** Sound Tab - Hide Label **************************************************/ + .tab-secondary-label:is([soundplaying], [muted], [activemedia-blocked], [pictureinpicture]){ + display: none !important; + } + + /** Sound Tab - Show with Favicons ******************************************/ + /* Makes the favicons always visible (also on hover) */ + .tab-icon-image:not([pinned]){ + opacity: 1 !important + } + + /* Makes the speaker icon to always appear if the tab is playing (not only on hover) */ + .tab-icon-overlay:not([crashed]), + .tab-icon-overlay[pinned][crashed][selected] { + /* Position */ + top: -3.5px !important; + inset-inline-end: -9px !important; + z-index: 1 !important; + + /* Shape */ + padding: 1.5px !important; + border-radius: 10px !important; + width: 17px !important; + height: 17px !important; + } + .tab-icon-overlay:not([sharing], [crashed]):is([soundplaying], [muted], [activemedia-blocked]) { + /* Color */ + color: currentColor !important; + stroke: transparent !important; + background: transparent !important; + fill-opacity: 0.8 !important; + opacity: 1 !important; + } + .tab-icon-overlay:not([pinned], [sharing], [crashed]):is([soundplaying], [muted], [activemedia-blocked]) { + margin-inline-end: 9.5px !important; + } + + /* None exist favicon */ + .tabbrowser-tab:not([image]) .tab-icon-overlay:not([pinned], [sharing],[crashed]) { + top: 0 !important; + inset-inline-end: 0 !important; + margin-inline-end: 5.5px !important; + padding: 2px 0 !important; + } + + /* Busy - Show */ + .tab-throbber[busy], .tab-icon-pending[busy] { + opacity: 1 !important; + } + + /* Busy - Overlay Position */ + .tabbrowser-tab:not([pinned])[busy] .tab-icon-overlay:is([soundplaying], [muted], [activemedia-blocked]) { + transform: translateX(-.5px) translateY(-2.5px); + } + .tabbrowser-tab:not([image]) .tab-icon-overlay:not([pinned], [sharing],[crashed])[busy] { + top: -3.5px !important; + inset-inline-end: -9px !important; + margin-inline-end: 9.5px !important; + padding: 1.5px !important; + } + + /* Hover */ + .tab-icon-overlay:not([crashed])[soundplaying]:hover, + .tab-icon-overlay:not([crashed])[muted]:hover, + .tab-icon-overlay:not([crashed])[activemedia-blocked]:hover { + color: var(--toolbar-bgcolor, white) !important; + stroke: var(--lwt-tab-text, var(--toolbar-color)) !important; + background-color: var(--lwt-tab-text, var(--toolbar-color)) !important; + fill-opacity: 0.95 !important; + } + + #TabsToolbar[brighttext] .tab-icon-overlay:not([crashed])[soundplaying]:hover, + #TabsToolbar[brighttext] .tab-icon-overlay:not([crashed])[muted]:hover, + #TabsToolbar[brighttext] .tab-icon-overlay:not([crashed])[activemedia-blocked]:hover { + color: var(--toolbar-bgcolor, black) !important; + } + + .tabbrowser-tab:not([image]) .tab-icon-overlay:not([pinned], [sharing],[crashed]):hover { + padding: 0 !important; + } + + /** PictureInPicture Tab - Show PIP Icon ************************************/ + .tab-icon-sound[pictureinpicture]:not([pinned]) { + /* Shape */ + display: -moz-inline-box !important; + width: 14px; + height: 14px; + -moz-box-ordinal-group: 2 !important; + + /* Color */ + fill: currentColor; + opacity: 0.8; + -moz-context-properties: fill; + + /* Icon */ + list-style-image: url(chrome://global/skin/media/picture-in-picture-open.svg); + } + .tab-icon-sound[pictureinpicture]:not([pinned])[selected] { + opacity: 0.95; + } + + /* Close Button's position */ + .tabbrowser-tab[pictureinpicture]:not([pinned]) .tab-close-button { + margin-left: 7px !important; + -moz-box-ordinal-group: 2 !important; + } + .tabbrowser-tab[pictureinpicture]:not([pinned]):hover .tab-close-button { + margin-left: 0px !important; + } + + /** Container Tab - Color line at icon's bottom *****************************/ + .tab-context-line { + display: none; + } + + .tab-icon-image, .tab-sharing-icon-overlay { + box-sizing: content-box; + padding: 3px 0; + + border-bottom: 2px solid var(--identity-icon-color); + } + + /* Busy, None exist favicon */ + .tabbrowser-tab[busy] .tab-content::before, + .tabbrowser-tab:not([image]):not([pinned], [sharing], [crashed]):not([soundplaying], [muted], [activemedia-blocked]) .tab-content::before, + .tabbrowser-tab[pinned][visuallyselected]:not([busy]):not(:hover) .tab-content::before { + /* Box Model */ + content: ''; + display: block; + position: absolute !important; + transition: 0.2s !important; + transform: translateY(10px) !important; + + /* Shape */ + border-bottom: 2px solid var(--identity-icon-color); + width: 16px; + } + .tabbrowser-tab[busy] .tab-content::before, + .tabbrowser-tab:not([image]):not([pinned], [sharing], [crashed]):not([soundplaying], [muted], [activemedia-blocked]) .tab-content::before { + transform: translateY(10px) !important; /* None exist favicon */ + } + + /* None exist favicon - With Sound */ + .tabbrowser-tab:not([image]) .tab-icon-overlay:not([pinned], [sharing], [crashed]):is([soundplaying], [muted], [activemedia-blocked]) { + box-sizing: content-box; + padding: 3px 0; + + border-radius: 0 !important; + border-bottom: 2px solid var(--identity-icon-color); + } + .tabbrowser-tab:not([image]) .tab-icon-overlay:not([pinned], [sharing], [crashed]):is([soundplaying], [muted], [activemedia-blocked]):hover { + padding: 0; + + border-radius: 10px !important; + border-bottom: none; + } + + /* Pinned Tab - Titlechanged Indicator override */ + .tabbrowser-tab:is([image], [pinned]) > .tab-stack > .tab-content[attention]:not([selected="true"]) .tab-icon-image, + .tabbrowser-tab > .tab-stack > .tab-content[pinned][titlechanged]:not([selected="true"]) .tab-icon-image { + border-bottom: 2px solid transparent !important; + } + + .tabbrowser-tab:is([image], [pinned])[usercontextid] > .tab-stack > .tab-content[attention]:not([selected="true"]), + .tabbrowser-tab[usercontextid] > .tab-stack > .tab-content[pinned][titlechanged]:not([selected="true"]) { + /* Original: radial-gradient(circle, var(--attention-icon-color), var(--attention-icon-color) 2px, transparent 2px); */ + --dotted-identity-image: radial-gradient(circle, var(--identity-icon-color), var(--identity-icon-color) 2px, transparent 2px); + background-image: var(--dotted-identity-image), var(--dotted-identity-image), var(--dotted-identity-image) !important; + background-position-x: 32%, 50%, 70% !important; + } + :root[uidensity=compact] .tabbrowser-tab:is([image], [pinned])[usercontextid] > .tab-stack > .tab-content[attention]:not([selected="true"]), + :root[uidensity=compact] .tabbrowser-tab[usercontextid] > .tab-stack > .tab-content[pinned][titlechanged]:not([selected="true"]) { + /* Original: radial-gradient(circle, var(--attention-icon-color), var(--attention-icon-color) 2px, transparent 2px); */ + background-position-x: 30%, 50%, 70% !important; + } + + /* Pinned Tab - Titlechanged & soundplaying */ + .tabbrowser-tab:is([image], [pinned])[usercontextid]:is([soundplaying], [muted], [activemedia-blocked]) > .tab-stack > .tab-content[attention]:not([selected="true"]), + .tabbrowser-tab[usercontextid]:is([soundplaying], [muted], [activemedia-blocked]) > .tab-stack > .tab-content[pinned][titlechanged]:not([selected="true"]) { + background-position-x: calc(32% - 1px), calc(50% - 1px), calc(70% - 1px) !important; + } + :root[uidensity=compact] .tabbrowser-tab:is([image], [pinned])[usercontextid]:is([soundplaying], [muted], [activemedia-blocked]) > .tab-stack > .tab-content[attention]:not([selected="true"]), + :root[uidensity=compact] .tabbrowser-tab[usercontextid]:is([soundplaying], [muted], [activemedia-blocked]) > .tab-stack > .tab-content[pinned][titlechanged]:not([selected="true"]) { + background-position-x: calc(30% - 1px), calc(50% - 1px), calc(70% - 1px) !important; + } + + /** Crashed Tab - Don't show Favicons ***************************************/ + .tab-icon-image[crashed] { + display: none !important; + } + + /** Panel - Icons ***********************************************************/ + /*= Padding ================================================================*/ + :root { + --arrowpanel-menublank-padding: calc(var(--arrowpanel-menuicon-padding) * 2 + 8px) !important; + --arrowpanel-menuimageblank-padding: calc(var(--arrowpanel-menuitem-padding) - 2px) !important; + } + + #downloadsHistory .button-text, + .subviewbutton > .toolbarbutton-text { + padding-inline-start: var(--arrowpanel-menuicon-padding) !important; + } + .toolbaritem-combined-buttons > .subviewbutton:not(.subviewbutton-iconic) > .toolbarbutton-text { + padding-inline-start: 0 !important; + } + #panelMenu_bookmarksMenu .subviewbutton[disabled=true] .toolbarbutton-text, + #appMenu_historyMenu .subviewbutton[disabled=true] .toolbarbutton-text { + padding-inline-start: var(--arrowpanel-menublank-padding) !important; + } + #appMenu-proton-update-banner .toolbarbutton-text { + margin-inline-start: 0 !important; + } + + #appMenu-multiView .subviewbutton::before, + #appMenu-proton-update-banner::before { + display: -moz-inline-box; + margin-inline-end: var(--arrowpanel-menuicon-padding); + width: 16px !important; + height: 16px !important; + } + #appMenu-proton-update-banner { + margin-bottom: 2px !important; + } + #appMenu-proton-update-banner::before { + margin-inline-start: var(--arrowpanel-menuitem-padding) !important; + } + #appMenu-fxa-status2, + #appMenu-zoom-controls2 { + align-items: center; + padding-top: var(--arrowpanel-menuimageblank-padding) !important; + padding-bottom: var(--arrowpanel-menuimageblank-padding) !important; + } + #appMenu-zoom-controls2::before { + margin-inline-end: 0 !important; + } + + /* Icons Color */ + #appMenu-multiView .subviewbutton::before, + #appMenu-proton-update-banner::before, + #downloadsHistory .button-icon, + .subviewbutton > image { + fill: currentColor !important; + fill-opacity: var(--toolbarbutton-icon-fill-opacity) !important; + -moz-context-properties: fill !important; + } + #appMenu-zoomReduce-button2 > .toolbarbutton-icon, + #appMenu-zoomEnlarge-button2 > .toolbarbutton-icon { + stroke: var(--zoom-controls-bgcolor, var(--button-bgcolor, ButtonFace)) !important; + -moz-context-properties: fill, stroke !important; + } + #appMenu-zoomReduce-button2:not([disabled], [open], :active):is(:hover) > .toolbarbutton-icon, #appMenu-zoomEnlarge-button2:not([disabled], [open], :active):is(:hover) > .toolbarbutton-icon { + stroke: var(--button-hover-bgcolor) !important; + } + + .subviewbutton[disabled=true] > image { + /* Ghost icons when disabled */ + opacity: 0.4; + } + + /*= Panel - Main ===========================================================*/ + #appMenu-proton-addon-banners > .addon-banner-item > .toolbarbutton-icon { + display: -moz-inline-box !important; + margin-inline-start: var(--arrowpanel-menuicon-padding); + -moz-box-ordinal-group: 0 !important; + } + + #appMenu-proton-update-banner::before { + content: url(chrome://browser/skin/whatsnew.svg); + } + #appMenu-fxa-status2::before { /* Don't exist img tag */ + content: url(chrome://browser/skin/fxa/avatar-empty.svg); + } + #appMenu-fxa-status2:is([fxastatus=signedin], [fxastatus=unverified], [fxastatus=login-failed])::before { + display: none; + } + #appMenu-fxa-status2:is([fxastatus=signedin], [fxastatus=unverified], [fxastatus=login-failed]) #appMenu-fxa-label2::before { + /* url("https://profile.accounts.firefox.com/v1/avatar/a") */ + content: ''; + border-radius: 50% !important; + background-size: 16px !important; + background-image: var(--avatar-image-url) !important; + } + + #appMenu-new-tab-button2 { + list-style-image: url(chrome://browser/skin/new-tab.svg); + } + #appMenu-new-window-button2 { + list-style-image: url(chrome://browser/skin/window.svg); + } + #appMenu-new-private-window-button2 { + list-style-image: url(chrome://browser/skin/privateBrowsing.svg); + } + + #appMenu-bookmarks-button{ + list-style-image: url(chrome://browser/skin/bookmark.svg); + } + #appMenu-history-button { + list-style-image: url(chrome://browser/skin/history.svg); + } + #appMenu-downloads-button { + list-style-image: url(chrome://browser/skin/downloads/downloads.svg); + } + #appMenu-passwords-button { + list-style-image: url(chrome://browser/skin/login.svg); + } + #appMenu-extensions-themes-button { + list-style-image: url(chrome://mozapps/skin/extensions/extension.svg); + } + + #appMenu-print-button2 { + list-style-image: url(chrome://global/skin/icons/print.svg); + } + #appMenu-save-file-button2 { + list-style-image: url(chrome://browser/skin/save.svg); + } + #appMenu-find-button2 { + list-style-image: url(chrome://global/skin/icons/search-glass.svg); + } + #appMenu-zoom-controls2::before { + content: url(./icons/screenshot.svg); + } + + #appMenu-settings-button { + list-style-image: url(chrome://global/skin/icons/settings.svg); + } + #appMenu-more-button2 { + list-style-image: url(chrome://browser/skin/ion.svg); + } + #appMenu-help-button2 { + list-style-image: url(chrome://global/skin/icons/help.svg); + } + + #appMenu-quit-button2 { + list-style-image: url(./icons/quit.svg); + } + + /*= Panel - Account ========================================================*/ + #PanelUI-fxa-menu-connect-device-button .toolbarbutton-icon, + #PanelUI-fxa-menu-account-signout-button .toolbarbutton-icon { + width: 16px !important; + height: 16px !important; + } + + /* Default */ + #fxa-menu-avatar { + display: -moz-inline-box !important; + margin-inline-end: var(--arrowpanel-menuicon-padding); + } + + .syncNowBtn { + visibility: visible !important; + -moz-box-ordinal-group: 1 !important; + margin-inline-end: var(--arrowpanel-menuicon-padding); + } + #PanelUI-fxa-menu-setup-sync-button { + list-style-image: url(chrome://browser/skin/sync.svg); + } + + #PanelUI-fxa-menu-connect-device-button { + list-style-image: url(chrome://browser/skin/fxa/add-device.svg); + } + #PanelUI-fxa-menu-sendtab-button { + list-style-image: url(./icons/send-to-device.svg); + } + #PanelUI-fxa-menu-sync-prefs-button, + #PanelUI-remotetabs-view-managedevices { + list-style-image: url(chrome://global/skin/icons/settings.svg); + } + #PanelUI-fxa-menu-account-signout-button { + list-style-image: url(./icons/sign-out.svg); + } + + .PanelUI-remotetabs-notabsforclient-label { + margin-inline-start: calc(var(--arrowpanel-menuicon-padding) + var(--arrowpanel-menuitem-padding)) !important; + padding-inline-start: var(--arrowpanel-menublank-padding) !important; + } + + /* Change Separator */ + #PanelUI-fxa-menu::before{ + content: ""; + display: -moz-box; + border-bottom: 1px solid var(--panel-separator-color); + margin: var(--panel-separator-margin); + padding: 0; + } + #PanelUI-fxa-menu > :first-child{ + -moz-box-ordinal-group: 0; + } + #PanelUI-sign-out-separator { + display: none; + } + .pageAction-sendToDevice-device.subviewbutton.sync-menuitem.sendtab-target[clientType=""] { + list-style-image: url(./icons/send-to-device.svg); + } + .pageAction-sendToDevice-device.subviewbutton.sync-menuitem.sendtab-target:not([clientType]) { + list-style-image: url(chrome://global/skin/icons/settings.svg); + } + + /*= Panel - Bookmark =======================================================*/ + #panelMenuBookmarkThisPage { + list-style-image: url(chrome://browser/skin/bookmark-hollow.svg); + } + panelMenuBookmarkThisPage[starred] { + list-style-image: url(chrome://browser/skin/bookmark.svg); + } + + #panelMenu_searchBookmarks { + list-style-image: url(chrome://global/skin/icons/search-glass.svg); + } + #panelMenu_viewBookmarksToolbar { + list-style-image: url(chrome://browser/skin/bookmarks-toolbar.svg); + } + + #panelMenu_showAllBookmarks { + list-style-image: url(chrome://browser/skin/bookmark-star-on-tray.svg); + } + + /*= Panel - History ========================================================*/ + #appMenuRecentlyClosedTabs { + list-style-image: url(chrome://browser/skin/tab.svg); + } + #appMenuRecentlyClosedWindows { + list-style-image: url(chrome://browser/skin/window.svg); + } + #appMenuRestoreSession { + list-style-image: url(./icons/restore-session.svg); + } + #appMenuClearRecentHistory { + list-style-image: url(chrome://browser/skin/forget.svg); + } + + #PanelUI-historyMore { + list-style-image: url(chrome://browser/skin/history.svg); + } + + #appMenu-library-recentlyClosedTabs { + list-style-image: url(./icons/movetowindow-16.svg); + } + #appMenu-library-recentlyClosedWindows { + list-style-image: url(./icons/restore-session.svg); + } + + /*= Panel - More tools =====================================================*/ + #appmenu-moreTools-button { + list-style-image: url(chrome://browser/skin/customize.svg); + } + + #appmenu-developer-tools-view .subviewbutton:nth-child(1) { /* Web Developer Tools */ + list-style-image: url(chrome://browser/skin/developer.svg); + } + #appmenu-developer-tools-view .subviewbutton:nth-child(2) { /* Task Manager */ + list-style-image: url(./icons/performance.svg); + } + #appmenu-developer-tools-view .subviewbutton:nth-child(3) { /* Remote Debugging - Edge bug.svg */ + list-style-image: url(./icons/bug.svg); + } + #appmenu-developer-tools-view .subviewbutton:nth-child(4) { /* Browser Toolbox - Edge webdeveloper.svg */ + list-style-image: url(./icons/webdeveloper.svg); + } + #appmenu-developer-tools-view .subviewbutton:nth-child(5) { /* Browser Content Toolbaox - */ + list-style-image: url(./icons/command-frames.svg); + } + #appmenu-developer-tools-view .subviewbutton:nth-last-child(5) { /* Browser Console */ + list-style-image: url(chrome://devtools/skin/images/command-console.svg); + } + #appmenu-developer-tools-view .subviewbutton:nth-last-child(4) { /* Responsive Design Mode */ + list-style-image: url(./icons/command-responsivemode.svg); + } + #appmenu-developer-tools-view .subviewbutton:nth-last-child(3) { /* Eyedropper */ + list-style-image: url(chrome://devtools/skin/images/command-eyedropper.svg); + } + #appmenu-developer-tools-view .subviewbutton:nth-last-child(2) { /* Page Source - Edge file-search.svg */ + list-style-image: url(./icons/search-file.svg); + } + #appmenu-developer-tools-view .subviewbutton:nth-last-child(1) { /* Extensions for Devel */ + list-style-image: url(chrome://devtools/skin/images/debugging-addons.svg); + } + #appmenu-developer-tools-view .subviewbutton:last-child { + margin-bottom: 6px !important; + } + + /*= Panel - Help ===========================================================*/ + #appMenu_menu_openHelp { + list-style-image: url(chrome://global/skin/icons/help.svg); + } + #appMenu_feedbackPage { + list-style-image: url(./icons/send.svg); + } + #appMenu_helpSafeMode { + list-style-image: url(chrome://devtools/skin/images/debugging-workers.svg); + } + #appMenu_troubleShooting { + list-style-image: url(chrome://global/skin/icons/more.svg); + } + #appMenu_help_reportSiteIssue { + list-style-image: url(chrome://global/skin/icons/lightbulb.svg); + } + #appMenu_menu_HelpPopup_reportPhishingtoolmenu { + list-style-image: url(chrome://global/skin/icons/warning.svg); + } + #appMenu_aboutName{ + list-style-image: url(chrome://global/skin/icons/info.svg); + } + + /*= Panel - Library ========================================================*/ + #appMenu-library-bookmarks-button { + list-style-image: url(chrome://browser/skin/bookmark.svg); + } + #appMenu-library-history-button { + list-style-image: url(chrome://browser/skin/history.svg); + } + #appMenu-library-downloads-button{ + list-style-image: url(chrome://browser/skin/downloads/downloads.svg); + } + + /*= Panel - Downloads ======================================================*/ + #downloadsHistory { + list-style-image: url(chrome://browser/skin/downloads/downloads.svg); + } + #downloadsHistory .box-inherit.button-box { + display: -moz-inline-box !important; + } + + /*= Toolbar - Overflow Menu ================================================*/ + #overflowMenu-customize-button { + list-style-image: url(chrome://browser/skin/customize.svg); + } + + /*= Tabbar - All Tab Menu ==================================================*/ + #allTabsMenu-undoCloseTab { + list-style-image: url(chrome://global/skin/icons/undo.svg); + } + #allTabsMenu-searchTabs { + list-style-image: url(chrome://global/skin/icons/search-glass.svg); + } + #allTabsMenu-containerTabsButton { + list-style-image: url(./icons/container-openin-16.svg); + } + + #allTabsMenu-hiddenTabsButton { + list-style-image: url(./icons/password-hide.svg); + } + + #allTabsMenu-containerTabsView .subviewbutton:last-child { + list-style-image: url(chrome://global/skin/icons/settings.svg); + } + + /** Context Menu - Icons ****************************************************/ + /*= Layout =================================================================*/ + menupopup menuitem:not([type="checkbox"]), + menupopup menu:not([type="checkbox"]) { + -moz-appearance: none !important; /* Linux: menulist */ + } + + /* Icon */ + :not(menu, #ContentSelectDropdown) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], .in-menulist), + :not(menu, #ContentSelectDropdown) > menupopup > menu:not(.menu-iconic, [type="checkbox"], .in-menulist), + #blockedPopupDontShowMessage { + /* Color */ + -moz-context-properties: fill, fill-opacity !important; + fill: currentColor !important; + + /* Layout */ + background-size: 16px !important; + background-repeat: no-repeat !important; + background-image: var(--menuitem-image); + } + + /* For native context menus on macOS */ + @supports -moz-bool-pref("widget.macos.native-context-menus") { + :not(menu, #ContentSelectDropdown) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], .in-menulist), + :not(menu, #ContentSelectDropdown) > menupopup > menu:not(.menu-iconic, [type="checkbox"], .in-menulist) { + list-style-image: var(--menuitem-image) !important; + } + } + + /* Padding */ + :root { + --context-menu-background-padding-default: 5px; + --context-menu-background-padding: var(--context-menu-background-padding-default); + } + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem, + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu, + #blockedPopupDontShowMessage { + background-position: left var(--context-menu-background-padding) center !important; + padding-inline-start: var(--context-menu-background-padding) !important; + } + + /* Padding - Windows */ + @media (-moz-os-version: windows-win7 ), + (-moz-os-version: windows-win8 ), + (-moz-os-version: windows-win10) { + /* Checkbox */ + :root { + --context-menu-text-padding: calc(var(--menu-padding) + var(--context-menu-background-padding-default) + 16px); + } + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem[type="checkbox"][checked="false"] > .menu-iconic-left { + padding-inline-start: var(--context-menu-text-padding); + } + } + + @media (-moz-os-version: windows-win7 ){ + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], .in-menulist), + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu:not(.menu-iconic, [type="checkbox"], .in-menulist), + #blockedPopupDontShowMessage { + background-position: left var(--context-menu-background-padding) center !important; + padding-inline-start: 0 !important; + } + } + @media (-moz-os-version: windows-win8 ), + (-moz-os-version: windows-win10) { + :root { + --context-menu-background-padding: 1em; + } + + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], .in-menulist), + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu:not(.menu-iconic, [type="checkbox"], .in-menulist), + #blockedPopupDontShowMessage { + padding-inline-start: calc(var(--context-menu-background-padding) + var(--context-menu-text-padding)) !important; + } + } + + /* Padding Mac */ + @supports -moz-bool-pref("layout.css.osx-font-smoothing.enabled") { + :root { + --context-menu-background-padding-default: 10px; + --context-menu-mac-padding: 21px; + } + + /* context menu width */ + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem:not(.menuitem-iconic, [type="checkbox"], .in-menulist), + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu:not(.menu-iconic, [type="checkbox"], .in-menulist), + #blockedPopupDontShowMessage { + padding-inline-end: var(--context-menu-background-padding) !important; + } + + /* text position */ + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem > .menu-text, + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu > menu-text { + padding-inline-start: var(--context-menu-mac-padding) !important; + } + + /* Checkbox menuitem, None iconic menu */ + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menuitem[type="checkbox"], + :not(menu, #ContentSelectDropdown, #context-navigation) > menupopup > menu:not(.menu-iconic) { + padding-inline-start: calc(var(--context-menu-background-padding) + var(--context-menu-mac-padding)) !important; + } + } + + /*= tabContextMenu =========================================================*/ + #context_openANewTab { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + + #context_reloadTab, + #context_reloadSelectedTabs { + --menuitem-image: url(chrome://browser/skin/reload.svg); + } + #context_toggleMuteTab, + #context_toggleMuteSelectedTabs { + --menuitem-image: url(chrome://browser/skin/tabbrowser/tab-audio-muted-small.svg); + } + #context_toggleMuteTab[muted], + #context_toggleMuteSelectedTabs[muted] { + --menuitem-image: url(chrome://browser/skin/tabbrowser/tab-audio-playing-small.svg); + } + #context_pinTab, + #context_pinSelectedTabs { + --menuitem-image: url(./icons/pin-tab.svg); + } + #context_unpinTab, + #context_unpinSelectedTabs { + --menuitem-image: url(./icons/unpin-tab.svg); + } + #context_duplicateTab, + #context_duplicateTabs { + --menuitem-image: url(./icons/tab-copy.svg); + } + + #context_bookmarkTab, + #context_bookmarkSelectedTabs { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #context_moveTabOptions { + --menuitem-image: url(./icons/arrow-swap.svg); + } + #context_sendTabToDevice { + --menuitem-image: url(./icons/send-to-device.svg); + } + #context_shareTabURL { /* At windows */ + --menuitem-image: url(./icons/share.svg); + } + #context_reopenInContainer { + --menuitem-image: url(./icons/container-openin-16.svg); + } + #context_selectAllTabs { + --menuitem-image: url(./icons/tab-multiple.svg); + } + + #context_closeTab { + --menuitem-image: url(chrome://global/skin/icons/close.svg); + } + #context_closeTabOptions { + } + #context_undoCloseTab { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + + /*= new-tab-button-popup ===================================================*/ + #new-tab-button-popup > menuitem[command="Browser:OpenAboutContainers"] { + --menuitem-image: url(chrome://global/skin/icons/settings.svg); + } + + /*= toolbar-context-menu ===================================================*/ + .customize-context-manageExtension { + --menuitem-image: url(chrome://global/skin/icons/settings.svg); + } + .customize-context-removeExtension { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + .customize-context-reportExtension { + --menuitem-image: url(./icons/send.svg); + } + + .customize-context-moveToPanel { + --menuitem-image: url(chrome://browser/skin/pin-12.svg); + } + .toolbar-context-autohide-downloads-button { + --menuitem-image: url(./icons/password-hide.svg); + } + .customize-context-removeFromToolbar { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + #toolbar-context-openANewTab { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + + #toolbar-context-reloadSelectedTab, + #toolbar-context-reloadSelectedTabs { + --menuitem-image: url(chrome://browser/skin/reload.svg); + } + #toolbar-context-bookmarkSelectedTab, + #toolbar-context-bookmarkSelectedTabs { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #toolbar-context-selectAllTabs { + --menuitem-image: url(./icons/tab-multiple.svg); + } + #toolbar-context-undoCloseTab { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + + #toggle_toolbar-menubar { /* checkbox */ + /* --menuitem-image: url(./icons/calendar-agenda.svg); */ + } + #toggle_PersonalToolbar { /* Also placeContext */ + --menuitem-image: url(chrome://browser/skin/bookmarks-toolbar.svg); + } + + menuitem.viewCustomizeToolbar { + --menuitem-image: url(chrome://browser/skin/customize.svg); + } + + /*= blockedPopupOptions ====================================================*/ + #blockedPopupAllowSite { + --menuitem-image: url("chrome://global/skin/icons/check.svg"); + } + #blockedPopupOptions > menuitem[oncommand="gPopupBlockerObserver.editPopupSettings();"] { + --menuitem-image: url("chrome://global/skin/icons/edit.svg"); + } + #blockedPopupDontShowMessage { /* checkbox */ + --menuitem-image: url("chrome://global/skin/icons/blocked.svg"); + } + + /*= autohide-context =======================================================*/ + #autohide-context > menuitem[data-l10n-id="full-screen-autohide"] { /* checkbox */ + } + + #autohide-context > menuitem[data-l10n-id="full-screen-exit"] { + --menuitem-image: url(chrome://browser/skin/fullscreen-exit.svg); + } + + /*= contentAreaContextMenu =================================================*/ + #context-viewsource-goToLine { + --menuitem-image: url(./icons/text-number-format.svg); + } + #context-viewsource-wrapLongLines { /* checkbox */ + /* --menuitem-image: url(./icons/arrow-sort-down-lines.svg); */ + } + + #context-viewsource-highlightSyntax { /* checkbox */ + /* --menuitem-image: url(./icons/code.svg); */ + } + + #spell-no-suggestions { + --menuitem-image: url(./icons/text-proofing-tools.svg); + } + #spell-add-to-dictionary { + --menuitem-image: url(./icons/book-add.svg); + } + #spell-undo-add-to-dictionary { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + + #context-openlinkincurrent { + --menuitem-image: url(./icons/link-square.svg); + } + #context-openlinkincontainertab { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + #context-openlinkintab { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + #context-openlinkinusercontext-menu { + --menuitem-image: url(./icons/container-openin-16.svg); + } + #context-openlink { + --menuitem-image: url(chrome://browser/skin/window.svg); + } + #context-openlinkprivate { + --menuitem-image: url(chrome://browser/skin/privateBrowsing.svg); + } + + #context-bookmarklink { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #context-savelink { + --menuitem-image: url(chrome://browser/skin/save.svg); + } + #context-savelinktopocket { + --menuitem-image: url(chrome://browser/skin/pocket-outline.svg); + } + #context-copyemail { + --menuitem-image: url(chrome://browser/skin/mail.svg); + } + #context-copylink { + --menuitem-image: url(chrome://browser/skin/link.svg); + } + #context-sendlinktodevice { + --menuitem-image: url(./icons/send-to-device.svg); + } + + #context-media-play { + --menuitem-image: url(chrome://global/skin/media/play-fill.svg); + } + #context-media-pause { + --menuitem-image: url(chrome://global/skin/media/pause-fill.svg); + } + #context-media-mute { + --menuitem-image: url(chrome://global/skin/media/audio-muted.svg); + } + #context-media-unmute { + --menuitem-image: url(chrome://global/skin/media/audio.svg); + } + #context-media-playbackrate { + --menuitem-image: url(./icons/time-picker.svg); + } + #context-media-loop { /* checkbox */ + /* --menuitem-image: url(./icons/arrow-repeat-all.svg); */ + } + #context-leave-dom-fullscreen { + --menuitem-image: url(chrome://global/skin/media/fullscreenExitButton.svg); + } + #context-video-fullscreen { + --menuitem-image: url(chrome://global/skin/media/fullscreenEnterButton.svg); + } + #context-media-hidecontrols { + --menuitem-image: url(./icons/eye-hide.svg); + } + #context-media-showcontrols { + --menuitem-image: url(./icons/eye-show.svg); + } + + #context-viewvideo { + --menuitem-image: url(./icons/video.svg); + } + #context-video-pictureinpicture { /* checkbox */ + /* --menuitem-image: url(chrome://global/skin/media/picture-in-picture-open.svg); */ + } + + #context-reloadimage { + --menuitem-image: url(./icons/image-arrow-counterclockwise.svg); + } + #context-viewimage { + --menuitem-image: url(./icons/image-add.svg); + } + #context-saveimage { + --menuitem-image: url(./icons/image.svg); + } + #context-video-saveimage { + --menuitem-image: url(./icons/video-snapshot.svg); + } + #context-savevideo { + --menuitem-image: url(./icons/video.svg); + } + #context-saveaudio { + --menuitem-image: url(chrome://global/skin/media/audio.svg); + } + #context-copyimage-contents { + --menuitem-image: url(./icons/image-copy.svg); + } + #context-copyimage, + #context-copyvideourl, + #context-copyaudiourl { + --menuitem-image: url(chrome://browser/skin/link.svg); + } + #context-sendimage, + #context-sendvideo, + #context-sendaudio { + --menuitem-image: url(chrome://browser/skin/mail.svg); + } + #context-viewimageinfo { + --menuitem-image: url(chrome://global/skin/icons/info.svg); + } + #context-viewimagedesc { + --menuitem-image: url(./icons/image-alt-text.svg); + } + #context-setDesktopBackground { + --menuitem-image: url(./icons/resize-image.svg); + } + #context-ctp-play { + --menuitem-image: url(chrome://global/skin/icons/plugin.svg); + } + #context-ctp-hide { + --menuitem-image: url(chrome://global/skin/icons/plugin-blocked.svg); + } + + #context-savepage { + --menuitem-image: url(chrome://browser/skin/save.svg); + } + #context-pocket { + --menuitem-image: url(chrome://browser/skin/pocket-outline.svg); + } + #context-sendpagetodevice { + --menuitem-image: url(./icons/send-to-device.svg); + } + #fill-login { + --menuitem-image: url(./icons/password.svg); + } + #fill-login-generated-password { + --menuitem-image: url(chrome://browser/skin/login.svg); + } + #manage-saved-logins { + --menuitem-image: url(./icons/key-multiple.svg); + } + + #context-undo { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + #context-redo { + } + + #context-cut { + --menuitem-image: url(chrome://browser/skin/edit-cut.svg); + } + #context-copy { + --menuitem-image: url(chrome://browser/skin/edit-copy.svg); + } + #context-paste { + --menuitem-image: url(chrome://browser/skin/edit-paste.svg); + } + #context-delete { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + #context-selectall { + --menuitem-image: url(./icons/select-all-on.svg); + } + #context-print-selection { + --menuitem-image: url(chrome://global/skin/icons/print.svg); + } + + #context-take-screenshot { + --menuitem-image: url(chrome://browser/skin/screenshot.svg); + } + + #context-keywordfield { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #context-searchselect, + #context-searchselect-private { + --menuitem-image: url(chrome://global/skin/icons/search-glass.svg); + } + + #frame { + --menuitem-image: url(./icons/command-frames.svg); + } + + #spell-check-enabled { /* checkbox */ + } + #spell-add-dictionaries-main { + --menuitem-image: url(./icons/book-add.svg); + } + #spell-dictionaries { + --menuitem-image: url(./icons/book.svg); + } + + #context-bidi-text-direction-toggle { + --menuitem-image: url(./icons/text-direction-horizontal-ltr.svg); + } + #context-bidi-page-direction-toggle { + --menuitem-image: url(./icons/document-landscape-split-hint.svg); + } + + #context-viewpartialsource-selection, + #context-viewsource { + --menuitem-image: url(./icons/search-file.svg); + } + #context-inspect-a11y { + --menuitem-image: url(chrome://devtools/skin/images/tool-accessibility.svg); + } + #context-inspect { + --menuitem-image: url(chrome://devtools/skin/images/command-pick.svg) + } + + #context-media-eme-learnmore { /* iconic */ + } + + @supports -moz-bool-pref("layout.css.osx-font-smoothing.enabled") { + #context-back { + --menuitem-image: url(chrome://browser/skin/back.svg); + } + #context-forward { + --menuitem-image: url(chrome://browser/skin/forward.svg); + } + #context-reload { + --menuitem-image: url(chrome://browser/skin/reload.svg); + } + #context-stop { + --menuitem-image: url(chrome://global/skin/icons/close.svg); + } + + #context-bookmarkpage { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + } + + /*= pictureInPictureToggleContextMenu ======================================*/ + #pictureInPictureToggleContextMenu > menuitem[oncommand="PictureInPicture.hideToggle();"] { + --menuitem-image: url(./icons/eye-hide.svg); + } + + /*= placeContext ===========================================================*/ + #placesContext_open { + --menuitem-image: url(./icons/link-square.svg); + } + #placesContext_openBookmarkContainer\:tabs, + #placesContext_openBookmarkLinks\:tabs { + --menuitem-image: url(./icons/movetowindow-16.svg); + } + #placesContext_open\:newtab, + #placesContext_openContainer\:tabs, + #placesContext_openLinks\:tabs { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + #placesContext_open\:newwindow { + --menuitem-image: url(chrome://browser/skin/window.svg); + } + #placesContext_open\:newprivatewindow { + --menuitem-image: url(chrome://browser/skin/privateBrowsing.svg); + } + + #placesContext_show_bookmark\:info, + #placesContext_show\:info, + #placesContext_show_folder\:info { + --menuitem-image: url(chrome://global/skin/icons/edit.svg); + } + #placesContext_deleteBookmark, + #placesContext_deleteFolder, + #placesContext_delete, + #placesContext_delete_history { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + #placesContext_deleteHost { + --menuitem-image: url(./icons/eye-hide.svg); + } + #placesContext_sortBy\:name { + --menuitem-image: url(./icons/text-sort-ascending.svg); + } + + #placesContext_cut { + --menuitem-image: url(chrome://browser/skin/edit-cut.svg); + } + #placesContext_copy { + --menuitem-image: url(chrome://browser/skin/edit-copy.svg); + } + #placesContext_paste_group { + --menuitem-image: url(chrome://browser/skin/edit-paste.svg); + } + + #placesContext_new\:bookmark { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #placesContext_new\:folder { + --menuitem-image: url(chrome://global/skin/icons/folder.svg); + } + #placesContext_new\:separator { + --menuitem-image: url(./icons/vertical-line.svg); + } + + #placesContext_paste { + --menuitem-image: url(chrome://browser/skin/edit-paste.svg); + } + + #placesContext_createBookmark { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #show-other-bookmarks_PersonalToolbar { /* checkbox */ + /* --menuitem-image: url(./icons/star-line-horizontal.svg); */ + } + #placesContext_showAllBookmarks { + --menuitem-image: url(chrome://browser/skin/bookmark-star-on-tray.svg); + } + + menupopup[context="placesContext"] > .openintabs-menuitem { + --menuitem-image: url(./icons/movetowindow-16.svg); + } + + /*= pageActionContextMenu ==================================================*/ + .pageActionContextMenuItem.extensionPinned.extensionUnpinned.manageExtensionItem { + --menuitem-image: url(chrome://global/skin/icons/settings.svg); + } + .pageActionContextMenuItem.extensionPinned.extensionUnpinned.removeExtensionItem { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + + /*= customizationPanelItemContextMenu ======================================*/ + #customizationPanelItemContextMenuUnpin { + --menuitem-image: url(./icons/unpin-tab.svg); + } + .customize-context-removeFromPanel { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + + /*= customizationPaletteItemContextMenu ====================================*/ + .customize-context-addToToolbar { + --menuitem-image: url(chrome://devtools/skin/images/dock-bottom.svg); + } + .customize-context-addToPanel { + --menuitem-image: url(chrome://browser/skin/menu.svg); + } + + /*= customizationPanelContextMenu ==========================================*/ + #customizationPanelContextMenu > menuitem[command="cmd_CustomizeToolbars"] { + --menuitem-image: url(chrome://browser/skin/customize.svg); + } + + /*= downloads-button-autohide-panel ========================================*/ + #downloads-button-autohide-checkbox { /* checkbox */ + } + + /*= downloadsContextMenu ===================================================*/ + .downloadPauseMenuItem { + --menuitem-image: url(chrome://global/skin/media/pause-fill.svg); + } + .downloadResumeMenuItem { + --menuitem-image: url(chrome://global/skin/media/play-fill.svg); + } + .downloadUnblockMenuItem { + --menuitem-image: url(./icons/checkmark-circle.svg); + } + .downloadUseSystemDefaultMenuItem { + --menuitem-image: url(chrome://browser/skin/open.svg); + } + .downloadAlwaysUseSystemDefaultMenuItem { /* checkbox */ + } + .downloadShowMenuItem { + --menuitem-image: url(chrome://global/skin/icons/folder.svg); + } + + #downloadsContextMenu > menuitem[command="downloadsCmd_openReferrer"] { + --menuitem-image: url(./icons/link-square.svg); + } + #downloadsContextMenu > menuitem[command="downloadsCmd_copyLocation"] { + --menuitem-image: url(chrome://browser/skin/link.svg); + } + + .downloadRemoveFromHistoryMenuItem { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + #downloadsContextMenu > menuitem[command="downloadsCmd_clearList"], + #downloadsContextMenu > menuitem[command="downloadsCmd_clearDownloads"] { + --menuitem-image: url(./icons/broom.svg); + } + + /*= SyncedTabsSidebarContext ===============================================*/ + #syncedTabsOpenSelected { + --menuitem-image: url(./icons/link-square.svg); + } + #syncedTabsOpenSelectedInTab { + --menuitem-image: url(chrome://browser/skin/new-tab.svg); + } + #syncedTabsOpenSelectedInWindow { + --menuitem-image: url(chrome://browser/skin/window.svg); + } + #syncedTabsOpenSelectedInPrivateWindow { + --menuitem-image: url(chrome://browser/skin/privateBrowsing.svg); + } + + #syncedTabsBookmarkSelected { + --menuitem-image: url(chrome://browser/skin/bookmark.svg); + } + #syncedTabsCopySelected { + --menuitem-image: url(chrome://browser/skin/link.svg); + } + + #syncedTabsOpenAllInTabs { + --menuitem-image: url(./icons/movetowindow-16.svg); + } + #syncedTabsManageDevices { + --menuitem-image: url(chrome://global/skin/icons/settings.svg); + } + #syncedTabsRefresh { + --menuitem-image: url(chrome://browser/skin/sync.svg); + } + + /*= SyncedTabsSidebarTabsFilterContext =====================================*/ + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_undo"] { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_cut"] { + --menuitem-image: url(chrome://browser/skin/edit-cut.svg); + } + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_copy"]{ + --menuitem-image: url(chrome://browser/skin/edit-copy.svg); + } + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_paste"]{ + --menuitem-image: url(chrome://browser/skin/edit-paste.svg); + } + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_delete"]{ + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + + #SyncedTabsSidebarTabsFilterContext > menuitem[cmd="cmd_selectAll"]{ + --menuitem-image: url(./icons/select-all-on.svg); + } + + #syncedTabsRefreshFilter { + --menuitem-image: url(chrome://browser/skin/sync.svg); + } + + /*= urlbar-input-container =================================================*/ + #urlbar-input-container .textbox-contextmenu menuitem[cmd="cmd_undo"] { + --menuitem-image: url(chrome://global/skin/icons/undo.svg); + } + #urlbar-input-container .textbox-contextmenu menuitem[cmd="cmd_redo"] { + } + + #urlbar-input-container .textbox-contextmenu menuitem[cmd="cmd_cut"] { + --menuitem-image: url(chrome://browser/skin/edit-cut.svg); + } + #urlbar-input-container .textbox-contextmenu menuitem[cmd="cmd_copy"] { + --menuitem-image: url(chrome://browser/skin/edit-copy.svg); + } + #urlbar-input-container .textbox-contextmenu menuitem[cmd="cmd_paste"] { + --menuitem-image: url(chrome://browser/skin/edit-paste.svg); + } + #paste-and-go { + } + #urlbar-input-container .textbox-contextmenu menuitem[cmd="cmd_delete"] { + --menuitem-image: url(chrome://global/skin/icons/delete.svg); + } + #urlbar-input-container .textbox-contextmenu menuitem[cmd="cmd_selectAll"] { + --menuitem-image: url(./icons/select-all-on.svg); + } +} diff --git a/home/browsers/firefox/lepton/userContent.css b/home/browsers/firefox/lepton/userContent.css new file mode 100644 index 0000000..0e2aee1 --- /dev/null +++ b/home/browsers/firefox/lepton/userContent.css @@ -0,0 +1,1011 @@ +@media (-moz-proton) { + @-moz-document url("about:home"), url("about:newtab") { + /** Activity Stream - Search Focus Border: like URL ***********************/ + /* At DarkMode, Color */ + body[style*="--newtab-background-color:rgba(28, 27, 34, 1);"], + body[style*="--newtab-background-color:rgba(42, 42, 46, 1);"], + body[style*="--newtab-background-color: rgba(42, 42, 46, 1);"], + body[style*="--newtab-background-color: rgba(43, 42, 51, 1);"] { + /* inner */ + --newtab-focus-border: rgba(0, 221, 255, 0.5) !important; /* Original: #B5D3FF, Better color-mix(in srgb, #B5D3FF 70%, transparent) */ + --newtab-focus-border-selected: rgba(0, 221, 255, 0.5) !important; /* Original: #B5D3FF */ + } + + /** Activity Stream - Web Site Icon: full size ****************************/ + .top-site-outer .tile .icon-wrapper { + width: 100% !important; /* Original: 48px */ + height: 100% !important; /* Original: 48px */ + } + } + + /** Error Page - Restore illustrations **************************************/ + @-moz-document url-prefix("about:neterror"), + url("about:restartrequired"), url("chrome://browser/content/aboutRestartRequired.xhtml"), + url("about:sessionrestore"), url(chrome://browser/content/aboutSessionRestore.xhtml) { + /* Illustrations Position */ + #errorPageContainer, .description-wrapper { + min-height: 300px; + background-position: left center; + background-repeat: no-repeat; + background-size: 38%; + } + + #errorPageContainer { + display: flex; + flex-direction: column; + } + .description-wrapper { + padding-inline-start: 38%; + } + + /* Container */ + .container { + min-width: var(--in-content-container-min-width); /* 13em */ + max-width: var(--in-content-container-max-width); /* 52em */ + } + + /* Text Position */ + #text-container { + margin: auto; + padding-inline-start: 38%; + } + } + + @-moz-document url-prefix("about:neterror?e=connectionFailure"), + url-prefix("about:neterror?e=netInterrupt"), + url-prefix("about:neterror?e=netTimeout"), + url-prefix("about:neterror?e=netReset"), + url-prefix("about:neterror?e=netOffline"), + url("about:restartrequired"), url("chrome://browser/content/aboutRestartRequired.xhtml") { + #errorPageContainer { + background-image: url("./icons/error-connection-failure.svg"); + } + } + @-moz-document url-prefix("about:neterror?e=dnsNotFound") { + #errorPageContainer { + background-image: url("./icons/error-server-not-found.svg"); + } + } + @-moz-document url-prefix("about:neterror?e=malformedURI") { + #errorPageContainer { + background-image: url("chrome://browser/skin/illustrations/error-malformed-url.svg"); + } + } + @-moz-document url-prefix("about:neterror?e=clockSkewError"), + url-prefix("about:neterror?e=nssFailure") { + #errorPageContainer { + background-image: url("./icons/blue-berror.svg"); + background-size: 18.5em; + } + } + + @-moz-document url("about:sessionrestore"), url(chrome://browser/content/aboutSessionRestore.xhtml) { + .description-wrapper { + background-image: url("./icons/error-session-restore.svg"); + } + } + + @-moz-document url-prefix("about:neterror?e=fileNotFound") { + @media (min-width: 970px) { + .title { + background-image: + url("chrome://global/skin/icons/info.svg") !important; + } + } + + #text-container { + padding-inline-start: 0; + } + } + @-moz-document url-prefix("about:tabcrashed") { + @media (min-width: 970px) { + .title { + background-image: url("chrome://browser/skin/tab-crashed.svg") !important; + } + } + } + @-moz-document url("about:robots"), url("chrome://browser/content/aboutRobots.xhtml") { + @media (min-width: 970px) { + .title { + background-image: url("chrome://browser/content/aboutRobots-icon.png") !important; + } + } + } + @-moz-document url("about:welcomeBack"), url("chrome://browser/content/aboutWelcomeBack.xhtml") { + @media (min-width: 970px) { + .title { + background-image: url("./icons/welcome-back.svg") !important; + } + } + } + + /** Fully Dark Mode *********************************************************/ + /*= Fully Dark Mode - Dark Mode Colors =====================================*/ + /* Based on chrome://global/skin/in-content/common.css */ + :host, + :root { + --in-content-page-color: rgb(21, 20, 26); + --in-content-page-background: #fff; + --in-content-text-color: var(--in-content-page-color); + --in-content-deemphasized-text: rgb(91, 91, 102); + --in-content-box-background: #fff; + --in-content-box-background-odd: rgba(12, 12, 13, 0.05); /* grey 90 a05 */ + --in-content-box-border-color: color-mix(in srgb, currentColor 41%, transparent); + --in-content-box-info-background: #f0f0f4; + --in-content-item-hover: color-mix(in srgb, var(--in-content-primary-button-background) 20%, transparent); + --in-content-item-hover-text: var(--in-content-page-color); + --in-content-item-selected: var(--in-content-primary-button-background); + --in-content-item-selected-text: var(--in-content-primary-button-text-color); + --in-content-icon-color: rgb(91,91,102); + --in-content-accent-color: #0a84ff; + --in-content-accent-color-active: #0060df; + --in-content-border-hover: var(--grey-90-a50); + --in-content-border-invalid: var(--red-50); + --in-content-border-color: #d7d7db; + --in-content-error-text-color: #c50042; + --in-content-link-color: var(--blue-60); + --in-content-link-color-hover: var(--blue-70); + --in-content-link-color-active: var(--blue-80); + --in-content-link-color-visited: var(--blue-60); + /* button background states are also used for checkboxes and radiobuttons */ + --in-content-button-text-color: var(--in-content-text-color); + --in-content-button-text-color-hover: var(--in-content-text-color); + --in-content-button-background: rgba(207,207,216,.33); + --in-content-button-background-hover: rgba(207,207,216,.66); + --in-content-button-background-active: rgb(207,207,216); + --in-content-primary-button-text-color: rgb(251,251,254); + --in-content-primary-button-text-color-hover: var(--in-content-primary-button-text-color); + --in-content-primary-button-background: #0061e0; + --in-content-primary-button-background-hover: #0250bb; + --in-content-primary-button-background-active: #053e94; + --in-content-danger-button-background: #e22850; + --in-content-danger-button-background-hover: #c50042; + --in-content-danger-button-background-active: #810220; + --in-content-focus-outline-color: var(--in-content-primary-button-background); + + /* Note: 1px smaller than we want because we have a 1px transparent border. */ + /* Once proton ships, these can probably stop being variables. */ + --in-content-button-border-radius: 4px; + --in-content-button-horizontal-padding: 15px; + --in-content-button-vertical-padding: 7px; + + --in-content-table-background: #f8f8fa; + --in-content-table-border-dark-color: #d1d1d1; + --in-content-table-header-background: #0a84ff; + --in-content-table-header-color: #ffffff; + --in-content-sidebar-width: 240px; + + --dialog-warning-text-color: var(--red-60); + + --checkbox-border-color: var(--in-content-box-border-color); + --checkbox-unchecked-bgcolor: var(--in-content-button-background); + --checkbox-unchecked-hover-bgcolor: var(--in-content-button-background-hover); + --checkbox-unchecked-active-bgcolor: var(--in-content-button-background-active); + --checkbox-checked-bgcolor: var(--in-content-primary-button-background); + --checkbox-checked-color: var(--in-content-primary-button-text-color); + --checkbox-checked-border-color: transparent; + --checkbox-checked-hover-bgcolor: var(--in-content-primary-button-background-hover); + --checkbox-checked-active-bgcolor: var(--in-content-primary-button-background-active); + + --blue-40: #45a1ff; + --blue-50: #0a84ff; + --blue-60: #0060df; + --blue-70: #003eaa; + --blue-80: #002275; + --grey-30: #d7d7db; + --grey-60: #4a4a4f; + --grey-90-a10: rgba(12, 12, 13, 0.1); + --grey-90-a20: rgba(12, 12, 13, 0.2); + --grey-90-a30: rgba(12, 12, 13, 0.3); + --grey-90-a50: rgba(12, 12, 13, 0.5); + --grey-90-a60: rgba(12, 12, 13, 0.6); + --green-50: #30e60b; + --green-60: #12bc00; + --green-70: #058b00; + --green-80: #006504; + --green-90: #003706; + --orange-50: #ff9400; + --red-40: #ff4f5e; + --red-50: #ff0039; + --red-60: #d70022; + --red-70: #a4000f; + --red-80: #5a0002; + --red-90: #3e0200; + --yellow-50: #ffe900; + --yellow-60: #d7b600; + --yellow-60-a30: rgba(215, 182, 0, 0.3); + --yellow-70: #a47f00; + --yellow-80: #715100; + --yellow-90: #3e2800; + + --shadow-10: 0 1px 4px var(--grey-90-a10); + --shadow-30: 0 4px 16px var(--grey-90-a10); + + --card-padding: 16px; + --card-shadow: var(--shadow-10); + --card-outline-color: var(--grey-30); + --card-shadow-hover: var(--card-shadow), 0 0 0 5px var(--card-outline-color); + } + + @media (-moz-toolbar-prefers-color-scheme: dark) { + :host, + :root { + /* Keep these in sync with layout/base/PresShell.cpp, and plaintext.css */ + --in-content-page-background: rgb(28,27,34); + --in-content-page-color: rgb(251,251,254); + --in-content-deemphasized-text: rgb(191,191,201); + + --in-content-box-background: rgb(35, 34, 43); + --in-content-box-background-odd: rgba(249,249,250,0.05); + --in-content-box-info-background: rgba(249,249,250,0.15); + + --in-content-border-color: rgba(249,249,250,0.2); + --in-content-border-hover: rgba(249,249,250,0.3); + --in-content-border-invalid: rgb(255,132,139); + + --in-content-error-text-color: #FF9AA2; + + --in-content-button-background: rgb(43,42,51); + --in-content-button-background-hover: rgb(82,82,94); + --in-content-button-background-active: rgb(91,91,102); + --in-content-icon-color: rgb(251,251,254); + + --in-content-primary-button-text-color: rgb(43,42,51); + --in-content-primary-button-background: rgb(0,221,255); + --in-content-primary-button-background-hover: rgb(128,235,255); + --in-content-primary-button-background-active: rgb(170,242,255); + + --in-content-danger-button-background: #ff848b; + --in-content-danger-button-background-hover: #ffbdc5; + --in-content-danger-button-background-active: #ffdfe7; + + --in-content-table-background: rgb(35, 34, 43); + --in-content-table-border-dark-color: rgba(249,249,250,0.2); + --in-content-table-header-background: rgb(5, 64, 150); + --in-content-table-header-color: var(--in-content-page-color); + + --in-content-accent-color: var(--in-content-primary-button-background); + --in-content-accent-color-active: var(--in-content-primary-button-background-hover); + --in-content-link-color: var(--in-content-primary-button-background); + --in-content-link-color-hover: var(--in-content-primary-button-background-hover); + --in-content-link-color-active: var(--in-content-primary-button-background-active); + --in-content-link-color-visited: var(--in-content-link-color); + + --card-outline-color: var(--grey-60); + + --dialog-warning-text-color: var(--red-40); + + scrollbar-color: rgba(249,249,250,.4) rgba(20,20,25,.3); + } + + /*= Addons.org =============================================================*/ + @-moz-document url-prefix("https://addons.mozilla.org") { + /* Basic */ + .Page-content, + .SecondaryHero, + main[aria-label="Content"] { + color: var(--in-content-page-color) !important; + background: var(--in-content-page-background) !important; + } + + /* Text */ + .AutoSearchInput-query, + .AutoSearchInput-suggestions-list, + .Page-content h1, + .Page-content h2, + .SearchResult-link, + .Home-SubjectShelf-link:link, + .Home-SubjectShelf-link:visited, + .DropdownMenuItem-link a, + .Select, + .Badge, + .Notice-generic, + .Notice-genericWarning, + .Notice-button, + .Paginate .Button.Paginate-item:first-child, + .Paginate .Button.Paginate-item:last-child, + .Paginate .Button.Paginate-item--current-page, + .Button--neutral, + .blog-entry-title, + .blogpost-nav * { + color: var(--in-content-text-color) !important; + } + .AutoSearchInput-suggestions-item:is(:active, :focus, :hover), + .SecondaryHero-message-link, + .SecondaryHero-module-link, + .Card-footer-link a, + .Card-shelf-footer-in-header a, + .SearchResult-link:is(:active, :focus, :hover), + .SearchResult:hover .SearchResult-link, + .Home-SubjectShelf-link:is(:active, :focus, :hover), + .DropdownMenuItem-link a:is(:active, :focus, :hover), + .AddonMeta .MetadataCard-title a:is(:active, :hover), + .AddonMeta .MetadataCard-title a.AddonMeta-reviews-content-link:is(:active, :hover), + .AddonMeta .MetadataCard-content a:is(:active, :hover), + .AddonMeta .MetadataCard-content a.AddonMeta-reviews-content-link:is(:active, :hover), + .Addon-summary a, + .RatingsByStar-count a:hover, + .RatingsByStar-star a:hover, + .Paginate .Button.Paginate-item:not(:first-child, :last-child, .Paginate-item--current-page), + .AddonTitle-author a, + .PermissionsCard-learn-more, + .DefinitionList a, + .ShowMoreCard-contents a, + .AddonDescription-contents a, + .AddonTitle a, + .TooltipMenu-opener, + .LanguageTools .Card-contents a, + .blog-entry-read-more-link, + .blogpost-nav-next.blogpost-nav-no-prev:hover p, + .blogpost-content-wrapper p a, + .blogpost-nav-prev:hover p, + .blogpost-nav-next:hover p { + color: var(--in-content-link-color) !important; + } + .SearchResult--meta-section, + .MetadataCard-title, + .MetadataCard-title a, + .MetadataCard-content a, + .CollectionSort-label, + .SearchResult-summary, + .AddonMeta .MetadataCard-content a.AddonMeta-reviews-content-link, + .AddonMeta .MetadataCard-title a.AddonMeta-reviews-content-link, + .PermissionsCard-subhead--optional, + .PermissionsCard-subhead--required, + .Definition-dt, + .RatingsByStar-count a, + .RatingsByStar-star a, + .Paginate-page-number, + .AddonSummaryCard-addonAverage, + .AddonReviewCard-authorByLine, + .Home-heroHeader-subtitle, + .blog-entry-date, + .blogpost-breadcrumb *, + .AddonTitle-author, + .ExpandableCard-ToggleLink, + .SearchFilters-label, + .PromotedBadge-label--line { + color: var(--in-content-deemphasized-text) !important; + } + .PromotedBadge-label--recommended { + color: color-mix(in srgb, #712b00 15%, #ff9400) !important; + } + + /* Background */ + .Button--action { + color: var(--in-content-primary-button-text-color) !important; + background: var(--in-content-primary-button-background) !important; + } + .Select, + .Button--neutral, + .Button--neutral:link, + .Notice-button { + background-color: var(--in-content-button-background) !important; + } + .Button--neutral.Button--micro:not(.Button--disabled):hover, + .Button--neutral:not(.Button--disabled):hover, + .Notice-button:hover { + background: var(--in-content-button-background-hover) !important; + } + .Button--action.Button--micro:not(.Button--disabled):hover, + .Button--action:not(.Button--disabled):hover { + background: var(--in-content-primary-button-background-hover) !important; + } + .ShowMoreCard-contents::after { + background: linear-gradient(hsla(0,0%,100%,0), var(--in-content-table-background)) !important; + } + .AutoSearchInput-query, + .AutoSearchInput-suggestions-list, + .SecondaryHero-module, + .Card-header, + .Card-contents, + .CardList ul > li, + .AddonsCard--horizontal ul.AddonsCard-list .SearchResult-wrapper:is(:focus, :hover), + .Paginate, + .LandingPage-header, + .DropdownMenu-items, + .DropdownMenu-items::after, + .MetadataCard, + .AddonsCard-list, + .Card-footer, + .StaticAddonCard, + .blogpost-nav * { + background: var(--in-content-table-background) !important; + } + + .Paginate .Button.Paginate-item:is(:active, :hover) { + background: var(--in-content-button-background-hover) !important; + } + .Notice-generic, + .Notice-genericWarning { + background: color-mix(in srgb, var(--in-content-page-background) 40%, var(--in-content-table-background)) !important; + } + + .LanguageTools-header-row { + color: var(--in-content-table-header-color) !important; + background: var(--in-content-table-header-background) !important; + } + .LanguageTools-table.responsiveTable tbody tr:nth-child(2n) { + background-color: var(--in-content-box-background-odd) !important; + } + + /* Fill */ + .Icon-arrow-blue.SearchSuggestion-icon-arrow { + filter: hue-rotate(330deg) brightness(1.3) !important; + } + .SecondaryHero-module-icon { + -moz-context-properties: fill, fill-opacity !important; + fill: currentColor !important; + } + .Icon-magnifying-glass, + .Notice-icon { + filter: invert(65%) !important; + } + .Icon-heart { + filter: brightness(0) !important; + } + .Permission .Icon { + filter: grayscale(100%) brightness(30) !important; + } + + /* Others */ + .DropdownMenu-items { + box-shadow: 0 0 2px var(--in-content-border-color) !important; + } + + .AutoSearchInput-query { + border: 1px solid var(--in-content-table-background) !important; + } + .AutoSearchInput-query:is(:hover, :focus) { + border-color: var(--in-content-primary-button-background) !important; + } + + .PromotedBadge-link--line { + border-color: var(--in-content-deemphasized-text) !important; + } + .PromotedBadge-link--line:hover { + border-color: var(--in-content-button-background-hover) !important; + } + + .blog-entry-read-more-link { + border-color: var(--in-content-link-color) !important; + } + + .blogpost-nav-arrow-left .cls-1, + .blogpost-nav-arrow-right .cls-1 { + stroke: var(--in-content-text-color) !important; + } + } + + /*= Support.org ============================================================*/ + @-moz-document url-prefix("https://support.mozilla.org") { + /* Basic */ + :root { + --color-blue-06: var(--in-content-link-color) !important; + --color-blue-07: var(--in-content-link-color-hover) !important; + + --page-bg: var(--in-content-page-background) !important; + --color-white: var(--in-content-page-background) !important; + --color-shade-bg: var(--in-content-page-background) !important; + --color-marketing-gray-02: var(--card-outline-color) !important; + --color-inverse-bg: var(--in-content-page-color) !important; + --color-inverse: var(--in-content-page-background) !important; + --color-text: var(--in-content-page-color) !important; + --color-text-light: var(--in-content-deemphasized-text) !important; + --color-link: var(--in-content-link-color) !important; + --color-success: var(--green-60) !important; + --color-warning: var(--yellow-60) !important; + --color-error: var(--red-60) !important; + --color-error-hover: var(--red-50) !important; + --color-moz-heading: #fff; + --color-moz-inverse-bg: var(red) !important; + --focus-shadow: 0 0 0 4px color-mix(in srgb, var(--in-content-primary-button-background) 30%, transparent),0 0 0 2px var(--in-content-primary-button-background-active); + } + body, + #main-content, + #instant-search-content, + #mzp-c-menu-panel-help, + .mzp-c-navigation { + color: var(--in-content-page-color) !important; + background: var(--in-content-page-background) !important; + } + + /* Text */ + .mzp-c-menu-category .mzp-c-menu-title, + .mzp-c-menu-item .mzp-c-menu-item-link, + .mzp-c-menu-item .mzp-c-menu-item-link > *, + .mzp-c-menu-item .mzp-c-menu-item-list a, + #doc-content .menu, + .document--content .menu, + .forum--entry-content .menu{ + color: var(--in-content-page-color) !important; + } + + .ts-select-trigger, + input[type="date"], + input[type="email"], + input[type="number"], + input[type="password"], + input[type="search"], + input[type="tel"], + input[type="text"], + input[type="time"], + input[type="url"], + select, + textarea, + #doc-content .button, + #doc-content .key, + .document--content .button, + .document--content .key, + .forum--entry-content .button, + .forum--entry-content .key{ + color: var(--in-content-deemphasized-text) !important; + } + + /* Background */ + .sidebar-nav.topics, .sidebar-nav.topics > li { + background: var(--in-content-page-background) !important; + } + + /* Fill */ + .sumo-nav--logo, + .sumo-nav--search-button, + .sumo-nav--toggle-button, + .card--icon-sm, + .mzp-c-menu-item-icon, + .mzp-c-menu-button-close, + .topic-article--icon, + .card--topic > .card--icon { + filter: invert(95%) !important; + } + + /* Others */ + .sumo-button.secondary-button { + border-color: none !important; + } + .mzp-c-menu-panel { + border-color: var(--in-content-button-background-hover) !important; + } + .mzp-c-menu-item:is(:focus, :hover, :active) .mzp-c-menu-item-link .mzp-c-menu-item-title { + border-color: var(--in-content-page-color) !important; + } + + @media screen and (min-width: 768px) { + .mzp-c-menu-panel { + box-shadow: box-shadow: 0 16px 16px -16px rgba(255,255,255,.3) !important; + } + } + .card--product, + .card--topic, + .card--article { + box-shadow: 0 5px 10px -3px rgba(249, 249, 250, .12), + 0 3px 16px 2px rgba(91, 91, 102, .12), + 0 8px 12px 1px rgba(82, 82, 94, .04) !important; + } + } + + /*= Accounts.com ===========================================================*/ + @-moz-document url-prefix("https://accounts.firefox.com") { + /* Basic */ + body { + color: var(--in-content-page-color) !important; + background: var(--in-content-page-background) !important; + } + .button.primary-button, + .button[type="submit"]:not(.secondary-button), + .settings-button.primary-button, + .settings-button[type="submit"]:not(.secondary-button), + button.primary-button, button[type="submit"]:not(.secondary-button) { + color: var(--in-content-primary-button-text-color) !important; + background: var(--in-content-primary-button-background) !important; + } + + /* Text */ + header h1, + .info, + .info a, + .faint a:hover, + .cta-neutral:hover { + color: var(--in-content-page-color) !important; + } + .links a, + .link-blue, + .text-blue-500 { + color: var(--in-content-link-color) !important; + } + .link-blue:hover { + color: var(--in-content-link-color-hover) !important; + } + .input-row input[type="email"], + .input-row input[type="number"], + .input-row input[type="password"], + .input-row input[type="tel"], + .input-row input[type="text"], + .input-row input::placeholder, + .firefox-family-services > ul > .firefox-service, + .faint, + .faint a, + .text-grey-400 { + color: var(--in-content-deemphasized-text) !important; + } + + + /* Background */ + .password-row .show-password-label { + background-color: unset !important; + } + #main-content, + .firefox-family-services, + .input-row input[type="email"], + .input-row input[type="number"], + .input-row input[type="password"], + .input-row input[type="tel"], + .input-row input[type="text"], + .password-row .show-password-label, + header, + .bg-white:not(nav) { + background: var(--in-content-box-background) !important; + } + #suggest-sync, + .cta-neutral { + background: var(--in-content-button-background) !important; + } + .cta-neutral:hover, + .bg-grey-50:hover, + .hover\:bg-grey-100:hover { + background: var(--in-content-button-background-hover) !important; + } + .hover\:bg-grey-200:hover { + background: var(--in-content-button-background-active) !important; + } + .button.primary-button:hover:enabled, + .button[type="submit"]:not(.secondary-button):hover:enabled, + .settings-button.primary-button:hover:enabled, + .settings-button[type="submit"]:not(.secondary-button):hover:enabled, + button.primary-button:hover:enabled, + button[type="submit"]:not(.secondary-button):hover:enabled { + background: var(--in-content-primary-button-background-hover) !important; + } + .tooltip, + .tooltip::before { + background: var(--in-content-danger-button-background) !important; + } + + /* Fill */ + .dismiss, + #about-mozilla, + .show-password-label, + footer a[data-testid="link-mozilla"] { + filter: invert(95%) !important; + } + header button svg, + header .rounded svg, + #service svg { + filter: brightness(15) !important; + } + button.relative, + #fxa-settings nav svg{ + filter: brightness(2) !important; + } + + /* Others */ + .input-row input[type="email"], + .input-row input[type="number"], + .input-row input[type="password"], + .input-row input[type="tel"], + .input-row input[type="text"], + .unit-row-hr + .border-grey-100 { + border-color: var(--in-content-border-color) !important; + } + .input-row input[type="email"]:hover, + .input-row input[type="number"]:hover, + .input-row input[type="password"]:hover, + .input-row input[type="tel"]:hover, + .input-row input[type="text"]:hover { + border-color: var(--in-content-border-hover) !important; + } + #main-content { + box-shadow: 0 12px 18px 2px rgba(249, 249, 250, .12) , + 0 6px 22px 4px rgba(91, 91, 102, .12), + 0 6px 10px -4px rgba(82, 82, 94, .04) !important; + } + .input-row input[type="email"]:focus, + .input-row input[type="number"]:focus, + .input-row input[type="password"]:focus, + .input-row input[type="tel"]:focus, + .input-row input[type="text"]:focus { + box-shadow: 0 0 0 3px color-mix(in srgb, var(--in-content-primary-button-background-hover) 80%, transparent) !important; + } + } + } + + /** Fully Proton Mode *******************************************************/ + /*= abouts' common =========================================================*/ + @-moz-document url-prefix("about:plugins"), + url-prefix("about:cache"), + url-prefix("about:checkerboard"), + url-prefix("about:sync-log"), + url-prefix("about:memory"), + regexp("^[file:///].*[^(html|svg|pdf)]$") { + /* Base */ + html, + body { + font: message-box !important; + appearance: none !important; + background-color: var(--in-content-page-background) !important; + color: var(--in-content-page-color) !important; + } + body { + font-size: 15px !important; + font-weight: normal !important; + margin: 0 !important; + } + + h1 { + line-height: 1.2 !important; + } + h2 { + line-height: 1.4em !important; + } + + /* Link */ + a { + color: var(--in-content-link-color) !important; + } + a:hover, + .text-link:hover { + color: var(--in-content-link-color-hover) !important; + text-decoration: underline !important; + } + a:visited { + color: var(--in-content-link-color-visited) !important; + } + a:hover:active, + .text-link:hover:active { + color: var(--in-content-link-color-active) !important; + } + a:-moz-focusring, + .text-link:-moz-focusring { + outline: 2px solid var(--in-content-focus-outline-color) !important; + outline-offset: 1px !important; + border-radius: 4px !important; + } + + /* Button */ + button { + font: inherit; + } + button, + select, + input[type="color"] { + appearance: none !important; + min-height: 32px !important; + color: var(--in-content-button-text-color, inherit) !important; + border: 1px solid transparent !important; /* shows up in high-contrast mode */ + border-radius: var(--in-content-button-border-radius) !important; + background-color: var(--in-content-button-background) !important; + font-weight: 400 !important; + padding: var(--in-content-button-vertical-padding) var(--in-content-button-horizontal-padding) !important; + text-decoration: none !important; + margin: 4px 8px !important; + /* Ensure font-size isn't overridden by widget styling (e.g. in forms.css) */ + font-size: 1em !important; + } + button { + font-weight: 600 !important; + /* Use the same margin of other elements for the alignment */ + margin-inline: 4px !important; + min-width: 6.3em !important; + } + /* Medium and small buttons get sized to 7/14 and 6/12px padding (when adding + * the 1px border): */ + button.medium { + --in-content-button-vertical-padding: 6px; + --in-content-button-horizontal-padding: 13px; + min-height: 28px !important; + font-size: 0.95em !important; + } + button.small { + --in-content-button-vertical-padding: 5px; + --in-content-button-horizontal-padding: 11px; + min-height: 24px !important; + font-size: 0.9em !important; + } + ::-moz-focus-inner { + border: none !important; + } + button:-moz-focusring { + box-shadow: none !important; + outline: 2px solid var(--in-content-focus-outline-color) !important; + outline-offset: 2px !important; + } + button:enabled:hover, + input[type="color"]:hover { + background-color: var(--in-content-button-background-hover) !important; + color: var(--in-content-button-text-color-hover) !important; + border-color: transparent !important; + } + button:enabled:hover:active, + input[type="color"]:enabled:hover:active { + background-color: var(--in-content-button-background-active) !important; + } + button:disabled, + input[type="color"]:disabled { + opacity: 0.4 !important; + } + button[autofocus], + button[type="submit"], + button.primary { + background-color: var(--in-content-primary-button-background) !important; + color: var(--in-content-primary-button-text-color) !important; + } + button[autofocus]:enabled:hover, + button[type="submit"]:enabled:hover, + button.primary:enabled:hover { + background-color: var(--in-content-primary-button-background-hover) !important; + color: var(--in-content-primary-button-text-color-hover) !important; + } + button[autofocus]:enabled:hover:active, + button[type="submit"]:enabled:hover:active, + button.primary:enabled:hover:active { + background-color: var(--in-content-primary-button-background-active) !important; + } + + /* Checkbox */ + input[type="checkbox"] { + margin-block: 2px !important; + } + input[type="checkbox"] { + appearance: none !important; + height: 16px !important; + width: 16px !important; + border: 1px solid var(--checkbox-border-color) !important; + background-color: var(--checkbox-unchecked-bgcolor) !important; + border-radius: 2px !important; + margin-inline: 0 6px !important; + flex-shrink: 0 !important; /* avoid shrinking inside flex container */ + } + input[type="checkbox"]:enabled:hover { + background-color: var(--checkbox-unchecked-hover-bgcolor) !important; + } + input[type="checkbox"]:enabled:hover:active { + background-color: var(--checkbox-unchecked-active-bgcolor) !important; + } + input[type="checkbox"]:checked { + border-color: var(--checkbox-checked-border-color) !important; + background-color: var(--checkbox-checked-bgcolor) !important; + background-image: url("chrome://global/skin/icons/check.svg") !important; + background-position: center !important; + background-repeat: no-repeat !important; + -moz-context-properties: fill !important; + fill: currentColor !important; + color: var(--checkbox-checked-color) !important; + /* Style the button also when printing with "Print Backgrounds" unchecked */ + color-adjust: exact !important; + } + input[type="checkbox"]:enabled:checked:hover { + background-color: var(--checkbox-checked-hover-bgcolor) !important; + } + input[type="checkbox"]:enabled:checked:hover:active { + background-color: var(--checkbox-checked-active-bgcolor) !important; + } + + /* Textarea */ + input:is([type="email"], [type="tel"], [type="text"], [type="password"], [type="url"], [type="number"]), + textarea { + appearance: none !important; + border: 1px solid var(--in-content-box-border-color) !important; + border-radius: 4px !important; + color: inherit !important; + background-color: var(--in-content-box-background) !important; + } + input:is([type="email"], [type="tel"], [type="text"], [type="password"], [type="url"], [type="number"]), + textarea { + font-family: inherit !important; + font-size: inherit !important; + padding: 8px !important; + margin: 2px 4px !important; + } + input:is([type="email"], [type="tel"], [type="text"], [type="password"], [type="url"], [type="number"]):focus, + textarea:focus, + search-textbox[focused], + tree:focus-visible, + richlistbox:focus-visible { + border-color: transparent !important; + outline: 2px solid var(--in-content-focus-outline-color) !important; + outline-offset: -1px !important; /* Prevents antialising around the corners */ + } + input:is([type="email"], [type="tel"], [type="text"], [type="password"], [type="url"], [type="number"]):-moz-ui-invalid, + textarea:-moz-ui-invalid { + border-color: transparent !important; + outline: 2px solid var(--in-content-border-invalid) !important; + outline-offset: -1px !important; /* Prevents antialising around the corners */ + } + input:is([type="email"], [type="tel"], [type="text"], [type="password"], [type="url"], [type="number"]):disabled, + textarea:disabled, + search-textbox[disabled="true"] { + opacity: 0.4 !important; + } + + /* Table */ + table { + width: 100% !important; + } + } + + @-moz-document url-prefix("about:plugins"), + url-prefix("about:cache"), + url-prefix("about:checkerboard") { + table { + border: 1px solid var(--in-content-border-color) !important; + border-radius: 0 !important; + } + } + @-moz-document url-prefix("about:cache"), + url-prefix("about:checkerboard") { + th, td { + border: 1px solid var(--in-content-border-color) !important; + } + th { + background-color: var(--in-content-table-header-background) !important; + color: var(--in-content-table-header-color) !important; + } + } + + /*= Directory View =========================================================*/ + @-moz-document url-prefix("about:sync-log"), + regexp("^[file:///].*[^(html|svg|pdf)]$") { + body { + background-color: var(--in-content-box-background) !important; + } + thead a { + color: var(--in-content-page-color) !important; + } + td ::before { + vertical-align: top !important; + } + } + + /*= about:plugins ==========================================================*/ + @-moz-document url-prefix("about:plugins") { + .notice { + background: var(--in-content-box-background) !important; + border: 1px solid var(--in-content-border-color) !important; + } + } + + /*= about:cache ============================================================*/ + @-moz-document url-prefix("about:cache") { + table { + padding: 0 !important; + } + + th, td { + padding: 4px !important; + text-align: match-parent !important; + } + } + + /*= about:checkerboard =====================================================*/ + @-moz-document url-prefix("about:checkerboard") { + #canvas { + border: 1px solid var(--in-content-border-color) !important; + } + #excludePageFromZoom { + vertical-align: bottom !important; + } + } + + /*= about:memory ===========================================================*/ + @-moz-document url-prefix("about:memory") { + .opsRow, + .section { + background-color: var(--in-content-box-background) !important; + color: var(--in-content-page-color) !important; + } + .opsRowLabel input { + vertical-align: bottom !important; + } + } +} diff --git a/home/dav/common.nix b/home/dav/common.nix new file mode 100644 index 0000000..0637197 --- /dev/null +++ b/home/dav/common.nix @@ -0,0 +1,239 @@ +{ config, pkgs, ... }: + +let + calendars = "${config.home.homeDirectory}/Calendars"; + contacts = "${config.home.homeDirectory}/Contacts"; + addressbook = "${config.home.homeDirectory}/.abook/addressbook"; + pass = "${pkgs.pass}/bin/pass"; + tokens = "${config.home.homeDirectory}/.vdirsyncer/tokens/"; +in { + home.file.".config/vdirsyncer/config".text = '' + [general] + status_path = "${config.home.homeDirectory}/.vdirsyncer/status/" + + + ############# + # nextcloud # + ############# + + ## calendar + + [pair nextcloud_calendar] + a = "nextcloud_calendar_local" + b = "nextcloud_calendar_remote" + collections = ["personal", "contact_birthdays", "yoga", "events"] + metadata = ["color"] + + [storage nextcloud_calendar_local] + type = "filesystem" + path = "${calendars}/nextcloud/" + fileext = ".ics" + + [storage nextcloud_calendar_remote] + type = "caldav" + url = "https://nextcloud.monotremata.xyz/" + username = "rilla" + password.fetch = ["command", "${pass}", "narwhal/nextcloud.monotremata.xyz/rilla"] + + ## contacts + + [pair nextcloud_contacts] + a = "nextcloud_contacts_local" + b = "nextcloud_contacts_remote" + collections = ["contacts"] + + [storage nextcloud_contacts_local] + type = "filesystem" + path = "${contacts}/nextcloud/" + fileext = ".vcf" + + [storage nextcloud_contacts_remote] + type = "carddav" + url = "https://nextcloud.monotremata.xyz/" + username = "rilla" + password.fetch = ["command", "${pass}", "narwhal/nextcloud.monotremata.xyz/rilla"] + + + ########## + # google # + ########## + + ## calendar + + [pair google_calendar_sync] + a = "google_calendar_remote" + b = "google_calendar_local" + collections = [["gcal", "r.illa.pujagut@gmail.com", "r.illa.pujagut@gmail.com"]] + + [storage google_calendar_local] + type = "filesystem" + path = "${calendars}/google/" + fileext = ".ics" + + [storage google_calendar_remote] + type = "google_calendar" + token_file = "${tokens}/goole_calendar" + client_id.fetch = ["command", "${pass}", "google.com/vdirsyncer/client_id"] + client_secret.fetch = ["command", "${pass}", "google.com/vdirsyncer/client_secret"] + + ## contacts + + [pair google_contacts] + a = "google_contacts_local" + b = "google_contacts_remote" + collections = [["gcontacts", "default", "default"]] + + [storage google_contacts_local] + type = "filesystem" + path = "${contacts}/google/" + fileext = ".vcf" + + [storage google_contacts_remote] + type = "google_contacts" + token_file = "${tokens}/google_contacts" + client_id.fetch = ["command", "${pass}", "google.com/vdirsyncer/client_id"] + client_secret.fetch = ["command", "${pass}", "google.com/vdirsyncer/client_secret"] + + + ########### + # trakken # + ########### + + ## calendar + + [pair trakken_calendar_sync] + a = "trakken_calendar_remote" + b = "trakken_calendar_local" + collections = [["trakken_cal", "ricard@trkkn.com", "ricard@trkkn.com"]] + + [storage trakken_calendar_local] + type = "filesystem" + path = "${calendars}/trakken/" + fileext = ".ics" + + [storage trakken_calendar_remote] + type = "google_calendar" + token_file = "${tokens}/trakken_calendar" + client_id.fetch = ["command", "${pass}", "google.com/vdirsyncer/client_id"] + client_secret.fetch = ["command", "${pass}", "google.com/vdirsyncer/client_secret"] + + ## contacts + + [pair trakken_contacts] + a = "trakken_contacts_local" + b = "trakken_contacts_remote" + collections = [["trakken_contacts", "default", "default"]] + + [storage trakken_contacts_local] + type = "filesystem" + path = "${contacts}/trakken" + fileext = ".vcf" + + [storage trakken_contacts_remote] + type = "google_contacts" + token_file = "${tokens}/trakken_contacts" + client_id.fetch = ["command", "${pass}", "google.com/vdirsyncer/client_id"] + client_secret.fetch = ["command", "${pass}", "google.com/vdirsyncer/client_secret"] + ''; + + home.file.".config/khal/config".text = '' + [calendars] + + [[default]] + path = ${calendars}/nextcloud/personal/ + color = dark green + + [[birthdays]] + path = ${calendars}/nextcloud/contact_birthdays/ + color = dark green + + [[google]] + path = ${calendars}/google/r.illa.pujagut@gmail.com/ + color = dark blue + + [[trakken]] + path = ${calendars}/trakken/ricard@trkkn.com/ + color = dark red + + [[yoga]] + path = ${calendars}/nextcloud/yoga/ + color = dark magenta + + [[events]] + path = ${calendars}/nextcloud/events + color = brown + + # supported colors: + # black, white, brown, yellow, dark gray, dark green, dark blue, + # light gray, light green, light blue, dark magenta, dark cyan, dark red, + # light magenta, light cyan, light red. + + [view] + dynamic_days = True + frame = color + theme = dark + + [locale] + default_timezone = Europe/Madrid + local_timezone = Europe/Madrid + timeformat = %H:%M + dateformat= %m-%d + longdateformat= %Y-%m-%d + datetimeformat= %m-%d %H:%M + longdatetimeformat= %Y-%m-%d %H:%M + ''; + + home.file.".config/khard/khard.conf".text = '' + [addressbooks] + [[default]] + path = ${contacts}/nextcloud/contacts/ + [[google]] + path = ${contacts}/google/default/ + [[trakken]] + path = ${contacts}/trakken/default/ + + [general] + debug = no + default_action = list + # These are either strings or comma seperated lists + editor = vim, -i, NONE + merge_editor = vimdiff + + [contact table] + # display names by first or last name: first_name / last_name / formatted_name + display = first_name + # group by address book: yes / no + group_by_addressbook = no + # reverse table ordering: yes / no + reverse = no + # append nicknames to name column: yes / no + show_nicknames = no + # show uid table column: yes / no + show_uids = yes + # sort by first or last name: first_name / last_name / formatted_name + sort = last_name + # localize dates: yes / no + localize_dates = yes + # set a comma separated list of preferred phone number types in descending priority + # or nothing for non-filtered alphabetical order + preferred_phone_number_type = pref, cell, home + # set a comma separated list of preferred email address types in descending priority + # or nothing for non-filtered alphabetical order + preferred_email_address_type = pref, work, home + + [vcard] + # extend contacts with your own private objects + # these objects are stored with a leading "X-" before the object name in the vcard files + # every object label may only contain letters, digits and the - character + # example: + # private_objects = Jabber, Skype, Twitter + # default: , (the empty list) + private_objects = Jabber, Skype, Twitter + # preferred vcard version: 3.0 / 4.0 + preferred_version = 3.0 + # Look into source vcf files to speed up search queries: yes / no + search_in_source_files = no + # skip unparsable vcard files: yes / no + skip_unparsable = no + ''; +} diff --git a/home/dav/davsync.nix b/home/dav/davsync.nix new file mode 100644 index 0000000..75bd3b5 --- /dev/null +++ b/home/dav/davsync.nix @@ -0,0 +1,22 @@ +{ config, pkgs, contacts, addressbook, ... }: + +let + shell = "${pkgs.dash}/bin/dash"; + vdirsyncer = "${pkgs.vdirsyncer}/bin/vdirsyncer"; + mkdir = "${pkgs.coreutils}/bin/mkdir"; + cat = "${pkgs.coreutils}/bin/cat"; + abook = "${pkgs.abook}/bin/abook"; + dirname = "${pkgs.coreutils}/bin/dirname"; +in + pkgs.writeScriptBin "davsync" '' + #!${shell} + ${vdirsyncer} discover && \ + ${vdirsyncer} sync && \ + ${mkdir} -p "$(${dirname} ${addressbook})" && \ + ${cat} "${contacts}"/*/*/* | \ + ${abook} \ + --convert \ + --informat vcard \ + --outformat abook > \ + "${config.home.homeDirectory}/.abook/adressbook" + '' diff --git a/home/dav/davsync_macos.nix b/home/dav/davsync_macos.nix new file mode 100644 index 0000000..33f2ced --- /dev/null +++ b/home/dav/davsync_macos.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +let + shell = "${pkgs.dash}/bin/dash"; + vdirsyncer = "${pkgs.vdirsyncer}/bin/vdirsyncer"; + mkdir = "${pkgs.coreutils}/bin/mkdir"; + cat = "${pkgs.coreutils}/bin/cat"; + dirname = "${pkgs.coreutils}/bin/dirname"; +in + pkgs.writeScriptBin "davsync" '' + #!${shell} + ${vdirsyncer} discover && \ + ${vdirsyncer} sync + '' diff --git a/home/dav/default.nix b/home/dav/default.nix new file mode 100644 index 0000000..b6d13af --- /dev/null +++ b/home/dav/default.nix @@ -0,0 +1,11 @@ +{ config, pkgs, ... }: + +let + contacts = "${config.home.homeDirectory}/Contacts"; + davsync = pkgs.callPackage ./davsync.nix { + inherit config pkgs contacts addressbook; + }; +in { + imports = [ ./common.nix ]; + home.packages = [ davsync pkgs.vdirsyncer pkgs.khal pkgs.khard pkgs.abook ]; +} diff --git a/home/dav/macos.nix b/home/dav/macos.nix new file mode 100644 index 0000000..94956e7 --- /dev/null +++ b/home/dav/macos.nix @@ -0,0 +1,9 @@ +{ config, pkgs, ... }: + +let + davsync = + pkgs.callPackage ./davsync_macos.nix { inherit config pkgs; }; +in { + imports = [ ./common.nix ]; + home.packages = [ davsync pkgs.vdirsyncer pkgs.khal pkgs.khard ]; +} diff --git a/home/default.nix b/home/default.nix new file mode 100644 index 0000000..c3b2f0b --- /dev/null +++ b/home/default.nix @@ -0,0 +1,212 @@ +{ config, pkgs, ... }: + +let + impermanence = builtins.fetchTarball { + url = "https://github.com/nix-community/impermanence/archive/master.tar.gz"; + }; +in { + # Let Home Manager install and manage itself. + # programs.home-manager.enable = true; + + # Home Manager needs a bit of information about you and the + # paths it should manage. + home.username = "rilla"; + home.homeDirectory = "/home/rilla"; + + imports = [ + "${impermanence}/home-manager.nix" + # ./desktop-sway + ./alacritty + ./arduino + ./barrier + ./browsers + ./dav + ./desktop-xmonad + ./fonts + ./git + ./gotify + ./gpg + ./idasen + ./mail + ./minidisc + ./mpd + ./msg + ./music + ./neovim + ./pass + ./rss + ./scripts + ./snapcast + ./sound + ./ssh + ./theming + ./tmux + ./vitetris + ./wallets + ./zsh + ]; + + home.persistence."/persist/system/${config.home.homeDirectory}" = { + directories = [ + ".abook" + ".bitmonero" + ".cache" + ".config/Nextcloud" + ".config/chromium" + ".config/whatsapp-for-linux" + ".gnupg/private-keys-v1.d" + ".local/share/keyrings" + ".local/share/mpd" + ".local/share/webkitgtk" + ".mozilla" + ".newsboat" + ".vdirsyncer" + ]; + files = [ + ".gnupg/pubring.kbx" + ".gnupg/trustdb.gpg" + ".mailsynclastrun" + ".ssh/known_hosts" + ".zsh_history" + ]; + allowOther = true; + }; + + home.persistence."/persist/user/${config.home.homeDirectory}" = { + directories = [ + ".config/Signal" + ".config/Element" + ".local/share/TelegramDesktop" + ".local/share/dino" + ".local/share/Bisq" + ".password-store" + ".walletwasabi" + "Calendars" + "Contacts" + "Documents" + "Downloads" + "Images" + "Maildir" + "Monero" + "Nextcloud" + "code" + "configs" + "misc" + "workspace" + ]; + files = [ ]; + allowOther = true; + }; + + home.sessionVariables = { + EDITOR = "${pkgs.neovim}/bin/nvim"; + VISUAL = "${pkgs.neovim}/bin/nvim"; + BROWSER = "${pkgs.firefox}/bin/firefox"; + # OPENER = "todo"; # todo + TERMINAL = "${pkgs.alacritty}/bin/alacritty"; + CM_LAUNCHER = "rofi"; # for clipmenu + LEDGER_FILE = "${config.home.homeDirectory}/finance/2021.journal"; + QT_QPA_PLATFORMTHEME = "qt5ct"; + }; + + home.packages = with pkgs; [ + R + acpi + android-tools + ansible + bind.dnsutils + calibre + docker-compose + file + gimp + gnumake + htop + jq + killall + lbry + libnotify + libreoffice + lxqt.pcmanfm-qt + mosh + mpv + neofetch + networkmanagerapplet + nextcloud-client + pandoc + pv + ripgrep + signify + sxiv + telnet + virt-manager + wget + ]; + + services.syncthing.enable = true; + + services.kdeconnect.enable = true; + + programs.bat = { + enable = true; + config = { theme = "gruvbox-dark"; }; + }; + + programs.fzf = { + enable = true; + enableZshIntegration = true; + # defaultOptions = [ + # "--preview --preview 'bat --color=always --style=header,grid --line-range :300 {}'" + # ]; + tmux.enableShellIntegration = true; + }; + + services.gnome-keyring = { + enable = true; + components = [ "secrets" ]; + }; + + services.nextcloud-client = { + enable = true; + startInBackground = true; + }; + + xdg.mimeApps = { + enable = true; + defaultApplications = { + "x-scheme-handler/http" = "firefox.desktop"; + "x-scheme-handler/https" = " firefox.desktop"; + "x-scheme-handler/chrome" = " firefox.desktop"; + "text/html" = "firefox.desktop"; + "application/x-extension-htm" = "firefox.desktop"; + "application/x-extension-html" = "firefox.desktop"; + "application/x-extension-shtml" = "firefox.desktop"; + "application/xhtml+xml" = "firefox.desktop"; + "application/x-extension-xhtml" = "firefox.desktop"; + "application/x-extension-xht" = "firefox.desktop"; + "x-scheme-handler/tg" = "userapp-Telegram Desktop.desktop"; + }; + associations.added = { + "x-scheme-handler/http" = "firefox.desktop"; + "x-scheme-handler/https" = " firefox.desktop"; + "x-scheme-handler/chrome" = " firefox.desktop"; + "text/html" = "firefox.desktop"; + "application/x-extension-htm" = "firefox.desktop"; + "application/x-extension-html" = "firefox.desktop"; + "application/x-extension-shtml" = "firefox.desktop"; + "application/xhtml+xml" = "firefox.desktop"; + "application/x-extension-xhtml" = "firefox.desktop"; + "application/x-extension-xht" = "firefox.desktop"; + "x-scheme-handler/tg" = "userapp-Telegram Desktop.desktop"; + + }; + }; + + dconf.settings = { + "org/virt-manager/virt-manager/connections" = { + "autoconnect" = [ "qemu:///system" ]; + "uris" = [ "qemu:///system" ]; + }; + }; + + home.stateVersion = "21.11"; +} diff --git a/home/desktop-sway/default.nix b/home/desktop-sway/default.nix new file mode 100644 index 0000000..9250cac --- /dev/null +++ b/home/desktop-sway/default.nix @@ -0,0 +1,63 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./sway.nix ./waybar.nix ./wofi.nix ]; + + home.packages = with pkgs; [ + swaylock + swayidle + wl-clipboard + wtype + brightnessctl + ]; + + programs.mako = { + enable = true; + actions = true; + anchor = "top-right"; + backgroundColor = "#282828E6"; + borderColor = "#458588"; + borderRadius = 0; + borderSize = 1; + font = "Inter 10"; + icons = true; + textColor = "#ebdbb2"; + defaultTimeout = 5000; + }; + + home.file.".config/swaylock/config".text = '' + ignore-empty-password + font=Inter + + color=282828E6 + inside-color=504945 + ring-color=504945 + line-color=504945 + separator-color=504945 + + inside-clear-color=FE8019 + line-clear-color=FE8019 + ring-clear-color=FE8019 + + inside-ver-color=458588 + line-ver-color=458588 + ring-ver-color=458588 + + inside-wrong-color=CC241D + line-wrong-color=CC241D + ring-wrong-color=CC241D + + key-hl-color=B8BB26 + bs-hl-color=FB4934 + + text-color=282828 + text-clear-color=282828 + text-ver-color=282828 + text-wrong-color=282828 + ''; + + programs.zsh.loginExtra = '' + [[ -z "''${DISPLAY}" ]] && [[ "$(tty)" = "/dev/tty1" ]] && \ + exec ${pkgs.sway}/bin/sway 1> "${config.home.homeDirectory}/.sway-errors" 2>&1 + ''; +} diff --git a/home/desktop-sway/sway.nix b/home/desktop-sway/sway.nix new file mode 100644 index 0000000..ed39444 --- /dev/null +++ b/home/desktop-sway/sway.nix @@ -0,0 +1,146 @@ +{ config, pkgs, ... }: + +let + cfg = config.wayland.windowManager.sway.config; + wofi_pass = pkgs.callPackage ./wofi-pass.nix { inherit config pkgs; }; + pactl = "${pkgs.pulseaudio}/bin/pactl"; + brightnessctl = "${pkgs.brightnessctl}/bin/brightnessctl"; + playerctl = "${pkgs.playerctl}/bin/playerctl"; +in +{ + wayland.windowManager.sway = { + enable = true; + wrapperFeatures.gtk = true; + config = { + modifier = "Mod4"; + terminal = "alacritty"; + menu = "${pkgs.wofi}/bin/wofi --show run"; + + left = "h"; + down = "j"; + up = "k"; + right = "l"; + + output = { + "LVDS-1" = { + resolution = "1366x768"; + bg = "~/Images/wallpapers/times_of_grace.jpg fill"; + }; + }; + + input = { + "type:keyboard" = { + xkb_layout = "us"; + xkb_variant = "altgr-intl"; + xkb_options = "caps:escape"; + }; + }; + + keybindings = { + "${cfg.modifier}+Return" = "exec ${cfg.terminal}"; + "${cfg.modifier}+Shift+c" = "kill"; + "${cfg.modifier}+r" = "exec ${cfg.menu}"; + "${cfg.modifier}+Shift+r" = "reload"; + "${cfg.modifier}+Shift+Escape" = "exec ${pkgs.sway}/bin/swaymsg exit"; + "${cfg.modifier}+Escape" = "exec ${pkgs.swaylock}/bin/swaylock"; + + "${cfg.modifier}+${cfg.left}" = "focus left"; + "${cfg.modifier}+${cfg.down}" = "focus down"; + "${cfg.modifier}+${cfg.up}" = "focus up"; + "${cfg.modifier}+${cfg.right}" = "focus right"; + + "${cfg.modifier}+Shift+${cfg.left}" = "move left"; + "${cfg.modifier}+Shift+${cfg.down}" = "move down"; + "${cfg.modifier}+Shift+${cfg.up}" = "move up"; + "${cfg.modifier}+Shift+${cfg.right}" = "move right"; + + "${cfg.modifier}+Control+${cfg.left}" = "move workspace to output left"; + "${cfg.modifier}+Control+${cfg.down}" = "move workspace to output down"; + "${cfg.modifier}+Control+${cfg.up}" = "move workspace to output up"; + "${cfg.modifier}+Control+${cfg.right}" = "move workspace to output right"; + + "${cfg.modifier}+Shift+w" = "move window to output left"; + "${cfg.modifier}+Shift+e" = "move window to output right"; + "${cfg.modifier}+w" = "focus output left"; + "${cfg.modifier}+e" = "focus output right"; + + "${cfg.modifier}+1" = "workspace number 1"; + "${cfg.modifier}+2" = "workspace number 2"; + "${cfg.modifier}+3" = "workspace number 3"; + "${cfg.modifier}+4" = "workspace number 4"; + "${cfg.modifier}+5" = "workspace number 5"; + "${cfg.modifier}+6" = "workspace number 6"; + "${cfg.modifier}+7" = "workspace number 7"; + "${cfg.modifier}+8" = "workspace number 8"; + "${cfg.modifier}+9" = "workspace number 9"; + + "${cfg.modifier}+Shift+1" = "move container to workspace number 1"; + "${cfg.modifier}+Shift+2" = "move container to workspace number 2"; + "${cfg.modifier}+Shift+3" = "move container to workspace number 3"; + "${cfg.modifier}+Shift+4" = "move container to workspace number 4"; + "${cfg.modifier}+Shift+5" = "move container to workspace number 5"; + "${cfg.modifier}+Shift+6" = "move container to workspace number 6"; + "${cfg.modifier}+Shift+7" = "move container to workspace number 7"; + "${cfg.modifier}+Shift+8" = "move container to workspace number 8"; + "${cfg.modifier}+Shift+9" = "move container to workspace number 9"; + + "${cfg.modifier}+b" = "splith"; + "${cfg.modifier}+v" = "splitv"; + + "${cfg.modifier}+s" = "layout stacking"; + "${cfg.modifier}+t" = "layout tabbed"; + # "${cfg.modifier}+e" = "layout toggle split"; + + "${cfg.modifier}+m" = "fullscreen toggle"; + + "${cfg.modifier}+a" = "focus parent"; + "${cfg.modifier}+f" = "floating toggle"; + # "${cfg.modifier}+space" = "focus mode_toggle"; + "${cfg.modifier}+d" = "mode resize"; + + "${cfg.modifier}+space" = "layout toggle all"; + "${cfg.modifier}+Shift+space" = "layout default"; + + "${cfg.modifier}+p" = "exec ${wofi_pass}/bin/wofi-pass"; + + "XF86AudioRaiseVolume" = "exec ${pactl} set-sink-volume @DEFAULT_SINK@ +5%"; + "XF86AudioLowerVolume" = "exec ${pactl} set-sink-volume @DEFAULT_SINK@ -5%"; + "XF86AudioMute" = "exec ${pactl} set-sink-mute @DEFAULT_SINK@ toggle"; + "XF86AudioMicMute" = "exec ${pactl} set-source-mute @DEFAULT_SOURCE@ toggle"; + "XF86MonBrightnessDown" = "exec ${brightnessctl} set 5%-"; + "XF86MonBrightnessUp" = "exec ${brightnessctl} set +5%"; + "XF86AudioPlay" = "exec ${playerctl} play-pause"; + "XF86AudioNext" = "exec ${playerctl} next"; + "XF86AudioPrev" = "exec ${playerctl} previous"; + "XF86Search" = "exec ${cfg.menu}"; + }; + + colors = { + + focused = rec { + childBorder = "#458588"; + background = "#282828"; + text = "#fbf1c7"; + indicator = "#3c3836"; + border = "#83a598"; + }; + + unfocused = rec { + childBorder = "#504945"; + background = "#282828"; + text = "#ebdbb2"; + indicator = "#3c3836"; + border = "#bdae93"; + }; + + }; + + focus.followMouse = true; + window.border = 3; + workspaceAutoBackAndForth = true; + + bars = []; + + }; + }; +} diff --git a/home/desktop-sway/waybar.nix b/home/desktop-sway/waybar.nix new file mode 100644 index 0000000..77fc35c --- /dev/null +++ b/home/desktop-sway/waybar.nix @@ -0,0 +1,150 @@ +{ config, pkgs, ... }: + +{ + programs.waybar = { + enable = true; + settings = [ + { + modules-left = [ "sway/workspaces" ]; + modules-center = [ "sway/window" ]; + modules-right = [ "tray" "pulseaudio" "battery" "network" "clock" ]; + modules = { + clock.format = "{: %m/%d |  %H:%M}"; + network = { + format-icons = [ + "" + "" + "" + ]; + format = "({ifname})"; + format-wifi = "{icon} {signalStrength}"; + format-disconnected = ""; + format-ethernet = ""; + }; + battery = { + states = { + good = 95; + warning = 50; + critical = 20; + }; + format-icons = { + discharging = [ + "" + "" + "" + "" + "" + "" + "" + "" + "" + ]; #  + charging = [ + "" + "" + "" + "" + "" + "" + ]; #  + }; + format = " {capacity}"; + format-full = ""; + format-good-charging = ""; + format-plugged = ""; + format-charging = "{icon} {capacity}"; + format-discharging = "{icon} {capacity} ({time})"; + interval = 5; + }; + pulseaudio = { + states = { + high = 101; + very_high = 111; + }; + format-icons = [ + "" + "奔" + "" + ]; + format = "{icon} {volume}"; + format-bluetooth = "{icon} {volume}"; + format-muted = "ﱝ"; + }; + + tray.icon-size = 10; + }; + } + ]; + style = '' + * { + border-radius: 0px; + border: none; + font-family: Inter, "mplus Nerd Font"; + font-size: 13px; + min-height: 0; + } + + window#waybar { + background-color: #282828; + color: #ebdbb2; + } + + #workspaces { + padding: 0px; + margin: 0px; + } + + #workspaces button { + padding: 0px; + margin: 0px; + background: transparent; + } + + #window { + color: #fbf1c7; + padding-left: 10px; + padding-right: 10px; + } + + #workspaces button.focused { + background-color: #458588; + color: #fbf1c7; + } + + #tray, + #pulseaudio, + #battery, + #network, + #cpu, + #memory, + #clock { + color: #fbf1c7; + padding-left: 5px; + padding-right: 5px; + } + + #tray, + #pulseaudio, + #battery, + #cpu, + #memory, + #network { + border-right: 1px solid #a89984; + } + + #pulseaudio.high { + color: #fabd2f; + } + + #pulseaudio.very_high { + color: #fb4944; + } + + #pulseaudio.muted { + color: #a8997a; + } + + ''; + systemd.enable = true; + }; +} diff --git a/home/desktop-sway/wofi-pass.nix b/home/desktop-sway/wofi-pass.nix new file mode 100644 index 0000000..d3ef3ba --- /dev/null +++ b/home/desktop-sway/wofi-pass.nix @@ -0,0 +1,30 @@ +{ config, pkgs, ... }: + +let + bash = "${pkgs.bash}/bin/bash"; + wofi = "${pkgs.wofi}/bin/wofi"; + pass = "${pkgs.pass}/bin/pass"; + wtype = "${pkgs.wtype}/bin/wtype"; + xargs = "${pkgs.findutils}/bin/xargs"; + wl-copy = "${pkgs.wl-clipboard}/bin/wl-copy"; + prefix = "${config.home.homeDirectory}/.password-store"; +in + pkgs.writeScriptBin "wofi-pass" '' + #!${bash} + + password_files=( "${prefix}"/**/*.gpg ) + password_files=( "''${password_files[@]#"${prefix}"/}" ) + password_files=( "''${password_files[@]%.gpg}" ) + + sel=$( + printf '%s\n' "''${password_files[@]}" | \ + ${wofi} --dmenu "$@" + ) + + #[ -n "''${sel}" ] && \ + # ${pass} show "''${sel}" | \ + # ${xargs} ${wtype} + + [ -n "''${sel}" ] && \ + ${pass} show "''${sel}" | ${wl-copy} + '' diff --git a/home/desktop-sway/wofi.nix b/home/desktop-sway/wofi.nix new file mode 100644 index 0000000..d2f165f --- /dev/null +++ b/home/desktop-sway/wofi.nix @@ -0,0 +1,57 @@ +{ config, pkgs, ... }: + +let + wofi_pass = pkgs.callPackage ./wofi-pass.nix { inherit config pkgs; }; +in +{ + + home.packages = [ pkgs.wofi wofi_pass ]; + + home.file.".config/wofi/style.css".text = '' + * { + font-family: Inter; + } + + #outer-box { + border: 2px solid #458588; + padding: 5px; + padding-bottom: 0px; + } + + window { + background-color: rgba(40, 40, 40, 0.9); + } + + #entry { + border-radius: 0px; + } + + #input { + border-radius: 0px; + background-color: #282828; + border: none; + border-bottom: 1px solid #928374; + margin-bottom: 5px; + background-color: transparent; + } + + #entry:selected { + background-color: rgba(69, 133, 136, 0.9); + } + + #text { + color: #ebdbb2; + } + + #text:selected { + background-color: transparent; + color: #fbf1c7; + } + + #scroll { + margin: 0px; + border: none; + } + + ''; +} diff --git a/home/desktop-xmonad/autorandr.nix b/home/desktop-xmonad/autorandr.nix new file mode 100644 index 0000000..e9a9b04 --- /dev/null +++ b/home/desktop-xmonad/autorandr.nix @@ -0,0 +1,52 @@ +{ config, pkgs, ... }: + +let + lvds_fingerprint = { + "LVDS-1" = "00ffffffffffff0030e4d8020000000000160103801c1078ea8855995b558f261d505400000001010101010101010101010101010101601d56d85000183030404700159c1000001b000000000000000000000000000000000000000000fe004c4720446973706c61790a2020000000fe004c503132355748322d534c42330059"; + }; + hdmi_fingerprint = { + "HDMI-2" = "00ffffffffffff0009d1e67845540000261d0103803c22782e4825a756529c270f5054a56b80d1c0b300a9c08180810081c001010101023a801871382d40582c450056502100001e000000ff004c394b30303333313031510a20000000fd00324c1e5311000a202020202020000000fc0042656e51204757323738300a200117020322f14f901f04130312021101140607151605230907078301000065030c001000023a801871382d40582c450056502100001f011d8018711c1620582c250056502100009f011d007251d01e206e28550056502100001e8c0ad08a20e02d10103e960056502100001800000000000000000000000000000000000000000047"; + }; + lvds_config = { + "LVDS-1" = { + enable = true; + crtc = 0; + mode = "1366x768"; + position = "1920x0"; + rate = "60.00"; + }; + }; + hdmi_config = { + "HDMI-2" = { + enable = true; + primary = true; + crtc = 0; + mode = "1920x1080"; + position = "0x0"; + rate = "60.00"; + }; + }; +in +{ + programs.autorandr = { + enable = true; + hooks.postswitch = { + "change-background" = "/run/current-system/sw/bin/systemctl --user restart random-background.service"; + "restart-xmonad" = "${pkgs.xmonad-with-packages}/bin/xmonad --restart"; + }; + profiles = { + "default" = { + fingerprint = lvds_fingerprint; + config = lvds_config; + }; + "docked-open" = { + fingerprint = pkgs.lib.mkMerge [ hdmi_fingerprint lvds_fingerprint ]; + config = pkgs.lib.mkMerge [ hdmi_config lvds_config ]; + }; + "docked-closed" = { + fingerprint = hdmi_fingerprint; + config = hdmi_config; + }; + }; + }; +} diff --git a/home/desktop-xmonad/default.nix b/home/desktop-xmonad/default.nix new file mode 100644 index 0000000..c09fad2 --- /dev/null +++ b/home/desktop-xmonad/default.nix @@ -0,0 +1,388 @@ +{ config, pkgs, ... }: + +let + gruvbox-dark = { + bg = "#282828"; + bg1 = "#3c3836"; + bg2 = "#504945"; + + fg = "#ebdbb2"; + fg0 = "#fbf1c7"; + fg3 = "#bdae93"; + + red = "#cc241d"; + green = "#98971a"; + yellow = "#d79921"; + blue = "#458588"; + purple = "#b16286"; + aqua = "#689d6a"; + gray = "#a89984"; + + gray2 = "#928374"; + red-light = "#fb4934"; + green-light = "#b8bb26"; + yellow-light = "#fabd2f"; + blue-light = "#83a598"; + purple-light = "#d3869b"; + aqua-light = "#8ec07c"; + + }; + colors = { + fg = gruvbox-dark.fg; + selFg = gruvbox-dark.fg0; + bg = gruvbox-dark.bg; + sel = gruvbox-dark.blue; + inactive = gruvbox-dark.gray; + inactiveBorder = gruvbox-dark.bg2; + urgent = gruvbox-dark.red; + }; + rofiTransparency = "96"; + font = { + name = "Inter"; + size = "10"; + }; + monoFont = { + name = "Hack"; + size = "9"; + }; + hmonitors = pkgs.haskellPackages.callPackage ./hmonitors.nix {}; + obtoxmd = pkgs.callPackage ./obtoxmd.nix { inherit config pkgs; }; + + hmonitorsQuery = "${hmonitors}/bin/hmonitors-query"; + acpi = "${pkgs.acpi}/bin/acpi"; + nmcli = "${pkgs.networkmanager}/bin/nmcli"; + pamixer = "${pkgs.pamixer}/bin/pamixer"; + +in +{ + imports = [ ./autorandr.nix ./misc.nix ]; + home = { + keyboard = { + layout = "us"; + options = ["caps:escape"]; + variant = "altgr-intl"; + }; + packages = [hmonitors obtoxmd pkgs.acpi pkgs.pamixer pkgs.openbox]; + file = { + ".xinitrc".text = "exec ${config.home.homeDirectory}/.xsession"; + ".xmonad/icons/3cols.xpm".source = ./icons/3cols.xpm; + ".xmonad/icons/float.xpm".source = ./icons/float.xpm; + ".xmonad/icons/full.xpm".source = ./icons/full.xpm; + ".xmonad/icons/grid.xpm".source = ./icons/grid.xpm; + ".xmonad/icons/mtall.xpm".source = ./icons/mtall.xpm; + ".xmonad/icons/tabs.xpm".source = ./icons/tabs.xpm; + ".xmonad/icons/tall.xpm".source = ./icons/tall.xpm; + }; + }; + + xsession = { + enable = true; + initExtra = '' + xset s off -dpms + ${pkgs.autorandr}/bin/autorandr --change --default default + export WINIT_X11_SCALE_FACTOR=1.33 + ''; + windowManager.xmonad = { + enable = true; + enableContribAndExtras = true; + extraPackages = haskellPackages : [ + haskellPackages.monad-logger + haskellPackages.dbus + ]; + config = ./xmonad/xmonad.hs; + libFiles = { + "Bindings.hs" = ./xmonad/lib/Bindings.hs; + "DefaultConfig.hs" = ./xmonad/lib/DefaultConfig.hs; + "Layouts.hs" = ./xmonad/lib/Layouts.hs; + "ManageHook.hs" = ./xmonad/lib/ManageHook.hs; + "Prompts.hs" = ./xmonad/lib/Prompts.hs; + "Utils.hs" = ./xmonad/lib/Utils.hs; + "Xmobar.hs" = ./xmonad/lib/Xmobar.hs; + "HostConfig.hs" = pkgs.writeText "HostConfig.hs" '' + module HostConfig + ( fontConfig + , colorConfig + , FontConfig (FontConfig) + , fontSize + , fontName + , ColorConfig (ColorConfig) + , fgColor + , selFgColor + , bgColor + , selColor + , inactiveColor + , inactiveBorderColor + , urgentColor + ) where + + fontConfig :: FontConfig + fontConfig = FontConfig + { fontSize = ${font.size} + , fontName = "${font.name}" + } + + colorConfig :: ColorConfig + colorConfig = ColorConfig + { fgColor = "${colors.fg}" + , selFgColor = "${colors.selFg}" + , bgColor = "${colors.bg}" + , selColor = "${colors.sel}" + , inactiveColor = "${colors.inactive}" + , inactiveBorderColor = "${colors.inactiveBorder}" + , urgentColor = "${colors.urgent}" + } + + data FontConfig = FontConfig + { fontSize :: Int + , fontName :: String + } deriving Show + + data ColorConfig = ColorConfig + { fgColor :: String + , selFgColor :: String + , bgColor :: String + , selColor :: String + , inactiveColor :: String + , inactiveBorderColor :: String + , urgentColor :: String + } deriving Show + ''; + }; + }; + }; + + programs.xmobar = { + enable = true; + extraConfig = '' + Config + { font = "xft:${font.name}:style=Regular:size=${font.size}" + , additionalFonts = ["xft:mplus Nerd Font:size=12"] + , bgColor = "${colors.bg}" + , fgColor = "${colors.fg}" + , alignSep = "}{" + , sepChar = "%" + , template = "%StdinReader% }{ %vol%%bat%%net%%date%" + , lowerOnStart = True + , hideOnStart = False + , persistent = True + , allDesktops = True + , position = TopW L 100 + , commands = + [ Run Com "${hmonitorsQuery}" ["date" ] "date" 10 + , Run Com "${hmonitorsQuery}" ["bat", "${acpi}" ] "bat" 10 + , Run Com "${hmonitorsQuery}" ["net", "${nmcli}" ] "net" 20 + , Run Com "${hmonitorsQuery}" ["vol", "${pamixer}"] "vol" 5 + , Run StdinReader + ] + } + ''; + }; + + programs.rofi = { + enable = true; + font = "${font.name} ${font.size}"; + extraConfig = { + display-run = " "; + # display-drun = " "; + display-window = " "; + drun-display-format = "{name}"; + modi = "window,run,drun,ssh"; + show-icons = false; + }; + theme = let + inherit (config.lib.formats.rasi) mkLiteral; + in { + "*" = { + background-color = mkLiteral "transparent"; + border = 0; + margin = 0; + padding = 0; + spacing = 0; + }; + element = { + padding = 2; + orientation = "vertical"; + }; + "element-text" = { + text-color = mkLiteral colors.fg; + }; + + "element selected" = { + text-color = mkLiteral colors.selFg; + background-color = mkLiteral "${colors.sel}A0"; + }; + entry = { + padding = mkLiteral "0 0 6 3"; + text-color = mkLiteral colors.fg; + }; + inputbar = { + children = map mkLiteral ["prompt" "entry"]; + border = mkLiteral "0 0 1 0"; + border-color = mkLiteral gruvbox-dark.gray2; + margin = mkLiteral "0 0 5 0"; + }; + listview = { + columns = 1; + fixed-height = false; + }; + mainbox = { + children = map mkLiteral ["inputbar" "listview"]; + margin = 6; + }; + prompt = { + padding = mkLiteral "0 0 0 6"; + text-color = mkLiteral colors.fg; + background-color = mkLiteral "transparent"; + }; + window = { + transparency = "real"; + background-color = mkLiteral "${colors.bg}D0"; + y-offset = mkLiteral "-25%"; + border = 2; + border-color = mkLiteral colors.sel; + }; + }; + terminal = "${pkgs.alacritty}/bin/alacritty"; + pass = { + enable = true; + extraConfig = '' + URL_field='url' + USERNAME_field='user' + AUTOTYPE_field='autotype' + delay=2 + wait=0.2 + xdotool_delay=12 + EDITOR='gvim -f' + BROWSER='xdg-open' + default_do='typePass' # menu, autotype, copyPass, typeUser, typePass, copyUser, copyUrl, viewEntry, typeMenu, actionMenu, copyMenu, openUrl + auto_enter='false' + notify='false' + default_autotype='user :tab pass' + help_color="${gruvbox-dark.blue-light}" + clip=primary + clip_clear=45 + edit_new_pass="true" + default_user=":filename" + autotype="Alt+1" + type_user="Alt+u" + type_pass="Alt+p" + copy_name="" + copy_pass="" + ''; + }; + }; + + services.dunst = { + enable = true; + iconTheme = { + name = "Papirus-Dark"; + package = pkgs.papirus-icon-theme; + }; + settings = { + global = { + font = "${font.name} ${font.size}"; + format = ''%s\n%b''; + sort = "yes"; + indicate_hidden = "yes"; + alignment = "left"; + bounce_freq = 0; + show_age_threshold = 60; + word_wrap = "yes"; + ignore_newline = "no"; + geometry = "300x5-30+20"; + shrink = "yes"; + transparency = 0; + idle_threshold = 10; + monitor = 0; + follow = "mouse"; + sticky_history = "yes"; + history_length = 20; + show_indicators = "yes"; + line_height = 0; + separator_height = 2; + padding = 8; + horizontal_padding = 8; + separator_color = "frame"; + startup_notification = false; + dmenu = "${pkgs.rofi}/bin/rofi -dmenu -p dunst:"; + browser = "${pkgs.firefox}/bin/firefox"; + icon_position = "left"; + frame_width = 0; + frame_color = colors.inactive; + }; + shortcuts = { + close = "ctrl+space"; + close_all = "ctrl+shift+space"; + context = "ctrl+shift+period"; + }; + urgency_low = { + background = "${colors.bg}${rofiTransparency}"; + foreground = colors.fg; + timeout = 10; + }; + urgency_normal = { + background = "${colors.sel}${rofiTransparency}"; + foreground = colors.selFg; + timeout = 10; + }; + urgency_critical = { + background = "${colors.urgent}${rofiTransparency}"; + foreground = colors.selFg; + timeout = 10; + }; + }; + }; + + services.stalonetray = { + enable = true; + config = { + icon_size = 20; + background = colors.bg; + sticky = true; + geometry = "3x1-350+0"; + icon_gravity = "E"; + grow_gravity = "E"; + }; + }; + + xresources.properties = { + "Sxiv.foreground" = colors.fg; + "Sxiv.background" = colors.bg; + "Sxiv.font" = "${monoFont.name}:size=${monoFont.size}"; + }; + + programs.zathura = { + enable = true; + options = { + font = "${monoFont.name} ${monoFont.size}"; + default-bg = colors.bg; + default-fg = gruvbox-dark.bg1; + statusbar-fg = gruvbox-dark.fg3; + statusbar-bg = gruvbox-dark.bg2; + inputbar-bg = colors.bg; + inputbar-fg = colors.sel; + notification-bg = colors.bg; + notification-fg = colors.sel; + notification-error-bg = colors.bg; + notification-error-fg = gruvbox-dark.red-light; + notification-warning-bg = colors.bg; + notification-warning-fg = gruvbox-dark.red-light; + highlight-color = gruvbox-dark.yellow-light; + highlight-active-color = gruvbox-dark.blue-light; + completion-bg = gruvbox-dark.bg1; + completion-fg = gruvbox-dark.blue-light; + completion-highlight-fg = colors.selFg; + completion-highlight-bg = gruvbox-dark.blue-light; + recolor-lightcolor = colors.bg; + recolor-darkcolor = colors.fg; + recolor = false; + recolor-keephue = false; + }; + }; + + programs.zsh.loginExtra = '' + [[ -z "''${DISPLAY}" ]] && [[ "$(tty)" = "/dev/tty1" ]] && \ + exec "${pkgs.xorg.xinit}/bin/startx" 1> "${config.home.homeDirectory}/.xsession-errors" 2>&1 + ''; + +} diff --git a/home/desktop-xmonad/hmonitors.nix b/home/desktop-xmonad/hmonitors.nix new file mode 100644 index 0000000..8e4bd9f --- /dev/null +++ b/home/desktop-xmonad/hmonitors.nix @@ -0,0 +1,21 @@ +{ mkDerivation, base, containers, lib, process, regex-compat, split +, time +}: +mkDerivation { + pname = "hmonitors"; + version = "0.1.0.0"; + src = builtins.fetchGit { + name = "hmonitors"; + url = "https://git.monotremata.xyz/rilla/hmonitors.git"; + ref = "master"; + # rev = "165195cd964969c744120997850954c9371690a4"; + rev = "24a52ffb02b068135d736006fecccfe955099da7"; + }; + isLibrary = true; + isExecutable = true; + libraryHaskellDepends = [ + base containers process regex-compat split time + ]; + executableHaskellDepends = [ base ]; + license = lib.licenses.bsd3; +} diff --git a/home/desktop-xmonad/icons/3cols.xpm b/home/desktop-xmonad/icons/3cols.xpm new file mode 100644 index 0000000..7b2b68a --- /dev/null +++ b/home/desktop-xmonad/icons/3cols.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char *_cols[] = { +/* columns rows colors chars-per-pixel */ +"16 16 2 1 ", +" c #EBDBB2", +". c None", +/* pixels */ +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. " +}; diff --git a/home/desktop-xmonad/icons/float.xpm b/home/desktop-xmonad/icons/float.xpm new file mode 100644 index 0000000..fa47c61 --- /dev/null +++ b/home/desktop-xmonad/icons/float.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char *float[] = { +/* columns rows colors chars-per-pixel */ +"16 16 2 1 ", +" c #EBDBB2", +". c None", +/* pixels */ +".. ", +".. ", +".. ", +".. ", +".. ", +".. ", +".. ", +"......... ", +"......... ", +" .. ", +" .. ", +" .. ", +" .. ", +" .. ", +" .........", +" ........." +}; diff --git a/home/desktop-xmonad/icons/full.xpm b/home/desktop-xmonad/icons/full.xpm new file mode 100644 index 0000000..1ec7edb --- /dev/null +++ b/home/desktop-xmonad/icons/full.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char *full[] = { +/* columns rows colors chars-per-pixel */ +"16 16 1 1 ", +" c #EBDBB2", +/* pixels */ +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" " +}; diff --git a/home/desktop-xmonad/icons/grid.xpm b/home/desktop-xmonad/icons/grid.xpm new file mode 100644 index 0000000..b744afb --- /dev/null +++ b/home/desktop-xmonad/icons/grid.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char *grid[] = { +/* columns rows colors chars-per-pixel */ +"16 16 2 1 ", +" c #EBDBB2", +". c None", +/* pixels */ +" .. ", +" .. ", +" .. ", +" .. ", +" .. ", +" .. ", +" .. ", +"................", +"................", +" .. ", +" .. ", +" .. ", +" .. ", +" .. ", +" .. ", +" .. " +}; diff --git a/home/desktop-xmonad/icons/mtall.xpm b/home/desktop-xmonad/icons/mtall.xpm new file mode 100644 index 0000000..058fe7a --- /dev/null +++ b/home/desktop-xmonad/icons/mtall.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char *mtall[] = { +/* columns rows colors chars-per-pixel */ +"16 16 2 1 ", +" c #EBDBB2", +". c None", +/* pixels */ +" ", +" ", +" ", +" ", +" ", +" ", +" ", +"................", +"................", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. ", +" .. .. " +}; diff --git a/home/desktop-xmonad/icons/tabs.xpm b/home/desktop-xmonad/icons/tabs.xpm new file mode 100644 index 0000000..88e1faf --- /dev/null +++ b/home/desktop-xmonad/icons/tabs.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char *tabs[] = { +/* columns rows colors chars-per-pixel */ +"16 16 2 1 ", +" c #EBDBB2", +". c None", +/* pixels */ +" ", +" .............. ", +" ", +"................", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" " +}; diff --git a/home/desktop-xmonad/icons/tall.xpm b/home/desktop-xmonad/icons/tall.xpm new file mode 100644 index 0000000..3c5cd01 --- /dev/null +++ b/home/desktop-xmonad/icons/tall.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char *tall[] = { +/* columns rows colors chars-per-pixel */ +"16 16 2 1 ", +" c #EBDBB2", +". c None", +/* pixels */ +" .. ", +" .. ", +" .. ", +" .. ", +" .........", +" .........", +" .. ", +" .. ", +" .. ", +" .. ", +" .........", +" .........", +" .. ", +" .. ", +" .. ", +" .. " +}; diff --git a/home/desktop-xmonad/misc.nix b/home/desktop-xmonad/misc.nix new file mode 100644 index 0000000..73811bc --- /dev/null +++ b/home/desktop-xmonad/misc.nix @@ -0,0 +1,36 @@ +{ config, pkgs, ... }: + +let + wallpapers = "${config.home.homeDirectory}/Images/wallpapers/enabled"; +in +{ + services.picom = { + enable = true; + blur = true; + fade = false; + shadow = true; + }; + + services.random-background = { + enable = true; + enableXinerama = true; + display = "fill"; + imageDirectory = wallpapers; + }; + + systemd.user.services.xbanish = { + Unit = { + Description = "Xbanish"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + Service = { + Type = "simple"; + ExecStart = "${pkgs.xbanish}/bin/xbanish"; + }; + Install = { + WantedBy = [ "graphical-session.target" ]; + }; + }; + +} diff --git a/home/desktop-xmonad/obtoxmd.nix b/home/desktop-xmonad/obtoxmd.nix new file mode 100644 index 0000000..bb71639 --- /dev/null +++ b/home/desktop-xmonad/obtoxmd.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ...}: + +let + shell = "${pkgs.dash}/bin/dash"; + xmonad = "${pkgs.haskellPackages.xmonad}/bin/xmonad"; + openbox = "${pkgs.openbox}/bin/openbox"; +in + pkgs.writeScriptBin "obtoxmd" '' + #!${shell} + ${openbox} + ${xmonad} + '' diff --git a/home/desktop-xmonad/xmonad/lib/Bindings.hs b/home/desktop-xmonad/xmonad/lib/Bindings.hs new file mode 100644 index 0000000..a13c053 --- /dev/null +++ b/home/desktop-xmonad/xmonad/lib/Bindings.hs @@ -0,0 +1,366 @@ +module Bindings + ( keybinds + , mousebinds + ) where + +-- +-- q , w , e : screen naviagation +-- h , j , k , l : vim-style 2D navitgation +-- n , p : next/previous +-- r : run +-- t : tile +-- g : toggle spacing (gaps) +-- b " toggle bar +-- x , y : reflect +-- z : minimize +-- [ , ] : tab navigation + +import System.Exit (exitSuccess) + +import Data.Monoid ( appEndo ) +import Data.Ratio ( (%) ) +import qualified Data.Map as M + +import XMonad ( (.|.) , gets ) +import XMonad.Util.Types ( Direction2D (U, D, L, R) ) +import XMonad.Hooks.ManageDocks ( ToggleStruts (ToggleStruts) ) +import XMonad.Util.Run ( safeSpawn ) +import XMonad.Util.Paste ( pasteSelection ) +import XMonad.Layout.ResizableTile ( MirrorResize (MirrorShrink, MirrorExpand) ) +import XMonad.Layout.Reflect ( REFLECTX (REFLECTX) , REFLECTY (REFLECTY) ) +import XMonad.Layout.MultiToggle ( Toggle (Toggle) ) +import XMonad.Layout.BoringWindows ( focusUp , focusDown ) +import XMonad.Layout.Maximize ( maximizeRestore ) +import XMonad.Actions.CopyWindow ( kill1 ) +import XMonad.Actions.FloatKeys ( keysResizeWindow, keysMoveWindow ) +import XMonad.Actions.Navigation2D ( switchLayer , windowGo , windowSwap ) +import XMonad.Hooks.ManageHelpers ( doRectFloat ) + +import XMonad.Core + ( Layout + , X + , terminal + , modMask + , layoutHook + , XConfig (XConfig) + , whenJust + , runQuery + , windowset + , io + , ScreenId + , WindowSpace + ) + +import XMonad.Layout.IndependentScreens + ( workspaces' + , onCurrentScreen + , unmarshallS + ) + +import XMonad.Layout.SubLayouts + ( onGroup + , pushGroup + , GroupMsg (MergeAll, UnMerge) + ) + +import Graphics.X11.Types + ( Window , ButtonMask , KeyMask , KeySym , Button + , button1 , button2 , button3 + , shiftMask , controlMask + , xK_Return , xK_Escape , xK_Insert , xK_Right , xK_Left + , xK_space , xK_plus , xK_minus , xK_comma , xK_period + , xK_bracketleft , xK_bracketright + , xK_1 , xK_9 , xK_0 + , xK_b , xK_c , xK_e , xK_g , xK_h , xK_j , xK_k , xK_l , xK_m + , xK_n , xK_o , xK_p , xK_q , xK_r , xK_t , xK_u , xK_w , xK_x + , xK_y , xK_z + , xK_KP_End , xK_KP_Down , xK_KP_Next + , xK_KP_Add, xK_KP_Subtract, xK_KP_Insert, xK_KP_Enter + ) + +import Graphics.X11.ExtraTypes.XF86 + ( xF86XK_AudioMute + , xF86XK_AudioLowerVolume , xF86XK_AudioRaiseVolume + , xF86XK_AudioPlay , xF86XK_AudioStop + , xF86XK_AudioPrev , xF86XK_AudioNext + , xF86XK_RotateWindows + , xF86XK_MonBrightnessUp , xF86XK_MonBrightnessDown + ) + +import XMonad.Layout + ( IncMasterN (..) + , Resize (Shrink, Expand) + , ChangeLayout (NextLayout) + ) + +import XMonad.Operations + ( windows + , sendMessage + , setLayout + , withFocused + , screenWorkspace + , restart + , mouseResizeWindow + , mouseMoveWindow + , focus + ) + +import XMonad.StackSet + ( StackSet (..) + , RationalRect (..) + , Workspace (..) + , shift + , greedyView + , swapUp + , swapDown + , sink + , view + , floating + , screen + , shiftMaster + , focusDown' + , focusUp' + ) + +import XMonad.Layout.Spacing + ( toggleScreenSpacingEnabled + , toggleWindowSpacingEnabled + ) + +import XMonad.Actions.Minimize + ( minimizeWindow + , withLastMinimized + , maximizeWindowAndFocus + ) + +import XMonad.Actions.CycleWS + ( toggleWS' + , WSType (WSIs) + , shiftTo + , moveTo + , Direction1D (Next, Prev) + ) + +import ManageHook ( scratchpadKeybinds ) +import Prompts ( promptKeybinds ) +import Utils ( mkSubmap ) + +mousebinds :: XConfig Layout -> M.Map (KeyMask, Button) (Window -> X ()) +mousebinds XConfig {modMask = modm} = M.fromList bindings + where + bindings = + [ ((modm, button1), move) + , ((modm, button2), toMaster) + , ((modm, button3), resize) + ] + move = mouseDo mouseMoveWindow + resize = mouseDo mouseResizeWindow + toMaster = mouseDo return + mouseDo f w = focus w >> f w >> windows shiftMaster + +keybinds :: XConfig Layout -> M.Map (ButtonMask, KeySym) (X ()) +keybinds = foldr1 keyComb + [ wmBinds + , spawnBinds + , promptKeybinds + , scratchpadKeybinds + , workspaceBinds + , screenBinds + ] + where + keyComb f g conf = M.union (f conf) (g conf) + +spawnBinds :: XConfig Layout -> M.Map (ButtonMask, KeySym) (X ()) +spawnBinds conf = M.fromList . map mkSpawn $ bindList + where + bindList = singles ++ playerctl ++ xbacklight ++ pamixer + singles = + [ ((modm, xK_Return), terminal conf, []) + , ((0, xF86XK_RotateWindows), "thinkpad-rotate", []) + , ((modm, xK_Escape), "slock", []) + ] + -- mpc = withCmd "mpc" + -- [ ((0, xK_KP_End), ["prev"]) + -- , ((0, xK_KP_Down), ["toggle"]) + -- , ((0, xK_KP_Next), ["next"]) + -- , ((0, xF86XK_AudioPlay), ["toggle"]) + -- , ((0, xF86XK_AudioStop), ["stop"]) + -- , ((0, xF86XK_AudioPrev), ["prev"]) + -- , ((0, xF86XK_AudioNext), ["next"]) + -- ] + playerctl = withCmd "playerctl" + [ ((0, xK_KP_End), ["previous"]) + , ((0, xK_KP_Down), ["play-pause"]) + , ((0, xK_KP_Next), ["next"]) + , ((0, xF86XK_AudioPlay), ["play-pause"]) + , ((0, xF86XK_AudioStop), ["stop"]) + , ((0, xF86XK_AudioPrev), ["previous"]) + , ((0, xF86XK_AudioNext), ["next"]) + ] + xbacklight = withCmd "xbacklight" + [ ((0, xF86XK_MonBrightnessUp), ["-inc", "10"]) + , ((0, xF86XK_MonBrightnessDown), ["-dec", "10"]) + ] + pamixer = withCmd "pamixer" + [ ((0, xK_KP_Subtract), ["--decrease", "5"]) + , ((0, xK_KP_Add), ["--increase", "5", "--allow-boost"]) + , ((0, xK_KP_Enter), ["--set-volume", "100"]) + , ((0, xK_KP_Insert), ["--togle-mute"]) + , ((0, xF86XK_AudioLowerVolume), ["--decrease", "5"]) + , ((0, xF86XK_AudioRaiseVolume), ["--increase", "5", "--allow-boost"]) + , ((0, xF86XK_AudioMute), ["--toggle-mute"]) + ] + mkSpawn (comb,cmd,args) = (comb, safeSpawn cmd args) + withCmd cmd = map (\(comb,args) -> (comb,cmd,args)) + modm = modMask conf + +wmBinds :: XConfig Layout -> M.Map (ButtonMask, KeySym) (X ()) +wmBinds conf@XConfig {modMask = modm} = M.fromList + [ ((0, xK_Insert), pasteSelection) + + , ((modm .|. shiftMask, xK_o), restart "obtoxmd" True) + , ((modm .|. shiftMask, xK_r), restart "xmonad" True) + , ((modm .|. shiftMask, xK_Escape), io exitSuccess) + + -- navigating windows + , ((modm, xK_j), windowGo D False) + , ((modm, xK_k), windowGo U False) + , ((modm, xK_h), windowGo L False) + , ((modm, xK_l), windowGo R False) + , ((modm, xK_n), focusDown) + , ((modm, xK_p), focusUp) + + -- sublayout things + , ((modm .|. controlMask, xK_m), withFocused (sendMessage . MergeAll)) + , ((modm .|. controlMask, xK_u), withFocused (sendMessage . UnMerge)) + , ((modm .|. controlMask, xK_h), sendMessage $ pushGroup L) + , ((modm .|. controlMask, xK_l), sendMessage $ pushGroup R) + , ((modm .|. controlMask, xK_k), sendMessage $ pushGroup U) + , ((modm .|. controlMask, xK_j), sendMessage $ pushGroup D) + , ((modm, xK_bracketleft), onGroup focusUp') + , ((modm, xK_bracketright), onGroup focusDown') + + -- moving windows + , ((modm .|. shiftMask, xK_j), move M.! "D") + , ((modm .|. shiftMask, xK_k), move M.! "U") + , ((modm .|. shiftMask, xK_h), move M.! "L") + , ((modm .|. shiftMask, xK_l), move M.! "R") + , ((modm .|. shiftMask, xK_n), windows swapDown) + , ((modm .|. shiftMask, xK_p), windows swapUp) + + -- resizing windows + , ((modm, xK_plus ), resize M.! "+") + , ((modm, xK_minus), resize M.! "-") + , ((modm .|. shiftMask .|. controlMask, xK_h), resize M.! "L") + , ((modm .|. shiftMask .|. controlMask, xK_l), resize M.! "R") + , ((modm .|. shiftMask .|. controlMask, xK_j), resize M.! "D") + , ((modm .|. shiftMask .|. controlMask, xK_k), resize M.! "U") + + , ((modm .|. controlMask, xK_space), switchLayer) + + , ((modm .|. shiftMask, xK_c ), kill1) + , ((modm, xK_space ), sendMessage NextLayout) + , ((modm .|. shiftMask, xK_space ), setLayout $ layoutHook conf) + , ((modm, xK_x ), sendMessage $ Toggle REFLECTX) + , ((modm, xK_y ), sendMessage $ Toggle REFLECTY) + , ((modm, xK_z ), withFocused minimizeWindow) + , ((modm .|. shiftMask, xK_z ), unminimize) + , ((modm, xK_m ), toggleMax) + + , ((modm, xK_t ), withFocused $ windows . sink) + , ((modm .|. shiftMask, xK_t ), untile) + + , ((modm, xK_comma ), sendMessage (IncMasterN 1)) + , ((modm, xK_period), sendMessage (IncMasterN (-1))) + , ((modm, xK_g ), toggleSpacing) + , ((modm, xK_b ), sendMessage ToggleStruts) + + , ((modm, xK_Right ), moveTo Next spacesOnCurrentScreen) + , ((modm, xK_Left ), moveTo Prev spacesOnCurrentScreen) + , ((modm .|. shiftMask, xK_Right ), shiftTo Next spacesOnCurrentScreen) + , ((modm .|. shiftMask, xK_Left ), shiftTo Prev spacesOnCurrentScreen) + + , ((modm, xK_0), toggleWS' ["NSP"]) + ] + + where + toggleSpacing = toggleWindowSpacingEnabled >> toggleScreenSpacingEnabled + toggleMax = withFocused (sendMessage . maximizeRestore) + unminimize = withLastMinimized maximizeWindowAndFocus + + untile = withFocused rectFloatFocused + where + rectFloatFocused focused = action focused >>= windows + action = fmap appEndo . doIt + doIt = runQuery $ doRectFloat rect + rect = RationalRect 0.05 0.05 0.9 0.9 + + floatResize = M.fromList + [ ("L", (-n, 0)) + , ("R", (n, 0)) + , ("D", (0, n)) + , ("U", (0, -n)) + ] + tillingResize = M.fromList + [ ("L", sendMessage Shrink) + , ("R", sendMessage Expand) + , ("D", sendMessage MirrorShrink) + , ("U", sendMessage MirrorExpand) + ] + tillingMove = M.fromList + [ ("L", L) + , ("R", R) + , ("D", D) + , ("U", U) + ] + incDec = M.fromList + [ ("+", (n,n)) + , ("-", (-n,-n)) + ] + n = 10 + + resize = M.union lrdu chSize + where + flt = fmap (\x -> keysResizeWindow x (0,0)) floatResize + lrdu = M.intersectionWith onFloat flt tillingResize + chSize = fmap (g . f) incDec + where + f x = keysResizeWindow x (1%2,1%2) + g x = onFloat x $ return () + + move = M.intersectionWith onFloat flt tilling + where + flt = fmap keysMoveWindow floatResize + tilling = fmap (`windowSwap` False) tillingMove + + onFloat a b = withFocused $ ifFloat a (const b) + where + ifFloat x y w = isFloat w >>= picker x y w + + picker x _ w True = x w + picker _ y w False = y w + + isFloat :: Window -> X Bool + isFloat w = M.member w . floating <$> gets windowset + +spacesOnCurrentScreen :: WSType +spacesOnCurrentScreen = WSIs $ isOnScreen <$> currentScreen + where + + isOnScreen :: ScreenId -> WindowSpace -> Bool + isOnScreen s = (s ==) . unmarshallS . tag + + currentScreen :: X ScreenId + currentScreen = gets $ screen . current . windowset + +workspaceBinds :: XConfig Layout -> M.Map (ButtonMask, KeySym) (X ()) +workspaceBinds conf@ XConfig {modMask = modm} = M.fromList $ + [((m .|. modm, k), windows $ onCurrentScreen f i) + | (i, k) <- zip (workspaces' conf) [xK_1 .. xK_9] + , (f, m) <- [(greedyView, 0), (shift, shiftMask)]] + +screenBinds :: XConfig Layout -> M.Map (ButtonMask, KeySym) (X ()) +screenBinds XConfig {modMask = modm} = M.fromList $ + [((m .|. modm, k), screenWorkspace i >>= flip whenJust (windows . f)) + | (i, k) <- zip [0,1] [xK_w, xK_e] + , (f, m) <- [(view, 0), (shift, shiftMask)]] diff --git a/home/desktop-xmonad/xmonad/lib/DefaultConfig.hs b/home/desktop-xmonad/xmonad/lib/DefaultConfig.hs new file mode 100644 index 0000000..37d98b6 --- /dev/null +++ b/home/desktop-xmonad/xmonad/lib/DefaultConfig.hs @@ -0,0 +1,85 @@ +module DefaultConfig + ( mkPP + , wsNamer + , defaultPP + ) where + +import MyConfig + ( workspaceLog + , layoutLog + , taskbar + ) + +import Theme + ( inactiveColor + , urgentColor + , selFg + , selectionColor + ) + +import GHC.IO.Handle.Types (Handle) + +import XMonad.Hooks.DynamicLog + ( ppCurrent + , ppOutput + , ppExtras + , ppVisible + , ppHidden + , ppHiddenNoWindows + , ppUrgent + , ppOrder + , ppTitle + , ppSep + , ppLayout + , PP + , xmobarColor + , wrap + , shorten + ) + +import XMonad.Config (def) + +import XMonad.Util.Run (hPutStrLn) + + +mkPP :: (String -> String) -> Bool -> Handle -> Int -> PP +mkPP workspaceNamer complete bar screen = common + { ppOutput = hPutStrLn bar + , ppExtras = extras complete + } + where + common = def + { ppCurrent = const "" + , ppVisible = const "" + , ppHidden = const "" + , ppHiddenNoWindows = const "" + , ppUrgent = xmobarColor urgentColor "" + , ppOrder = order complete + , ppTitle = title complete + , ppSep = xmobarColor inactiveColor "" "|" + , ppLayout = const "" + } + + extras True = + [ workspaceLog workspaceNamer screen + , layoutLog screen + , taskbar screen + ] + extras False = + [ workspaceLog workspaceNamer screen + , layoutLog screen + ] + + order True (_:_:_:xs) = xs + order False (_:_:t:ws:l:_) = [ws, l, t] + order _ _ = [] + + title True = const "" + title False = wrap " " "" . xmobarColor selFg selectionColor . wrap " " " " . shorten 80 + +wsNamer :: String -> String +wsNamer "NSP" = "" +wsNamer x = x + +defaultPP :: Handle -> Int -> PP +defaultPP = mkPP wsNamer True diff --git a/home/desktop-xmonad/xmonad/lib/Layouts.hs b/home/desktop-xmonad/xmonad/lib/Layouts.hs new file mode 100644 index 0000000..5aae708 --- /dev/null +++ b/home/desktop-xmonad/xmonad/lib/Layouts.hs @@ -0,0 +1,124 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# OPTIONS_GHC -fno-warn-missing-signatures #-} + +module Layouts (myLayoutHook) where + +import Text.Printf (printf) + +import XMonad.Config (def) +import XMonad.Core ( LayoutClass ) +import XMonad.Hooks.ManageDocks (avoidStruts) + +import XMonad.Layout ( Mirror (Mirror) , (|||) ) +import XMonad.Layout.PerWorkspace ( onWorkspaces ) +import XMonad.Layout.LayoutModifier ( ModifiedLayout , LayoutModifier ) +import XMonad.Layout.BoringWindows ( boringWindows ) +import XMonad.Layout.Decoration ( Theme , DefaultShrinker , Decoration ) +import XMonad.Layout.Maximize ( maximizeWithPadding ) +import XMonad.Layout.Minimize ( minimize ) +import XMonad.Layout.MultiToggle ( mkToggle , single ) +import XMonad.Layout.Renamed ( renamed, Rename (Replace) ) +import XMonad.Layout.NoBorders ( smartBorders ) +import XMonad.Layout.ResizableTile ( ResizableTall (..) ) +import XMonad.Layout.Spacing ( Spacing , spacingRaw , Border (..) ) +import XMonad.Layout.WindowNavigation ( windowNavigation ) +import XMonad.Layout.SubLayouts ( subLayout , Sublayout ) +import XMonad.Layout.Simplest ( Simplest(Simplest) ) +import XMonad.Layout.Grid ( Grid(Grid) ) +import XMonad.Layout.Reflect + ( REFLECTX (REFLECTX) + , REFLECTY (REFLECTY) + ) +import XMonad.Layout.Tabbed + ( shrinkText + , addTabs + , TabbedDecoration + ) +import qualified XMonad.Layout.Tabbed as T + ( activeColor + , inactiveColor + , activeBorderColor + , inactiveBorderColor + , urgentColor + , activeTextColor + , inactiveTextColor + , urgentTextColor + , fontName + ) + +import XMonad.Layout.PositionStoreFloat (positionStoreFloat) +import XMonad.Layout.NoFrillsDecoration (noFrillsDeco) +import XMonad.Layout.BorderResize (borderResize) + +import HostConfig + ( FontConfig + , fontName + , fontSize + , ColorConfig + , fgColor + , selFgColor + , bgColor + , selColor + , inactiveColor + , inactiveBorderColor + , urgentColor + , colorConfig + , fontConfig + ) + +named :: String -> l a -> ModifiedLayout Rename l a +named x = renamed [Replace x] + +myLayoutHook = commonMods mainLayouts + where + tileMods = mkToggle (single REFLECTX) . mkToggle (single REFLECTY) + . smartBorders + . windowNavigation . mySubTabbed theme + . spaces + commonMods = avoidStruts + . maximizeWithPadding 0 + . minimize + . boringWindows + tLayouts = tileMods $ named "tall" tall ||| named "mtall" mtall + mainLayouts = tLayouts ||| floating theme + +floating theme = named "float" . floatingDeco . borderResize $ positionStoreFloat + where + floatingDeco = noFrillsDeco shrinkText theme + +mySubTabbed + :: (Eq a, LayoutModifier (Sublayout Simplest) a, LayoutClass l a) + => Theme + -> l a + -> ModifiedLayout + (Decoration TabbedDecoration DefaultShrinker) + (ModifiedLayout (Sublayout Simplest) l) + a +mySubTabbed theme x = addTabs shrinkText theme $ subLayout [] Simplest x + +spaces :: l a -> ModifiedLayout Spacing l a +spaces = spacingRaw False b False b False + where + b = Border defSpacing defSpacing defSpacing defSpacing + defSpacing = 5 + +tall :: ResizableTall a +tall = ResizableTall 1 (3/100) (1/2) [] + +mtall :: Mirror ResizableTall a +mtall = Mirror tall + +theme :: Theme +theme = def + { T.activeColor = selColor colorConfig + , T.activeBorderColor = inactiveColor colorConfig + , T.activeTextColor = selFgColor colorConfig + + , T.inactiveColor = bgColor colorConfig + , T.inactiveBorderColor = inactiveBorderColor colorConfig + , T.inactiveTextColor = fgColor colorConfig + + , T.urgentColor = urgentColor colorConfig + , T.urgentTextColor = urgentColor colorConfig + , T.fontName = printf "xft:%s:size=%d" (fontName fontConfig) (fontSize fontConfig) + } diff --git a/home/desktop-xmonad/xmonad/lib/ManageHook.hs b/home/desktop-xmonad/xmonad/lib/ManageHook.hs new file mode 100644 index 0000000..a19aff2 --- /dev/null +++ b/home/desktop-xmonad/xmonad/lib/ManageHook.hs @@ -0,0 +1,135 @@ + module ManageHook + ( myManageHook + , scratchpadKeybinds + ) where + +import Text.Printf (printf) +import qualified Data.Map as M + +import XMonad.Core + ( ManageHook + , X + , XConfig(XConfig) + , modMask + , Layout + ) + +import XMonad.StackSet (RationalRect (RationalRect)) +import XMonad.Hooks.ManageHelpers (isFullscreen, doFullFloat) + +import Graphics.X11.Types + ( KeySym , ButtonMask + , xK_s , xK_t , xK_m + , xK_Return + ) + +import XMonad.ManageHook + ( className + , (=?) + , resource + , composeAll + , (-->) + , doFloat + , doShift + , stringProperty + ) + +import XMonad.Util.NamedScratchpad + ( NamedScratchpad (NS) + , customFloating + , namedScratchpadManageHook + , namedScratchpadAction + ) + +import Utils ( mkSubmap ) + +scratchpadKeybinds :: XConfig Layout -> M.Map (ButtonMask, KeySym) (X ()) +scratchpadKeybinds XConfig {modMask = modm} = M.fromList + [ ((modm, xK_s), mkSubmap modm . map buildSubmap $ + [ (xK_Return, "scratchpad") + , (xK_m, "mixer") + -- , (xK_p, "player") + , (xK_t, "top") + -- , (xK_w, "whatsapp") + -- , (xK_g, "hangouts") + ]) + ] + where + buildSubmap (key,name) = ((0,key), namedScratchpadAction myScratchpads name) + +myScratchpads :: [NamedScratchpad] +myScratchpads = + [ termApp "scratchpad" "zsh" mngTopScratch + , termApp "top" "top" mngBigFloat + --, termApp "player" "ncmpcpp" mngBiggerFloat + + --, NS "mixer" "pavucontrol" (className =? "Pavucontrol") mngSmallerFloat + + -- , chromiumApp "whatsapp" "web.whatsapp.com" mngSmallFloat + -- , chromiumApp "hangouts" "hangouts.google.com" mngSmallFloat + ] + +myManageHook :: ManageHook +myManageHook = mkManageHook myScratchpads + +termApp :: String -> String -> ManageHook -> NamedScratchpad +termApp name app = NS name cmd findIt + where + cmd = printf fmt name name app + fmt = "alacritty --class %s --command tmux new -A -s %s %s" + findIt = resource =? name + +--chromiumApp :: String -> String -> ManageHook -> NamedScratchpad +--chromiumApp name url = NS name cmd findIt +-- where +-- cmd = printf "chromium --app=https://%s" url +-- findIt = resource =? url + +--mngSmallerFloat :: ManageHook +--mngSmallerFloat = centeredFloat 0.6 + +--mngSmallFloat :: ManageHook +--mngSmallFloat = centeredFloat 0.7 + +mngBigFloat :: ManageHook +mngBigFloat = centeredFloat 0.8 + +--mngBiggerFloat :: ManageHook +--mngBiggerFloat = centeredFloat 0.9 + +centeredFloat :: Rational -> ManageHook +centeredFloat s = customFloating $ RationalRect p p s s + where + p = (1-s) / 2 + +mngTopScratch :: ManageHook +mngTopScratch = customFloating $ RationalRect l t w h + where + h = 0.3 -- height, 30% + w = 1 -- width, 100% + t = 0 -- distance from top edge, 0% + l = 1 - w -- distance from left edge, 0% + +mkManageHook :: [NamedScratchpad] -> ManageHook +mkManageHook scratchpads = composeAll + [ isFullscreen --> doFullFloat + , className =? "MPlayer" --> doFloat + , className =? "VirtualBox" --> doFloat + , className =? "Pinentry" --> doFloat + , className =? "qjackctl" --> doFloat + , className =? "Xmessage" --> doFloat + , className =? "SuperCollider" --> doFloat + , role =? "gimp-dock" --> doFloat + , role =? "GtkFileChooserDialog" --> doFloat + + --, className =? "Signal" --> doShift "msg" + --, className =? "Slack" --> doShift "msg" + --, className =? "Element" --> doShift "msg" + --, className =? "TelegramDesktop" --> doShift "msg" + --, resource =? "hangouts.google.com" --> doShift "msg" + --, resource =? "web.whatsapp.com" --> doShift "msg" + + , namedScratchpadManageHook scratchpads + ] + where + role = stringProperty "WM_WINDOW_ROLE" diff --git a/home/desktop-xmonad/xmonad/lib/Polybar.hs b/home/desktop-xmonad/xmonad/lib/Polybar.hs new file mode 100644 index 0000000..3b1e6ad --- /dev/null +++ b/home/desktop-xmonad/xmonad/lib/Polybar.hs @@ -0,0 +1,60 @@ +module Polybar (polybarLogHook, mkDbusClient) where + +import XMonad.Hooks.DynamicLog + +import Text.Printf (printf) + +import XMonad.Layout.IndependentScreens (marshallPP) + +import qualified DBus as D +import qualified DBus.Client as D +import qualified Codec.Binary.UTF8.String as UTF8 + + +mkDbusClient :: IO D.Client +mkDbusClient = do + dbus <- D.connectSession + D.requestName dbus (D.busName_ "org.xmonad.log") opts + return dbus + where + opts = [D.nameAllowReplacement, D.nameReplaceExisting, D.nameDoNotQueue] + +monitorMsg :: Int -> String -> String +monitorMsg = printf "{\"%d\": \"%s\"}" + +-- Emit a DBus signal on log updates +dbusOutput :: D.Client -> String -> IO () +dbusOutput dbus str = + let opath = D.objectPath_ "/org/xmonad/Log" + iname = D.interfaceName_ "org.xmonad.Log" + mname = D.memberName_ "Update" + signal = D.signal opath iname mname + body = [D.toVariant $ UTF8.decodeString $ monitorMsg 0 str] + in D.emit dbus $ signal { D.signalBody = body } + +polybarFmt :: String -> String -> String -> String +polybarFmt var color elem = "%{" ++ var ++ color ++ "}" ++ elem ++ "%{" ++ var ++ "-}" + +polybarFg :: String -> String -> String +polybarFg = polybarFmt "F" + +polybarBg :: String -> String -> String +polybarBg = polybarFmt "B" + +polybarBgFg :: String -> String -> String -> String +polybarBgFg bg fg = polybarBg bg . polybarFg fg + +polybarHook :: D.Client -> PP +polybarHook dbus = def + { ppOutput = dbusOutput dbus + , ppCurrent = polybarBgFg "#458588" "#fbf1c7" + , ppVisible = polybarFg "#ebdbb2" + , ppUrgent = polybarBgFg "#cc241d" "#fbf1c7" + , ppHidden = polybarFg "#ebdbb2" + , ppLayout = const "" + , ppHiddenNoWindows = const "" + , ppTitle = shorten 100 . polybarFg "#fbf1c7" + , ppSep = polybarFg "#a89974" " | " + } + +polybarLogHook dbus = dynamicLogWithPP $ (marshallPP 0 . polybarHook) dbus diff --git a/home/desktop-xmonad/xmonad/lib/Prompts.hs b/home/desktop-xmonad/xmonad/lib/Prompts.hs new file mode 100644 index 0000000..dcebaf4 --- /dev/null +++ b/home/desktop-xmonad/xmonad/lib/Prompts.hs @@ -0,0 +1,92 @@ +module Prompts ( promptKeybinds ) where + +import Text.Printf (printf) +import qualified Data.Map as M ( Map , fromList ) + +import Graphics.X11.Types + ( KeySym , ButtonMask + , xK_Tab + , xK_a , xK_b , xK_c , xK_p , xK_r , xK_s , xK_u , xK_t + ) +import Graphics.X11.ExtraTypes.XF86 ( xF86XK_Launch1 ) + +import XMonad.Core ( X , modMask , XConfig(XConfig) , Layout ) +import XMonad.Util.Run ( safeSpawn ) + +import qualified XMonad.Prompt as P + ( XPConfig + , def + , font + , bgColor + , fgColor + , bgHLight + , fgHLight + , bgColor + , borderColor + , promptBorderWidth + , alwaysHighlight + , defaultPrompter + ) + +import HostConfig + ( ColorConfig + , FontConfig + , fontConfig + , colorConfig + , fontName + , fontSize + , bgColor + , fgColor + , selColor + , selFgColor + ) + +import Utils ( mkSubmap ) + +promptKeybinds :: XConfig Layout -> M.Map (ButtonMask, KeySym) (X ()) +promptKeybinds XConfig {modMask = modm} = M.fromList + [ ((0, xF86XK_Launch1), run) + , ((modm, xK_r), run) + , ((modm, xK_a) , subMapMaker + [ ( xK_r , drun ) + , ( xK_p , pass ) + , ( xK_Tab , window ) + , ( xK_t , todo ) + , ( xK_c , clipmenu ) + , ( xK_b , buku ) + , ( xK_s , ssh ) + ]) + ] + where + run = safeSpawn "rofi" ["-show", "run"] + drun = safeSpawn "rofi" ["-show", "drun"] + pass = safeSpawn "rofi-pass" [] + buku = safeSpawn "rofi-buku" [] + ssh = safeSpawn "rofi" ["-show", "ssh"] + window = safeSpawn "rofi" ["-show", "window"] + clipmenu = safeSpawn "clipmenu" dmenuArgs + todo = safeSpawn "todo-rofi" [] + subMapMaker = mkSubmap modm . map (\(key,action) -> ((0,key),action)) + +dmenuArgs :: [String] +dmenuArgs = + [ "-b" -- bottom + , "-fn", printf "%s:size=%d" (fontName fontConfig) (fontSize fontConfig) + , "-nb", bgColor colorConfig -- normal background + , "-nf", fgColor colorConfig -- normal foreground + , "-sb", selColor colorConfig -- selected background + , "-sf", selFgColor colorConfig -- selected foreground + ] + +theme :: P.XPConfig +theme = P.def + { P.font = printf "xft:%s:size=%d" (fontName fontConfig) (fontSize fontConfig) + , P.bgColor = bgColor colorConfig + , P.fgColor = fgColor colorConfig + , P.bgHLight = selColor colorConfig + , P.fgHLight = selFgColor colorConfig + , P.borderColor = bgColor colorConfig + , P.promptBorderWidth = 0 + , P.alwaysHighlight = True + , P.defaultPrompter = const "" + } diff --git a/home/desktop-xmonad/xmonad/lib/Utils.hs b/home/desktop-xmonad/xmonad/lib/Utils.hs new file mode 100644 index 0000000..20c1376 --- /dev/null +++ b/home/desktop-xmonad/xmonad/lib/Utils.hs @@ -0,0 +1,15 @@ +module Utils ( mkSubmap ) where + +import qualified Data.Map as M ( fromList ) + +import XMonad ( (.|.) ) +import Graphics.X11.Types ( KeyMask , KeySym , ButtonMask ) + +import XMonad.Core ( X ) +import XMonad.Actions.Submap ( submap ) + +mkSubmap :: ButtonMask -> [((KeyMask, KeySym), X ())] -> X () +mkSubmap modm = submap . M.fromList . concatMap buildSubmaps + where + buildSubmaps x = map (buildSubmap x) [0,modm] + buildSubmap ((modKey,key),action) m = ((modKey .|. m,key),action) diff --git a/home/desktop-xmonad/xmonad/lib/Xmobar.hs b/home/desktop-xmonad/xmonad/lib/Xmobar.hs new file mode 100644 index 0000000..55856c1 --- /dev/null +++ b/home/desktop-xmonad/xmonad/lib/Xmobar.hs @@ -0,0 +1,119 @@ +module Xmobar (mkBars) where + +import XMonad.Layout.IndependentScreens (marshallPP) + +import GHC.IO.Handle.Types (Handle) +import Text.Printf (printf) + +import Data.List (intercalate, isPrefixOf) +import Graphics.X11.Types (Window) + +import XMonad.Core + ( Layout + , ScreenDetail + , ScreenId (S) + , withWindowSet + , WorkspaceId + , WindowSet + , description + , X + ) + +import XMonad (MonadIO) +import XMonad.Config (def) +import XMonad.Util.Run (hPutStrLn, spawnPipe) +import XMonad.Util.NamedWindows (getName) +import XMonad.Util.Loggers (Logger) + +import XMonad.StackSet ( Workspace (..) , screen , workspace , current ) +import qualified XMonad.StackSet as S + +import XMonad.Hooks.DynamicLog + ( PP + , ppCurrent + , ppExtras + , ppHidden + , ppHiddenNoWindows + , ppLayout + , ppOrder + , ppOutput + , ppSep + , ppTitle + , ppUrgent + , ppVisible + , shorten + , wrap + , xmobarAction + , xmobarColor + , dynamicLogWithPP + ) + +import HostConfig + ( colorConfig + , fontConfig + , FontConfig + , fontName + , fontSize + + , ColorConfig + , bgColor + , fgColor + , selFgColor + , selColor + , inactiveColor + , urgentColor + ) + +mkBars :: MonadIO m => [Int] -> m (X ()) +mkBars screens = do + xmprocs <- mkXmprocs screens + return $ mapM_ dynamicLogWithPP $ zipWith mkPP xmprocs screens + +mkXmprocs :: MonadIO m => [Int] -> m [Handle] +mkXmprocs = mapM (spawnPipe . printf "xmobar --screen='%d'") + +mkPP :: Handle -> Int -> PP +mkPP bar nscreen = marshallPP (S nscreen) $ def + { ppOutput = hPutStrLn bar + , ppCurrent = xmobarColor (selFgColor colorConfig) (selColor colorConfig) + , ppVisible = xmobarColor (fgColor colorConfig) "" + , ppHidden = xmobarColor (fgColor colorConfig) "" + , ppHiddenNoWindows = const "" + , ppUrgent = xmobarColor (urgentColor colorConfig) "" + , ppLayout = getLayoutIcon . layoutNameCleaner + , ppTitle = xmobarColor (selFgColor colorConfig) "" . shorten 100 + , ppSep = xmobarColor (inactiveColor colorConfig) "" " | " + } + +layoutNameCleaner = unwords . filter (not . (`elem` toClean)) . words + where + toClean = + [ "Simple" + , "Simplest" + , "Minimize" + , "Maximize" + , "ImageButtonDeco" + , "DefaultDecoration" + , "Spacing" + , "ReflectX" + , "ReflectY" + , "Tabbed" + , "0" + ] + +getLayoutIcon :: String -> String +getLayoutIcon "empty" = "" +getLayoutIcon x + | x `elem` icons = printf "" iconsDir x + | otherwise = x + where + iconsDir = "/home/rilla/.xmonad/icons" + icons = + [ "3cols" + , "float" + , "full" + , "grid" + , "mtall" + , "tabs" + , "tall" + ] diff --git a/home/desktop-xmonad/xmonad/xmonad.hs b/home/desktop-xmonad/xmonad/xmonad.hs new file mode 100644 index 0000000..9c7b93b --- /dev/null +++ b/home/desktop-xmonad/xmonad/xmonad.hs @@ -0,0 +1,92 @@ +import XMonad ( xmonad ) +import XMonad.Core + ( ScreenId (S) + , terminal + , modMask + , borderWidth + , normalBorderColor + , focusedBorderColor + , workspaces + , keys + , mouseBindings + , layoutHook + , manageHook + , XConfig + ( logHook + , focusFollowsMouse + , startupHook + , handleEventHook + ) + ) +import XMonad.Config ( def ) + +import XMonad.Hooks.ServerMode ( serverModeEventHook ) +import XMonad.Hooks.EwmhDesktops ( ewmh ) +import XMonad.Hooks.ManageDocks ( docks ) +import XMonad.Hooks.SetWMName ( setWMName ) + +import XMonad.Layout.IndependentScreens ( countScreens , withScreens ) +import XMonad.Util.Replace ( replace ) + +import XMonad.Actions.UpdatePointer ( updatePointer ) +import XMonad.Actions.Navigation2D + ( withNavigation2DConfig + , Navigation2DConfig + , centerNavigation + , singleWindowRect + , defaultTiledNavigation + , layoutNavigation + , unmappedWindowRect + ) + +import Graphics.X11.Types ( mod4Mask ) + +import HostConfig + ( colorConfig + , selColor + , inactiveBorderColor + ) +import ManageHook ( myManageHook ) +import Xmobar ( mkBars ) +import Bindings ( keybinds, mousebinds ) +import Layouts ( myLayoutHook ) + +main :: IO () +main = do + replace + nscreens <- countScreens + let + myScreens = [0 .. nscreens-1] + wsLs = withScreens (S nscreens) myWorkspaces + bars <- mkBars myScreens + xmonad $ opts def + { terminal = "alacritty" + , modMask = mod4Mask + , borderWidth = 4 + , normalBorderColor = inactiveBorderColor colorConfig + , focusedBorderColor = selColor colorConfig + , workspaces = wsLs + , keys = keybinds + , mouseBindings = mousebinds + , layoutHook = myLayoutHook + , manageHook = myManageHook + , logHook = bars >> updatePtr + , focusFollowsMouse = True + , handleEventHook = serverModeEventHook + , startupHook = setWMName "LG3D" + } + where + opts = docks . ewmh . withNavigation2DConfig myNav2DConf + updatePtr = updatePointer (0.9, 0.9) (0, 0) + +myNav2DConf :: Navigation2DConfig +myNav2DConf = def + { defaultTiledNavigation = centerNavigation + , layoutNavigation = [("Full", centerNavigation)] + , unmappedWindowRect = [("Full", singleWindowRect)] + } + +myWorkspaces :: [String] +myWorkspaces = map show ids + where ids :: [Int] + ids = [1..9] diff --git a/home/fonts/default.nix b/home/fonts/default.nix new file mode 100644 index 0000000..57c8468 --- /dev/null +++ b/home/fonts/default.nix @@ -0,0 +1,18 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + (nerdfonts.override { + fonts = [ + "Hack" # my default monospace font + "MPlus" # to display symbols on xmobar + "InconsolataGo" # sometimes I use it as a change from Hack + "CascadiaCode" # used by rofi; todo: set fontconfig to use MPlus instead + ]; + }) + inter # Inter is my default sans-serif font + hack-font # Hack is my default monospace font + libertinus # Libertinus Serif is my default serif font + ]; + #fonts.fontconfig.enable = true; +} diff --git a/home/git/common.nix b/home/git/common.nix new file mode 100644 index 0000000..4da4824 --- /dev/null +++ b/home/git/common.nix @@ -0,0 +1,26 @@ +{ config, pkgs, ... }: + +{ + home.packages = [ pkgs.diff-so-fancy pkgs.tig ]; + + programs.git = { + enable = true; + userName = "Ricard Illa"; + signing = { + key = "0x8333CFB0B9D3244D"; + signByDefault = true; + }; + # delta = maybe? + extraConfig = { + core = { + editor = "${pkgs.neovim}/bin/nvim"; + pager = + "${pkgs.diff-so-fancy}/bin/diff-so-fancy | ${pkgs.less}/bin/less --tabs=4 -RFX"; + }; + color.ui = true; + pull.rebase = false; + init.defaultBranch = "master"; + diff-so-fancy.stripLeadingSymbols = false; + }; + }; +} diff --git a/home/git/default.nix b/home/git/default.nix new file mode 100644 index 0000000..2244fe4 --- /dev/null +++ b/home/git/default.nix @@ -0,0 +1,6 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + programs.git.userEmail = "rilla@monotremata.xyz"; +} diff --git a/home/git/macos.nix b/home/git/macos.nix new file mode 100644 index 0000000..8c60803 --- /dev/null +++ b/home/git/macos.nix @@ -0,0 +1,6 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + programs.git.userEmail = "ricard@trkkn.com"; +} diff --git a/home/gotify/default.nix b/home/gotify/default.nix new file mode 100644 index 0000000..58190b3 --- /dev/null +++ b/home/gotify/default.nix @@ -0,0 +1,49 @@ +{ config, pkgs, ... }: + +let + server_url = "gotify.monotremata.xyz"; + server_port = "443"; + client_token = "CToaKlqyMrBKJcp"; + app_token = "AsMyhbR5h5ZlNXb"; + default_priority = "5"; +in +{ + home.packages = [ + pkgs.gotify-desktop + pkgs.gotify-cli + ]; + + home.file.".config/gotify-desktop/config.toml".text = '' + [gotify] + url = "wss://${server_url}:${server_port}" + token = "${client_token}" + auto_delete = true + + [notification] + min_priority = 1 + ''; + + home.file.".config/gotify/cli.json".text = '' + { + "token": "${app_token}", + "url": "https://${server_url}", + "defaultPriority": ${default_priority} + } + ''; + + systemd.user.services.gotify = { + Unit = { + Description = "Gotify desktop"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + Service = { + Type = "simple"; + ExecStart = "${pkgs.gotify-desktop}/bin/gotify-desktop"; + }; + Install = { + WantedBy = [ "graphical-session.target" ]; + }; + }; + +} diff --git a/home/gpg/default.nix b/home/gpg/default.nix new file mode 100644 index 0000000..c520278 --- /dev/null +++ b/home/gpg/default.nix @@ -0,0 +1,34 @@ +{ config, pkgs, ... }: + +{ + programs.gpg = { + enable = true; + settings = { + personal-cipher-preferences = "AES256 AES192 AES"; + personal-digest-preferences = "SHA512 SHA384 SHA256"; + personal-compress-preferences = "ZLIB BZIP2 ZIP Uncompressed"; + default-preference-list = "SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed"; + cert-digest-algo = "SHA512"; + s2k-digest-algo = "SHA512"; + s2k-cipher-algo = "AES256"; + charset = "utf-8"; + fixed-list-mode = true; + no-comments = true; + no-emit-version = true; + keyid-format = "0xlong"; + list-options = "show-uid-validity"; + verify-options = "show-uid-validity"; + with-fingerprint = true; + require-cross-certification = true; + use-agent = true; + }; + }; + services.gpg-agent = { + enable = true; + enableSshSupport = true; + pinentryFlavor = "gtk2"; + defaultCacheTtl = 60; + maxCacheTtl = 120; + # extraConfig = "log-file ${config.home.homeDirectory}/gpg-agent.log"; + }; +} diff --git a/home/gpg/macos.nix b/home/gpg/macos.nix new file mode 100644 index 0000000..e7cbdc3 --- /dev/null +++ b/home/gpg/macos.nix @@ -0,0 +1,43 @@ +{ config, pkgs, ... }: + +let + pinentry = + "${pkgs.pinentry_mac}/Applications/pinentry-mac.app/Contents/MacOS/pinentry-mac"; + +in { + home.packages = [ pkgs.gnupg pkgs.pinentry_mac ]; + + home.file.".gnupg/gpg-agent.conf".text = '' + enable-ssh-support + default-cache-ttl 60 + max-cache-ttl 120 + display :0 + pinentry-program ${pinentry} + log-file ${config.home.homeDirectory}/.local/var/log/gpg-agent.log + ''; + + home.file.".gnupg/gpg.conf".text = '' + personal-cipher-preferences AES256 AES192 AES + personal-digest-preferences SHA512 SHA384 SHA256 + personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed + default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed + cert-digest-algo SHA512 + s2k-digest-algo SHA512 + s2k-cipher-algo AES256 + charset utf-8 + fixed-list-mode + no-comments + no-emit-version + keyid-format 0xlong + list-options show-uid-validity + verify-options show-uid-validity + with-fingerprint + require-cross-certification + use-agent + ''; + + home.file.".gnupg/scdaemon.conf".text = '' + disable-ccid + reader-port "Yubico YubiKey OTP+FIDO+CCID" + ''; +} diff --git a/home/idasen/default.nix b/home/idasen/default.nix new file mode 100644 index 0000000..d62def7 --- /dev/null +++ b/home/idasen/default.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +{ + home = { + packages = [pkgs.idasen]; + file.".config/idasen/idasen.yaml".text = pkgs.lib.generators.toYAML {} { + mac_address = "F8:3E:14:A6:42:DB"; + positions = { + sit = 0.684; + stand = 1.068; + }; + }; + }; +} diff --git a/home/macos.nix b/home/macos.nix new file mode 100644 index 0000000..6d2b62d --- /dev/null +++ b/home/macos.nix @@ -0,0 +1,22 @@ +{ config, pkgs, ... }: + +{ + home.username = "rilla"; + home.homeDirectory = "/Users/rilla"; + + imports = [ + ./alacritty/macos.nix + ./dav/macos.nix + ./git/macos.nix + ./gpg/macos.nix + ./mail/macos.nix + ./mpd/macos.nix + ./neovim/macos.nix + ./pass/macos.nix + ./rss # done + ./ssh # done + ./tmux # done + ./vitetris/macos.nix + ./zsh/macos.nix + ]; +} diff --git a/home/mail/common.nix b/home/mail/common.nix new file mode 100644 index 0000000..a751791 --- /dev/null +++ b/home/mail/common.nix @@ -0,0 +1,535 @@ +{ config, pkgs, ... }: + +let + gpgKey = "B51D4548A4846E3C8D115C808333CFB0B9D3244D"; + + personalSignature = '' + Ricard Illa + https://monotremata.xyz + http://zswm576cm7wgmgcwluy4l4ixkfasj25taqbn2r5pnrrj552l263ff2qd.onion + public key fingerprint: B51D4548A4846E3C8D115C808333CFB0B9D3244D + ''; + + workSignature = '' + Ricard Illa + Data Engineer + + Trakken GmbH + - Sucursal en España + Carrer de Sardenya 229 + 08013 Barcelona + + + E-mail:ricard@trkkn.com + Web:www.trkkn.com + + ___________________________________________________________ + + HRB 104862, Amtsgericht Hamburg + Managing Directors: Timo Aden, Lennart Paulsen + ___________________________________________________________ + ''; + + accountSignature = { showSignature ? "append", text ? "" }: { + showSignature = showSignature; + text = text; + }; + + pwCmd = x: "${pkgs.pass}/bin/pass ${x}"; + + defaultAccountSettings = { accountEmail + , mailboxes ? ''"=Inbox" "=Archive" "=Drafts" "=Junk" "=Sent" "=Trash"'' + , smtpHost ? "mail.monotremata.xyz", imapHost ? "mail.monotremata.xyz" }: { + primary = false; + realName = "Ricard Illa"; + + aliases = [ accountEmail ]; + address = accountEmail; + userName = accountEmail; + neomutt = { + enable = true; + extraConfig = '' + unmailboxes * + mailboxes ${mailboxes} + set status_format = "[ ${accountEmail} ] [ %f ] [%r%m messages%?n? (%n new)?%?d? (%d to delete)?%?t? (%t tagged)? ]%>─%?p?( %p postponed )?" + ''; + sendMailCommand = "msmtp -a ${accountEmail}"; + }; + signature = accountSignature { text = personalSignature; }; + mbsync = { + enable = true; + create = "both"; + expunge = "both"; + flatten = "."; + patterns = [ "*" ]; + remove = "both"; + }; + gpg = { + encryptByDefault = false; + signByDefault = true; + key = gpgKey; + }; + msmtp.enable = true; + + smtp = { + host = smtpHost; + tls = { + enable = true; + useStartTls = true; + }; + port = 587; + }; + + imap = { + host = imapHost; + tls.enable = true; + port = 993; + }; + }; + + switchAccountMacro = i: x: { + map = [ "index" "pager" ]; + key = "i${i}"; + action = + "source ${config.xdg.configHome}/neomutt/${x}!"; + }; + +in { + accounts.email.accounts = { + + "rilla@monotremata.xyz" = + defaultAccountSettings { accountEmail = "rilla@monotremata.xyz"; } // { + primary = true; + passwordCommand = pwCmd "mail.monotremata.xyz/rilla@monotremata.xyz"; + }; + + "r.illa.pujagut@gmail.com" = defaultAccountSettings { + accountEmail = "r.illa.pujagut@gmail.com"; + mailboxes = '' + "=INBOX" "=[Gmail].Drafts" "=[Gmail].Sent Mail" "=[Gmail].Trash" "=[Gmail].Spam" "=[Gmail].All Mail"''; + smtpHost = "smtp.gmail.com"; + imapHost = "imap.gmail.com"; + } // { + passwordCommand = pwCmd "google.com/mutt/r.illa.pujagut@gmail.com"; + }; + + "ricard@trkkn.com" = defaultAccountSettings { + accountEmail = "ricard@trkkn.com"; + mailboxes = '' + "=INBOX" "=[Gmail].Drafts" "=[Gmail].Sent Mail" "=[Gmail].Trash" "=[Gmail].Spam" "=[Gmail].All Mail"''; + smtpHost = "smtp.gmail.com"; + imapHost = "imap.gmail.com"; + } // { + signature = accountSignature { text = workSignature; }; + aliases = [ "ricard@trkkn.com" "ricard@trakken.es" ]; + passwordCommand = pwCmd "trakken/google.com/mutt/ricard@trkkn.com"; + }; + + "accounts@monotremata.xyz" = + defaultAccountSettings { accountEmail = "accounts@monotremata.xyz"; } // { + realName = "monotremata.xyz"; + signature = accountSignature { showSignature = "none"; }; + passwordCommand = pwCmd "mail.monotremata.xyz/accounts@monotremata.xyz"; + }; + + "admin@monotremata.xyz" = + defaultAccountSettings { accountEmail = "admin@monotremata.xyz"; } // { + aliases = [ + "admin@monotremata.xyz" + "postmaster@monotremata.xyz" + "hostmaster@monotremata.xyz" + "webmaster@monotremata.xyz" + "abuse@monotremata.xyz" + ]; + realName = "monotremata.xyz"; + signature = accountSignature { text = "admin@monotremata.xyz"; }; + passwordCommand = pwCmd "mail.monotremata.xyz/admin@monotremata.xyz"; + }; + }; + + programs.neomutt = { + enable = true; + editor = "nvim"; + sort = "threads"; + # vimKeys = true; + sidebar = { + enable = true; + shortPath = true; + width = 20; + format = "%D%?F? [%F]?%* %?N?%N/? %?S?%S?"; + }; + extraConfig = '' + alternative_order text/html text/plain text/enriched text/* + auto_view text/html application/gpg-encrypted text/calendar application/ics + + # Default index colors: + color index yellow default '.*' + color index_author red default '.*' + color index_number blue default + color index_subject cyan default '.*' + + # New mail is boldened: + color index brightyellow black "~N" + color index_author brightred black "~N" + color index_subject brightcyan black "~N" + + # Tagged mail is highlighted: + color index brightyellow blue "~T" + color index_author brightred blue "~T" + color index_subject brightcyan blue "~T" + + # Other colors and aesthetic settings: + mono bold bold + mono underline underline + mono indicator reverse + mono error bold + color normal default default + color indicator brightblack white + color sidebar_highlight red default + color sidebar_divider brightblack black + color sidebar_flagged red black + color sidebar_new green black + color normal brightyellow default + color error red default + color tilde black default + color message cyan default + color markers red white + color attachment white default + color search brightmagenta default + color status brightyellow black + color hdrdefault brightgreen default + color quoted green default + color quoted1 blue default + color quoted2 cyan default + color quoted3 yellow default + color quoted4 red default + color quoted5 brightred default + color signature brightgreen default + color bold black default + color underline black default + color normal default default + + # Regex highlighting: + color header blue default ".*" + color header brightmagenta default "^(From)" + color header brightcyan default "^(Subject)" + color header brightwhite default "^(CC|BCC)" + color body brightred default "[\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+" # Email addresses + color body brightblue default "(https?|ftp)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+" # URL + color body green default "\`[^\`]*\`" # Green text between ` and ` + color body brightblue default "^# \.*" # Headings as bold blue + color body brightcyan default "^## \.*" # Subheadings as bold cyan + color body brightgreen default "^### \.*" # Subsubheadings as bold green + color body yellow default "^(\t| )*(-|\\*) \.*" # List items as yellow + color body brightcyan default "[;:][-o][)/(|]" # emoticons + color body brightcyan default "[;:][)(|]" # emoticons + color body brightcyan default "[ ][*][^*]*[*][ ]?" # more emoticon? + color body brightcyan default "[ ]?[*][^*]*[*][ ]" # more emoticon? + color body red default "(BAD signature)" + color body cyan default "(Good signature)" + color body brightblack default "^gpg: Good signature .*" + color body brightyellow default "^gpg: " + color body brightyellow red "^gpg: BAD signature from.*" + mono body bold "^gpg: Good signature" + mono body bold "^gpg: BAD signature from.*" + color body red default "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]" + + set fast_reply # skip to compose when replying + set fcc_attach # save attachments with the body + set forward_quote # include message in forwards + set reverse_name # reply as whomever it was to + set include # include message in replies + set uncollapse_jump + set sort_re + set quit + set beep_new + ''; + settings = { + # set mailcap_path = /usr/local/share/mutt-wizard/mailcap:$mailcap_path # todo + mime_type_query_command = ''"${pkgs.file}/bin/file --mime-type -b %s"''; + date_format = ''"%d.%m.%Y %H:%M"''; + index_format = ''"%2C %Z %?X?A& ? %D %-15.15F %s (%-4.4c)"''; + rfc2047_parameters = "yes"; + sleep_time = "0"; # Pause 0 seconds for informational messages + markers = "no"; # Disables the `+` displayed at line wraps + mark_old = "no"; # Unread mail stay unread until read + mime_forward = "yes"; # attachments are forwarded with mail + wait_key = "no"; # mutt won't ask "press key to continue" + forward_format = ''"Fwd: %s"''; # format of subject when forwarding + status_chars = ''" *%A"''; + sort_aux = "reverse-last-date-received"; + reply_regexp = ''"^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*"''; + quote_regexp = ''"^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+"''; + send_charset = "utf-8:iso-8859-1:us-ascii"; + charset = "utf-8"; + arrow_cursor = "no"; # Change `color indicator` depending + }; + binds = [ + { + map = [ "index" ]; + key = "h"; + action = "noop"; + } + { + map = [ "index" ]; + key = "\\Cf"; + action = "noop"; + } + { + map = [ "pager" ]; + key = "r"; + action = "noop"; + } + { + map = [ "editor" ]; + key = ""; + action = "noop"; + } + { + map = [ "index" "pager" ]; + key = "i"; + action = "noop"; + } + { + map = [ "index" "pager" ]; + key = "g"; + action = "noop"; + } + + # general rebindings + { + map = [ "index" ]; + key = "j"; + action = "next-entry"; + } + { + map = [ "index" ]; + key = "k"; + action = "previous-entry"; + } + { + map = [ "index" ]; + key = "G"; + action = "last-entry"; + } + { + map = [ "index" ]; + key = "gg"; + action = "first-entry"; + } + { + map = [ "index" ]; + key = "D"; + action = "delete-message"; + } + { + map = [ "index" ]; + key = "U"; + action = "undelete-message"; + } + { + map = [ "index" ]; + key = "L"; + action = "limit"; + } + { + map = [ "index" ]; + key = "l"; + action = "display-message"; + } + { + map = [ "index" ]; + key = "\\031"; + action = "previous-undeleted"; + } # Mouse wheel + { + map = [ "index" ]; + key = "\\005"; + action = "next-undeleted"; + } # Mouse wheel + { + map = [ "attach" ]; + key = ""; + action = "view-mailcap"; + } + { + map = [ "attach" ]; + key = "l"; + action = "view-mailcap"; + } + { + map = [ "pager" ]; + key = "j"; + action = "next-line"; + } + { + map = [ "pager" ]; + key = "k"; + action = "previous-line"; + } + { + map = [ "pager" ]; + key = "l"; + action = "view-attachments"; + } + { + map = [ "pager" ]; + key = "\\031"; + action = "previous-line"; + } # Mouse wheel + { + map = [ "pager" ]; + key = "\\005"; + action = "next-line"; + } # Mouse wheel + { + map = [ "editor" ]; + key = ""; + action = "complete-query"; + } + { + map = [ "browser" ]; + key = "l"; + action = "select-entry"; + } + { + map = [ "index" "pager" ]; + key = "H"; + action = "view-raw-message"; + } + { + map = [ "index" "pager" ]; + key = "S"; + action = "sync-mailbox"; + } + { + map = [ "index" "pager" ]; + key = "R"; + action = "group-reply"; + } + { + map = [ "index" "pager" ]; + key = "rg"; + action = "group-reply"; + } + { + map = [ "index" "pager" ]; + key = "rr"; + action = "reply"; + } + { + map = [ "index" "query" ]; + key = ""; + action = "tag-entry"; + } + { + map = [ "pager" "browser" ]; + key = "gg"; + action = "top-page"; + } + { + map = [ "pager" "browser" ]; + key = "G"; + action = "bottom-page"; + } + { + map = [ "pager" "attach" ]; + key = "h"; + action = "exit"; + } + { + map = [ "index" "pager" "browser" ]; + key = "d"; + action = "half-down"; + } + { + map = [ "index" "pager" "browser" ]; + key = "u"; + action = "half-up"; + } + + # sidebar mappings + { + map = [ "index" "pager" ]; + key = "\\Ck"; + action = "sidebar-prev"; + } + { + map = [ "index" "pager" ]; + key = "\\Cj"; + action = "sidebar-next"; + } + { + map = [ "index" "pager" ]; + key = "\\Co"; + action = "sidebar-open"; + } + { + map = [ "index" "pager" ]; + key = "\\Cp"; + action = "sidebar-prev-new"; + } + { + map = [ "index" "pager" ]; + key = "\\Cn"; + action = "sidebar-next-new"; + } + { + map = [ "index" "pager" ]; + key = "B"; + action = "sidebar-toggle-visible"; + } + ]; + + macros = [ + { + map = [ "browser" ]; + key = "h"; + action = ".."; + } # go to parent folder + { + map = [ "index" ]; + key = "\\Cr"; + action = "T~UN."; + } # mark all messages as read + { + map = [ "index" ]; + key = "A"; + action = "all\\n"; + } # show all messages (undo limit) + + { + map = [ "index" "pager" ]; + key = "\\cb"; + action = " ${pkgs.urlscan}/bin/urlscan"; + } # call urlscan to extract URLs out of a message" + { + map = [ "attach" "compose" ]; + key = "\\cb"; + action = " ${pkgs.urlscan}/bin/urlscan"; + } # call urlscan to extract URLs out of a message + { + map = [ "index" "pager" ]; + key = "A"; + action = "${pkgs.khard}/bin/khard add-email"; + } # add the sender email address to khard + + ] ++ [ + (switchAccountMacro "1" "rilla@monotremata.xyz") + (switchAccountMacro "2" "r.illa.pujagut@gmail.com") + (switchAccountMacro "3" "ricard@trkkn.com") + (switchAccountMacro "4" "accounts@monotremata.xyz") + (switchAccountMacro "5" "admin@monotremata.xyz") + ]; + }; + + #programs.notmuch = { + # enable = true; + # new = { + # tags = ["unread" "inbox"]; + # }; + #}; + + programs.mbsync.enable = true; + programs.msmtp.enable = true; +} diff --git a/home/mail/default.nix b/home/mail/default.nix new file mode 100644 index 0000000..c1a0458 --- /dev/null +++ b/home/mail/default.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +let mailsync = pkgs.callPackage ./mailsync.nix { inherit config pkgs; }; +in { + imports = [ ./common.nix ]; + home.packages = [ mailsync pkgs.urlscan pkgs.abook ]; + programs.neomutt.settings.query_command = + ''"${pkgs.abook}/bin/abook --mutt-query '%s'"''; + programs.alot.enable = true; +} diff --git a/home/mail/macos.nix b/home/mail/macos.nix new file mode 100644 index 0000000..58fe9b7 --- /dev/null +++ b/home/mail/macos.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +let mailsync = pkgs.callPackage ./mailsync_macos.nix { inherit config pkgs; }; +in { + imports = [ ./common.nix ]; + home.packages = [ mailsync pkgs.urlscan ]; + programs.alot.enable = false; +} diff --git a/home/mail/mailsync.nix b/home/mail/mailsync.nix new file mode 100644 index 0000000..1710be1 --- /dev/null +++ b/home/mail/mailsync.nix @@ -0,0 +1,132 @@ +{ config, pkgs, ... }: + +let + shell = "${pkgs.dash}/bin/dash"; + pidof = "${pkgs.procps}/bin/pidof"; + pgrep = "${pkgs.procps}/bin/pgrep"; + grep = "${pkgs.gnugrep}/bin/grep"; + sed = "${pkgs.gnused}/bin/sed"; + awk = "${pkgs.gawk}/bin/awk"; + perl = "${pkgs.perl}/bin/perl"; + find = "${pkgs.findutils}/bin/find"; + notifySend = "${pkgs.libnotify}/bin/notify-send"; + notmuch = "${pkgs.notmuch}/bin/notmuch"; + head = "${pkgs.coreutils}/bin/head"; + touch = "${pkgs.coreutils}/bin/touch"; + tr = "${pkgs.coreutils}/bin/tr"; + + mbsyncrc = "${config.home.homeDirectory}/.mbsyncrc"; + mbsync = "${pkgs.isync}/bin/mbsync -c ${mbsyncrc}"; + + maildir = "${config.home.homeDirectory}/Maildir"; + passwordStoreDir = "${config.home.homeDirectory}/.password-store"; + notmuchConfig = "${config.home.homeDirectory}/.notmuch-config"; + gnupghome = "${config.home.homeDirectory}/.gnupg"; + lastrun = "${config.home.homeDirectory}/.mailsynclastrun"; +in + pkgs.writeScriptBin "mailsync" '' + #!${shell} + + # Run only if not already running in other instance + ${pidof} mbsync >/dev/null && { + echo "mbsync is already running." + exit + } + + export PASSWORD_STORE_DIR="${passwordStoreDir}" + export NOTMUCH_CONFIG="${notmuchConfig}" + export GNUPGHOME="${gnupghome}" + export GPG_TTY=$TTY + + notify() { + pgrepoutput="$(${pgrep} -a X\(org\|wayland\))" + displays="$(echo "$pgrepoutput" | ${grep} -wo "[0-9]*:[0-9]\+" | sort -u)" + [ -n "$pgrepoutput" ] && for x in ''${displays:-0:}; do + export DISPLAY=$x + ${notifySend} \ + --app-name="email" \ + "email" \ + "📬 $2 new mail(s) in \`$1\` account." + done + } + + messageinfo() { + from="$1" + subject="$2" + pgrepoutput="$(${pgrep} -a X\(org\|wayland\))" + displays="$(echo "$pgrepoutput" | ${grep} -wo "[0-9]*:[0-9]\+" | sort -u)" + [ -n "$pgrepoutput" ] && for x in ''${displays:-0:}; do + export DISPLAY=$x + ${notifySend} \ + --app-name="email" \ + "📧$from:" \ + "$subject" + done + } + + # Check account for new mail. Notify if there is new content. + syncandnotify() { + accounts="$1" + acc="$(echo "$account" | ${sed} "s/.*\///")" + if [ -z "$opts" ]; then + ${mbsync} "$acc" + else + ${mbsync} "$opts" "$acc" + fi + new=$( + ${find} \ + "${maildir}/$acc/INBOX/new/" \ + "${maildir}/$acc/Inbox/new/" \ + "${maildir}/mail/$acc/inbox/new/" \ + -type f \ + -newer "${lastrun}" \ + 2> /dev/null + ) + newcount=$(echo "$new" | ${sed} '/^\s*$/d' | wc -l) + if [ "$newcount" -gt 5 ]; then + notify "$acc" "$newcount" + elif [ "$newcount" -gt 0 ]; then + for file in $new; do + # Extract subject and sender from mail. + from=$( + ${awk} '/^From: / && ++n ==1,/^\<.*\>:/' "$file" | \ + ${perl} -CS -MEncode -ne 'print decode("MIME-Header", $_)' | \ + ${awk} '{ $1=""; if (NF>=3)$NF=""; print $0 }' | \ + ${sed} 's/^[[:blank:]]*[\"'\''\'''\'\<]*//;s/[\"'\''\'''\'\>]*[[:blank:]]*$//' + ) + subject=$( + ${awk} '/^Subject: / && ++n == 1,/^\<.*\>: / && ++i == 2' "$file" | \ + ${head} -n 1 | ${perl} -CS -MEncode -ne 'print decode("MIME-Header", $_)' | \ + ${sed} 's/^Subject: //' | \ + ${sed} 's/^{[[:blank:]]*[\"'\''\'''\'\<]*//;s/[\"'\''\'''\'\>]*[[:blank:]]*$//' | \ + ${tr} -d '\n' + ) + messageinfo "$from" "$subject" & + done + fi + } + + # Sync accounts passed as argument or all. + if [ "$#" -eq "0" ]; then + accounts="$(${awk} '/^Channel/ {print $2}' "${mbsyncrc}")" + else + for arg in "$@"; do + [ "''${arg%''${arg#?}}" = '-' ] && \ + opts="''${opts:+''${opts} }''${arg}" && \ + shift 1 + done + accounts=$* + fi + + # Parallelize multiple accounts + for account in $accounts; do + syncandnotify "''${account}" & + done + + wait + + ${notmuch} new 2>/dev/null + + #Create a touch file that indicates the time of the last run of mailsync + ${touch} "${lastrun}" + '' diff --git a/home/mail/mailsync_macos.nix b/home/mail/mailsync_macos.nix new file mode 100644 index 0000000..1710be1 --- /dev/null +++ b/home/mail/mailsync_macos.nix @@ -0,0 +1,132 @@ +{ config, pkgs, ... }: + +let + shell = "${pkgs.dash}/bin/dash"; + pidof = "${pkgs.procps}/bin/pidof"; + pgrep = "${pkgs.procps}/bin/pgrep"; + grep = "${pkgs.gnugrep}/bin/grep"; + sed = "${pkgs.gnused}/bin/sed"; + awk = "${pkgs.gawk}/bin/awk"; + perl = "${pkgs.perl}/bin/perl"; + find = "${pkgs.findutils}/bin/find"; + notifySend = "${pkgs.libnotify}/bin/notify-send"; + notmuch = "${pkgs.notmuch}/bin/notmuch"; + head = "${pkgs.coreutils}/bin/head"; + touch = "${pkgs.coreutils}/bin/touch"; + tr = "${pkgs.coreutils}/bin/tr"; + + mbsyncrc = "${config.home.homeDirectory}/.mbsyncrc"; + mbsync = "${pkgs.isync}/bin/mbsync -c ${mbsyncrc}"; + + maildir = "${config.home.homeDirectory}/Maildir"; + passwordStoreDir = "${config.home.homeDirectory}/.password-store"; + notmuchConfig = "${config.home.homeDirectory}/.notmuch-config"; + gnupghome = "${config.home.homeDirectory}/.gnupg"; + lastrun = "${config.home.homeDirectory}/.mailsynclastrun"; +in + pkgs.writeScriptBin "mailsync" '' + #!${shell} + + # Run only if not already running in other instance + ${pidof} mbsync >/dev/null && { + echo "mbsync is already running." + exit + } + + export PASSWORD_STORE_DIR="${passwordStoreDir}" + export NOTMUCH_CONFIG="${notmuchConfig}" + export GNUPGHOME="${gnupghome}" + export GPG_TTY=$TTY + + notify() { + pgrepoutput="$(${pgrep} -a X\(org\|wayland\))" + displays="$(echo "$pgrepoutput" | ${grep} -wo "[0-9]*:[0-9]\+" | sort -u)" + [ -n "$pgrepoutput" ] && for x in ''${displays:-0:}; do + export DISPLAY=$x + ${notifySend} \ + --app-name="email" \ + "email" \ + "📬 $2 new mail(s) in \`$1\` account." + done + } + + messageinfo() { + from="$1" + subject="$2" + pgrepoutput="$(${pgrep} -a X\(org\|wayland\))" + displays="$(echo "$pgrepoutput" | ${grep} -wo "[0-9]*:[0-9]\+" | sort -u)" + [ -n "$pgrepoutput" ] && for x in ''${displays:-0:}; do + export DISPLAY=$x + ${notifySend} \ + --app-name="email" \ + "📧$from:" \ + "$subject" + done + } + + # Check account for new mail. Notify if there is new content. + syncandnotify() { + accounts="$1" + acc="$(echo "$account" | ${sed} "s/.*\///")" + if [ -z "$opts" ]; then + ${mbsync} "$acc" + else + ${mbsync} "$opts" "$acc" + fi + new=$( + ${find} \ + "${maildir}/$acc/INBOX/new/" \ + "${maildir}/$acc/Inbox/new/" \ + "${maildir}/mail/$acc/inbox/new/" \ + -type f \ + -newer "${lastrun}" \ + 2> /dev/null + ) + newcount=$(echo "$new" | ${sed} '/^\s*$/d' | wc -l) + if [ "$newcount" -gt 5 ]; then + notify "$acc" "$newcount" + elif [ "$newcount" -gt 0 ]; then + for file in $new; do + # Extract subject and sender from mail. + from=$( + ${awk} '/^From: / && ++n ==1,/^\<.*\>:/' "$file" | \ + ${perl} -CS -MEncode -ne 'print decode("MIME-Header", $_)' | \ + ${awk} '{ $1=""; if (NF>=3)$NF=""; print $0 }' | \ + ${sed} 's/^[[:blank:]]*[\"'\''\'''\'\<]*//;s/[\"'\''\'''\'\>]*[[:blank:]]*$//' + ) + subject=$( + ${awk} '/^Subject: / && ++n == 1,/^\<.*\>: / && ++i == 2' "$file" | \ + ${head} -n 1 | ${perl} -CS -MEncode -ne 'print decode("MIME-Header", $_)' | \ + ${sed} 's/^Subject: //' | \ + ${sed} 's/^{[[:blank:]]*[\"'\''\'''\'\<]*//;s/[\"'\''\'''\'\>]*[[:blank:]]*$//' | \ + ${tr} -d '\n' + ) + messageinfo "$from" "$subject" & + done + fi + } + + # Sync accounts passed as argument or all. + if [ "$#" -eq "0" ]; then + accounts="$(${awk} '/^Channel/ {print $2}' "${mbsyncrc}")" + else + for arg in "$@"; do + [ "''${arg%''${arg#?}}" = '-' ] && \ + opts="''${opts:+''${opts} }''${arg}" && \ + shift 1 + done + accounts=$* + fi + + # Parallelize multiple accounts + for account in $accounts; do + syncandnotify "''${account}" & + done + + wait + + ${notmuch} new 2>/dev/null + + #Create a touch file that indicates the time of the last run of mailsync + ${touch} "${lastrun}" + '' diff --git a/home/minidisc/atracdenc.nix b/home/minidisc/atracdenc.nix new file mode 100644 index 0000000..c544642 --- /dev/null +++ b/home/minidisc/atracdenc.nix @@ -0,0 +1,37 @@ +{ + pkgs ? import {}, + stdenv ? pkgs.stdenv, +}: + +stdenv.mkDerivation rec { + pname = "atracdenc"; + version = "0.1.0"; + + src = pkgs.fetchFromGitHub { + owner = "dcherednik"; + repo = "atracdenc"; + rev = "62ced878b526d49e5ef6ad42ca2eb7efc874867a"; + sha256 = "1azjs0sbd5yc505ky2rf7l9m0lci6fkixazd85rdb8n678da5dfz"; + }; + + buildInputs = [ + pkgs.gnumake + pkgs.cmake + pkgs.libsndfile + ]; + + configurePhase = '' + mkdir src/build + cd src/build + cmake ../ + ''; + + buildPhase = '' + make + ''; + + installPhase = '' + mkdir -p $out/bin + mv atracdenc $out/bin + ''; +} diff --git a/home/minidisc/default.nix b/home/minidisc/default.nix new file mode 100644 index 0000000..16f7ba4 --- /dev/null +++ b/home/minidisc/default.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +let + atracdenc = pkgs.callPackage ./atracdenc.nix {}; + linux-minidisc = pkgs.libsForQt5.callPackage ./linux-minidisc.nix {}; +in + { + home.packages = [ + pkgs.ffmpeg + atracdenc + linux-minidisc + ]; + } diff --git a/home/minidisc/linux-minidisc.nix b/home/minidisc/linux-minidisc.nix new file mode 100644 index 0000000..b32c118 --- /dev/null +++ b/home/minidisc/linux-minidisc.nix @@ -0,0 +1,41 @@ +{ pkgs, stdenv, lib, qtbase, wrapQtAppsHook }: + +stdenv.mkDerivation rec { + pname = "linux-minidisc"; + version = "0.1.0"; + + src = pkgs.fetchFromGitHub { + owner = "linux-minidisc"; + repo = "linux-minidisc"; + rev = "0aa2c4eeb2c3f136f1cd039e2818837812cf8891"; + sha256 = "140hvg55hdwp5j3qcrsazy4vf29qb3k4lnkm453bmykspn8ylbv2"; + }; + + nativeBuildInputs = [ wrapQtAppsHook ]; + + buildInputs = [ + pkgs.glib + pkgs.libgcrypt + pkgs.libid3tag + pkgs.libmad + pkgs.libsForQt5.full + pkgs.libusb1 + pkgs.pkg-config + pkgs.taglib + ]; + + configurePhase = '' + qmake + ''; + + buildPhase = '' + make + ''; + + installPhase = '' + mkdir -p "$out/bin" + mv netmdcli/netmdcli "$out/bin" + mv himdcli/himdcli "$out/bin" + mv qhimdtransfer/qhimdtransfer "$out/bin" + ''; +} diff --git a/home/mpd/common.nix b/home/mpd/common.nix new file mode 100644 index 0000000..3065b44 --- /dev/null +++ b/home/mpd/common.nix @@ -0,0 +1,77 @@ +{ config, pkgs, ... }: + +{ + home.packages = [ pkgs.mpc_cli ]; + + programs.ncmpcpp = { + enable = true; + package = pkgs.ncmpcpp.override { visualizerSupport = true; }; + bindings = [ + { key = "+"; command = "show_clock"; } + { key = "="; command = "volume_up"; } + { key = "j"; command = "scroll_down"; } + { key = "k"; command = "scroll_up"; } + { key = "h"; command = "previous_column"; } + { key = "l"; command = "next_column"; } + { key = "."; command = "show_lyrics"; } + { key = "n"; command = "next_found_item"; } + { key = "N"; command = "previous_found_item"; } + { key = "J"; command = "move_sort_order_down"; } + { key = "K"; command = "move_sort_order_up"; } + { key = "ctrl-u"; command = "page_up"; } + { key = "ctrl-d"; command = "page_down"; } + ]; + mpdMusicDir = "${config.home.homeDirectory}/music"; + settings = { + autocenter_mode = "yes"; + follow_now_playing_lyrics = "yes"; + ignore_leading_the = "yes"; + ignore_diacritics = "yes"; + default_place_to_search_in = "database"; + + user_interface = "alternative"; + alternative_header_first_line_format = "$0$aqqu$/a {$6%a$9 - }{$3%t$9}|{$3%f$9} $0$atqq$/a$9"; + alternative_header_second_line_format = "{{$4%b$9}{ [$8%y$9]}}|{$4%D$9}"; + + song_status_format = " $6%a $7| $3%t $7| $4%b "; + + colors_enabled = "yes"; + main_window_color = "white"; + header_window_color = "cyan"; + volume_color = "green"; + statusbar_color = "white"; + progressbar_color = "cyan"; + progressbar_elapsed_color = "white"; + + playlist_editor_display_mode = "columns"; + search_engine_display_mode = "columns"; + browser_display_mode = "columns"; + playlist_display_mode = "columns"; + + song_columns_list_format = "(10)[blue]{l} (30)[green]{t} (30)[magenta]{a} (30)[yellow]{b}"; + song_list_format = "{$7%a - $9}{$5%t$9}|{$5%f$9}$R{$6%b $9}{$3%l$9}"; + + progressbar_look = "═❯─"; + + current_item_prefix = "$(blue)$r"; + current_item_suffix = "$/r$(end)"; + current_item_inactive_column_prefix = "$(cyan)$r"; + + now_playing_prefix = "❯ "; + centered_cursor = "yes"; + + selected_item_prefix = "* "; + discard_colors_if_item_is_selected = "yes"; + + display_bitrate = "yes"; + enable_window_title = "yes"; + empty_tag_marker = ""; + + visualizer_data_source = "/tmp/mpd.fifo"; + visualizer_output_name = "my_fifo"; + visualizer_type = "spectrum"; + visualizer_in_stereo = "yes"; + visualizer_look = "◆▋"; + }; + }; +} diff --git a/home/mpd/default.nix b/home/mpd/default.nix new file mode 100644 index 0000000..b7d740f --- /dev/null +++ b/home/mpd/default.nix @@ -0,0 +1,26 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + home.packages = [ pkgs.mpc_cli ]; + services.mpd = { + enable = true; + musicDirectory = "${config.home.homeDirectory}/music"; + network = { + listenAddress = "any"; + port = 6600; + }; + extraConfig = '' + audio_output { + type "pipewire" + name "pipewire audio" + } + audio_output { + type "fifo" + name "my_fifo" + path "/tmp/mpd.fifo" + format "44100:16:2" + } + ''; + }; +} diff --git a/home/mpd/macos.nix b/home/mpd/macos.nix new file mode 100644 index 0000000..acf98c5 --- /dev/null +++ b/home/mpd/macos.nix @@ -0,0 +1,47 @@ +{ config, pkgs, ... }: + +let + musicDir = "${config.home.homeDirectory}/shared/music"; + mpdDir = "${config.home.homeDirectory}/.mpd"; +in { + imports = [ ./common.nix ]; + home.packages = [ pkgs.mpc_cli ]; + home.file.".mpd/mpd.conf".text = '' + music_directory "${musicDir}" + playlist_directory "${mpdDir}/playlists" + db_file "${mpdDir}/mpd.db" + log_file "${mpdDir}/mpd.log" + pid_file "${mpdDir}/mpd.pid" + state_file "${mpdDir}/mpdstate" + auto_update "yes" + auto_update_depth "2" + follow_outside_symlinks "yes" + follow_inside_symlinks "yes" + + audio_output { + type "osx" + name "CoreAudio" + mixer_type "software" + } + + decoder { + plugin "mp4ff" + enabled "no" + } + + bind_to_address "0.0.0.0" + port "6600" + user "rilla" + + # Visualizer + audio_output { + type "fifo" + name "my_fifo" + path "/tmp/mpd.fifo" + format "44100:16:2" + auto_resample "no" + use_mmap "yes" + } + ''; + +} diff --git a/home/msg/default.nix b/home/msg/default.nix new file mode 100644 index 0000000..de8c75d --- /dev/null +++ b/home/msg/default.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + + +{ + home.packages = [ + pkgs.dino + pkgs.element-desktop + pkgs.ferdi + pkgs.profanity + pkgs.signal-desktop + pkgs.tdesktop + pkgs.whatsapp-for-linux + ]; + home.file.".local/share/applications/userapp-Telegram Desktop.desktop".text = + '' + [Desktop Entry] + Encoding=UTF-8 + Version=1.0 + Type=Application + NoDisplay=true + Exec=${pkgs.tdesktop}/bin/bin/.telegram-desktop-wrapped -workdir ${config.home.homeDirectory}/.local/share/TelegramDesktop/ -- %u + Name=Telegram Desktop + Comment=Custom definition for Telegram Desktop + ''; +} diff --git a/home/music/default.nix b/home/music/default.nix new file mode 100644 index 0000000..fe045f4 --- /dev/null +++ b/home/music/default.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + home.packages = [ + pkgs.ardour + pkgs.hydrogen + pkgs.lmms + pkgs.tenacity + ]; +} diff --git a/home/neovim/common.nix b/home/neovim/common.nix new file mode 100644 index 0000000..d6908db --- /dev/null +++ b/home/neovim/common.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ black jq sqlfluff nixfmt shfmt ]; + programs.neovim = { + enable = true; + viAlias = true; + vimAlias = true; + vimdiffAlias = true; + withPython3 = true; + }; +} diff --git a/home/neovim/default.nix b/home/neovim/default.nix new file mode 100644 index 0000000..1946955 --- /dev/null +++ b/home/neovim/default.nix @@ -0,0 +1,135 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + programs.neovim = { + plugins = with pkgs.vimPlugins; + # find sha256 with: + # nix-prefetch-url --unpack https://github.com/${owner}/${repo}/archive/${rev}.tar.gz + let + nerdfont-vim = pkgs.vimUtils.buildVimPlugin { + pname = "nerdfont-vim"; + version = "git"; + src = pkgs.fetchFromGitHub { + owner = "lambdalisue"; + repo = "nerdfont.vim"; + rev = "5f484cf638ca31fc9db95b33b92bf5aa4b2d1270"; + sha256 = "01lfqlsbs1192v0kydz98qypbvl6h3vkjjj5cl6zcadq52macl5s"; + }; + meta.homepage = "https://github.com/lambdalisue/nerdfont.vim"; + }; + fern-renderer-nerdfont = pkgs.vimUtils.buildVimPlugin { + pname = "fern-renderer-nerdfont"; + version = "git"; + src = pkgs.fetchFromGitHub { + owner = "lambdalisue"; + repo = "fern-renderer-nerdfont.vim"; + rev = "942be10bda577ba4840c4a939200f05024b8603c"; + sha256 = "0nz5ycs9r9w0in3jjmcm121ik3jggj4mj3r88fmk8bw1jwl1hffm"; + }; + meta.homepage = + "https://github.com/lambdalisue/fern-renderer-nerdfont.vim"; + }; + glyph-palette = pkgs.vimUtils.buildVimPlugin { + pname = "glyph-palette"; + version = "git"; + src = pkgs.fetchFromGitHub { + owner = "lambdalisue"; + repo = "glyph-palette.vim"; + rev = "a8ecb59733d8b4a2f45fdbcabf5174fdee18c4ec"; + sha256 = "0pzlwiyvrp994f5d9sw2vymdi1s5x7ywvwm0n4vmv3i9q9yyhxja"; + }; + meta.homepage = + "https://github.com/lambdalisue/fern-renderer-nerdfont.vim"; + }; + fern-git-status = pkgs.vimUtils.buildVimPlugin { + pname = "fern-git-status"; + version = "git"; + src = pkgs.fetchFromGitHub { + owner = "lambdalisue"; + repo = "fern-git-status.vim"; + rev = "151336335d3b6975153dad77e60049ca7111da8e"; + sha256 = "1iqd035psn953v162didqd72cb7f0n7w34c2qsf15qkyq3y97pzl"; + }; + meta.homepage = "https://github.com/lambdalisue/fern-git-status.vim"; + }; + fern-mapping-git = pkgs.vimUtils.buildVimPlugin { + pname = "fern-mapping-git"; + version = "git"; + src = pkgs.fetchFromGitHub { + owner = "lambdalisue"; + repo = "fern-mapping-git.vim"; + rev = "df5e7466df8596c95dd355d49a72893018919cf1"; + sha256 = "1lhppbydg9wlc520042k6bqvwblvmr7xx0w44s2xwbwbffj6hjz3"; + }; + meta.homepage = "https://github.com/lambdalisue/fern-mapping-git.vim"; + }; + fern-hijack = pkgs.vimUtils.buildVimPlugin { + pname = "fern-hijack"; + version = "git"; + src = pkgs.fetchFromGitHub { + owner = "lambdalisue"; + repo = "fern-hijack.vim"; + rev = "24daa61d69b878947946e84a7711f8b58eae0f50"; + sha256 = "1z8zracqk52rar6wra7n1hlvfa1xqks1x0np7rs1aq9g7d02d6wg"; + }; + meta.homepage = "https://github.com/lambdalisue/fern-hijack.vim"; + }; + black-vim = pkgs.vimUtils.buildVimPlugin { + pname = "black-vim"; + version = "git"; + src = pkgs.fetchFromGitHub { + owner = "psf"; + repo = "black"; + rev = "f1d4e742c91dd5179d742b0db9293c4472b765f8"; + sha256 = "124a76cpl3xx9v2kbcprsajr149f93nib4hgacqii798m3mzm1x9"; + }; + meta.homepage = "https://github.com/psf/black"; + }; + + in [ # nix-env -f '' -qaP -A vimPlugins + gitgutter + fugitive + vim-markdown + sensible + vim-unimpaired + vim-css-color + easymotion + vim-slime + rainbow + vim-jinja + gruvbox-community + deoplete-nvim + nerdcommenter + goyo + limelight-vim + fzf-vim + todo-txt-vim + airline + vim-airline-themes + vimwiki + vim-ledger + fern-vim + FixCursorHold-nvim + indentLine + tmux-navigator + neomake + ale + neoformat + vim-smoothie + ultisnips + vim-snippets + vim-nix + vim-terraform + + nerdfont-vim + fern-renderer-nerdfont + glyph-palette + fern-git-status + fern-mapping-git + fern-hijack + black-vim + ]; + extraConfig = builtins.readFile ./init.vim; + }; +} diff --git a/home/neovim/init.vim b/home/neovim/init.vim new file mode 100644 index 0000000..3b722e7 --- /dev/null +++ b/home/neovim/init.vim @@ -0,0 +1,230 @@ +set nowrap +set nocompatible +syntax enable +filetype plugin on +set number +set mouse=a " mouse support +set showcmd " show incomplete cmds down the bottom +set showmode " show current mode +set visualbell " no sounds +set autoread " reload files changed outside vim +"set gcr=a:blinkon0 " disable cursor blink +set backspace=indent,eol,start " allow backspacing over everything in insert +mode +set shiftround " use multiple of shiftwidth when indenting with '<' and '>' +set showmatch " set show matching parenthesis +set ignorecase " ignore case when searching +set smartcase " ignore case if search pattern is all lowercase, case-sensitive otherwise +set smarttab " insert tabs on the start of a line according to shiftwidth, not tabstop +set hlsearch " highlight search terms +set incsearch " show search matches as you type +set hidden +set ruler +set clipboard=unnamed " system clipboard +set list listchars=tab:\ \ ,trail:· " display tabs and trailing spaces visually +set colorcolumn=80 + +set splitbelow +set splitright +nmap r + +let mapleader="," +let maplocalleader="\\" + +" use alt-x to go to a specific tab +nnoremap 1gt +nnoremap 2gt +nnoremap 3gt +nnoremap 4gt +nnoremap 5gt +nnoremap 6gt +nnoremap 7gt +nnoremap 8gt +nnoremap :tablast + +" clean highlights when C-l +nnoremap :nohl + +" HIGHLIGHT LINE WHEN IN INSERT MODE +hi CursorLine cterm=NONE,underline ctermbg=NONE +set timeoutlen=1000 ttimeoutlen=0 " eliminate annoying delay +autocmd InsertEnter * :set cursorline +autocmd InsertLeave * :set nocursorline + +" INDENTATION: +filetype indent on +set softtabstop=4 +set expandtab +set shiftwidth=4 " number of spaces to use for autoindenting +set tabstop=4 " a tab is four spaces +set autoindent " always set autoindenting on +set copyindent " copy the previous indentation on autoindenting + +" TAG JUMPING: +command! MakeTags !ctags -R . +" - ^] to jump to tag under cursor +" - g^] for ambiguous tags +" - ^t to jump back up the tag stack + +" TURN OF SWAP FILES: +set noswapfile +set nobackup +set nowb + +"FOLDS: +set foldmethod=indent " fold based on indent +set foldnestmax=3 " deepest fold is 3 levels +set nofoldenable " don't fold by default + +" FINDING FILES: +set path+=** +set wildmenu +" - Hit tab to find for partial match +" - Use * to make it fuzzy + +let g:markdown_syntax_conceal = 0 + +set updatetime=100 " reduce vim update time so magke gitgutter more responsive + +set termguicolors + +"set fillchars+=vert:\ " cleaner vertical line + +"let g:gruvbox_contrast_dark="hard" +"let g:gruvbox_contrast_light="hard" +"let g:gruvbox_italic=1 +"let g:gruvbox_invert_indent_guides=1 +"let g:gruvbox_vert_split='bg1' + +let g:gruvbox_contrast_dark="hard" +set background=dark +colorscheme gruvbox + +let g:fern#renderer = "nerdfont" + +function! s:init_fern() abort + nmap T (fern-action-open:tab) + nmap S (fern-action-open:split) + nmap V (fern-action-open:vsplit) +endfunction + +augroup fern-custom + autocmd! * + autocmd FileType fern call s:init_fern() +augroup END + +augroup my-glyph-palette + autocmd! * + autocmd FileType fern call glyph_palette#apply() + autocmd FileType nerdtree,startify call glyph_palette#apply() +augroup END + +nnoremap t :Fern . -drawer -toggle +nnoremap f :Files +nnoremap rg :Rg +nnoremap :cd .. +nnoremap b :Buffers + +"let g:NERDTreeIndicatorMapCustom = { + "\ "Modified" : "✹", + "\ "Staged" : "✚", + "\ "Untracked" : "✭", + "\ "Renamed" : "➜", + "\ "Unmerged" : "═", + "\ "Deleted" : "✖", + "\ "Dirty" : "✗", + "\ "Clean" : "✔︎", + "\ 'Ignored' : '☒', + "\ "Unknown" : "?" + "\ } + +let g:indentLine_char = '▏' +"let g:indentLine_color_term = 2854 + +let g:indentLine_setConceal = 0 +"let g:indentLine_concealcursor="" + +let g:slime_target="tmux" +let g:slime_python_ipython=1 + +let g:tmux_navigator_no_mappings = 1 + +nnoremap :TmuxNavigateLeft +nnoremap :TmuxNavigateDown +nnoremap :TmuxNavigateUp +nnoremap :TmuxNavigateRight + +"let g:lightline = {'colorscheme': 'gruvbox'} +let g:limelight_conceal_ctermfg = 'DarkGray' + +" let g:vim_json_syntax_conceal = 0 + +let g:airline_theme='base16_gruvbox_dark_hard' +let g:airline#extensions#tabline#enabled = 1 +let g:airline#extensions#ale#enabled = 1 + +let g:ale_linters ={ + \ 'haskell': ['hlint', 'hdevtools', 'hfmt'], + \} +let g:ale_python_auto_pipenv=1 " see ale-integrations-local-executables +"let g:ale_python_pylint_auto_pipenv=1 +let g:ale_python_pylint_executable="pipenv" +let g:ale_python_pylint_change_directory=1 + +autocmd! User GoyoEnter Limelight +autocmd! User GoyoLeave Limelight!! + +" function LoadBraces (except) +" if (&ft != a:except) +" RainbowParenthesesLoadBraces +" endif +" endfunction +" +" " For rainbow parenhteses +" au VimEnter * RainbowParenthesesToggle +" au Syntax * RainbowParenthesesLoadRound +" au Syntax * RainbowParenthesesLoadSquare +" au Syntax * call LoadBraces('haskell') + +"autocmd! BufWritePost,BufEnter * Neomake + +let g:deoplete#enable_at_startup = 1 + +let g:rainbow_active = 1 + +let g:black_linelength=79 + +let g:NERDDefaultAlign = 'left' + +nnoremap i +inoremap +nnoremap a +inoremap + +nnoremap p "=system('xsel')p +nnoremap m :!make + +" CLOJURE +let g:clj_fmt_autosave = 0 +"autocmd FileType clojure nnoremap :hi Normal ctermbg=none +autocmd FileType clojure nnoremap :Eval +autocmd FileType clojure vnoremap :Eval +autocmd FileType clojure nnoremap :Eval (stop) +autocmd FileType clojure nnoremap :Cljfmt + +"set formatoptions+=w +"set tw=80 +"nnoremap Q gqip + +" au BufNewFile,BufRead *.go setlocal noet ts=4 sw=4 sts=4 + +let g:UltiSnipsExpandTrigger="" +let g:UltiSnipsJumpForwardTrigger="" +let g:UltiSnipsJumpBackwardTrigger="" + +autocmd FileType python nnoremap :Black +autocmd FileType sql nnoremap :%!sqlfluff fix - +autocmd FileType sh nnoremap :Shfmt +autocmd FileType json nnoremap :%!jq --indent 4 . +autocmd FileType terraform nnoremap :TerraformFmt +autocmd FileType nix nnoremap :%!nixfmt < % diff --git a/home/neovim/init_macos.vim b/home/neovim/init_macos.vim new file mode 100644 index 0000000..21705d2 --- /dev/null +++ b/home/neovim/init_macos.vim @@ -0,0 +1,269 @@ +set nowrap +set nocompatible +syntax on +filetype plugin on +set number +set mouse=a " mouse support +set showcmd " show incomplete cmds down the bottom +set showmode " show current mode +set visualbell " no sounds +set autoread " reload files changed outside vim +"set gcr=a:blinkon0 " disable cursor blink +set backspace=indent,eol,start " allow backspacing over everything in insert +mode +set shiftround " use multiple of shiftwidth when indenting with '<' and '>' +set showmatch " set show matching parenthesis +set ignorecase " ignore case when searching +set smartcase " ignore case if search pattern is all lowercase, case-sensitive otherwise +set smarttab " insert tabs on the start of a line according to shiftwidth, not tabstop +set hlsearch " highlight search terms +set incsearch " show search matches as you type +set hidden +set ruler +set clipboard=unnamed " system clipboard +set list listchars=tab:\ \ ,trail:· " display tabs and trailing spaces visually +set colorcolumn=80 + +set splitbelow +set splitright +nmap r + +"let g:python_host_prog = '/usr/bin/python2' +"let g:python3_host_prog = '/usr/local/bin/python3' + +let mapleader="," +let maplocalleader="\\" + +" use alt-x to go to a specific tab +nnoremap 1gt +nnoremap 2gt +nnoremap 3gt +nnoremap 4gt +nnoremap 5gt +nnoremap 6gt +nnoremap 7gt +nnoremap 8gt +nnoremap :tablast + +" clean highlights when C-l +nnoremap :nohl + +highlight Comment cterm=italic gui=italic + +" HIGHLIGHT LINE WHEN IN INSERT MODE +hi CursorLine cterm=NONE,underline ctermbg=NONE +set timeoutlen=1000 ttimeoutlen=0 " eliminate annoying delay +autocmd InsertEnter * :set cursorline +autocmd InsertLeave * :set nocursorline + +" INDENTATION: +filetype indent on +set softtabstop=4 +set expandtab +set shiftwidth=4 " number of spaces to use for autoindenting +set tabstop=4 " a tab is four spaces +set autoindent " always set autoindenting on +set copyindent " copy the previous indentation on autoindenting + +" TAG JUMPING: +command! MakeTags !ctags -R . +" - ^] to jump to tag under cursor +" - g^] for ambiguous tags +" - ^t to jump back up the tag stack + +" TURN OF SWAP FILES: +set noswapfile +set nobackup +set nowb + +"FOLDS: +set foldmethod=indent " fold based on indent +set foldnestmax=3 " deepest fold is 3 levels +set nofoldenable " don't fold by default + +" FINDING FILES: +set path+=** +set wildmenu +" - Hit tab to find for partial match +" - Use * to make it fuzzy + +call plug#begin('~/.config/nvim/plugged') + Plug 'LaTeX-Box-Team/LaTeX-Box' + Plug 'APZelos/blamer.nvim' + Plug 'vito-c/jq.vim' + Plug 'tpope/vim-haml' + Plug 'tpope/vim-surround' + Plug 'junegunn/goyo.vim' + " Plug 'vim-pandoc/vim-pandoc' + " Plug 'vim-pandoc/vim-pandoc-syntax' + Plug 'lambdalisue/nerdfont.vim' + Plug 'lambdalisue/fern-renderer-nerdfont.vim' + Plug 'lambdalisue/glyph-palette.vim' + Plug 'lambdalisue/fern-git-status.vim' + Plug 'lambdalisue/fern-mapping-git.vim' " to check + Plug 'lambdalisue/fern-hijack.vim' + " Plug 'voldikss/vim-floaterm' + " Plug 'camspiers/animate.vim' + " Plug 'camspiers/lens.vim' + Plug 'psf/black', { 'branch': 'stable' } + Plug 'elzr/vim-json' + Plug 'https://tildegit.org/sloum/gemini-vim-syntax.git' + Plug 'maksimr/vim-jsbeautify' + Plug 'glacambre/firenvim' + Plug 'hashivim/vim-terraform' + Plug 'martinda/Jenkinsfile-vim-syntax' + Plug 'z0mbix/vim-shfmt', { 'for': 'sh' } + Plug 'LnL7/vim-nix' +call plug#end() + +let g:markdown_syntax_conceal = 0 + + +set updatetime=100 " reduce vim update time so magke gitgutter more responsive + +set termguicolors + +"set fillchars+=vert:\ " cleaner vertical line + +let g:gruvbox_contrast_dark="hard" +let g:gruvbox_contrast_light="hard" +let g:gruvbox_italic=1 +let g:gruvbox_invert_indent_guides=1 +let g:gruvbox_vert_split='bg1' +colorscheme gruvbox + +" colorscheme gruvbox8_hard + +set background=dark + +let g:fern#renderer = "nerdfont" + +function! s:init_fern() abort + nmap T (fern-action-open:tab) + nmap S (fern-action-open:split) + nmap V (fern-action-open:vsplit) + nmap (fern-action-mark:toggle) +endfunction + +augroup fern-custom + autocmd! * + autocmd FileType fern call s:init_fern() +augroup END + +augroup my-glyph-palette + autocmd! * + autocmd FileType fern call glyph_palette#apply() + autocmd FileType nerdtree,startify call glyph_palette#apply() +augroup END + +nnoremap t :Fern . -drawer -toggle +nnoremap f :Files +nnoremap rg :Rg +nnoremap :cd .. +nnoremap b :Buffers + +"let g:NERDTreeIndicatorMapCustom = { + "\ "Modified" : "✹", + "\ "Staged" : "✚", + "\ "Untracked" : "✭", + "\ "Renamed" : "➜", + "\ "Unmerged" : "═", + "\ "Deleted" : "✖", + "\ "Dirty" : "✗", + "\ "Clean" : "✔︎", + "\ 'Ignored' : '☒', + "\ "Unknown" : "?" + "\ } + +let g:indentLine_char = '▏' +"let g:indentLine_color_term = 2854 + +let g:indentLine_setConceal = 0 +"let g:indentLine_concealcursor="" + +let g:slime_target="tmux" +let g:slime_python_ipython=1 + +let g:tmux_navigator_no_mappings = 1 + +nnoremap :TmuxNavigateLeft +nnoremap :TmuxNavigateDown +nnoremap :TmuxNavigateUp +nnoremap :TmuxNavigateRight + +"let g:lightline = {'colorscheme': 'gruvbox'} +" let g:limelight_conceal_ctermfg = 'DarkGray' + +" let g:vim_json_syntax_conceal = 0 + +let g:airline_theme='base16_gruvbox_dark_hard' +let g:airline#extensions#tabline#enabled = 1 +let g:airline#extensions#ale#enabled = 1 + +let g:ale_linters ={ + \ 'haskell': ['hlint', 'hdevtools', 'hfmt'], + \} +let g:ale_python_auto_pipenv=1 " see ale-integrations-local-executables +"let g:ale_python_pylint_auto_pipenv=1 +let g:ale_python_pylint_executable="pipenv" +let g:ale_python_pylint_change_directory=1 + +let g:ale_lint_on_text_changed = 'never' +let g:ale_lint_on_insert_leave = 0 +let g:ale_lint_on_enter = 0 + +autocmd! User GoyoEnter Limelight +autocmd! User GoyoLeave Limelight!! + +" function LoadBraces (except) +" if (&ft != a:except) +" RainbowParenthesesLoadBraces +" endif +" endfunction +" +" " For rainbow parenhteses +" au VimEnter * RainbowParenthesesToggle +" au Syntax * RainbowParenthesesLoadRound +" au Syntax * RainbowParenthesesLoadSquare +" au Syntax * call LoadBraces('haskell') + +"autocmd! BufWritePost,BufEnter * Neomake + +" let g:deoplete#enable_at_startup = 1 + +" let g:black_linelength=79 + +let g:shfmt_extra_args = '-i 4' + +let g:NERDDefaultAlign = 'left' + +nnoremap i +inoremap +nnoremap a +inoremap + +nnoremap p "=system('xsel')p +nnoremap m :!make + +"set formatoptions+=w +"set tw=80 +"nnoremap Q gqip +"set textwidth=79 +" set wrap linebreak + +" au BufNewFile,BufRead *.go setlocal noet ts=4 sw=4 sts=4 + +let g:UltiSnipsExpandTrigger="" +let g:UltiSnipsJumpForwardTrigger="" +let g:UltiSnipsJumpBackwardTrigger="" + +" autocmd FileType sql nnoremap :%!sqlformat --reindent --keywords upper --identifiers lower - +" autocmd FileType sql nnoremap :%!sqlformat --reindent --keywords upper - +autocmd FileType sql nnoremap :%!sqlfluff fix - +autocmd FileType python nnoremap :Black +autocmd FileType sh nnoremap :Shfmt +autocmd FileType json nnoremap :%!jq --indent 4 . +autocmd FileType terraform nnoremap :TerraformFmt +autocmd FileType nix nnoremap :%!nixfmt < % + +let g:vimwiki_list = [{'path': '~/notes/', 'syntax': 'markdown', 'ext': '.md'}] diff --git a/home/neovim/macos.nix b/home/neovim/macos.nix new file mode 100644 index 0000000..40e8d6f --- /dev/null +++ b/home/neovim/macos.nix @@ -0,0 +1,44 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + programs.neovim = { + plugins = + with pkgs.vimPlugins; [ # nix-env -f '' -qaP -A vimPlugins + gitgutter + fugitive + vim-markdown + sensible + vim-unimpaired + vim-css-color + easymotion + vim-slime + rainbow + vim-jinja + gruvbox-community + deoplete-nvim + nerdcommenter + goyo + limelight-vim + fzf-vim + todo-txt-vim + airline + vim-airline-themes + vimwiki + vim-ledger + fern-vim + FixCursorHold-nvim + indentLine + tmux-navigator + neomake + ale + neoformat + vim-smoothie + ultisnips + vim-snippets + vim-nix + vim-terraform + ]; + extraConfig = builtins.readFile ./init_macos.vim; + }; +} diff --git a/home/pass/common.nix b/home/pass/common.nix new file mode 100644 index 0000000..db2aa68 --- /dev/null +++ b/home/pass/common.nix @@ -0,0 +1,11 @@ +{ config, pkgs, ... }: + +{ + programs.password-store = { + enable = true; + settings = { + PASSWORD_STORE_DIR = "${config.home.homeDirectory}/.password-store"; + PASSWORD_STORE_KEY = "B51D4548A4846E3C8D115C808333CFB0B9D3244D"; + }; + }; +} diff --git a/home/pass/default.nix b/home/pass/default.nix new file mode 100644 index 0000000..f120fb2 --- /dev/null +++ b/home/pass/default.nix @@ -0,0 +1,9 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + programs.browserpass = { + enable = true; + browsers = [ "firefox" "chromium" ]; + }; +} diff --git a/home/pass/macos.nix b/home/pass/macos.nix new file mode 100644 index 0000000..9a7db85 --- /dev/null +++ b/home/pass/macos.nix @@ -0,0 +1,5 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; +} diff --git a/home/rss/default.nix b/home/rss/default.nix new file mode 100644 index 0000000..6074d45 --- /dev/null +++ b/home/rss/default.nix @@ -0,0 +1,42 @@ +{ config, pkgs, ... }: + +let + url = "miniflux.monotremata.xyz"; + user = "rilla"; + rsssync = pkgs.callPackage ./rsssync.nix { inherit config pkgs; }; +in +{ + home.packages = [rsssync]; + programs.newsboat = { + enable = true; + autoReload = true; + browser = "firefox"; # todo: should be my open_link script + reloadThreads = 100; + extraConfig = '' + urls-source "miniflux" + miniflux-url "https://${url}/" + miniflux-login "rilla" + miniflux-passwordeval "${pkgs.pass}/bin/pass suricata/${url}/${user}" + + # unbind keys + unbind-key j + unbind-key k + unbind-key J + unbind-key K + + # bind keys - vim style + bind-key j down + bind-key k up + bind-key l open + bind-key h quit + + color background color15 color0 + color listnormal color15 color0 + color listfocus color230 color4 + color listnormal_unread color2 color0 + color listfocus_unread color2 color4 bold + color info color230 color4 bold + color article color15 color0 + ''; + }; +} diff --git a/home/rss/rsssync.nix b/home/rss/rsssync.nix new file mode 100644 index 0000000..d2211c5 --- /dev/null +++ b/home/rss/rsssync.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +let + shell = "${pkgs.dash}/bin/dash"; + newsboat = "${pkgs.newsboat}/bin/newsboat"; +in + pkgs.writeScriptBin "rsssync" '' + #!${shell} + ${newsboat} --execute="reload" + '' diff --git a/home/scripts/default.nix b/home/scripts/default.nix new file mode 100644 index 0000000..2c29f79 --- /dev/null +++ b/home/scripts/default.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = [ + (pkgs.callPackage ./nixos-rebuild.nix { inherit config pkgs; }) + ]; +} diff --git a/home/scripts/nixos-rebuild.nix b/home/scripts/nixos-rebuild.nix new file mode 100644 index 0000000..517d1e9 --- /dev/null +++ b/home/scripts/nixos-rebuild.nix @@ -0,0 +1,11 @@ +{ config, pkgs, ... }: + +let + config-dir="configs/nixos"; +in + pkgs.writeScriptBin "nixos-rebuild" '' + #!${pkgs.dash}/bin/dash + HOSTNAME="''${HOSTNAME:-''$(hostname)}" + export NIXOS_CONFIG="${config.home.homeDirectory}/${config-dir}/''${HOSTNAME}.nix" + ${pkgs.nixos-rebuild}/bin/nixos-rebuild "$@" + '' diff --git a/home/snapcast/default.nix b/home/snapcast/default.nix new file mode 100644 index 0000000..ba53179 --- /dev/null +++ b/home/snapcast/default.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: + +let snapserver_ip = "192.168.1.144"; +in +{ + home.packages = [ pkgs.snapcast ]; + + systemd.user.services.snapclient = { + Unit = { + After = [ "pipewire.service" ]; + }; + Service = { + Type = "simple"; + ExecStart = "${pkgs.snapcast}/bin/snapclient --host ${snapserver_ip}"; + }; + Install = { + WantedBy = [ "pipewire.service" ]; + }; + }; + +} diff --git a/home/sound/default.nix b/home/sound/default.nix new file mode 100644 index 0000000..a649e4a --- /dev/null +++ b/home/sound/default.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +{ + home.packages = [ + pkgs.pamixer + pkgs.pulsemixer + pkgs.pavucontrol + pkgs.alsa-utils + ]; + + # services.easyeffects = { + # enable = true; + # }; +} diff --git a/home/ssh/default.nix b/home/ssh/default.nix new file mode 100644 index 0000000..a62d08a --- /dev/null +++ b/home/ssh/default.nix @@ -0,0 +1,80 @@ +{ config, pkgs, ... }: + +{ + home.file.".ssh/id_rsa_yubikey.pub".source = ./id_rsa_yubikey.pub; + programs.ssh = { + enable = true; + matchBlocks = { + + "github.com" = { + identitiesOnly = true; + identityFile = "~/.ssh/id_rsa_yubikey.pub"; + }; + + "openwrt" = { + hostname = "openwrt"; + identitiesOnly = true; + identityFile = "~/.ssh/id_rsa_yubikey.pub"; + forwardAgent = true; + user = "root"; + }; + + "suricata" = { + hostname = "suricata.monotremata.xyz"; + identitiesOnly = true; + identityFile = "~/.ssh/id_rsa_yubikey.pub"; + forwardAgent = true; + port = 2222; + }; + + "narwhal" = { + hostname = "192.168.1.133"; + identitiesOnly = true; + identityFile = "~/.ssh/id_rsa_yubikey.pub"; + forwardAgent = true; + port = 22; + }; + + "sloth" = { + hostname = "192.168.1.144"; + identitiesOnly = true; + identityFile = "~/.ssh/id_rsa_yubikey.pub"; + forwardAgent = true; + port = 22; + }; + + "trantor" = { + hostname = "192.168.1.203"; + identitiesOnly = true; + identityFile = "~/.ssh/id_rsa_yubikey.pub"; + forwardAgent = true; + port = 22; + }; + + "axolotl" = { + hostname = "192.168.1.180"; + identitiesOnly = true; + identityFile = "~/.ssh/id_rsa_yubikey.pub"; + forwardAgent = true; + port = 22; + }; + + "caladan" = { + hostname = "caladan.monotremata.xyz"; + identitiesOnly = true; + identityFile = "~/.ssh/id_rsa_yubikey.pub"; + forwardAgent = true; + port = 2222; + }; + + "fugu" = { + hostname = "mail.monotremata.xyz"; + identitiesOnly = true; + identityFile = "~/.ssh/id_rsa_yubikey.pub"; + forwardAgent = true; + port = 22; + }; + + }; + }; +} diff --git a/home/ssh/id_rsa_yubikey.pub b/home/ssh/id_rsa_yubikey.pub new file mode 100644 index 0000000..c092b27 --- /dev/null +++ b/home/ssh/id_rsa_yubikey.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDaiwmnSKC4DpznZlode1987DvGVLWqkvDZXZ6ey/LOZhRHvNnr5lP4Ke034R17mHHuTlzzuTKUKTN6JcIxBURGUwjWgNQO5z+7SapdOvPpw7M8wOlgp92CbIMiE/tReNbUi2e584Y5NR4tMCQm+FPvQ7c7nY/WoxJ6VSiKBbXzN+IrB9H6ZAVyfAlzHpxhwXeuP5xFwTtapzyzyc4phvuIhbXUc9NOZHXwoAR2La/0TVOgDyktEmCq6aGet03Azz6KPRptdnf4g9V3u8YivccXfd9WTrJr9fj1fWjDU9bBKVU6GtdcSwfqKwa6X4sQIZfONKvVEfqbIIEB70FsXHcdfnm3EN5L1PWbC441Q8bB1zvu/GnlXTlxDFmzByxnbLWTSPLuQyKq5sv9va8Jl9QEVpS3qWJbPHYBTevgboTExyLmpEfsCI+Of86Oxb8PNjyhX1/oWiy8S3w+5oQgAb+yNfSVPnX7CO4oGQhnttoXHA94LzxArYr9zZIp2asRMlc4VVWVH/jQ4FdLDjvKNARYiytOplZBPvFOHJiGb/rfjZKbMPPE+3V1WQPZ6B2nlWN5QxTpnLgTQnONr5rlSrvzFPY8BISUAYcdOCErG4agHDkHFZqWn8u+51wUZUnXo4NI+rty4Nzmc/kPfqWyv/8mSJfihidfuuHGEEzCk1qVdQ== cardno:000611073199 diff --git a/home/theming/default.nix b/home/theming/default.nix new file mode 100644 index 0000000..ef7f10c --- /dev/null +++ b/home/theming/default.nix @@ -0,0 +1,34 @@ +{ config, pkgs, ... }: + +{ + home.packages = [ + pkgs.gruvbox-dark-gtk + pkgs.papirus-icon-theme + pkgs.lxappearance + pkgs.qt5ct + pkgs.gtk-engine-murrine + pkgs.gtk_engines + ]; + + gtk = { + enable = true; + font = { + name = "Inter"; + size = 10; + package = pkgs.inter; + }; + theme = { + name = "gruvbox-dark"; + package = pkgs.gruvbox-dark-gtk; + }; + iconTheme = { + name = "Papirus-Dark"; + package = pkgs.papirus-icon-theme; + }; + }; + + qt = { + enable = true; + platformTheme = "gtk"; + }; +} diff --git a/home/tmux/default.nix b/home/tmux/default.nix new file mode 100644 index 0000000..a592b91 --- /dev/null +++ b/home/tmux/default.nix @@ -0,0 +1,86 @@ +{ config, pkgs, ... }: + +{ + programs.tmux = { + enable = true; + clock24 = true; + keyMode = "vi"; + prefix = "C-b"; + shell = "${pkgs.zsh}/bin/zsh"; + extraConfig = '' + set -g default-terminal "tmux-256color" + set-option -sa terminal-overrides ',alacritty:Tc' + + is_vim="ps -o state= -o comm= -t '#{pane_tty}' \ + | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'" + + bind -n 'M-h' if-shell "$is_vim" 'send-keys M-h' 'select-pane -L' + bind -n 'M-j' if-shell "$is_vim" 'send-keys M-j' 'select-pane -D' + bind -n 'M-k' if-shell "$is_vim" 'send-keys M-k' 'select-pane -U' + bind -n 'M-l' if-shell "$is_vim" 'send-keys M-l' 'select-pane -R' + + bind-key -T copy-mode-vi 'C-h' select-pane -L + bind-key -T copy-mode-vi 'C-j' select-pane -D + bind-key -T copy-mode-vi 'C-k' select-pane -U + bind-key -T copy-mode-vi 'C-l' select-pane -R + + bind -n 'M-1' 'select-window -t 1' + bind -n 'M-2' 'select-window -t 2' + bind -n 'M-3' 'select-window -t 3' + bind -n 'M-4' 'select-window -t 4' + bind -n 'M-5' 'select-window -t 5' + bind -n 'M-6' 'select-window -t 6' + bind -n 'M-7' 'select-window -t 7' + bind -n 'M-8' 'select-window -t 8' + bind -n 'M-9' 'select-window -t 9' + + bind -n M-p select-window -p + bind -n M-n select-window -n + + bind u \ + capture-pane \; \ + save-buffer /tmp/tmux-buffer \; \ + run-shell 'sh -c "openurl /tmp/tmux-buffer"' + + set -g base-index 1 + setw -g pane-base-index 1 + + unbind p + bind-key -T copy-mode-vi y \ + send-keys -X copy-pipe-and-cancel "xsel -i -p && xsel -o -p | xsel -i -b" + bind-key p run "xsel -o | tmux load-buffer - ; tmux paste-buffer" + + bind c new-window -c "#{pane_current_path}" + bind | split-window -h -c "#{pane_current_path}" + bind - split-window -v -c "#{pane_current_path}" + + set-option -g automatic-rename on + + set -g mouse on + + set -sg escape-time 0 + + set -g status-left-length 32 + set -g status-right-length 150 + + set -g status-fg '#ebdbb2' + set -g status-bg '#282828' + + setw -g window-status-separator ' ' + set -g status-left '#[bg=#ebdbb2,fg=#282828,bold] #S #[bg=#282828] ' + #set -g window-status-format "#[fg=#ebdbb2,bg=#a89974] #I #[fg=#a89974,bg=#282828]⮀#[fg=#a89974,bg=#282828] #W " + set -g window-status-format "#[fg=#ebdbb2,bg=#a89974] #I #[fg=#a89974,bg=#282828]#[fg=#a89974,bg=#282828] #W " + #set -g window-status-current-format "#[fg=#fbf1c7,bg=#458588,noreverse,bold] #I #[fg=#458588,bg=#282828]⮀#[fg=#fbf1c7,bg=#282828,noreverse,bold] #W " + set -g window-status-current-format "#[fg=#fbf1c7,bg=#458588,noreverse,bold] #I #[fg=#458588,bg=#282828]#[fg=#fbf1c7,bg=#282828,noreverse,bold] #W " + + set -g status-right \'\' + + set-hook -g 'session-created' 'run-shell -b "if [ \#{session_windows} -eq 1 ]; then tmux set status off; else tmux set status on; fi"' + set-hook -g 'after-new-window' 'run-shell -b "if [ \#{session_windows} -eq 1 ]; then tmux set status off; else tmux set status on; fi; if [ \#{window_panes} -eq 1 ]; then tmux set pane-border-status off; fi"' + set-hook -g 'after-kill-pane' 'run-shell -b "if [ \#{session_windows} -eq 1 ]; then tmux set status off; else tmux set status on; fi; if [ \#{window_panes} -eq 1 ]; then tmux set pane-border-status off; fi"' + set-hook -g 'pane-exited' 'run-shell -b "if [ \#{session_windows} -eq 1 ]; then tmux set status off; else tmux set status on; fi; if [ \#{window_panes} -eq 1 ]; then tmux set pane-border-status off; fi"' + set-hook -g 'after-split-window' 'run-shell -b "if [ \#{window_panes} -gt 1 ]; then tmux set pane-border-status top; fi"' + set -g default-command ${pkgs.zsh}/bin/zsh + ''; + }; +} diff --git a/home/vitetris/common.nix b/home/vitetris/common.nix new file mode 100644 index 0000000..12ba7ee --- /dev/null +++ b/home/vitetris/common.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + home.file.".vitetris".text = '' + mode=1 + level=0 + height=5 + rotate=2 + softdrop=1 + [stdin] + left=h + right=l + up=k + down=j + ''; +} diff --git a/home/vitetris/default.nix b/home/vitetris/default.nix new file mode 100644 index 0000000..3764704 --- /dev/null +++ b/home/vitetris/default.nix @@ -0,0 +1,6 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + home.packages = [ pkgs.vitetris ]; +} diff --git a/home/vitetris/macos.nix b/home/vitetris/macos.nix new file mode 100644 index 0000000..9a7db85 --- /dev/null +++ b/home/vitetris/macos.nix @@ -0,0 +1,5 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; +} diff --git a/home/wallets/default.nix b/home/wallets/default.nix new file mode 100644 index 0000000..c474130 --- /dev/null +++ b/home/wallets/default.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: + +let + dev_name = "wallets"; + uuid = "9d594b35-8a01-410a-8ea1-52589b54160c"; + pw_name = "luks/wallets"; + opts = "compress-force=zstd"; + + mount_wallets = pkgs.callPackage ./mount_wallets.nix { inherit dev_name uuid pw_name opts config pkgs; }; + umount_wallets = pkgs.callPackage ./umount_wallets.nix { inherit dev_name config pkgs; }; +in +{ + home.packages = [ + pkgs.monero + pkgs.monero-gui + pkgs.wasabiwallet + pkgs.bisq-desktop + mount_wallets + umount_wallets + ]; +} diff --git a/home/wallets/mount_wallets.nix b/home/wallets/mount_wallets.nix new file mode 100644 index 0000000..11e1a18 --- /dev/null +++ b/home/wallets/mount_wallets.nix @@ -0,0 +1,34 @@ +{ dev_name, uuid, pw_name, opts, config, pkgs, ... }: + +let + + device = "/dev/mapper/${dev_name}"; + home = "${config.home.homeDirectory}"; + shell = "${pkgs.dash}/bin/dash"; + cryptsetup = "${pkgs.cryptsetup}/bin/cryptsetup"; + mkdir = "${pkgs.coreutils}/bin/mkdir"; + pass = "${pkgs.pass}/bin/pass"; + sudo = "/run/wrappers/bin/doas"; + mount = "/run/wrappers/bin/mount"; + +in + pkgs.writeScriptBin "mount_wallets" '' + #!${shell} + + if [ ! -b "${device}" ]; then + ${pass} "${pw_name}" | ${sudo} ${cryptsetup} open "UUID=${uuid}" ${dev_name} + fi + + ${mkdir} -p \ + "${home}/.walletwasabi" \ + "${home}/.local/share/Bisq" \ + "${home}/.bitmonero" \ + "${home}/monero-storage" \ + "${home}/.electrumfair" + + ${sudo} ${mount} ${device} -o subvol=@wasabi,${opts} "${home}/.walletwasabi" + ${sudo} ${mount} ${device} -o subvol=@bisq,${opts} "${home}/.local/share/Bisq" + ${sudo} ${mount} ${device} -o subvol=@monero/@bitmonero,${opts} "${home}/.bitmonero" + ${sudo} ${mount} ${device} -o subvol=@monero/@monero-storage,${opts} "${home}/monero-storage" + ${sudo} ${mount} ${device} -o subvol=@electrumfair,${opts} "${home}/.electrumfair" + '' diff --git a/home/wallets/umount_wallets.nix b/home/wallets/umount_wallets.nix new file mode 100644 index 0000000..1c534d1 --- /dev/null +++ b/home/wallets/umount_wallets.nix @@ -0,0 +1,20 @@ +{ dev_name, config, pkgs, ... }: + +let + home = "${config.home.homeDirectory}"; + shell = "${pkgs.dash}/bin/dash"; + cryptsetup = "${pkgs.cryptsetup}/bin/cryptsetup"; + sudo = "/run/wrappers/bin/sudo"; + umount = "/run/wrappers/bin/umount"; +in + pkgs.writeScriptBin "umount_wallets" '' + #!${shell} + + ${sudo} ${umount} --recursive "${home}/.walletwasabi" + ${sudo} ${umount} --recursive "${home}/.local/share/Bisq" + ${sudo} ${umount} --recursive "${home}/.bitmonero" + ${sudo} ${umount} --recursive "${home}/monero-storage" + ${sudo} ${umount} --recursive "${home}/.electrumfair" + + ${sudo} ${cryptsetup} close ${dev_name} + '' diff --git a/home/zsh/common.nix b/home/zsh/common.nix new file mode 100644 index 0000000..2333345 --- /dev/null +++ b/home/zsh/common.nix @@ -0,0 +1,64 @@ +{ config, pkgs, ... }: + +{ + programs.starship = { + enable = true; + enableZshIntegration = true; + settings = { + right_format = "$directory"; + add_newline = false; + character = { + success_symbol = "[❯](white)"; + error_symbol = "[✖](red)"; + vicmd_symbol = "[❮](white)"; + }; + directory = { + disabled = false; + style = "cyan"; + truncation_symbol = "…/"; + read_only = ""; + }; + aws = { disabled = true; }; + line_break = { disabled = true; }; + }; + }; + programs.exa = { + enable = true; + # enableAliases = true; + }; + programs.zsh = { + enableAutosuggestions = true; + enableCompletion = true; + initExtraBeforeCompInit = '' + zstyle ':completion:*' matcher-list ''' \ + 'm:{a-z\-}={A-Z\_}' \ + 'r:[^[:alpha:]]||[[:alpha:]]=** r:|=* m:{a-z\-}={A-Z\_}' \ + 'r:[[:ascii:]]||[[:ascii:]]=** r:|=* m:{a-z\-}={A-Z\_}' + zstyle ':completion:*:functions' ignored-patterns '_*' + zstyle ':completion:*' format $'\n%F{green}%d%f' + zstyle ':completion:*' group-name ''' + setopt COMPLETE_ALIASES + zstyle ':completion:*' menu select + ''; + enableSyntaxHighlighting = true; + enableVteIntegration = true; + autocd = true; + defaultKeymap = "viins"; + history = { + expireDuplicatesFirst = true; + extended = true; + ignoreDups = true; + ignoreSpace = true; + share = false; + }; + shellAliases = { + testpl = ''echo "\ue0b0 \u00b1 \ue0a0 \u27a6 \u2718 \u26a1 \u2699"''; + ls = "exa --icons"; + "..." = "../.."; + "...." = "../../.."; + "....." = "../../../.."; + "......" = "../../../../.."; + }; + localVariables = { KEYTIMEOUT = 1; }; + }; +} diff --git a/home/zsh/default.nix b/home/zsh/default.nix new file mode 100644 index 0000000..5e4572f --- /dev/null +++ b/home/zsh/default.nix @@ -0,0 +1,48 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + programs.starship = { + settings = { + gcloud = { disabled = true; }; + python = { disabled = true; }; + }; + }; + programs.zsh = { + enable = true; + initExtra = '' + autoload -U history-search-end + zle -N history-beginning-search-backward-end history-search-end + zle -N history-beginning-search-forward-end history-search-end + bindkey "^[[A" history-beginning-search-backward-end + bindkey "^[[B" history-beginning-search-forward-end + # setopt PROMPT_CR + # setopt PROMPT_SP + # export PROMPT_EOL_MARK="" + unsetopt PROMPT_SP + + precmd() { + precmd() { + echo + } + } + + VENV_DIR="${config.home.homeDirectory}/virtualenvs" + export WORKON_HOME="''${VENV_DIR}" + function activate-venv() { + local selected_env + selected_env=$( + ${pkgs.findutils}/bin/find \ + "''${VENV_DIR}" \ + -maxdepth 1 \ + -mindepth 1 \ + -type d \ + -exec basename {} \; | \ + ${pkgs.fzf}/bin/fzf + ) + [ -n "$selected_env" ] && \ + source "''${VENV_DIR}/''${selected_env}/bin/activate" + } + ''; + }; +} diff --git a/home/zsh/macos.nix b/home/zsh/macos.nix new file mode 100644 index 0000000..302b488 --- /dev/null +++ b/home/zsh/macos.nix @@ -0,0 +1,71 @@ +{ config, pkgs, ... }: + +{ + imports = [ ./common.nix ]; + programs.starship = { + settings = { + gcloud = { + disabled = false; + format = '' + on [$symbol$account(@$domain)(($region))]($style) + ''; + symbol = "☁️ "; + }; + python = { + disabled = true; + symbol = ""; + format = '' + via [$symbol$pyenv_prefix($version )(($virtualenv) )]($style) + ''; + python_binary = [ + "python" + "python2" + "python3" + "/usr/bin/python" + "/usr/local/bin/python3" + ]; + }; + }; + }; + + programs.zsh = { + enableVteIntegration = false; + initExtra = '' + autoload -U history-search-end + zle -N history-beginning-search-backward-end history-search-end + zle -N history-beginning-search-forward-end history-search-end + bindkey "^[[A" history-beginning-search-backward-end + bindkey "^[[B" history-beginning-search-forward-end + # setopt PROMPT_CR + # setopt PROMPT_SP + # export PROMPT_EOL_MARK="" + unsetopt PROMPT_SP + + precmd() { + precmd() { + echo + } + } + + VENV_DIR="${config.home.homeDirectory}/virtualenvs" + export WORKON_HOME="''${VENV_DIR}" + function activate-venv() { + local selected_env + selected_env=$( + ${pkgs.findutils}/bin/find \ + "''${VENV_DIR}" \ + -maxdepth 1 \ + -mindepth 1 \ + -type d \ + -exec basename {} \; | \ + ${pkgs.fzf}/bin/fzf + ) + [ -n "$selected_env" ] && \ + source "''${VENV_DIR}/''${selected_env}/bin/activate" + } + + export LANG=en_US.utf8 + export LC_ALL=en_US.UTF-8 + ''; + }; +} diff --git a/macos/choose-pass.nix b/macos/choose-pass.nix new file mode 100644 index 0000000..772c76d --- /dev/null +++ b/macos/choose-pass.nix @@ -0,0 +1,18 @@ +{ config, pkgs, ... }: + +pkgs.writeScriptBin "choose-pass" '' + #!${pkgs.dash}/bin/dash + + prefix=''${PASSWORD_STORE_DIR-"''${HOME}/.password-store"} + + sel=$( + ${pkgs.findutils}/bin/find "$prefix" -name '*.gpg' | \ + ${pkgs.gnused}/bin/sed -E "s|^''${prefix}/?||" | \ + ${pkgs.gnused}/bin/sed 's/.gpg$//' | \ + /usr/local/bin/choose -f Inter -s 20 -c fbf1c7 -b 458588 + ) + + [ -n "$sel" ] || exit + + ${pkgs.pass}/bin/pass show "$sel" | tr -d "\n" | /usr/bin/pbcopy +'' diff --git a/nixos/common.nix b/nixos/common.nix new file mode 100644 index 0000000..2582035 --- /dev/null +++ b/nixos/common.nix @@ -0,0 +1,217 @@ +{ config, pkgs, ... }: + +let + home-manager = builtins.fetchTarball { + url = "https://github.com/nix-community/home-manager/archive/release-21.11.tar.gz"; + }; +in { + imports = [ "${home-manager}/nixos" ]; + + nixpkgs.config = { + packageOverrides = pkgs: { + nur = import (builtins.fetchTarball + "https://github.com/nix-community/NUR/archive/master.tar.gz") { + inherit pkgs; + }; + }; + }; + + # boot.binfmt.emulatedSystems = [ "aarch64-linux" "qemu-aarch64" ]; + + networking = { + networkmanager = { + enable = true; + wifi = { scanRandMacAddress = false; }; + }; + + useDHCP = false; + interfaces = { }; + + firewall = { + allowedUDPPorts = [ 51820 ]; + + # if packets are still dropped, they will show up in dmesg + logReversePathDrops = true; + # wireguard trips rpfilter up + extraCommands = '' + ip46tables -t raw -I nixos-fw-rpfilter -p udp -m udp --sport 51820 -j RETURN + ip46tables -t raw -I nixos-fw-rpfilter -p udp -m udp --dport 51820 -j RETURN + ''; + extraStopCommands = '' + ip46tables -t raw -D nixos-fw-rpfilter -p udp -m udp --sport 51820 -j RETURN || true + ip46tables -t raw -D nixos-fw-rpfilter -p udp -m udp --dport 51820 -j RETURN || true + ''; + }; + }; + + # Set your time zone. + time.timeZone = "Europe/Madrid"; + + # Configure network proxy if necessary + # networking.proxy.default = "http://user:password@proxy:port/"; + # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain"; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + console = { + font = "Lat2-Terminus16"; + keyMap = "us"; + }; + + services.dbus.enable = true; + + services.xserver = { + enable = true; + layout = "us"; + xkbVariant = "altgr-intl"; + xkbOptions = "caps:escape"; + displayManager.startx.enable = true; + libinput.enable = true; + extraConfig = '' + Section "InputClass" + Identifier "trackball" + MatchProduct "Clearly Superior Technologies. CST Laser Trackball" + Driver "libinput" + Option "ButtonMapping" "3 2 1 4 5" + Option "AccelerationProfile" "0" + Option "AccelerationScheme" "predictable" + Option "AccelerationNumerator" "3" + EndSection + ''; + }; + + services.tor.enable = true; + + services.udev = { packages = [ pkgs.android-udev-rules ]; }; + + services.avahi.enable = true; + + # Enable CUPS to print documents. + # services.printing.enable = true; + + # Enable sound. + # sound.enable = true; + # hardware.pulseaudio.enable = true; + security.rtkit.enable = true; + services.pipewire = { + enable = true; + alsa = { + enable = true; + support32Bit = true; + }; + pulse.enable = true; + jack.enable = true; + }; + + security.doas = { + enable = true; + extraRules = [{ + groups = [ "wheel" ]; + keepEnv = true; + noPass = true; + }]; + }; + security.sudo.enable = false; + + security.pam.services = { + swaylock.text = '' + auth include login + ''; + login = { + allowNullPassword = true; + setEnvironment = true; + setLoginUid = true; + startSession = true; + unixAuth = true; + updateWtmp = true; + + # Unlock keyring on login. + enableGnomeKeyring = true; + }; + }; + + # List packages installed in system profile. To search, run: + # $ nix search wget + # environment.systemPackages = with pkgs; [ + # vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. + # wget + # firefox + # ]; + environment.systemPackages = with pkgs; [ dmidecode flashrom git ]; + + # Enable touchpad support (enabled default in most desktopManager). + + # Define a user account. Don't forget to set a password with ‘passwd’. + users = { + mutableUsers = false; + groups = { plugdev = { }; }; + users = { + root.initialHashedPassword = + "$6$3TVh31LfZQFaZi8T$9.cNxrApCaAetC8wRJXxA5U9n4Hbta3CoggvG0HntTQ6sCRQWIV01EhIjdzJoZZ1kqF2ItWkF8Sqprl5raUKY0"; + rilla = { + uid = 1000; + isNormalUser = true; + shell = pkgs.zsh; + extraGroups = [ + "wheel" + "docker" + "libvirtd" + "dialout" + "plugdev" + "adbusers" + "dockervolumes" + ]; + openssh.authorizedKeys.keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDaiwmnSKC4DpznZlode1987DvGVLWqkvDZXZ6ey/LOZhRHvNnr5lP4Ke034R17mHHuTlzzuTKUKTN6JcIxBURGUwjWgNQO5z+7SapdOvPpw7M8wOlgp92CbIMiE/tReNbUi2e584Y5NR4tMCQm+FPvQ7c7nY/WoxJ6VSiKBbXzN+IrB9H6ZAVyfAlzHpxhwXeuP5xFwTtapzyzyc4phvuIhbXUc9NOZHXwoAR2La/0TVOgDyktEmCq6aGet03Azz6KPRptdnf4g9V3u8YivccXfd9WTrJr9fj1fWjDU9bBKVU6GtdcSwfqKwa6X4sQIZfONKvVEfqbIIEB70FsXHcdfnm3EN5L1PWbC441Q8bB1zvu/GnlXTlxDFmzByxnbLWTSPLuQyKq5sv9va8Jl9QEVpS3qWJbPHYBTevgboTExyLmpEfsCI+Of86Oxb8PNjyhX1/oWiy8S3w+5oQgAb+yNfSVPnX7CO4oGQhnttoXHA94LzxArYr9zZIp2asRMlc4VVWVH/jQ4FdLDjvKNARYiytOplZBPvFOHJiGb/rfjZKbMPPE+3V1WQPZ6B2nlWN5QxTpnLgTQnONr5rlSrvzFPY8BISUAYcdOCErG4agHDkHFZqWn8u+51wUZUnXo4NI+rty4Nzmc/kPfqWyv/8mSJfihidfuuHGEEzCk1qVdQ== cardno:000611073199" + ]; + initialHashedPassword = + "$6$tzMk5I1KZlx7byaO$BvlSz7Cgo1g09e4RpxAjrZEuCptzjibF8nDWDfnOImTbz61Py/qzATDAa7HwAC3JyiZxb.2slTb.vA.f25ypd1"; + }; + }; + }; + + home-manager.users.rilla = import ./home; + + # Some programs need SUID wrappers, can be configured further or are + # started in user sessions. + # programs.mtr.enable = true; + # programs.gnupg.agent = { + # enable = true; + # enableSSHSupport = true; + # }; + programs.mosh.enable = true; + programs.zsh.enable = true; + + programs.fuse.userAllowOther = true; + + # List services that you want to enable: + + services.pcscd.enable = true; + + services.openssh = { + enable = true; + passwordAuthentication = false; + permitRootLogin = "no"; + }; + + virtualisation = { + docker.enable = true; + libvirtd.enable = true; + }; + programs.dconf.enable = true; + + # Open ports in the firewall. + # networking.firewall.allowedTCPPorts = [ ... ]; + # + # networking.firewall.allowedUDPPorts = [ ... ]; + # Or disable the firewall altogether. + # networking.firewall.enable = false; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "21.05"; # Did you read the comment? +} diff --git a/nixos/hardware-configuration/capibara.nix b/nixos/hardware-configuration/capibara.nix new file mode 100644 index 0000000..ced88bd --- /dev/null +++ b/nixos/hardware-configuration/capibara.nix @@ -0,0 +1,17 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "sd_mod" "sr_mod" "sdhci_pci" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/trantor.nix b/trantor.nix new file mode 100644 index 0000000..1aaec82 --- /dev/null +++ b/trantor.nix @@ -0,0 +1,108 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page +# and in the NixOS manual (accessible by running ‘nixos-help’). + +{ config, pkgs, ... }: + +{ + imports = [ # Include the results of the hardware scan. + ./hardware-configuration.nix + ./common.nix + ]; + + fileSystems = { + "/" = { + device = "/dev/mapper/cryptroot"; + fsType = "btrfs"; + options = [ "subvol=root" "compress-force=zstd" ]; + }; + + "/nix" = { + device = "/dev/mapper/cryptroot"; + fsType = "btrfs"; + options = [ "subvol=nix" "compress-force=zstd" ]; + }; + + "/var/log" = { + device = "/dev/mapper/cryptroot"; + fsType = "btrfs"; + options = [ "subvol=log" "compress-force=zstd" ]; + }; + + "/home" = { + device = "/dev/mapper/cryptroot"; + fsType = "btrfs"; + options = [ "subvol=home" "compress-force=zstd" ]; + }; + + "/boot" = { + device = "/dev/mapper/cryptroot"; + fsType = "btrfs"; + options = [ "subvol=boot" "compress-force=zstd" ]; + }; + + "/swap" = { + device = "/dev/mapper/cryptroot"; + fsType = "btrfs"; + options = [ "subvol=swap" ]; + }; + + "/boot/efi" = { + device = "/dev/disk/by-uuid/0BFA-9A66"; + fsType = "vfat"; + }; + }; + + swapDevices = [{ device = "/swap/swapfile"; }]; + + nixpkgs.config.allowUnfree = true; + + boot = { + loader = { + systemd-boot.enable = true; + efi = { + canTouchEfiVariables = true; + efiSysMountPoint = "/boot/efi"; + }; + grub = { + enable = true; + version = 2; + device = "nodev"; + efiSupport = true; + enableCryptodisk = true; + }; + }; + initrd = { + luks.devices = { + "cryptroot" = { + device = "/dev/disk/by-uuid/b9778e01-a86c-4c6b-beb3-f97888d4a6eb"; + keyFile = "/root_keyfile.bin"; + }; + "crypthome" = { + device = "/dev/disk/by-uuid/d8e9b35d-704a-4f66-bc19-0dd3e158de36"; + keyFile = "/home_keyfile.bin"; + }; + }; + secrets = { + "/root_keyfile.bin" = "/boot/root_keyfile.bin"; + "/home_keyfile.bin" = "/boot/home_keyfile.bin"; + }; + }; + }; + + networking = { + hostName = "trantor"; + interfaces = { + enp3s0f1.useDHCP = true; + wlp4s0.useDHCP = true; + }; + }; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "21.05"; # Did you read the comment? +}