aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorArpit Chakladar <arpitchakladar+git@gmail.com>2026-07-27 22:58:52 +0530
committerArpit Chakladar <arpitchakladar+git@gmail.com>2026-07-27 23:04:07 +0530
commitc1daed5370b8ca2555c12cb5f248b5891bc8896a (patch)
tree06c1f13e9b499458ffced4865c4d158fda06df36 /modules
parent1079bdef3a4630c915f62c437187a821167e8d7b (diff)
downloadhome-manager-config-c1daed5370b8ca2555c12cb5f248b5891bc8896a.tar.gz
home-manager-config-c1daed5370b8ca2555c12cb5f248b5891bc8896a.zip
feat: using ungoogled-chromium, accelerated graphics for hyprland
- Switch to using ungoogled-chromium package instead of chromium to get away from google tracking - Installing extensions unpacked from their source code/zip downloads for ungoogled-chromium - Using hl.env to pass environment variables to hyprland as home.sessionVariables don't get passed - Fixed the graphics acceleration for hyprland, but passing the environment variables through hl.env
Diffstat (limited to 'modules')
-rw-r--r--modules/desktop/hyprland/default.nix4
-rw-r--r--modules/web/chromium/browserpass.nix1
-rw-r--r--modules/web/chromium/default.nix141
-rw-r--r--modules/web/chromium/extensions/aria2-explorer.nix33
-rw-r--r--modules/web/chromium/extensions/browserpass.nix35
-rw-r--r--modules/web/chromium/extensions/dark-mode.nix32
-rw-r--r--modules/web/chromium/extensions/default.nix15
-rw-r--r--modules/web/chromium/extensions/lib.nix116
-rw-r--r--modules/web/chromium/extensions/ublock-origin.nix32
9 files changed, 345 insertions, 64 deletions
diff --git a/modules/desktop/hyprland/default.nix b/modules/desktop/hyprland/default.nix
index 4c5281d..1e48e3f 100644
--- a/modules/desktop/hyprland/default.nix
+++ b/modules/desktop/hyprland/default.nix
@@ -20,13 +20,13 @@ in
primaryCard = lib.mkOption {
type = lib.types.str;
- default = "/dev/dri/by-path/pci-0000:05:00.0-card";
+ default = "/dev/dri/gpu-amd";
description = "Path to primary DRM card device for Aquamarine/Hyprland rendering";
};
secondaryCard = lib.mkOption {
type = lib.types.nullOr lib.types.str;
- default = "/dev/dri/by-path/pci-0000:01:00.0-card";
+ default = "/dev/dri/gpu-nvidia";
description = "Path to secondary DRM card device for offloading (null if single GPU)";
};
};
diff --git a/modules/web/chromium/browserpass.nix b/modules/web/chromium/browserpass.nix
index a07b1d7..860d46e 100644
--- a/modules/web/chromium/browserpass.nix
+++ b/modules/web/chromium/browserpass.nix
@@ -1,4 +1,3 @@
-# Browserpass - browser extension providing it access to your password store
{
lib,
config,
diff --git a/modules/web/chromium/default.nix b/modules/web/chromium/default.nix
index f867e3b..8cf0bea 100644
--- a/modules/web/chromium/default.nix
+++ b/modules/web/chromium/default.nix
@@ -1,7 +1,7 @@
-# Chromium - Web browser configuration
{
config,
lib,
+ pkgs,
...
}:
{
@@ -17,77 +17,96 @@
defaultText = lib.literalExpression "config.programs.chromium.finalPackage";
description = "Package to use for chromium. Defaults to the wrapped finalPackage from programs.chromium.";
};
+ checkForUpdates = lib.mkOption {
+ type = lib.types.bool;
+ default = true;
+ description = ''
+ Check GitHub for newer extension releases before building, and abort
+ with upgrade instructions if the pinned version is stale. Requires
+ network access during evaluation (pass --impure to nix/home-manager).
+ '';
+ };
};
- config = lib.mkIf config.web.chromium.enable {
- programs.chromium = {
- enable = true;
+ config = lib.mkIf config.web.chromium.enable (
+ let
+ exts = import ./extensions {
+ inherit lib pkgs;
+ checkForUpdates = config.web.chromium.checkForUpdates;
+ };
- commandLineArgs = [
- "--force-device-scale-factor=1.15"
+ extensionDirs = [
+ exts.ublockOrigin.drv
+ exts.darkMode.drv
+ exts.browserpass.drv
+ exts.aria2Explorer.drv
];
- extensions = [
- { id = "ddkjiahejlhfcafbddmgiahcphecmpfh"; } # uBlock Origin Lite
- { id = "naepdomgkenhinolocfifgehidddafch"; } # Browserpass
- { id = "faeadnfmdfamenfhaipofoffijhlnkif"; } # True Amoled Black Theme
- { id = "eimadpbcbfnmbkopoojfekhnkhdbieeh"; } # Dark Reader
- { id = "mpkodccbngfoacfalldjimigbofkhgjn"; } # Aria2 Explorer
+ pinnedIds = lib.filter (id: id != null) [
+ exts.browserpass.id
+ exts.darkMode.id
+ exts.ublockOrigin.id
];
- };
+ in
+ {
+ programs.chromium = {
+ enable = true;
+ package = pkgs.ungoogled-chromium;
+ commandLineArgs = [
+ "--force-device-scale-factor=1.15"
+ "--load-extension=${lib.concatStringsSep "," extensionDirs}"
+ ];
+ };
- xdg.mimeApps.defaultApplications = {
- "x-scheme-handler/http" = "chromium-browser.desktop";
- "x-scheme-handler/https" = "chromium-browser.desktop";
- "x-scheme-handler/chrome" = "chromium-browser.desktop";
- "text/html" = "chromium-browser.desktop";
- "application/xhtml+xml" = "chromium-browser.desktop";
- };
+ xdg.mimeApps.defaultApplications = {
+ "x-scheme-handler/http" = "chromium-browser.desktop";
+ "x-scheme-handler/https" = "chromium-browser.desktop";
+ "x-scheme-handler/chrome" = "chromium-browser.desktop";
+ "text/html" = "chromium-browser.desktop";
+ "application/xhtml+xml" = "chromium-browser.desktop";
+ };
- xdg.configFile."chromium/Default/Preferences" = {
- force = true;
- text = builtins.toJSON {
- browser = {
- show_full_urls = true;
- theme = {
- follows_system_colors = true;
+ xdg.configFile."chromium/Default/Preferences" = {
+ force = true;
+ text = builtins.toJSON {
+ browser = {
+ show_full_urls = true;
+ theme = {
+ follows_system_colors = true;
+ };
};
- };
- search = {
- suggest_enabled = false;
- };
- url_handling = {
- show_full_urls = true;
- };
- autofill = {
- profile_enabled = false;
- credit_card_enabled = false;
- };
- vertical_tabs = {
- collapsed_state = true;
- enabled = true;
- enabled_first_time = true;
- uncollapsed_width = 240;
- };
- credentials_enable_service = false;
- credentials_enable_autosignin = false;
- extensions = {
- pinned_extensions = [
- "ddkjiahejlhfcafbddmgiahcphecmpfh"
- "naepdomgkenhinolocfifgehidddafch"
- "eimadpbcbfnmbkopoojfekhnkhdbieeh"
- ];
- ui = {
- developer_mode = true;
+ search = {
+ suggest_enabled = false;
};
- };
- profile = {
- default_content_setting_values = {
- notifications = 2;
+ url_handling = {
+ show_full_urls = true;
+ };
+ autofill = {
+ profile_enabled = false;
+ credit_card_enabled = false;
+ };
+ vertical_tabs = {
+ collapsed_state = true;
+ enabled = true;
+ enabled_first_time = true;
+ uncollapsed_width = 240;
};
+ credentials_enable_service = false;
+ credentials_enable_autosignin = false;
+ extensions = {
+ pinned_extensions = pinnedIds;
+ ui = {
+ developer_mode = true;
+ };
+ };
+ profile = {
+ default_content_setting_values = {
+ notifications = 2;
+ };
+ };
+ high_efficiency_mode_enabled = true;
};
- high_efficiency_mode_enabled = true;
};
- };
- };
+ }
+ );
}
diff --git a/modules/web/chromium/extensions/aria2-explorer.nix b/modules/web/chromium/extensions/aria2-explorer.nix
new file mode 100644
index 0000000..1f6e5b1
--- /dev/null
+++ b/modules/web/chromium/extensions/aria2-explorer.nix
@@ -0,0 +1,33 @@
+{
+ lib,
+ pkgs,
+ extLib,
+}:
+let
+ pname = "aria2-explorer";
+ owner = "alexhua";
+ repo = "Aria2-Explorer";
+ version = "2.8.2";
+ checkedVersion = extLib.checkExtensionVersion {
+ inherit
+ pname
+ owner
+ repo
+ version
+ ;
+ tagPrefix = "v";
+ urlTemplate = "https://github.com/${owner}/${repo}/releases/download/v<version>/A2E-v<version>.crx";
+ };
+in
+{
+ inherit pname;
+ version = checkedVersion;
+ id = "dkcfilkhokojanlmgpbmjidiidoebnbm";
+ drv = extLib.fetchUnpackedExtension {
+ inherit pname;
+ version = checkedVersion;
+ url = "https://github.com/${owner}/${repo}/releases/download/v${checkedVersion}/A2E-v${checkedVersion}.crx";
+ hash = "sha256-ljTgKd9QJTRJ11rlNx+PTynlQvdLW3IEoYNnCeOU2K8=";
+ isCrx = true;
+ };
+}
diff --git a/modules/web/chromium/extensions/browserpass.nix b/modules/web/chromium/extensions/browserpass.nix
new file mode 100644
index 0000000..527f073
--- /dev/null
+++ b/modules/web/chromium/extensions/browserpass.nix
@@ -0,0 +1,35 @@
+{
+ lib,
+ pkgs,
+ extLib,
+}:
+let
+ pname = "browserpass";
+ owner = "browserpass";
+ repo = "browserpass-extension";
+ version = "3.12.0";
+ checkedVersion = extLib.checkExtensionVersion {
+ inherit
+ pname
+ owner
+ repo
+ version
+ ;
+ tagPrefix = "";
+ urlTemplate = "https://github.com/${owner}/${repo}/releases/download/<version>/browserpass-webstore-<version>.crx";
+ };
+in
+{
+ inherit pname;
+ version = checkedVersion;
+ # Stable webstore ID — only holds if the crx's manifest.json embeds "key".
+ # Verify at chrome://extensions after switching; update if it drifts.
+ id = "klfoddkbhleoaabpmiigbmpbjfljimgb";
+ drv = extLib.fetchUnpackedExtension {
+ inherit pname;
+ version = checkedVersion;
+ url = "https://github.com/${owner}/${repo}/releases/download/${checkedVersion}/browserpass-webstore-${checkedVersion}.crx";
+ hash = "sha256-NfLbEe2EBctmntJqbsIpwm2WRFdo8q6yjWGjVK2MmFE=";
+ isCrx = true;
+ };
+}
diff --git a/modules/web/chromium/extensions/dark-mode.nix b/modules/web/chromium/extensions/dark-mode.nix
new file mode 100644
index 0000000..4ac9040
--- /dev/null
+++ b/modules/web/chromium/extensions/dark-mode.nix
@@ -0,0 +1,32 @@
+{
+ lib,
+ pkgs,
+ extLib,
+}:
+let
+ pname = "dark-mode";
+ owner = "code-charity";
+ repo = "dark-mode";
+ version = "3.3.11";
+ checkedVersion = extLib.checkExtensionVersion {
+ inherit
+ pname
+ owner
+ repo
+ version
+ ;
+ tagPrefix = "v";
+ urlTemplate = "https://github.com/${owner}/${repo}/archive/refs/tags/v<version>.zip";
+ };
+in
+{
+ inherit pname;
+ version = checkedVersion;
+ id = "ifpghghnlimndidoppdkdnbljddikfoj";
+ drv = extLib.fetchUnpackedExtension {
+ inherit pname;
+ version = checkedVersion;
+ url = "https://github.com/${owner}/${repo}/archive/refs/tags/v${checkedVersion}.zip";
+ hash = "sha256-Lt3T8i0ylV0l+T0eqnzs6veBcOpizhP79LgSkUx4xI8=";
+ };
+}
diff --git a/modules/web/chromium/extensions/default.nix b/modules/web/chromium/extensions/default.nix
new file mode 100644
index 0000000..a44286e
--- /dev/null
+++ b/modules/web/chromium/extensions/default.nix
@@ -0,0 +1,15 @@
+{
+ lib,
+ pkgs,
+ checkForUpdates ? true,
+}:
+let
+ extLib = import ./lib.nix { inherit lib pkgs checkForUpdates; };
+ mkExtension = path: import path { inherit lib pkgs extLib; };
+in
+{
+ ublockOrigin = mkExtension ./ublock-origin.nix;
+ darkMode = mkExtension ./dark-mode.nix;
+ browserpass = mkExtension ./browserpass.nix;
+ aria2Explorer = mkExtension ./aria2-explorer.nix;
+}
diff --git a/modules/web/chromium/extensions/lib.nix b/modules/web/chromium/extensions/lib.nix
new file mode 100644
index 0000000..f5e83a1
--- /dev/null
+++ b/modules/web/chromium/extensions/lib.nix
@@ -0,0 +1,116 @@
+{
+ lib,
+ pkgs,
+ checkForUpdates ? true,
+}:
+rec {
+ # --- Hit the GitHub releases API and return the latest tag name. ---
+ # Impure: requires --impure since there's no fixed output hash for the API
+ # response itself. Optionally uses $GITHUB_TOKEN to dodge rate limits.
+ fetchLatestGithubReleaseTag =
+ { owner, repo }:
+ let
+ token = builtins.getEnv "GITHUB_TOKEN";
+ raw = builtins.fetchurl {
+ url = "https://api.github.com/repos/${owner}/${repo}/releases/latest";
+ name = "${repo}-latest-release.json";
+ };
+ json = builtins.fromJSON (builtins.readFile raw);
+ in
+ json.tag_name;
+
+ # --- Compare pinned version against upstream latest, abort with instructions if stale. ---
+ # Returns `version` unchanged on success so it can be threaded into the
+ # derivation below and force this check to actually run.
+ checkExtensionVersion =
+ {
+ pname,
+ owner,
+ repo,
+ version,
+ urlTemplate, # human-readable template shown in the error message
+ tagPrefix ? "", # e.g. "v" if tags look like "v1.2.3"
+ }:
+ if !checkForUpdates then
+ version
+ else
+ let
+ latestTag = fetchLatestGithubReleaseTag { inherit owner repo; };
+ latestVersion =
+ if lib.hasPrefix tagPrefix latestTag then lib.removePrefix tagPrefix latestTag else latestTag;
+ in
+ if latestVersion != version then
+ throw ''
+ [${pname}] A newer release is available upstream — refusing to build a stale extension.
+
+ pinned version : ${version}
+ latest version : ${latestVersion} (tag: ${latestTag})
+
+ To upgrade, edit extensions/${pname}.nix:
+ 1. Set version = "${latestVersion}";
+ 2. Point the url at the new release asset:
+ ${urlTemplate}
+ 3. Set hash = lib.fakeHash;
+ then re-run your switch — it'll fail with a hash mismatch showing
+ the real sha256. Paste that in as the final hash.
+ 4. Re-run once more. This check passes once pinned == latest.
+
+ To skip this check for now (e.g. offline / pure eval), set:
+ web.chromium.checkForUpdates = false;
+ ''
+ else
+ version;
+
+ # --- Download + unpack a zip *or* crx into a plain unpacked-extension dir. ---
+ # A CRX3 file is just: "Cr24" magic (4B) + version (4B) + header length N (4B)
+ # + N bytes of protobuf header + a normal zip payload. We slice off the
+ # header when isCrx = true, then unzip exactly like any other release zip —
+ # so every extension, crx or not, goes through one identical pipeline.
+ fetchUnpackedExtension =
+ {
+ pname,
+ version,
+ url,
+ hash,
+ isCrx ? false,
+ }:
+ pkgs.stdenv.mkDerivation {
+ inherit pname version;
+ src = pkgs.fetchurl { inherit url hash; };
+ nativeBuildInputs = [
+ pkgs.unzip
+ pkgs.python3
+ ];
+ dontUnpack = true;
+
+ buildPhase = ''
+ runHook preBuild
+ mkdir -p $out
+
+ if [ "${lib.boolToString isCrx}" = "true" ]; then
+ offset=$(python3 -c "
+ import struct
+ with open('$src', 'rb') as f:
+ magic, ver, hlen = struct.unpack('<4sII', f.read(12))
+ assert magic == b'Cr24', 'not a CRX file'
+ print(12 + hlen)
+ ")
+ dd if=$src of=payload.zip bs=1 skip=$offset status=none
+ unzip -q payload.zip -d $out
+ else
+ unzip -q $src -d $out
+ fi
+
+ # Flatten a single wrapping folder (common in GitHub release zips)
+ if [ "$(ls -1 $out | wc -l)" -eq 1 ] && [ -d "$out"/* ]; then
+ shopt -s dotglob
+ mv "$out"/*/* "$out"/ 2>/dev/null || true
+ rmdir "$out"/*/ 2>/dev/null || true
+ shopt -u dotglob
+ fi
+ runHook postBuild
+ '';
+
+ installPhase = "true";
+ };
+}
diff --git a/modules/web/chromium/extensions/ublock-origin.nix b/modules/web/chromium/extensions/ublock-origin.nix
new file mode 100644
index 0000000..7d11ee4
--- /dev/null
+++ b/modules/web/chromium/extensions/ublock-origin.nix
@@ -0,0 +1,32 @@
+{
+ lib,
+ pkgs,
+ extLib,
+}:
+let
+ pname = "ublock-origin";
+ owner = "gorhill";
+ repo = "uBlock";
+ version = "1.72.2";
+ checkedVersion = extLib.checkExtensionVersion {
+ inherit
+ pname
+ owner
+ repo
+ version
+ ;
+ tagPrefix = "";
+ urlTemplate = "https://github.com/${owner}/${repo}/releases/download/<version>/uBlock0_<version>.chromium.zip";
+ };
+in
+{
+ inherit pname;
+ version = checkedVersion;
+ id = "nnpdegnhelmjgchicpfdigllmhgpndeg"; # unpacked, ID derives from manifest key at load time
+ drv = extLib.fetchUnpackedExtension {
+ inherit pname;
+ version = checkedVersion;
+ url = "https://github.com/${owner}/${repo}/releases/download/${checkedVersion}/uBlock0_${checkedVersion}.chromium.zip";
+ hash = "sha256-0QTKxOH0jXaxw/+Irt4uqoJpgUrgbMnIUNJ6+1J05TM=";
+ };
+}