feat: Add host sydpc

My, this is a lot TwT.  Much work was batched as part of the transition from
guix-rebound to nixos-testbed/sydpc.

- Discord/Vesktop module & config.
- Syncthing setup.
- Assorted Emacs changes.
- Waybar config.
- Niri config.
- Steam config.
- Some MPD.
- Stylix config.
- Files/Impermanence things.
- Enable Ghostty.
- God knows what else.
This commit is contained in:
Madeleine Sydney
2025-03-17 12:34:26 -06:00
parent 4464e7cec1
commit c48a93ad10
40 changed files with 2632 additions and 179 deletions

63
modules/home/discord.nix Normal file
View File

@@ -0,0 +1,63 @@
{ config, lib, pkgs, ... }:
let cfg = config.sydnix.discord;
in {
options.sydnix.discord = {
enable = lib.mkEnableOption "Discord";
fixWayland = lib.mkOption {
description = ''
Fix flickering on Wayland.
'';
type = lib.types.bool;
default = false;
};
};
config = lib.mkIf cfg.enable
(let
# Fixes flickering and platform detection on Wayland.
vesktop-wayland-wrapper =
pkgs.symlinkJoin {
name = "vesktop-wayland-wrapper";
paths = [ pkgs.callPackage pkgs.vesktop ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/vesktop \
--add-flags "--disable-gpu-compositing"
# --add-flags "--disable-gpu-compositing --ozone-platform-hint=auto"
'';
};
in {
sydnix.impermanence.directories =
let xdg-config-home =
config.home.confighome
or "${config.home.homeDirectory}/.config";
in [
# This directory should really be written in terms of
# `config.programs.nixcord.vesktopConfigDir`, but it defaults to null
# for unknown reasons. This is in conflict with the docs, which claim
# it should be the path used here.
(lib.removePrefix
config.home.homeDirectory
"${xdg-config-home}/vesktop/sessionData")
];
programs.nixcord = {
enable = true;
discord = {
# Install Vesktop without Discord.
enable = false;
# openASAR.enable = true;
vencord.enable = false;
vencord.package = pkgs.vencord;
};
vesktop = {
enable = true;
# package =
# if cfg.fixWayland
# then vesktop-wayland-wrapper
# else pkgs.vesktop;
};
};
});
}

25
modules/home/steam.nix Normal file
View File

@@ -0,0 +1,25 @@
{ config, pkgs, lib, inputs, system, ... }:
let cfg = config.sydnix.steam;
in {
options.sydnix.steam = {
enable = lib.mkEnableOption "Steam";
};
config = lib.mkIf cfg.enable {
sydnix.impermanence.directories = [
# Steam has a number of mysterious issues when its state directories are
# symlinks. Most bizarrely, I've experienced complementory issues;
# everything breaks when I use bind-mounts, but not
# symlinks. Thanks, Valve!
#
# https://github.com/ValveSoftware/steam-for-linux/issues/10552
{ directory = ".local/share/Steam"; method = "symlink"; }
{ directory = ".steam"; method = "symlink"; }
];
home.packages = [
pkgs.protonup-qt
];
};
}

View File

@@ -40,6 +40,7 @@ in {
};
config = lib.mkIf cfg.enable {
# TODO: sydnix.syncthing module
sydnix.impermanence.directories =
let xdg-state-dir =

View File

@@ -8,6 +8,10 @@ in {
programs.bash = {
enable = true;
};
home.shellAliases = {
nix2json = "nix eval --impure --json --file -";
};
};
}

View File

@@ -0,0 +1,33 @@
{ config, lib, pkgs, ... }:
let cfg = config.sydnix.users.crumb.discord;
in {
options.sydnix.users.crumb.discord = {
enable = lib.mkEnableOption "Discord";
};
config = lib.mkIf cfg.enable {
sydnix.discord.enable = true;
programs.nixcord = {
config = {
themeLinks = [
# Compact++ (Default) — Themes Discord to look more like a typical IRC
# client.
"https://gitlab.com/api/v4/projects/52800868/snippets/3628352/files/main/compactplusplus-default.theme.css/raw"
];
plugins = {
ircColors.enable = true;
};
};
vesktop = {
state.firstLaunch = false;
settings = {
discordBranch = "stable";
minimizeToTray = false;
arRPC = true;
};
};
};
};
}

View File

@@ -4,12 +4,12 @@ let cfg = config.sydnix.users.crumb.emacs;
in {
options.sydnix.users.crumb.emacs.enable =
lib.mkEnableOption ''Emacs, à la crumb'';
config = lib.mkIf cfg.enable
(let
emacsBasePackage = pkgs'.emacs-unstable-pgtk;
# Hard-coded path. }:\
emacsConfigDir =
"/persist/dots/modules/home/users/${config.home.username}/emacs";
config = lib.mkIf cfg.enable
(let
emacsBasePackage = pkgs'.emacs-unstable-pgtk;
# Hard-coded path. }:\
emacsConfigDir =
"/persist/dots/modules/home/users/${config.home.username}/emacs";
# Create a new instance of nixpkgs with emacs-overlay applied. This is a
# little unorthodox, but we do it
@@ -17,116 +17,119 @@ in {
# codebase, I want everything Emacs to stay in this file;
# 2. and, there's simply no need to leak emacs-overlay's packages into the
# global nixpkgs instance when nothing else is using it!
pkgs' = import inputs.nixpkgs {
system = args.system;
overlays = [ inputs.emacs-overlay.overlays.emacs ];
};
pkgs' = import inputs.nixpkgs {
system = args.system;
overlays = [ inputs.emacs-overlay.overlays.emacs ];
};
emacsDataDir = "${config.xdg.dataHome}/emacs";
emacsCacheDir = "${emacsDataDir}/cache";
straightBaseDir = "${emacsDataDir}/straight";
emacsDataDir = "${config.xdg.dataHome}/emacs";
emacsCacheDir = "${emacsDataDir}/cache";
straightBaseDir = "${emacsDataDir}/straight";
fontPackages = [
pkgs.julia-mono
pkgs.nerd-fonts.victor-mono
pkgs.ibm-plex
];
fontPackages = [
pkgs.julia-mono
pkgs.nerd-fonts.victor-mono
pkgs.ibm-plex
];
my-aspell = pkgs.aspellWithDicts
(dicts: with dicts; [
en en-computers en-science
]);
my-aspell = pkgs.aspellWithDicts
(dicts: with dicts; [
en en-computers en-science
]);
my-emacs =
let ewp = (pkgs.emacsPackagesFor emacsBasePackage).emacsWithPackages
(epkgs: with epkgs; [
jinx
pdf-tools
treesit-grammars.with-all-grammars
]);
in pkgs.symlinkJoin {
name = "sydmacs";
paths = [ ewp ];
nativeBuildInputs = [ pkgs.makeWrapper ];
buildInputs = [
pkgs.git # Dependency of Straight.el.
my-aspell
pkgs.direnv
];
postBuild = ''
find "$out/bin" -name emacs -or -name "emacs-*" \
| while IFS= read -r emacs; do
echo "emacs: $emacs"
wrapProgram "$emacs" \
--add-flags "--init-directory \"${emacsConfigDir}\"" \
--set EMACS_STRAIGHT_BASE_DIR "${straightBaseDir}" \
--set EMACS_CACHE_DIR "${emacsCacheDir}" \
--set EMACS_DATA_DIR "${emacsDataDir}" \
--prefix PATH : "${pkgs.git}/bin" \
--prefix PATH : "${my-aspell}/bin" \
--prefix PATH : "${pkgs.direnv}/bin" \
--prefix PATH : "${pkgs.texliveFull}/bin" \
--set ASPELL_CONF "dict-dir ${my-aspell}/lib/aspell"
done
'';
meta = emacsBasePackage.meta;
version = emacsBasePackage.version;
};
my-emacs =
let ewp = (pkgs.emacsPackagesFor emacsBasePackage).emacsWithPackages
(epkgs: with epkgs; [
jinx
pdf-tools
treesit-grammars.with-all-grammars
]);
in pkgs.symlinkJoin {
name = "sydmacs";
paths = [ ewp ];
nativeBuildInputs = [ pkgs.makeWrapper ];
buildInputs = [
pkgs.git # Dependency of Straight.el.
my-aspell
pkgs.direnv
];
postBuild = ''
find "$out/bin" -name emacs -or -name "emacs-*" \
| while IFS= read -r emacs; do
echo "emacs: $emacs"
wrapProgram "$emacs" \
--add-flags "--init-directory \"${emacsConfigDir}\"" \
--set EMACS_STRAIGHT_BASE_DIR "${straightBaseDir}" \
--set EMACS_CACHE_DIR "${emacsCacheDir}" \
--set EMACS_DATA_DIR "${emacsDataDir}" \
--prefix PATH : "${pkgs.git}/bin" \
--prefix PATH : "${my-aspell}/bin" \
--prefix PATH : "${pkgs.direnv}/bin" \
--prefix PATH : "${pkgs.texliveFull}/bin" \
--set ASPELL_CONF "dict-dir ${my-aspell}/lib/aspell"
done
'';
meta = emacsBasePackage.meta;
version = emacsBasePackage.version;
};
emacsclient-or-emacs = pkgs.writeShellScriptBin "emacsclient-or-emacs" ''
emacsclient --alternate-editor=${config.programs.emacs.finalPackage}/bin/emacs "$@"
'';
in {
programs.emacs = {
enable = true;
package = my-emacs;
};
emacsclient-or-emacs = pkgs.writeShellScriptBin "emacsclient-or-emacs" ''
emacsclient --alternate-editor=${config.programs.emacs.finalPackage}/bin/emacs "$@"
'';
in {
programs.emacs = {
enable = true;
package = my-emacs;
};
sydnix.impermanence.cache.directories =
sydnix.impermanence.cache.directories =
# Impermanence expects the path to be relative to ~.
map (lib.removePrefix config.home.homeDirectory) [
straightBaseDir
emacsCacheDir
emacsDataDir
];
map (lib.removePrefix config.home.homeDirectory) [
straightBaseDir
emacsCacheDir
emacsDataDir
];
# Set emacsclient as the default editor for the time being.
home.sessionVariables =
let e = "${emacsclient-or-emacs}/bin/emacsclient-or-emacs";
in {
"EDITOR" = e;
"VISUAL" = e;
};
home.sessionVariables =
let e = "${emacsclient-or-emacs}/bin/emacsclient-or-emacs";
in {
"EDITOR" = e;
"VISUAL" = e;
};
home.file =
let default =
lib.removePrefix "${config.home.homeDirectory}/"
"${straightBaseDir}/straight/versions/default.el";
in {
${default}.source =
config.lib.file.mkOutOfStoreSymlink
"${emacsConfigDir}/straight-lockfile.el";
};
home.file =
let default =
lib.removePrefix "${config.home.homeDirectory}/"
"${straightBaseDir}/straight/versions/default.el";
in {
${default}.source =
config.lib.file.mkOutOfStoreSymlink
"${emacsConfigDir}/straight-lockfile.el";
};
home.packages = [
emacsclient-or-emacs
] ++ fontPackages;
home.packages = [
emacsclient-or-emacs
] ++ fontPackages;
# There's probably a better place to put this, but the current setup demands
# Fontconfig for Emacs to find my fonts.
fonts.fontconfig.enable = true;
fonts.fontconfig.enable = true;
# TODO: Make sure this is using the right package for Emacs...
services.emacs = {
enable = true;
services.emacs = {
enable = true;
# Generate a desktop entry for emacsclient.
client.enable = true;
};
client.enable = true;
};
# We do this ourselves.
stylix.targets.emacs.enable = false;
home.shellAliases = {
e = "emacsclient-or-emacs";
ec = "emacsclient";
em = "emacs";
};
});
});
}

View File

@@ -0,0 +1 @@
[cool-deer goes here]

View File

@@ -10,8 +10,11 @@
(setq use-package-compute-statistics t)
(setq gc-cons-threshold
;; (6 gibibytes)
(* 6 (expt 1024 3)))
;; (8 gibibytes)
(* 8 (expt 1024 3)))
(set-frame-parameter nil 'drag-with-header-line t)
(set-frame-parameter nil 'undecorated t)
;; By default, Emacs will cache compilation artifacts in my personal config
;; directory — I'm not keen on that! Redirect it to a dedicated cache directory.

View File

@@ -0,0 +1,9 @@
;;; syd-lang-kdl.el -*- lexical-binding: t; -*-
(use-package kdl-ts-mode
:mode "\\.kdl\\'"
:straight (:type git
:host github
:repo "dataphract/kdl-ts-mode"))
(provide 'syd-lang-kdl)

View File

@@ -13,8 +13,16 @@
(nix-repl)
(current-buffer))
(evil-define-text-object syd-nix-obj-outer-binding (count _beg _end _type)
"TODO"
:type 'inclusive
(let* ((cleanup-p (memq evil-this-operator '(evil-delete)))
(node (treesit-thing-at-point "binding" "nested")))
(list (treesit-node-start node)
(treesit-node-end node))))
(use-package nix-mode
:mode "\\.nix\\'"
;; :mode "\\.nix\\'"
:init
(add-to-list 'auto-mode-alist
(cons (rx "/flake.lock'")
@@ -24,17 +32,30 @@
:config
(add-hook 'nix-mode-hook #'lsp)
(set-popup-rule! (rx bol "*nixos-options-doc*" eol) :ttl 0 :quit t)
(set-repl-handler! 'nix-mode #'syd-nix-open-nix-repl)
(set-repl-handler! '(nix-mode nix-ts-mode) #'syd-nix-open-nix-repl)
(dolist (c '(?- ?_))
(modify-syntax-entry c "w" nix-mode-syntax-table))
;; Inform Smartparens and Evil-surround of Nix's alternative string syntax.
(with-eval-after-load 'smartparens
(sp-local-pair 'nix-mode "''" "''"))
(syd-add-hook 'nix-mode-hook
(sp-local-pair '(nix-mode nix-ts-mode) "''" "''"))
(syd-add-hook '(nix-mode-hook nix-ts-mode-hook)
(defun syd-nix--configure-evil-surround-h ()
(with-eval-after-load 'evil-surround
(push '(?Q . ("''" . "''"))
evil-surround-pairs-alist)))))
(use-package nix-ts-mode
:mode "\\.nix\\'"
:config
(require 'nix-mode)
(general-def
:keymaps 'nix-ts-mode-map
:states '(visual operator)
"ad" #'syd-nix-obj-outer-binding)
(syd-add-hook 'nix-ts-mode-hook
(defun syd-nix-set-syntax-table-h ()
"Set the syntax table in `nix-ts-mode' buffers to `nix-mode-syntax-table'."
(set-syntax-table nix-mode-syntax-table))))
(provide 'syd-lang-nix)

View File

@@ -352,14 +352,14 @@ interactive call to `eval-expression' is stored.")
(advice-add #'evil-indent
:around #'syd-evil-dont-move-point-a))
(use-package evil-leap
:hook (on-first-input . evil-leap-mode)
:load-path "/home/crumb/src/evil-leap"
:straight nil
;; :straight (:type git
;; :host gitlab
;; :repo "msyds/evil-leap")
:config
(evil-leap-install-default-keybindings))
;(use-package evil-leap
; :hook (on-first-input . evil-leap-mode)
; :load-path "/home/crumb/src/evil-leap"
; :straight nil
; ;; :straight (:type git
; ;; :host gitlab
; ;; :repo "msyds/evil-leap")
; :config
; (evil-leap-install-default-keybindings))
(provide 'syd-evil)

View File

@@ -2,6 +2,7 @@
(file-name-concat user-emacs-directory "modules" "lang"))
(require 'syd-lang-agda)
(require 'syd-lang-kdl)
(require 'syd-lang-emacs-lisp)
(require 'syd-lang-clojure)
(require 'syd-lang-nix)

View File

@@ -30,7 +30,8 @@
(use-package emacs
:custom ((initial-scratch-message
(with-temp-buffer
(insert-file-contents "/persist/vault/crumb/cool-deer.org")
(insert-file-contents (file-name-concat user-emacs-directory
"cool-deer.org"))
(buffer-string)))
;; Initial major mode for scratch buffer.
(initial-major-mode 'fundamental-mode)

View File

@@ -7,6 +7,38 @@ in {
lib.mkEnableOption "Firefox, à la crumb";
config = lib.mkIf cfg.enable {
# We are very granular about which Firefox files are persisted. While there
# is a lot of mutable state (e.g. search history), it is mixed with less
# mutable configuration that we force ourselves to manage declaratively.
#
# For an overview of important files in the profile directory, see
# https://support.mozilla.org/en-US/kb/recovering-important-data-from-an-old-profile.
sydnix.impermanence =
{ directories = [ ".mozilla/firefox/msyds" ]; };
# let p = ".mozilla/firefox/msyds";
# in {
# files = [
# # Passwords
# "${p}/key4.db"
# "${p}/logins.json"
# "${p}/logins-backup.json"
# # Site-specific permissions
# "${p}/permissions.sqlite"
# # Bookmarks, downloads and browsing history
# "${p}/places.sqlite"
# # Cached favicons for use in the history menu.
# "${p}/favicons.sqlite"
# # Cookies
# "${p}/cookies.sqlite"
# # Security certificate settings
# "${p}/cert9.db"
# # Form history (for completions)
# "${p}/formhistory.sqlite"
# ];
# };
stylix.targets.firefox.profileNames = [ "msyds" ];
programs.firefox = {
enable = true;
@@ -80,6 +112,7 @@ in {
overlays = [ inputs.nur.overlays.default ];
};
in
# https://nur.nix-community.org/repos/rycee/
with pkgs'.nur.repos.rycee.firefox-addons; [
ublock-origin
darkreader
@@ -87,12 +120,68 @@ in {
vimium
kagi-search
duckduckgo-privacy-essentials
edit-with-emacs
textern
copy-as-org-mode
clearurls
sidebery
adaptive-tab-bar-colour
adnauseam
# tree-style-tab
# tab-unload-for-tree-style-tab
# tst-tab-search
# tst-more-tree-commands
# tst-lock-tree-collapsed
# tst-fade-old-tabs
# tst-bookmarks-subpanel
# move-unloaded-tabs-for-tst
tab-stash
unpaywall
sourcegraph
sponsorblock
cookies-txt
copy-selected-tabs-to-clipboard
copy-link-text
df-youtube
];
};
# https://github.com/mbnuqw/sidebery/wiki/Firefox-Styles-Snippets-(via-userChrome.css)
userChrome = ''
/* Hide the tab bar in favour of that provided by the tree-style tabs
* addon */
/**
* Dynamic Horizontal Tabs Toolbar (with animations)
* sidebar.verticalTabs: false (with native horizontal tabs)
*/
#main-window #TabsToolbar > .toolbar-items {
overflow: hidden;
transition: height 0.3s 0.3s !important;
}
/* Default state: Set initial height to enable animation */
#main-window #TabsToolbar > .toolbar-items { height: 3em !important; }
#main-window[uidensity="touch"] #TabsToolbar > .toolbar-items { height: 3.35em !important; }
#main-window[uidensity="compact"] #TabsToolbar > .toolbar-items { height: 2.7em !important; }
/* Hidden state: Hide native tabs strip */
#main-window[titlepreface*="\200b"] #TabsToolbar > .toolbar-items { height: 0 !important; }
/* Hidden state: Fix z-index of active pinned tabs */
#main-window[titlepreface*="\200b"] #tabbrowser-tabs { z-index: 0 !important; }
/* Hidden state: Hide window buttons in tabs-toolbar */
#main-window[titlepreface*="\200b"] #TabsToolbar .titlebar-spacer,
#main-window[titlepreface*="\200b"] #TabsToolbar .titlebar-buttonbox-container {
display: none !important;
}
/* [Optional] Uncomment block below to show window buttons in nav-bar
* (maybe, I didn't test it on non-linux-i3wm env) */
/* #main-window[titlepreface*="\200b"] #nav-bar > .titlebar-buttonbox-container,
#main-window[titlepreface*="\200b"] #nav-bar > .titlebar-buttonbox-container > .titlebar-buttonbox {
display: flex !important;
} */
/* [Optional] Uncomment one of the line below if you need space near
* window buttons */
/* #main-window[titlepreface*="\200b"] #nav-bar > .titlebar-spacer[type="pre-tabs"] { display: flex !important; } */
/* #main-window[titlepreface*="\200b"] #nav-bar > .titlebar-spacer[type="post-tabs"] { display: flex !important; } */
'';
search = {
# Override non-declared settings.
force = true;
@@ -101,6 +190,14 @@ in {
default = "Kagi";
privateDefault = "DuckDuckGo";
engines = {
"Kagi" = {
urls = [{
template = "https://kagi.com/search";
params = [
{ name = "q"; value = "{searchTerms}"; }
];
}];
};
"Nixpkgs" = {
urls = [{
template = "https://search.nixos.org/packages";
@@ -132,9 +229,13 @@ in {
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.urlbar.sponsoredTopSites" = false;
"services.sync.prefs.sync.browser.newtabpage.activity-stream.showSponsored"
= false;
= false;
"services.sync.prefs.sync.browser.newtabpage.activity-stream.showSponsoredTopSites"
= false;
= false;
"browser.sessionstore.persist_closed_tabs_between_sessions" = true;
"browser.download.always_ask_before_handling_new_types" = true;
# Enable userChrome.css.
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
};
};
};

View File

@@ -0,0 +1,13 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sydnix.users.crumb.ghostty;
in {
options.sydnix.users.crumb.ghostty.enable =
lib.mkEnableOption "Ghostty, à la crumb";
config = lib.mkIf cfg.enable {
programs.ghostty.enable = true;
};
}

View File

@@ -30,7 +30,10 @@ in {
# mpdscribble uses our password files, so it is imperative that the service
# runs only after said password files are brought into existence. }:)
systemd.user.services.mpdscribble.Unit.After = [ "sops-nix.service" ];
systemd.user.services.mpdscribble.Unit = {
After = [ "sops-nix.service" ];
WantedBy = [ "mpd.service" ];
};
};
}

View File

@@ -0,0 +1,209 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sydnix.users.crumb.niri;
in {
options.sydnix.users.crumb.niri = {
enable = lib.mkEnableOption "Niri, à la crumb";
wallpaper = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = config.stylix.image;
};
# xwayland-satellite implements rootless Xwayland in a separate application,
# without the host compositor's involvement. It makes X11 windows appear as
# normal windows, just like a native Xwayland integration. While it is still
# somewhat experimental, it handles a lot of applications correctly, like
# Steam, games and Discord.
xwayland-satellite.enable =
lib.mkEnableOption "xwayland-satellite starting with Niri"
// { default = true; };
};
config = lib.mkIf cfg.enable {
stylix.targets.swaylock.enable = true;
programs.niri = {
# Activates some Nixpkgs patches to help run Electron applications under
# Wayland.
settings = {
environment."NIXOS_OZONE_WL" = "1";
environment."DISPLAY" = ":0";
spawn-at-startup =
[{ command = [ "${pkgs.swaynotificationcenter}/bin/swaync" ]; }]
++ lib.optional
cfg.xwayland-satellite.enable
{ command = [ "${pkgs.xwayland-satellite}/bin/xwayland-satellite" ]; }
++ lib.optional
(! builtins.isNull cfg.wallpaper)
{ command = [ "${pkgs.wbg}/bin/wbg" "${cfg.wallpaper}" ]; };
input = {
keyboard.xkb = {
layout = "us";
options = "ctrl:swapcaps,compose:menu";
};
mouse = {
accel-speed = -0.5;
accel-profile = "flat";
};
focus-follows-mouse.enable = true;
};
outputs."DP-1" = {
mode.width = 2560;
mode.height = 1440;
mode.refresh = 144.0;
scale = 1;
};
layout = {
gaps = 8;
# center-focused-column = "always";
center-focused-column = "on-overflow";
preset-column-widths = [
{ proportion = 1.0 / 3.0; }
{ proportion = 1.0 / 2.0; }
{ proportion = 2.0 / 3.0; }
];
default-column-width.proportion = 0.5;
# default-column-width.proportion = {};
focus-ring = {
enable = false;
width = 2;
};
border = {
enable = true;
width = 2;
# Override Niri's Stylix integration. Default uses Crystal Blue; we
# override it with Old White.
active.color = config.lib.stylix.colors.withHashtag.base06;
};
shadow = {
enable = true;
softness = 30;
spread = 5;
offset.x = 5;
offset.y = 5;
};
};
prefer-no-csd = true;
screenshot-path = "~/Pictures/Screenshots/%Y-%m-%d %H-%M-%S.png";
cursor = {
theme = "default";
size = 24;
};
window-rules = [
{
# This regular expression is intentionally made as specific as
# possible, since this is the default config, and we want no false
# positives. You can get away with just app-id="wezterm" if you
# want.
matches = [
{ app-id = "^org\\.wezfurlong\\.wezterm$"; }
];
default-column-width = {};
}
{
# Open the Firefox picture-in-picture player as floating by default.
matches = [
{ app-id = "firefox$"; title = "^Picture-in-Picture$"; }
];
open-floating = true;
}
{
# Enable rounded corners for all windows.
geometry-corner-radius =
let r = 8.0;
in {
bottom-left = r;
top-left = r;
bottom-right = r;
top-right = r;
};
clip-to-geometry = true;
}
];
binds = with config.lib.niri.actions; {
"Mod+Q".action.close-window = [];
"Mod+Shift+Q".action.quit = [];
"Mod+Ctrl+L".action.spawn = ["${pkgs.swaylock}/bin/swaylock"];
"Mod+D".action.spawn = ["${pkgs.fuzzel}/bin/fuzzel"];
"Mod+Shift+Slash".action.show-hotkey-overlay = [];
# Powers off the monitors. To turn them back on, do any input like
# moving the mouse or pressing any other key.
"Mod+Shift+P".action.power-off-monitors = [];
"Mod+BracketLeft".action.consume-or-expel-window-left = [];
"Mod+BracketRight".action.consume-or-expel-window-right = [];
"Mod+Comma".action.consume-window-into-column = [];
"Mod+Period".action.expel-window-from-column = [];
"Mod+Minus".action.set-column-width = ["-10%"];
"Mod+Equal".action.set-column-width = ["+10%"];
"Mod+Shift+Minus".action.set-window-height = ["-10%"];
"Mod+Shift+Equal".action.set-window-height = ["+10%"];
"Mod+C".action.center-column = [];
"Mod+M".action.maximize-column = [];
"Mod+Shift+M".action.fullscreen-window = [];
# Currently unreleased }:(.
# "Mod+Ctrl+M".action.toggle-windowed-fullscreen = [];
"Mod+Shift+S".action.screenshot = [];
"Print".action.screenshot-screen = [];
"Mod+Print".action.screenshot-window = [];
"Mod+X".action.spawn = [
"emacsclient-or-emacs"
"-ce"
"(eshell t)"
];
"Mod+Shift+F".action.toggle-window-floating = [];
"Mod+F".action.switch-focus-between-floating-and-tiling = [];
"Mod+Shift+T".action.toggle-column-tabbed-display = [];
"Alt+Tab".action.focus-window-previous = [];
"Mod+H".action.focus-column-left = [];
"Mod+J".action.focus-window-down = [];
"Mod+K".action.focus-window-up = [];
"Mod+L".action.focus-column-right = [];
"Mod+Shift+H".action.move-column-left = [];
"Mod+Shift+J".action.move-window-down = [];
"Mod+Shift+K".action.move-window-up = [];
"Mod+Shift+L".action.move-column-right = [];
"Mod+1".action.focus-workspace = [1];
"Mod+2".action.focus-workspace = [2];
"Mod+3".action.focus-workspace = [3];
"Mod+4".action.focus-workspace = [4];
"Mod+5".action.focus-workspace = [5];
"Mod+6".action.focus-workspace = [6];
"Mod+7".action.focus-workspace = [7];
"Mod+8".action.focus-workspace = [8];
"Mod+9".action.focus-workspace = [9];
"Mod+Shift+1".action.move-column-to-workspace = [1];
"Mod+Shift+2".action.move-column-to-workspace = [2];
"Mod+Shift+3".action.move-column-to-workspace = [3];
"Mod+Shift+4".action.move-column-to-workspace = [4];
"Mod+Shift+5".action.move-column-to-workspace = [5];
"Mod+Shift+6".action.move-column-to-workspace = [6];
"Mod+Shift+7".action.move-column-to-workspace = [7];
"Mod+Shift+8".action.move-column-to-workspace = [8];
"Mod+Shift+9".action.move-column-to-workspace = [9];
"Mod+Shift+R".action.switch-preset-window-height = [];
"Mod+Ctrl+R".action.reset-window-height = [];
"XF86AudioRaiseVolume".action =
spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1+";
"XF86AudioLowerVolume".action =
spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1-";
};
};
};
};
}

View File

@@ -0,0 +1,27 @@
{ config, lib, pkgs, ... }:
let cfg = config.sydnix.users.crumb.waybar;
in {
options.sydnix.users.crumb.waybar = {
enable = lib.mkEnableOption "Waybar, à la crumb";
};
config = lib.mkIf cfg.enable {
home.packages = [
pkgs.martian-mono
pkgs.nerd-fonts.symbols-only
];
stylix.targets.waybar.enable = false;
programs.waybar = {
enable = true;
style = ./waybar/src/waybar.css;
systemd.enable = true;
systemd.target = "niri.service";
settings.sydbar = import ./waybar/src/waybar.nix {
niri-gaps = config.programs.niri.settings.layout.gaps;
inherit pkgs lib;
};
};
};
}

View File

@@ -0,0 +1 @@
use nix

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p inotify-tools waybar mako swaynotificationcenter libnotify pavucontrol
# This script will watch waybar.nix and compile it to /tmp/waybar.json. Offers
# a much tighter feedback loop than that offered by the Nix module.
# Inotify will sometimes double-fire events. We avoid unnecessary recompilation
# by putting a cooldown on builds.
last_build=0
waybar_pid=""
update () {
last_build="$(date +%s)"
if [ ! -z "$waybar_pid" ]; then
kill "$waybar_pid"
echo >&2 "Killed waybar..."
waybar_pid=""
fi
echo >&2 "Building waybar.json..."
nix eval --impure --json --expr "import ./waybar.nix {}" \
> /tmp/waybar.json \
&& echo >&2 "Built waybar.json!"
waybar -c waybar.json -b sydbar -s waybar.css 2>&1 >/dev/null &
waybar_pid=$!
echo >&2 "Started Waybar [$waybar_pid]"
}
update
inotifywait -me modify waybar.nix waybar.css cycle_notifications.clj |
while read _ _ file_name; do
ct="$(date +%s)"
if (( ct - last_build < 1 )); then
echo >&2 "Ignoring event (on cooldown)"
else
update
fi
done

View File

@@ -0,0 +1,14 @@
{ pkgs ? import <nixpkgs> {}
}:
pkgs.mkShell {
packages = with pkgs; [
inotify-tools
waybar
mako
swaynotificationcenter
libnotify
babashka
pavucontrol
];
}

View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
check() {
command -v "$1" 1>/dev/null
}
check sensors || exit
data="$(sensors coretemp-isa-0000 | sed 's/+//g')"
package="$(echo "$data" | awk -e '/Package/ {print $4}')"
coretemp="$(echo "$data" | awk -e '/Core/ {print $3}')"
tooltip="<b>Core Temp: $package </b>\n"
# "format-icons" : [ "", "", "", "", "" ] ,
tempint=''${package%.*}
temp="<b>''${tempint}󰔄</b>"
# icon=""
class="cool"
[ "$tempint" -gt 50 ] && {
# icon=""
class="normal"
}
[ "$tempint" -gt 70 ] && {
# icon=" "
class="warm"
}
[ "$tempint" -gt 85 ] && {
# icon=" "
class="warn"
}
[ "$tempint" -gt 95 ] && {
# icon=" "
class="critical"
}
j=0
for i in $coretemp; do
tooltip+="Core $j: $i\n"
((j = j + 1))
done
tooltip="''${tooltip::-2}"
cat <<EOF
{"text":"$temp","tooltip":"$tooltip", "class": "$class"}
EOF

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bb
(ns cycle-notifications
(:require [babashka.process :as p]
[clojure.string :as str]
[cheshire.core :as json]))
(defn get-mode []
(case (:out (p/shell {:out :string} "swaync-client -D"))
"true" :dnd
"false" :default))
#_
(get-mode)
(defn toggle! []
(p/shell {:out nil} "swaync-client -d")
;; Update Waybar.
(p/shell "pkill -SIGRTMIN+2 waybar"))
(defn status []
(-> (case (:out (p/shell {:out :string} "swaync-client -D"))
"false" {:text "" :tooltip "Notify"}
"true" {:text "" :tooltip "Do not disturb"})
json/generate-string
println))
(defn -main [& args]
(case (first args)
"toggle" (toggle!)
nil (status)))

View File

@@ -0,0 +1,312 @@
/* !!!!!!! Shamelessly stolen from Niksingh710 */
/* https://github.com/niksingh710/gdots/blob/d97c544a9d73a34d12770ba20b6b80d14e964aa1/.config/waybar/style.css */
@define-color fuji-white #DCD7BA;
@define-color old-white #C8C093;
@define-color sumi-ink-0 #16161D;
@define-color sumi-ink-1 #1F1F28;
@define-color sumi-ink-2 #2A2A37;
@define-color sumi-ink-3 #363646;
@define-color sumi-ink-4 #54546D;
@define-color wave-blue-1 #223249;
@define-color wave-blue-2 #2D4F67;
@define-color winter-green #2B3328;
@define-color winter-yellow #49443C;
@define-color winter-red #43242B;
@define-color winter-blue #252535;
@define-color autumn-green #76946A;
@define-color autumn-red #C34043;
@define-color autumn-yellow #DCA561;
@define-color samurai-red #E82424;
@define-color ronin-yellow #FF9E3B;
@define-color wave-aqua-1 #6A9589;
@define-color dragon-blue #658594;
@define-color fuji-gray #727169;
@define-color spring-violet-1 #938AA9;
@define-color oni-violet #957FB8;
@define-color crystal-blue #7E9CD8;
@define-color spring-violet-2 #9CABCA;
@define-color spring-blue #7FB4CA;
@define-color light-blue #A3D4D5;
@define-color wave-aqua-2 #7AA89F;
@define-color spring-green #98BB6C;
@define-color boat-yellow-1 #938056;
@define-color boat-yellow-2 #C0A36E;
@define-color carp-yellow #E6C384;
@define-color sakura-pink #D27E99;
@define-color wave-red #E46876;
@define-color peach-red #FF5D62;
@define-color surimi-orange #FFA066;
@define-color background @sumi-ink-1;
@define-color foreground @fuji-white;
@define-color border @sumi-ink-4;
@define-color active @old-white;
*
{ font-size: 16px
; font-family: "Symbols Nerd Font"
; min-width: 8px
; min-height: 0px
; border: none
; border-radius: 0
; box-shadow: none
; text-shadow: none
; padding: 0px
}
window#waybar
{ transition-property: background-color
; transition-duration: 0.5s
; border-radius: 8px
; border: 2px solid @active
; background: @background
; background: alpha(@background, 0.7)
; color: lighter(@active)
}
menu,
tooltip
{ border-radius: 8px
; padding: 2px
; border: 1px solid lighter(@active)
; background: alpha(@background, 0.6)
; color: lighter(@active)
}
menu label,
tooltip label
{ font-size: 14px
; color: lighter(@active)
}
#submap,
#tray>.needs-attention
{ animation-name: blink-active
; animation-duration: 1s
; animation-timing-function: linear
; animation-iteration-count: infinite
; animation-direction: alternate
}
.modules-right
{ margin: 0px 6px 6px 6px
; border-radius: 4px
; background: alpha(@background, 0.4)
; color: lighter(@active)
}
.modules-left
{ transition-property: background-color
; transition-duration: 0.5s
; margin: 6px 6px 6px 6px
; border-radius: 4px
; background: alpha(@background, 0.4)
; color: lighter(@active)
}
#gcpu,
#custom-github,
#memory,
#disk,
#together,
#submap,
#custom-weather,
#custom-recorder,
#connection,
#cnoti,
#brightness,
#power,
#custom-updates,
#tray,
#audio,
#privacy,
#sound
{ border-radius: 4px
; margin: 2px 2px 4px 2px
; background: alpha(darker(@active), 0.3)
}
#custom-notifications
{ padding-left: 4px
}
#custom-hotspot,
#custom-github,
#custom-notifications
{ font-size: 14px
}
#custom-hotspot
{ padding-right: 2px
}
#custom-vpn,
#custom-hotspot
{ background: alpha(darker(@active), 0.3)
}
#privacy-item
{ padding: 6px 0px 6px 6px
}
#gcpu
{ padding: 8px 0px 8px 0px
}
#custom-cpu-icon
{ font-size: 25px
}
#custom-cputemp,
#disk,
#memory,
#cpu
{ font-size: 14px
; font-weight: bold
}
#custom-github
{ padding-top: 2px
; padding-right: 4px
}
#custom-dmark
{ color: alpha(@foreground, 0.3)
}
#submap
{ margin-bottom: 0px
}
#workspaces
{ margin: 0px 2px
; padding: 4px 0px 0px 0px
; border-radius: 8px
}
#workspaces button
{ transition-property: background-color
; transition-duration: 0.5s
; color: @foreground
; background: transparent
; border-radius: 4px
; color: alpha(@foreground, 0.3)
}
#workspaces button.urgent
{ font-weight: bold
; color: @foreground
}
#workspaces button.active
{ padding: 4px 2px
; background: alpha(@active, 0.4)
; color: lighter(@active)
; border-radius: 4px
}
#network.wifi
{ padding-right: 4px
}
#submap
{ min-width: 0px
; margin: 4px 6px 4px 6px
}
#custom-weather,
#tray
{ padding: 4px 0px 4px 0px
}
#bluetooth
{ padding-top: 2px
}
#battery
{ border-radius: 8px
; padding: 4px 0px
; margin: 4px 2px 4px 2px
}
#battery.discharging.warning
{ animation-name: blink-yellow
; animation-duration: 1s
; animation-timing-function: linear
; animation-iteration-count: infinite
; animation-direction: alternate
}
#battery.discharging.critical
{ animation-name: blink-red
; animation-duration: 1s
; animation-timing-function: linear
; animation-iteration-count: infinite
; animation-direction: alternate
}
#clock
{ font-weight: bold
; padding: 4px 2px 2px 2px
; font-family: "MartianMono"
}
#pulseaudio.mic
{ border-radius: 4px
; color: @background
; background: alpha(darker(@foreground), 0.6)
; padding-left: 4px
}
#backlight-slider slider,
#pulseaudio-slider slider
{ background-color: transparent
; box-shadow: none
}
#backlight-slider trough,
#pulseaudio-slider trough
{ margin-top: 4px
; min-width: 6px
; min-height: 60px
; border-radius: 8px
; background-color: alpha(@background, 0.6)
}
#backlight-slider highlight,
#pulseaudio-slider highlight
{ border-radius: 8px
; background-color: lighter(@active)
}
#bluetooth.discoverable,
#bluetooth.discovering,
#bluetooth.pairable
{ border-radius: 8px
; animation-name: blink-active
; animation-duration: 1s
; animation-timing-function: linear
; animation-iteration-count: infinite
; animation-direction: alternate
}
@keyframes blink-active
{ to
{ background-color: @active
; color: @foreground
}
}
@keyframes blink-red
{ to
{ background-color: @samurai-red
; color: @foreground
}
}
@keyframes blink-yellow
{ to
{ background-color: @autumn-yellow
; color: @foreground
}
}

View File

@@ -0,0 +1,485 @@
# !!!!!! Shamelessly stolen from Niksingh710's config!
# https://github.com/niksingh710/gdots/blob/d97c544a9d73a34d12770ba20b6b80d14e964aa1/.config/waybar/bars/top.jsonc
{ niri-gaps ? 8
, pkgs ? import <nixpkgs> {}
, lib ? pkgs.lib
}:
let
cputemp = pkgs.writeShellApplication {
name = "cputemp";
runtimeInputs = with pkgs; [
lm_sensors
];
text = builtins.readFile ./cputemp;
};
cycle-notifications = pkgs.writeShellApplication {
name = "cycle-notifications";
runtimeInputs = with pkgs; [
swaynotificationcenter
];
text = ''
${pkgs.babashka}/bin/bb -cp ${./.} -m cycle-notifications -- "$@"
'';
};
in {
layer = "top";
# Left margin will be provided by Niri's gaps.
margin =
let i = builtins.toString niri-gaps;
in "${i} ${i} ${i} 0";
modules-left = [
# "custom/updates"
"niri/workspaces"
"group/info"
];
modules-right = [
"custom/recorder"
"privacy"
"group/brightness"
"group/sound"
"group/together"
# "group/cnoti"
"tray"
# "group/power"
];
backlight = {
device = "intel_backlight";
format = "{icon}";
format-icons =
[ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ];
on-scroll-down = "brightnessctl s 5%-";
on-scroll-up = "brightnessctl s +5%";
smooth-scrolling-threshold = 1;
tooltip = true;
tooltip-format = "Brightness: {percent}% ";
};
"backlight/slider" = {
device = "intel_backlight";
max = 100;
min = 5;
orientation = "vertical";
};
battery = {
format = "{icon}";
format-charging = "<b>{icon} </b>";
format-full = "<span color='#82A55F'><b>{icon}</b></span>";
format-icons = [ "󰁻" "󰁼" "󰁾" "󰂀" "󰂂" "󰁹" ];
rotate = 270;
states = {
critical = 15;
good = 95;
warning = 30;
};
tooltip-format = "{timeTo} {capacity} % | {power} W";
};
bluetooth = {
format-connected = "<b></b>";
format-disabled = "";
format-off = "󰂲";
format-on = "";
on-click = "rofi-bluetooth -config ~/.config/rofi/menu.d/network.rasi -i";
tooltip-format = ''
{controller_alias} {controller_address}
{num_connections} connected'';
tooltip-format-connected = ''
{controller_alias} {controller_address}
{num_connections} connected
{device_enumerate}'';
tooltip-format-enumerate-connected = "{device_alias} {device_address}";
tooltip-format-enumerate-connected-battery =
"{device_alias} {device_address} {device_battery_percentage}%";
};
"bluetooth#status" = {
format-connected = "<b>{num_connections}</b>";
format-connected-battery =
"<small><b>{device_battery_percentage}%</b></small>";
format-disabled = "";
format-off = "";
format-on = "";
on-click = "rofi-bluetooth -config ~/.config/rofi/menu.d/network.rasi -i";
tooltip-format = ''
{controller_alias} {controller_address}
{num_connections} connected'';
tooltip-format-connected = ''
{controller_alias} {controller_address}
{num_connections} connected
{device_enumerate}'';
tooltip-format-enumerate-connected = "{device_alias} {device_address}";
tooltip-format-enumerate-connected-battery =
"{device_alias} {device_address} {device_battery_percentage}%";
};
clock = {
calendar = {
format = { today = "<span color='#a6e3a1'><b><u>{}</u></b></span>"; };
mode = "month";
mode-mon-col = 3;
on-click-right = "mode";
on-scroll = 1;
weeks-pos = "right";
};
format = ''
{:%H
%M}'';
tooltip-format = "<tt><small>{calendar}</small></tt>";
};
cpu = {
format = "<b>{usage}󱉸</b>";
on-click = "foot btop";
};
"custom/colorpicker" = {
exec = "colorpicker -j";
format = "{}";
interval = "once";
on-click = "sleep 1 && colorpicker";
return-type = "json";
signal = 1;
};
"custom/cpu-icon" = {
format = "󰻠";
tooltip = false;
};
"custom/cputemp" = {
exec = "${cputemp}/bin/cputemp";
format = "{}";
interval = 10;
return-type = "json";
};
"custom/dmark" = {
format = "";
tooltip = false;
};
"custom/github" = {
exec = "$HOME/.config/waybar/bin/github.sh";
format = "{}";
interval = 3600;
on-click =
"xdg-open https://github.com/notifications;pkill -RTMIN+9 waybar";
return-type = "json";
signal = 9;
};
"custom/hotspot" = {
exec = "~/.config/waybar/bin/hotspot";
format = "{} ";
interval = 5;
on-click = "hash wihotspot && wihotspot";
return-type = "json";
};
"custom/hyprkill" = {
exec = ''
echo '
Kill clients using hyrpctl kill'
'';
format = "{}";
interval = "once";
on-click = "sleep 1 && hyprctl kill";
};
"custom/hyprshade" = {
exec = "toggle-hyprshade status";
format = "{}";
on-click = "toggle-hyprshade";
return-type = "json";
signal = 11;
tooltip = true;
};
"custom/mark" = {
format = "";
tooltip = false;
};
"custom/notifications" = {
exec = "${cycle-notifications}/bin/cycle-notifications";
format = "<b>{}</b> ";
interval = "once";
on-click = "swaync-client -t";
on-click-right = "~/scratch/waybar/cycle-notifications toggle";
return-type = "json";
signal = 2;
};
"custom/recorder" = {
exec = "echo ''";
exec-if = "pgrep 'wl-screenrec'";
format = "{}";
interval = "once";
on-click = "recorder";
signal = 4;
tooltip = "false";
};
"custom/updates" = {
exec = "~/.config/waybar/bin/updatecheck";
exec-if = "exit 0";
format = "{}";
interval = 10800;
return-type = "json";
signal = 8;
};
"custom/vpn" = {
exec = "~/.config/waybar/bin/vpn";
format = "{} ";
interval = 5;
return-type = "json";
};
"custom/weather" = {
exec = ''
wttrbar --custom-indicator '{ICON}
<b>{temp_C}</b>' --location noida
'';
format = "{}";
interval = 3600;
return-type = "json";
tooltip = true;
};
disk = {
format = ''
<b> 󰋊
{percentage_used}󱉸</b>
'';
interval = 600;
path = "/";
};
"group/audio" = {
drawer = {
transition-duration = 500;
transition-left-to-right = false;
};
modules = [ "pulseaudio" "pulseaudio#mic" "pulseaudio/slider" ];
orientation = "inherit";
};
"group/bluetooth" = {
drawer = {
transition-duration = 500;
transition-left-to-right = true;
};
modules = [ "bluetooth" "bluetooth#status" ];
orientation = "inherit";
};
"group/brightness" = {
drawer = {
transition-duration = 500;
transition-left-to-right = false;
};
modules = [
"backlight"
"backlight/slider"
];
orientation = "inherit";
};
"group/cnoti" = {
modules = [ "custom/github" ];
orientation = "inherit";
};
"group/connection" = {
modules =
[ "custom/vpn" "custom/hotspot" "group/network" "group/bluetooth" ];
orientation = "inherit";
};
"group/gcpu" = {
modules = [ "custom/cpu-icon" "custom/cputemp" "cpu" ];
orientation = "inherit";
};
"group/info" = {
drawer = {
transition-duration = 500;
transition-left-to-right = false;
};
modules = [ "custom/dmark" "group/gcpu" "memory" "disk" ];
orientation = "inherit";
};
"group/network" = {
drawer = {
transition-duration = 500;
transition-left-to-right = true;
};
modules = [ "network" "network#speed" ];
orientation = "inherit";
};
"group/power" = {
drawer = {
transition-duration = 500;
transition-left-to-right = false;
};
modules = [ "battery" "power-profiles-daemon" ];
orientation = "inherit";
};
"group/sound" = {
modules = [ "group/audio" "custom/notifications" ];
orientation = "inherit";
};
"group/together" = {
modules = [
"group/utils"
"clock"
];
orientation = "inherit";
};
"group/utils" = {
drawer = {
transition-duration = 500;
transition-left-to-right = true;
};
modules = [
"custom/mark"
# "custom/weather"
# "custom/colorpicker"
# "custom/hyprshade"
"idle_inhibitor"
"custom/hyprkill"
];
orientation = "inherit";
};
"hyprland/submap" = {
format = "<b>󰇘</b>";
max-length = 8;
tooltip = true;
};
"hyprland/workspaces" = {
all-outputs = true;
format = "{icon}";
format-icons = {
"1" = "";
"10" = "";
"2" = "";
"3" = "";
"4" = "";
"5" = "";
"6" = "";
"7" = "";
"8" = "";
"9" = "";
};
on-click = "activate";
};
idle_inhibitor = {
format = "{icon}";
format-icons = {
activated = "󱎴";
deactivated = "󰍹";
};
tooltip-format-activated = "Idle Inhibitor is active";
tooltip-format-deactivated = "Idle Inhibitor is not active";
};
memory = {
format = ''
<b>
{:2}󱉸</b>'';
};
network = {
format = "{icon}";
format-disconnected = "󰖪";
format-ethernet = "󰈀";
format-icons = {
disconnected = [ "󰖪" ];
ethernet = [ "󰈀" ];
wifi = [ "󰤨" ];
};
format-linked = "󰈁";
format-wifi = "󰤨";
on-click =
"pgrep -x rofi &>/dev/null && notify-send rofi || networkmanager_dmenu";
tooltip = false;
};
"network#speed" = {
format = " {bandwidthDownBits} ";
interval = 5;
on-click =
"pgrep -x rofi &>/dev/null && notify-send rofi || networkmanager_dmenu";
rotate = 90;
tooltip = true;
tooltip-format = "{ipaddr}";
tooltip-format-disconnected = "Not Connected to any type of Network";
tooltip-format-ethernet = ''
{ifname} 󰈀
{ipaddr} | {frequency} MHz{icon} '';
tooltip-format-wifi = ''
{essid} ({signalStrength}%)
{ipaddr} | {frequency} MHz{icon} '';
};
"niri/workspaces" = {
all-outputs = true;
format = "{icon}";
format-icons = {
"1" = "";
"10" = "";
"2" = "";
"3" = "";
"4" = "";
"5" = "";
"6" = "";
"7" = "";
"8" = "";
"9" = "";
};
on-click = "activate";
};
position = "right";
power-profiles-daemon = {
format = "{icon}";
format-icons = {
balanced = "<span><small> </small></span>";
default = "";
performance = "<span color='#B37F34'><small></small></span>";
power-saver = "<span color='#a6e3a1'><small></small></span>";
};
tooltip = true;
tooltip-format = ''
Power profile: {profile}
Driver: {driver}'';
};
privacy = {
icon-size = 14;
icon-spacing = 4;
modules = [{
tooltip = true;
tooltip-icon-size = 24;
type = "screenshare";
}];
orientation = "vertical";
transition-duration = 250;
};
pulseaudio = {
format = "{icon}";
format-bluetooth = "{icon}";
format-icons = {
car = " ";
default = [ "󰕿" "󰖀" "󰕾" ];
handsfree = "󰋌";
headphones = "󰋌";
headset = "󰋌";
phone = "";
portable = "";
};
format-muted = "󰖁";
on-click = "${pkgs.pavucontrol}/bin/pavucontrol";
on-click-right = "volume mute";
on-scroll-down = "pactl set-sink-volume @DEFAULT_SINK@ -5%";
on-scroll-up = "pactl set-sink-volume @DEFAULT_SINK@ +5%";
smooth-scrolling-threshold = 1;
tooltip-format = "{volume}% {icon} | {desc}";
};
"pulseaudio#mic" = {
format = "{format_source}";
format-source = "";
format-source-muted = "";
on-click = "pactl set-source-mute 0 toggle";
on-scroll-down = "pactl set-source-volume 0 -1%";
on-scroll-up = "pactl set-source-volume 0 +1%";
tooltip-format = "{volume}% {format_source} ";
};
"pulseaudio/slider" = {
max = 140;
min = 0;
orientation = "vertical";
};
reload_style_on_change = true;
tray = {
icon-size = 18;
spacing = 10;
};
}