Compare commits

..

2 commits

Author SHA1 Message Date
RingOfStorms (Joshua Bell)
6570da6f33 Merge branch 'master' of ssh://git.joshuabell.xyz:3032/ringofstorms/dotfiles 2025-10-20 20:45:27 -05:00
RingOfStorms (Joshua Bell)
7215fd37bf WIP new top level flakes break down 2025-10-20 20:45:26 -05:00
57 changed files with 3033 additions and 69 deletions

View file

@ -3,7 +3,6 @@
# NOTE if you add/change any inputs here also add them in the TOP level repo's flake.nix
home-manager.url = "github:rycee/home-manager/release-25.05";
ragenix.url = "github:yaxitech/ragenix";
nix-flatpak.url = "github:gmodena/nix-flatpak/?ref=latest";
hyprland.url = "github:hyprwm/Hyprland";
};
@ -28,7 +27,6 @@
imports = [
home-manager.nixosModules.default
ragenix.nixosModules.age
nix-flatpak.nixosModules.nix-flatpak
hyprland.nixosModules.default
./_home_manager
./options.nix

View file

@ -13,7 +13,6 @@ in
./docker.nix
./podman.nix
./incus.nix
./flatpaks.nix
./virt-manager.nix
];
config = {

View file

@ -1,66 +0,0 @@
{
config,
lib,
...
}:
let
ccfg = import ../config.nix;
cfg_path = [
ccfg.custom_config_key
"programs"
"flatpaks"
];
cfg = lib.attrsets.getAttrFromPath cfg_path config;
in
{
options =
{ }
// lib.attrsets.setAttrByPath cfg_path {
enable = lib.mkEnableOption "flatpaks";
packages = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "List of Flatpak package names to install.";
};
};
config = lib.mkIf cfg.enable {
services.flatpak = {
enable = true;
packages = cfg.packages;
overrides = {
global = {
Context.sockets = [
"wayland"
"x11"
];
Context.devices = [ "dri" ]; # allow GPU access if desired
Environment = {
XCURSOR_PATH = "/run/host/user-share/icons:/run/host/share/icons";
GTK_THEME = "Adwaita:dark";
# Force wayland as much as possible.
ELECTRON_OZONE_PLATFORM_HINT = "auto"; # or 'auto'
GTK_USE_PORTAL = "1";
OZONE_PLATFORM = "wayland";
QT_QPA_PLATFORM = "xcb"; # force XCB for Flatpaks (XWayland)
};
};
"org.signal.Signal" = {
Environment = {
SIGNAL_PASSWORD_STORE = "gnome-libsecret";
};
Context = {
sockets = [
"xfg-settings"
];
};
};
"com.google.Chrome" = {
Environment = {
CHROME_EXTRA_ARGS = "--enable-features=WaylandWindowDecorations --ozone-platform-hint=auto";
};
};
};
};
};
}

16
flakes/common/flake.nix Normal file
View file

@ -0,0 +1,16 @@
let
utils = import ./utils.nix;
in
with utils;
{
description = "Common NixOS configuration modules and Home Manager modules that require not other inputs beyond nixpkgs or home-manager itself. This is made by me for me and not designed to be general purpose for anyone else, but could be useful nontheless.";
inputs = { };
outputs =
{
...
}:
{
nixosModules = importAll ./nix_modules;
homeManagerModules = importAll ./hm_modules;
};
}

View file

@ -0,0 +1,34 @@
{ ... }:
{
programs.alacritty = {
enable = true;
settings = {
window = {
decorations = "None";
dynamic_title = false;
};
colors = {
primary = {
foreground = "#e0e0e0";
background = "#262626";
};
normal = {
# Catppuccin Coal
black = "#1f1f1f";
red = "#f38ba8";
green = "#a6e3a1";
yellow = "#f9e2af";
blue = "#89b4fa";
magenta = "#cba6f7";
cyan = "#89dceb";
white = "#e0e0e0";
};
};
font = {
normal = { family = "JetBrainsMonoNL Nerd Font"; style = "Regular"; };
size = 12.0;
};
};
};
}

View file

@ -0,0 +1,18 @@
{ ... }:
# TODO setup auto secret/login for sync
{
programs.atuin = {
enable = true;
enableZshIntegration = true; # TODO make dynamic?
flags = [ "--disable-up-arrow" ];
settings = {
workspaces = true;
exit-mode = "return-query";
enter_accept = true;
sync_address = "https://atuin.joshuabell.xyz";
sync = {
records = true;
};
};
};
}

View file

@ -0,0 +1,12 @@
{ ... }:
{
imports = [
./theme.nix
./sway.nix
./waybar.nix
./wofi.nix
./swaync.nix
./swaylock.nix
./polkit.nix
];
}

View file

@ -0,0 +1,4 @@
{ ... }:
{
services.polkit-gnome.enable = true;
}

View file

@ -0,0 +1,180 @@
{
config,
...
}:
{
wayland.windowManager.sway = {
enable = true;
xwayland = true;
systemd.enable = true;
config = rec {
modifier = "Mod4"; # SUPER
terminal = "foot";
menu = "wofi --show drun";
# Per-output workspace mapping (user can extend via extraOptions)
# Example (left as defaults): users can add `output HDMI-A-1 workspace 1,3,5` in extraOptions
input = {
"type:keyboard" = {
xkb_layout = "us";
xkb_options = "caps:escape";
};
"type:touchpad" = {
natural_scroll = "enabled";
tap = "enabled";
dwt = "enabled";
};
# Disable focus follows mouse to avoid accidental focus changes
# In Sway this behavior is controlled by focus_follows_mouse
};
focus = {
followMouse = "no";
# onWindowActivation = "urgent"; # don't steal focus; mark urgent instead
};
gaps = {
inner = 2;
outer = 5;
smartGaps = false;
smartBorders = "on";
};
colors = {
focused = {
background = "#444444";
border = "#555555";
childBorder = "#444444";
indicator = "#595959";
text = "#f1f1f1";
};
unfocused = {
background = "#222222";
border = "#333333";
childBorder = "#222222";
indicator = "#292d2e";
text = "#888888";
};
};
window = {
border = 1;
titlebar = false;
commands = [
# Bitwarden chrome popup as floating example from Hyprland rules
{
criteria = {
app_id = "chrome-nngceckbapebfimnlniiiahkandclblb-Default";
};
command = "floating enable";
}
{
criteria = {
app_id = "pavucontrol";
};
command = "floating enable, move position center, resize set 620 1200";
}
{
criteria = {
class = "Google-chrome";
window_role = "pop-up";
};
command = "floating enable, move position center, resize set 720 480";
}
{
criteria = {
window_role = "pop-up";
};
command = "floating enable, move position center, resize set 640 420";
}
{
criteria = {
window_role = "About";
};
command = "floating enable, move position center, resize set 640 420";
}
];
};
# Keybindings mirroring Hyprland
keybindings = {
# Apps
"${modifier}+return" = "exec ${config.wayland.winfowManager.sway.config.terminal}";
"${modifier}+space" = "exec pkill wofi || wofi --show drun";
"${modifier}+q" = "kill";
"${modifier}+shift+Escape" = "exit";
"${modifier}+shift+q" = "exec swaylock";
"${modifier}+f" = "floating toggle";
# Focus
"${modifier}+h" = "focus left";
"${modifier}+l" = "focus right";
"${modifier}+k" = "focus up";
"${modifier}+j" = "focus down";
# Workspaces (numbers and vim-like mirror)
"${modifier}+1" = "workspace number 1";
"${modifier}+n" = "workspace number 1";
"${modifier}+2" = "workspace number 2";
"${modifier}+m" = "workspace number 2";
"${modifier}+3" = "workspace number 3";
"${modifier}+comma" = "workspace number 3";
"${modifier}+4" = "workspace number 4";
"${modifier}+period" = "workspace number 4";
"${modifier}+5" = "workspace number 5";
"${modifier}+slash" = "workspace number 5";
"${modifier}+6" = "workspace number 6";
"${modifier}+7" = "workspace number 7";
"${modifier}+8" = "workspace number 8";
"${modifier}+9" = "workspace number 9";
"${modifier}+0" = "workspace number 10";
# Move windows
"${modifier}+shift+h" = "move left";
"${modifier}+shift+l" = "move right";
"${modifier}+shift+k" = "move up";
"${modifier}+shift+j" = "move down";
"${modifier}+shift+1" = "move container to workspace number 1";
"${modifier}+shift+n" = "move container to workspace number 1";
"${modifier}+shift+2" = "move container to workspace number 2";
"${modifier}+shift+m" = "move container to workspace number 2";
"${modifier}+shift+3" = "move container to workspace number 3";
"${modifier}+shift+comma" = "move container to workspace number 3";
"${modifier}+shift+4" = "move container to workspace number 4";
"${modifier}+shift+period" = "move container to workspace number 4";
"${modifier}+shift+5" = "move container to workspace number 5";
"${modifier}+shift+slash" = "move container to workspace number 5";
"${modifier}+shift+6" = "move container to workspace number 6";
"${modifier}+shift+7" = "move container to workspace number 7";
"${modifier}+shift+8" = "move container to workspace number 8";
"${modifier}+shift+9" = "move container to workspace number 9";
"${modifier}+shift+0" = "move container to workspace number 10";
"${modifier}+left" = "resize shrink width 10 px or 10 ppt";
"${modifier}+down" = "resize shrink height 10 px or 10 ppt";
"${modifier}+up" = "resize grow height 10 px or 10 ppt";
"${modifier}+right" = "resize grow width 10 px or 10 ppt";
# Mouse bindings (Mod + drag)
"${modifier}+button1" = "move";
"${modifier}+button3" = "resize";
# Screenshot
"Print" = "exec grim -g \"$(slurp)\" - | wl-copy";
};
bars = [ ]; # Use Waybar via Home Manager
startup = [
{
command = "exec sh -c 'sleep 0.01; swaymsg workspace number 7 ; sleep 0.01; swaymsg workspace number 1'";
}
# Waybar is managed by Home Manager systemd unit
# { command = "pgrep waybar >/dev/null || waybar"; }
];
};
};
}

View file

@ -0,0 +1,15 @@
{ ... }:
{
programs.swaylock = {
enable = true;
settings = {
color = "#000000";
indicator-caps-lock = true;
indicator-idle-visible = true;
indicator-radius = 100;
indicator-thickness = 10;
font = "JetBrainsMono Nerd Font Regular";
font-size = 20;
};
};
}

View file

@ -0,0 +1,100 @@
{ ... }:
{
services.swaync = {
enable = true;
settings = {
ignore = [ "com.spotify.Client" ];
positionX = "right";
positionY = "top";
layer = "overlay";
control-center-layer = "top";
layer-shell = true;
cssPriority = "application";
control-center-margin-top = 0;
control-center-margin-bottom = 0;
control-center-margin-right = 0;
control-center-margin-left = 0;
notification-2fa-action = true;
notification-inline-replies = false;
notification-icon-size = 64;
notification-body-image-height = 100;
notification-body-image-width = 200;
timeout = 10;
timeout-low = 5;
timeout-critical = 0;
control-center-width = 500;
control-center-height = 600;
notification-window-width = 500;
keyboard-shortcuts = true;
image-visibility = "when-available";
transition-time = 200;
hide-on-clear = false;
hide-on-action = true;
script-fail-notify = true;
widgets = [
"inhibitors"
"title"
"dnd"
"volume"
"backlight"
"mpris"
"buttons-grid#quick"
"notifications"
];
widget-config = {
inhibitors = {
text = "Inhibitors";
button-text = "Clear All";
clear-all-button = true;
};
title = {
text = "Notifications";
clear-all-button = true;
button-text = "Clear All";
};
dnd.text = "Do Not Disturb";
mpris = {
image-size = 96;
image-radius = 12;
};
volume = {
label = "󰕾";
show-per-app = true;
};
backlight = {
label = "󰃟";
device = "intel_backlight";
};
# "buttons-grid#quick" = {
# columns = 4;
# icon-size = 20;
# actions = [
# { label = "󰐥"; tooltip = "Shutdown"; command = "confirm-action 'systemctl poweroff' 'Shutdown?'"; }
# { label = "󰜉"; tooltip = "Reboot"; command = "confirm-action 'systemctl reboot' 'Reboot?'"; }
# { label = "󰍃"; tooltip = "Logout"; command = "confirm-action 'swaymsg exit' 'Logout?'"; }
# ];
# };
};
};
style = ''
.control-center { background: #1a1b26; border: 2px solid #7dcae4; border-radius: 12px; }
.control-center-list { background: transparent; }
.control-center .notification-row:focus, .control-center .notification-row:hover { opacity: 1; background: #24283b; }
.notification { border-radius: 8px; margin: 6px 12px; box-shadow: 0 0 0 1px rgba(125,196,228,.3), 0 1px 3px 1px rgba(0,0,0,.7), 0 2px 6px 2px rgba(0,0,0,.3); padding: 0; }
.widget-title { margin: 8px; font-size: 1.5rem; color: #c0caf5; }
.widget-dnd { margin: 8px; font-size: 1.1rem; color: #c0caf5; }
.widget-dnd > switch { font-size: initial; border-radius: 8px; background: #414868; border: 1px solid #7dcae4; }
.widget-dnd > switch:checked { background: #7dcae4; }
.widget-mpris { color: #c0caf5; background: #24283b; padding: 8px; margin: 8px; border-radius: 8px; }
.widget-mpris-player { padding: 8px; margin: 8px; }
.widget-mpris-title { font-weight: bold; font-size: 1.25rem; }
.widget-mpris-subtitle { font-size: 1.1rem; color: #9ece6a; }
.widget-volume, .widget-backlight, .widget-menubar { background: #24283b; padding: 8px; margin: 8px; border-radius: 8px; color: #c0caf5; }
.widget-menubar .menu-item button { background: #1f2335; color: #c0caf5; border-radius: 8px; padding: 6px 10px; margin: 4px; border: 1px solid #2e3440; font-family: "JetBrainsMonoNL Nerd Font"; }
.widget-menubar .menu-item button:hover { background: #414868; border-color: #7dcae4; }
.topbar-buttons button { border: none; background: transparent; color: #c0caf5; font-size: 1.1rem; border-radius: 8px; margin: 0 4px; padding: 8px; }
.topbar-buttons button:hover { background: #414868; }
.topbar-buttons button:active { background: #7dcae4; color: #1a1b26; }
'';
};
}

View file

@ -0,0 +1,15 @@
{ pkgs, ... }:
{
home.pointerCursor = {
gtk.enable = true;
package = pkgs.bibata-cursors;
name = "Bibata-Modern-Classic";
size = 16;
};
gtk = {
enable = true;
theme = { package = pkgs.flat-remix-gtk; name = "Flat-Remix-GTK-Grey-Darkest"; };
iconTheme = { package = pkgs.adwaita-icon-theme; name = "Adwaita"; };
font = { name = "Sans"; size = 11; };
};
}

View file

@ -0,0 +1,246 @@
{ ... }:
{
programs.waybar = {
enable = true;
systemd.enable = true;
settings = {
mainBar = {
layer = "top";
position = "top";
height = 28;
spacing = 6;
margin-top = 0;
margin-bottom = 0;
margin-left = 10;
margin-right = 10;
modules-left = [
"sway/workspaces"
];
modules-center = [
"clock"
"temperature"
"cpu"
"memory"
"disk"
];
modules-right = [
"battery"
"battery#bat2"
"pulseaudio"
"network"
"bluetooth"
"power-profiles-daemon"
"backlight"
"custom/notifications"
"sway/language"
"tray"
"custom/power"
];
"sway/workspaces" = {
format = "{icon}";
format-icons = {
"1" = "";
"2" = "";
"3" = "";
"4" = "";
"5" = "";
"6" = "";
"7" = "";
"8" = "";
"9" = "";
"10" = "";
"11" = "";
"12" = "";
"13" = "";
"14" = "";
"15" = "";
"16" = "";
"17" = "";
"18" = "";
"19" = "";
"20" = "";
};
disable-scroll = false;
};
# CENTER
clock = {
format = "{:%b %d, %H:%M}";
tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
};
temperature = {
thermal-zone = 2;
hwmon-path = "/sys/class/hwmon/hwmon2/temp1_input";
critical-threshold = 80;
format-critical = "󰔏 {temperatureC}°C";
format = "󰔏 {temperatureC}°C";
};
cpu = {
format = "󰻠 {usage}%";
tooltip = true;
on-click = "btop";
};
memory = {
format = "󰍛 {}%";
on-click = "btop";
};
disk = {
interval = 30;
format = "󰋊 {percentage_used}%";
path = "/";
on-click = "btop";
};
# RIGHT
"battery" = {
"states" = {
# "good"= 95;
"warning" = 30;
"critical" = 15;
};
"format" = "{capacity}% {icon}";
"format-full" = "{capacity}% {icon}";
"format-charging" = "{capacity}% ";
"format-plugged" = "{capacity}% ";
"format-alt" = "{time} {icon}";
# "format-good"= ""; // An empty format will hide the module
# "format-full"= "";
"format-icons" = [
""
""
""
""
""
];
};
"battery#bat2" = {
"bat" = "BAT2";
};
pulseaudio = {
format = "{icon} {volume}%";
format-bluetooth = "󰂰 {volume}%";
format-bluetooth-muted = "󰂲 ";
format-muted = "󰖁 ";
format-source = "󰍬 {volume}%";
format-source-muted = "󰍭 ";
format-icons = {
headphone = "󰋋";
hands-free = "󰂑";
headset = "󰂑";
phone = "󰏲";
portable = "󰦧";
car = "󰄋";
default = [
"󰕿"
"󰖀"
"󰕾"
];
};
scroll-step = 5;
on-click = "pavucontrol";
on-click-right = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
};
network = {
format-wifi = "󰤨 {essid} ({signalStrength}%)";
format-ethernet = "󰈀 {ipaddr}/{cidr}";
tooltip-format = "{ifname} via {gwaddr} ";
format-linked = "󰈀 {ifname} (No IP)";
format-disconnected = "󰖪 Disconnected";
# on-click = "wofi-wifi-menu";
# on-click-right = "nmcli radio wifi toggle";
};
bluetooth = {
format = "󰂯 {status}";
format-connected = "󰂱 {device_alias}";
format-connected-battery = "󰂱 {device_alias} {device_battery_percentage}%";
tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected";
tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}";
tooltip-format-enumerate-connected = "{device_alias}\t{device_address}";
tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%";
# on-click = "wofi-bluetooth-menu";
# on-click-right = "bluetoothctl power toggle";
};
"power-profiles-daemon" = {
format = "{icon}";
"tooltip-format" = "Power profile: {profile}\nDriver: {driver}";
tooltip = true;
"format-icons" = {
default = "";
performance = "";
balanced = "";
"power-saver" = "";
};
};
backlight = {
format = "{percent}% {icon}";
"format-icons" = [
""
""
""
""
""
""
""
""
""
];
};
"custom/notifications" = {
format = "{icon} {}";
format-icons = {
notification = "";
none = "";
dnd-notification = "󰂛";
dnd-none = "󰂛";
inhibited-notification = "";
inhibited-none = "";
dnd-inhibited-notification = "󰂛";
dnd-inhibited-none = "󰂛";
};
return-type = "json";
exec-if = "which swaync-client";
exec = "swaync-client -swb";
on-click = "swaync-client -t -sw";
on-click-right = "swaync-client -d -sw";
escape = true;
tooltip = false;
};
"sway/language" = {
format = "{}";
};
"tray" = {
"spacing" = 10;
};
"custom/power" = {
format = " ";
tooltip = false;
menu = "on-click";
"menu-file" = ./waybar/power_menu.xml;
"menu-actions" = {
shutdown = "shutdown 0";
reboot = "reboot";
logout = "loginctl terminate-session $(loginctl list-sessions | grep seat0 | awk '{print $1}')";
};
};
};
};
style = builtins.readFile ./waybar/waybar.css;
};
}

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkMenu" id="menu">
<child>
<object class="GtkMenuItem" id="logout">
<property name="label">Logout</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="delimiter1" />
</child>
<child>
<object class="GtkMenuItem" id="reboot">
<property name="label">Reboot</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="delimiter2" />
</child>
<child>
<object class="GtkMenuItem" id="shutdown">
<property name="label">Shutdown</property>
</object>
</child>
</object>
</interface>

View file

@ -0,0 +1,101 @@
* {
/* `otf-font-awesome` is required to be installed for icons */
font-family: "JetBrainsMonoNL Nerd Font", FontAwesome, Roboto, Helvetica, Arial, sans-serif;
font-size: 14px;
border: none;
border-radius: 0;
min-height: 0;
color: #f1f1f1;
}
window#waybar {
background: transparent;
}
#workspaces button.focused {
background-color: rgba(220, 220, 220, 0.2);
}
#workspaces button.urgent {
background-color: rgba(214, 82, 82, 0.3);
}
button,
#clock,
#battery,
#cpu,
#memory,
#disk,
#temperature,
#backlight,
#network,
#pulseaudio,
#wireplumber,
#custom-media,
#custom-notifications,
#custom-power,
#tray,
#mode,
#idle_inhibitor,
#scratchpad,
#power-profiles-daemon,
#bluetooth,
#language,
#mpd {
padding: 0 5px;
color: #f1f1f1;
background-color: rgba(220, 220, 220, 0.1);
border-radius: 6px;
}
button:hover,
#clock:hover,
#battery:hover,
#cpu:hover,
#memory:hover,
#disk:hover,
#temperature:hover,
#backlight:hover,
#network:hover,
#pulseaudio:hover,
#wireplumber:hover,
#custom-media:hover,
#custom-notifications:hover,
#tray:hover,
#mode:hover,
#idle_inhibitor:hover,
#scratchpad:hover,
#power-profiles-daemon:hover,
#bluetooth:hover,
#language:hover,
#mpd:hover {
color: #f1f1f1;
background-color: rgba(220, 220, 220, 0.2);
border-radius: 6px;
}
#power-profiles-daemon {
padding-right: 15px;
}
#power-profiles-daemon.performance {
color: #fff7d6;
}
#power-profiles-daemon.balanced {
color: #d6efff;
}
#power-profiles-daemon.power-saver {
color:#dcffd6;
}
#tray>.passive {
-gtk-icon-effect: dim;
}
#tray>.needs-attention {
-gtk-icon-effect: highlight;
background-color: #eb4d4b;
}

View file

@ -0,0 +1,23 @@
{ ... }:
{
programs.wofi = {
enable = true;
settings = {
width = 500;
height = 600;
location = "bottom";
show = "drun";
prompt = "...";
filter_rate = 100;
allow_markup = true;
no_actions = true;
halign = "fill";
orientation = "vertical";
content_halign = "fill";
insensitive = true;
allow_images = true;
image_size = 40;
gtk_dark = true;
};
};
}

View file

@ -0,0 +1,23 @@
{ ... }:
{
programs.direnv = {
enable = true;
enableZshIntegration = true;
nix-direnv.enable = true;
config = {
nix-direnv = true;
global = {
strict_env = true;
load_dotenv = true;
hide_env_diff = true;
};
whitelist = {
prefix = [
"~/projects"
"~/.config"
"~/.local/share/git_worktrees/"
];
};
};
};
}

View file

@ -0,0 +1,47 @@
{ ... }:
{
programs.foot = {
enable = true;
# This renders to ~/.config/foot/foot.ini
settings = {
main = {
# Use the same font and size as your Kitty config
font = "JetBrainsMonoNL Nerd Font:size=12";
# Initial window size in character cells (Kitty used 160c x 55c)
"initial-window-size-chars" = "160x55";
};
colors = {
# Background opacity (1.0 = opaque)
alpha = "0.94";
# Foreground/background
foreground = "e0e0e0";
background = "262626";
# 16-color palette
# normal (07)
regular0 = "1f1f1f"; # black
regular1 = "f38ba8"; # red
regular2 = "a6e3a1"; # green
regular3 = "f9e2af"; # yellow
regular4 = "89b4fa"; # blue
regular5 = "cba6f7"; # magenta
regular6 = "89dceb"; # cyan
regular7 = "e0e0e0"; # white
# bright (815)
bright0 = "565656"; # bright black
bright1 = "f38ba8"; # bright red
bright2 = "a6e3a1"; # bright green
bright3 = "f9e2af"; # bright yellow
bright4 = "89b4fa"; # bright blue
bright5 = "cba6f7"; # bright magenta
bright6 = "89dceb"; # bright cyan
bright7 = "ffffff"; # bright white
};
};
};
}

View file

@ -0,0 +1,67 @@
{ ... }:
{
programs.git = {
enable = true;
# TODO make configurable
userEmail = "ringofstorms@gmail.com";
userName = "RingOfStorms (Joshua Bell)";
extraConfig = {
core.pager = "bat";
core.editor = "nano";
pull.rebase = false;
init.defaultBranch = "main";
rerere.enabled = true;
};
difftastic = {
enable = true;
background = "dark";
};
ignores = [
# --------------
# Intellij
# --------------
"*.iml"
# --------------
# MAC OS
# --------------
".DS_Store"
".AppleDouble"
".LSOverride"
# Icon must end with two \r
"Icon"
# Thumbnails
"._*"
# Files that might appear in the root of a volume
".DocumentRevisions-V100"
".fseventsd"
".Spotlight-V100"
".TemporaryItems"
".Trashes"
".VolumeIcon.icns"
".com.apple.timemachine.donotpresent"
# Directories potentially created on remote AFP share
".AppleDB"
".AppleDesktop"
"Network Trash Folder"
"Temporary Items"
".apdisk"
# direnv things
".direnv"
# local only files
"*.local"
# AI tooling
".aider*"
"aider"
];
};
}

View file

@ -0,0 +1,56 @@
{ ... }:
{
# Enable Kitty terminal
programs.kitty = {
enable = true;
settings = {
# Window settings
background_opacity = 1.0;
os_window_class = "kitty";
remember_window_size = false;
placement_strategy = "center";
initial_window_width = "160c";
initial_window_height = "55c";
# Remove window borders
hide_window_decorations = "titlebar-only";
tab_title_template = "none";
active_tab_title_template = "none";
draw_minimal_borders = "yes";
window_border_width = "0.1pt";
# Colors (Catppuccin Coal)
foreground = "#e0e0e0";
background = "#262626";
color0 = "#1f1f1f";
color1 = "#f38ba8";
color2 = "#a6e3a1";
color3 = "#f9e2af";
color4 = "#89b4fa";
color5 = "#cba6f7";
color6 = "#89dceb";
color7 = "#e0e0e0";
color8 = "#565656";
color9 = "#f38ba8";
color10 = "#a6e3a1";
color11 = "#f9e2af";
color12 = "#89b4fa";
color13 = "#cba6f7";
color14 = "#89dceb";
color15 = "#ffffff";
# Font settings
font_family = "JetBrainsMonoNL Nerd Font";
font_size = 12.0;
bold_font = "auto";
italic_font = "auto";
italic_bold_font = "auto";
};
# If you want to include extra configuration this way instead of through the main `settings` attribute
extraConfig = ''
# You can add additional config here if needed
'';
};
}

View file

@ -0,0 +1,18 @@
{
pkgs,
...
}:
{
programs.rofi = {
enable = true;
plugins = with pkgs; [ rofi-calc ];
extraConfig = {
modi = "drun,run,ssh,window,calc";
terminal = "alacritty";
};
theme = "glue_pro_blue";
};
programs.wofi = {
enable = true;
};
}

View file

@ -0,0 +1,7 @@
{ ... }:
{
home.file.".psqlrc".text = ''
\pset pager off
'';
}

View file

@ -0,0 +1,33 @@
{ pkgs, ... }:
let
orca-slicer-fix = pkgs.stdenv.mkDerivation {
name = "orca-slicer";
buildInputs = [ pkgs.makeWrapper ];
unpackPhase = "true";
buildPhase = ''
mkdir -p $out/bin
makeWrapper ${pkgs.orca-slicer}/bin/orca-slicer $out/bin/orca-slicer \
--set WEBKIT_DISABLE_DMABUF_RENDERER 1
'';
installPhase = ''
mkdir -p $out/share/applications
cat > $out/share/applications/orca-slicer.desktop <<EOF
[Desktop Entry]
Name=Orca Slicer
Comment=3D printing slicer
Exec=$out/bin/orca-slicer
Icon=orca-slicer
Terminal=false
Type=Application
Categories=Graphics;3DGraphics;
EOF
'';
};
in
{
home.packages = with pkgs; [
prusa-slicer
orca-slicer-fix
];
}

View file

@ -0,0 +1,162 @@
{
osConfig,
lib,
...
}:
let
inherit (osConfig) age;
hasSecret =
secret:
let
secrets = age.secrets or { };
in
secrets ? ${secret} && secrets.${secret} != null;
in
{
# TODO can I put all IP's in the flake.nix top level settings and pull them in here instead?
programs.ssh = {
enable = true;
extraConfig = ''
Host *
SetEnv TERM=xterm-256color
'';
matchBlocks = {
# EXTERNAL
"github.com" = lib.mkIf (hasSecret "nix2github") {
identityFile = age.secrets.nix2github.path;
};
"bitbucket.org" = lib.mkIf (hasSecret "nix2bitbucket") {
identityFile = age.secrets.nix2bitbucket.path;
};
# "git.joshuabell.xyz" = lib.mkIf (hasSecret "nix2gitjosh") { # TODO remove old
# identityFile = age.secrets.nix2gitjosh.path;
# user = "git";
# };
"git.joshuabell.xyz" = lib.mkIf (hasSecret "nix2gitforgejo") {
identityFile = age.secrets.nix2gitforgejo.path;
user = "git";
};
# PERSONAL DEVICES
"lio" = lib.mkIf (hasSecret "nix2lio") {
identityFile = age.secrets.nix2lio.path;
user = "josh";
};
"lio_" = lib.mkIf (hasSecret "nix2lio") {
identityFile = age.secrets.nix2lio.path;
hostname = "10.12.14.116";
user = "josh";
};
"oren" = lib.mkIf (hasSecret "nix2oren") {
identityFile = age.secrets.nix2oren.path;
user = "josh";
};
"joe" = lib.mkIf (hasSecret "nix2joe") {
identityFile = age.secrets.nix2joe.path;
user = "ringo";
};
"gp3" = lib.mkIf (hasSecret "nix2gpdPocket3") {
identityFile = age.secrets.nix2gpdPocket3.path;
user = "josh";
};
"t" = lib.mkIf (hasSecret "nix2t") {
identityFile = age.secrets.nix2t.path;
user = "joshua.bell";
localForwards = [
{
bind.port = 3002;
host.port = 3002;
host.address = "localhost";
}
];
setEnv = {
TERM = "vt100";
};
};
"t_" = lib.mkIf (hasSecret "nix2t") {
identityFile = age.secrets.nix2t.path;
hostname = "10.12.14.181";
user = "joshua.bell";
localForwards = [
{
bind.port = 3002;
host.port = 3002;
host.address = "localhost";
}
];
setEnv = {
TERM = "vt100";
};
};
"mbptv" = lib.mkIf (hasSecret "nix2gpdPocket3") {
identityFile = age.secrets.nix2gpdPocket3.path;
user = "waka";
setEnv = {
TERM = "vt100";
};
};
"mbptv_" = lib.mkIf (hasSecret "nix2gpdPocket3") {
identityFile = age.secrets.nix2gpdPocket3.path;
hostname = "10.12.14.30";
user = "waka";
setEnv = {
TERM = "vt100";
};
};
"nothing1" = lib.mkIf (hasSecret "nix2gpdPocket3") {
identityFile = age.secrets.nix2gpdPocket3.path;
user = "TODO";
};
"tab1" = lib.mkIf (hasSecret "nix2gpdPocket3") {
identityFile = age.secrets.nix2gpdPocket3.path;
user = "TODO";
};
"pixel6" = lib.mkIf (hasSecret "nix2gpdPocket3") {
identityFile = age.secrets.nix2gpdPocket3.path;
user = "TODO";
};
# HOME SERVERS
"h001" = lib.mkIf (hasSecret "nix2h001") {
identityFile = age.secrets.nix2h001.path;
user = "luser";
};
"h001_" = lib.mkIf (hasSecret "nix2h001") {
identityFile = age.secrets.nix2h001.path;
hostname = "10.12.14.10";
user = "luser";
};
"h002" = lib.mkIf (hasSecret "nix2h002") {
identityFile = age.secrets.nix2h002.path;
user = "luser";
};
"h003" = lib.mkIf (hasSecret "nix2h003") {
identityFile = age.secrets.nix2h003.path;
user = "luser";
};
# LINODE SERVERS
"l001" = lib.mkIf (hasSecret "nix2linode") {
identityFile = age.secrets.nix2linode.path;
hostname = "172.236.111.33"; # Not on the tailscale network it is the primary host
user = "root";
};
"l002_" = lib.mkIf (hasSecret "nix2linode") {
identityFile = age.secrets.nix2linode.path;
hostname = "172.234.26.141";
user = "root";
};
"l002" = lib.mkIf (hasSecret "nix2linode") {
identityFile = age.secrets.nix2linode.path;
user = "root";
};
# ORACLE SERVERS
"o001" = lib.mkIf (hasSecret "nix2oracle") {
identityFile = age.secrets.nix2oracle.path;
user = "root";
};
"o001_" = lib.mkIf (hasSecret "nix2oracle") {
identityFile = age.secrets.nix2oracle.path;
hostname = "64.181.210.7";
user = "root";
};
};
};
}

View file

@ -0,0 +1,52 @@
{ ... }:
{
programs.starship = {
enable = true;
enableZshIntegration = true;
settings = {
add_newline = false;
palette = "catppuccin_coal";
palettes.catppuccin_coal = {
# Same as catppuccin mocha for these
rosewater = "#f5e0dc";
flamingo = "#f2cdcd";
pink = "#f5c2e7";
mauve = "#cba6f7";
red = "#f38ba8";
maroon = "#eba0ac";
peach = "#fab387";
yellow = "#f9e2af";
green = "#a6e3a1";
teal = "#94e2d5";
sky = "#89dceb";
sapphire = "#74c7ec";
blue = "#89b4fa";
lavender = "#b4befe";
# Coal variant: https://gist.joshuabell.xyz/ringofstorms/catppucin-coal
text = "#e0e0e0";
subtext1 = "#cccccc";
subtext0 = "#b8b8b8";
overlay2 = "#a3a3a3";
overlay1 = "#8c8c8c";
overlay0 = "#787878";
surface2 = "#636363";
surface1 = "#4f4f4f";
surface0 = "#3b3b3b";
base = "#262626";
mantle = "#1f1f1f";
crust = "#171717";
};
nix_shell = {
heuristic = true;
impure_msg = " \\(\\)";
pure_msg = " \\(\\)";
};
git_branch = {
format = " [$symbol$branch(:$remote_branch)]($style) ";
};
cmd_duration = {
format = " [$duration]($style) ";
};
};
};
}

View file

@ -0,0 +1,76 @@
{ lib, pkgs, ... }:
{
# home manager doesn't give us an option to add tmux extra config at the top so we do it ourselves here.
xdg.configFile."tmux/tmux.conf".text = lib.mkBefore (builtins.readFile ./tmux-reset.conf);
programs.tmux = {
enable = true;
# Revisit this later, permission denied to make anything in `/run` as my user...
secureSocket = false;
# default is B switch to space for easier dual hand use
shortcut = "Space";
prefix = "C-Space";
baseIndex = 1;
mouse = true;
keyMode = "vi";
shell = "${pkgs.zsh}/bin/zsh";
terminal = "tmux-256color";
aggressiveResize = true;
sensibleOnTop = false;
plugins = with pkgs.tmuxPlugins; [
{
plugin = catppuccin.overrideAttrs (_: {
src = pkgs.fetchgit {
url = "https://git.joshuabell.xyz/ringofstorms/tmux-catppuccin-coal.git";
rev = "d078123cd81c0dbb3f780e8575a9d38fe2023e1b";
sha256 = "sha256-qPY/dovDyut5WoUkZ26F2w3fJVmw4gcC+6l2ugsA65Y=";
};
});
extraConfig = ''
set -g @catppuccin_flavour 'mocha'
set -g @catppuccin_window_left_separator ""
set -g @catppuccin_window_right_separator " "
set -g @catppuccin_window_middle_separator " "
set -g @catppuccin_window_number_position "right"
set -g @catppuccin_window_default_fill "number"
set -g @catppuccin_window_default_text "#W"
set -g @catppuccin_window_current_fill "number"
set -g @catppuccin_window_current_text "#W#{?window_zoomed_flag,(),}"
set -g @catppuccin_status_modules_right "directory application date_time"
set -g @catppuccin_status_modules_left "session"
set -g @catppuccin_status_left_separator " "
set -g @catppuccin_status_right_separator " "
set -g @catppuccin_status_right_separator_inverse "no"
set -g @catppuccin_status_fill "icon"
set -g @catppuccin_status_connect_separator "no"
set -g @catppuccin_directory_text "#{b:pane_current_path}"
set -g @catppuccin_date_time_text "%H:%M"
'';
}
{
plugin = resurrect;
extraConfig = ''
set -g @resurrect-strategy-nvim 'session'
set -g @resurrect-capture-pane-contents 'on'
# Hook to save tmux-resurrect state when a pane is closed
set-hook -g pane-died "run-shell 'tmux-resurrect save'"
'';
}
{
plugin = continuum;
extraConfig = ''
set -g @continuum-restore 'on'
set -g @continuum-save-interval '5' # minutes
'';
}
];
};
home.shellAliases = {
t = "tmux";
tat = "tmux attach-session";
};
}

View file

@ -0,0 +1,76 @@
# Reset everything then add what we want exactly
unbind-key -a
bind C-Space send-prefix
# Windows
# bind -r p previous-window
# bind -r n next-window
bind -r & kill-window
bind c new-window -a -c "#{pane_current_path}"
bind ',' command-prompt "rename-window %%"
bind "\|" split-window -h -c "#{pane_current_path}"
bind "\\" split-window -v -c "#{pane_current_path}"
bind w choose-tree -Zw
bind 1 select-window -t:1
bind 2 select-window -t:2
bind 3 select-window -t:3
bind 4 select-window -t:4
bind 5 select-window -t:5
bind 6 select-window -t:6
bind 7 select-window -t:7
bind 8 select-window -t:8
bind 9 select-window -t:9
# custom
bind m command-prompt -p "Swap with window index:" "swap-window -t '%%'"
bind -r [ swap-window -t -1 \; previous-window
bind -r ] swap-window -t +1 \; next-window
# Panes
bind ! break-pane
bind -r left select-pane -L
bind -r down select-pane -D
bind -r up select-pane -U
bind -r right select-pane -R
bind x kill-pane
bind -r space resize-pane -Z
bind S select-layout tiled
bind -r h select-pane -L
bind -r j select-pane -D
bind -r k select-pane -U
bind -r l select-pane -R
bind -r C-h swap-pane -t '{left-of}'
bind -r C-j swap-pane -D
bind -r C-k swap-pane -U
bind -r C-l swap-pane -t '{right-of}'
bind -n C-Left resize-pane -L 5
bind -n C-Down resize-pane -D 5
bind -n C-Up resize-pane -U 5
bind -n C-Right resize-pane -R 5
# Sessions
bind $ command-prompt "rename-session %%"
bind -r ) switch-client -n
bind -r ( switch-client -p
# custom
bind C command-prompt -p "session name:" "new-session -s '%%'"
# Tmux util
bind : command-prompt
bind C-d detach
# ==========
# My options
set -g default-terminal "tmux-256color"
set-option -g terminal-overrides ',tmux-256color:RGB'
set -g detach-on-destroy off
set -g renumber-windows on
set -g status-position top
set -sg escape-time 0
set -g xterm-keys on
set-option -g set-titles on
set-option -g set-titles-string "tmux: #S - #W"
set-option -g focus-events on

View file

@ -0,0 +1,8 @@
{ ... }:
{
programs.zoxide = {
enable = true;
enableZshIntegration = true;
options = [ "--cmd cd" ];
};
}

View file

@ -0,0 +1,42 @@
{ ... }:
{
programs.zsh = {
enable = true;
autosuggestion.enable = true;
shellAliases = { };
defaultKeymap = "emacs";
initContent = ''
# Set editor to neovim, TODO only do this if mod.neovim is enabled
export EDITOR=nvim
export VISUAL=nvim
# Enable editing command in external editor
autoload -Uz edit-command-line
zle -N edit-command-line
# fix delete key
bindkey "^[[3~" delete-char
# Try multiple bindings for edit-command-line
bindkey '^X^E' edit-command-line # Traditional Ctrl+X,Ctrl+E binding
bindkey '^[^M' edit-command-line # Alt+Enter
# Note: Ctrl+Enter might not be distinctly capturable in all terminals
# Make home/end and ctrl + left/right nav how I expect them to like in bash
bindkey "\e[1~" beginning-of-line
bindkey "\e[4~" end-of-line
bindkey '^[[1;5D' emacs-backward-word
bindkey '^[[1;5C' emacs-forward-word
# Auto completion/suggestions/and case insensitivity
autoload -Uz compinit && compinit
setopt correct
setopt extendedglob
setopt nocaseglob
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' # Case insensitive tab completion
zstyle ':completion:*' list-colors "''${(s.:.)LS_COLORS}" # Colored completion (different colors for dirs/files/etc)
zstyle ':completion:*' rehash true # automatically find new executables in path
'';
};
}

View file

@ -0,0 +1,10 @@
{
...
}:
{
boot.loader.grub = {
enable = true;
device = "/dev/sda";
};
}

View file

@ -0,0 +1,15 @@
{
...
}:
{
boot.loader = {
systemd-boot = {
enable = true;
consoleMode = "keep";
};
timeout = 5;
efi = {
canTouchEfiVariables = true;
};
};
}

View file

@ -0,0 +1,121 @@
{
config,
lib,
pkgs,
...
}:
{
# Enable for all users via Home Manager fragments in this module
home-manager = {
sharedModules = [ ./home_manager ];
};
services.greetd = {
enable = true;
vt = 2;
settings = {
default_session = {
command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --remember --remember-session --cmd '${pkgs.dbus}/bin/dbus-run-session ${pkgs.sway}/bin/sway'";
user = "greeter";
};
};
};
# Caps Lock as Escape for console/tty and Wayland
console.useXkbConfig = true;
services.xserver.xkb = {
layout = "us";
options = "caps:escape";
};
# Core packages and tools
environment.systemPackages = with pkgs; [
wl-clipboard
wl-clip-persist
wofi # application launcher
nemo # file manager (x11)
feh # image viewer (x11)
networkmanager
upower
brightnessctl
wireplumber
libgtop
bluez
power-profiles-daemon
grim
slurp
wf-recorder
btop
pavucontrol
];
services.blueman.enable = config.hardware.bluetooth.enable;
programs.sway = {
enable = true;
wrapperFeatures.gtk = true; # include GTK integration env
extraPackages = with pkgs; [
xwayland # allow legacy X11 apps
];
};
xdg.portal = {
enable = true;
extraPortals = lib.mkForce [
pkgs.xdg-desktop-portal-wlr
pkgs.xdg-desktop-portal-gtk
];
config.common.default = [
"wlr"
"gtk"
];
};
# Enable PipeWire + WirePlumber so xdg-desktop-portal can do screencast
services.pipewire = {
enable = true;
# Enable WirePlumber session manager via the pipewire module option
wireplumber = {
enable = true;
};
};
# Ensure graphics/OpenGL are enabled so Sway uses GPU-backed rendering
hardware.graphics = {
enable = true;
# extraPackages can be used to force vendor-specific mesa/drivers if needed
# Keep defaults; Sway runs fine with mesa in system
# extraPackages = with pkgs; [];
};
# Environment variables
environment.sessionVariables = lib.mkMerge [
{
GTK_THEME = "Adwaita:dark";
XDG_SESSION_TYPE = "wayland";
XDG_CURRENT_DESKTOP = "sway";
XDG_SESSION_DESKTOP = "sway";
# prefer EGL renderer (can be changed back to "auto" if needed)
WLR_RENDERER = "egl";
# Tell apps to run native wayland
NIXOS_OZONE_WL = "1";
ELECTRON_OZONE_PLATFORM_HINT = "wayland";
ELECTRON_ENABLE_WAYLAND = "1";
ELECTRON_DISABLE_SANDBOX = "0";
GDK_BACKEND = "wayland,x11"; # GTK
QT_QPA_PLATFORM = "wayland;xcb"; # Qt 5/6
MOZ_ENABLE_WAYLAND = "1"; # Firefox
SDL_VIDEODRIVER = "wayland"; # SDL apps/games
CLUTTER_BACKEND = "wayland";
}
];
# Qt theming
qt = {
enable = true;
platformTheme = "gtk2";
style = "adwaita-dark";
};
}

56
flakes/common/utils.nix Normal file
View file

@ -0,0 +1,56 @@
# utils.nix
{
/*
Auto-imports all Nix files and directories within a given `path`.
Args:
path: The absolute path to the directory to scan.
(e.g., `./.` or `/path/to/dir`)
Returns:
An attribute set where keys are the filenames (without .nix) or
directory names, and values are the imported modules.
It ignores:
- Dotfiles (e.g., .git)
- default.nix and flake.nix (common entry points)
- Itself (utils.nix)
*/
importAll = path:
let
# Read all entries in the given path
entries = builtins.readDir path;
# Get the names of all entries
entryNames = builtins.attrNames entries;
# Filter for entries we want to import
filteredNames = builtins.filter (name:
let
entryType = entries.${name};
isDotfile = builtins.substring 0 1 name == ".";
isIgnoredFile = name == "default.nix" || name == "flake.nix" || name == "utils.nix";
isNixFile = entryType == "regular" && builtins.match ".*\\.nix$" name != null;
isDirectory = entryType == "directory";
in
!isDotfile && !isIgnoredFile && (isNixFile || isDirectory)
) entryNames;
# Create an attribute { name = "key"; value = import ./path/key; } for each entry
createAttr = name: {
# The key for the final attribute set
name =
if builtins.match ".*\\.nix$" name != null
# If it's a .nix file, strip the extension for the key name
then builtins.elemAt (builtins.match "(.*)\\.nix$" name) 0
# Otherwise, use the directory name
else name;
# The value is the imported file/directory
value = import (path + "/${name}");
};
in
# Convert the list of attributes into a single attribute set
builtins.listToAttrs (map createAttr filteredNames);
}

170
flakes/hyprland/default.nix Normal file
View file

@ -0,0 +1,170 @@
{
config,
lib,
pkgs,
hyprland,
hyprlandPkgs,
...
}:
let
ccfg = import ../../config.nix;
cfg_path = [
ccfg.custom_config_key
"desktopEnvironment"
"hyprland"
];
cfg = lib.attrsets.getAttrFromPath cfg_path config;
in
with lib;
{
options =
{ }
// lib.attrsets.setAttrByPath cfg_path {
enable = lib.mkEnableOption "hyprland desktop environment";
terminalCommand = mkOption {
type = lib.types.str;
default = "foot";
description = "The terminal command to use.";
};
extraOptions = mkOption {
type = lib.types.attrs;
default = { };
description = "Extra options for Hyprland configuration.";
};
hyprpaperSettings = lib.mkOption {
type = lib.types.attrs;
default = { };
description = "Extra options for hyprpaper configuration.";
};
swaync = {
enable = lib.mkEnableOption "Enable Swaync (notification center for Hyprland)";
};
waybar = {
enable = lib.mkEnableOption "Enable Waybar (status bar for Hyprland)";
};
};
config = lib.mkIf cfg.enable {
# Enable for all users
home-manager = {
sharedModules = [
hyprland.homeManagerModules.default
./home_manager
];
};
services.greetd = {
enable = true;
vt = 2;
settings = {
default_session = {
command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --remember --remember-session --cmd '${pkgs.dbus}/bin/dbus-run-session ${hyprlandPkgs.hyprland}/bin/Hyprland'";
user = "greeter";
};
};
};
# Caps Lock as Escape for console/tty
console.useXkbConfig = true;
services.xserver.xkb = {
layout = "us";
options = "caps:escape";
};
environment.systemPackages = with pkgs; [
wl-clipboard
wl-clip-persist
wofi # application launcher
nemo # file manager (x11)
# nautilus # file manager
feh # image viewer (x11)
# imv # image viewer
networkmanager # network management
upower # power management
brightnessctl # screen/keyboard brightness control
wireplumber # media session manager
libgtop # system monitor library
bluez # Bluetooth support
power-profiles-daemon # power profiles
grim
slurp
hyprpicker
grimblast # screenshot tool
wf-recorder # screen recording tool
btop # system monitor
];
services.blueman.enable = config.hardware.bluetooth.enable;
programs.hyprland = {
enable = true;
# xwayland.enable = false;
# withUWSM = true;
# set the flake package
package = hyprlandPkgs.hyprland;
# make sure to also set the portal package, so that they are in sync
# This is set below now in xdf portal directly so we can also add things like gtk
# portalPackage = hyprlandPkgs.xdg-desktop-portal-hyprland;
};
xdg.portal = {
enable = true;
extraPortals = lib.mkForce [
hyprlandPkgs.xdg-desktop-portal-hyprland
# hyprlandPkgs.xdg-desktop-portal-wlr
hyprlandPkgs.xdg-desktop-portal-gtk
];
config.common.default = [
"hyprland"
# "wlr"
"gtk"
];
};
# Enable PipeWire + WirePlumber so xdg-desktop-portal can do screencast
services.pipewire = {
enable = true;
# Enable WirePlumber session manager via the pipewire module option
wireplumber = {
enable = true;
};
};
hardware.graphics = {
enable = true;
package = hyprlandPkgs.mesa;
# if you also want 32-bit support (e.g for Steam)
# enable32Bit = true;
package32 = hyprlandPkgs.pkgsi686Linux.mesa;
};
# Environment variables
environment.sessionVariables = {
GTK_THEME = "Adwaita:dark";
XDG_SESSION_TYPE = "wayland";
# XDG_CURRENT_DESKTOP = "sway";
# XDG_SESSION_DESKTOP = "sway";
# prefer EGL renderer (can be changed back to "auto" if needed)
WLR_RENDERER = "egl";
# Tell apps to run native wayland
NIXOS_OZONE_WL = "1";
ELECTRON_OZONE_PLATFORM_HINT = "wayland";
ELECTRON_ENABLE_WAYLAND = "1";
ELECTRON_DISABLE_SANDBOX = "0";
GDK_BACKEND = "wayland,x11"; # GTK
QT_QPA_PLATFORM = "wayland;xcb"; # Qt 5/6
MOZ_ENABLE_WAYLAND = "1"; # Firefox
SDL_VIDEODRIVER = "wayland"; # SDL apps/games
CLUTTER_BACKEND = "wayland";
};
# Qt theming
qt = {
enable = true;
platformTheme = "gtk2";
style = "adwaita-dark";
};
};
}

36
flakes/hyprland/flake.nix Normal file
View file

@ -0,0 +1,36 @@
{
inputs = {
ragenix.url = "github:yaxitech/ragenix";
};
outputs =
{
hyprland,
...
}:
{
nixosModules = {
default =
{
config,
lib,
pkgs,
...
}:
{
imports = [
hyprland.nixosModules.default
];
config = {
_module.args = {
inherit hyprland;
hyprlandPkgs = import hyprland.inputs.nixpkgs {
system = pkgs.stdenv.hostPlatform.system;
config = config.nixpkgs.config or { };
};
};
};
};
};
};
}

View file

@ -0,0 +1,15 @@
{ ... }:
{
imports = [
./theme.nix
./hyprland.nix
./hyprpaper.nix
# ./quickshell.nix
./waybar.nix
./hyprpolkitagent.nix
./wofi.nix
./swaync.nix
./scripts.nix
./swaylock.nix
];
}

View file

@ -0,0 +1,176 @@
{
osConfig,
lib,
hyprlandPkgs,
...
}:
let
ccfg = import ../../../config.nix;
cfg_path = [
ccfg.custom_config_key
"desktopEnvironment"
"hyprland"
];
cfg = lib.attrsets.getAttrFromPath cfg_path osConfig;
in
{
wayland.windowManager.hyprland = {
enable = true;
xwayland.enable = osConfig.programs.hyprland.xwayland.enable;
# plugins = with hyprlandPkgs.hyprlandPlugins; [
# hyprspace
# ];
settings = lib.attrsets.recursiveUpdate {
# Debug logs enabled when this is uncommented
debug.disable_logs = false;
debug.disable_time = false;
# exec-once = [ "pgrep waybar>/dev/null || waybar" ];
# Default monitor configuration
monitor = "monitor = , preferred, auto, 1";
windowrulev2 = [
# Bitwarden password manager popup for chrome, always float it
"float, class:^(?i)chrome-nngceckbapebfimnlniiiahkandclblb-Default$, initialtitle:^_crx_nngceckbapebfimnlniiiahkandclblb$"
"center, class:^(?i)chrome-nngceckbapebfimnlniiiahkandclblb-Default$, initialtitle:^_crx_nngceckbapebfimnlniiiahkandclblb$"
"size 720 600, class:^(?i)chrome-nngceckbapebfimnlniiiahkandclblb-Default$, initialtitle:^_crx_nngceckbapebfimnlniiiahkandclblb$"
];
# Input configuration
input = {
kb_layout = "us";
kb_options = "caps:escape";
follow_mouse = 2;
touchpad = {
natural_scroll = true;
disable_while_typing = true;
};
};
# General settings
general = {
gaps_in = 2;
gaps_out = 4;
border_size = 1;
"col.active_border" = "rgba(797979aa)";
"col.inactive_border" = "rgba(393939aa)";
layout = "dwindle";
};
# Decoration
decoration = {
rounding = 4;
blur.enabled = false;
};
# Animations
animations = {
enabled = false;
};
# Layout
dwindle = {
pseudotile = true;
preserve_split = true;
};
# Misc
misc = {
force_default_wallpaper = 0;
disable_hyprland_logo = true;
disable_splash_rendering = true;
};
# Key bindings
"$mainMod" = "SUPER";
bind = [
# Applications
"$mainMod, Return, exec, ${cfg.terminalCommand}"
"$mainMod, Space, exec, pkill wofi || wofi --show drun"
"$mainMod, q, killactive"
"$mainMod SHIFT, escape, exit"
"$mainMod SHIFT, q, exec, swaylock"
"$mainMod, f, togglefloating"
"$mainMod SHIFT, F, fullscreen"
"$mainMod, g, pseudo"
"$mainMod, t, togglesplit"
# Move focus with mainMod + hjkl
"$mainMod, h, movefocus, l"
"$mainMod, l, movefocus, r"
"$mainMod, k, movefocus, u"
"$mainMod, j, movefocus, d"
# Switch workspaces with mainMod + [0-9]
"$mainMod, 1, workspace, 1"
"$mainMod, n, workspace, 1"
"$mainMod, 2, workspace, 2"
"$mainMod, m, workspace, 2"
"$mainMod, 3, workspace, 3"
"$mainMod, comma, workspace, 3"
"$mainMod, 4, workspace, 4"
"$mainMod, period, workspace, 4"
"$mainMod, 5, workspace, 5"
"$mainMod, slash, workspace, 5"
"$mainMod, 6, workspace, 6"
"$mainMod, 7, workspace, 7"
"$mainMod, 8, workspace, 8"
"$mainMod, 9, workspace, 9"
"$mainMod, 0, workspace, 10"
# Window management (similar to your GNOME setup)
"$mainMod SHIFT, h, movewindow, l"
"$mainMod SHIFT, l, movewindow, r"
"$mainMod SHIFT, k, movewindow, u"
"$mainMod SHIFT, j, movewindow, d"
"$mainMod SHIFT, 1, movetoworkspacesilent, 1"
"$mainMod SHIFT, n, movetoworkspacesilent, 1"
"$mainMod SHIFT, 2, movetoworkspacesilent, 2"
"$mainMod SHIFT, m, movetoworkspacesilent, 2"
"$mainMod SHIFT, 3, movetoworkspacesilent, 3"
"$mainMod SHIFT, comma, movetoworkspacesilent, 3"
"$mainMod SHIFT, 4, movetoworkspacesilent, 4"
"$mainMod SHIFT, period, movetoworkspacesilent, 4"
"$mainMod SHIFT, 5, movetoworkspacesilent, 5"
"$mainMod SHIFT, slash, movetoworkspacesilent, 5"
"$mainMod SHIFT, 6, movetoworkspacesilent, 6"
"$mainMod SHIFT, 7, movetoworkspacesilent, 7"
"$mainMod SHIFT, 8, movetoworkspacesilent, 8"
"$mainMod SHIFT, 9, movetoworkspacesilent, 9"
"$mainMod SHIFT, 0, movetoworkspacesilent, 10"
# Screenshots
", Print, exec, grimblast copy area"
];
bindr = [
# overview
# "$mainMod, SUPER_L, overview:toggle" $ hyprspace plugin
"$mainMod SHIFT, R, exec, systemctl --user restart hyprpanel.service"
];
binde = [
# Move between workspaces
# "$mainMod, n, workspace, r+1"
# "$mainMod, p, workspace, r-1"
# Resize windows
"$mainMod CTRL, h, resizeactive, -40 0"
"$mainMod CTRL, l, resizeactive, 40 0"
"$mainMod CTRL, k, resizeactive, 0 -20"
"$mainMod CTRL, j, resizeactive, 0 20"
];
# Mouse bindings
bindm = [
"$mainMod, mouse:272, movewindow"
"$mainMod, mouse:273, resizewindow"
];
} cfg.extraOptions;
};
}

View file

@ -0,0 +1,22 @@
{
osConfig,
lib,
...
}:
let
ccfg = import ../../../config.nix;
cfg_path = [
ccfg.custom_config_key
"desktopEnvironment"
"hyprland"
];
cfg = lib.attrsets.getAttrFromPath cfg_path osConfig;
in
{
config = {
services.hyprpaper = {
enable = true;
settings = cfg.hyprpaperSettings;
};
};
}

View file

@ -0,0 +1,8 @@
{
...
}:
{
services.hyprpolkitagent = {
enable = true;
};
}

View file

@ -0,0 +1,93 @@
{
osConfig,
lib,
pkgs,
upkgs,
...
}:
let
ccfg = import ../../../config.nix;
cfg_path = [
ccfg.custom_config_key
"desktopEnvironment"
"hyprland"
];
cfg = lib.attrsets.getAttrFromPath cfg_path osConfig;
in
{
home.packages = with pkgs; [
upkgs.quickshell
pulseaudio
brightnessctl
networkmanager
bluez
bluez-tools
power-profiles-daemon
upower
systemd
hyprlock
];
# Ensure CLI quickshell can resolve modules when not using --config-path
home.sessionVariables = {
QML_IMPORT_PATH = "$HOME/.config/quickshell";
QML2_IMPORT_PATH = "$HOME/.config/quickshell";
};
# install config files
home.file = {
".config/quickshell/shell.qml".source = ./quickshell/shell.qml;
".config/quickshell/panels/TopBar.qml".source = ./quickshell/panels/TopBar.qml;
".config/quickshell/notifications/NotificationServer.qml".source =
./quickshell/notifications/NotificationServer.qml;
".config/quickshell/notifications/NotificationPopup.qml".source =
./quickshell/notifications/NotificationPopup.qml;
".config/quickshell/notifications/NotificationCenter.qml".source =
./quickshell/notifications/NotificationCenter.qml;
".config/quickshell/widgets/status/Workspaces.qml".source =
./quickshell/widgets/status/Workspaces.qml;
".config/quickshell/widgets/status/Clock.qml".source = ./quickshell/widgets/status/Clock.qml;
".config/quickshell/widgets/status/SystemTrayWidget.qml".source =
./quickshell/widgets/status/SystemTrayWidget.qml;
".config/quickshell/widgets/status/Battery.qml".source = ./quickshell/widgets/status/Battery.qml;
".config/quickshell/widgets/controls/QuickSettings.qml".source =
./quickshell/widgets/controls/QuickSettings.qml;
".config/quickshell/widgets/controls/Audio.qml".source = ./quickshell/widgets/controls/Audio.qml;
".config/quickshell/widgets/controls/Network.qml".source =
./quickshell/widgets/controls/Network.qml;
".config/quickshell/widgets/controls/Bluetooth.qml".source =
./quickshell/widgets/controls/Bluetooth.qml;
".config/quickshell/widgets/controls/Brightness.qml".source =
./quickshell/widgets/controls/Brightness.qml;
".config/quickshell/widgets/controls/PowerProfilesWidget.qml".source =
./quickshell/widgets/controls/PowerProfilesWidget.qml;
".config/quickshell/panels/qmldir".source = ./quickshell/panels/qmldir;
".config/quickshell/notifications/qmldir".source = ./quickshell/notifications/qmldir;
".config/quickshell/widgets/status/qmldir".source = ./quickshell/widgets/status/qmldir;
".config/quickshell/widgets/controls/qmldir".source = ./quickshell/widgets/controls/qmldir;
# optional: .qmlls.ini should be gitignored; create empty to enable LSP
".config/quickshell/.qmlls.ini".text = "";
};
systemd.user.services.quickshell = {
Unit = {
Description = "Quickshell Desktop Shell";
PartOf = [ "graphical-session.target" ];
After = [ "graphical-session.target" ];
};
Service = {
ExecStart = "${upkgs.quickshell}/bin/quickshell --config-path %h/.config/quickshell";
Restart = "on-failure";
RestartSec = 2;
Environment = [
"QML_IMPORT_PATH=%h/.config/quickshell"
"QT_QPA_PLATFORM=wayland"
# Ensure we find icons
"XDG_CURRENT_DESKTOP=quickshell"
];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
};
}

View file

@ -0,0 +1,10 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
(writeShellScriptBin "toggle-airplane-mode" (builtins.readFile ./scripts/toggle-airplane-mode.sh))
(writeShellScriptBin "toggle-power-profile" (builtins.readFile ./scripts/toggle-power-profile.sh))
(writeShellScriptBin "wofi-wifi-menu" (builtins.readFile ./scripts/wofi-wifi-menu.sh))
(writeShellScriptBin "wofi-bluetooth-menu" (builtins.readFile ./scripts/wofi-bluetooth-menu.sh))
(writeShellScriptBin "confirm-action" (builtins.readFile ./scripts/confirm-action.sh))
];
}

View file

@ -0,0 +1,14 @@
#!/usr/bin/env bash
COMMAND_TO_RUN="$1"
PROMPT_MESSAGE="$2"
if [ -z "$PROMPT_MESSAGE" ]; then
PROMPT_MESSAGE="Are you sure?"
fi
choice=$(echo -e "No\nYes" | wofi --dmenu --location center -p "$PROMPT_MESSAGE")
if [ "$choice" == "Yes" ]; then
eval "$COMMAND_TO_RUN"
fi

View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
if [ "$(nmcli radio all)" = "enabled" ]; then
nmcli radio all off
else
nmcli radio all on
fi

View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
if [ "$(powerprofilesctl get)" = "performance" ]; then
powerprofilesctl set balanced
else
powerprofilesctl set performance
fi

View file

@ -0,0 +1,21 @@
#!/usr/bin/env bash
devices=$(bluetoothctl devices | awk '{print $2, $3}')
if [ -z "$devices" ]; then
options="󰂲 Power On\n󰂬 Scan for devices"
else
options="$devices\n󰂲 Power Off\n󰂬 Scan for devices"
fi
chosen=$(echo -e "$options" | wofi --dmenu --location 3 --yoffset 40 --xoffset -20 -p "Bluetooth")
case "$chosen" in
"󰂲 Power On") bluetoothctl power on;;
"󰂲 Power Off") bluetoothctl power off;;
"󰂬 Scan for devices") bluetoothctl scan on;;
*)
mac=$(echo "$chosen" | awk '{print $1}')
bluetoothctl connect "$mac"
;;
esac

View file

@ -0,0 +1,24 @@
#!/usr/bin/env bash
# Get a list of available Wi-Fi networks
nets=$(nmcli --terse --fields SSID,SECURITY,BARS device wifi list | sed '/^--/d' | sed 's/\\:/__/g')
# Get the current connection status
connected_ssid=$(nmcli -t -f active,ssid dev wifi | egrep '^yes' | cut -d: -f2)
if [[ ! -z "$connected_ssid" ]]; then
toggle="󰖪 Toggle Wi-Fi Off"
else
toggle="󰖩 Toggle Wi-Fi On"
fi
# Present the menu to the user
chosen_network=$(echo -e "$toggle\n$nets" | wofi --dmenu --location 3 --yoffset 40 --xoffset -20 -p "Wi-Fi Networks")
# Perform an action based on the user's choice
if [ "$chosen_network" = "$toggle" ]; then
nmcli radio wifi $([ "$connected_ssid" = "" ] && echo "on" || echo "off")
elif [ ! -z "$chosen_network" ]; then
ssid=$(echo "$chosen_network" | sed 's/__/\\:/g' | awk -F' ' '{print $1}')
nmcli device wifi connect "$ssid"
fi

View file

@ -0,0 +1,17 @@
{
...
}:
{
programs.swaylock = {
enable = true;
settings = {
color = "#000000";
indicator-caps-lock = true;
indicator-idle-visible = true;
indicator-radius = 100;
indicator-thickness = 10;
font = "JetBrainsMono Nerd Font Regular";
font-size = 20;
};
};
}

View file

@ -0,0 +1,251 @@
{
lib,
osConfig,
...
}:
let
ccfg = import ../../../config.nix;
cfg_path = [
ccfg.custom_config_key
"desktopEnvironment"
"hyprland"
"swaync"
];
cfg = lib.attrsets.getAttrFromPath cfg_path osConfig;
in
{
config = lib.mkIf cfg.enable {
services.swaync = {
enable = true;
settings = {
ignore = [
"com.spotify.Client"
];
positionX = "right";
positionY = "top";
layer = "overlay";
control-center-layer = "top";
layer-shell = true;
cssPriority = "application";
control-center-margin-top = 0;
control-center-margin-bottom = 0;
control-center-margin-right = 0;
control-center-margin-left = 0;
notification-2fa-action = true;
notification-inline-replies = false;
notification-icon-size = 64;
notification-body-image-height = 100;
notification-body-image-width = 200;
timeout = 10;
timeout-low = 5;
timeout-critical = 0;
control-center-width = 500;
control-center-height = 600;
notification-window-width = 500;
keyboard-shortcuts = true;
image-visibility = "when-available";
transition-time = 200;
hide-on-clear = false;
hide-on-action = true;
script-fail-notify = true;
widgets = [
"inhibitors"
"title"
"dnd"
"volume"
"backlight"
"mpris"
"buttons-grid#quick"
"notifications"
];
# Widget configurations
widget-config = {
inhibitors = {
text = "Inhibitors";
button-text = "Clear All";
clear-all-button = true;
};
title = {
text = "Notifications";
clear-all-button = true;
button-text = "Clear All";
};
dnd.text = "Do Not Disturb";
mpris = {
image-size = 96;
image-radius = 12;
};
volume = {
label = "󰕾";
show-per-app = true;
};
backlight = {
label = "󰃟";
device = "intel_backlight";
};
"buttons-grid#quick" = {
columns = 4; # adjust: 3/4/5
icon-size = 20; # tweak to taste
actions = [
# Power
{
label = "󰐥";
tooltip = "Shutdown";
command = "confirm-action 'systemctl poweroff' 'Shutdown?'";
}
{
label = "󰜉";
tooltip = "Reboot";
command = "confirm-action 'systemctl reboot' 'Reboot?'";
}
{
label = "󰍃";
tooltip = "Logout";
command = "confirm-action 'hyprctl dispatch exit' 'Logout?'";
}
];
};
};
};
# Custom CSS for the control center
style = ''
.control-center {
background: #1a1b26;
border: 2px solid #7dcae4;
border-radius: 12px;
}
.control-center-list {
background: transparent;
}
.control-center .notification-row:focus,
.control-center .notification-row:hover {
opacity: 1;
background: #24283b;
}
.notification {
border-radius: 8px;
margin: 6px 12px;
box-shadow: 0 0 0 1px rgba(125, 196, 228, 0.3), 0 1px 3px 1px rgba(0, 0, 0, 0.7), 0 2px 6px 2px rgba(0, 0, 0, 0.3);
padding: 0;
}
/* Widget styling */
.widget-title {
margin: 8px;
font-size: 1.5rem;
color: #c0caf5;
}
.widget-dnd {
margin: 8px;
font-size: 1.1rem;
color: #c0caf5;
}
.widget-dnd > switch {
font-size: initial;
border-radius: 8px;
background: #414868;
border: 1px solid #7dcae4;
}
.widget-dnd > switch:checked {
background: #7dcae4;
}
.widget-mpris {
color: #c0caf5;
background: #24283b;
padding: 8px;
margin: 8px;
border-radius: 8px;
}
.widget-mpris-player {
padding: 8px;
margin: 8px;
}
.widget-mpris-title {
font-weight: bold;
font-size: 1.25rem;
}
.widget-mpris-subtitle {
font-size: 1.1rem;
color: #9ece6a;
}
.widget-volume {
background: #24283b;
padding: 8px;
margin: 8px;
border-radius: 8px;
color: #c0caf5;
}
.widget-backlight {
background: #24283b;
padding: 8px;
margin: 8px;
border-radius: 8px;
color: #c0caf5;
}
.widget-menubar {
background: #24283b;
padding: 8px;
margin: 8px;
border-radius: 8px;
color: #c0caf5;
}
.widget-menubar .menu-item button {
background: #1f2335;
color: #c0caf5;
border-radius: 8px;
padding: 6px 10px;
margin: 4px;
border: 1px solid #2e3440;
font-family: "JetBrainsMonoNL Nerd Font";
}
.widget-menubar .menu-item button:hover {
background: #414868;
border-color: #7dcae4;
}
.topbar-buttons button {
border: none;
background: transparent;
color: #c0caf5;
font-size: 1.1rem;
border-radius: 8px;
margin: 0 4px;
padding: 8px;
}
.topbar-buttons button:hover {
background: #414868;
}
.topbar-buttons button:active {
background: #7dcae4;
color: #1a1b26;
}
'';
};
};
}

View file

@ -0,0 +1,18 @@
{
osConfig,
lib,
pkgs,
...
}:
let
ccfg = import ../../../config.nix;
cfg_path = [
ccfg.custom_config_key
"desktopEnvironment"
"hyprland"
];
cfg = lib.attrsets.getAttrFromPath cfg_path osConfig;
in
{
}

View file

@ -0,0 +1,32 @@
{
pkgs,
...
}:
{
home.pointerCursor = {
gtk.enable = true;
# x11.enable = true;
package = pkgs.bibata-cursors;
name = "Bibata-Modern-Classic";
size = 16;
};
# GTK theming
gtk = {
enable = true;
theme = {
package = pkgs.flat-remix-gtk;
name = "Flat-Remix-GTK-Grey-Darkest";
};
iconTheme = {
package = pkgs.adwaita-icon-theme;
name = "Adwaita";
};
font = {
name = "Sans";
size = 11;
};
};
}

View file

@ -0,0 +1,258 @@
{ lib, osConfig, ... }:
let
ccfg = import ../../../config.nix;
cfg_path = [
ccfg.custom_config_key
"desktopEnvironment"
"hyprland"
"waybar"
];
cfg = lib.attrsets.getAttrFromPath cfg_path osConfig;
in
{
config = lib.mkIf cfg.enable {
programs.waybar = {
enable = true;
systemd.enable = true;
settings = {
mainBar = {
layer = "top";
position = "top";
height = 28;
spacing = 6;
margin-top = 0;
margin-bottom = 0;
margin-left = 10;
margin-right = 10;
modules-left = [
"hyprland/workspaces"
];
modules-center = [
"clock"
"temperature"
"cpu"
"memory"
"disk"
];
modules-right = [
"battery"
"battery#bat2"
"pulseaudio"
"network"
"bluetooth"
"power-profiles-daemon"
"backlight"
"custom/notifications"
"tray"
"custom/power"
];
"hyprland/workspaces" = {
format = "{icon}";
format-icons = {
"1" = "";
"2" = "";
"3" = "";
"4" = "";
"5" = "";
"6" = "";
"7" = "";
"8" = "";
"9" = "";
"10" = "";
"11" = "";
"12" = "";
"13" = "";
"14" = "";
"15" = "";
"16" = "";
"17" = "";
"18" = "";
"19" = "";
"20" = "";
};
disable-scroll = false;
};
# CENTER
clock = {
format = "{:%b %d, %H:%M}";
tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
};
temperature = {
thermal-zone = 2;
hwmon-path = "/sys/class/hwmon/hwmon2/temp1_input";
critical-threshold = 80;
format-critical = "󰔏 {temperatureC}°C";
format = "󰔏 {temperatureC}°C";
};
cpu = {
format = "󰻠 {usage}%";
tooltip = true;
on-click = "btop";
};
memory = {
format = "󰍛 {}%";
on-click = "btop";
};
disk = {
interval = 30;
format = "󰋊 {percentage_used}%";
path = "/";
on-click = "btop";
};
# RIGHT
"battery" = {
"states" = {
# "good"= 95;
"warning" = 30;
"critical" = 15;
};
"format" = "{capacity}% {icon}";
"format-full" = "{capacity}% {icon}";
"format-charging" = "{capacity}% ";
"format-plugged" = "{capacity}% ";
"format-alt" = "{time} {icon}";
# "format-good"= ""; // An empty format will hide the module
# "format-full"= "";
"format-icons" = [
""
""
""
""
""
];
};
"battery#bat2" = {
"bat" = "BAT2";
};
pulseaudio = {
format = "{icon} {volume}%";
format-bluetooth = "󰂰 {volume}%";
format-bluetooth-muted = "󰂲 ";
format-muted = "󰖁 ";
format-source = "󰍬 {volume}%";
format-source-muted = "󰍭 ";
format-icons = {
headphone = "󰋋";
hands-free = "󰂑";
headset = "󰂑";
phone = "󰏲";
portable = "󰦧";
car = "󰄋";
default = [
"󰕿"
"󰖀"
"󰕾"
];
};
scroll-step = 5;
on-click = "pavucontrol";
on-click-right = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
};
network = {
format-wifi = "󰤨 {essid} ({signalStrength}%)";
format-ethernet = "󰈀 {ipaddr}/{cidr}";
tooltip-format = "{ifname} via {gwaddr} ";
format-linked = "󰈀 {ifname} (No IP)";
format-disconnected = "󰖪 Disconnected";
# on-click = "wofi-wifi-menu";
# on-click-right = "nmcli radio wifi toggle";
};
bluetooth = {
format = "󰂯 {status}";
format-connected = "󰂱 {device_alias}";
format-connected-battery = "󰂱 {device_alias} {device_battery_percentage}%";
tooltip-format = "{controller_alias}\t{controller_address}\n\n{num_connections} connected";
tooltip-format-connected = "{controller_alias}\t{controller_address}\n\n{num_connections} connected\n\n{device_enumerate}";
tooltip-format-enumerate-connected = "{device_alias}\t{device_address}";
tooltip-format-enumerate-connected-battery = "{device_alias}\t{device_address}\t{device_battery_percentage}%";
# on-click = "wofi-bluetooth-menu";
# on-click-right = "bluetoothctl power toggle";
};
"power-profiles-daemon" = {
format = "{icon}";
"tooltip-format" = "Power profile: {profile}\nDriver: {driver}";
tooltip = true;
"format-icons" = {
default = "";
performance = "";
balanced = "";
"power-saver" = "";
};
};
backlight = {
format = "{percent}% {icon}";
"format-icons" = [
""
""
""
""
""
""
""
""
""
];
};
"custom/notifications" = {
format = "{icon} {}";
format-icons = {
notification = "";
none = "";
dnd-notification = "󰂛";
dnd-none = "󰂛";
inhibited-notification = "";
inhibited-none = "";
dnd-inhibited-notification = "󰂛";
dnd-inhibited-none = "󰂛";
};
return-type = "json";
exec-if = "which swaync-client";
exec = "swaync-client -swb";
on-click = "swaync-client -t -sw";
on-click-right = "swaync-client -d -sw";
escape = true;
tooltip = false;
};
"sway/language" = {
format = "{}";
};
"tray" = {
"spacing" = 10;
};
"custom/power" = {
format = " ";
tooltip = false;
menu = "on-click";
"menu-file" = ./waybar/power_menu.xml;
"menu-actions" = {
shutdown = "shutdown 0";
reboot = "reboot";
logout = "loginctl terminate-session $(loginctl list-sessions | grep seat0 | awk '{print $1}')";
};
};
};
};
style = builtins.readFile ./waybar/waybar.css;
};
};
}

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkMenu" id="menu">
<child>
<object class="GtkMenuItem" id="logout">
<property name="label">Logout</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="delimiter1" />
</child>
<child>
<object class="GtkMenuItem" id="reboot">
<property name="label">Reboot</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="delimiter2" />
</child>
<child>
<object class="GtkMenuItem" id="shutdown">
<property name="label">Shutdown</property>
</object>
</child>
</object>
</interface>

View file

@ -0,0 +1,102 @@
* {
/* `otf-font-awesome` is required to be installed for icons */
font-family: "JetBrainsMonoNL Nerd Font", FontAwesome, Roboto, Helvetica, Arial, sans-serif;
font-size: 14px;
border: none;
border-radius: 0;
min-height: 0;
color: #f1f1f1;
}
window#waybar {
background: transparent;
}
#workspaces button.focused,
#workspaces button.active {
background-color: rgba(220, 220, 220, 0.2);
}
#workspaces button.urgent {
background-color: rgba(214, 82, 82, 0.3);
}
button,
#clock,
#battery,
#cpu,
#memory,
#disk,
#temperature,
#backlight,
#network,
#pulseaudio,
#wireplumber,
#custom-media,
#custom-notifications,
#custom-power,
#tray,
#mode,
#idle_inhibitor,
#scratchpad,
#power-profiles-daemon,
#bluetooth,
#language,
#mpd {
padding: 0 5px;
color: #f1f1f1;
background-color: rgba(220, 220, 220, 0.1);
border-radius: 6px;
}
button:hover,
#clock:hover,
#battery:hover,
#cpu:hover,
#memory:hover,
#disk:hover,
#temperature:hover,
#backlight:hover,
#network:hover,
#pulseaudio:hover,
#wireplumber:hover,
#custom-media:hover,
#custom-notifications:hover,
#tray:hover,
#mode:hover,
#idle_inhibitor:hover,
#scratchpad:hover,
#power-profiles-daemon:hover,
#bluetooth:hover,
#language:hover,
#mpd:hover {
color: #f1f1f1;
background-color: rgba(220, 220, 220, 0.2);
border-radius: 6px;
}
#power-profiles-daemon {
padding-right: 15px;
}
#power-profiles-daemon.performance {
color: #fff7d6;
}
#power-profiles-daemon.balanced {
color: #d6efff;
}
#power-profiles-daemon.power-saver {
color:#dcffd6;
}
#tray>.passive {
-gtk-icon-effect: dim;
}
#tray>.needs-attention {
-gtk-icon-effect: highlight;
background-color: #eb4d4b;
}

View file

@ -0,0 +1,26 @@
{
...
}:
{
programs.wofi = {
enable = true;
settings = {
width = 500;
height = 600;
location = "bottom";
show = "drun";
prompt = "...";
filter_rate = 100;
allow_markup = true;
no_actions = true;
halign = "fill";
orientation = "vertical";
content_halign = "fill";
insensitive = true;
allow_images = true;
image_size = 40;
gtk_dark = true;
};
};
}

33
flakes/secrets/flake.nix Normal file
View file

@ -0,0 +1,33 @@
{
inputs = {
ragenix.url = "github:yaxitech/ragenix";
};
outputs =
{
ragenix,
...
}:
{
nixosModules = {
default =
{
config,
lib,
pkgs,
...
}:
{
imports = [
ragenix.nixosModules.age
./secrets
];
config = {
_module.args = {
inherit ragenix;
};
};
};
};
};
}

0
flakes/test Normal file
View file

View file

@ -0,0 +1,10 @@
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
}