summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-06-22 04:24:07 -0700
committerFuwn <[email protected]>2024-06-22 04:24:07 -0700
commitf440ba84f27fb322448e444b7eb62ff56033fc67 (patch)
tree8b041fc95766367e4a6fa99b6594dadb1728dacb
downloadnixos-config-f440ba84f27fb322448e444b7eb62ff56033fc67.tar.xz
nixos-config-f440ba84f27fb322448e444b7eb62ff56033fc67.zip
feat: initial configuration
-rw-r--r--.gitignore5
-rw-r--r--applications/cli/bat/default.nix6
-rw-r--r--applications/cli/default.nix13
-rw-r--r--applications/cli/eza/default.nix7
-rw-r--r--applications/cli/fd/default.nix1
-rw-r--r--applications/cli/gemini/bollux/default.nix36
-rw-r--r--applications/cli/gemini/default.nix4
-rw-r--r--applications/cli/nvtop/default.nix1
-rw-r--r--applications/cli/ripgrep/default.nix4
-rw-r--r--applications/cli/rm-improved/default.nix1
-rw-r--r--applications/cli/starship/default.nix301
-rw-r--r--applications/cli/tealdeer/default.nix1
-rw-r--r--applications/default.nix1
-rw-r--r--applications/gui/default.nix7
-rw-r--r--applications/gui/gemini/default.nix1
-rw-r--r--applications/gui/kitty/default.nix1
-rw-r--r--applications/gui/warp/default.nix1
-rw-r--r--desktop/default.nix1
-rw-r--r--desktop/wayland/default.nix1
-rw-r--r--desktop/wayland/hyprland/default.nix19
-rw-r--r--desktop/wayland/hyprland/hypridle/default.nix34
-rw-r--r--desktop/wayland/hyprland/hyprland/animations.nix86
-rw-r--r--desktop/wayland/hyprland/hyprland/binds.nix208
-rw-r--r--desktop/wayland/hyprland/hyprland/decoration.nix44
-rw-r--r--desktop/wayland/hyprland/hyprland/default.nix42
-rw-r--r--desktop/wayland/hyprland/hyprland/environment.nix78
-rw-r--r--desktop/wayland/hyprland/hyprland/executions.nix53
-rw-r--r--desktop/wayland/hyprland/hyprland/general.nix137
-rw-r--r--desktop/wayland/hyprland/hyprland/plugins.nix69
-rw-r--r--desktop/wayland/hyprland/hyprland/rules.nix94
-rw-r--r--desktop/wayland/hyprland/hyprland/scripts/common.sh146
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/fake_fullscreen_status18
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/hycov_easymotion10
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/initialise_gtk17
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/initialise_waybar22
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/initialise_xdg_portal13
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/move_focus_to_monitor9
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/move_window_to_monitor18
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/move_window_to_workspace12
-rw-r--r--desktop/wayland/hyprland/hyprland/scripts/source/screenshot.ab158
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/switch_workspace5
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/toggle_gaps13
-rwxr-xr-xdesktop/wayland/hyprland/hyprland/scripts/toggle_layout22
-rw-r--r--desktop/wayland/hyprland/hyprland/workspaces.nix32
-rw-r--r--desktop/wayland/hyprland/pyprland/default.nix38
-rw-r--r--desktop/wayland/waybar/default.nix95
-rw-r--r--desktop/wayland/waybar/waybar/default-modules.nix324
-rwxr-xr-xdesktop/wayland/waybar/waybar/scripts/brightness.sh54
-rwxr-xr-xdesktop/wayland/waybar/waybar/scripts/mediaplayer.py155
-rwxr-xr-xdesktop/wayland/waybar/waybar/scripts/spotify.sh27
-rwxr-xr-xdesktop/wayland/waybar/waybar/scripts/theme.sh45
-rwxr-xr-xdesktop/wayland/waybar/waybar/scripts/volume.sh73
-rwxr-xr-xdesktop/wayland/waybar/waybar/scripts/wallpaper.sh28
-rw-r--r--desktop/wayland/waybar/waybar/style.css133
-rw-r--r--home.nix89
-rw-r--r--rice/bottom/default.nix1
-rw-r--r--rice/default.nix3
-rw-r--r--rice/fastfetch/default.nix31
-rw-r--r--tools/default.nix1
-rw-r--r--tools/languages/c/default.nix1
-rw-r--r--tools/languages/default.nix1
-rw-r--r--tools/languages/gleam/default.nix1
-rw-r--r--tools/languages/go/default.nix1
-rw-r--r--tools/languages/javascript/default.nix9
-rw-r--r--tools/languages/python/default.nix1
-rw-r--r--tools/languages/rust/default.nix3
-rw-r--r--tools/nix/default.nix10
-rw-r--r--tools/tcp/default.nix1
68 files changed, 2877 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..379dde0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+# Visual Studio Code
+.vscode
+
+# Temporary Files
+*.bak
diff --git a/applications/cli/bat/default.nix b/applications/cli/bat/default.nix
new file mode 100644
index 0000000..c1dad3f
--- /dev/null
+++ b/applications/cli/bat/default.nix
@@ -0,0 +1,6 @@
+{ pkgs, ... }: {
+ programs.bat = {
+ enable = true;
+ config.pager = "less -FR";
+ };
+}
diff --git a/applications/cli/default.nix b/applications/cli/default.nix
new file mode 100644
index 0000000..ac6975d
--- /dev/null
+++ b/applications/cli/default.nix
@@ -0,0 +1,13 @@
+_: {
+ imports = [
+ ./bat
+ ./eza
+ ./fd
+ ./gemini
+ # ./nvtop
+ ./ripgrep
+ ./rm-improved
+ ./starship
+ ./tealdeer
+ ];
+}
diff --git a/applications/cli/eza/default.nix b/applications/cli/eza/default.nix
new file mode 100644
index 0000000..a8d2f57
--- /dev/null
+++ b/applications/cli/eza/default.nix
@@ -0,0 +1,7 @@
+_: {
+ programs.eza = {
+ enable = true;
+ icons = true;
+ enableFishIntegration = true;
+ };
+}
diff --git a/applications/cli/fd/default.nix b/applications/cli/fd/default.nix
new file mode 100644
index 0000000..ba676b1
--- /dev/null
+++ b/applications/cli/fd/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ fd ]; }
diff --git a/applications/cli/gemini/bollux/default.nix b/applications/cli/gemini/bollux/default.nix
new file mode 100644
index 0000000..175fe80
--- /dev/null
+++ b/applications/cli/gemini/bollux/default.nix
@@ -0,0 +1,36 @@
+{ pkgs, lib, ... }:
+let
+ bollux =
+ pkgs.stdenvNoCC.mkDerivation rec {
+ pname = "bollux";
+ version = "f472e60f1164f0dc025d06db2a13ff4e8ebee1a2";
+ src = pkgs.fetchFromGitea {
+ domain = "tildegit.org";
+ owner = "acdw";
+ repo = "bollux";
+ rev = version;
+ hash = "sha256-mo2qWCPfW+dUaYcJLsos/vR5nJ8n1eABy8Zy8OZsfVg=";
+ };
+ installPhase = ''
+ mkdir -p $out/bin
+ make install PREFIX=$out
+ '';
+ meta = with lib; {
+ description = "a Gemini browser in like, idk, 96% pure Bash";
+ homepage = "https://tildegit.org/acdw/bollux";
+ license = licenses.mit;
+ platforms = platforms.unix;
+ mainProgram = "bollux";
+ };
+ };
+in
+{
+ home.packages = [
+ # I'll update this later and move the above derivation to its own package
+ # once I push my entire NixOS system configuration.
+ # (pkgs.callPackage /path/to/pkgs/bollux.nix {
+ # src = bollux;
+ # })
+ bollux
+ ];
+}
diff --git a/applications/cli/gemini/default.nix b/applications/cli/gemini/default.nix
new file mode 100644
index 0000000..c76ecf7
--- /dev/null
+++ b/applications/cli/gemini/default.nix
@@ -0,0 +1,4 @@
+{ pkgs, ... }: {
+ imports = [ ./bollux ];
+ home.packages = with pkgs; [ amfora gmni ];
+}
diff --git a/applications/cli/nvtop/default.nix b/applications/cli/nvtop/default.nix
new file mode 100644
index 0000000..b0a672b
--- /dev/null
+++ b/applications/cli/nvtop/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ nvtopPackages.nvidia ]; }
diff --git a/applications/cli/ripgrep/default.nix b/applications/cli/ripgrep/default.nix
new file mode 100644
index 0000000..5b127fb
--- /dev/null
+++ b/applications/cli/ripgrep/default.nix
@@ -0,0 +1,4 @@
+{ pkgs, ... }: {
+ home.packages = with pkgs; [ ripgrep-all ];
+ # programs.ripgrep.enable = true;
+}
diff --git a/applications/cli/rm-improved/default.nix b/applications/cli/rm-improved/default.nix
new file mode 100644
index 0000000..a7cbebf
--- /dev/null
+++ b/applications/cli/rm-improved/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ rm-improved ]; }
diff --git a/applications/cli/starship/default.nix b/applications/cli/starship/default.nix
new file mode 100644
index 0000000..a23ed9c
--- /dev/null
+++ b/applications/cli/starship/default.nix
@@ -0,0 +1,301 @@
+{ pkgs, ... }: {
+ home.packages = with pkgs; [ starship ];
+ programs.starship = {
+ enable = true;
+ enableFishIntegration = true;
+ # I CBA to update the formatting to match the rest of the expressions, since
+ # this is a one-off that I tend to import over directly from starship.
+ settings = {
+ format = "[term%](bold green) ";
+ right_format = "$character$all";
+ add_newline = false;
+
+ line_break = {
+ disabled = true;
+ };
+
+ character = {
+ success_symbol = "[i](bold green)";
+ error_symbol = "[x](bold red)";
+ vimcmd_symbol = "[n](bold green)";
+ vimcmd_visual_symbol = "[v](bold green)";
+ vimcmd_replace_symbol = "[R](bold green)";
+ vimcmd_replace_one_symbol = "[r](bold green)";
+ };
+
+ git_commit = {
+ tag_symbol = " tag ";
+ };
+
+ git_status = {
+ ahead = ">";
+ behind = "<";
+ diverged = "<>";
+ renamed = "r";
+ deleted = "x";
+ };
+
+ aws = {
+ symbol = "aws ";
+ };
+
+ azure = {
+ symbol = "az ";
+ };
+
+ bun = {
+ symbol = "bun ";
+ };
+
+ c = {
+ symbol = "C ";
+ };
+
+ cobol = {
+ symbol = "cobol ";
+ };
+
+ conda = {
+ symbol = "conda ";
+ };
+
+ crystal = {
+ symbol = "cr ";
+ };
+
+ cmake = {
+ symbol = "cmake ";
+ };
+
+ daml = {
+ symbol = "daml ";
+ };
+
+ dart = {
+ symbol = "dart ";
+ };
+
+ deno = {
+ symbol = "deno ";
+ };
+
+ dotnet = {
+ symbol = ".NET ";
+ };
+
+ directory = {
+ read_only = " ro";
+ };
+
+ docker_context = {
+ symbol = "docker ";
+ };
+
+ elixir = {
+ symbol = "exs ";
+ };
+
+ elm = {
+ symbol = "elm ";
+ };
+
+ fennel = {
+ symbol = "fnl ";
+ };
+
+ fossil_branch = {
+ symbol = "fossil ";
+ };
+
+ gcloud = {
+ symbol = "gcp ";
+ };
+
+ git_branch = {
+ symbol = "git ";
+ };
+
+ golang = {
+ symbol = "go ";
+ };
+
+ gradle = {
+ symbol = "gradle ";
+ };
+
+ guix_shell = {
+ symbol = "guix ";
+ };
+
+ hg_branch = {
+ symbol = "hg ";
+ };
+
+ java = {
+ symbol = "java ";
+ };
+
+ julia = {
+ symbol = "jl ";
+ };
+
+ kotlin = {
+ symbol = "kt ";
+ };
+
+ lua = {
+ symbol = "lua ";
+ };
+
+ nodejs = {
+ symbol = "nodejs ";
+ };
+
+ memory_usage = {
+ symbol = "memory ";
+ };
+
+ meson = {
+ symbol = "meson ";
+ };
+
+ nim = {
+ symbol = "nim ";
+ };
+
+ nix_shell = {
+ symbol = "nix ";
+ };
+
+ ocaml = {
+ symbol = "ml ";
+ };
+
+ opa = {
+ symbol = "opa ";
+ };
+
+ os = {
+ symbols = {
+ Alpaquita = "alq ";
+ Alpine = "alp ";
+ Amazon = "amz ";
+ Android = "andr ";
+ Arch = "rch ";
+ Artix = "atx ";
+ CentOS = "cent ";
+ Debian = "deb ";
+ DragonFly = "dfbsd ";
+ Emscripten = "emsc ";
+ EndeavourOS = "ndev ";
+ Fedora = "fed ";
+ FreeBSD = "fbsd ";
+ Garuda = "garu ";
+ Gentoo = "gent ";
+ HardenedBSD = "hbsd ";
+ Illumos = "lum ";
+ Linux = "lnx ";
+ Mabox = "mbox ";
+ Macos = "mac ";
+ Manjaro = "mjo ";
+ Mariner = "mrn ";
+ MidnightBSD = "mid ";
+ Mint = "mint ";
+ NetBSD = "nbsd ";
+ NixOS = "nix ";
+ OpenBSD = "obsd ";
+ OpenCloudOS = "ocos ";
+ openEuler = "oeul ";
+ openSUSE = "osuse ";
+ OracleLinux = "orac ";
+ Pop = "pop ";
+ Raspbian = "rasp ";
+ Redhat = "rhl ";
+ RedHatEnterprise = "rhel ";
+ Redox = "redox ";
+ Solus = "sol ";
+ SUSE = "suse ";
+ Ubuntu = "ubnt ";
+ Unknown = "unk ";
+ Windows = "win ";
+ };
+ };
+
+ package = {
+ symbol = "pkg ";
+ };
+
+ perl = {
+ symbol = "pl ";
+ };
+
+ php = {
+ symbol = "php ";
+ };
+
+ pijul_channel = {
+ symbol = "pijul ";
+ };
+
+ pulumi = {
+ symbol = "pulumi ";
+ };
+
+ purescript = {
+ symbol = "purs ";
+ };
+
+ python = {
+ symbol = "py ";
+ };
+
+ raku = {
+ symbol = "raku ";
+ };
+
+ ruby = {
+ symbol = "rb ";
+ };
+
+ rust = {
+ symbol = "rs ";
+ };
+
+ scala = {
+ symbol = "scala ";
+ };
+
+ spack = {
+ symbol = "spack ";
+ };
+
+ solidity = {
+ symbol = "solidity ";
+ };
+
+ status = {
+ symbol = "[x](bold red) ";
+ };
+
+ sudo = {
+ symbol = "sudo ";
+ };
+
+ swift = {
+ symbol = "swift ";
+ };
+
+ typst = {
+ symbol = "typst ";
+ };
+
+ terraform = {
+ symbol = "terraform ";
+ };
+
+ zig = {
+ symbol = "zig ";
+ };
+ };
+ };
+}
diff --git a/applications/cli/tealdeer/default.nix b/applications/cli/tealdeer/default.nix
new file mode 100644
index 0000000..54befa9
--- /dev/null
+++ b/applications/cli/tealdeer/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ tealdeer ]; }
diff --git a/applications/default.nix b/applications/default.nix
new file mode 100644
index 0000000..885fdcf
--- /dev/null
+++ b/applications/default.nix
@@ -0,0 +1 @@
+_: { imports = [ ./cli ./gui ]; }
diff --git a/applications/gui/default.nix b/applications/gui/default.nix
new file mode 100644
index 0000000..7c44c60
--- /dev/null
+++ b/applications/gui/default.nix
@@ -0,0 +1,7 @@
+_: {
+ imports = [
+ ./gemini
+ # ./kitty
+ # ./warp
+ ];
+}
diff --git a/applications/gui/gemini/default.nix b/applications/gui/gemini/default.nix
new file mode 100644
index 0000000..28d08de
--- /dev/null
+++ b/applications/gui/gemini/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ geopard ]; }
diff --git a/applications/gui/kitty/default.nix b/applications/gui/kitty/default.nix
new file mode 100644
index 0000000..193f352
--- /dev/null
+++ b/applications/gui/kitty/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { programs.kitty.enable = true; }
diff --git a/applications/gui/warp/default.nix b/applications/gui/warp/default.nix
new file mode 100644
index 0000000..347c651
--- /dev/null
+++ b/applications/gui/warp/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ warp-terminal ]; }
diff --git a/desktop/default.nix b/desktop/default.nix
new file mode 100644
index 0000000..36de93a
--- /dev/null
+++ b/desktop/default.nix
@@ -0,0 +1 @@
+_: { imports = [ ./wayland ]; }
diff --git a/desktop/wayland/default.nix b/desktop/wayland/default.nix
new file mode 100644
index 0000000..a0e1328
--- /dev/null
+++ b/desktop/wayland/default.nix
@@ -0,0 +1 @@
+_: { imports = [ ./hyprland ./waybar ]; }
diff --git a/desktop/wayland/hyprland/default.nix b/desktop/wayland/hyprland/default.nix
new file mode 100644
index 0000000..26ee84d
--- /dev/null
+++ b/desktop/wayland/hyprland/default.nix
@@ -0,0 +1,19 @@
+{ pkgs, ... }: {
+ # Insipration
+ # https://github.com/codingjerk/dotfiles/blob/main/config/hypr/hyprland.conf
+ # https://github.com/JoshM-Yoru/dotfiles/blob/main/hypr/hyprland.conf
+ # https://github.com/end-4/dots-hyprland/blob/main/.config/hypr/hyprland.conf
+ # https://github.com/Andy3153/hyprland-rice
+ imports = [
+ ./hypridle
+ ./pyprland
+ ./hyprland
+ ];
+ wayland.windowManager.hyprland = {
+ enable = true;
+ systemd = {
+ enable = true;
+ variables = [ "--all" ];
+ };
+ };
+}
diff --git a/desktop/wayland/hyprland/hypridle/default.nix b/desktop/wayland/hyprland/hypridle/default.nix
new file mode 100644
index 0000000..78e0153
--- /dev/null
+++ b/desktop/wayland/hyprland/hypridle/default.nix
@@ -0,0 +1,34 @@
+{ pkgs, ... }: {
+ # exec-once = swayidle timeout 600 '[ $(pgrep -x hyprlock || pgrep -x swaylock) ] || (hyprctl dispatcher dpms off && hyprlock)'
+ services.hypridle = {
+ enable = true;
+ settings = {
+ "$lock_command" = "pidof hyprlock || hyprlock";
+ # $suspend_command = pidof steam || systemctl suspend || loginctl suspend # fuck nvidia
+ general = {
+ lock_cmd = "$lock_command";
+
+ # before_sleep_cmd = $suspend_command
+ before_sleep_cmd = "playerctl pause";
+
+ ignore_dbus_inhibit = false;
+ ignore_systemd_inhibit = false;
+ };
+ listener = [
+ {
+ timeout = 180; # 3 minutes
+ on-timeout = "$lock_command";
+ }
+ {
+ timeout = 240; # 4 minutes
+ on-timeout = "hyprctl dispatch dpms off";
+ on-resume = "hyprctl dispatch dpms on";
+ }
+ # {
+ # timeout = 540; # 9 minutes
+ # on-timeout = "$suspend_cmd";
+ # }
+ ];
+ };
+ };
+}
diff --git a/desktop/wayland/hyprland/hyprland/animations.nix b/desktop/wayland/hyprland/hyprland/animations.nix
new file mode 100644
index 0000000..bb8a4e2
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/animations.nix
@@ -0,0 +1,86 @@
+_: {
+ wayland.windowManager.hyprland = {
+ extraConfig = ''
+ # animations {
+ # enabled = yes
+
+ # # bezier = myBezier, 0.05, 0.9, 0.1, 1.05
+
+ # # animation = windows, 1, 5, myBezier
+ # # animation = windowsOut, 1, 7, default, popin
+ # # animation = border, 1, 10, default
+ # # animation = fade, 1, 7, default
+ # # animation = workspaces, 1, 6, default, slidevert
+
+ # # bezier = overshot,0.5,0.1,0.4,1.2
+
+ # # animation = global, 1, 3, default
+ # # animation = workspaces, 1, 4, default
+ # # animation = windowsMove, 1, 2, default
+ # # animation = fade, 1, 2, default
+
+ # bezier = overshot, 0.05, 0.5, 0.1, 1.05
+ # bezier = smoothOut, 0.36, 0, 0.66, -0.56
+ # bezier = smoothIn, 0.25, 0.8, 0.5, 1
+
+ # animation = windows, 1, 5, overshot, slide
+ # animation = windowsOut, 1, 4, smoothOut, slide
+ # animation = windowsMove, 1, 4, default
+ # animation = border, 1, 10, default
+ # animation = fade, 1, 10, smoothIn
+ # animation = fadeDim, 1, 10, smoothIn
+ # animation = workspaces, 1, 6, default
+ # }
+
+ bezier = smoothIn, 0.25, 1, 0.5, 1
+ bezier = wind, 0.05, 0.9, 0.1, 1.06
+ bezier = winIn, 0.1, 1.1, 0.1, 1.05
+ bezier = linear, 1, 1, 1, 1
+
+ animations {
+ enabled = yes
+
+ #buttery_smoooooooth... (slide)
+ # animation = windows, 1, 5, default, slide
+ # animation = windowsOut, 1, 8, smoothIn, slide
+ # animation = windowsMove, 1, 7, default
+ # animation = fade, 1, 5, smoothIn
+ # animation = fadeOut, 1, 4, smoothIn
+ # animation = fadeDim, 1, 3, smoothIn
+ # animation = workspaces, 1, 5, default, slidefadevert
+ # animation = specialWorkspace, 1, 5, default, fade
+
+ #buttery_smoooooooth... (Popin...)
+ # animation = windows, 1, 3, default, popin 70%
+ # animation = windowsOut, 1, 20, default, popin 85%
+ # animation = windowsMove, 1, 7, default
+ # animation = fade, 1, 6, smoothIn
+ # animation = fadeOut, 1, 3, smoothIn
+ # animation = fadeDim, 1, 3, smoothIn
+ # animation = workspaces, 1, 5, wind, slidefadevert 40%
+
+ # fasssstt popin
+ animation = windows, 1, 2, default, popin 80%
+ animation = windowsOut, 1, 5, default, popin 90%
+ animation = windowsMove, 1, 5, default
+ animation = layers, 1, 3, default, popin 90%
+ animation = fade, 1, 4, smoothIn
+ animation = fadeOut, 1, 2, smoothIn
+ animation = fadeDim, 1, 3, smoothIn
+ animation = workspaces, 1, 3, default, slidefadevert 15%
+ animation = specialWorkspace, 1, 3, default, slidefadevert 15%
+
+ # Random...
+ # animation = windows, 1, 5, wind, slide
+ # animation = windowsIn, 1, 4, winIn, slide
+ # animation = windowsOut, 1 , 7, smoothIn, slide
+ # animation = windowsMove, 1, 6, default
+ # animation = fade, 1, 5, smoothIn
+ # animation = fadeOut, 1, 3, smoothIn
+ # animation = fadeDim, 1, 3, smoothIn
+ # animation = workspaces, 1, 4, wind, slidefadevert 15%
+ # animation = specialWorkspace, 1, 3, default, slidefadevert 15%
+ }
+ '';
+ };
+}
diff --git a/desktop/wayland/hyprland/hyprland/binds.nix b/desktop/wayland/hyprland/hyprland/binds.nix
new file mode 100644
index 0000000..3e293d8
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/binds.nix
@@ -0,0 +1,208 @@
+_: {
+ wayland.windowManager.hyprland = {
+ settings = {
+ "$mod" = "SUPER";
+ "$mail" = "mailspring --password-store=\"gnome-libsecret\" --enable-features=UseOzonePlatform --ozone-platform=wayland";
+ "$script_path" = "$HOME/.config/hypr/hyprland/scripts";
+ "$term" = "kitty";
+
+ bind = (
+ builtins.concatLists
+ (builtins.genList
+ (
+ x:
+ let
+ ws =
+ let
+ c = (x + 1) / 10;
+ in
+ builtins.toString (x + 1 - (c * 10));
+ in
+ [
+ # Switch pseudo-tag (workspaces)
+ "$mod, ${ws}, exec, $script_path/switch_workspace ${toString (x + 1)}"
+ # "$mod, ${ws}, split-workspace, ${toString (x + 1)}"
+
+ # Move window to pseudo-tag (workspace)
+ "$mod SHIFT, ${ws}, exec, $script_path/move_window_to_workspace ${toString (x + 1)}"
+ # "$mod SHIFT, ${ws}, split-movetoworkspacesilent, ${toString (x + 1)}"
+ ]
+ )
+ 10)
+ ++
+ [
+ # Scratchpads
+ "$mod, apostrophe, exec, pypr toggle spcalc"
+ "$mod SHIFT, RETURN, exec, pypr toggle spterm"
+ "$mod SHIFT, c, exec, pypr toggle spgpt"
+ "$mod SHIFT, s, exec, pypr toggle spspotify"
+ "$mod SHIFT, apostrophe, exec, pgrep qalculate-gtk && hyprctl dispatch togglespecialworkspace calculator || qalculate-gtk &"
+
+ # Focus
+ "$mod, k, movefocus, u"
+ "$mod, j, movefocus, d"
+ "$mod, l, movefocus, r"
+ "$mod, h, movefocus, l"
+
+ # "$mod, j, layoutmsg, cyclenext"
+ # "$mod, j, layoutmsg, cycleprev"
+
+ "$mod, tab, hycov:toggleoverview"
+ "$mod SHIFT, tab, overview:toggle"
+
+ # Emoji picker
+ "$mod, GRAVE, exec, rofi -modi emoji -show emoji"
+
+ # Volume control
+ "$mod, MINUS, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
+ "$mod SHIFT, MINUS, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 15%-"
+ "$mod, EQUAL, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"
+ "$mod SHIFT, EQUAL, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 15%+"
+
+ # Session control
+ "$mod SHIFT, Q, exec, wlogout"
+ "$mod SHIFT, R, exec, hyprctl reload"
+
+ # Window control
+ "$mod, F, fullscreen"
+ # "$mod SHIFT, F, fullscreen, 2"
+ "$mod SHIFT, F, exec, hyprctl dispatch fakefullscreen && $script_path/fake_fullscreen_status"
+ "$mod, G, togglefloating"
+ "$mod, P, pseudo"
+ "$mod SHIFT, P, pin"
+ "$mod, T, togglesplit"
+ "$mod, U, focusurgentorlast"
+ "$mod, Q, killactive"
+ "$mod, S, exec, hyprctl keyword window:sticky 1"
+ "$mod, b, exec, pkill -SIGUSR1 waybar"
+ "$mod, SPACE, layoutmsg, swapwithmaster"
+ "$mod, V, exec, $script_path/toggle_layout"
+
+ # Application binds
+ "$mod, W, exec, $BROWSER"
+ "$mod SHIFT, W, exec, $term -e sudo nmtui"
+ "$mod, E, exec, $mail"
+ "$mod SHIFT, R, exec, $term -e htop"
+ "$mod, R, exec, rofi -show run"
+ "$mod SHIFT, D, exec, bitwarden-desktop"
+ "$mod, RETURN, exec, $term"
+ "$mod SHIFT, N, exec, $BROWSER https://sumi.news"
+ "$mod, M, exec, spotify"
+ "$mod SHIFT, M, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
+ "$mod ALT, A, exec, hyprpicker -a"
+
+ # Launchers
+ "$mod, D, exec, rofi -show combi"
+ "$mod, C, exec, cliphist list | rofi -dmenu | cliphist decode | wl-copy"
+
+ # Spotify control
+ "$mod, P, exec, spt pb --toggle"
+ "$mod SHIFT, P, exec, mpc pause; pauseallmpv"
+ "$mod, BRACKETLEFT, exec, spt pb --seek -10"
+ "$mod SHIFT, BRACKETLEFT, exec, spt pb --seek -60"
+ "$mod, BRACKETRIGHT, exec, spt pb --seek +10"
+ "$mod SHIFT, BRACKETRIGHT, exec, spt pb --seek +60"
+ "$mod, COMMA, exec, spt pb --pp"
+ "$mod, PERIOD, exec, spt pb --next"
+ "$mod SHIFT, PERIOD, exec, spt pb --previous"
+
+ # Gaps control
+ "$mod, a, exec, $script_path/toggle_gaps"
+ "$mod SHIFT, a, exec, bash -c 'hyprctl keyword general:gaps_in 5; hyprctl keyword general:gaps_out 10'"
+
+ # Increment gaps
+ "$mod, mouse_up, exec, hyprctl keyword general:gaps_out `expr $(hyprctl getoption general:gaps_out | awk '{ print $3 }') + 3`"
+ "$mod, mouse_up, exec, hyprctl keyword general:gaps_in `expr $(hyprctl getoption general:gaps_in | awk '{ print $3 }') + 2`"
+
+ # Decrement gaps
+ "$mod, mouse_down, exec, hyprctl keyword general:gaps_out `expr $(hyprctl getoption general:gaps_out | awk '{ print $3 }') - 3`"
+ "$mod, mouse_down, exec, hyprctl keyword general:gaps_in `expr $(hyprctl getoption general:gaps_in | awk '{ print $3 }') - 2`"
+
+ # Move focus to monitor
+ "$mod, LEFT, exec, $script_path/move_focus_to_monitor left"
+ "$mod, RIGHT, exec, $script_path/move_focus_to_monitor right"
+
+ # Move window to monitor
+ "$mod SHIFT, h, exec, $script_path/move_window_to_monitor left"
+ "$mod SHIFT, l, exec, $script_path/move_window_to_monitor right"
+
+ # Screenshot
+ ", Print, exec, screenshot --area"
+ "$mod SHIFT, Print, exec, screenshot --window"
+ "$mod CTRL, Print, exec, screenshot --monitor"
+ "$mod, Print, exec, screenshot --now"
+ "$mod SHIFT, v, exec, screenshot --now --clipboard && pypr toggle spgpt && ydotool key 42:1 1:1 1:0 42:0 29:1 47:1 29:0 47:0"
+
+ # Skipping media keys for now
+ ]
+ );
+
+ binde = (
+ [
+ # Increment gaps
+ "$mod, Z, exec, hyprctl --batch \"keyword general:gaps_out `expr $(hyprctl getoption general:gaps_out | awk '{ print $3 }') + 3`; keyword general:gaps_in `expr $(hyprctl getoption general:gaps_in | awk '{ print $3 }') + 2`\""
+
+ # Decrement gaps
+ "$mod, X, exec, hyprctl --batch \"keyword general:gaps_out `expr $(hyprctl getoption general:gaps_out | awk '{ print $3 }') - 3`; keyword general:gaps_in `expr $(hyprctl getoption general:gaps_in | awk '{ print $3 }') - 2`\""
+
+ # Resize active window
+ "$mod SHIFT, UP, resizeactive, 0 -50"
+ "$mod SHIFT, DOWN, resizeactive, 0 50"
+ "$mod SHIFT, RIGHT, resizeactive, 50 0"
+ "$mod SHIFT, LEFT, resizeactive, -50 0"
+
+ # Move active window
+ "$mod ALT, k, moveactive, 0 -100"
+ "$mod ALT, j, moveactive, 0 100"
+ "$mod ALT, l, moveactive, 100 0"
+ "$mod ALT, h, moveactive, -100 0"
+ ]
+ );
+
+ bindm = (
+ [
+ # Move window with mouse
+ "$mod, mouse:272, movewindow"
+ "$mod, mouse:273, resizewindow"
+ "$mod SHIFT, mouse:273, resizewindow 1"
+ ]
+ );
+ };
+
+ extraConfig = ''
+ # Media keys
+ bind = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
+ bind = , XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 0%- && wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
+ bind = , XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 0%+ && wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
+ bind = , XF86AudioPrev, exec, playerctl previous
+ bind = , XF86AudioNext, exec, playerctl next
+ bind = , XF86AudioPause, exec, playerctl play-pause
+ bind = , XF86AudioPlay, exec, playerctl play-pause
+ bind = , XF86AudioStop, exec, playerctl stop
+ bind = , XF86AudioRewind, exec, playerctl position -10
+ bind = , XF86AudioForward, exec, playerctl position +10
+ bind = , XF86AudioMedia, exec, spotify
+ bind = , XF86AudioMicMute, exec, pactl set-source-mute @DEFAULT_SOURCE@ toggle
+
+ # Other media keys
+ bind = , XF86Calculator, exec, $term -e bc -l
+ bind = , XF86Sleep, exec, sudo -A zzz
+ bind = , XF86WWW, exec, $BROWSER
+ bind = , XF86DOS, exec, $term
+ bind = , XF86ScreenSaver, exec, pidof hyprlock || hyprlock && hyprctl dispatch dpms off
+ bind = , XF86TaskPane, exec, $term -e htop
+ bind = , XF86Mail, exec, $mail
+ bind = , XF86MyComputer, exec, $term -e ranger
+ bind = , XF86Launch1, exec, hyprctl dispatch dpms off
+
+ # Touchpad control
+ bind = , XF86TouchpadToggle, exec, (synclient | grep 'TouchpadOff.*1' && synclient TouchpadOff=0) || synclient TouchpadOff=1
+ bind = , XF86TouchpadOff, exec, synclient TouchpadOff=1
+ bind = , XF86TouchpadOn, exec, synclient TouchpadOff=0
+
+ # Brightness control
+ bind = , XF86MonBrightnessUp, exec, xbacklight -inc 15
+ bind = , XF86MonBrightnessDown, exec, xbacklight -dec 15
+ '';
+ };
+}
diff --git a/desktop/wayland/hyprland/hyprland/decoration.nix b/desktop/wayland/hyprland/hyprland/decoration.nix
new file mode 100644
index 0000000..ffabda8
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/decoration.nix
@@ -0,0 +1,44 @@
+_: {
+ wayland.windowManager.hyprland.settings.decoration = {
+ rounding = 10;
+
+ drop_shadow = true;
+ shadow_ignore_window = true;
+ shadow_range = 8;
+ shadow_render_power = 10;
+ shadow_offset = "2 2";
+ "col.shadow" = "rgba(00000055)"; # 2A
+
+ blurls = [
+ "gtk-layer-shell"
+ "lockscreen"
+ ];
+
+ # active_opacity = 0.9
+ # inactive_opacity = 0.7
+ # fullscreen_opacity = 1.0
+ active_opacity = 1.0;
+ inactive_opacity = 0.95;
+
+ blur = {
+ enabled = true;
+ xray = true;
+ special = false;
+ # size = 1;
+ passes = 2;
+ ignore_opacity = true;
+ new_optimizations = true;
+ # vibrancy = 0.1696;
+ # noise = 0.01;
+ brightness = 1;
+ contrast = 1;
+
+ popups = true;
+ popups_ignorealpha = 0.6;
+ };
+
+ dim_special = 0.35;
+ dim_inactive = false;
+ dim_strength = 0.1;
+ };
+}
diff --git a/desktop/wayland/hyprland/hyprland/default.nix b/desktop/wayland/hyprland/hyprland/default.nix
new file mode 100644
index 0000000..9d0af4c
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/default.nix
@@ -0,0 +1,42 @@
+_: {
+ imports = [
+ ./animations.nix
+ ./binds.nix
+ ./decoration.nix
+ ./environment.nix
+ ./executions.nix
+ ./general.nix
+ ./plugins.nix
+ ./rules.nix
+ ./workspaces.nix
+ ];
+
+ xdg.configFile = (
+ let
+ scripts = [
+ "common.sh"
+ "fake_fullscreen_status"
+ "hycov_easymotion"
+ "initialise_gtk"
+ "initialise_waybar"
+ "initialise_xdg_portal"
+ "move_focus_to_monitor"
+ "move_window_to_monitor"
+ "move_window_to_workspace"
+ "switch_workspace"
+ "toggle_gaps"
+ "toggle_layout"
+ ];
+ in
+ (
+ builtins.listToAttrs (map
+ (script: {
+ name = "hypr/hyprland/scripts/${script}";
+ value = {
+ source = ./scripts/${script};
+ };
+ })
+ scripts)
+ )
+ );
+}
diff --git a/desktop/wayland/hyprland/hyprland/environment.nix b/desktop/wayland/hyprland/hyprland/environment.nix
new file mode 100644
index 0000000..d79c773
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/environment.nix
@@ -0,0 +1,78 @@
+_: {
+ wayland.windowManager.hyprland = {
+ extraConfig = ''
+ # Proton
+ env = PROTON_ENABLE_NGX_UPDATER, 1
+
+ # Cursor
+ env = XCURSOR_SIZE, 18
+ env = HYPRCURSOR_SIZE, 18
+
+ # Wayland & Xwayland
+ env = GDK_BACKEND, wayland,x11,*
+ env = SDL_VIDEODRIVER, wayland
+ env = CLUTTER_BACKEND, wayland
+ env = XWAYLAND_NO_GLAMOR, 1 # With this, you'll need to use gamescope for gaming.
+
+ # Nvidia
+ env = LIBVA_DRIVER_NAME, nvidia
+ env = GBM_BACKEND, nvidia-drm
+ env = __GLX_VENDOR_LIBRARY_NAME, nvidia
+ env = __VK_LAYER_NV_optimus, NVIDIA_only
+ env = __NV_PRIME_RENDER_OFFLOAD, 1
+ env = NVD_BACKEND, direct
+
+ # OpenGL
+ env = __GL_GSYNC_ALLOWED, 1
+ env = __GL_VRR_ALLOWED, 1
+ env = __GL_MaxFramesAllowed, 1
+
+ # Electron
+ # env = ELECTRON_OZONE_PLATFORM_HINT, auto
+ env = OZONE_PLATFORM, wayland
+
+ # Qt
+ env = QT_AUTO_SCREEN_SCALE_FACTOR, 1
+ env = QT_QPA_PLATFORM, wayland;xcb
+ env = QT_WAYLAND_DISABLE_WINDOWDECORATION, 1
+ env = QT_QPA_PLATFORMTHEME, qt5ct
+ # env = QT_STYLE_OVERRIDE, kvantum
+
+ # wlroots
+ env = WLR_NO_HARDWARE_CURSORS, 1
+ env = WLR_DRM_NO_ATOMIC, 1
+ env = WLR_USE_LIBINPUT, 1
+ env = WLR_RENDERER_ALLOW_SOFTWARE, 1
+ env = WLR_DRM_DEVICES=/dev/dri/card0
+ # env = WLR_EGL_NO_MODIFIERS, 1
+
+ # XDG
+ env = XDG_SESSION_TYPE, wayland
+ env = XDG_CURRENT_DESKTOP, Hyprland
+ env = XDG_SESSION_DESKTOP, Hyprland
+
+ # Mozilla
+ env = MOZ_ENABLE_WAYLAND, 1
+ env = MOZ_DISABLE_RDD_SANDBOX, 1
+
+ # Fcitx
+ # https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland
+ env = QT_IM_MODULE, fcitx
+ env = XMODIFIERS, @im=fcitx
+ # env = GTK_IM_MODULE, wayland # Crashes Electron apps in Xwayland
+ # env = GTK_IM_MODULE, fcitx # My Gtk apps no longer require this to work with fcitx5. Hmm.
+ env = SDL_IM_MODULE, fcitx
+ env = GLFW_IM_MODULE, ibus
+ env = INPUT_METHOD, fcitx
+
+ # GTK
+ env = GTK_USE_PORTAL, 1
+
+ # Java
+ env = _JAVA_AWT_WM_NONREPARENTING, 1
+
+ # SSH
+ # env = SSH_AUTH_SOCK, $XDG_RUNTIME_DIR/ssh-agent.socket
+ '';
+ };
+}
diff --git a/desktop/wayland/hyprland/hyprland/executions.nix b/desktop/wayland/hyprland/hyprland/executions.nix
new file mode 100644
index 0000000..c4e547f
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/executions.nix
@@ -0,0 +1,53 @@
+{ pkgs, ... }: {
+ wayland.windowManager.hyprland.settings = {
+ exec-once = ([
+ # One-shots
+ "hyprctl dispatch workspace 1"
+ "swww-daemon"
+ "gammastep -l 45.540750:-122.385330 >/dev/null"
+ "${pkgs.pyprland}/bin/pypr"
+ "hyprpm reload"
+ "swaddle"
+ "${pkgs.waybar}/bin/waybar"
+
+ # Fcitx5
+ "fcitx5-remote -r"
+ "fcitx5 -d --replace"
+ "fcitx5-remote -r"
+
+ # GTK
+ "$script_path/initialise_gtk"
+
+ # KWallet
+ # "pam_kwallet_init"
+ # "kwalletd6"
+
+ # GNOME/Keyring
+ "gnome-keyring-daemon --replace --components=pkcs11,secrets,ssh,gpg"
+ "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 || /usr/libexec/polkit-gnome-authentication-agent-1"
+
+ # XDG, XDPH, & Qt
+ "dbus-update-activation-environment --systemd --all"
+ "dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP"
+ "systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP"
+ "systemctl --user import-environment QT_QPA_PLATFORMTHEME"
+ "$script_path/initialise_xdg_portal"
+
+ # Clipboard
+ "wl-paste --type text --watch cliphist store"
+ "wl-paste --type image --watch cliphist store"
+
+ # JamesDSP & Solaar
+ "jamesdsp -t"
+ # "solaar -w hide"
+
+ # SSH
+ # "killall -q ssh-agent"
+ # "eval $(ssh-agent -c)"
+ # "set -Ux SSH_AUTH_SOCK $SSH_AUTH_SOCK"
+ # "set -Ux SSH_AGENT_PID $SSH_AGENT_PID"
+ # "set -Ux SSH_AUTH_SOCK $SSH_AUTH_SOCK"
+ # "export SSH_AUTH_SOCK=\"$XDG_RUNTIME_DIR/ssh-agent.socket\""
+ ]);
+ };
+}
diff --git a/desktop/wayland/hyprland/hyprland/general.nix b/desktop/wayland/hyprland/hyprland/general.nix
new file mode 100644
index 0000000..270fa1c
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/general.nix
@@ -0,0 +1,137 @@
+_: {
+ wayland.windowManager.hyprland = {
+ settings = {
+ monitor = [
+ "HDMI-A-2, [email protected], 0x0, 1"
+ "DP-2, [email protected], 1920x0, 1"
+ "DP-1, [email protected], 3840x0, 1"
+ ];
+
+ source = "/home/fuwn/.cache/wal/colors-hyprland";
+
+ general = {
+ gaps_in = 5;
+ gaps_out = 10;
+ border_size = 0;
+
+ layout = "master";
+
+ allow_tearing = true;
+
+ resize_on_border = true;
+
+ no_focus_fallback = true;
+ };
+
+ input = {
+ kb_layout = "us";
+ # kb_variant =
+ # kb_model =
+ # kb_options =
+ # kb_rules =
+
+ # repeat_rate = 50;
+ # repeat_delay = 200;
+ repeat_rate = 35;
+ repeat_delay = 250;
+
+ follow_mouse = 1;
+
+ special_fallthrough = true;
+
+ touchpad = {
+ natural_scroll = true;
+ disable_while_typing = true;
+ clickfinger_behavior = true;
+ scroll_factor = 0.15;
+ tap-to-click = true;
+ middle_button_emulation = true;
+ };
+
+ sensitivity = -0.5;
+ accel_profile = "flat";
+ scroll_factor = 1.0;
+ # natural_scroll = false;
+ };
+
+ binds = {
+ allow_workspace_cycles = true;
+ scroll_event_delay = 0;
+ workspace_back_and_forth = true;
+ };
+
+ dwindle = {
+ pseudotile = true;
+
+ preserve_split = true;
+ force_split = 2;
+ smart_split = false;
+ smart_resizing = false;
+
+ no_gaps_when_only = 0;
+
+ special_scale_factor = 0.98;
+ };
+
+ master = {
+ allow_small_split = true;
+ new_is_master = false;
+ mfact = 0.55;
+ # no_gaps_when_only = yes;
+ orientation = "left";
+ inherit_fullscreen = false;
+ };
+
+ gestures = {
+ workspace_swipe = true;
+ workspace_swipe_distance = 700;
+ workspace_swipe_fingers = 4;
+ workspace_swipe_cancel_ratio = 0.2;
+ workspace_swipe_min_speed_to_force = 5;
+ workspace_swipe_direction_lock = true;
+ workspace_swipe_direction_lock_threshold = 10;
+ workspace_swipe_create_new = true;
+ };
+
+ misc = {
+ vrr = false;
+ vfr = false;
+
+ enable_swallow = true;
+ swallow_regex = "^(kitty|footclient|foot|Alacritty|wezterm)$";
+
+ disable_hyprland_logo = true;
+ disable_splash_rendering = true;
+ force_default_wallpaper = 0;
+
+ mouse_move_enables_dpms = true;
+ # key_press_enables_dpms = true;
+
+ # focus_on_activate = true;
+ animate_manual_resizes = true;
+ # animate_mouse_windowdragging = false;
+ mouse_move_focuses_monitor = true;
+
+ # new_window_takes_over_fullscreen = 2;
+ allow_session_lock_restore = true;
+
+ initial_workspace_tracking = false;
+ };
+
+ cursor = {
+ hide_on_key_press = true;
+ enable_hyprcursor = true;
+ };
+
+ xwayland = {
+ force_zero_scaling = true;
+ };
+
+ debug = {
+ watchdog_timeout = 0;
+ disable_logs = false;
+ damage_blink = false;
+ };
+ };
+ };
+}
diff --git a/desktop/wayland/hyprland/hyprland/plugins.nix b/desktop/wayland/hyprland/hyprland/plugins.nix
new file mode 100644
index 0000000..61d73e3
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/plugins.nix
@@ -0,0 +1,69 @@
+_: {
+ wayland.windowManager.hyprland.settings.plugin = {
+ # split-monitor-workspaces = {
+ # count = 10;
+ # keep_focused = 0;
+ # enable_notifications = 0;
+ # };
+
+ hyprtrails = {
+ color = "rgba(cfddf619)";
+ };
+
+ hyprfocus = {
+ enabled = true;
+ animate_floating = true;
+ animate_workspacechange = true;
+ focus_animation = "flash";
+
+ bezier = [
+ "bezIn, 0.5, 0.0, 1.0, 0.5"
+ "bezOut, 0.0, 0.5, 0.5, 1.0"
+ "overshot, 0.05, 0.9, 0.1, 1.05"
+ "smoothOut, 0.36, 0, 0.66, -0.56"
+ "smoothIn, 0.25, 1, 0.5, 1"
+ "realsmooth, 0.28, 0.29, .69, 1.08"
+ ];
+
+ flash = {
+ flash_opacity = 0.85;
+ in_bezier = "realsmooth";
+ in_speed = 0.5;
+ out_bezier = "realsmooth";
+ out_speed = 3;
+ };
+
+ shrink = {
+ shrink_percentage = 0.99;
+ in_bezier = "realsmooth";
+ in_speed = 1;
+ out_bezier = "realsmooth";
+ out_speed = 2;
+ };
+ };
+
+ hycov = {
+ overview_gappo = 10; # gaps width from screen edge
+ overview_gappi = 10; # gaps width from clients
+ enable_hotarea = 0; # enable mouse cursor hotarea, when cursor enter hotarea, it will toggle overview
+ enable_click_action = 1; # enable mouse left button jump and right button kill in overview mode
+ hotarea_monitor = "all"; # monitor name which hotarea is in, default is all
+ hotarea_pos = 1; # position of hotarea (1: bottom left, 2: bottom right, 3: top left, 4: top right)
+ hotarea_size = 10; # hotarea size, 10x10
+ swipe_fingers = 4; # finger number of gesture,move any directory
+ move_focus_distance = 100; # distance for movefocus,only can use 3 finger to move
+ enable_gesture = 0; # enable gesture
+ auto_exit = 1; # enable auto exit when no client in overview
+ auto_fullscreen = 0; # auto make active window maximize after exit overview
+ only_active_workspace = 0; # only overview the active workspace
+ only_active_monitor = 0; # only overview the active monitor
+ enable_alt_release_exit = 1; # alt swith mode arg,see readme for detail
+ alt_replace_key = "Super_L"; # alt swith mode arg,see readme for detail
+ alt_toggle_auto_next = 0; # auto focus next window when toggle overview in alt swith mode
+ click_in_cursor = 1; # when click to jump,the target windwo is find by cursor, not the current foucus window.
+ height_of_titlebar = 0; # height deviation of title bar height
+ show_special = 0; # show windwos in special workspace in overview.
+ raise_float_to_top = 1; # raise the window that is floating before to top after leave overview mode
+ };
+ };
+}
diff --git a/desktop/wayland/hyprland/hyprland/rules.nix b/desktop/wayland/hyprland/hyprland/rules.nix
new file mode 100644
index 0000000..f9f671e
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/rules.nix
@@ -0,0 +1,94 @@
+_: {
+ wayland.windowManager.hyprland = {
+ settings = {
+ # Layer Rules
+ layerrule = [
+ "animation slide, notifications"
+ "noanim, selection"
+ "noanim, picker"
+ ];
+
+ windowrulev2 = [
+ # Dialog Rules
+ "float, class:file_progress"
+ "float, class:confirm"
+ "float, class:dialog"
+ "float, class:download"
+ "float, class:notification"
+ "float, class:error"
+ "float, class:splash"
+ "float, class:confirmreset"
+ "float, title:Open File"
+ "float, title:branchdialog"
+ "float, title:^(Open File)(.*)$"
+ "float, title:^(Select a File)(.*)$"
+ "float, title:^(Choose wallpaper)(.*)$"
+ "float, title:^(Open Folder)(.*)$"
+ "float, title:^(Save As)(.*)$"
+ "float, title:^(Library)(.*)$"
+ "float, initialClass:^(xdg-desktop-portal-.*)$"
+
+ # Control Application Rules
+ "float, class:^(Network)$"
+ "float, class:^(pavucontrol)$"
+ "float, class:^(Color Picker)$"
+ "float, class:^(File Picker)$"
+ "float, class:^(nm-connection-editor)$"
+ "float, class:pavucontrol-qt"
+ "float, class:pavucontrol"
+ "float, title:^(Media viewer)$"
+ "float, title:^(Volume Control)$"
+ "float, title:^(Picture-in-Picture)$"
+ "float, class:^(blueberry.py)$"
+ "float, class:Lxappearance"
+ "pseudo, class:fcitx"
+ "size 50% 50%, title:^(Volume Control)$"
+
+ # Launcher & Bar Rules
+ "float, class:^(eww)$"
+ "float, class:^(Rofi)$"
+ "float, title:wlogout"
+ "fullscreen, class:wlogout"
+ "fullscreen, title:wlogout"
+
+ # Application Rules
+ "float, class:^(transmission-gtk)$"
+ "float, class:viewnior"
+ "float, class:feh"
+ "float, class:^(steam)$"
+ "float, class:file-roller"
+ "center, class:feh"
+ "workspace 9, initialTitle:^(Spotify Premium)$"
+ "tile, initialTitle:^(Photopea)$"
+ "tile, initialTitle:^(WorldsPlayer by Worlds Inc)$"
+ # "size 75% 75%, class:feh"
+
+ # Scratchpad Rules
+ "float, class:^(spcalc)$"
+ "float, class:^(spterm)$"
+ "float, class:^(spgpt)$"
+ "float, class:^(qalculate-gtk)$"
+ "center, class:^(spcalc)$"
+ "workspace special:calculator, class:(qalculate-gtk)"
+ "size 50% 50%, class:(qalculate-gtk)"
+
+ # XWayland Video Bridge
+ "noblur, class:^(xwaylandvideobridge)$"
+ "noanim, class:^(xwaylandvideobridge)$"
+ "noinitialfocus, class:^(xwaylandvideobridge)$"
+ "opacity 0.0 override, class:^(xwaylandvideobridge)$"
+ "maxsize 1 1, class:^(xwaylandvideobridge)$"
+
+ # Tearing
+ "immediate, class:.*\.exe"
+ "immediate, class:(steam_app)"
+
+ # Idle Inhibit
+ # "idleinhibit fullscreen, class:^(*)$"
+ # "idleinhibit fullscreen, title:^(*)$"
+ "idleinhibit fullscreen, fullscreen:1"
+ "idleinhibit focus, class:mpv"
+ ];
+ };
+ };
+}
diff --git a/desktop/wayland/hyprland/hyprland/scripts/common.sh b/desktop/wayland/hyprland/hyprland/scripts/common.sh
new file mode 100644
index 0000000..25be5b6
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/common.sh
@@ -0,0 +1,146 @@
+#!/usr/bin/env bash
+
+# . "$(dirname "$(readlink -f "${BASH_SOURCE[0]}" 2>/dev/null || echo "${0}")" || true)/common.sh"
+# or
+# . "${HOME}/.config/hypr/hyprland/scripts/common.sh"
+
+get_hyprctl_monitors() {
+ hyprctl monitors -j || true
+}
+
+get_hyprctl_workspaces() {
+ hyprctl workspaces -j || true
+}
+
+get_focused_monitor() {
+ (get_hyprctl_monitors || true) |
+ jq -r '.[] | select(.focused) | .name'
+}
+
+get_active_monitor() {
+ get_focused_monitor
+}
+
+get_active_workspaces() {
+ local monitor=$1
+
+ (get_hyprctl_workspaces || true) |
+ (jq -r ".[] | select(.monitor == \"${monitor}\") | .id" || true) |
+ grep -v '-'
+}
+
+get_active_workspace() {
+ local monitor=$1
+
+ (get_hyprctl_monitors || true) |
+ jq -r ".[] | select(.name == \"${monitor}\") | .activeWorkspace.id"
+}
+
+get_current_workspace() {
+ (hyprctl activeworkspace -j || true) |
+ jq -r ".id"
+}
+
+get_empty_workspace() {
+ local monitor=$1
+
+ (hyprctl workspaces -j || true) |
+ (jq -r ".[] | select(.monitor == \"${monitor}\" and .windows == 0) | .id" || true) |
+ (grep -v '-' || true) |
+ head -n 1
+}
+
+get_workspace_client_count() {
+ local workspace=$1
+
+ (hyprctl workspaces -j || true) | jq -r ".[] | select(.id == ${workspace}) | .windows"
+}
+
+get_relative_target_workspace() {
+ target_workspace=$1
+ workspace=0
+
+ case "$(get_focused_monitor)" in
+ "HDMI-A-2")
+ workspace=$((target_workspace + 10))
+ ;;
+ "DP-2")
+ workspace=${target_workspace}
+ ;;
+ "DP-1")
+ workspace=$((target_workspace + 20))
+ ;;
+ *)
+ exit 1
+ ;;
+ esac
+
+ echo "${workspace}"
+}
+
+is_monitor_fullscreen() {
+ monitor=$1
+
+ (hyprctl workspaces -j || true) |
+ jq -r ".[] | select(.monitor == \"${monitor}\") | select(.id == $(get_active_workspace "${monitor}" || true)) | .hasfullscreen"
+}
+
+get_relative_target_monitor() {
+ direction=$1
+ ignore_fullscreen=${2:-0}
+
+ case $(get_focused_monitor) in
+ "HDMI-A-2")
+ if [[ "${direction}" == "right" ]]; then
+ target_monitor="DP-2"
+ else
+ target_monitor="DP-1"
+ fi
+ ;;
+ "DP-2")
+ if [[ "${direction}" == "right" ]]; then
+ target_monitor="DP-1"
+ else
+ target_monitor="HDMI-A-2"
+ fi
+ ;;
+ "DP-1")
+ if [[ "${direction}" == "left" ]]; then
+ target_monitor="DP-2"
+ else
+ target_monitor="HDMI-A-2"
+ fi
+ ;;
+ *)
+ exit 1
+ ;;
+ esac
+
+ if [[ "$(is_monitor_fullscreen "${target_monitor}")" == "true" && "${ignore_fullscreen}" = 0 ]]; then
+ case $target_monitor in
+ "HDMI-A-2")
+ if [[ "$direction" == "right" ]]; then
+ target_monitor="DP-2"
+ else
+ target_monitor="DP-1"
+ fi
+ ;;
+ "DP-2")
+ if [[ "$direction" == "right" ]]; then
+ target_monitor="DP-1"
+ else
+ target_monitor="HDMI-A-2"
+ fi
+ ;;
+ "DP-1")
+ if [[ "$direction" == "left" ]]; then
+ target_monitor="DP-2"
+ else
+ target_monitor="HDMI-A-2"
+ fi
+ ;;
+ esac
+ fi
+
+ echo "${target_monitor}"
+}
diff --git a/desktop/wayland/hyprland/hyprland/scripts/fake_fullscreen_status b/desktop/wayland/hyprland/hyprland/scripts/fake_fullscreen_status
new file mode 100755
index 0000000..e198758
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/fake_fullscreen_status
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+. "${HOME}/.config/hypr/hyprland/scripts/common.sh"
+
+previous_id=$(cat /tmp/fake_fullscreen_notify_id 2>/dev/null)
+previous_id_flag=""
+
+if [[ -n "${previous_id}" ]]; then
+ previous_id_flag="-r ${previous_id}"
+fi
+
+id=$(notify-send -p ${previous_id_flag} "$(hyprctl activewindow -j | jq -r '.title')
+
+Fake fullscreen is $([[ "$(hyprctl activewindow -j | jq -r '.fakeFullscreen')" == "true" ]] &&
+ echo "enabled" ||
+ echo "disabled").")
+
+echo "${id}" >/tmp/fake_fullscreen_notify_id
diff --git a/desktop/wayland/hyprland/hyprland/scripts/hycov_easymotion b/desktop/wayland/hyprland/hyprland/scripts/hycov_easymotion
new file mode 100755
index 0000000..ab7c3bb
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/hycov_easymotion
@@ -0,0 +1,10 @@
+#!/usr/bin/env dash
+
+workspace_name=$(hyprctl -j activeworkspace | jq -r '.name')
+
+if [ "${workspace_name}" = "OVERVIEW" ]; then
+ hyprctl dispatch hycov:leaveoverview
+else
+ hyprctl dispatch hycov:enteroverview
+ hyprctl dispatch 'easymotion action:hyprctl --batch "dispatch focuswindow address:{} ; dispatch hycov:leaveoverview"'
+fi
diff --git a/desktop/wayland/hyprland/hyprland/scripts/initialise_gtk b/desktop/wayland/hyprland/hyprland/scripts/initialise_gtk
new file mode 100755
index 0000000..9035cbb
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/initialise_gtk
@@ -0,0 +1,17 @@
+#!/usr/bin/env dash
+
+THEME='WhiteSur-Dark'
+ICONS='WhiteSur-dark'
+FONT='SF Pro Text'
+CURSOR='WhiteSur-cursors'
+
+SCHEMA='gsettings set org.gnome.desktop.interface'
+
+apply_themes() {
+ ${SCHEMA} gtk-theme "$THEME"
+ ${SCHEMA} icon-theme "$ICONS"
+ ${SCHEMA} cursor-theme "$CURSOR"
+ ${SCHEMA} font-name "$FONT"
+}
+
+apply_themes
diff --git a/desktop/wayland/hyprland/hyprland/scripts/initialise_waybar b/desktop/wayland/hyprland/hyprland/scripts/initialise_waybar
new file mode 100755
index 0000000..ff4a25f
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/initialise_waybar
@@ -0,0 +1,22 @@
+#!/usr/bin/env dash
+
+CONFIG_FILES="${HOME}/.config/waybar/config.json ${HOME}/.config/waybar/default-modules.json ${HOME}/.config/waybar/style.css ${HOME}/.cache/wal/colors-waybar.css"
+
+trap "pkill -x waybar" EXIT
+
+# Initial copy of colors
+\cp -r ~/.cache/wal/colors-waybar.css ~/.config/waybar/
+
+while true; do
+ # If Waybar is not running, start it
+ if ! pgrep -x "waybar" >/dev/null; then
+ waybar -c ~/.config/waybar/config.json -s ~/.config/waybar/style.css &
+ fi
+
+ # Wait for changes in the configuration files
+ inotifywait -e create,modify ${CONFIG_FILES}
+
+ # Kill Waybar gracefully and wait until it's completely terminated
+ pkill -x waybar
+ while pgrep -x waybar >/dev/null; do sleep 0.5; done
+done
diff --git a/desktop/wayland/hyprland/hyprland/scripts/initialise_xdg_portal b/desktop/wayland/hyprland/hyprland/scripts/initialise_xdg_portal
new file mode 100755
index 0000000..10470eb
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/initialise_xdg_portal
@@ -0,0 +1,13 @@
+#!/usr/bin/env dash
+
+sleep 1
+
+killall -e xdg-desktop-portal-hyprland
+killall -e xdg-desktop-portal-wlr
+killall xdg-desktop-portal
+
+/usr/lib/xdg-desktop-portal-hyprland &
+
+sleep 2
+
+/usr/lib/xdg-desktop-portal &
diff --git a/desktop/wayland/hyprland/hyprland/scripts/move_focus_to_monitor b/desktop/wayland/hyprland/hyprland/scripts/move_focus_to_monitor
new file mode 100755
index 0000000..27562a9
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/move_focus_to_monitor
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+. "${HOME}/.config/hypr/hyprland/scripts/common.sh"
+
+target_monitor=$(get_relative_target_monitor "$1" 1)
+
+if [[ -n "${target_monitor}" ]]; then
+ hyprctl dispatch focusmonitor "${target_monitor}"
+fi
diff --git a/desktop/wayland/hyprland/hyprland/scripts/move_window_to_monitor b/desktop/wayland/hyprland/hyprland/scripts/move_window_to_monitor
new file mode 100755
index 0000000..76fd463
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/move_window_to_monitor
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+. "${HOME}/.config/hypr/hyprland/scripts/common.sh"
+
+target_monitor=$(get_relative_target_monitor "$1")
+target_workspace=$(get_active_workspace "${target_monitor}")
+
+# # Get the empty workspace on the target monitor, if available
+# target_workspace=$(get_empty_workspace $target_monitor)
+
+# # If no empty workspace is found, fall back to the active workspace
+# if [[ -z "$target_workspace" ]]; then
+# target_workspace=$(get_active_workspaces $target_monitor | head -n 1)
+# fi
+
+if [[ -n "${target_workspace}" ]]; then
+ hyprctl dispatch movetoworkspace "${target_workspace}"
+fi
diff --git a/desktop/wayland/hyprland/hyprland/scripts/move_window_to_workspace b/desktop/wayland/hyprland/hyprland/scripts/move_window_to_workspace
new file mode 100755
index 0000000..4256a9f
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/move_window_to_workspace
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+. "${HOME}/.config/hypr/hyprland/scripts/common.sh"
+
+initial_active_workspace="$(get_current_workspace)"
+target_workspace="$(get_relative_target_workspace "${1}")"
+
+hyprctl dispatch movetoworkspace "${target_workspace}"
+
+if [[ $(get_workspace_client_count "${target_workspace}") -gt 2 ]]; then
+ hyprctl dispatch workspace "${initial_active_workspace}"
+fi
diff --git a/desktop/wayland/hyprland/hyprland/scripts/source/screenshot.ab b/desktop/wayland/hyprland/hyprland/scripts/source/screenshot.ab
new file mode 100644
index 0000000..6bc510d
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/source/screenshot.ab
@@ -0,0 +1,158 @@
+let current_date_time = unsafe $date +%Y-%m-%d-%H-%M-%S$
+let output_directory = "{unsafe $xdg-user-dir PICTURES$}/Screenshots"
+let output_file = "Screenshot_{current_date_time}_{unsafe $echo \$RANDOM$}.png"
+
+fun notify_command(message: Text): Null {
+ unsafe $notify-send -h string:x-canonical-private-synchronous:shot-notify -u low "{message}"$
+}
+
+fun notify(clipboard: Bool, type: Text): Null {
+ notify_command("Screenshot copied to clipboard. ({type})")
+
+ if not clipboard {
+ if unsafe $test -f "{output_directory}/{output_file}" &&
+ echo 'true' ||
+ echo 'false'$ == "true"
+ {
+ // unsafe $feh "{output_directory}/{output_file}"$
+
+ notify_command("Screenshot saved. ({type})")
+ } else {
+ notify_command("Screenshot deleted.")
+ }
+ }
+}
+
+fun get_hyprctl_monitors(): Text {
+ return $hyprctl monitors -j || true$ failed {
+ notify_command("Failed to get monitors.")
+
+ fail status
+ }
+}
+
+fun get_focused_monitor(): Text {
+ let monitors = get_hyprctl_monitors() failed {
+ notify_command("Failed to get monitors.")
+
+ fail status
+ }
+
+ return $echo {monitors} | jq -r '.[] | select(.focused) | .name'$ failed {
+ notify_command("Failed to get focused monitor.")
+
+ fail status
+ }
+}
+
+fun screenshot_now(clipboard: Bool): Null {
+ if clipboard {
+ unsafe $(grim - || true) | wl-copy$
+ } else {
+ unsafe $cd "{output_directory}" &&
+ grim - |
+ tee "{output_file}" |
+ wl-copy$
+ }
+
+ notify(clipboard, "now")
+}
+
+fun screenshot_window(clipboard: Bool): Null {
+ let width_position = unsafe $hyprctl activewindow |
+ grep 'at:' |
+ cut -d':' -f2 |
+ tr -d ' ' |
+ tail -n1$
+ let width_size = unsafe $hyprctl activewindow |
+ grep 'size:' |
+ cut -d':' -f2 |
+ tr -d ' ' |
+ tail -n1 |
+ sed s/,/x/g$
+
+ if clipboard {
+ unsafe $grim -g "{width_position} {width_size}" - | wl-copy$
+ } else {
+ unsafe $cd "{output_directory}" &&
+ grim -g "{width_position} {width_size}" - |
+ tee "{output_file}" |
+ wl-copy$
+ }
+
+ notify(clipboard, "window")
+}
+
+fun screenshot_monitor(clipboard: Bool): Null {
+ if clipboard {
+ unsafe $grim -o "{get_focused_monitor()}" - | wl-copy$
+ } else {
+ unsafe $cd "{output_directory}" &&
+ grim -o "{get_focused_monitor()}" - |
+ tee "{output_file}" |
+ wl-copy$
+ }
+
+ notify(clipboard, "monitor")
+}
+
+fun screenshot_area(clipboard: Bool): Null {
+ // slurp -b 1B1F28CC -c E06B74ff -s C778DD0D -w 2
+
+ if clipboard {
+ unsafe $grim -g "{unsafe $slurp$}" - | wl-copy$
+ } else {
+ unsafe $cd "{output_directory}" &&
+ grim -g "{unsafe $slurp$}" - |
+ tee "{output_file}" |
+ wl-copy$
+ }
+
+ notify(clipboard, "area")
+}
+
+fun screenshot(mode: Text, clipboard: Bool): Null {
+ if {
+ mode == "now" {
+ screenshot_now(clipboard)
+ }
+ mode == "window" {
+ screenshot_window(clipboard)
+ }
+ mode == "monitor" {
+ screenshot_monitor(clipboard)
+ }
+ mode == "area" {
+ screenshot_area(clipboard)
+ }
+ else {
+ echo "usage: {unsafe $echo "\${0}"$} [flags]\n"
+ echo "flags:"
+ echo " --now"
+ echo " --window"
+ echo " --area"
+ echo " --monitor"
+ echo " --clipboard"
+ echo " --help"
+ echo ""
+ }
+ }
+}
+
+main {
+ if unsafe $test -d "{output_directory}" &&
+ echo 'true' ||
+ echo 'false'$ == "false"
+ {
+ $mkdir -p "{output_directory}"$ failed {
+ notify_command("Failed to create output directory.")
+
+ fail status
+ }
+ }
+
+ screenshot(
+ unsafe $echo "\${1}" | sed -E s/--//g$,
+ unsafe $echo "\${2}"$ == "--clipboard"
+ )
+}
diff --git a/desktop/wayland/hyprland/hyprland/scripts/switch_workspace b/desktop/wayland/hyprland/hyprland/scripts/switch_workspace
new file mode 100755
index 0000000..fc8900c
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/switch_workspace
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+. "${HOME}/.config/hypr/hyprland/scripts/common.sh"
+
+hyprctl dispatch workspace "$(get_relative_target_workspace "${1}")"
diff --git a/desktop/wayland/hyprland/hyprland/scripts/toggle_gaps b/desktop/wayland/hyprland/hyprland/scripts/toggle_gaps
new file mode 100755
index 0000000..d593ab2
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/toggle_gaps
@@ -0,0 +1,13 @@
+#!/usr/bin/env dash
+
+inner_gap_size=5
+outer_gap_size=10
+
+if [ "$(hyprctl getoption general:gaps_in | awk '{print $3}' || true)" -eq 0 ] &&
+ [ "$(hyprctl getoption general:gaps_out | awk '{print $3}' || true)" -eq 0 ]; then
+ hyprctl keyword general:gaps_in "${inner_gap_size}"
+ hyprctl keyword general:gaps_out "${outer_gap_size}"
+else
+ hyprctl keyword general:gaps_in 0
+ hyprctl keyword general:gaps_out 0
+fi
diff --git a/desktop/wayland/hyprland/hyprland/scripts/toggle_layout b/desktop/wayland/hyprland/hyprland/scripts/toggle_layout
new file mode 100755
index 0000000..1ef8774
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/scripts/toggle_layout
@@ -0,0 +1,22 @@
+#!/usr/bin/env dash
+
+layout=$(hyprctl -j getoption general:layout)
+new_layout=""
+
+case "$(echo "${layout}" | jq -r .str)" in
+dwindle)
+ hyprctl keyword general:layout master
+
+ new_layout="master"
+
+ ;;
+master)
+ hyprctl keyword general:layout dwindle
+
+ new_layout="dwindle"
+
+ ;;
+*) ;;
+esac
+
+notify-send "You've changed the layout to ${new_layout}."
diff --git a/desktop/wayland/hyprland/hyprland/workspaces.nix b/desktop/wayland/hyprland/hyprland/workspaces.nix
new file mode 100644
index 0000000..a8d30df
--- /dev/null
+++ b/desktop/wayland/hyprland/hyprland/workspaces.nix
@@ -0,0 +1,32 @@
+_: {
+ wayland.windowManager.hyprland.settings.workspace = (
+ let
+ generateWorkspaces = monitor: workspaces: offset:
+ builtins.genList
+ (x:
+ let
+ ws =
+ let
+ c = (x + 1) / workspaces;
+ in
+ builtins.toString (x + 1 - (c * workspaces));
+ in
+ [ "${toString (x + offset + 1)}, monitor:${monitor}" ]
+ )
+ workspaces;
+ generateWorkspacesAll = monitors: tags:
+ builtins.concatLists (builtins.map
+ (monitor: generateWorkspaces
+ (builtins.elemAt monitors monitor)
+ tags
+ (builtins.elemAt
+ (builtins.genList
+ (index: index * tags)
+ (builtins.length monitors))
+ monitor))
+ (builtins.genList (index: index) (builtins.length monitors))
+ );
+ in
+ builtins.concatLists (generateWorkspacesAll [ "DP-2" "HDMI-A-2" "DP-1" ] 10)
+ );
+}
diff --git a/desktop/wayland/hyprland/pyprland/default.nix b/desktop/wayland/hyprland/pyprland/default.nix
new file mode 100644
index 0000000..2dc04c7
--- /dev/null
+++ b/desktop/wayland/hyprland/pyprland/default.nix
@@ -0,0 +1,38 @@
+{ pkgs, ... }: {
+ home.packages = with pkgs; [ pyprland ];
+ xdg.configFile."hypr/pyprland.toml".text = ''
+ [pyprland]
+ plugins = ["scratchpads"]
+
+ [scratchpads.spterm]
+ animation = "fromTop"
+ command = "kitty --class spterm"
+ class = "spterm"
+ size = "50% 65%"
+ margin = "17%" # (50 / 3)
+
+ [scratchpads.spcalc]
+ animation = "fromTop"
+ command = "kitty --class spcalc -e bc -lq"
+ class = "spcalc"
+ size = "50% 50%"
+ margin = "25%" # (50 / 2)
+
+ [scratchpads.spgpt]
+ animation = "fromTop"
+ command = "thorium-browser --user-data-dir=/home/fuwn/.local/share/spgpt --app='https://chatgpt.com/'"
+ class = "thorium-chatgpt.com__-Default"
+ size = "65% 75%"
+ # process_tracking = false
+ match_by = "class"
+ margin = "13%" # (50 / 4)
+
+ [scratchpads.spspotify]
+ animation = "fromTop"
+ command = "LD_PRELOAD=/usr/lib/spotifywm.so /opt/spotify/spotify"
+ class = "Spotify"
+ size = "65% 90%"
+ unfocus = "hide"
+ lazy = true
+ '';
+}
diff --git a/desktop/wayland/waybar/default.nix b/desktop/wayland/waybar/default.nix
new file mode 100644
index 0000000..e823913
--- /dev/null
+++ b/desktop/wayland/waybar/default.nix
@@ -0,0 +1,95 @@
+{ pkgs, ... }: {
+ programs.waybar = {
+ enable = true;
+ style = ./waybar/style.css;
+ settings = (
+ let
+ defaultModules =
+ (import ./waybar/default-modules.nix {
+ inherit pkgs;
+ }).mainBar;
+ hyprland-workspaces-base = {
+ disable-scroll = true;
+ disable-markup = false;
+ all-outputs = false;
+ format = "{icon}";
+ };
+ in
+ [
+ (defaultModules // {
+ output = "HDMI-A-2";
+ "hyprland/workspaces" = hyprland-workspaces-base // {
+ format-icons = {
+ "11" = "一";
+ "12" = "二";
+ "13" = "三";
+ "14" = "四";
+ "15" = "五";
+ "16" = "六";
+ "17" = "七";
+ "18" = "八";
+ "19" = "九";
+ "20" = "十";
+ };
+ };
+ })
+ (defaultModules // {
+ output = "DP-2";
+ "hyprland/workspaces" = hyprland-workspaces-base // {
+ format-icons = {
+ "1" = "一";
+ "2" = "二";
+ "3" = "三";
+ "4" = "四";
+ "5" = "五";
+ "6" = "六";
+ "7" = "七";
+ "8" = "八";
+ "9" = "九";
+ "10" = "十";
+ };
+ };
+ })
+ (defaultModules // {
+ output = "DP-1";
+ "hyprland/workspaces" = hyprland-workspaces-base // {
+ format-icons = {
+ "21" = "一";
+ "22" = "二";
+ "23" = "三";
+ "24" = "四";
+ "25" = "五";
+ "26" = "六";
+ "27" = "七";
+ "28" = "八";
+ "29" = "九";
+ "30" = "十";
+ };
+ };
+ })
+ ]
+ );
+ };
+ xdg.configFile = (
+ let
+ scripts = [
+ "brightness.sh"
+ "mediaplayer.py"
+ "spotify.sh"
+ "theme.sh"
+ "volume.sh"
+ "wallpaper.sh"
+ ];
+ in
+ (
+ builtins.listToAttrs (map
+ (script: {
+ name = "waybar/scripts/${script}";
+ value = {
+ source = ./waybar/scripts/${script};
+ };
+ })
+ scripts)
+ )
+ );
+}
diff --git a/desktop/wayland/waybar/waybar/default-modules.nix b/desktop/wayland/waybar/waybar/default-modules.nix
new file mode 100644
index 0000000..9b9cf07
--- /dev/null
+++ b/desktop/wayland/waybar/waybar/default-modules.nix
@@ -0,0 +1,324 @@
+{ pkgs, ... }: {
+ mainBar = {
+ "layer" = "top";
+ "position" = "top";
+ "margin-left" = 8;
+ "margin-right" = 8;
+ "height" = 40;
+ "idle_inhibitor" = {
+ "format" = "{icon}";
+ "format-icons" = {
+ "activated" = "";
+ "deactivated" = "";
+ };
+ };
+ "bluetooth" = {
+ "format" = "";
+ "on-click" = "blueberry";
+ };
+ "battery" = {
+ "states" = {
+ # "good" = 95;
+ "warning" = 30;
+ "critical" = 15;
+ };
+ "format" = "{capacity}% {icon} ";
+ "format-charging" = "{capacity}% 󰂄";
+ "format-plugged" = "{capacity}% ";
+ # "format-good" = "",
+ # "format-full" = "";
+ "format-icons" = [ "" "" "" "" "" ];
+ };
+ "custom/PBPbattery" = {
+ "exec" = "~/.config/waybar/scripts/PBPbattery.sh";
+ "format" = "{}";
+ };
+ "clock" = {
+ "locale" = "ja_JP.utf8";
+ "interval" = 5;
+
+ # "format-alt" = " {:%e %b %Y}", # Icon: calendar-alt
+ # "format" = "{:%e %b %Y %H:%M}";
+ # "tooltip-format" = "{:%e %B %Y}";
+ # "tooltip-format" = "<tt><small>{calendar}</small></tt>";
+ # "format" = "{:%m月 %d日 %I時%M分%S秒}";
+
+ # "format" = "{:%m月 %d日 %H:%M:%S}";
+ "format" = "{:%m月 %d日 %H:%M}";
+ # "format-alt" = "{:L%G年%b %d日 %A}";
+ "format-alt" = "{:L%G年%b %d日 %A}";
+ };
+ "cpu" = {
+ "interval" = 5;
+ "format" = " {usage}% ({load})";
+ "states" = {
+ "warning" = 70;
+ "critical" = 90;
+ };
+ "on-click" = "kitty -e '${pkgs.bottom}/bin/btm'";
+ };
+ "custom/keyboard-layout" = {
+ "exec" = "swaymsg -t get_inputs | grep -m1 'xkb_active_layout_name' | cut -d '\"' -f4";
+ "interval" = 30;
+ "format" = " {}";
+ "signal" = 1; # SIGHUP
+ "tooltip" = false;
+ "on-click" = "~/.config/waybar/scripts/keyhint.sh";
+ };
+ "memory" = {
+ "interval" = 5;
+ "format" = " {}%";
+ "format-alt" = " {used:0.1f}/{total:0.1f}ギガ";
+ "states" = {
+ "warning" = 70;
+ "critical" = 90;
+ };
+ };
+ "network" = {
+ "interval" = 1;
+ # "format-wifi" = " ",
+ # "format-ethernet" = " {bandwidthUpBytes} {bandwidthDownBytes}",
+ "format" = " {bandwidthUpBytes}  {bandwidthDownBytes}";
+ "format-disconnected" = "⚠ Disconnected";
+ "tooltip-format" = "{ifname}: {ipaddr}";
+ "on-click" = "kitty -e 'nmtui'";
+ };
+ "network#vpn" = {
+ "interface" = "tun0";
+ "format" = " ";
+ "format-disconnected" = "⚠ Disconnected";
+ "tooltip-format" = "{ifname}: {ipaddr}/{cidr}";
+ };
+ "hyprland/mode" = {
+ "format" = "{}";
+ "tooltip" = false;
+ };
+ "hyprland/window" = {
+ "format" = "{}";
+ "max-length" = 120;
+ "separate-outputs" = true;
+ "icon" = false;
+ "rewrite" = {
+ "(.*) - Thorium" = "󰖟 $1";
+ "(.*) - NVIM" = " $1";
+ "ChatGPT" = " ChatGPT";
+ "~(.*)" = " ~$1";
+ "…(.*)" = " …$1";
+ "zsh" = " ~";
+ "fish" = " ~";
+ "kitty" = " ~";
+ "Volume Control" = " Volume Control";
+ "Bluetooth" = " Bluetooth";
+ "JamesDSP for Linux" = "󰺢 JamesDSP";
+ };
+ };
+ "pulseaudio" = {
+ "scroll-step" = 1;
+ # "format" = "{icon} {volume}%";
+ "format" = "{icon} {volume}%";
+ # "format-bluetooth" = "{volume}% {icon}  {format_source}";
+ # "format-bluetooth-muted" = " {icon}  {format_source}";
+ "format-muted" = "󰸈";
+ "format-icons" = {
+ "headphone" = "󰋋";
+ "hands-free" = "וֹ";
+ "headset" = "󱡏";
+ "phone" = "";
+ "portable" = "";
+ "car" = "";
+ "default" = [ "" ];
+ };
+ "on-click" = "pactl set-sink-mute @DEFAULT_SINK@ toggle";
+ "on-click-right" = "pavucontrol";
+ "on-scroll-up" = "pactl set-sink-volume @DEFAULT_SINK@ +2%";
+ "on-scroll-down" = "pactl set-sink-volume @DEFAULT_SINK@ -2%";
+ };
+ "pulseaudio#microphone" = {
+ "format" = "{format_source}";
+ "format-source" = " {volume}%";
+ "format-source-muted" = " ";
+ "on-click" = "pamixer --default-source -t";
+ "on-click-right" = "pavucontrol";
+ "on-scroll-up" = "pamixer --default-source -i 5";
+ "on-scroll-down" = "pamixer --default-source -d 5";
+ "scroll-step" = 5;
+ };
+ "custom/weather" = {
+ "exec" = "~/.config/waybar/scripts/weather.sh tampa";
+ "return-type" = "json";
+ "interval" = 600;
+ };
+ "tray" = {
+ # "icon-size" = 18;
+ "spacing" = 10;
+ "show-passive-items" = true;
+ };
+ "backlight#icon" = {
+ "format" = "{icon}";
+ "format-icons" = [ "" ];
+ "on-scroll-down" = "brightnessctl -c backlight set 1%-";
+ "on-scroll-up" = "brightnessctl -c backlight set +1%";
+ };
+ "backlight#value" = {
+ "format" = "{percent}%";
+ "on-scroll-down" = "brightnessctl -c backlight set 1%-";
+ "on-scroll-up" = "brightnessctl -c backlight set +1%";
+ };
+ "custom/firefox" = {
+ "format" = " ";
+ "on-click" = "exec firefox";
+ "tooltip" = false;
+ };
+ "custom/terminal" = {
+ "format" = " ";
+ "on-click" = "exec kitty";
+ "tooltip" = false;
+ };
+ "custom/files" = {
+ "format" = " ";
+ "on-click" = "exec nautilus";
+ "tooltip" = false;
+ };
+ "custom/power" = {
+ "format" = "⏻";
+ "on-click" = "exec ~/.config/waybar/scripts/power-menu.sh";
+ "tooltip" = false;
+ };
+ "image#album-art" = {
+ "path" = "/tmp/mediaplayer_art";
+ "size" = 22.5; # (18 + (18 / 4))
+ "interval" = 5;
+ "on-click" = "playerctl play-pause";
+ };
+ "custom/media" = {
+ "format" = "{icon} {}";
+ "return-type" = "json";
+ "max-length" = 40;
+ "format-icons" = {
+ "spotify" = " ";
+ "default" = "󰗃 ";
+ };
+ "escape" = true;
+ "exec" = "/usr/bin/python3 ~/.config/waybar/scripts/mediaplayer.py 2> /dev/null";
+ "on-click" = "playerctl play-pause";
+ "on-scroll-up" = "playerctl next";
+ "on-scroll-down" = "playerctl previous";
+ };
+ "cava#cava1" = {
+ "framerate" = 280;
+ "autosens" = 1;
+ "sensitivity" = 3;
+ "bars" = 26;
+ "lower_cutoff_freq" = 50;
+ "higher_cutoff_freq" = 10000;
+ "method" = "pipewire";
+ "source" = "auto";
+ "stereo" = true;
+ "reverse" = true;
+ "bar_delimiter" = 0;
+ "monstercat" = false;
+ "waves" = false;
+ "hide_on_silence" = true;
+ "noise_reduction" = 0.77;
+ "input_delay" = 0;
+ "on-click" = "playerctl play-pause";
+ # "format-icons" = ["░", "▒", "▓", "█", "█", "█", "█", "█"]
+ # "format-icons" = ["⎺", "⎻", "⎼", "⎽", "⎼", "⎻", "⎺", "⎹"]
+ # "format-icons" = ["▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"]
+ "format-icons" = [ "⠁" "⠃" "⠇" "⠋" "⠛" "⠟" "⠿" "⣿" ];
+ # "format-icons" = ["◰", "◳", "◲", "◱", "▘", "▝", "▖", "▗"]
+ # "format-icons" = ["▖", "▗", "▘", "▝", "▚", "▞", "▛", "▟"]
+ # "format-icons" = ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█", "▉", "▊"]
+ # "format-icons" = ["⎯", "⎰", "⎱", "⎲", "⎳", "⎴", "⎵", "⎶"]
+ # "format-icons" = ["⎺", "⎻", "⎼", "⎽", "⎾", "⎿", "⏀", "⏁"]
+ # "format-icons" = ["♪", "♫", "♬", "♭", "♮", "♯", "♩", "♪"]
+ # "format-icons" = ["→", "⇉", "⇒", "⇉", "→", "⇉", "⇒", "⇉"]
+ # "format-icons" = ["·", ":", "⁙", "⁘", "⁙", ":", "·", "•"]
+ # "format-icons" = ["○", "◔", "◑", "◕", "●", "◍", "◎", "◉"]
+ # "format-icons" = ["△", "▲", "▴", "▸", "▶", "▹", "►", "▻"]
+ # "format-icons" = ["◇", "◈", "◉", "◍", "◎", "◯", "⦿", "◑"]
+ # "format-icons" = ["-", "–", "—", "––", "–––", "——", "———", "——––"]
+ # "format-icons" = ["-", "=", "≡", "≣", "≠", "≢", "≜", "≝"]
+ # "format-icons" = ["✓", "✔", "✕", "✖", "✗", "✘", "✙", "✚"]
+ # "format-icons" = ["✩", "✪", "✫", "✬", "✭", "✮", "✯", "✰"]
+ /* "actions" = {
+ "on-click-right" = "mode";
+ } */
+ };
+ "cava#cava2" = {
+ "framerate" = 280;
+ "autosens" = 1;
+ "sensitivity" = 4;
+ "bars" = 10;
+ "lower_cutoff_freq" = 50;
+ "higher_cutoff_freq" = 10000;
+ "method" = "pipewire";
+ "source" = "auto";
+ "stereo" = false;
+ "reverse" = true;
+ "bar_delimiter" = 0;
+ "monstercat" = false;
+ "waves" = false;
+ "hide_on_silence" = true;
+ "noise_reduction" = 0.77;
+ "input_delay" = 0;
+ # "format-icons" = ["░", "▒", "▓", "█", "█", "█", "█", "█"]
+ # "format-icons" = ["⎺", "⎻", "⎼", "⎽", "⎼", "⎻", "⎺", "⎹"]
+ # "format-icons" = ["▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"]
+ "format-icons" = [ "⠁" "⠃" "⠇" "⠋" "⠛" "⠟" "⠿" "⣿" ];
+ # "format-icons" = ["◰", "◳", "◲", "◱", "▘", "▝", "▖", "▗"]
+ # "format-icons" = ["▖", "▗", "▘", "▝", "▚", "▞", "▛", "▟"]
+ # "format-icons" = ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█", "▉", "▊"]
+ # "format-icons" = ["⎯", "⎰", "⎱", "⎲", "⎳", "⎴", "⎵", "⎶"]
+ # "format-icons" = ["⎺", "⎻", "⎼", "⎽", "⎾", "⎿", "⏀", "⏁"]
+ # "format-icons" = ["♪", "♫", "♬", "♭", "♮", "♯", "♩", "♪"]
+ # "format-icons" = ["→", "⇉", "⇒", "⇉", "→", "⇉", "⇒", "⇉"]
+ # "format-icons" = ["·", ":", "⁙", "⁘", "⁙", ":", "·", "•"]
+ # "format-icons" = ["○", "◔", "◑", "◕", "●", "◍", "◎", "◉"]
+ # "format-icons" = ["△", "▲", "▴", "▸", "▶", "▹", "►", "▻"]
+ # "format-icons" = ["◇", "◈", "◉", "◍", "◎", "◯", "⦿", "◑"]
+ # "format-icons" = ["-", "–", "—", "––", "–––", "——", "———", "——––"]
+ # "format-icons" = ["-", "=", "≡", "≣", "≠", "≢", "≜", "≝"]
+ # "format-icons" = ["✓", "✔", "✕", "✖", "✗", "✘", "✙", "✚"]
+ # "format-icons" = ["✩", "✪", "✫", "✬", "✭", "✮", "✯", "✰"]
+ /* "actions" = { "on-click-right" = "mode"; } */
+ };
+ "custom/know" = {
+ "exec" = "know";
+ "interval" = 1;
+ };
+ "custom/gpu" = {
+ "exec" = "gpu-utilisation";
+ "interval" = 5;
+ "format" = " {}";
+ "on-click" = "kitty -e 'nvtop'";
+ };
+ "modules-left" = [
+ "hyprland/workspaces"
+ "hyprland/window"
+ "custom/media"
+ "image#album-art"
+ ];
+ "modules-center" = [ "clock" ];
+ "modules-right" = [
+ # "custom/know"
+ # "cava#cava1"
+ # "network"
+ # "cava#cava2"
+ "tray"
+ # "idle_inhibitor"
+ "cpu"
+ "custom/gpu"
+ "memory"
+ # "custom/keyboard-layout"
+ #"custom/PBPbattery"
+ # "backlight#icon"
+ # "backlight#value"
+ "bluetooth"
+ "pulseaudio"
+ # "pulseaudio#microphone"
+ # "network"
+ # "battery"
+ ];
+ };
+}
diff --git a/desktop/wayland/waybar/waybar/scripts/brightness.sh b/desktop/wayland/waybar/waybar/scripts/brightness.sh
new file mode 100755
index 0000000..9830a3a
--- /dev/null
+++ b/desktop/wayland/waybar/waybar/scripts/brightness.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+
+iDIR="$HOME/.config/dunst/imgs"
+
+# Get brightness
+get_backlight() {
+ MAX=$(brightnessctl max)
+ LIGHT=$(printf "%.0f\n" $(brightnessctl get))
+ PERCENTAGE=$(expr 100 \* $LIGHT / $MAX)
+ echo "${PERCENTAGE}%"
+}
+
+# Get icons
+get_icon() {
+ backlight="$(get_backlight)"
+ current="${backlight%%%}"
+ if [[ ("$current" -ge "0") && ("$current" -le "20") ]]; then
+ icon="$iDIR/brightness-20.png"
+ elif [[ ("$current" -ge "20") && ("$current" -le "40") ]]; then
+ icon="$iDIR/brightness-40.png"
+ elif [[ ("$current" -ge "40") && ("$current" -le "60") ]]; then
+ icon="$iDIR/brightness-60.png"
+ elif [[ ("$current" -ge "60") && ("$current" -le "80") ]]; then
+ icon="$iDIR/brightness-80.png"
+ elif [[ ("$current" -ge "80") && ("$current" -le "100") ]]; then
+ icon="$iDIR/brightness-100.png"
+ fi
+}
+
+# Notify
+notify_user() {
+ notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i "$icon" "Brightness : $(get_backlight)"
+}
+
+# Increase brightness
+inc_backlight() {
+ brightnessctl set 5%+ && get_icon && notify_user
+}
+
+# Decrease brightness
+dec_backlight() {
+ brightnessctl set 5%- && get_icon && notify_user
+}
+
+# Execute accordingly
+if [[ "$1" == "--get" ]]; then
+ get_backlight
+elif [[ "$1" == "--inc" ]]; then
+ inc_backlight
+elif [[ "$1" == "--dec" ]]; then
+ dec_backlight
+else
+ get_backlight
+fi \ No newline at end of file
diff --git a/desktop/wayland/waybar/waybar/scripts/mediaplayer.py b/desktop/wayland/waybar/waybar/scripts/mediaplayer.py
new file mode 100755
index 0000000..cec64a6
--- /dev/null
+++ b/desktop/wayland/waybar/waybar/scripts/mediaplayer.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python3
+import argparse
+import logging
+import os
+import sys
+import signal
+import gi
+import json
+
+gi.require_version("Playerctl", "2.0")
+from gi.repository import Playerctl, GLib
+
+logger = logging.getLogger(__name__)
+
+
+def write_output(text, player):
+ logger.info("Writing output")
+
+ output = {
+ "text": text,
+ "class": "custom-" + player.props.player_name,
+ "alt": player.props.player_name,
+ "art": player.props.metadata["mpris:artUrl"],
+ }
+
+ sys.stdout.write(json.dumps(output) + "\n")
+ sys.stdout.flush()
+
+
+def on_play(player, status, manager):
+ logger.info("Received new playback status")
+ on_metadata(player, player.props.metadata, manager)
+
+
+def on_metadata(player, metadata, manager):
+ logger.info("Received new metadata")
+ track_info = ""
+
+ if (
+ player.props.player_name == "spotify"
+ and "mpris:trackid" in metadata.keys()
+ and ":ad:" in player.props.metadata["mpris:trackid"]
+ ):
+ track_info = "AD PLAYING"
+ elif player.get_artist() != "" and player.get_title() != "":
+ track_info = "{artist} - {title}".format(
+ artist=player.get_artist(), title=player.get_title()
+ )
+ else:
+ track_info = player.get_title()
+
+ if "file://" in player.props.metadata["mpris:artUrl"]:
+ os.system(
+ f"cp $(echo '{player.props.metadata['mpris:artUrl']}' | sed -E 's/file:\\/\\///g') /tmp/mediaplayer_art"
+ )
+ else:
+ os.system(
+ f"curl --silent $(echo '{player.props.metadata['mpris:artUrl']}' | sed -E 's/file:\\/\\///g') --output /tmp/mediaplayer_art"
+ )
+
+ # if player.props.status != 'Playing' and track_info:
+ # track_info = ' ' + track_info
+ write_output(track_info, player)
+
+
+def on_player_appeared(manager, player, selected_player=None):
+ if player is not None and (
+ selected_player is None or player.name == selected_player
+ ):
+ init_player(manager, player)
+ else:
+ logger.debug("New player appeared, but it's not the selected player, skipping")
+
+
+def on_player_vanished(manager, player):
+ logger.info("Player has vanished")
+ sys.stdout.write("\n")
+ sys.stdout.flush()
+ os.system("rm /tmp/mediaplayer_art")
+
+
+def init_player(manager, name):
+ logger.debug("Initialize player: {player}".format(player=name.name))
+ player = Playerctl.Player.new_from_name(name)
+ player.connect("playback-status", on_play, manager)
+ player.connect("metadata", on_metadata, manager)
+ manager.manage_player(player)
+ on_metadata(player, player.props.metadata, manager)
+
+
+def signal_handler(sig, frame):
+ logger.debug("Received signal to stop, exiting")
+ sys.stdout.write("\n")
+ sys.stdout.flush()
+ # loop.quit()
+ sys.exit(0)
+
+
+def parse_arguments():
+ parser = argparse.ArgumentParser()
+
+ # Increase verbosity with every occurrence of -v
+ parser.add_argument("-v", "--verbose", action="count", default=0)
+
+ # Define for which player we're listening
+ parser.add_argument("--player")
+
+ return parser.parse_args()
+
+
+def main():
+ arguments = parse_arguments()
+
+ # Initialize logging
+ logging.basicConfig(
+ stream=sys.stderr,
+ level=logging.DEBUG,
+ format="%(name)s %(levelname)s %(message)s",
+ )
+
+ # Logging is set by default to WARN and higher.
+ # With every occurrence of -v it's lowered by one
+ logger.setLevel(max((3 - arguments.verbose) * 10, 0))
+
+ # Log the sent command line arguments
+ logger.debug("Arguments received {}".format(vars(arguments)))
+
+ manager = Playerctl.PlayerManager()
+ loop = GLib.MainLoop()
+
+ manager.connect(
+ "name-appeared", lambda *args: on_player_appeared(*args, arguments.player)
+ )
+ manager.connect("player-vanished", on_player_vanished)
+
+ signal.signal(signal.SIGINT, signal_handler)
+ signal.signal(signal.SIGTERM, signal_handler)
+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+
+ for player in manager.props.player_names:
+ if arguments.player is not None and arguments.player != player.name:
+ logger.debug(
+ "{player} is not the filtered player, skipping it".format(
+ player=player.name
+ )
+ )
+ continue
+
+ init_player(manager, player)
+
+ loop.run()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/desktop/wayland/waybar/waybar/scripts/spotify.sh b/desktop/wayland/waybar/waybar/scripts/spotify.sh
new file mode 100755
index 0000000..8d25ebd
--- /dev/null
+++ b/desktop/wayland/waybar/waybar/scripts/spotify.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+while true; do
+
+ player_status=$(playerctl status 2>/dev/null)
+
+ if [ -z "$(playerctl metadata album)" ]; then
+ if [ "$player_status" = "Playing" ]; then
+ echo "$(playerctl metadata artist) - $(playerctl metadata title)"
+ elif [ "$player_status" = "Paused" ]; then
+ echo " $(playerctl metadata artist) - $(playerctl metadata title)"
+ else
+ echo ""
+ fi
+ else
+ if [ "$player_status" = "Playing" ]; then
+ echo "<span color='#1db954'></span> $(playerctl metadata artist) - $(playerctl metadata title)"
+ elif [ "$player_status" = "Paused" ]; then
+ echo "<span color='#1db954'></span>  $(playerctl metadata artist) - $(playerctl metadata title)"
+ else
+ echo ""
+ fi
+ fi
+
+ sleep 1
+
+done
diff --git a/desktop/wayland/waybar/waybar/scripts/theme.sh b/desktop/wayland/waybar/waybar/scripts/theme.sh
new file mode 100755
index 0000000..97fdc66
--- /dev/null
+++ b/desktop/wayland/waybar/waybar/scripts/theme.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+export PATH="${PATH}:${HOME}/.local/bin/"
+
+CURRENTIMG="$(<~/.cache/wal/wal )"
+MODE=""
+
+if [[ -e "${HOME}/.cache/wal/mode" ]]; then
+ MODE="$(<~/.cache/wal/mode )"
+else
+ cd ${HOME}/.cache/wal && touch mode
+
+ set -o noclobber
+ echo "dark" >| ${HOME}/.cache/wal/mode
+
+ MODE="dark"
+fi
+
+if [[ $MODE = "light" ]]; then
+ notify-send "Changing to dark theme..."
+
+ MODE="dark"
+
+ wal -i $CURRENTIMG --cols16
+
+ . $HOME/.config/mako/update-colors.sh
+
+ set -o noclobber
+ echo "dark" >| ${HOME}/.cache/wal/mode
+
+ notify-send "Changed to dark theme!"
+else
+ notify-send "Changing to light theme..."
+
+ MODE="light"
+
+ wal -i $CURRENTIMG -l --cols16
+
+ . $HOME/.config/mako/update-colors.sh
+
+ set -o noclobber
+ echo "light" >| ${HOME}/.cache/wal/mode
+
+ notify-send "Changed to light theme!"
+fi \ No newline at end of file
diff --git a/desktop/wayland/waybar/waybar/scripts/volume.sh b/desktop/wayland/waybar/waybar/scripts/volume.sh
new file mode 100755
index 0000000..e4a9183
--- /dev/null
+++ b/desktop/wayland/waybar/waybar/scripts/volume.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+
+iDIR="$HOME/.config/dunst/imgs"
+
+# Get Volume
+get_volume() {
+ volume=$(pamixer --get-volume)
+ echo "$volume"
+}
+
+# Get icons
+get_icon() {
+ current=$(get_volume)
+ if [[ "$current" -eq "0" ]]; then
+ echo "$iDIR/volume-mute.png"
+ elif [[ ("$current" -ge "0") && ("$current" -le "30") ]]; then
+ echo "$iDIR/volume-low.png"
+ elif [[ ("$current" -ge "30") && ("$current" -le "60") ]]; then
+ echo "$iDIR/volume-mid.png"
+ elif [[ ("$current" -ge "60") && ("$current" -le "100") ]]; then
+ echo "$iDIR/volume-high.png"
+ fi
+}
+
+# Notify
+notify_user() {
+ notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i "$(get_icon)" "Volume : $(get_volume)"
+}
+
+# Increase Volume
+inc_volume() {
+ pamixer -i 5 && notify_user
+}
+
+# Decrease Volume
+dec_volume() {
+ pamixer -d 5 && notify_user
+}
+
+# Toggle Mute
+toggle_mute() {
+ if [ "$(pamixer --get-mute)" == "false" ]; then
+ pamixer -m && notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i "$iDIR/volume-mute.png" "Volume Switched OFF"
+ elif [ "$(pamixer --get-mute)" == "true" ]; then
+ pamixer -u && notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i "$(get_icon)" "Volume Switched ON"
+ fi
+}
+
+# Toggle Mic
+toggle_mic() {
+ if [ "$(pamixer --source 66 --get-mute)" == "false" ]; then
+ pamixer -m --source 66 && notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i "$iDIR/microphone-mute.png" "Microphone Switched OFF"
+ elif [ "$(pamixer --source 66 --get-mute)" == "true" ]; then
+ pamixer -u --source 66 && notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i "$iDIR/microphone.png" "Microphone Switched ON"
+ fi
+}
+
+# Execute accordingly
+if [[ "$1" == "--get" ]]; then
+ get_volume
+elif [[ "$1" == "--inc" ]]; then
+ inc_volume
+elif [[ "$1" == "--dec" ]]; then
+ dec_volume
+elif [[ "$1" == "--toggle" ]]; then
+ toggle_mute
+elif [[ "$1" == "--toggle-mic" ]]; then
+ toggle_mic
+elif [[ "$1" == "--get-icon" ]]; then
+ get_icon
+else
+ get_volume
+fi
diff --git a/desktop/wayland/waybar/waybar/scripts/wallpaper.sh b/desktop/wayland/waybar/waybar/scripts/wallpaper.sh
new file mode 100755
index 0000000..23935cc
--- /dev/null
+++ b/desktop/wayland/waybar/waybar/scripts/wallpaper.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+export PATH="${PATH}:${HOME}/.local/bin/"
+
+DIR=$HOME/Wallpapers
+PICS=($(ls ${DIR}))
+
+RANDOMPICS=${PICS[ $RANDOM % ${#PICS[@]} ]}
+
+if [[ $(pidof swww) ]]; then
+ pkill swww
+fi
+
+swww img ${DIR}/${RANDOMPICS} --transition-type grow --transition-fps 60 --transition-duration 0.5 --transition-bezier 0.65,0,0.35,1 --transition-pos 0.794,0.972 --transition-step 1
+
+sleep 1.25
+
+if [[ "$(<~/.cache/wal/mode )" = "dark" ]]; then
+ wal -i ${DIR}/${RANDOMPICS} --cols16
+elif [[ "$(<~/.cache/wal/mode )" = "light" ]]; then
+ wal -i ${DIR}/${RANDOMPICS} -l --cols16
+fi
+
+pywal-discord -t default
+pywalfox update
+wal-telegram --wal
+
+. $HOME/.config/mako/update-colors.sh \ No newline at end of file
diff --git a/desktop/wayland/waybar/waybar/style.css b/desktop/wayland/waybar/waybar/style.css
new file mode 100644
index 0000000..c08905f
--- /dev/null
+++ b/desktop/wayland/waybar/waybar/style.css
@@ -0,0 +1,133 @@
+@import "/home/fuwn/.cache/wal/colors-waybar.css";
+
+* {
+ /* font-family: CartographCF Nerd Font, Iosevka Nerd Font, cursive; */
+ /* font-family: Noto Sans Mono, Sarasa Mono J, cursive; */
+ /* font-family: SF Mono, cursive; */
+ /* font-family: MesloLGS NF; */
+ font-family: SF Pro, Hiragino Sans, cursive;
+ font-size: 15px;
+}
+
+window#waybar {
+ background-color: rgba(0, 0, 0, 0);
+ color: @foreground;
+ /* -gtk-icon-shadow: */
+ /* -1px 0 #ffffff, */
+ /* 0 1px #ffffff, */
+ /* 1px 0 #ffffff, */
+ /* 0 -1px #ffffff; */
+}
+
+#battery,
+#cava,
+#custom-know,
+#clock,
+#backlight,
+#cpu,
+#custom-keyboard-layout,
+#memory,
+#mode,
+#custom-weather,
+#network,
+#pulseaudio,
+#temperature,
+#tray,
+#idle_inhibitor,
+#window,
+#bluetooth,
+#custom-power,
+#workspaces,
+#custom-media,
+#custom-gpu,
+#custom-PBPbattery {
+ /* padding: 0.25rem 0.75rem; */
+ /* margin: 10px 5px 0px 0; */
+ padding: 5px 15px;
+ margin: 10px 1rem 0px 0;
+ background-color: @background;
+ border-radius: 10px; /* 9 */
+ color: @foreground;
+}
+
+#image {
+ margin-top: 10px;
+ border-top-right-radius: 10px;
+ border-bottom-right-radius: 10px;
+ background-color: @background;
+ margin-right: 1rem;
+ padding-right: 1rem;
+}
+
+#image > * {
+ border-radius: 10px;
+}
+
+#image.empty {
+ background-color: transparent;
+ min-width: 0;
+ min-height: 0;
+ margin: 0;
+ padding: 0;
+}
+
+window#waybar #custom-media {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ padding-right: 1rem;
+ margin-right: 0;
+}
+
+window#waybar.empty #window {
+ background-color: transparent;
+ padding: 0;
+ margin: 0;
+}
+
+window#custom-media.empty #window {
+ background-color: transparent;
+}
+
+#workspaces button.active {
+ color: @color11;
+}
+
+#workspaces button:hover {
+ background-color: unset;
+}
+
+#pulseaudio {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ margin-left: 0;
+ padding-left: 0.5rem;
+}
+
+#bluetooth {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ margin-right: 0;
+ padding-right: 0.5rem;
+}
+
+#memory {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ margin-left: 0;
+ padding-left: 0.5rem;
+}
+
+#custom-gpu {
+ border-radius: 0;
+ margin-right: 0;
+ margin-left: 0;
+ padding-right: 0.5rem;
+ padding-left: 0.5rem;
+}
+
+#cpu {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ margin-right: 0;
+ padding-right: 0.5rem;
+}
diff --git a/home.nix b/home.nix
new file mode 100644
index 0000000..984e1fa
--- /dev/null
+++ b/home.nix
@@ -0,0 +1,89 @@
+{ config, pkgs, ... }: {
+ home = {
+ # Home Manager needs a bit of information about you and the paths it should
+ # manage.
+ username = "fuwn";
+ homeDirectory = "/home/fuwn";
+
+ # This value determines the Home Manager release that your configuration is
+ # compatible with. This helps avoid breakage when a new Home Manager release
+ # introduces backwards incompatible changes.
+ #
+ # You should not change this value, even if you update Home Manager. If you do
+ # want to update the value, then make sure to first check the Home Manager
+ # release notes.
+ stateVersion = "24.05"; # Please read the comment before changing.
+
+ # The home.packages option allows you to install Nix packages into your
+ # environment.
+ packages = [
+ # # Adds the 'hello' command to your environment. It prints a friendly
+ # # "Hello, world!" when run.
+ # pkgs.hello
+
+ # # It is sometimes useful to fine-tune packages, for example, by applying
+ # # overrides. You can do that directly here, just don't forget the
+ # # parentheses. Maybe you want to install Nerd Fonts with a limited number of
+ # # fonts?
+ # (pkgs.nerdfonts.override { fonts = [ "FantasqueSansMono" ]; })
+
+ # # You can also create simple shell scripts directly inside your
+ # # configuration. For example, this adds a command 'my-hello' to your
+ # # environment:
+ # (pkgs.writeShellScriptBin "my-hello" ''
+ # echo "Hello, \${config.home.username}!"
+ # '')
+ ];
+
+ # Home Manager is pretty good at managing dotfiles. The primary way to manage
+ # plain files is through 'home.file'.
+ file = {
+ # # Building this configuration will create a copy of 'dotfiles/screenrc' in
+ # # the Nix store. Activating the configuration will then make '~/.screenrc' a
+ # # symlink to the Nix store copy.
+ # ".screenrc".source = dotfiles/screenrc;
+
+ # # You can also set the file content immediately.
+ # ".gradle/gradle.properties".text = ''
+ # org.gradle.console=verbose
+ # org.gradle.daemon.idletimeout=3600000
+ # '';
+ };
+
+ # Home Manager can also manage your environment variables through
+ # 'home.sessionVariables'. These will be explicitly sourced when using a
+ # shell provided by Home Manager. If you don't want to manage your shell
+ # through Home Manager then you have to manually source 'hm-session-vars.sh'
+ # located at either
+ #
+ # ~/.nix-profile/etc/profile.d/hm-session-vars.sh
+ #
+ # or
+ #
+ # ~/.local/state/nix/profiles/profile/etc/profile.d/hm-session-vars.sh
+ #
+ # or
+ #
+ # /etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh
+ #
+ sessionVariables = {
+ # EDITOR = "emacs";
+ };
+
+ # sessionPath = [
+ # "$HOME/.local/bin"
+ # ];
+ };
+
+ # Let Home Manager install and manage itself.
+ programs.home-manager.enable = true;
+
+ imports = [ ./applications ./desktop ./rice ./tools ];
+
+ nixpkgs = {
+ config = {
+ allowUnfree = true;
+ # allowBroken = true;
+ };
+ };
+}
diff --git a/rice/bottom/default.nix b/rice/bottom/default.nix
new file mode 100644
index 0000000..3d6066b
--- /dev/null
+++ b/rice/bottom/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { programs.bottom.enable = true; }
diff --git a/rice/default.nix b/rice/default.nix
new file mode 100644
index 0000000..0d8cb82
--- /dev/null
+++ b/rice/default.nix
@@ -0,0 +1,3 @@
+_: {
+ imports = [ ./bottom ./fastfetch ];
+}
diff --git a/rice/fastfetch/default.nix b/rice/fastfetch/default.nix
new file mode 100644
index 0000000..ba325d2
--- /dev/null
+++ b/rice/fastfetch/default.nix
@@ -0,0 +1,31 @@
+{ pkgs, ... }: {
+ programs.fastfetch = {
+ enable = true;
+ settings = {
+ logo = {
+ source = "~/Downloads/91363-1550240807.png";
+ width = 30;
+ padding = {
+ top = 0;
+ };
+ };
+ modules = [
+ "title"
+ "break"
+ "os"
+ "kernel"
+ "uptime"
+ "packages"
+ "shell"
+ "de"
+ "wm"
+ "terminal"
+ "cpu"
+ "gpu"
+ "memory"
+ "break"
+ "colors"
+ ];
+ };
+ };
+}
diff --git a/tools/default.nix b/tools/default.nix
new file mode 100644
index 0000000..8819a86
--- /dev/null
+++ b/tools/default.nix
@@ -0,0 +1 @@
+_: { imports = [ ./languages ./nix ./tcp ]; }
diff --git a/tools/languages/c/default.nix b/tools/languages/c/default.nix
new file mode 100644
index 0000000..bdc1087
--- /dev/null
+++ b/tools/languages/c/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ cmake ]; }
diff --git a/tools/languages/default.nix b/tools/languages/default.nix
new file mode 100644
index 0000000..c89c78c
--- /dev/null
+++ b/tools/languages/default.nix
@@ -0,0 +1 @@
+_: { imports = [ ./c ./gleam ./go ./javascript ./python ./rust ]; }
diff --git a/tools/languages/gleam/default.nix b/tools/languages/gleam/default.nix
new file mode 100644
index 0000000..d0d7355
--- /dev/null
+++ b/tools/languages/gleam/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ gleam ]; }
diff --git a/tools/languages/go/default.nix b/tools/languages/go/default.nix
new file mode 100644
index 0000000..5a3981b
--- /dev/null
+++ b/tools/languages/go/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ go ]; }
diff --git a/tools/languages/javascript/default.nix b/tools/languages/javascript/default.nix
new file mode 100644
index 0000000..5aaccda
--- /dev/null
+++ b/tools/languages/javascript/default.nix
@@ -0,0 +1,9 @@
+{ pkgs, ... }: {
+ home.packages = with pkgs; [
+ bun
+ # deno
+ # nodejs
+ # typescript
+ # nodePackages.npm
+ ];
+}
diff --git a/tools/languages/python/default.nix b/tools/languages/python/default.nix
new file mode 100644
index 0000000..050e2bb
--- /dev/null
+++ b/tools/languages/python/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ poetry python3 ]; }
diff --git a/tools/languages/rust/default.nix b/tools/languages/rust/default.nix
new file mode 100644
index 0000000..7c94599
--- /dev/null
+++ b/tools/languages/rust/default.nix
@@ -0,0 +1,3 @@
+{ pkgs, ... }: {
+ home.packages = with pkgs; [ cargo-outdated cargo-watch rustup ];
+}
diff --git a/tools/nix/default.nix b/tools/nix/default.nix
new file mode 100644
index 0000000..fe41b1d
--- /dev/null
+++ b/tools/nix/default.nix
@@ -0,0 +1,10 @@
+{ pkgs, ... }: {
+ home.packages = with pkgs; [
+ nil
+ statix
+ alejandra
+ nurl
+ nix-init
+ nix-prefetch-git
+ ];
+}
diff --git a/tools/tcp/default.nix b/tools/tcp/default.nix
new file mode 100644
index 0000000..00b61f2
--- /dev/null
+++ b/tools/tcp/default.nix
@@ -0,0 +1 @@
+{ pkgs, ... }: { home.packages = with pkgs; [ netcat-openbsd ]; }