diff --git a/common/dunst.nix b/common/dunst.nix
index 818061d..05fe9fe 100644
--- a/common/dunst.nix
+++ b/common/dunst.nix
@@ -3,6 +3,5 @@
{
services.dunst = {
enable = true;
-
};
}
diff --git a/modules/dunst.nix b/modules/dunst.nix
new file mode 100644
index 0000000..052f450
--- /dev/null
+++ b/modules/dunst.nix
@@ -0,0 +1,14 @@
+{ config, lib, pkgs, inputs, ... }:
+let
+ cfg = config.modules.dunst;
+in
+{
+ options.modules.dunst = {
+ enable = lib.mkEnableOption "enable dunst for notifications";
+ };
+ config = lib.mkIf cfg.enable {
+ services.dunst = {
+ enable = true;
+ };
+ };
+}
diff --git a/modules/hyprland.nix b/modules/hyprland.nix
index 310a8c9..0d18fe7 100644
--- a/modules/hyprland.nix
+++ b/modules/hyprland.nix
@@ -1,27 +1,34 @@
{ config, lib, pkgs, inputs, ... }:
let
- hyprland = inputs.hyprland.packages.${pkgs.system}.hyprland;
cfg = config.modules.hyprland;
in
{
- options = {
- cfg.enable = lib.mkEnableOption "enable hyprland";
- # TODO: make custom terminal support work better
- # cfg.terminal = lib.mkOption {
- # type = lib.types.package;
- # default = pkgs.kitty;
- # description = "What terminal emulator should be used in hyprland";
- # };
+ options.modules.hyprland = {
+ enable = lib.mkEnableOption "enable hyprland";
+ package = lib.mkOption {
+ type = lib.types.package;
+ default = pkgs.hyprland;
+ example = lib.literalExpression ''inputs.hyprland.packages.${pkgs.system}.hyprland'';
+ };
+ terminal = lib.mkOption {
+ type = lib.types.package;
+ default = pkgs.kitty;
+ description = "What terminal emulator should be used in hyprland";
+ };
};
+ imports = [
+ ./waybar.nix
+ ./wofi.nix
+ ./dunst.nix
+ ];
config = lib.mkIf cfg.enable {
+ modules = {
+ waybar.enable = lib.mkDefault true;
+ wofi.enable = lib.mkDefault true;
+ dunst.enable = lib.mkDefault true;
+ };
# these are necessary for the config to function correctly
- imports = [
- ./kitty.nix
- ./waybar.nix
- ./wofi.nix
- ./dunst.nix
- ];
home.packages = with pkgs; [
# I always want these with hyprland anyways
libnotify # to enable the notify-send command
@@ -34,14 +41,13 @@ in
playerctl
];
- programs.waybar.enable = true;
- xdg.portal.configPackages = [ hyprland ];
+ xdg.portal.configPackages = [ cfg.package ];
services.playerctld.enable = true;
wayland.windowManager.hyprland = {
enable = true;
- package = hyprland;
+ package = cfg.package;
settings = {
monitor = [
"DP-3,2560x1440@360,2560x0,1"
@@ -93,7 +99,7 @@ in
};
"$mod" = "SUPER";
bind = [
- "$mod,Return,exec,${pkgs.kitty.pname}"
+ "$mod,Return,exec,${cfg.terminal.pname}"
"$mod,tab,cyclenext"
"SUPERSHIFT,Q,killactive"
"$mod,SPACE,exec,wofi-launch"
diff --git a/modules/waybar.nix b/modules/waybar.nix
new file mode 100644
index 0000000..cb91d7c
--- /dev/null
+++ b/modules/waybar.nix
@@ -0,0 +1,431 @@
+{ config, pkgs, lib, ... }:
+let
+ cfg = config.modules.waybar;
+in
+{
+ options.modules.waybar = {
+ enable = lib.mkEnableOption "enable waybar";
+ package = lib.mkOption {
+ type = lib.types.package;
+ default = pkgs.waybar;
+ };
+ };
+ config = lib.mkIf cfg.enable {
+ home.packages = with pkgs; [
+ font-awesome
+ ];
+ programs.waybar = {
+ enable = true;
+ package = cfg.package;
+ settings = {
+ mainBar = {
+ layer = "top";
+ position = "top";
+ height = 39;
+ margin-top = 8;
+ margin-left = 10;
+ margin-right = 10;
+ output = [
+ "DP-3"
+ "DP-2"
+ ];
+ modules-left = [ "hyprland/workspaces" "tray" "custom/pronouns" "hyprland/window" ];
+ modules-center = [ "clock" ];
+ modules-right = [ "custom/vpn" "wireplumber" "battery" "network" "cpu" "memory" "temperature" "custom/poweroff" ];
+ "clock" = {
+ tooltip-format = "{:%Y %B}\n\n{calendar}";
+ interval = 1;
+ format = "{:%H:%M:%S}";
+ format-alt = ":%Y-%m-%d %H:%M:%S}";
+ on-click-middle = "gnome-clocks";
+ calendar = {
+ weeks-pos = "left";
+ format = {
+ today = "{}"; # TODO: use nix-colors
+ weeks = "{}"; # TODO: use nix-colors
+ };
+ };
+ };
+ "tray".spacing = 10;
+ "cpu" = {
+ format = "cpu: {usage}%";
+ tooltip = false;
+ };
+ "memory" = {
+ format = "mem: {}%";
+ tooltip = false;
+ };
+ "wireplumber" = {
+ format = "{volume}% {icon}";
+ format-muted = "";
+ on-click = "helvum";
+ format-icons = ["" "" ""];
+ };
+ "custom/vpn" = {
+ format = "VPN";
+ exec = "echo '{\"class\": \"connected\"}'";
+ exec-if = "test -d /proc/sys/net/ipv4/conf/tun0";
+ return-type = "json";
+ interval = 5;
+ };
+ "temperature" = {
+ thermal-zone = 2;
+ hwmon-path = "/sys/class/hwmon/hwmon3/temp1_input";
+ critical-threshold = 80;
+ format = "{temperatureC}°C {icon}";
+ format-icons = ["" "" ""];
+ };
+ "custom/poweroff" = {
+ format = "";
+ on-click = "wofi-power";
+ on-click-right = "swaylock";
+ };
+ "battery" = {
+ bat = "hidpp_battery_2";
+ states = {
+ full = 100;
+ good = 50;
+ warning = 30;
+ critical = 30;
+ };
+ format = "mouse: {capacity}% {icon}";
+ format-charging = "mouse: {capacity}% {icon}";
+ format-plugged = "mouse: {capacity}% {icon}";
+ format-alt = "mouse: {time} {icon}";
+ interval = 1;
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ };
+ "hyprland/window" = {
+ max-length = 36;
+ };
+ "network" = {
+ format-wifi = "{essid} ({signalStrength}%) ";
+ format-ethernet = "{ipaddr}/{cidr} ";
+ tooltip-format = "{ifname} via {gwaddr} ";
+ format-linked = "{ifname} (No IP) ";
+ format-disconnected = "Disconnected ";
+ format-alt = "{ifname}: {ipaddr}/{cidr}";
+ };
+ "custom/pronouns" = {
+ format = "{}";
+ # exec = "${config.xdg.configHome}/waybar/pronouns"; # TODO: install pronouns
+ interval = 5;
+ };
+ "hyprland/workspaces" = {
+ format = "{name}";
+ on-click = "activate";
+ sort-by = "id";
+ };
+ };
+ };
+ style = ''
+ * {
+ /* `otf-font-awesome` is required to be installed for icons */
+ font-family: "Maple Mono NF";
+ font-size: 14px;
+ }
+
+ window#waybar {
+ background-color: transparent;
+
+ border-radius: 999px;
+ color: #${config.colorScheme.palette.text};
+ transition-property: background-color;
+ transition-duration: .5s;
+ }
+ window#waybar.hidden {
+ opacity: 0.2;
+ }
+
+ window#waybar.termite {
+ background-color: transparent;
+ }
+
+ window#waybar.chromium {
+ background-color: transparent;
+ }
+
+ button {
+ /* Use box-shadow instead of border so the text isn't offset */
+ box-shadow: inset 0 -1px transparent;
+ /* Avoid rounded borders under each button name */
+ border: none;
+ border-radius: 0;
+ }
+
+ /* https://githbackground: #000000ub.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
+ button:hover {
+ background: inherit;
+ border-radius: 999px;
+ }
+
+ #workspaces button {
+ transition: all 0.2s;
+ padding: 3px 3px 3px 5px;
+ margin: 3px;
+ min-width: 15px;
+ min-height: 15px;
+ background-color: transparent;
+ color: #${config.colorScheme.palette.textMuted};
+ border-radius: 999px;
+ }
+
+ #workspaces button:hover {
+ background-color: #${config.colorScheme.palette.highlight};
+ }
+
+ #workspaces button.active {
+ color: #${config.colorScheme.palette.text};
+ font-weight: bold;
+ background-color: #${config.colorScheme.palette.highlight};
+ }
+
+ #workspaces button.urgent {
+ background-color: #${config.colorScheme.palette.danger};
+ }
+
+ #clock,
+ #battery,
+ #cpu,
+ #memory,
+ #disk,
+ #temperature,
+ #backlight,
+ #network,
+ #pulseaudio,
+ #wireplumber,
+ #custom-media,
+ #mode,
+ #idle_inhibitor,
+ #custom-vpn,
+ #scratchpad,
+ #tray,
+ #custom-updates,
+ #custom-poweroff,
+ #mpd {
+ color: #${config.colorScheme.palette.textMuted};
+ margin: 0px 2px;
+ padding: 0 15px;
+
+ border-radius: 999px;
+ box-shadow: inset 0 0 0 1px #${config.colorScheme.palette.backgroundMuted};
+ }
+
+ .modules-right > widget:last-child > #battery {
+ margin-right: 0px;
+ }
+
+ #tray {
+ padding: 4px 10px;
+ border-radius: 999px 999px 999px 999px;
+ box-shadow: inset 0px 0px 0 1px #${config.colorScheme.palette.backgroundMuted};
+ }
+
+ #window {
+ margin-left: 6px;
+ color: #${config.colorScheme.palette.textMuted};
+ }
+
+ #workspaces {
+ margin: 0 4px;
+ padding: 4px 4px;
+ border-radius: 999px;
+ box-shadow: inset 0px 0px 0 1px #${config.colorScheme.palette.backgroundMuted};
+ }
+
+ #cpu {
+ border-radius: 999px 0px 0px 999px;
+ margin-right: 0px;
+ }
+
+ #memory {
+ border-radius: 0px;
+ padding: 0 10px;
+ margin: 0px;
+ box-shadow: inset 0px 2px 0 -1px #${config.colorScheme.palette.backgroundMuted},
+ inset 0px -2px 0 -1px #${config.colorScheme.palette.backgroundMuted};
+ }
+
+ #clock {
+ box-shadow: none;
+ }
+
+
+ #battery {
+ min-width: 50px;
+ border-radius: 999px;
+ box-shadow: inset 0 0 0 1px #${config.colorScheme.palette.backgroundMuted};
+ background-color: #${config.colorScheme.palette.backgroundMuted};
+ transition: all 0.3s;
+ }
+
+ #battery.charging, #battery.plugged {
+ color: #${config.colorScheme.palette.succes};
+ background-color: transparent;
+ animation: batteryCharging 1.2s linear 0s infinite normal forwards,
+ }
+ #battery.full {
+ animation: batteryFull 7.0s linear 0s infinite normal forwards;
+ }
+ #battery.critical:not(.charging) {
+ background-color: #${config.colorScheme.palette.background};
+ animation: batteryCritical 1.2s linear 0s infinite normal forwards;
+ }
+
+ #network {
+
+ }
+
+ #network.disconnected,
+ #pulseaudio.muted {
+ transition: all 0.2s;
+ color: #${config.colorScheme.palette.backgroundMuted};
+ }
+
+ .custom-spotify {
+ color: #${config.colorScheme.palette.spotifyGreen};
+ margin-right: 10px;
+ }
+
+ #temperature {
+ margin-left: 0px;
+ border-radius: 0px 999px 999px 0px;
+ }
+
+ #temperature.critical {
+ background-color: transparent;
+ color: #${config.colorScheme.palette.danger};
+ }
+
+ #tray {
+ background-color: transparent;
+ }
+
+
+ #tray > .passive {
+ -gtk-icon-effect: dim;
+ }
+
+ #tray > .needs-attention {
+ background-color: #${config.colorScheme.palette.danger};
+ border-radius: 999px;
+ }
+
+ #scratchpad {
+ background: rgba(0, 0, 0, 0.1);
+ }
+ #scratchpad.empty {
+ background-color: transparent;
+ }
+
+ #custom-updates {
+ box-shadow: inset 0 0 0 1px #${config.colorScheme.palette.backgroundMuted};
+ color: #${config.colorScheme.palette.textMuted};
+ transition: all 0.5s;
+ }
+
+ #custom-updates.pending {
+ box-shadow: inset 0 0 0 2px #${config.colorScheme.palette.highlight};
+ color: #${config.colorScheme.palette.highlight};
+ font-weight: bold;
+ transition: all 0.5s;
+ }
+
+ tooltip {
+ background-color: #${config.colorScheme.palette.background};
+ border: 1px solid;
+ border-color: #${config.colorScheme.palette.border};
+ border-radius: 10px;
+ color: #${config.colorScheme.palette.text};
+ }
+ tooltip label {
+ padding: 5px;
+ }
+
+ /* Keyframes ---------------------------------------------------------------- */
+
+ @keyframes batteryCritical {
+ 0% {
+ box-shadow: inset 0px 20px 8px -16px #${config.colorScheme.palette.danger},
+ inset 0px -20px 8px -16px #${config.colorScheme.palette.danger};
+ color: #${config.colorScheme.palette.danger};
+ }
+ 50% {
+ box-shadow: inset 0px 12px 8px -16px #${config.colorScheme.palette.danger},
+ inset 0px -12px 8px -16px #${config.colorScheme.palette.danger};
+ color: #${config.colorScheme.palette.textMuted};
+ }
+ 100% {
+ box-shadow: inset 0px 20px 8px -16px #${config.colorScheme.palette.danger},
+ inset 0px -20px 8px -16px #${config.colorScheme.palette.danger};
+ color: #${config.colorScheme.palette.danger};
+ }
+ }
+
+ @keyframes batteryCharging {
+ 0% {
+ box-shadow: inset 0px 0px 8px 0px #${config.colorScheme.palette.info},
+ inset 0px 20px 8px -18px #${config.colorScheme.palette.ok},
+ inset 0px -20px 8px -18px #${config.colorScheme.palette.ok};
+ }
+ 25% {
+ box-shadow: inset 0px 0px 8px 0px #${config.colorScheme.palette.info},
+ inset 14px 14px 8px -18px #${config.colorScheme.palette.ok},
+ inset -14px -14px 8px -18px #${config.colorScheme.palette.ok};
+ }
+ 50% {
+ box-shadow: inset 0px 0px 8px 0px #${config.colorScheme.palette.info},
+ inset 20px 0px 8px -18px #${config.colorScheme.palette.ok},
+ inset -20px 0px 8px -18px #${config.colorScheme.palette.ok};
+ }
+ 75% {
+ box-shadow: inset 0px 0px 8px 0px #${config.colorScheme.palette.info},
+ inset 14px -14px 8px -18px #${config.colorScheme.palette.ok},
+ inset -14px 14px 8px -18px #${config.colorScheme.palette.ok};
+ }
+ 100% {
+ box-shadow: inset 0px 0px 8px 0px #${config.colorScheme.palette.info},
+ inset 0px -20px 8px -18px #${config.colorScheme.palette.ok},
+ inset 0px 20px 8px -18px #${config.colorScheme.palette.ok};
+ }
+ }
+
+
+
+ @keyframes batteryFull {
+ 0% {
+ box-shadow: inset 0px 20px 8px -16px #${config.colorScheme.palette.warn},
+ inset 0px -20px 8px -16px #${config.colorScheme.palette.warn};
+ color: #${config.colorScheme.palette.warn};
+ }
+ 25% {
+ box-shadow: inset 0px 19px 8px -16px #${config.colorScheme.palette.warn},
+ inset 0px -19px 8px -16px #${config.colorScheme.palette.warn};
+ color: #${config.colorScheme.palette.warn};
+ }
+ 50% {
+ box-shadow: inset 0px 15px 8px -16px #${config.colorScheme.palette.warn},
+ inset 0px -15px 8px -16px #${config.colorScheme.palette.warn};
+ color: #${config.colorScheme.palette.warn};
+ }
+ 75% {
+ box-shadow: inset 0px 19px 8px -16px #${config.colorScheme.palette.warn},
+ inset 0px -19px 8px -16px #${config.colorScheme.palette.warn};
+ color: #${config.colorScheme.palette.warn};
+ }
+ 100% {
+ box-shadow: inset 0px 20px 8px -16px #${config.colorScheme.palette.warn},
+ inset 0px -20px 8px -16px #${config.colorScheme.palette.warn};
+ color: #${config.colorScheme.palette.warn};
+ }
+ }
+ '';
+ };
+ };
+}
diff --git a/modules/wofi.nix b/modules/wofi.nix
new file mode 100644
index 0000000..41e9681
--- /dev/null
+++ b/modules/wofi.nix
@@ -0,0 +1,126 @@
+{ lib, config, pkgs, ... }:
+let
+ cfg = config.modules.wofi;
+in
+{
+ options.modules.wofi = {
+ enable = lib.mkEnableOption "enable wofi app launcher";
+ };
+ imports = [
+ ../common/colors.nix
+ ];
+ config = lib.mkIf cfg.enable {
+ home.packages = with pkgs; [
+ (writeShellScriptBin "wofi-launch" ''
+ ${wofi}/bin/wofi --show drun
+ '')
+ (writeShellScriptBin "wofi-power" ''
+ lock="Lock"
+ poweroff="Poweroff"
+ reboot="Reboot"
+ sleep="Suspend"
+
+ selected_option=$(echo -e "$lock\n$sleep\n$reboot\n$poweroff" | wofi --dmenu -i -p "Powermenu")
+
+ if [ "$selected_option" == "$lock" ]
+ then
+ echo "lock"
+ swaylock
+ elif [ "$selected_option" == "$poweroff" ]
+ then
+ echo "poweroff"
+ poweroff
+ elif [ "$selected_option" == "$reboot" ]
+ then
+ echo "reboot"
+ reboot
+ elif [ "$selected_option" == "$sleep" ]
+ then
+ echo "sleep"
+ suspend
+ else
+ echo "No match"
+ fi
+ '')
+ ];
+ programs.wofi = {
+ enable = true;
+ settings = {
+
+ };
+ style = ''
+ * {
+ outline: none;
+ outline-style: none;
+ }
+
+ #window {
+ margin: 10px;
+ border: none;
+ background-color: #${config.colorScheme.palette.background};
+ border-radius: 10px;
+ font-family:
+ JetBrains Mono NF,
+ monospace;
+ font-weight: bold;
+ font-size: 14px;
+ }
+
+ #outer-box {
+ margin: 10px;
+ border: 2px #${config.colorScheme.palette.backgroundMuted};
+ border-radius: 10px;
+ background-color: transparent;
+ }
+
+ #input {
+ border: none;
+ border-radius: 10px;
+ margin-left: 2px;
+ color: #${config.colorScheme.palette.info};
+ outline-style: none;
+ background-color: #${config.colorScheme.palette.background};
+ }
+
+ #scroll {
+ border: 10px solid #${config.colorScheme.palette.border};
+ border-radius: 10px;
+ /*padding-right: 10px;*/
+ outline: none;
+ background-color: #${config.colorScheme.palette.background};
+ }
+
+ #inner-box {
+ border: none;
+ border-radius: 10px;
+ background-color: transparent;
+ }
+
+ #entry {
+ border: none;
+ /*border-radius: 10px;
+ margin-right: 15px;
+ margin-left: 15px;*/
+ padding-right: 10px;
+ padding-left: 10px;
+ color: #${config.colorScheme.palette.text};
+ background-color: #${config.colorScheme.palette.background};
+ }
+ #entry:selected {
+ border: none;
+ background-color: #${config.colorScheme.palette.info};
+ }
+
+ #text:selected {
+ border: none;
+ color: #${config.colorScheme.palette.textMuted};
+ }
+
+ #img {
+ background-color: transparent;
+ margin-right: 6px;
+ }
+ '';
+ };
+ };
+}