diff --git a/flake.lock b/flake.lock
index b3be713..f1d86b0 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,22 +1,5 @@
{
"nodes": {
- "aq": {
- "flake": false,
- "locked": {
- "lastModified": 1736050555,
- "narHash": "sha256-TUoKhJ2QMK2AYTRvBCRpYFmaSihiF/OgB+HDZjamZtI=",
- "owner": "quantum9innovation",
- "repo": "aquamarine",
- "rev": "546ce7963d18cbd30b32bf8d464f9ab3f6d54f74",
- "type": "github"
- },
- "original": {
- "owner": "quantum9innovation",
- "ref": "patch-125",
- "repo": "aquamarine",
- "type": "github"
- }
- },
"base16": {
"inputs": {
"fromYaml": "fromYaml"
@@ -328,12 +311,26 @@
"type": "github"
}
},
+ "nixpkgs_2": {
+ "locked": {
+ "lastModified": 1745377448,
+ "narHash": "sha256-jhZDfXVKdD7TSEGgzFJQvEEZ2K65UMiqW5YJ2aIqxMA=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "507b63021ada5fee621b6ca371c4fca9ca46f52c",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
"nixvim": {
"inputs": {
"nixCats": "nixCats",
- "nixpkgs": [
- "nixpkgs"
- ],
+ "nixpkgs": "nixpkgs_2",
"plugins-blink-ripgrep": "plugins-blink-ripgrep",
"plugins-pomo-nvim": "plugins-pomo-nvim"
},
@@ -408,7 +405,6 @@
},
"root": {
"inputs": {
- "aq": "aq",
"home-manager": "home-manager",
"nixpkgs": "nixpkgs",
"nixvim": "nixvim",
diff --git a/flake.nix b/flake.nix
index 29d2ab1..4fba3ff 100644
--- a/flake.nix
+++ b/flake.nix
@@ -13,7 +13,6 @@
};
nixvim = {
url = "github:kaitotlex/vix1";
- inputs.nixpkgs.follows = "nixpkgs";
};
stylix = {
url = "github:danth/stylix";
@@ -31,10 +30,6 @@
url = "github:kaitotlex/wallpaper";
flake = false;
};
- aq = {
- url = "github:quantum9innovation/aquamarine/patch-125";
- flake = false;
- };
};
outputs =
diff --git a/hosts/shiroko/configuration.nix b/hosts/shiroko/configuration.nix
index b3ab013..724f932 100644
--- a/hosts/shiroko/configuration.nix
+++ b/hosts/shiroko/configuration.nix
@@ -13,19 +13,22 @@
];
services.fprintd.enable = true;
security.pam.services.login.fprintAuth = true;
- hardware.graphics.extraPackages = with pkgs; [ vaapiIntel intel-media-driver ];
- hardware.opengl = {
+ hardware.graphics.extraPackages = with pkgs; [
+ vaapiIntel
+ intel-media-driver
+ ];
+ hardware.graphics.enable32Bit = true;
+ hardware.opengl = {
enable = true;
extraPackages = with pkgs; [
# your Open GL, Vulkan and VAAPI drivers
- vpl-gpu-rt # for newer GPUs on NixOS >24.05 or unstable
+ vpl-gpu-rt # for newer GPUs on NixOS >24.05 or unstable
# onevpl-intel-gpu # for newer GPUs on NixOS <= 24.05
# intel-media-sdk # for older GPUs
];
};
hardware = {
- graphics.enable32Bit = true;
pulseaudio.support32Bit = true;
openrazer.enable = true;
};
@@ -150,7 +153,7 @@
};
# Select internationalisation properties.
-networking.firewall = {
+ networking.firewall = {
allowedUDPPorts = [ 51820 ]; # Clients and peers can use the same port, see listenport
};
# Enable WireGuard
@@ -189,7 +192,7 @@ networking.firewall = {
# ];
# };
# };
-i18n.defaultLocale = "en_US.UTF-8";
+ i18n.defaultLocale = "en_US.UTF-8";
i18n.extraLocaleSettings = {
LC_ADDRESS = "en_US.UTF-8";
@@ -202,7 +205,7 @@ i18n.defaultLocale = "en_US.UTF-8";
LC_TELEPHONE = "en_US.UTF-8";
LC_TIME = "en_US.UTF-8";
};
-
+
# Some programs need SUID wrappers, can be configured further or are
# started in user sessions.
# programs.mtr.enable = true;
diff --git a/hosts/shiroko/default.nix b/hosts/shiroko/default.nix
index a3cfae5..928917f 100644
--- a/hosts/shiroko/default.nix
+++ b/hosts/shiroko/default.nix
@@ -7,5 +7,6 @@
../../modules/audio
../../modules/stylix
../../modules/electrical
+ ../../modules/desktop-environment
];
}
diff --git a/modules/core/default.nix b/modules/core/default.nix
index 908bea6..7298a94 100644
--- a/modules/core/default.nix
+++ b/modules/core/default.nix
@@ -4,9 +4,6 @@
...
}:
{
- imports = [
- ../graphics
- ];
# Enable the X11 windowing system.
# You can disable this if you're only using the Wayland session.
services.xserver.enable = false;
diff --git a/modules/desktop-environment/default.nix b/modules/desktop-environment/default.nix
new file mode 100644
index 0000000..33981e5
--- /dev/null
+++ b/modules/desktop-environment/default.nix
@@ -0,0 +1,64 @@
+{
+ pkgs,
+ lib,
+ config,
+ ...
+}:
+let
+ cfg = config.liminalOS.desktop;
+in
+{
+ options.liminalOS.desktop = {
+ enable = lib.mkOption {
+ type = lib.types.bool;
+ default = true;
+ description = ''
+ Whether to enable the liminalOS desktop environment.
+ '';
+ };
+ hyprland.enable = lib.mkOption {
+ type = lib.types.bool;
+ default = cfg.enable;
+ description = ''
+ Whether to enable Hyprland. Sets up a default configuration at the system and user level, and installs xdg-desktop-portal-gtk.
+ '';
+ };
+ };
+
+ options.liminalOS.formFactor = lib.mkOption {
+ type = lib.types.nullOr (
+ lib.types.enum [
+ "laptop"
+ "desktop"
+ ]
+ );
+ default = "desktop";
+ description = ''
+ Form factor of the machine. Adjusts some UI settings.
+ '';
+ };
+
+ options.liminalOS.powersave = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Whether to set some options to reduce power consumption (mostly Hyprland).
+ '';
+ };
+
+ config = lib.mkIf cfg.enable {
+ xdg.portal = lib.mkIf cfg.hyprland.enable {
+ enable = true;
+ extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
+ };
+
+ programs.hyprland.enable = cfg.hyprland.enable;
+
+ services.xserver.enable = false;
+
+ services.xserver = {
+ xkb.layout = "us";
+ xkb.variant = "";
+ };
+ };
+}
diff --git a/modules/graphics/default.nix b/modules/graphics/default.nix
deleted file mode 100644
index 094830e..0000000
--- a/modules/graphics/default.nix
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- config,
- lib,
- inputs,
- ...
-}:
-let
- cfg = config.hardware.nvidia;
-in
-{
- options.hardware.nvidia.usePatchedAquamarine = lib.mkEnableOption "q9i's patched aquamarine with working sleep on Nvidia";
-
- config = lib.mkIf cfg.usePatchedAquamarine {
- nixpkgs.overlays = [
- (final: prev: {
- aquamarine = prev.aquamarine.overrideAttrs {
- src = inputs.aq;
- version = inputs.aq.rev;
- };
- })
- ];
- };
-}
diff --git a/users/kaitotlex/de/default.nix b/users/kaitotlex/de/default.nix
deleted file mode 100644
index d021f05..0000000
--- a/users/kaitotlex/de/default.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- imports = [
- ./sway
- ./waybar
- #./rofi
- ];
-}
diff --git a/users/kaitotlex/de/sway/default.nix b/users/kaitotlex/de/sway/default.nix
deleted file mode 100644
index 6fcf452..0000000
--- a/users/kaitotlex/de/sway/default.nix
+++ /dev/null
@@ -1,89 +0,0 @@
-{
- wayland.windowManager.sway = {
- enable = true;
- config = rec {
- terminal = "kitty";
- modifier = "Mod4";
- menu = "rofi -show combi";
- #lock = "swaylock";
- bars = [
- {
- command = "waybar";
- }
- ];
- gaps = {
- inner = 12;
- };
- # colors = {
- # focused = {
- # background = "#191724";
- # border = "#6e6a86";
- # childBorder = "#6e6a86";
- # indicator = "#26233a";
- # text = "#e0def4";
- # };
- # focusedInactive = {
- # background = "#797593";
- # border = "#393552";
- # childBorder = "#393552";
- # indicator = "#ea9d34";
- # text = "#e0def4";
- # };
- # placeholder = {
- # background = "#1f1d2e";
- # border = "#000000";
- # childBorder = "#9893a5";
- # indicator = "#000000";
- # text = "#e0def4";
- # };
- # unfocused = {
- # background = "#1f1d2e";
- # border = "#1f1d2e";
- # childBorder = "#1f1d2e";
- # indicator = "#797593";
- # text = "#e0def4";
- # };
- # urgent = {
- # background = "#2a273f";
- # border = "#ea9a97";
- # childBorder = "#ea9a97";
- # indicator = "#1f1d2e";
- # text = "#e0def4";
- # };
- # };
- window = {
- border = 3;
- titlebar = false;
- };
- # startup = [
- # {
- # always = true;
- # command = "swaybg -i /home/kaitotlex/Pictures/eff.png";
- # }
- # ];
- };
- xwayland = true;
- extraConfig = ''
- bindsym XF86AudioRaiseVolume exec pamixer -i 5
- bindsym XF86AudioLowerVolume exec pamixer -d 5
- bindsym XF86AudioMute exec pamixer -t
- bindsym XF86MonBrightnessUp exec brightnessctl s 5%+
- bindsym XF86MonBrightnessDown exec brightnessctl s 5%-
- bindsym XF86AudioMicMute exec spotify
- input "type:touchpad" {
- natural_scroll enabled
- tap enabled # enables click-on-tap
- tap_button_map lrm # tap with 1 finger = left click, 2 fingers = right click, 3 fingers = middle click
- #dwt enabled # disable (touchpad) while typing
- }
- bindsym XF86KbdBrightnessDown exec brightnessctl -d asus::kbd_backlight s 1-
- bindsym XF86KbdBrightnessUp exec brightnessctl -d asus::kbd_backlight s +1
- bindsym XF86Tools exec brightnessctl s 0
- bindsym XF86WebCam exec systemctl sleep
- bindsym Prior exec playerctl previous
- bindsym Next exec playerctl next
- bindsym XF86RotateWindows exec playerctl play-pause
- '';
- };
-
-}
diff --git a/users/kaitotlex/de/waybar/default.nix b/users/kaitotlex/de/waybar/default.nix
deleted file mode 100644
index 0d7fb89..0000000
--- a/users/kaitotlex/de/waybar/default.nix
+++ /dev/null
@@ -1,172 +0,0 @@
-{ pkgs, ... }:
-{
- programs.waybar = {
- enable = true;
- style = ./style.css;
- settings = {
- mainBar = {
- name = "bar0";
-
- layer = "top";
- position = "top";
-
- height = 28;
- # "width" = 1920;
-
- "margin" = "5px 10px 0px 10px";
- "spacing" = 10;
-
- "mode" = "top";
- # "exclusive" = true;
-
- # "output" = "eDP-1";
-
- reload_style_on_change = true;
-
- modules-left = [
- "sway/workspaces"
- "sway/window"
- ];
- modules-right = [
- "tray"
- "idle_inhibitor"
- "backlight"
- "wireplumber"
- "network"
- "battery"
- "disk"
- "memory"
- "cpu"
- "temperature"
- "clock"
- ];
-
- idle_inhibitor = {
- format = "{icon}";
- format-icons = {
- activated = " ";
- deactivated = " ";
- };
- };
-
- network = {
- format = "{ifname}";
- format-wifi = "{icon}{essid}";
- format-ethernet = " {essid}";
- format-disconnected = " Disconnected";
- format-icons = [
- " "
- " "
- " "
- ];
- tooltip-format = " {bandwidthUpBits} | {bandwidthDownBits}";
- tooltip-format-wifi = " {bandwidthUpBits} | {bandwidthDownBits} | {signalStrength}";
- };
-
- backlight = {
- interval = 2;
- format = " {percent}%";
- on-scroll-up = "${pkgs.brightnessctl}/bin/brightnessctl -d amdgpu_bl2 set 10%";
- on-scroll-down = "${pkgs.brightnessctl}/bin/brightnessctl -d amdgpu_bl2 set 10%-";
- };
-
- wireplumber = {
- format = "{icon} {volume}%";
- format-muted = " ";
- on-click = "pamixer -t";
- on-scroll-up = "${pkgs.pamixer}/bin/pamixer set 5%+";
- on-scroll-down = "${pkgs.pamixer}/bin/pamixer set 5%-";
- format-icons = [
- ""
- ""
- ""
- ""
- ""
- ];
- };
-
- battery = {
- interval = 10;
- format = "{icon} {capacity}%";
- format-icons = [
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ];
- tooltip = true;
- tooltip-format = "{timeTo}";
- };
-
- disk = {
- intervel = 30;
- format = " {percentage_used}%";
- tooltip-format = "{used} used out of {total} on \"{path}\" ({percentage_used}%)";
- };
-
- memory = {
- interval = 10;
- format = " {used}";
- tooltip-format = "{used}GiB used of {total}GiB ({percentage}%)";
- };
-
- cpu = {
- interval = 10;
- format = " {usage}%";
- };
-
- temperature = {
- interval = 10;
- };
-
- clock = {
- interval = 1;
- format = "{:%H:%M:%S}";
- };
-
- "hyprland/workspaces" = {
- show-special = true;
- persistent-workspaces = {
- "*" = [
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- ];
- };
- format = "{icon}";
- format-icons = {
- active = "";
- empty = "";
- default = "";
- urgent = "";
- special = "";
- };
- };
- "hyprland/window" = {
- icon = true;
- icon-size = 20;
- max-length = 50;
- rewrite = {
- "(.*) — firefox" = "$1";
- "(.*) — chromium" = "$1";
- "^$" = "👾";
- };
- };
- };
- };
- };
-}
diff --git a/users/kaitotlex/de/waybar/nord.css b/users/kaitotlex/de/waybar/nord.css
deleted file mode 100644
index 7ae564f..0000000
--- a/users/kaitotlex/de/waybar/nord.css
+++ /dev/null
@@ -1,27 +0,0 @@
-@define-color bg #2E3440;
-/*@define-color bg #353C4A;*/
-@define-color light #D8DEE9;
-/*@define-color dark @nord_dark_font;*/
-@define-color warning #ebcb8b;
-@define-color critical #BF616A;
-@define-color mode #434C5E;
-/*@define-color workspaces @bg;*/
-/*@define-color workspaces @nord_dark_font;*/
-/*@define-color workspacesfocused #434C5E;*/
-@define-color workspacesfocused #4C566A;
-@define-color tray @workspacesfocused;
-@define-color sound #EBCB8B;
-@define-color network #5D7096;
-@define-color memory #546484;
-@define-color cpu #596A8D;
-@define-color temp #4D5C78;
-@define-color layout #5e81ac;
-@define-color battery #88c0d0;
-@define-color date #434C5E;
-@define-color time #434C5E;
-@define-color backlight #434C5E;
-@define-color nord_bg #434C5E;
-@define-color nord_bg_blue #546484;
-@define-color nord_light #D8DEE9;
-@define-color nord_light_font #D8DEE9;
-@define-color nord_dark_font #434C5E;
diff --git a/users/kaitotlex/de/waybar/rose-pine-dawn.css b/users/kaitotlex/de/waybar/rose-pine-dawn.css
deleted file mode 100644
index a85bab2..0000000
--- a/users/kaitotlex/de/waybar/rose-pine-dawn.css
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-* Variant: Rosé Pine Dawn
-* Maintainer: DankChoir
-*/
-
-@define-color base #faf4ed;
-@define-color surface #fffaf3;
-@define-color overlay #f2e9e1;
-
-@define-color muted #9893a5;
-@define-color subtle #797593;
-@define-color text #575279;
-
-@define-color love #b4637a;
-@define-color gold #ea9d34;
-@define-color rose #d7827e;
-@define-color pine #286983;
-@define-color foam #56949f;
-@define-color iris #907aa9;
-
-@define-color highlightLow #f4ede8;
-@define-color highlightMed #dfdad9;
-@define-color highlightHigh #cecacd;
diff --git a/users/kaitotlex/de/waybar/style.css b/users/kaitotlex/de/waybar/style.css
deleted file mode 100644
index b87b208..0000000
--- a/users/kaitotlex/de/waybar/style.css
+++ /dev/null
@@ -1,75 +0,0 @@
-@import "./nord.css";
-window#waybar {
- font-family: "CaskaydiaCove Nerd Font";
- background-color: @bg;
- font-size: 0.8rem;
- border-radius: 0.5rem;
-}
-
-.modules-left {
- opacity: 1;
- background-color: #95a3bb;
- border-radius: 0.5rem;
- padding: 2px;
-}
-
-.modules-center {
- opacity: 0;
-}
-
-.modules-right {
- opacity: 1;
- background-color: #95a3bb;
- border-radius: 0.5rem;
- padding: 2px 2px 2px 10px
-}
-
-/* label.module {
- margin-left: -1px;
-} */
-
-#workspaces {
- background-color: #6e7581;
- border-radius: 0.5rem;
- padding: 0 2px;
-}
-
-#workspaces button {
- font-size: 0.6rem;
- padding: 0 0.3rem 0 0;
-}
-
-#window {
- background-color: #95a3bb;
- border-radius: 0.5rem;
- padding: 2px 5px;
-}
-
-#clock {
- border-radius: 0.5rem;
- padding: 0 3px 0 0;
-}
-
-#battery {
- color: @date;
-}
-
-#memory {
- color: @memory;
-}
-
-#disk {
- color: @date;
-}
-
-#cpu {
- color: @cpu;
-}
-
-#temperature {
- color: @temp;
-}
-
-#network {
- color: @network;
-}
diff --git a/users/kaitotlex/de/waybar/style.css.bak b/users/kaitotlex/de/waybar/style.css.bak
deleted file mode 100644
index 9fbd8ff..0000000
--- a/users/kaitotlex/de/waybar/style.css.bak
+++ /dev/null
@@ -1,76 +0,0 @@
-@import "./rose-pine-dawn.css";
-window#waybar {
- font-family: "CaskaydiaCove Nerd Font";
- background-color: @base;
- font-size: 0.8rem;
- border-radius: 0.5rem;
-}
-
-.modules-left {
- opacity: 1;
- background: linear-gradient(45deg, @muted, @subtle);
- border-radius: 0.5rem;
- padding: 2px;
-}
-
-.modules-center {
- opacity: 0;
-}
-
-.modules-right {
- opacity: 1;
- background-color: @subtle;
- border-radius: 0.5rem;
- padding: 2px 2px 2px 10px
-}
-
-/* label.module {
- margin-left: -1px;
-} */
-
-#workspaces {
- background-color: @rose;
- border-radius: 0.5rem;
- padding: 0 2px;
-}
-
-#workspaces button {
- font-size: 0.6rem;
- padding: 0 0.3rem 0 0;
-}
-
-#window {
- background-color: @iris;
- border-radius: 0.5rem;
- padding: 2px 5px;
-}
-
-#clock {
- border-radius: 0.5rem;
- padding: 0 3px 0 0;
-}
-
-#battery {
- color: @foam;
-}
-
-#memory {
- color: @iris;
-}
-
-#disk {
- color: @gold;
-}
-
-#cpu {
- color: @rose;
-}
-
-#temperature {
- color: @foam;
-}
-
-#network {
- color: @rose;
-}
-
diff --git a/users/kaitotlex/default.nix b/users/kaitotlex/default.nix
index 51cda52..1ff4145 100644
--- a/users/kaitotlex/default.nix
+++ b/users/kaitotlex/default.nix
@@ -2,7 +2,10 @@
imports = [
./home.nix
./spicetify.nix
- ./de
./stylix
+ ./desktop-environment
];
+
+ liminalOS.formFactor = "desktop";
+ liminalOS.powersave = false;
}
diff --git a/users/kaitotlex/desktop-environment/default.nix b/users/kaitotlex/desktop-environment/default.nix
new file mode 100644
index 0000000..18ac71f
--- /dev/null
+++ b/users/kaitotlex/desktop-environment/default.nix
@@ -0,0 +1,22 @@
+{
+ osConfig,
+ lib,
+ ...
+}:
+{
+ imports = [
+ ./hyprland
+ ./waybar
+ ./swaync.nix
+ ];
+
+ options.liminalOS.desktop = {
+ enable = lib.mkOption {
+ type = lib.types.bool;
+ default = osConfig.liminalOS.desktop.enable;
+ description = ''
+ Whether to enable the default configuration for the userland portions of the liminalOS desktop environment.
+ '';
+ };
+ };
+}
diff --git a/users/kaitotlex/desktop-environment/hyprland/binds.nix b/users/kaitotlex/desktop-environment/hyprland/binds.nix
new file mode 100644
index 0000000..2b40153
--- /dev/null
+++ b/users/kaitotlex/desktop-environment/hyprland/binds.nix
@@ -0,0 +1,95 @@
+{
+ lib,
+ pkgs,
+ config,
+ ...
+}:
+let
+ cfg = config.liminalOS.desktop.hyprland;
+ hyprnome = "${pkgs.hyprnome}/bin/hyprnome";
+in
+{
+ wayland.windowManager.hyprland.settings = lib.mkIf cfg.enable {
+ bind = [
+ "$mod+Shift, $Left, scroller:movewindow, l"
+ "$mod+Shift, $Right, scroller:movewindow, r"
+ "$mod+Shift, $Up, scroller:movewindow, u"
+ "$mod+Shift, $Down, scroller:movewindow, d"
+
+ # Move around
+ "$mod, $Left, scroller:movefocus, l"
+ "$mod, $Right, scroller:movefocus, r"
+ "$mod, $Up, scroller:movefocus, u"
+ "$mod, $Down, scroller:movefocus, d"
+ "$mod, comma, scroller:admitwindow"
+ "$mod, period, scroller:expelwindow"
+ "$mod, F, scroller:fitsize, active"
+ "$mod, Y, scroller:fitsize, all"
+ "$mod, semicolon, scroller:cyclesize, next"
+ "$mod, apostrophe, scroller:cyclesize, previous"
+
+ "$mod+Shift, U, exec, ${hyprnome} --move"
+ "$mod+Shift, I, exec, ${hyprnome} --previous --move"
+
+ "$mod, U, exec, ${hyprnome}"
+ "$mod, I, exec, ${hyprnome} --previous"
+
+ "$mod, C, scroller:setmode, c"
+ "$mod, V, scroller:setmode, r"
+
+ "$mod, G, scroller:jump"
+ "$mod+Ctrl, G, scroller:toggleoverview"
+ # Window actions
+ "$mod, Q, killactive"
+ "$mod, W, togglefloating"
+ "$mod, Return, fullscreen"
+
+ # Utilities
+ "$mod, Space, exec, pkill -x rofi || rofi -show drun" # Run rofi application launcher
+ "$mod, X, exec, pkill -x rofi || rofi -show window" # Run rofi window switcher
+
+ "$mod, Backspace, exec, pkill -x wlogout || wlogout" # show logout menu
+
+ "$mod, Z, exec, loginctl lock-session"
+
+ # Media controls
+ ",XF86AudioMute, exec, ${pkgs.pamixer}/bin/pamixer -t"
+ ",XF86AudioPlay, exec, ${pkgs.playerctl}/bin/playerctl --player=%any,firefox play-pause"
+ ",XF86AudioNext, exec, ${pkgs.playerctl}/bin/playerctl --player=%any,firefox next"
+ ",XF86AudioRewind, exec, ${pkgs.playerctl}/bin/playerctl --player=%any,firefox previous"
+
+ "$mod, S, togglespecialworkspace"
+ "$mod+Alt, S, movetoworkspacesilent, special"
+ "$mod, Tab, workspace, previous"
+ ''$mod+Shift, P, exec, ${pkgs.grim}/bin/grim - | ${pkgs.swappy}/bin/swappy -f -'' # Screenshot full screen
+ ''$mod, P, exec, ${pkgs.grim}/bin/grim -g "$(${pkgs.slurp}/bin/slurp)" - | ${pkgs.swappy}/bin/swappy -f -'' # Screenshot
+
+ "$mod, B, exec, zen"
+
+ "$mod, N, exec, sleep 0.1 && ${pkgs.swaynotificationcenter}/bin/swaync-client -t -sw"
+ # Application Keybinds
+ "$mod, R, exec, ${pkgs.pavucontrol}/bin/pavucontrol -t 3" # open pavucontrol on 'outputs' tab
+ "$mod, T, exec, ${pkgs.kitty}/bin/kitty"
+ "$mod, E, exec, ${pkgs.xfce.thunar}/bin/thunar"
+ "$mod, M, exec, ${pkgs.thunderbird}/bin/thunderbird"
+ ];
+
+ bindm = [
+ "$mod, mouse:272, movewindow"
+ "$mod, mouse:273, resizewindow"
+ ];
+ bindel = [
+ ",XF86MonBrightnessDown, exec, ${pkgs.brightnessctl}/bin/brightnessctl set 5%-"
+ ",XF86MonBrightnessUp, exec, ${pkgs.brightnessctl}/bin/brightnessctl set 5%+"
+ ",XF86AudioRaiseVolume, exec, ${pkgs.pamixer}/bin/pamixer -i 5"
+ ",XF86AudioLowerVolume, exec, ${pkgs.pamixer}/bin/pamixer -d 5"
+ ];
+ binde = [
+ # Resize windows
+ "$mod+Alt, $Right, resizeactive, 30 0"
+ "$mod+Alt, $Left, resizeactive, -30 0"
+ "$mod+Alt, $Up, resizeactive, 0 -30"
+ "$mod+Alt, $Down, resizeactive, 0 30"
+ ];
+ };
+}
diff --git a/users/kaitotlex/desktop-environment/hyprland/default.nix b/users/kaitotlex/desktop-environment/hyprland/default.nix
new file mode 100644
index 0000000..ab83cd4
--- /dev/null
+++ b/users/kaitotlex/desktop-environment/hyprland/default.nix
@@ -0,0 +1,242 @@
+{
+ pkgs,
+ config,
+ lib,
+ osConfig,
+ ...
+}:
+let
+ cfg = config.liminalOS.desktop.hyprland;
+in
+{
+ imports = [
+ ./binds.nix
+ ./utilities.nix
+ ./windowrules.nix
+ ];
+
+ options.liminalOS.formFactor = lib.mkOption {
+ type = lib.types.nullOr (
+ lib.types.enum [
+ "laptop"
+ "desktop"
+ ]
+ );
+ default = osConfig.liminalOS.formFactor;
+ description = ''
+ Form factor of the machine. Adjusts some UI settings.
+ '';
+ };
+
+ options.liminalOS.powersave = lib.mkOption {
+ type = lib.types.bool;
+ default = osConfig.liminalOS.powersave;
+ description = ''
+ Whether to set some options to reduce power consumption (mostly Hyprland).
+ '';
+ };
+
+ options.liminalOS.desktop.hyprland = {
+ enable = lib.mkOption {
+ type = lib.types.bool;
+ default = config.liminalOS.desktop.enable;
+ description = ''
+ Whether to enable and rice Hyprland as well as some basic desktop utilities.
+ '';
+ };
+ gtkUseOpenGL = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Whether to set GSK_RENDERER environment variable to stop GTK apps from crashing.
+ '';
+ };
+ idleDaemon.enable = lib.mkOption {
+ type = lib.types.bool;
+ default = cfg.enable;
+ description = ''
+ Whether to setup and enable Hypridle with some defaults to automatically lock the screen and suspend after idling.
+ '';
+ };
+ screenlocker.enable = lib.mkOption {
+ type = lib.types.bool;
+ default = cfg.enable && cfg.idleDaemon.enable;
+ description = ''
+ Whether to set up Hyprlock for screen locking.
+ '';
+ };
+ screenlocker.useCrashFix = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Whether to use a workaround for Hyprlock background blur not working on some machines. Before locking, a screenshot will be taken and placed at `/tmp/__hyprlock-monitor-screenshot.png`.
+ '';
+ };
+ screenlocker.monitor = lib.mkOption {
+ type = lib.types.nullOr lib.types.str;
+ default = null;
+ description = ''
+ Monitor to use for screen locker. Use `hyprctl monitors` to determine.
+ '';
+ };
+ bluelight.enable = lib.mkOption {
+ type = lib.types.bool;
+ default = true;
+ description = ''
+ Whether to enable `hyprsunset` as a daemon.
+ '';
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ home.packages = with pkgs; [
+ wl-clipboard
+ libsForQt5.qtstyleplugin-kvantum
+ libsForQt5.qt5ct
+ papirus-icon-theme
+ libsForQt5.qt5ct
+ hyprland-qtutils
+ ];
+
+ wayland.windowManager.hyprland = {
+ enable = true;
+ plugins = [
+ (pkgs.hyprlandPlugins.hyprscroller.overrideAttrs {
+ version = "0-unstable-2025-03-28";
+ src = pkgs.fetchFromGitHub {
+ owner = "dawsers";
+ repo = "hyprscroller";
+ rev = "3f86916f3e9a583154b1be0af4e8a1ef1f7435b2";
+ hash = "sha256-mgYq3vc4JtIzVuAKTWdALOynImYyNZEXh7tiVPvMZg4=";
+ };
+ })
+ ];
+ settings = {
+ exec-once = [
+ "hyprctl dispatch workspace 100000"
+ ];
+ "$mod" = "SUPER";
+ "$Left" = "H";
+ "$Right" = "L";
+ "$Up" = "K";
+ "$Down" = "J";
+ env = (
+ lib.optionals cfg.gtkUseOpenGL [
+ "GSK_RENDERER,ngl"
+ ]
+ );
+ layerrule = [
+ "blur,rofi"
+ "ignorezero,rofi"
+ "animation slide bottom 0.2 0.2 wind,rofi"
+ "blur,notifications"
+ "ignorezero,notifications"
+ "blur,swaync-notification-window"
+ "animation slide right 0.5 0.5,swaync-control-center"
+ "animation slide right 0.5 0.5,notifications"
+ "animation slide right 0.5 0.5,swaync-notification-window"
+ "ignorezero,swaync-notification-window"
+ "blur,swaync-control-center"
+ "ignorezero,swaync-control-center"
+ "blur,logout_dialog"
+ ];
+ dwindle = {
+ pseudotile = "yes";
+ preserve_split = "yes";
+ };
+ animations = {
+ enabled = "yes";
+ bezier = [
+ "wind, 0.05, 0.9, 0.1, 1.05"
+ "winIn, 0.1, 1.1, 0.1, 1.1"
+ "winOut, 0.3, -0.3, 0, 1"
+ "liner, 1, 1, 1, 1"
+ "windup, 0.05, 0.9, 0.1, 1.05"
+ ];
+ animation =
+ [
+ "windows, 1, 6, wind, slide"
+ "windowsIn, 1, 6, winIn, slide"
+ "windowsOut, 1, 5, winOut, slide"
+ "windowsMove, 1, 5, wind, slide"
+ "fade, 1, 10, default"
+ # "layers, 1, 8, default, slide"
+ "workspaces, 1, 5, wind, slidefadevert"
+ ]
+ ++ (lib.optionals (!osConfig.liminalOS.powersave) [
+ "border, 1, 1, liner"
+ "borderangle, 1, 30, liner, loop"
+ ]);
+ };
+
+ general =
+ let
+ inherit (config.lib.stylix) colors;
+ in
+ {
+ gaps_in = "3";
+ gaps_out = "8";
+ border_size = "2";
+ # "col.active_border" = pkgs.lib.mkForce "rgba(ca9ee6ff) rgba(f2d5cfff) 45deg";
+ # "col.inactive_border" = pkgs.lib.mkForce "rgba(b4befecc) rgba(6c7086cc) 45deg";
+ "col.active_border" = "rgba(${colors.base0A}ff) rgba(${colors.base09}ff) 45deg";
+ "col.inactive_border" = "rgba(${colors.base01}cc) rgba(${colors.base02}cc) 45deg";
+ layout = "scroller";
+ resize_on_border = "true";
+ };
+
+ misc = {
+ disable_hyprland_logo = true;
+ disable_splash_rendering = true;
+ };
+
+ cursor = {
+ hide_on_key_press = true;
+ };
+
+ decoration = {
+ rounding = "10";
+ dim_special = "0.3";
+ blur = {
+ enabled = "yes";
+ size = "6";
+ passes = "3";
+ new_optimizations = "on";
+ ignore_opacity = "on";
+ xray = "false";
+ special = true;
+ };
+ shadow = {
+ enabled = false;
+ };
+ };
+ input = {
+ sensitivity = if config.liminalOS.formFactor == "laptop" then "0.0" else "-0.65";
+ };
+ plugin.scroller = {
+ column_widths = "onethird onehalf twothirds one";
+ column_heights = "onethird onehalf twothirds one";
+ };
+ experimental.xx_color_management_v4 = true;
+ };
+ };
+
+ wayland.windowManager.hyprland.settings.input.touchpad =
+ lib.mkIf (config.liminalOS.formFactor == "laptop")
+ {
+ natural_scroll = true;
+ disable_while_typing = true;
+ clickfinger_behavior = true;
+ tap-to-click = false;
+ scroll_factor = 0.15;
+ };
+
+ assertions = [
+ {
+ assertion =
+ !cfg.screenlocker.useCrashFix || (cfg.screenlocker.useCrashFix && cfg.screenlocker.monitor != null);
+ message = "To use the Nvidia crash fix, you must set screenlocker.monitor to the monitor you want to use as the lock screen that blurs! Use `hyprctl monitors` to determine the monitor codes (should be something like DP-1, HDMI-A-1, etc).";
+ }
+ ];
+ };
+}
diff --git a/users/kaitotlex/desktop-environment/hyprland/utilities.nix b/users/kaitotlex/desktop-environment/hyprland/utilities.nix
new file mode 100644
index 0000000..40b3fff
--- /dev/null
+++ b/users/kaitotlex/desktop-environment/hyprland/utilities.nix
@@ -0,0 +1,183 @@
+{
+ pkgs,
+ lib,
+ config,
+ ...
+}:
+let
+ cfg = config.liminalOS.desktop.hyprland;
+in
+{
+ config = lib.mkIf cfg.enable {
+ systemd.user.services = lib.mkIf cfg.bluelight.enable {
+ hyprsunset = {
+ Unit = {
+ Description = "Start the hyprsunset daemon";
+ PartOf = "hyprland-session.target";
+ After = "hyprland-session.target";
+ };
+ Service = {
+ Type = "simple";
+ ExecStart = "${pkgs.hyprsunset}/bin/hyprsunset";
+ Restart = "on-failure";
+ RestartSec = 3;
+ };
+ Install = {
+ WantedBy = [ "hyprland-session.target" ];
+ };
+ };
+ };
+
+ services.hyprpaper.enable = true;
+
+ programs.wlogout.enable = true;
+
+ programs.rofi = {
+ enable = true;
+ package = pkgs.rofi-wayland;
+ terminal = "${pkgs.kitty}/bin/kitty";
+ theme =
+ let
+ inherit (config.lib.formats.rasi) mkLiteral;
+ mkRgba =
+ opacity: color:
+ let
+ c = config.lib.stylix.colors;
+ r = c."${color}-rgb-r";
+ g = c."${color}-rgb-g";
+ b = c."${color}-rgb-b";
+ in
+ mkLiteral "rgba ( ${r}, ${g}, ${b}, ${opacity} % )";
+ mkRgb = mkRgba "100";
+ rofiOpacity = builtins.toString (builtins.ceil (config.stylix.opacity.popups * 100));
+ in
+ {
+ "*" = {
+ font = "${config.stylix.fonts.monospace.name} ${toString config.stylix.fonts.sizes.popups}";
+ text-color = mkRgb "base05";
+ background-color = mkRgba rofiOpacity "base00";
+ };
+ "window" = {
+ height = mkLiteral "20em";
+ width = mkLiteral "30em";
+ border-radius = mkLiteral "8px";
+ border-width = mkLiteral "2px";
+ padding = mkLiteral "1.5em";
+ };
+ "mainbox" = {
+ background-color = mkRgba rofiOpacity "base01";
+ };
+ "inputbar" = {
+ margin = mkLiteral "0 0 1em 0";
+ };
+ "prompt" = {
+ enabled = false;
+ };
+ "entry" = {
+ placeholder = "Search...";
+ padding = mkLiteral "1em 1em";
+ text-color = mkRgb "base05";
+ background-color = mkRgba rofiOpacity "base00";
+ border-radius = mkLiteral "8px";
+ };
+ "element-text" = {
+ padding = mkLiteral "0.5em 1em";
+ margin = mkLiteral "0 0.5em";
+ };
+ "element-icon" = {
+ size = mkLiteral "3ch";
+ };
+ "element-text selected" = {
+ background-color = mkRgba rofiOpacity "base0A";
+ text-color = mkRgb "base01";
+ border-radius = mkLiteral "8px";
+ };
+ };
+ };
+
+ services.swayosd.enable = true;
+
+ programs.hyprlock = lib.mkIf cfg.screenlocker.enable {
+ enable = true;
+ settings = {
+ general = {
+ hide_cursor = true;
+ grace = 0;
+ };
+ background = {
+ monitor = cfg.screenlocker.monitor;
+ path =
+ if cfg.screenlocker.useCrashFix then "/tmp/__hyprlock-monitor-screenshot.png" else "screenshot";
+ blur_passes = 3;
+ blur_size = 7;
+ noise = 0.0117;
+ contrast = 0.8916;
+ brightness = 0.8172;
+ vibrancy = 0.1696;
+ vibrancy_darkness = 0.0;
+ };
+ input-field = {
+ monitor = "";
+ size = "200, 50";
+ outline_thickness = 3;
+ dots_size = 0.33;
+ dots_spacing = 0.15;
+ dots_center = false;
+ dots_rounding = -1;
+ outer_color = "rgb(151515)";
+ inner_color = "rgb(200, 200, 200)";
+ font_color = "rgb(10, 10, 10)";
+ fade_on_empty = true;
+ fade_timeout = 1000;
+ placeholder_text = "Input Password...";
+ hide_input = false;
+ rounding = -1;
+ check_color = "rgb(204, 136, 34)";
+ fail_color = "rgb(204, 34, 34)";
+ fail_text = "$FAIL ($ATTEMPTS)";
+ fail_timeout = 2000;
+ fail_transition = 300;
+ capslock_color = -1;
+ numlock_color = -1;
+ bothlock_color = -1;
+ invert_numlock = false;
+ swap_font_color = false;
+
+ position = "0, -20";
+ halign = "center";
+ valign = "center";
+ };
+ };
+ };
+
+ services.hypridle = lib.mkIf cfg.idleDaemon.enable {
+ enable = true;
+ settings = {
+ general = {
+ lock_cmd =
+ if cfg.screenlocker.useCrashFix then
+ "pidof hyprlock || ${pkgs.grim}/bin/grim -o ${config.programs.hyprlock.settings.background.monitor} /tmp/__hyprlock-monitor-screenshot.png && ${pkgs.hyprlock}/bin/hyprlock"
+ else
+ "pidof hyprlock || hyprlock";
+ before_sleep_cmd = "loginctl lock-session"; # lock before suspend.
+ after_sleep_cmd = "hyprctl dispatch dpms on"; # to avoid having to press a key twice to turn on the display.
+ };
+ listener = [
+ {
+ timeout = 1500;
+ on-timeout = "loginctl lock-session";
+ }
+ {
+ timeout = 330; # 5.5min
+ on-timeout = "hyprctl dispatch dpms off"; # screen off when timeout has passed
+ on-resume = "hyprctl dispatch dpms on"; # screen on when activity is detected after timeout has fired.
+ }
+ {
+ timeout = 1800;
+ on-timeout = "systemctl suspend";
+ }
+ ];
+ };
+ };
+ };
+}
diff --git a/users/kaitotlex/desktop-environment/hyprland/windowrules.nix b/users/kaitotlex/desktop-environment/hyprland/windowrules.nix
new file mode 100644
index 0000000..017128d
--- /dev/null
+++ b/users/kaitotlex/desktop-environment/hyprland/windowrules.nix
@@ -0,0 +1,95 @@
+{ config, lib, ... }:
+{
+ config.wayland.windowManager.hyprland.settings.windowrulev2 =
+ lib.mkIf config.liminalOS.desktop.hyprland.enable
+ [
+ "opacity 0.90 0.90,class:^(librewolf)$"
+ "opacity 0.90 0.90,class:^(floorp)$"
+ "opacity 0.90 0.90,class:^(zen-alpha)$"
+ "opacity 0.90 0.90,class:^(zen-beta)$"
+ "opacity 0.90 0.90,class:^(zen)$"
+ "opacity 0.90 0.90,class:^(Brave-browser)$"
+ "opacity 0.80 0.80,class:^(Steam)$"
+ "opacity 0.80 0.80,class:^(steam)$"
+ "opacity 0.80 0.80,class:^(steamwebhelper)$"
+ "opacity 0.80 0.80,class:^(Spotify)$"
+ "opacity 0.80 0.80,initialTitle:^(Spotify Premium)$"
+ "opacity 0.80 0.80,initialTitle:^(Spotify Free)$"
+ "opacity 0.80 0.80,class:^(code-oss)$"
+ "opacity 0.80 0.80,class:^(Code)$"
+ "opacity 0.80 0.80,class:^(code-url-handler)$"
+ "opacity 0.80 0.80,class:^(code-insiders-url-handler)$"
+ "opacity 0.80 0.80,class:^(kitty)$"
+ "opacity 0.80 0.80,class:^(neovide)$"
+ "opacity 0.80 0.80,class:^(org.kde.dolphin)$"
+ "opacity 0.80 0.80,class:^(thunar)$"
+ "opacity 0.80 0.80,class:^(org.kde.ark)$"
+ "opacity 0.80 0.80,class:^(nwg-look)$"
+ "opacity 0.80 0.80,class:^(qt5ct)$"
+ "opacity 0.80 0.80,class:^(qt6ct)$"
+ "opacity 0.80 0.80,class:^(kvantummanager)$"
+ "opacity 0.80 0.80,class:^(waypaper)$"
+ "opacity 0.80 0.80,class:^(org.pulseaudio.pavucontrol)$"
+ "opacity 0.80 0.80,class:^(com.github.wwmm.easyeffects)$"
+ "opacity 0.80 0.80,class:^(thunderbird)$"
+
+ "opacity 0.90 0.90,class:^(com.github.rafostar.Clapper)$ # Clapper-Gtk"
+ "opacity 0.80 0.80,class:^(com.github.tchx84.Flatseal)$ # Flatseal-Gtk"
+ "opacity 0.80 0.80,class:^(hu.kramo.Cartridges)$ # Cartridges-Gtk"
+ "opacity 0.80 0.80,class:^(com.obsproject.Studio)$ # Obs-Qt"
+ "opacity 0.80 0.80,class:^(gnome-boxes)$ # Boxes-Gtk"
+ "opacity 0.80 0.80,class:^(discord)$ # Discord-Electron"
+ "opacity 0.80 0.80,class:^(vesktop)$ # Vesktop-Electron"
+ "opacity 0.80 0.80,class:^(ArmCord)$ # ArmCord-Electron"
+ "opacity 0.80 0.80,class:^(app.drey.Warp)$ # Warp-Gtk"
+ "opacity 0.80 0.80,class:^(net.davidotek.pupgui2)$ # ProtonUp-Qt"
+ "opacity 0.80 0.80,class:^(yad)$ # Protontricks-Gtk"
+ "opacity 0.80 0.80,class:^(signal)$ # Signal-Gtk"
+ "opacity 0.80 0.80,class:^(io.github.alainm23.planify)$ # planify-Gtk"
+ "opacity 0.80 0.80,class:^(io.gitlab.theevilskeleton.Upscaler)$ # Upscaler-Gtk"
+ "opacity 0.80 0.80,class:^(com.github.unrud.VideoDownloader)$ # VideoDownloader-Gtk"
+ "opacity 0.80 0.80,class:^(lutris)$ # Lutris game launcher"
+
+ "opacity 0.80 0.70,class:^(pavucontrol)$"
+ "opacity 0.80 0.70,class:^(blueman-manager)$"
+ "opacity 0.80 0.70,class:^(nm-applet)$"
+ "opacity 0.80 0.70,class:^(nm-connection-editor)$"
+ "opacity 0.80 0.70,class:^(org.kde.polkit-kde-authentication-agent-1)$"
+
+ "float,class:^(org.kde.dolphin)$,title:^(Progress Dialog — Dolphin)$"
+ "float,class:^(org.kde.dolphin)$,title:^(Copying — Dolphin)$"
+ "float,title:^(Picture-in-Picture)$"
+ "float,class:^(librewolf)$,title:^(Library)$"
+ "float,class:^(floorp)$,title:^(Library)$"
+ "float,class:^(zen-alpha)$,title:^(Library)$"
+ "float,class:^(zen-beta)$,title:^(Library)$"
+ "float,class:^(zen)$,title:^(Library)$"
+ ''float,class:^(zen)$,title:^(.*Extension: \(Bitwarden Password Manager\).*)$''
+ "float,class:^(vlc)$"
+ "float,class:^(kvantummanager)$"
+ "float,class:^(qt5ct)$"
+ "float,class:^(qt6ct)$"
+ "float,class:^(nwg-look)$"
+ "float,class:^(org.kde.ark)$"
+ "float,class:^(org.pulseaudio.pavucontrol)$"
+ "float,class:^(com.github.rafostar.Clapper)$ # Clapper-Gtk"
+ "float,class:^(app.drey.Warp)$ # Warp-Gtk"
+ "float,class:^(net.davidotek.pupgui2)$ # ProtonUp-Qt"
+ "float,class:^(yad)$ # Protontricks-Gtk"
+ "float,class:^(eog)$ # Imageviewer-Gtk"
+ "float,class:^(io.github.alainm23.planify)$ # planify-Gtk"
+ "float,class:^(io.gitlab.theevilskeleton.Upscaler)$ # Upscaler-Gtk"
+ "float,class:^(com.github.unrud.VideoDownloader)$ # VideoDownloader-Gkk"
+ "float,class:^(blueman-manager)$"
+ "float,class:^(nm-applet)$"
+ "float,class:^(nm-connection-editor)$"
+ "float,class:^(org.kde.polkit-kde-authentication-agent-1)$"
+ "opacity 0.80 0.80,class:^(org.freedesktop.impl.portal.desktop.gtk)$"
+ "opacity 0.80 0.80,class:^(org.freedesktop.impl.portal.desktop.hyprland)$"
+
+ ''size 70% 70%,class:^(zen)$,title:^(.*Extension: \(Bitwarden Password Manager\).*)$''
+ "size 50% 50%,class:^(org.pulseaudio.pavucontrol)"
+
+ "stayfocused, class:^(pinentry-)" # fix pinentry losing focus
+ ];
+}
diff --git a/users/kaitotlex/desktop-environment/swaync.nix b/users/kaitotlex/desktop-environment/swaync.nix
new file mode 100644
index 0000000..73b1b3e
--- /dev/null
+++ b/users/kaitotlex/desktop-environment/swaync.nix
@@ -0,0 +1,325 @@
+{ config, lib, ... }:
+let
+ cfg = config.liminalOS.desktop.swaync;
+in
+{
+ options.liminalOS.desktop.swaync = {
+ enable = lib.mkOption {
+ type = lib.types.bool;
+ default = config.liminalOS.desktop.enable;
+ description = ''
+ Whether to enable the swaync notification center and daemon.
+ '';
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ services.swaync.enable = true;
+ services.swaync.settings = {
+ positionX = "right";
+ positionY = "top";
+ control-center-margin-top = 10;
+ control-center-margin-bottom = 10;
+ control-center-margin-right = 10;
+ control-center-margin-left = 10;
+ notification-icon-size = 64;
+ notification-body-image-height = 100;
+ notification-body-image-width = 200;
+ timeout = 10;
+ timeout-low = 5;
+ timeout-critical = 0;
+ fit-to-screen = false;
+ control-center-width = 500;
+ control-center-height = 800;
+ 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 = [
+ "title"
+ "mpris"
+ "volume"
+ "backlight"
+ "dnd"
+ "notifications"
+ ];
+ widget-config = {
+ title = {
+ text = "Mission Control";
+ clear-all-button = "true";
+ button-text = " All Systems Go";
+ };
+ dnd = {
+ text = "Do Not Disturb";
+ };
+ label = {
+ max-lines = 1;
+ text = "Mission Control";
+ };
+ mpris = {
+ image-size = 96;
+ image-radius = 7;
+ };
+ volume = {
+ label = "";
+ };
+ backlight = {
+ label = "";
+ };
+ };
+ };
+
+ home.file.".config/swaync/style.css".text = ''
+ * {
+ font-family: ${config.stylix.fonts.monospace.name};
+ }
+ .control-center .notification-row:focus,
+ .control-center .notification-row:hover {
+ background: #${config.lib.stylix.colors.base00}
+ }
+ .notification-row {
+ outline: none;
+ margin: 10px;
+ padding: 0;
+ }
+ .notification {
+ background: transparent;
+ padding: 0;
+ margin: 0px;
+ opacity: 0.75;
+ }
+ .notification-content {
+ background: #${config.lib.stylix.colors.base00};
+ padding: 10px;
+ border-radius: 5px;
+ border: 2px solid #${config.lib.stylix.colors.base05};
+ margin: 0;
+ }
+ .notification-default-action {
+ margin: 0;
+ padding: 0;
+ border-radius: 5px;
+ }
+ .close-button {
+ background: #${config.lib.stylix.colors.base08};
+ color: #${config.lib.stylix.colors.base00};
+ text-shadow: none;
+ padding: 0;
+ border-radius: 5px;
+ margin-top: 5px;
+ margin-right: 5px;
+ }
+ .close-button:hover {
+ box-shadow: none;
+ background: #${config.lib.stylix.colors.base0D};
+ transition: all .15s ease-in-out;
+ border: none
+ }
+ .notification-action {
+ border: 2px solid #${config.lib.stylix.colors.base0D};
+ border-top: none;
+ border-radius: 5px;
+ }
+ .notification-default-action:hover,
+ .notification-action:hover {
+ color: #${config.lib.stylix.colors.base0B};
+ background: #${config.lib.stylix.colors.base0B}
+ }
+ .notification-default-action {
+ border-radius: 5px;
+ margin: 0px;
+ }
+ .notification-default-action:not(:only-child) {
+ border-bottom-left-radius: 7px;
+ border-bottom-right-radius: 7px
+ }
+ .notification-action:first-child {
+ border-bottom-left-radius: 10px;
+ background: #${config.lib.stylix.colors.base00}
+ }
+ .notification-action:last-child {
+ border-bottom-right-radius: 10px;
+ background: #${config.lib.stylix.colors.base00}
+ }
+ .inline-reply {
+ margin-top: 8px
+ }
+ .inline-reply-entry {
+ background: #${config.lib.stylix.colors.base00};
+ color: #${config.lib.stylix.colors.base05};
+ caret-color: #${config.lib.stylix.colors.base05};
+ border: 1px solid #${config.lib.stylix.colors.base09};
+ border-radius: 5px
+ }
+ .inline-reply-button {
+ margin-left: 4px;
+ background: #${config.lib.stylix.colors.base00};
+ border: 1px solid #${config.lib.stylix.colors.base09};
+ border-radius: 5px;
+ color: #${config.lib.stylix.colors.base05}
+ }
+ .inline-reply-button:disabled {
+ background: initial;
+ color: #${config.lib.stylix.colors.base03};
+ border: 1px solid transparent
+ }
+ .inline-reply-button:hover {
+ background: #${config.lib.stylix.colors.base00}
+ }
+ .body-image {
+ margin-top: 6px;
+ background-color: #${config.lib.stylix.colors.base05};
+ border-radius: 5px
+ }
+ .summary {
+ font-size: 16px;
+ font-weight: 700;
+ background: transparent;
+ color: rgba(158, 206, 106, 1);
+ text-shadow: none
+ }
+ .time {
+ font-size: 16px;
+ font-weight: 700;
+ background: transparent;
+ color: #${config.lib.stylix.colors.base05};
+ text-shadow: none;
+ margin-right: 18px
+ }
+ .body {
+ font-size: 15px;
+ font-weight: 400;
+ background: transparent;
+ color: #${config.lib.stylix.colors.base05};
+ text-shadow: none
+ }
+ .control-center {
+ background: #${config.lib.stylix.colors.base00};
+ border: 2px solid #${config.lib.stylix.colors.base0C};
+ border-radius: 5px;
+ opacity: 0.85;
+ }
+ .control-center-list {
+ background: transparent
+ }
+ .control-center-list-placeholder {
+ opacity: .5
+ }
+ .floating-notifications {
+ background: transparent
+ }
+ .blank-window {
+ background: alpha(black, 0)
+ }
+ .widget-title {
+ color: #${config.lib.stylix.colors.base0B};
+ background: #${config.lib.stylix.colors.base00};
+ padding: 5px 10px;
+ margin: 10px 10px 5px 10px;
+ font-size: 1.5rem;
+ border-radius: 5px;
+ }
+ .widget-title>button {
+ font-size: 1rem;
+ color: #${config.lib.stylix.colors.base05};
+ text-shadow: none;
+ background: #${config.lib.stylix.colors.base00};
+ box-shadow: none;
+ border-radius: 5px;
+ }
+ .widget-title>button:hover {
+ background: #${config.lib.stylix.colors.base08};
+ color: #${config.lib.stylix.colors.base00};
+ }
+ .widget-dnd {
+ background: #${config.lib.stylix.colors.base00};
+ padding: 5px 10px;
+ margin: 10px 10px 5px 10px;
+ border-radius: 5px;
+ font-size: large;
+ color: #${config.lib.stylix.colors.base0B};
+ }
+ .widget-dnd>switch {
+ border-radius: 5px;
+ /* border: 1px solid #${config.lib.stylix.colors.base0B}; */
+ background: #${config.lib.stylix.colors.base0B};
+ }
+ .widget-dnd>switch:checked {
+ background: #${config.lib.stylix.colors.base08};
+ border: 1px solid #${config.lib.stylix.colors.base08};
+ }
+ .widget-dnd>switch slider {
+ background: #${config.lib.stylix.colors.base00};
+ border-radius: 5px
+ }
+ .widget-dnd>switch:checked slider {
+ background: #${config.lib.stylix.colors.base00};
+ border-radius: 5px
+ }
+ .widget-label {
+ margin: 10px 10px 5px 10px;
+ }
+ .widget-label>label {
+ font-size: 1rem;
+ color: #${config.lib.stylix.colors.base05};
+ }
+ .widget-mpris {
+ color: #${config.lib.stylix.colors.base05};
+ padding: 5px 10px;
+ margin: 10px 10px 5px 10px;
+ border-radius: 5px;
+ }
+ .widget-mpris > box > button {
+ border-radius: 5px;
+ }
+ .widget-mpris-player {
+ padding: 5px 10px;
+ margin: 10px
+ }
+ .widget-mpris-title {
+ font-weight: 700;
+ font-size: 1.25rem
+ }
+ .widget-mpris-subtitle {
+ font-size: 1.1rem
+ }
+ .widget-menubar>box>.menu-button-bar>button {
+ border: none;
+ background: transparent
+ }
+ .topbar-buttons>button {
+ border: none;
+ background: transparent
+ }
+ .widget-volume {
+ background: #${config.lib.stylix.colors.base01};
+ padding: 5px;
+ margin: 10px 10px 5px 10px;
+ border-radius: 5px;
+ font-size: x-large;
+ color: #${config.lib.stylix.colors.base05};
+ }
+ .widget-volume>box>button {
+ background: #${config.lib.stylix.colors.base0B};
+ border: none
+ }
+ .per-app-volume {
+ background-color: #${config.lib.stylix.colors.base00};
+ padding: 4px 8px 8px;
+ margin: 0 8px 8px;
+ border-radius: 5px;
+ }
+ .widget-backlight {
+ background: #${config.lib.stylix.colors.base01};
+ padding: 5px;
+ margin: 10px 10px 5px 10px;
+ border-radius: 5px;
+ font-size: x-large;
+ color: #${config.lib.stylix.colors.base05}
+ }
+ '';
+ };
+}
diff --git a/users/kaitotlex/desktop-environment/waybar/default.nix b/users/kaitotlex/desktop-environment/waybar/default.nix
new file mode 100644
index 0000000..6c776a0
--- /dev/null
+++ b/users/kaitotlex/desktop-environment/waybar/default.nix
@@ -0,0 +1,424 @@
+{
+ pkgs,
+ config,
+ lib,
+ osConfig,
+ ...
+}:
+let
+ cfg = config.liminalOS.desktop.waybar;
+ theme = config.lib.stylix;
+ palette = theme.colors;
+in
+{
+ options.liminalOS.desktop.waybar = {
+ enable = lib.mkOption {
+ type = lib.types.bool;
+ default = config.liminalOS.desktop.enable;
+ description = ''
+ Whether to enable Waybar and the liminalOS rice.
+ '';
+ };
+ };
+ config = lib.mkIf cfg.enable {
+ home.packages = with pkgs; [ playerctl ];
+ programs.waybar =
+ let
+ isDesktop = osConfig.liminalOS.formFactor == "desktop";
+ isLaptop = osConfig.liminalOS.formFactor == "laptop";
+ in
+ {
+ enable = true;
+ systemd.enable = true;
+ systemd.target = lib.mkIf config.liminalOS.desktop.hyprland.enable "hyprland-session.target";
+ settings.mainBar = {
+ name = "bar0";
+ reload_style_on_change = true;
+ position = "top";
+ layer = "top";
+ height = 37;
+ margin-top = 0;
+ margin-bottom = 0;
+ margin-left = 0;
+ margin-right = 0;
+ modules-left =
+ [
+ "custom/launcher"
+ ]
+ ++ (lib.optionals isDesktop [
+
+ "custom/playerctl#backward"
+ "custom/playerctl#play"
+ "custom/playerctl#foward"
+ ])
+ ++ [
+ "custom/playerlabel"
+ ]
+ ++ (lib.optionals isLaptop [
+ "hyprland/workspaces"
+ ]);
+ modules-center = lib.mkIf isDesktop [
+ "cava#left"
+ "hyprland/workspaces"
+ "cava#right"
+ ];
+ modules-right = [
+ "tray"
+ "battery"
+ "pulseaudio"
+ "network"
+ "clock"
+ ];
+ clock = {
+ format = " {:%a, %d %b, %I:%M %p}";
+ tooltip = "true";
+ tooltip-format = "{:%Y %B}\n{calendar}";
+ format-alt = " {:%d/%m}";
+ };
+ "hyprland/workspaces" = {
+ disable-scroll = false;
+ on-scroll-down = "${pkgs.hyprnome}/bin/hyprnome";
+ on-scroll-up = "${pkgs.hyprnome}/bin/hyprnome --previous";
+ format = "{icon}";
+ on-click = "activate";
+ format-icons = {
+ active = "";
+ default = "";
+ urgent = "";
+ special = "";
+ };
+ sort-by-number = true;
+ };
+ "cava#left" = {
+ framerate = 60;
+ autosens = 1;
+ bars = 18;
+ lower_cutoff_freq = 50;
+ higher_cutoff_freq = 10000;
+ method = "pipewire";
+ source = "auto";
+ stereo = true;
+ reverse = false;
+ bar_delimiter = 0;
+ monstercat = false;
+ waves = false;
+ input_delay = 2;
+ format-icons = [
+ "▁"
+ "▂"
+ "▃"
+ "▄"
+ "▅"
+ "▆"
+ "▇"
+ "█"
+ ];
+ };
+ "cava#right" = {
+ framerate = 60;
+ autosens = 1;
+ bars = 18;
+ lower_cutoff_freq = 50;
+ higher_cutoff_freq = 10000;
+ method = "pipewire";
+ source = "auto";
+ stereo = true;
+ reverse = false;
+ bar_delimiter = 0;
+ monstercat = false;
+ waves = false;
+ input_delay = 2;
+ format-icons = [
+ "▁"
+ "▂"
+ "▃"
+ "▄"
+ "▅"
+ "▆"
+ "▇"
+ "█"
+ ];
+ };
+ "custom/playerctl#backward" = {
+ format = " ";
+ on-click = "playerctl previous";
+ on-scroll-up = "playerctl volume .05+";
+ on-scroll-down = "playerctl volume .05-";
+ };
+ "custom/playerctl#play" = {
+ format = "{icon}";
+ return-type = "json";
+ exec = "playerctl -a metadata --format '{\"text\": \"{{artist}} - {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
+ on-click = "playerctl play-pause";
+ on-scroll-up = "playerctl volume .05+";
+ on-scroll-down = "playerctl volume .05-";
+ format-icons = {
+ Playing = " ";
+ Paused = " ";
+ Stopped = " ";
+ };
+ };
+ "custom/playerctl#foward" = {
+ format = " ";
+ on-click = "playerctl next";
+ on-scroll-up = "playerctl volume .05+";
+ on-scroll-down = "playerctl volume .05-";
+ };
+ "custom/playerlabel" = {
+ format = " {} ";
+ return-type = "json";
+ max-length = 40;
+ exec = "playerctl -a metadata --format '{\"text\": \"{{artist}} - {{markup_escape(title)}}\", \"tooltip\": \"{{playerName}} : {{markup_escape(title)}}\", \"alt\": \"{{status}}\", \"class\": \"{{status}}\"}' -F";
+ on-click = "";
+ };
+ battery = {
+ states = {
+ good = 95;
+ warning = 30;
+ critical = 15;
+ };
+ format = "{icon} {capacity}%";
+ format-charging = " {capacity}%";
+ format-plugged = " {capacity}% ";
+ format-alt = "{icon} {time}";
+ format-icons = [
+ ""
+ ""
+ ""
+ ""
+ ""
+ ];
+ };
+
+ memory = {
+ format = " {}%";
+ format-alt = " {used}/{total} GiB";
+ interval = 5;
+ };
+ cpu = {
+ format = " {usage}%";
+ format-alt = " {avg_frequency} GHz";
+ interval = 5;
+ };
+ network = {
+ format-wifi = " {signalStrength}%";
+ format-ethernet = " 100% ";
+ tooltip-format = "Connected to {essid} {ifname} via {gwaddr}";
+ format-linked = "{ifname} (No IP)";
+ format-disconnected = " 0% ";
+ };
+ tray = {
+ icon-size = 20;
+ spacing = 8;
+ };
+ pulseaudio = {
+ format = "{icon} {volume}%";
+ format-muted = "";
+ format-icons = {
+ default = [
+ ""
+ ""
+ ""
+ ];
+ };
+ scroll-step = 5;
+ on-click = "${pkgs.pavucontrol}/bin/pavucontrol";
+ };
+ "custom/launcher" =
+ let
+ toggle-colorscheme = pkgs.writeShellScriptBin "toggle-colorscheme.sh" ''
+ POLARITY_FILE="/etc/polarity"
+
+ if [[ ! -f "$POLARITY_FILE" ]]; then
+ exit 0
+ elif [[ ! -r "$POLARITY_FILE" ]]; then
+ echo "Error: Cannot read $POLARITY_FILE. Check permissions." >&2
+ exit 1
+ fi
+
+ current_scheme=$(cat "$POLARITY_FILE")
+ if [[ $? -ne 0 ]]; then
+ echo "Error: Failed to read content from $POLARITY_FILE." >&2
+ exit 1
+ fi
+
+ current_scheme=$(echo "$current_scheme" | xargs)
+
+ target_service=""
+ case "$current_scheme" in
+ dawn)
+ target_service="colorscheme-dusk.service"
+ ;;
+ dusk)
+ target_service="colorscheme-dawn.service"
+ ;;
+ *)
+ echo "Error: Invalid content '$current_scheme' found in $POLARITY_FILE. Expected 'dawn' or 'dusk'." >&2
+ exit 1
+ ;;
+ esac
+
+ echo "Current scheme: '$current_scheme'. Attempting to start '$target_service'..."
+ systemctl start "$target_service"
+
+ if [[ $? -ne 0 ]]; then
+ echo "Error: Failed to execute 'systemctl start $target_service'. Check systemctl logs or permissions." >&2
+ exit 1
+ else
+ echo "Command 'systemctl start $target_service' executed successfully."
+ fi
+
+ exit 0
+ '';
+ in
+ {
+ format = "";
+ on-click = "pkill -9 rofi || rofi -show drun";
+ on-click-right = "${toggle-colorscheme}/bin/toggle-colorscheme.sh";
+ tooltip = "false";
+ };
+ };
+ style =
+ ''
+ * {
+ border: none;
+ border-radius: 0px;
+ font-family: GeistMono Nerd Font;
+ font-size: 13px;
+ min-height: 0;
+ }
+ window#waybar {
+ background: #${palette.base01};
+ }
+
+ #cava.left, #cava.right {
+ background: #${palette.base00};
+ margin: 4px;
+ padding: 6px 16px;
+ color: #${palette.base00};
+ }
+ #cava.left {
+ border-radius: 24px 10px 24px 10px;
+ }
+ #cava.right {
+ border-radius: 10px 24px 10px 24px;
+ }
+ #workspaces {
+ background: #${palette.base00};
+ color: #${palette.base00}
+ }
+ #workspaces button {
+ padding: 0px 5px;
+ margin: 0px 3px;
+ border-radius: 16px;
+ color: transparent;
+ background: #${palette.base01};
+ transition: all 0.3s ease-in-out;
+ }
+
+ #workspaces button.active {
+ background-color: #${palette.base0A};
+ color: #${palette.base01};
+ border-radius: 16px;
+ min-width: 50px;
+ background-size: 400% 400%;
+ transition: all 0.3s ease-in-out;
+ }
+
+ #workspaces button:hover {
+ background-color: #${palette.base05};
+ color: #${palette.base01};
+ border-radius: 16px;
+ min-width: 50px;
+ background-size: 400% 400%;
+ }
+
+ #tray, #pulseaudio, #network, #battery,
+ #custom-playerctl.backward, #custom-playerctl.play, #custom-playerctl.foward{
+ background: #${palette.base00};
+ font-weight: bold;
+ margin: 4px 0px;
+ }
+ #tray, #pulseaudio, #network, #battery{
+ color: #${palette.base05};
+ border-radius: 10px 24px 10px 24px;
+ padding: 0 20px;
+ margin-left: 7px;
+ }
+ #clock {
+ color: #${palette.base05};
+ background: #${palette.base00};
+ border-radius: 0px 0px 0px 40px;
+ padding: 8px 10px 8px 25px;
+ margin-left: 7px;
+ font-weight: bold;
+ font-size: 14px;
+ }
+ #custom-launcher {
+ color: #${palette.base0A};
+ background: #${palette.base00};
+ border-radius: 0px 0px 40px 0px;
+ margin: 0px;
+ padding: 0px 35px 0px 15px;
+ font-size: 24px;
+ }
+
+ #custom-playerctl.backward, #custom-playerctl.play, #custom-playerctl.foward {
+ background: #${palette.base00};
+ font-size: 20px;
+ }
+ #custom-playerctl.backward:hover, #custom-playerctl.play:hover, #custom-playerctl.foward:hover{
+ color: #${palette.base05};
+ }
+ #custom-playerctl.backward {
+ color: #${palette.base08};
+ border-radius: 24px 0px 0px 10px;
+ padding-left: 16px;
+ margin-left: 7px;
+ }
+ #custom-playerctl.play {
+ color: #${palette.base0A};
+ padding: 0 5px;
+ }
+ #custom-playerctl.foward {
+ color: #${palette.base08};
+ border-radius: 0px 10px 24px 0px;
+ padding-right: 12px;
+ margin-right: 7px
+ }
+ #custom-playerlabel {
+ background: #${palette.base00};
+ color: #${palette.base05};
+ padding: 0 20px;
+ border-radius: 24px 10px 24px 10px;
+ margin: 4px 0;
+ font-weight: bold;
+ }
+ #window{
+ background: #${palette.base00};
+ padding-left: 15px;
+ padding-right: 15px;
+ border-radius: 16px;
+ margin-top: 4px;
+ margin-bottom: 4px;
+ font-weight: normal;
+ font-style: normal;
+ }
+ ''
+ + (lib.optionalString isLaptop ''
+ #workspaces {
+ margin: 4px;
+ padding: 6px 16px;
+ border-radius: 24px 10px 24px 10px;
+ }
+ '')
+ + (lib.optionalString isDesktop ''
+ #workspaces {
+ margin: 4px 5px;
+ padding: 6px 5px;
+ border-radius: 16px;
+ }
+ '');
+ };
+ };
+}
diff --git a/users/kaitotlex/home.nix b/users/kaitotlex/home.nix
index 79cf463..112f0c0 100644
--- a/users/kaitotlex/home.nix
+++ b/users/kaitotlex/home.nix
@@ -220,13 +220,6 @@
extraPortals = with pkgs; [ xdg-desktop-portal-gtk ];
};
- programs.rofi = {
- enable = true;
- cycle = true;
- location = "center";
- package = pkgs.rofi-wayland;
- };
-
services.dunst.enable = true;
programs.git = {
diff --git a/users/kaitotlex/stylix/default.nix b/users/kaitotlex/stylix/default.nix
index 5ad9af1..035671e 100644
--- a/users/kaitotlex/stylix/default.nix
+++ b/users/kaitotlex/stylix/default.nix
@@ -3,7 +3,9 @@
waybar.enable = false;
kitty.variant256Colors = true;
neovim.enable = false;
- sway.enable = true;
- swaylock.enable = true;
+ hyprland.enable = false;
+ hyprlock.enable = false;
+ rofi.enable = false;
+ swaync.enable = false;
};
}