diff --git a/README.md b/README.md
index d8a4539..0cf7bd8 100644
--- a/README.md
+++ b/README.md
@@ -20,4 +20,8 @@ these are sorted by `theme - de`.
### Catppuccin - Gnome
-![](./docs/assets/2024-01-08_14-24.png)
\ No newline at end of file
+![](./docs/assets/2024-01-08_14-24.png)
+
+### Catppuccin - Hyprland
+
+![](./docs/assets/2024-03-17_01-43.png)
\ No newline at end of file
diff --git a/assets/lockscreen.png b/assets/lockscreen.png
new file mode 100644
index 0000000..124dcb4
Binary files /dev/null and b/assets/lockscreen.png differ
diff --git a/assets/wallpaper.png b/assets/wallpaper.png
new file mode 100644
index 0000000..d23cdaa
Binary files /dev/null and b/assets/wallpaper.png differ
diff --git a/config/analys.frag b/config/analys.frag
new file mode 100644
index 0000000..021f59f
--- /dev/null
+++ b/config/analys.frag
@@ -0,0 +1,223 @@
+precision mediump float;
+varying vec2 v_texcoord;
+uniform sampler2D tex;
+uniform float time;
+
+// Analys cube
+// (c) 2019 FMS_Cat, MIT License
+
+// == tweak these numbers, yee =====================================================================
+#define SIZE 0.5
+#define FX_NYOOOM 0.0
+#define FX_FORWARD 1.0
+#define FX_KICK (0.1*exp(-3.0*mod(BEAT,4.0)))
+#define FX_TWIST (20.0*exp(-3.0*mod(BEAT-2.0,4.0)))
+#define FX_SKEW 0.0
+#define FX_DEFORM (0.2*0.0)
+#define FX_DEFORM_FREQ 0.1
+
+// == raymarch related constants ===================================================================
+#define MARCH_ITER 64
+#define MARCH_EPSILON 1E-4
+#define MARCH_NEAR 0.01
+#define MARCH_FAR 40.0
+#define MARCH_MULP 0.6
+
+// == common macros ================================================================================
+#define HALF_PI 1.57079632679
+#define PI 3.14159265359
+#define TAU 6.28318530718
+#define BEAT (time*170.0/60.0)
+#define saturate(i) clamp(i,0.,1.)
+#define linearstep(a,b,t) saturate(((t)-(a))/((b)-(a)))
+
+// == common functions =============================================================================
+mat2 rotate2D( float t ) {
+ return mat2( cos( t ), -sin( t ), sin( t ), cos( t ) );
+}
+
+// == camera =======================================================================================
+struct Camera {
+ vec3 pos;
+ vec3 dir;
+ vec3 up;
+ float roll;
+ float fov;
+};
+
+Camera newCamera( vec3 pos, vec3 dir ) {
+ Camera camera;
+ camera.pos = pos;
+ camera.dir = dir;
+ camera.up = vec3( 0.0, 1.0, 0.0 );
+ camera.roll = 0.0;
+ camera.fov = 0.5;
+ return camera;
+}
+
+// == ray ==========================================================================================
+struct Ray {
+ vec3 orig;
+ vec3 dir;
+};
+
+Ray newRay( vec3 ori, vec3 dir ) {
+ Ray ray;
+ ray.orig = ori;
+ ray.dir = dir;
+ return ray;
+}
+
+Ray rayFromCamera( Camera camera, vec2 p ) {
+ vec3 dirX = normalize( cross( camera.dir, camera.up ) );
+ vec3 dirY = cross( dirX, camera.dir );
+ vec2 pt = rotate2D( camera.roll ) * p;
+ return newRay(
+ camera.pos,
+ normalize( pt.x * dirX + pt.y * dirY + camera.dir / tan( camera.fov ) )
+ );
+}
+
+vec3 getRayPosition( Ray ray, float len ) {
+ return ray.orig + ray.dir * len;
+}
+
+// == isect ========================================================================================
+struct Intersection {
+ Ray ray;
+ float len;
+ vec3 pos;
+};
+
+Intersection newIntersection( Ray ray, float len ) {
+ Intersection isect;
+ isect.ray = ray;
+ isect.len = len;
+ isect.pos = getRayPosition( ray, len );
+ return isect;
+}
+
+// == march result =================================================================================
+struct MarchResult {
+ float dist;
+ vec2 uv;
+};
+
+// == distFuncs ====================================================================================
+float distFuncBox( vec3 p, vec3 b ) {
+ vec3 d = abs( p ) - b;
+ return length( max( d, 0.0 ) ) + min( max( d.x, max( d.y, d.z ) ), 0.0 );
+}
+
+vec3 deform( vec3 p ) {
+ vec3 pt = p;
+ pt.xy = rotate2D( FX_SKEW * pt.z ) * pt.xy;
+ pt.x *= 1.0 - sqrt( FX_NYOOOM );
+ pt.yz = rotate2D( FX_NYOOOM * exp( 5.0 * FX_NYOOOM ) * pt.x ) * pt.yz;
+ pt.y += 2.0 * FX_SKEW * pt.x;
+ pt += FX_DEFORM * (
+ texture2D( tex, FX_DEFORM_FREQ * ( pt.xy ) + 0.5 ).xyz - 0.5
+ );
+ pt.zx = rotate2D( mod( 2.5 * time + PI, TAU ) + FX_TWIST * pt.y ) * pt.zx;
+ pt.xy = rotate2D( 0.6 * sin( 0.9 * time ) ) * pt.xy;
+ pt.yz = rotate2D( 0.6 * sin( 1.4 * time ) ) * pt.yz;
+ pt -= normalize( pt ) * FX_KICK * sin( 15.0 * length( pt ) - 40.0 * time );
+ return pt;
+}
+
+MarchResult distFunc( vec3 p ) {
+ MarchResult result;
+
+ vec3 pt = p;
+ pt = deform( pt );
+ result.dist = distFuncBox( pt, vec3( SIZE ) );
+
+ vec3 spt = vec3( 1.0 );
+
+ if ( FX_FORWARD > 0.0 ) {
+ vec3 ptIfs = p;
+ ptIfs.z = mod( ptIfs.z - 16.0 * time + 3.0 * sin( HALF_PI * BEAT + 0.5 ), 6.0 ) - 3.0;
+ for ( int i = 0; i < 6; i ++ ) {
+ float fi = float( i );
+ spt *= sign( ptIfs );
+ ptIfs = abs( ptIfs ) - vec3( 3.2, 4.5, 1.2 ) / max( 1E-2, FX_FORWARD ) * pow( 0.5, fi );
+ ptIfs.xy = rotate2D( 1.1 ) * ptIfs.xy;
+ ptIfs.zx = rotate2D( 2.1 ) * ptIfs.zx;
+ }
+
+ ptIfs = deform( ptIfs );
+
+ float distIfs = distFuncBox( ptIfs, vec3( SIZE ) );
+
+ if ( result.dist < distIfs ) {
+ spt = vec3( 1.0 );
+ } else {
+ result.dist = distIfs;
+ pt = ptIfs;
+ }
+ }
+
+ vec3 abspt = abs( pt );
+ float n = max( abspt.x, max( abspt.y, abspt.z ) );
+
+ result.uv = 0.5 + (
+ ( n == abspt.z ) ? ( pt.xy * vec2( sign( pt.z ), 1.0 ) ) :
+ ( n == abspt.x ) ? ( pt.zy * vec2( -sign( pt.x ), 1.0 ) ) :
+ ( pt.xz * vec2( 1.0, -sign( pt.y ) ) )
+ ) * spt.x * spt.y * spt.z * 0.5 / SIZE;
+
+ return result;
+}
+
+vec3 normalFunc( vec3 p, float dd ) {
+ vec2 d = vec2( 0.0, dd );
+ return normalize( vec3(
+ distFunc( p + d.yxx ).dist - distFunc( p - d.yxx ).dist,
+ distFunc( p + d.xyx ).dist - distFunc( p - d.xyx ).dist,
+ distFunc( p + d.xxy ).dist - distFunc( p - d.xxy ).dist
+ ) );
+}
+
+vec3 normalFunc( vec3 p ) {
+ return normalFunc( p, MARCH_NEAR );
+}
+
+// == main procedure ===============================================================================
+void main() {
+ vec2 p = v_texcoord - 0.5;
+ Camera camera = newCamera( vec3( 0.0, 0.0, 0.0 ), vec3( 0.0, 0.0, -1.0 ) );
+ camera.fov = 0.6 + 0.9 * FX_FORWARD * ( 0.5 + 0.5 * sin( HALF_PI * BEAT - 0.5 ) );
+ camera.pos.z = 0.5 + 1.5 / camera.fov;
+ Ray ray = rayFromCamera( camera, p );
+
+ Intersection isect;
+ float rayLen = MARCH_NEAR;
+ vec3 rayPos = getRayPosition( ray, rayLen );
+ MarchResult result;
+ for ( int i = 0; i < MARCH_ITER; i ++ ) {
+ result = distFunc( rayPos );
+ if ( abs( result.dist ) < MARCH_NEAR ) { break; }
+ rayLen += result.dist * MARCH_MULP;
+ if ( MARCH_FAR < rayLen ) { break; }
+ rayPos = getRayPosition( ray, rayLen );
+ }
+
+ vec3 bg = vec3( 0.0 );
+
+ if ( abs( result.dist ) < MARCH_NEAR ) {
+ vec3 normal = normalFunc( rayPos );
+ float edge = linearstep( 0.498, 0.499, abs( result.uv.x - 0.5 ) );
+ edge += linearstep( 0.495, 0.497, abs( result.uv.y - 0.5 ) );
+ vec2 uv = result.uv;
+ vec4 tex = texture2D( tex, uv );
+ float fog = exp( -0.2 * max( 0.0, rayLen - 3.0 ) );
+ gl_FragColor = vec4( fog * mix(
+ 0.1 + 0.1 * normal + 0.8 * tex.rgb,
+ 1.0 + 1.0 * sin( vec3( 0.0, 1.0, 2.0 ) + 10.0 * length( result.uv - 0.5 ) - 10.0 * time ),
+ edge
+ ), 1.0 );
+ } else {
+ discard;
+ //gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
+ }
+}
diff --git a/config/dunst.conf b/config/dunst.conf
new file mode 100644
index 0000000..b6cb480
--- /dev/null
+++ b/config/dunst.conf
@@ -0,0 +1,64 @@
+# https://github.com/catppuccin/dunst/blob/main/src/mocha.conf
+[global]
+ frame_color = "#89B4FA"
+ separator_color= frame
+
+ follow = none
+ width = 300
+ height = 145
+ origin = top-right
+ alignment = "left"
+ vertical_alignment = "center"
+ ellipsize = "middle"
+ offset = "15x15"
+ padding = 15
+ horizontal_padding = 15
+ text_icon_padding = 15
+ icon_position = "left"
+ min_icon_size = 48
+ max_icon_size = 64
+ progress_bar = true
+ progress_bar_height = 8
+ progress_bar_frame_width = 1
+ progress_bar_min_width = 150
+ progress_bar_max_width = 300
+ separator_height = 2
+ frame_width = 2
+ corner_radius = 8
+ transparency = 0
+ gap_size = 8
+ line_height = 0
+ notification_limit = 0
+ idle_threshold = 120
+ history_length = 20
+ show_age_threshold = 60
+ markup = "full"
+ font = "Atkinson Hyperlegible 10"
+ word_wrap = "yes"
+ sort = "yes"
+ shrink = "no"
+ indicate_hidden = "yes"
+ sticky_history = "yes"
+ ignore_newline = "no"
+ show_indicators = "no"
+ stack_duplicates = true
+ always_run_script = true
+ hide_duplicate_count = false
+ ignore_dbusclose = false
+ mouse_left_click = "do_action"
+ mouse_middle_click = "close_all"
+ mouse_right_click = "close_current"
+
+[urgency_low]
+background = "#1E1E2E"
+foreground = "#CDD6F4"
+
+[urgency_normal]
+background = "#1E1E2E"
+foreground = "#CDD6F4"
+
+[urgency_critical]
+background = "#1E1E2E"
+foreground = "#CDD6F4"
+frame_color = "#FAB387"
+
diff --git a/config/nwg-drawer.css b/config/nwg-drawer.css
new file mode 100644
index 0000000..b1b365c
--- /dev/null
+++ b/config/nwg-drawer.css
@@ -0,0 +1,27 @@
+window {
+ /*background: @base;*/
+ background: alpha(@base, 0.3);
+ color: @text;
+ font-family: 'Atkinson Hyperlegible', FontAwesome, Noto Sans CJK;
+ font-size: 14px;
+ font-style: normal;
+}
+
+/* search entry */
+entry {
+ background-color: alpha(@surface0, 0.5);
+}
+
+button, image {
+ background: none;
+ border: none
+}
+
+button {
+ padding: 1em 0.5em;
+ border-radius: 1em;
+}
+
+button:hover {
+ background-color: alpha(@surface0, 0.5);
+}
\ No newline at end of file
diff --git a/config/rofi.rasi b/config/rofi.rasi
new file mode 100644
index 0000000..a4cad5c
--- /dev/null
+++ b/config/rofi.rasi
@@ -0,0 +1,98 @@
+* {
+ bg-col: #24273a;
+ bg-col-light: #313244;
+ border-col: #363a4f;
+ selected-col: #45475a;
+ pink: #f5c2e7;
+ fg-col: #cdd6f4;
+ fg-col2: @pink;
+ grey: #bac2de;
+
+ width: 450px;
+}
+
+element-text, element-icon , mode-switcher {
+ background-color: inherit;
+ text-color: inherit;
+}
+
+window {
+ height: 500px;
+ border: 2px;
+ border-radius: 1em;
+ border-color: @pink;
+ background-color: @bg-col;
+}
+
+mainbox {background-color: @bg-col;}
+
+inputbar {
+ margin: 10px 5px 5px 5px;
+ children: [prompt, entry];
+ background-color: @bg-col;
+ padding: 1px;
+}
+
+prompt {
+ background-color: transparent;
+ padding: 1px;
+ text-color: @fg-col;
+ border-radius: 1.5em;
+}
+
+textbox-prompt-colon {
+ expand: true;
+ str: ":";
+}
+
+entry {
+ padding: 1px;
+ margin: 0px;
+ text-color: @fg-col;
+ background-color: @bg-col;
+}
+
+listview {
+ border: 0px 0px 0px;
+ margin: 5px 0px 0px 10px;
+ columns: 1;
+ lines: 10;
+ background-color: @bg-col;
+}
+
+element {
+ padding: 1px;
+ background-color: @bg-col;
+ text-color: @fg-col;
+}
+
+element-icon {size: 12px;}
+
+element.selected {
+ background-color: @selected-col;
+ text-color: @fg-col2;
+}
+
+
+scrollbar {
+ width: 4px ;
+ border: 0;
+ handle-color: @fg-col;
+ handle-width: 8px ;
+ padding: 0;
+}
+
+mode-switcher {spacing: 0;}
+
+button {
+ spacing: 0;
+ background-color: @bg-col-light;
+ text-color: @grey;
+ vertical-align: 0.5;
+ horizontal-align: 0.5;
+}
+
+button.selected {
+ background-color: @bg-col;
+ text-color: @pink;
+}
\ No newline at end of file
diff --git a/config/waybar.css b/config/waybar.css
new file mode 100644
index 0000000..ca49431
--- /dev/null
+++ b/config/waybar.css
@@ -0,0 +1,118 @@
+* {
+ border: none;
+ border-radius: 0px;
+ min-height: 0;
+}
+
+window#waybar {
+ color: @text;
+ /*background: alpha(@base, 0.6);*/
+ background: @base;
+ border-radius: 1em;
+ /*font-family: VictorMono, Iosevka Nerd Font, Noto Sans CJK;*/
+ /*font-family: 'Atkinson Hyperlegible', FontAwesome, Noto Sans CJK;*/
+ font-family: CozetteVector, FontAwesome, Noto Sans CJK;
+ font-size: 13px;
+ font-style: normal;
+}
+
+box.module, .modules-right box {
+ background-color: @surface0;
+ margin: 0 0.25em;
+ padding: 0.15em 0.25em;
+ border-radius: 1em;
+}
+.modules-right label.module {
+ margin: 0 0.5em;
+}
+
+.modules-right box {
+ padding: 0.15em 0.4em;
+}
+.modules-left, .modules-right {
+ margin: 0.4em 0.5em;
+}
+
+#workspaces {
+ background-color: @surface0;
+ padding: 0;
+}
+
+#workspaces button {
+ background-color: transparent;
+ color: @text;
+ padding: 0 0.4em;
+}
+
+#workspaces button:nth-child(1) {
+ border-top-left-radius: 1em;
+ border-bottom-left-radius: 1em;
+}
+#workspaces button:nth-last-child(1) {
+ border-top-right-radius: 1em;
+ border-bottom-right-radius: 1em;
+}
+
+#workspaces button.visible {
+ background: @surface1;
+}
+
+#workspaces button.active {
+ background: @pink;
+ color: @surface0;
+}
+
+#workspaces button.urgent {
+ background: @red;
+ color: @surface0;
+}
+
+#window {
+ background: transparent;
+}
+
+#clock {
+ color: @lavender;
+}
+
+#power-profiles-daemon {
+ color: @teal;
+}
+
+#battery {
+ color: @green;
+}
+
+#battery.charging {
+ color: @green;
+}
+
+#battery.warning:not(.charging) {
+ color: @peach;
+}
+
+#battery.critical:not(.charging) {
+ color: @maroon;
+}
+
+#network {
+ color: @sapphire;
+}
+
+#backlight {
+ color: @yellow;
+}
+
+#pulseaudio {
+ color: @pink;
+}
+
+#custom-power {
+ color: @red;
+}
+
+tooltip {
+ color: @text;
+ background: @base;
+ border: 1px solid @pink;
+}
\ No newline at end of file
diff --git a/default.nix b/default.nix
index fcac25f..1649857 100644
--- a/default.nix
+++ b/default.nix
@@ -9,14 +9,24 @@
inherit (lib.modules) mkAliasOptionModule mkDefault mkIf;
inherit (lib.my) mapModulesRec';
in {
+ # disables Nixpkgs Hyprland module to avoid conflicts
+ #disabledModules = [ "programs/hyprland.nix" ];
+
imports =
[
inputs.home-manager.nixosModules.home-manager
- inputs.nix-colors.homeManagerModules.default
(mkAliasOptionModule ["hm"] ["home-manager" "users" config.user.name])
+ inputs.nix-colors.homeManagerModules.default
+ inputs.hyprland.nixosModules.default
]
++ (mapModulesRec' (toString ./modules) import);
+ hm.imports = [
+ inputs.hyprlock.homeManagerModules.hyprlock
+ inputs.hypridle.homeManagerModules.hypridle
+ inputs.hyprland.homeManagerModules.default
+ ];
+
# Common config for all nixos machines;
environment.variables = {
NIXPKGS_ALLOW_UNFREE = "1";
@@ -33,10 +43,11 @@ in {
auto-optimise-store = true;
keep-outputs = true;
keep-derivations = true;
- substituters = [ "https://nix-community.cachix.org" "https://nixpkgs-wayland.cachix.org" ];
+ substituters = [ "https://nix-community.cachix.org" "https://nixpkgs-wayland.cachix.org" "https://hyprland.cachix.org" ];
trusted-public-keys = [
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA="
+ "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
];
};
};
diff --git a/docs/assets/2024-03-17_01-43.png b/docs/assets/2024-03-17_01-43.png
new file mode 100644
index 0000000..245af61
Binary files /dev/null and b/docs/assets/2024-03-17_01-43.png differ
diff --git a/flake.lock b/flake.lock
index 278ff15..5c8c4aa 100644
--- a/flake.lock
+++ b/flake.lock
@@ -221,6 +221,227 @@
"type": "github"
}
},
+ "hyprcursor": {
+ "inputs": {
+ "hyprlang": "hyprlang_2",
+ "nixpkgs": [
+ "hyprland",
+ "nixpkgs"
+ ],
+ "systems": [
+ "hyprland",
+ "systems"
+ ]
+ },
+ "locked": {
+ "lastModified": 1710091028,
+ "narHash": "sha256-yFk2kc8J2kVh0RWlwT+PQf0bpfUNcROOcRYcyQJbpk4=",
+ "owner": "hyprwm",
+ "repo": "hyprcursor",
+ "rev": "05db7dfd7fc261e0195e54f8a6d655d4f370e70f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hyprcursor",
+ "type": "github"
+ }
+ },
+ "hypridle": {
+ "inputs": {
+ "hyprlang": "hyprlang",
+ "nixpkgs": "nixpkgs_3",
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1710180874,
+ "narHash": "sha256-ZSn3wXQuRz36Ta/L+UCFKuUVG6QpwK2QmRkPjpQprU4=",
+ "owner": "hyprwm",
+ "repo": "hypridle",
+ "rev": "4395339a2dc410bcf49f3e24f9ed3024fdb25b0a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hypridle",
+ "type": "github"
+ }
+ },
+ "hyprland": {
+ "inputs": {
+ "hyprcursor": "hyprcursor",
+ "hyprland-protocols": "hyprland-protocols",
+ "hyprlang": "hyprlang_3",
+ "nixpkgs": "nixpkgs_4",
+ "systems": "systems_3",
+ "wlroots": "wlroots",
+ "xdph": "xdph"
+ },
+ "locked": {
+ "lastModified": 1710344304,
+ "narHash": "sha256-jE+/UGqRYkKBBpLTTV5ayCtVmD9N1WsSKpufszUPzcA=",
+ "owner": "hyprwm",
+ "repo": "Hyprland",
+ "rev": "3e67ee0f5f66c74c0a0bd4f797361fd100c2e2d2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "Hyprland",
+ "type": "github"
+ }
+ },
+ "hyprland-catppuccin": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1702668781,
+ "narHash": "sha256-9BhZq9J1LmHfAPBqOr64chiAEzS+YV6zqe9ma95V3no=",
+ "owner": "catppuccin",
+ "repo": "hyprland",
+ "rev": "fc228737d3d0c12e34a7fa155a0fc3192e5e4017",
+ "type": "github"
+ },
+ "original": {
+ "owner": "catppuccin",
+ "repo": "hyprland",
+ "type": "github"
+ }
+ },
+ "hyprland-protocols": {
+ "inputs": {
+ "nixpkgs": [
+ "hyprland",
+ "nixpkgs"
+ ],
+ "systems": [
+ "hyprland",
+ "systems"
+ ]
+ },
+ "locked": {
+ "lastModified": 1691753796,
+ "narHash": "sha256-zOEwiWoXk3j3+EoF3ySUJmberFewWlagvewDRuWYAso=",
+ "owner": "hyprwm",
+ "repo": "hyprland-protocols",
+ "rev": "0c2ce70625cb30aef199cb388f99e19a61a6ce03",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hyprland-protocols",
+ "type": "github"
+ }
+ },
+ "hyprlang": {
+ "inputs": {
+ "nixpkgs": [
+ "hypridle",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1708212860,
+ "narHash": "sha256-nW3Zrhh9RJcMTvOcXAaKADnJM/g6tDf3121lJtTHnYo=",
+ "owner": "hyprwm",
+ "repo": "hyprlang",
+ "rev": "11d5ccda071c153dfdc18ef65338956a51cef96a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hyprlang",
+ "type": "github"
+ }
+ },
+ "hyprlang_2": {
+ "inputs": {
+ "nixpkgs": [
+ "hyprland",
+ "hyprcursor",
+ "nixpkgs"
+ ],
+ "systems": "systems_2"
+ },
+ "locked": {
+ "lastModified": 1709914708,
+ "narHash": "sha256-bR4o3mynoTa1Wi4ZTjbnsZ6iqVcPGriXp56bZh5UFTk=",
+ "owner": "hyprwm",
+ "repo": "hyprlang",
+ "rev": "a685493fdbeec01ca8ccdf1f3655c044a8ce2fe2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hyprlang",
+ "type": "github"
+ }
+ },
+ "hyprlang_3": {
+ "inputs": {
+ "nixpkgs": [
+ "hyprland",
+ "nixpkgs"
+ ],
+ "systems": [
+ "hyprland",
+ "systems"
+ ]
+ },
+ "locked": {
+ "lastModified": 1709914708,
+ "narHash": "sha256-bR4o3mynoTa1Wi4ZTjbnsZ6iqVcPGriXp56bZh5UFTk=",
+ "owner": "hyprwm",
+ "repo": "hyprlang",
+ "rev": "a685493fdbeec01ca8ccdf1f3655c044a8ce2fe2",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hyprlang",
+ "type": "github"
+ }
+ },
+ "hyprlang_4": {
+ "inputs": {
+ "nixpkgs": [
+ "hyprlock",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1708212860,
+ "narHash": "sha256-nW3Zrhh9RJcMTvOcXAaKADnJM/g6tDf3121lJtTHnYo=",
+ "owner": "hyprwm",
+ "repo": "hyprlang",
+ "rev": "11d5ccda071c153dfdc18ef65338956a51cef96a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hyprlang",
+ "type": "github"
+ }
+ },
+ "hyprlock": {
+ "inputs": {
+ "hyprlang": "hyprlang_4",
+ "nixpkgs": "nixpkgs_5",
+ "systems": "systems_4"
+ },
+ "locked": {
+ "lastModified": 1710528547,
+ "narHash": "sha256-zi2exTT5e3OOK6P7s6IjdiUUIawhqMN4R9RiUJ+T6Fc=",
+ "owner": "hyprwm",
+ "repo": "hyprlock",
+ "rev": "7ee406bf9b11351e3d73e6b6b2aec7de93ba61bf",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "hyprlock",
+ "type": "github"
+ }
+ },
"nix-colors": {
"inputs": {
"base16-schemes": "base16-schemes",
@@ -321,6 +542,54 @@
}
},
"nixpkgs_3": {
+ "locked": {
+ "lastModified": 1708475490,
+ "narHash": "sha256-g1v0TsWBQPX97ziznfJdWhgMyMGtoBFs102xSYO4syU=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "0e74ca98a74bc7270d28838369593635a5db3260",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_4": {
+ "locked": {
+ "lastModified": 1709961763,
+ "narHash": "sha256-6H95HGJHhEZtyYA3rIQpvamMKAGoa8Yh2rFV29QnuGw=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "3030f185ba6a4bf4f18b87f345f104e6a6961f34",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_5": {
+ "locked": {
+ "lastModified": 1708475490,
+ "narHash": "sha256-g1v0TsWBQPX97ziznfJdWhgMyMGtoBFs102xSYO4syU=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "0e74ca98a74bc7270d28838369593635a5db3260",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_6": {
"locked": {
"lastModified": 1710162809,
"narHash": "sha256-i2R2bcnQp+85de67yjgZVvJhd6rRnJbSYNpGmB6Leb8=",
@@ -341,9 +610,142 @@
"crystal-flake": "crystal-flake",
"hardware": "hardware",
"home-manager": "home-manager",
+ "hypridle": "hypridle",
+ "hyprland": "hyprland",
+ "hyprland-catppuccin": "hyprland-catppuccin",
+ "hyprlock": "hyprlock",
"nix-colors": "nix-colors",
- "nixpkgs": "nixpkgs_3",
- "nixpkgs-unstable": "nixpkgs-unstable"
+ "nixpkgs": "nixpkgs_6",
+ "nixpkgs-unstable": "nixpkgs-unstable",
+ "waybar-catppuccin": "waybar-catppuccin"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1689347949,
+ "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
+ "owner": "nix-systems",
+ "repo": "default-linux",
+ "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default-linux",
+ "type": "github"
+ }
+ },
+ "systems_2": {
+ "locked": {
+ "lastModified": 1689347949,
+ "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
+ "owner": "nix-systems",
+ "repo": "default-linux",
+ "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default-linux",
+ "type": "github"
+ }
+ },
+ "systems_3": {
+ "locked": {
+ "lastModified": 1689347949,
+ "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
+ "owner": "nix-systems",
+ "repo": "default-linux",
+ "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default-linux",
+ "type": "github"
+ }
+ },
+ "systems_4": {
+ "locked": {
+ "lastModified": 1689347949,
+ "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
+ "owner": "nix-systems",
+ "repo": "default-linux",
+ "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default-linux",
+ "type": "github"
+ }
+ },
+ "waybar-catppuccin": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1678438606,
+ "narHash": "sha256-WLJMA2X20E5PCPg0ZPtSop0bfmu+pLImP9t8A8V4QK8=",
+ "owner": "catppuccin",
+ "repo": "waybar",
+ "rev": "f74ab1eecf2dcaf22569b396eed53b2b2fbe8aff",
+ "type": "github"
+ },
+ "original": {
+ "owner": "catppuccin",
+ "repo": "waybar",
+ "type": "github"
+ }
+ },
+ "wlroots": {
+ "flake": false,
+ "locked": {
+ "host": "gitlab.freedesktop.org",
+ "lastModified": 1709983277,
+ "narHash": "sha256-wXWIJLd4F2JZeMaihWVDW/yYXCLEC8OpeNJZg9a9ly8=",
+ "owner": "wlroots",
+ "repo": "wlroots",
+ "rev": "50eae512d9cecbf0b3b1898bb1f0b40fa05fe19b",
+ "type": "gitlab"
+ },
+ "original": {
+ "host": "gitlab.freedesktop.org",
+ "owner": "wlroots",
+ "repo": "wlroots",
+ "rev": "50eae512d9cecbf0b3b1898bb1f0b40fa05fe19b",
+ "type": "gitlab"
+ }
+ },
+ "xdph": {
+ "inputs": {
+ "hyprland-protocols": [
+ "hyprland",
+ "hyprland-protocols"
+ ],
+ "hyprlang": [
+ "hyprland",
+ "hyprlang"
+ ],
+ "nixpkgs": [
+ "hyprland",
+ "nixpkgs"
+ ],
+ "systems": [
+ "hyprland",
+ "systems"
+ ]
+ },
+ "locked": {
+ "lastModified": 1709299639,
+ "narHash": "sha256-jYqJM5khksLIbqSxCLUUcqEgI+O2LdlSlcMEBs39CAU=",
+ "owner": "hyprwm",
+ "repo": "xdg-desktop-portal-hyprland",
+ "rev": "2d2fb547178ec025da643db57d40a971507b82fe",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hyprwm",
+ "repo": "xdg-desktop-portal-hyprland",
+ "type": "github"
}
}
},
diff --git a/flake.nix b/flake.nix
index 51bdfa9..f0bfea7 100644
--- a/flake.nix
+++ b/flake.nix
@@ -14,6 +14,15 @@
catppuccin-vsc.url = "github:catppuccin/vscode";
crystal-flake.url = "github:manveru/crystal-flake";
+
+ hyprland.url = "github:hyprwm/Hyprland";
+ hyprlock.url = "github:hyprwm/hyprlock";
+ hypridle.url = "github:hyprwm/hypridle";
+
+ waybar-catppuccin.url = "github:catppuccin/waybar";
+ waybar-catppuccin.flake = false;
+ hyprland-catppuccin.url = "github:catppuccin/hyprland";
+ hyprland-catppuccin.flake = false;
};
outputs = inputs @ {
diff --git a/hosts/seven-red-suns/default.nix b/hosts/seven-red-suns/default.nix
index 1f28c7a..6afe63a 100644
--- a/hosts/seven-red-suns/default.nix
+++ b/hosts/seven-red-suns/default.nix
@@ -23,6 +23,10 @@
cowsay file which tree gnused yt-dlp prismlauncher
] ++ (with pkgs.my; [
olympus iterator-icons
+ ]) ++ (with pkgs.gnome; [
+ # these are usually defaults, but are missing when non-gnome DEs are used
+ # however gnome apps are my beloved so i'm just adding them back
+ nautilus gnome-system-monitor pkgs.loupe gnome-disk-utility pkgs.gedit file-roller
]);
# usually you don't need to do this, but this is a workaround for https://github.com/flameshot-org/flameshot/issues/3328
@@ -44,7 +48,8 @@
};
desktop = {
envProto = "wayland";
- gnome.enable = true;
+
+ /*gnome.enable = true;
gnome.keybinds.shell = {
# disable defaults
"screenshot" = [];
@@ -70,8 +75,21 @@
binding = "Launch1";
command = ''${grabScript}'';
};
- };
+ };*/
+
#xfce.enable = true;
+
+ # in my mind they're a lesbian polycule
+ hyprland.enable = true;
+ hyprlock.enable = true;
+ hyprpaper.enable = true;
+ hypridle.enable = true;
+
+ dunst.enable = true;
+ waybar.enable = true;
+ rofi.enable = true;
+ nwg-drawer.enable = true;
+
themes.active = "catppuccin";
};
software = {
diff --git a/hosts/seven-red-suns/lenovo-thinkpad-x1-1st-gen.nix b/hosts/seven-red-suns/lenovo-thinkpad-x1-1st-gen.nix
index 7d43ed7..26f7996 100644
--- a/hosts/seven-red-suns/lenovo-thinkpad-x1-1st-gen.nix
+++ b/hosts/seven-red-suns/lenovo-thinkpad-x1-1st-gen.nix
@@ -1,6 +1,6 @@
# Largely based upon https://www.thinkwiki.org/wiki/X1_Linux_Tweaks
-{ ... }:
+{ pkgs, ... }:
{
# Laptop-specific battery usage tuning
powerManagement.enable = true;
@@ -11,8 +11,37 @@
# Use power-profile-daemon for battery saving management
services.power-profiles-daemon.enable = true;
+ # better performance than the actual Intel driver
+ services.xserver.videoDrivers = ["modesetting"];
+
+ # OpenCL support and VAAPI
+ hardware.opengl = {
+ extraPackages = with pkgs; [
+ #intel-compute-runtime
+ intel-media-driver
+ intel-vaapi-driver
+ libvdpau-va-gl
+ ];
+
+ extraPackages32 = with pkgs.pkgsi686Linux; [
+ #intel-compute-runtime
+ intel-media-driver
+ intel-vaapi-driver
+ libvdpau-va-gl
+ ];
+ };
+
+ environment.variables = {
+ LIBVA_DRIVER_NAME = "iHD";
+ VDPAU_DRIVER = "va_gl";
+ };
+
+ environment.systemPackages = with pkgs; [ intel-gpu-tools ];
+
boot.kernelParams = [
# Enable the i915 Sandybridge Framebuffer Compression (confirmed 475mw savings)
"i915.i915_enable_fbc=1"
+ "i915.fastboot=1"
+ "enable_gvt=1"
];
}
\ No newline at end of file
diff --git a/modules/desktop/default.nix b/modules/desktop/default.nix
index c104a3a..e21c935 100644
--- a/modules/desktop/default.nix
+++ b/modules/desktop/default.nix
@@ -42,10 +42,31 @@ in {
# https://discourse.nixos.org/t/boot-faster-by-disabling-udev-settle-and-nm-wait-online/6339
systemd.services.systemd-udev-settle.enable = false;
systemd.services.NetworkManager-wait-online.enable = false;
+
+ # https://wiki.archlinux.org/title/Systemd/Journal#Persistent_journals
+ # limit systemd journal size
+ # journals get big really fasti and on desktops they are not audited often
+ # on servers, however, they are important for both security and stability
+ # thus, persisting them as is remains a good idea
+ services.journald.extraConfig = ''
+ SystemMaxUse=100M
+ RuntimeMaxUse=50M
+ SystemMaxFileSize=50M
+ '';
}
(mkIf (cfg.envProto == "wayland") {
- # https://github.com/NixOS/nixpkgs/commit/b2eb5f62a7fd94ab58acafec9f64e54f97c508a6
- environment.sessionVariables.NIXOS_OZONE_WL = "1";
+ environment.sessionVariables = {
+ # https://github.com/NixOS/nixpkgs/commit/b2eb5f62a7fd94ab58acafec9f64e54f97c508a6
+ NIXOS_OZONE_WL = "1";
+ # the rest are borrowed from https://github.com/NotAShelf/nyx/blob/9fbba55f565c630469a971bc71e5957dc228703b/modules/core/common/system/os/display/wayland/environment.nix#L18
+ _JAVA_AWT_WM_NONEREPARENTING = "1";
+ GDK_BACKEND = "wayland,x11";
+ ANKI_WAYLAND = "1";
+ MOZ_ENABLE_WAYLAND = "1";
+ XDG_SESSION_TYPE = "wayland";
+ SDL_VIDEODRIVER = "wayland";
+ CLUTTER_BACKEND = "wayland";
+ };
})
(mkIf (cfg.envProto == "x11") {
services.xserver.excludePackages = [ pkgs.xterm ];
diff --git a/modules/desktop/dunst.nix b/modules/desktop/dunst.nix
new file mode 100644
index 0000000..dabe965
--- /dev/null
+++ b/modules/desktop/dunst.nix
@@ -0,0 +1,17 @@
+{ lib, config, ... }:
+
+with lib;
+let
+ cfg = config.modules.desktop.dunst;
+in {
+ options.modules.desktop.dunst = {
+ enable = mkEnableOption "Enable dunst, a lightweight replacement for the notification daemons provided by most desktop environments";
+ };
+
+ config = mkIf cfg.enable {
+ hm.services.dunst = {
+ enable = true;
+ configFile = ../../config/dunst.conf;
+ };
+ };
+}
\ No newline at end of file
diff --git a/modules/desktop/fonts.nix b/modules/desktop/fonts.nix
index 7cc0d0d..d459064 100644
--- a/modules/desktop/fonts.nix
+++ b/modules/desktop/fonts.nix
@@ -94,6 +94,7 @@ in {
"org/gnome/desktop/interface".monospace-font-name = with cfg.fonts.monospace; "${family} ${toString size}";
};
} // (mkIf cfg.baseFonts {
+ fonts.enableDefaultPackages = true;
fonts.packages = with pkgs; [
fira-code
fira-code-symbols
@@ -102,6 +103,10 @@ in {
proggyfonts
atkinson-hyperlegible
cozette
+ twemoji-color-font
+ noto-fonts-color-emoji
+ noto-fonts-monochrome-emoji
+ #font-awesome
];
});
}
\ No newline at end of file
diff --git a/modules/desktop/hypridle.nix b/modules/desktop/hypridle.nix
new file mode 100644
index 0000000..8b9fae3
--- /dev/null
+++ b/modules/desktop/hypridle.nix
@@ -0,0 +1,40 @@
+{ lib, config, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.modules.desktop.hypridle;
+in {
+ options.modules.desktop.hypridle = {
+ enable = mkEnableOption "Enable hypridle, Hyprland's idle daemon";
+ };
+
+ config = mkIf cfg.enable {
+ hm.services.hypridle = {
+ enable = true;
+
+ lockCmd = "${lib.getExe config.hm.programs.hyprlock.package}";
+ unlockCmd = "pkill -USR1 hyprlock";
+
+ listeners = [
+ {
+ timeout = 60 * 1; # 1 min
+ onTimeout = "${lib.getExe pkgs.brightnessctl} -s set 20";
+ onResume = "${lib.getExe pkgs.brightnessctl} -r" ;
+ }
+ {
+ timeout = 90; # 1.5 min
+ onTimeout = "hyprctl dispatch dpms off"; # turn off screen
+ onResume = "hyprctl dispatch dpms on"; # turn it back on
+ }
+ {
+ timeout = 60 * 2; # 2 min
+ onTimeout = "loginctl lock-session"; # lock the system
+ }
+ {
+ timeout = 60 * 5; # 5 min
+ onTimeout = "systemctl suspend"; # suspend
+ }
+ ];
+ };
+ };
+}
\ No newline at end of file
diff --git a/modules/desktop/hyprland.nix b/modules/desktop/hyprland.nix
new file mode 100644
index 0000000..0ba63ec
--- /dev/null
+++ b/modules/desktop/hyprland.nix
@@ -0,0 +1,267 @@
+{ inputs, lib, config, system, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.modules.desktop.hyprland;
+in {
+ options.modules.desktop.hyprland = {
+ enable = mkEnableOption "Enable Hyprland, a dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks";
+ allowTearing = mkEnableOption "Enable tearing, reduces latency in games but unsupported on some GPUs";
+ };
+
+ config = let
+ hyprpkgs = inputs.hyprland.packages.${system};
+ in mkIf cfg.enable {
+ services.xserver.displayManager.sessionPackages = [ hyprpkgs.hyprland ];
+ xdg.portal = {
+ enable = true;
+ extraPortals = [ pkgs.xdg-desktop-portal-gtk hyprpkgs.xdg-desktop-portal-hyprland ];
+ config = {
+ common = {
+ default = [ "hyprland" "gtk" ];
+
+ # for flameshot to work
+ # https://github.com/flameshot-org/flameshot/issues/3363#issuecomment-1753771427
+ "org.freedesktop.impl.portal.Screencast" = "hyprland";
+ "org.freedesktop.impl.portal.Screenshot" = "hyprland";
+ };
+ };
+ };
+ hm.wayland.windowManager.hyprland = {
+ enable = true;
+ xwayland.enable = true;
+ package = hyprpkgs.hyprland;
+
+ settings = {
+ source = [];
+
+ "$mod" = "SUPER";
+ bindm = [
+ # Move/resize windows with mod + LMB/RMB and dragging
+ "$mod, mouse:272, movewindow"
+ "$mod, mouse:273, resizewindow"
+ ];
+ bindel = [
+ ", XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 10%+"
+ ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 10%-"
+ ", XF86MonBrightnessUp, exec, ${lib.getExe pkgs.brightnessctl} s +5%"
+ ", XF86MonBrightnessDown, exec, ${lib.getExe pkgs.brightnessctl} s 5%-"
+ ];
+ bindl = [
+ ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
+ ", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
+ ];
+ bindr = [
+ "SUPER, Super_L, exec, ${lib.getExe pkgs.nwg-drawer}"
+ ];
+ bind =
+ [
+ "$mod, R, exec, ${lib.getExe pkgs.rofi-wayland} -show run"
+ ", Print, exec, ${lib.getExe pkgs.grimblast} copy area"
+ "$mod, T, exec, ${lib.getExe pkgs.wezterm}"
+ #"$mod, ;, exec, "
+ "$mod, Q, killactive, "
+ #"$mod, M, exit, "
+ "$mod, V, togglefloating, "
+ "$mod, P, pseudo, " # dwindle
+ "$mod, J, togglesplit, " # dwindle
+
+ # Move focus with mod + arrow keys
+ "$mod, left, movefocus, l"
+ "$mod, right, movefocus, r"
+ "$mod, up, movefocus, u"
+ "$mod, down, movefocus, d"
+
+ # Example special workspace (scratchpad)
+ "$mod, S, togglespecialworkspace, magic"
+ "$mod SHIFT, S, movetoworkspace, special:magic"
+
+ # Scroll through existing workspaces with mod + scroll
+ "$mod, mouse_down, workspace, e+1"
+ "$mod, mouse_up, workspace, e-1"
+ ]
+ ++ (
+ # workspaces
+ # binds $mod + [shift +] {1..10} to [move to] workspace {1..10}
+ builtins.concatLists (builtins.genList (
+ x: let
+ ws = let
+ c = (x + 1) / 10;
+ in
+ builtins.toString (x + 1 - (c * 10));
+ in [
+ "$mod, ${ws}, workspace, ${toString (x + 1)}"
+ "$mod SHIFT, ${ws}, movetoworkspace, ${toString (x + 1)}"
+ ]
+ )
+ 10)
+ );
+
+ input = {
+ kb_layout = "us,ru";
+ kb_variant = "workman,";
+ kb_options = "grp:alt_shift_toggle";
+ touchpad = {
+ disable_while_typing = false;
+ natural_scroll = true;
+ };
+
+ follow_mouse = 1;
+
+ sensitivity = 0; # -1.0 - 1.0, 0 means no modification.
+ };
+
+ # basically porting the default config for safety
+
+ # See https://wiki.hyprland.org/Configuring/Monitors/
+ monitor=",highrr,auto,auto";
+
+
+ # See https://wiki.hyprland.org/Configuring/Keywords/ for more
+
+ # Execute your favorite apps at launch
+ # exec-once = waybar & hyprpaper & firefox
+
+ exec-once = [ "${lib.getExe pkgs.networkmanagerapplet}" ];
+
+ # Source a file (multi-file configs)
+ # source = ~/.config/hypr/myColors.conf
+
+ # Some default env vars.
+ env = [
+ "XCURSOR_THEME,${config.modules.desktop.themes.cursor.name}"
+ "XCURSOR_SIZE,24"
+ ];
+
+ general = {
+ # See https://wiki.hyprland.org/Configuring/Variables/ for more
+
+ gaps_in = 6;
+ gaps_out = 6;
+ border_size = 2;
+ no_border_on_floating = true;
+
+ layout = "dwindle";
+
+ resize_on_border = true;
+
+ # https://wiki.hyprland.org/Configuring/Tearing/
+ allow_tearing = cfg.allowTearing;
+ };
+
+ windowrulev2 = [
+ # i think this only applies to proton
+ "immediate, class:^steam_app_"
+ "float, class:^steam_app_"
+
+ # common popups
+ "float, class:file-roller"
+ "float, class:org.gnome.Loupe"
+ "float, initialTitle:^Open Folder$"
+ "float, initialTitle:^Open File$"
+
+ #"float, class:org.gnome.Nautilus"
+
+ # fix focus
+ "stayfocused, class:^pinentry-"
+ "stayfocused, class:^rofi"
+
+ # workspace moving
+ "workspace 1, class:^vivaldi"
+ "workspace 2, class:code-url-handler"
+ "workspace 4, class:ArmCord"
+ ];
+
+ blurls = [
+ "gtk-layer-shell"
+ "waybar"
+ ];
+
+ decoration = {
+ # See https://wiki.hyprland.org/Configuring/Variables/ for more
+
+ rounding = 10;
+
+ blur = {
+ enabled = true;
+ size = 4;
+ passes = 1;
+ #popups = true;
+ };
+
+ drop_shadow = false;
+ #shadow_range = 4;
+ #shadow_render_power = 3;
+
+ # mistake mistake mistkae mistake mistake mistake mistake mistake mistake mistake
+ #screen_shader = toString ../../config/analys.frag;
+ };
+
+ animations = {
+ enabled = true;
+
+ # https://wiki.hyprland.org/Configuring/Animations/
+
+ bezier = [
+ "outCubic, 0.33, 1, 0.68, 1"
+ "outExpo, 0.16, 1, 0.3, 1"
+ ];
+
+ animation = [
+ "windows, 1, 5, outExpo, popin"
+ "windowsOut, 1, 5, outCubic, popin 80%"
+ "border, 1, 2, outExpo"
+ "fade, 1, 3, outCubic"
+ "workspaces, 1, 6, outExpo"
+ ];
+ };
+
+ dwindle = {
+ # See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
+ pseudotile = "yes"; # master switch for pseudotiling. Enabling is bound to mod + P in the keybinds section below
+ preserve_split = "yes"; # you probably want this
+ };
+
+ master = {
+ # See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
+ new_is_master = true;
+ };
+
+ gestures = {
+ # See https://wiki.hyprland.org/Configuring/Variables/ for more
+ workspace_swipe = true;
+ };
+
+ misc = {
+ # See https://wiki.hyprland.org/Configuring/Variables/ for more
+ force_default_wallpaper = 0; # Set to 0 to disable the anime mascot wallpapers
+ disable_splash_rendering = true;
+ disable_hyprland_logo = true;
+ vrr = 2;
+ };
+
+ # Example windowrule v1
+ # windowrule = float, ^(kitty)$
+ # Example windowrule v2
+ # windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
+ # See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
+ };
+ # this has to be done this way because source (on my end) is shoved at the bottom
+ # which means the theme variables aren't loaded in the regular config.
+ # luckily, extraConfig is always last
+ extraConfig = ''
+ general {
+ col.active_border=$pink
+ col.inactive_border=$surface0
+ }
+ decoration {
+ col.shadow=$surface0
+ col.shadow_inactive=$surface0
+ }
+ misc {
+ background_color=$crust
+ }
+ '';
+ };
+ };
+}
diff --git a/modules/desktop/hyprlock.nix b/modules/desktop/hyprlock.nix
new file mode 100644
index 0000000..ef1e73a
--- /dev/null
+++ b/modules/desktop/hyprlock.nix
@@ -0,0 +1,63 @@
+{ lib, config, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.modules.desktop.hyprlock;
+in {
+ options.modules.desktop.hyprlock = {
+ enable = mkEnableOption "Enable hyprlock, a simple, yet fast, multi-threaded and GPU-accelerated screen lock for hyprland";
+ };
+
+ config = mkIf cfg.enable {
+ security.pam.services.hyprlock.text = "auth include login";
+ hm.programs.hyprlock = with config.colorScheme.colors; {
+ enable = true;
+ general = {
+ hide_cursor = false;
+ no_fade_in = true;
+ no_fade_out = true;
+ };
+ backgrounds = [
+ {
+ path = toString ../../assets/lockscreen.png;
+ blur_passes = 3;
+ blur_size = 6;
+ }
+ ];
+ labels = [
+ {
+ text = "cmd[update:1000] echo \"$(date +'%H:%M')\"";
+ font_size = 58;
+ color = "rgb(${base05})";
+ font_family = config.modules.desktop.fonts.fonts.sansSerif.family;
+ position = { x = 0; y = 30; };
+ }
+ {
+ text = "cmd[update:1000] echo \"$(date +'%A %B %e')\"";
+ font_size = 14;
+ color = "rgb(${base05})";
+ font_family = config.modules.desktop.fonts.fonts.sansSerif.family;
+ position = { x = 0; y = 10; };
+ }
+ ];
+ input-fields = [
+ {
+ size = { width = 300; height = 28; };
+ outline_thickness = 2;
+ dots_size = 0.2;
+ fade_on_empty = false;
+ placeholder_text = "";
+
+ outer_color = "rgb(${base0E})";
+ inner_color = "rgb(${base00})";
+ font_color = "rgb(${base05})";
+ check_color = "rgb(${base02})";
+ fail_color = "rgb(${base08})";
+ capslock_color = "rgb(${base09})";
+
+ position = { x = 0; y = -30; };
+ }
+ ];
+ };
+ };
+}
\ No newline at end of file
diff --git a/modules/desktop/hyprpaper.nix b/modules/desktop/hyprpaper.nix
new file mode 100644
index 0000000..cef14bf
--- /dev/null
+++ b/modules/desktop/hyprpaper.nix
@@ -0,0 +1,23 @@
+{ lib, config, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.modules.desktop.hyprpaper;
+in {
+ options.modules.desktop.hyprpaper = {
+ enable = mkEnableOption "Enable Hyprpaper, a blazing fast wayland wallpaper utility";
+ };
+
+ config = mkIf cfg.enable {
+ hm.wayland.windowManager.hyprland.settings.exec-once = [ "${lib.getExe pkgs.hyprpaper}" ];
+ hm.xdg.configFile."hypr/hyprpaper.conf" = let
+ img = ../../assets/wallpaper.png;
+ in {
+ text = ''
+ preload = ${img}
+ wallpaper = ,${img}
+ splash = false
+ '';
+ };
+ };
+}
\ No newline at end of file
diff --git a/modules/desktop/nwg-drawer.nix b/modules/desktop/nwg-drawer.nix
new file mode 100644
index 0000000..60244d1
--- /dev/null
+++ b/modules/desktop/nwg-drawer.nix
@@ -0,0 +1,19 @@
+{ lib, config, pkgs, inputs, ... }:
+
+with lib;
+let
+ cfg = config.modules.desktop.nwg-drawer;
+in {
+ options.modules.desktop.nwg-drawer = {
+ enable = mkEnableOption "Enable nwg-drawer, a GTK-based application launcher for Wayland";
+ };
+
+ config = mkIf cfg.enable {
+ hm.wayland.windowManager.hyprland.settings.exec-once = [ "${lib.getExe pkgs.nwg-drawer} -r -nofs -nocats -term wezterm -spacing 15 -fm nautilus" ];
+ hm.xdg.configFile."nwg-drawer/drawer.css".text =
+ builtins.concatStringsSep "\n" [
+ "@import \"${inputs.waybar-catppuccin}/themes/mocha.css\";"
+ (lib.readFile ../../config/nwg-drawer.css)
+ ];
+ };
+}
\ No newline at end of file
diff --git a/modules/desktop/rofi.nix b/modules/desktop/rofi.nix
new file mode 100644
index 0000000..4454266
--- /dev/null
+++ b/modules/desktop/rofi.nix
@@ -0,0 +1,22 @@
+{ lib, config, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.modules.desktop.rofi;
+in {
+ options.modules.desktop.rofi = {
+ enable = mkEnableOption "Enable rofi, a window switcher, run dialog and dmenu replacement";
+ };
+
+ config = mkIf cfg.enable {
+ hm.programs.rofi = {
+ enable = true;
+ package = pkgs.rofi-wayland;
+ font = with config.modules.desktop.fonts.fonts.monospace; "${family} ${toString size}";
+ extraConfig = {
+ show-icons = true;
+ };
+ theme = ../../config/rofi.rasi;
+ };
+ };
+}
\ No newline at end of file
diff --git a/modules/desktop/themes/catppuccin/default.nix b/modules/desktop/themes/catppuccin/default.nix
index 1edf194..934d9d8 100644
--- a/modules/desktop/themes/catppuccin/default.nix
+++ b/modules/desktop/themes/catppuccin/default.nix
@@ -3,7 +3,8 @@
with lib;
let
cfg = config.modules.desktop.themes;
- #accent = "pink"; # TODO?
+ accent = "pink";
+ variant = "mocha";
in {
config = mkIf (cfg.active == "catppuccin") {
colorScheme = inputs.nix-colors.colorSchemes.catppuccin-mocha;
@@ -12,10 +13,10 @@ in {
dark = true;
gtkTheme = {
- name = "Catppuccin-Mocha-Compact-Pink-Dark";
+ name = "Catppuccin-Mocha-Compact-Pink-Dark"; #todo put accent in here
package = pkgs.catppuccin-gtk.override {
- variant = "mocha";
- accents = ["pink"];
+ variant = variant;
+ accents = [ accent ];
tweaks = ["rimless"];
size = "compact";
};
@@ -35,7 +36,7 @@ in {
vscode = {
name = "Catppuccin Mocha";
extension = (pkgs.vscode-extensions.catppuccin.catppuccin-vsc.override {
- accent = "pink";
+ accent = accent;
boldKeywords = false;
italicComments = false;
italicKeywords = false;
@@ -45,6 +46,8 @@ in {
});
};
};
+
+ hyprland = "${inputs.hyprland-catppuccin}/themes/${variant}.conf";
};
};
}
\ No newline at end of file
diff --git a/modules/desktop/themes/default.nix b/modules/desktop/themes/default.nix
index 73de823..a0b1501 100644
--- a/modules/desktop/themes/default.nix
+++ b/modules/desktop/themes/default.nix
@@ -33,6 +33,8 @@ in {
extension = mkPackageOption pkgs "extension" {};
};
};
+
+ hyprland = mkOpt (nullOr str) null;
};
config = mkIf (cfg.active != null) {
@@ -55,11 +57,18 @@ in {
theme = cfg.gtkTheme;
};
+ hm.services.dunst.iconTheme = {
+ name = cfg.iconTheme.name;
+ package = cfg.iconTheme.package;
+ };
+
hm.programs.vscode = {
extensions = [ cfg.editor.vscode.extension ];
userSettings = {
"workbench.colorTheme" = cfg.editor.vscode.name;
};
};
+
+ hm.wayland.windowManager.hyprland.settings.source = mkIf (cfg.hyprland != null) [ cfg.hyprland ];
};
}
\ No newline at end of file
diff --git a/modules/desktop/waybar.nix b/modules/desktop/waybar.nix
new file mode 100644
index 0000000..a93f1b0
--- /dev/null
+++ b/modules/desktop/waybar.nix
@@ -0,0 +1,244 @@
+{ lib, config, pkgs, inputs, ... }:
+
+with lib;
+let
+ cfg = config.modules.desktop.waybar;
+in {
+ options.modules.desktop.waybar = {
+ enable = mkEnableOption "Enable Waybar, a lightweight desktop environment based on GTK+";
+ };
+
+ config = mkIf cfg.enable {
+ hm.wayland.windowManager.hyprland.settings.exec-once = [ "${lib.getExe pkgs.waybar}" ];
+ hm.programs.waybar = {
+ enable = true;
+ #style = builtins.concatStringsSep "\n" [
+ # "@import \"${inputs.waybar-catppuccin}/themes/mocha.css\";"
+ # (lib.readFile ../../config/waybar.css)
+ #];
+ settings = {
+ mainBar = {
+ layer = "top";
+ position = "top";
+ #spacing = 4;
+ height = 24;
+ margin-top = 6;
+ margin-left = 6;
+ margin-right = 6;
+ margin-bottom = 0;
+ modules-left = [
+ "hyprland/workspaces"
+ "hyprland/window"
+ ];
+ modules-center = [
+ "clock"
+ ];
+ modules-right = [
+ "group/status"
+ "tray"
+ "group/power"
+ ];
+
+ "group/status" = {
+ orientation = "inherit";
+ modules = [
+ "hyprland/language"
+ "pulseaudio"
+ "backlight"
+ "cpu"
+ "memory"
+ "power-profiles-daemon"
+ "battery"
+ #"network"
+ ];
+ };
+ "group/power" = {
+ orientation = "inherit";
+ drawer = {
+ transition-duration = 200;
+ children-class = "not-power";
+ transition-left-to-right = false;
+ };
+ modules = [
+ "custom/power"
+ "custom/lock"
+ "custom/reboot"
+ "custom/quit"
+ ];
+ };
+ "custom/quit" = {
+ format = "";
+ tooltip = true;
+ tooltip-format = "Exit Hyprland";
+ on-click = "hyprctl dispatch exit";
+ };
+ "custom/lock" = {
+ format = "";
+ tooltip = true;
+ tooltip-format = "Lock the system";
+ on-click = "hyprlock";
+ };
+ "custom/reboot" = {
+ format = "↻";
+ tooltip = true;
+ tooltip-format = "Reboot";
+ on-click = "reboot";
+ };
+ "custom/power" = {
+ format = "⏻";
+ tooltip = true;
+ tooltip-format = "Power off";
+ on-click = "shutdown now";
+ };
+ "hyprland/workspaces" = {
+ format = "{icon}";
+ format-icons = {
+ "1" = "";
+ "2" = "";
+ "3" = "";
+ "4" = "";
+ urgent = "";
+ default = "•";
+ };
+ persistent-workspaces = {
+ "1" = [];
+ "2" = [];
+ "3" = [];
+ "4" = [];
+ };
+ };
+ "hyprland/window" = {
+ format = "{}";
+ icon = true;
+ icon-size = 16;
+ rewrite = {
+ "(.*) - Vivaldi" = "$1";
+ "(.*) - Visual Studio Code" = "$1";
+ #"(.*\\.nix\\s.*)" = "";
+ "(\\S+\\.js\\s.*)" = " $1";
+ "(\\S+\\.ts\\s.*)" = " $1";
+ "(\\S+\\.go\\s.*)" = " $1";
+ "(\\S+\\.lua\\s.*)" = " $1";
+ "(\\S+\\.java\\s.*)" = " $1";
+ "(\\S+\\.rb\\s.*)" = " $1";
+ "(\\S+\\.php\\s.*)" = " $1";
+ "(\\S+\\.jsonc?\\s.*)" = " $1";
+ "(\\S+\\.md\\s.*)" = " $1";
+ "(\\S+\\.txt\\s.*)" = " $1";
+ "(\\S+\\.cs\\s.*)" = " $1";
+ "(\\S+\\.c\\s.*)" = " $1";
+ "(\\S+\\.cpp\\s.*)" = " $1";
+ "(\\S+\\.hs\\s.*)" = " $1";
+ ".*Discord | (.*) | .*" = "$1 - ArmCord";
+ #"(.*) - ArmCord" = "$1";
+ };
+ separate-outputs = true;
+ };
+ "hyprland/language" = {
+ format = " {}";
+ format-en = "Aa";
+ format-ru = "Ру";
+ on-click = "hyprctl switchxkblayout at-translated-set-2-keyboard next";
+ tooltip = true;
+ tooltip-format = "{flag} {long}";
+ };
+ pulseaudio = {
+ format = "{icon} {volume}%";
+ format-bluetooth = "{icon} {volume}%";
+ format-muted = "婢 {volume}%";
+ format-icons = {
+ headphone = "";
+ hands-free = "";
+ headset = "";
+ phone = "";
+ portable = "";
+ car = "";
+ default = ["" "" ""];
+ };
+ scroll-step = 1;
+ on-click = "${lib.getExe pkgs.pavucontrol}";
+ ignored-sinks = ["Easy Effects Sink"];
+ };
+ backlight = {
+ format = "{icon} {percent}%";
+ format-icons = ["" ""];
+ scroll-step = 1;
+ };
+ cpu = {
+ interval = 4;
+ format = " {usage}%";
+ };
+ memory = {
+ interval = 4;
+ format = " {percentage}%";
+ tooltip-format = "{used:0.1f}GiB/{avail:0.1f}GiB used\n{swapUsed:0.1f}GiB/{swapAvail:0.1f}GiB swap";
+ };
+ "battery" = {
+ interval = 30;
+ states = {
+ warning = 20;
+ critical = 10;
+ };
+ full-at = 98;
+ format = "{icon} {capacity}%";
+ format-icons = ["" "" "" "" ""];
+ format-critical = " {capacity}%";
+ tooltip-format = "{timeTo} ({power}W)";
+ format-charging = " {capacity}%";
+ };
+ "network" = {
+ format = "";
+ format-ethernet = "";
+ format-wifi = " {signalStrength}%";
+ format-disconnected = "";
+ tooltip-format = "{ifname} via {gwaddr}";
+ tooltip-format-wifi = "connected to {essid}";
+ tooltip-format-ethernet = "{ifname}";
+ tooltip-format-disconnected = "Disconnected";
+ };
+ "clock" = {
+ format = "{:%H:%M}";
+ format-alt = "{:%a %b %d %R}";
+ tooltip-format = "{calendar}";
+ calendar = {
+ mode = "year";
+ mode-mon-col = 3;
+ weeks-pos = "right";
+ on-scroll = 1;
+ on-click-right = "mode";
+ format = {
+ months = "{}";
+ days = "{}";
+ weeks = "W{}";
+ weekdays = "{}";
+ today = "{}";
+ };
+ actions = {
+ on-click-right = "mode";
+ on-click-forward = "tz_up";
+ on-click-backward = "tz_down";
+ on-scroll-up = "shift_up";
+ on-scroll-down = "shift_down";
+ };
+ };
+ };
+ power-profiles-daemon = {
+ format = "{icon}";
+ tooltip-format = "Power profile: {profile}\nDriver: {driver}";
+ tooltip = true;
+ format-icons = {
+ default = "";
+ performance = " perf";
+ balanced = " balance";
+ power-saver = " save";
+ };
+ };
+ tray = {
+ icon-size = 16;
+ spacing = 4;
+ };
+ };
+ };
+ };
+ };
+}
\ No newline at end of file
diff --git a/modules/fstrim.nix b/modules/fstrim.nix
new file mode 100644
index 0000000..a0e92b1
--- /dev/null
+++ b/modules/fstrim.nix
@@ -0,0 +1,36 @@
+{ config, lib, ... }:
+
+with lib;
+{
+ # if lvm is enabled, then tell it to issue discards
+ # (this is good for SSDs and has almost no downsides on HDDs, so
+ # it's a good idea to enable it unconditionally)
+ environment.etc."lvm/lvm.conf".text = mkIf config.services.lvm.enable ''
+ devices {
+ issue_discards = 1
+ }
+ '';
+
+ # discard blocks that are not in use by the filesystem, good for SSDs
+ services.fstrim = {
+ # we may enable this unconditionally across all systems becuase it's performance
+ # impact is negligible on systems without a SSD - which means it's a no-op with
+ # almost no downsides aside from the service firing once per week
+ enable = true;
+
+ # the default value, good enough for average-load systems
+ interval = "weekly";
+ };
+
+ # tweak fstim service to run only when on AC power
+ # and to be nice to other processes
+ # (this is a good idea for any service that runs periodically)
+ systemd.services.fstrim = {
+ unitConfig.ConditionACPower = true;
+
+ serviceConfig = {
+ Nice = 19;
+ IOSchedulingClass = "idle";
+ };
+ };
+}
\ No newline at end of file
diff --git a/modules/lvm.nix b/modules/lvm.nix
new file mode 100644
index 0000000..b3b3d32
--- /dev/null
+++ b/modules/lvm.nix
@@ -0,0 +1,5 @@
+{lib, ...}:
+{
+ # I don't use lvm, can be disabled
+ services.lvm.enable = lib.mkDefault false;
+}
\ No newline at end of file
diff --git a/modules/security.nix b/modules/security.nix
index 40419f8..b678638 100644
--- a/modules/security.nix
+++ b/modules/security.nix
@@ -67,6 +67,22 @@ in {
};
networking.firewall.enable = false;
+
+ services.usbguard = {
+ IPCAllowedUsers = [ "root" "${env.mainUser}" ];
+ presentDevicePolicy = "allow";
+ rules = ''
+ allow with-interface equals { 08:*:* }
+
+ # Reject devices with suspicious combination of interfaces
+ reject with-interface all-of { 08:*:* 03:00:* }
+ reject with-interface all-of { 08:*:* 03:01:* }
+ reject with-interface all-of { 08:*:* e0:*:* }
+ reject with-interface all-of { 08:*:* 02:*:* }
+ '';
+ };
+
+ environment.systemPackages = [ pkgs.usbguard ];
} // (mkIf cfg.useDoas {
security.sudo.enable = false;
security.doas.enable = true;
diff --git a/modules/software/system/alacritty.nix b/modules/software/system/alacritty.nix
index ee3f0f1..db37584 100644
--- a/modules/software/system/alacritty.nix
+++ b/modules/software/system/alacritty.nix
@@ -9,6 +9,7 @@ in {
};
config = mkIf cfg.enable {
+ hm.programs.rofi.terminal = "alacritty";
hm.programs.alacritty = {
enable = true;
# custom settings
diff --git a/modules/software/system/wezterm.nix b/modules/software/system/wezterm.nix
index 0e3a2e6..0bc3ac9 100644
--- a/modules/software/system/wezterm.nix
+++ b/modules/software/system/wezterm.nix
@@ -9,6 +9,7 @@ in {
};
config = mkIf cfg.enable {
+ hm.programs.rofi.terminal = "wezterm";
hm.programs.wezterm = {
enable = true;
# custom settings
@@ -47,4 +48,4 @@ in {
'';
};
};
-}
\ No newline at end of file
+}
diff --git a/overlays/waybar.nix b/overlays/waybar.nix
new file mode 100644
index 0000000..d865892
--- /dev/null
+++ b/overlays/waybar.nix
@@ -0,0 +1,31 @@
+final: prev: {
+ waybar = prev.waybar.overrideAttrs ( old: {
+ version = "0.10.0";
+
+ src = prev.fetchFromGitHub {
+ owner = "Alexays";
+ repo = "Waybar";
+ rev = "0.10.0";
+ hash = "sha256-p1VRrKT2kTDy48gDXPMHlLbfcokAOFeTZXGzTeO1SAE=";
+ };
+
+ # fix gtk-layer-shell issue
+ mesonFlags = builtins.filter (a: !(prev.lib.strings.hasInfix "gtk-layer-shell" a)) old.mesonFlags;
+
+ # fix cava version mismatch issue
+ postUnpack = let
+ # Derived from subprojects/cava.wrap
+ libcava.src = prev.fetchFromGitHub {
+ owner = "LukashonakV";
+ repo = "cava";
+ rev = "0.10.1";
+ hash = "sha256-iIYKvpOWafPJB5XhDOSIW9Mb4I3A4pcgIIPQdQYEqUw=";
+ };
+ in ''
+ pushd "$sourceRoot"
+ cp -R --no-preserve=mode,ownership ${libcava.src} subprojects/cava-0.10.1
+ patchShebangs .
+ popd
+ '';
+ } );
+}
\ No newline at end of file