diff --git a/flake.lock b/flake.lock index a2a4a74..8f41c3c 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,26 @@ { "nodes": { + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1720042825, + "narHash": "sha256-A0vrUB6x82/jvf17qPCpxaM+ulJnD8YZwH9Ci0BsAzE=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "e1391fb22e18a36f57e6999c7a9f966dc80ac073", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-24.05", + "repo": "home-manager", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1717555607, @@ -18,6 +39,7 @@ }, "root": { "inputs": { + "home-manager": "home-manager", "nixpkgs": "nixpkgs", "stable": "stable", "unstable": "unstable" diff --git a/flake.nix b/flake.nix index 0281c34..20e2032 100644 --- a/flake.nix +++ b/flake.nix @@ -4,8 +4,13 @@ nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05"; stable.url = "github:NixOS/nixpkgs/nixos-24.05"; unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; + + home-manager = { + url = "github:nix-community/home-manager/release-24.05"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; - outputs = { self, nixpkgs, stable, unstable }@attrs: { + outputs = { self, nixpkgs, stable, unstable, home-manager, ... }@attrs: { nixosConfigurations.harrowhark = nixpkgs.lib.nixosSystem rec { pkgs = let nixpkgsConfig = { @@ -27,6 +32,13 @@ ({ config, pkgs, options, ... }: { nix.registry.nixpkgs.flake = nixpkgs; }) + + home-manager.nixosModules.home-manager + { + home-manager.useGlobalPackages = true; + home-manager.useUserPackages = true; + home-manager.users.jaina = import ./home-manager/home.nix; + } ]; }; }; diff --git a/home-manager/.gitignore b/home-manager/.gitignore new file mode 100644 index 0000000..930a600 --- /dev/null +++ b/home-manager/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +**.kak.** diff --git a/home-manager/catppuccin/latte.nix b/home-manager/catppuccin/latte.nix new file mode 100644 index 0000000..4df14b1 --- /dev/null +++ b/home-manager/catppuccin/latte.nix @@ -0,0 +1,28 @@ +{ + rosewater = "#dc8a78"; + flamingo = "#dd7878"; + pink = "#ea76cb"; + mauve = "#8839ef"; + red = "#d20f39"; + maroon = "#e64553"; + peach = "#fe640b"; + yellow = "#df8e1d"; + green = "#40a02b"; + teal = "#179299"; + sky = "#04a5e5"; + sapphire = "#209fb5"; + blue = "#1e66f5"; + lavender = "#7287fd"; + text = "#4c4f69"; + subtext1 = "#5c5f77"; + subtext0 = "#6c6f85"; + overlay2 = "#7c7f93"; + overlay1 = "#8c8fa1"; + overlay0 = "#9ca0b0"; + surface2 = "#acb0be"; + surface1 = "#bcc0cc"; + surface0 = "#ccd0da"; + base = "#eff1f5"; + mantle = "#e6e9ef"; + crust = "#dce0e8"; +} diff --git a/home-manager/catppuccin/mocha.nix b/home-manager/catppuccin/mocha.nix new file mode 100644 index 0000000..a78de2f --- /dev/null +++ b/home-manager/catppuccin/mocha.nix @@ -0,0 +1,28 @@ +{ + rosewater = "#f5e0dc"; + flamingo = "#f2cdcd"; + pink = "#f5c2e7"; + mauve = "#cba6f7"; + red = "#f38ba8"; + maroon = "#eba0ac"; + peach = "#fab387"; + yellow = "#f9e2af"; + green = "#a6e3a1"; + teal = "#94e2d5"; + sky = "#89dceb"; + sapphire = "#74c7ec"; + blue = "#89b4fa"; + lavender = "#b4befe"; + text = "#cdd6f4"; + subtext1 = "#bac2de"; + subtext0 = "#a6adc8"; + overlay2 = "#9399b2"; + overlay1 = "#7f849c"; + overlay0 = "#6c7086"; + surface2 = "#585b70"; + surface1 = "#45475a"; + surface0 = "#313244"; + base = "#1e1e2e"; + mantle = "#181825"; + crust = "#11111b"; +} diff --git a/home-manager/flake.lock b/home-manager/flake.lock new file mode 100644 index 0000000..c8411a4 --- /dev/null +++ b/home-manager/flake.lock @@ -0,0 +1,247 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1659877975, + "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1718530513, + "narHash": "sha256-BmO8d0r+BVlwWtMLQEYnwmngqdXIuyFzMwvmTcLMee8=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "a1fddf0967c33754271761d91a3d921772b30d0e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-24.05", + "repo": "home-manager", + "type": "github" + } + }, + "hyprland": { + "inputs": { + "hyprland-protocols": "hyprland-protocols", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems", + "wlroots": "wlroots", + "xdph": "xdph" + }, + "locked": { + "lastModified": 1701881246, + "narHash": "sha256-p7el5oQZPy9l1zyIrlHu6nA4BAu59eLoSqBjhkw2jaw=", + "owner": "hyprwm", + "repo": "Hyprland", + "rev": "d74607e414dcd16911089a6d4b6aeb661c880923", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "ref": "v0.33.1", + "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" + } + }, + "nixgl": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1713543440, + "narHash": "sha256-lnzZQYG0+EXl/6NkGpyIz+FEOc/DSEG57AP1VsdeNrM=", + "owner": "guibou", + "repo": "nixGL", + "rev": "310f8e49a149e4c9ea52f1adf70cdc768ec53f8a", + "type": "github" + }, + "original": { + "owner": "guibou", + "repo": "nixGL", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1660551188, + "narHash": "sha256-a1LARMMYQ8DPx1BgoI/UN4bXe12hhZkCNqdxNi6uS0g=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "441dc5d512153039f19ef198e662e4f3dbb9fd65", + "type": "github" + }, + "original": { + "owner": "nixos", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1719253556, + "narHash": "sha256-A/76RFUVxZ/7Y8+OMVL1Lc8LRhBxZ8ZE2bpMnvZ1VpY=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "fc07dc3bdf2956ddd64f24612ea7fc894933eb2e", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "home-manager": "home-manager", + "hyprland": "hyprland", + "nixgl": "nixgl", + "nixpkgs": "nixpkgs_2", + "stable": "stable", + "unstable": "unstable" + } + }, + "stable": { + "locked": { + "lastModified": 1705957679, + "narHash": "sha256-Q8LJaVZGJ9wo33wBafvZSzapYsjOaNjP/pOnSiKVGHY=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "9a333eaa80901efe01df07eade2c16d183761fa3", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "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" + } + }, + "unstable": { + "locked": { + "lastModified": 1719082008, + "narHash": "sha256-jHJSUH619zBQ6WdC21fFAlDxHErKVDJ5fpN0Hgx4sjs=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "9693852a2070b398ee123a329e68f0dab5526681", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "wlroots": { + "flake": false, + "locked": { + "host": "gitlab.freedesktop.org", + "lastModified": 1701368958, + "narHash": "sha256-7kvyoA91etzVEl9mkA/EJfB6z/PltxX7Xc4gcr7/xlo=", + "owner": "wlroots", + "repo": "wlroots", + "rev": "5d639394f3e83b01596dcd166a44a9a1a2583350", + "type": "gitlab" + }, + "original": { + "host": "gitlab.freedesktop.org", + "owner": "wlroots", + "repo": "wlroots", + "rev": "5d639394f3e83b01596dcd166a44a9a1a2583350", + "type": "gitlab" + } + }, + "xdph": { + "inputs": { + "hyprland-protocols": [ + "hyprland", + "hyprland-protocols" + ], + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "systems": [ + "hyprland", + "systems" + ] + }, + "locked": { + "lastModified": 1700508250, + "narHash": "sha256-X4o/mifI7Nhu0UKYlxx53wIC+gYDo3pVM9L2u3PE2bE=", + "owner": "hyprwm", + "repo": "xdg-desktop-portal-hyprland", + "rev": "eb120ff25265ecacd0fc13d7dab12131b60d0f47", + "type": "github" + }, + "original": { + "owner": "hyprwm", + "repo": "xdg-desktop-portal-hyprland", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/home-manager/flake.nix b/home-manager/flake.nix new file mode 100644 index 0000000..efcd228 --- /dev/null +++ b/home-manager/flake.nix @@ -0,0 +1,48 @@ +{ + description = "home manager flake"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/release-24.05"; + stable.url = "github:nixos/nixpkgs/release-23.05"; + unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + nixgl.url = "github:guibou/nixGL"; + home-manager = { + url = "github:nix-community/home-manager/release-24.05"; + inputs.nixpkgs.follows = "nixpkgs"; + # url = "github:nix-community/home-manager/master"; + #inputs.nixpkgs.follows = "unstable"; + }; + hyprland = { + url = "github:hyprwm/Hyprland/v0.33.1"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { nixpkgs, stable, unstable, home-manager, hyprland, nixgl, ... }: { + defaultPackage.x86_64-linux = home-manager.defaultPackage.x86_64-linux; + + homeConfigurations = let system = "x86_64-linux"; + in rec { + "jaina" = home-manager.lib.homeManagerConfiguration { + pkgs = let + nixpkgsConfig = { + inherit system; + config.allowUnfree = true; + }; + in import nixpkgs (nixpkgsConfig // { + overlays = [ + (new: prev: { + unstable = import unstable nixpkgsConfig; + stable = import stable nixpkgsConfig; + }) + nixgl.overlay + ]; + }); + + #inputs.cat = import ./catppuccin/mocha.nix; + + modules = [ ./home.nix ]; + }; + }; + }; +} diff --git a/home-manager/fontconfig.nix b/home-manager/fontconfig.nix new file mode 100644 index 0000000..ae97b34 --- /dev/null +++ b/home-manager/fontconfig.nix @@ -0,0 +1,63 @@ +{ config, pkgs, lib, ... }: + +with lib; +let + cfg = config.fonts.fontconfig-extra; +in { + options.fonts.fontconfig-extra = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable advanced fontconfig configuration. + This will allow you to set default fonts for your applications. + ''; + }; + + defaultFonts = let + mkFontOption = name: mkOption { + type = types.nullOr hm.types.fontType; + default = null; + description = '' + The default font to use when a ${name} font is requested. + ''; + }; + in { + sans-serif = mkFontOption "sans-serif"; + serif = mkFontOption "serif"; + monospace = mkFontOption "monospace"; + }; + }; + + config = mkIf cfg.enable { + home.packages = let + optionalPackage = opt: optional (opt != null && opt.package != null) opt.package; + in concatMap optionalPackage [ + cfg.defaultFonts.sans-serif + cfg.defaultFonts.serif + cfg.defaultFonts.monospace + ]; + + xdg.configFile."fontconfig/conf.d/80-hm-fonts-extra.conf".text = let + mkConfig = family: font: mapNullable (notNullFont: '' + + + ${family} + + + ${font.name} + + + '') font; + configs = concatStrings (filter (v: ! isNull v) ( + attrValues (mapAttrs mkConfig cfg.defaultFonts) + )); + in '' + + + + ${configs} + + ''; + }; +} diff --git a/home-manager/home.nix b/home-manager/home.nix new file mode 100644 index 0000000..471b953 --- /dev/null +++ b/home-manager/home.nix @@ -0,0 +1,549 @@ +{ config, pkgs, lib, ... }: + +# TODOs: +# - Add in configs for: +# + Rofi +# + mako +# + The scratchpad manager (maybe wait for hyprland) +# - Setup better on-screen-keyboard support +# - rofi-emoji +# - Create settings bar or something +# - Figure out how to get info or widgets on lockscreen +# - Explore Hyprland + +let + fonts = { + primary = { + name = "Iosevka Comfy Duo"; + package = pkgs.iosevka-comfy.comfy-duo; + size = 11; + }; + serif = { + name = "Iosevka Comfy Motion Duo"; + package = pkgs.iosevka-comfy.comfy-motion-duo; + size = 11; + }; + fixed = { + name = "Iosevka Comfy Wide"; + package = pkgs.iosevka-comfy.comfy-wide; + size = 11; + }; + + wmOverlay = + lib.trivial.mergeAttrs fonts.primary { size = fonts.primary.size + 1; }; + }; + fronters = { + jams = { + name = "jams"; + displayName = "jams"; + accents = { + primary = "Green"; + secondary = "Teal"; + }; + wallpaper = ./wallpapers/slimejaina_extinct_lesboba.png; + }; + + velma = { + name = "velma"; + displayName = "Velma Jade"; + accents = { + primary = "Peach"; + secondary = "Yellow"; + }; + wallpaper = ./wallpapers/velma_picrew_cropped.png; + }; + + alys = { + name = "alys"; + displayName = "alys elrena"; + nicknames = [ "elrena" ]; + accents = { + primary = "Blue"; + secondary = "Sapphire"; + }; + wallpaper = ./wallpapers/elrena-lauriam-cropped.jpg; + }; + + sarina = { + name = "sarina"; + displayName = "Sarina"; + nicknames = [ "rachel" ]; + accents = { + primary = "Pink"; + secondary = "Mauve"; + }; + wallpaper = ./wallpapers/sarina.png; + }; + + denise = { + name = "denise"; + displayName = "denise_"; + nicknames = [ "0x7F454C46" "_denise" ]; + accents = { + primary = "Lavender"; + secondary = "Blue"; + }; + wallpaper = ./wallpapers/denise_picrew_2.png; + }; + }; + defaultFront = fronters.jams; +in { + nixpkgs.config.allowUnfree = true; + + imports = [ ./jwm.nix ./fontconfig.nix ]; + + jainawm = { + enable = true; + fonts = fonts; + phelper = { + profiles = fronters; + defaultProfile = "jams"; + makeSpecializations = true; + }; + }; + # specialization = builtins.mapAttrs (n: c: { configuration = { + # jainawm.phelper.activeProfile = n; + # home.activation.recordVersion = lib.hm.dag.entryAnywhere ""; + # }; }) fronters; + + # Home Manager needs a bit of information about you and the + # paths it should manage. + home.username = "jaina"; + home.homeDirectory = "/home/jaina"; + + fonts.fontconfig-extra = { + enable = true; + defaultFonts = { + sans-serif = fonts.primary; + serif = fonts.serif; + monospace = fonts.fixed; + }; + }; + + xdg.enable = true; + xdg.cacheHome = builtins.toPath "${config.home.homeDirectory}/.cache"; + xdg.configHome = builtins.toPath "${config.home.homeDirectory}/.config"; + xdg.dataHome = builtins.toPath "${config.home.homeDirectory}/.local/share"; + xdg.stateHome = builtins.toPath "${config.home.homeDirectory}/.local/state"; + #xdg.mimeApps = {}; + xdg.userDirs = { + enable = true; + desktop = null; + publicShare = null; + templates = null; + documents = "${config.home.homeDirectory}/documents"; + download = "${config.home.homeDirectory}/downloads"; + music = "${config.home.homeDirectory}/music"; + pictures = "${config.home.homeDirectory}/pictures"; + videos = "${config.home.homeDirectory}/videos"; + }; + + xdg.desktopEntries = { + webcord = { + name = "WebCord"; + terminal = false; + exec = + "webcord --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu"; + }; + }; + + # home.activation = { + # recordVersion = lib.mkDefault (lib.hm.dag.entryAfter ["writeBoundary"] '' + # rm -f "${config.xdg.stateHome}/hm-generation" + # ${pkgs.coreutils}/bin/ln -s "$( + # ${pkgs.home-manager}/bin/home-manager generations | \ + # ${pkgs.coreutils}/bin/head -n1 | \ + # ${pkgs.gawk}/bin/awk '{ print $7; }' + # )" \ + # "${config.xdg.stateHome}/hm-generation" + # ''); + # }; + + gtk = { + enable = true; + font = fonts.primary; + }; + home.pointerCursor = { + gtk.enable = true; + x11.enable = true; + name = "Catppuccin-Mocha-Light-Cursors"; + size = 32; + package = pkgs.catppuccin-cursors.mochaLight; + }; + + home.enableNixpkgsReleaseCheck = true; + + programs.kitty = { + enable = true; + font = fonts.fixed; + theme = "Catppuccin-Mocha"; + + settings = { + background_opacity = "0.85"; + show_hyperlink_targets = true; + enable_audio_bell = false; + visual_bell_duration = "0.05"; + }; + }; + + home.packages = with pkgs; [ + neofetch + less + fish + killall + htop + wget + binutils + coreutils-full + zip + unzip + git + + #sway + #rofi-wayland + #waybar + bc + mako + python3 + swaybg + swayidle + brightnessctl + pamixer + libnotify + inotify-tools + wl-clipboard + pulseaudio + pipewire + sqlite + grim + slurp + swaylock-effects + xdg-user-dirs + + firefox + + firefox-devedition-bin + + qutebrowser + #qutebrowser-qt6 + kakoune + kitty + keepassxc + discord + webcord + + pavucontrol + evince + + # (steam.override { + # extraPkgs = pkgs: + # with pkgs; [ + # xorg.libXcursor + # xorg.libXi + # xorg.libXinerama + # xorg.libXScrnSaver + # libpng + # libpulseaudio + # libvorbis + # stdenv.cc.cc.lib + # libkrb5 + # keyutils + + # # GW2 + # libpng12 + # gnutls + # freetype + # zlib + # #llvm + # ]; + # }) + steam + gamemode + lutris + #wine + #wine64 + wineWowPackages.stableFull + SDL2 + vulkan-loader + + mpd + + mpv + + #rofi-emoji + squeekboard + wtype + + qbittorrent + qbittorrent-nox + nftables + + fabric-installer + minecraft-server + prismlauncher + + syncthing + + nixos-generators + + qemu_kvm + OVMF.fd + + clementine + + gnumake + gcc + + appimage-run + + shticker-book-unwritten + + jq + + iosevka-comfy.comfy-duo + iosevka-comfy.comfy-wide-duo + iosevka + + font-awesome + (nerdfonts.override { fonts = [ "NerdFontsSymbolsOnly" ]; }) + + pinta + + krita + blender + + p7zip + + go + #zig + #unstable.zig_0_11 + + llvm + libclang + + luajitPackages.fennel + fnlfmt + + lmms + + aspell + + libreoffice + + #yarn + #postgresql + sqlite + #redis + + emacs + + #rofi-wayland + + colmena + + liferea + evolution + okular + + nixfmt + + stable.dolphin-emu + + glxinfo + + #any-nix-shell + nix-your-shell + + gdb + + scdl + ffmpeg + unstable.yt-dlp + stable.spotdl + + strawberry + + element-desktop + + #(eww.override { withWayland = true; }) + eww + socat + + (rustPlatform.buildRustPackage rec { + pname = "hyprland-workspaces"; + version = "v2.0.1"; + src = fetchFromGitHub { + owner = "FieldofClay"; + repo = pname; + rev = version; + sha256 = "GhUjvFMlgjTdgtV9ASW7IqE2dBktPyOlRwg6qM1r7vc="; + }; + + # patches = [ ./patches/hyprland-workspaces/output-monitor-info.patch ]; + + # need to patch cargo.lock for unreleased hyprland-rs + # cargoLock = { + # lockFileContents = + # builtins.readFile ./patches/hyprland-workspaces/Cargo.lock; + # outputHashes = { + # "hyprland-0.3.13" = + # "sha256-m3Ax6gvD+TAClSGvFrFTZ8Xs0Kgd55cZPu7q5O9s8uk="; + # }; + # }; + + cargoSha256 = "zjgm4HllLtRKvjSgSOWIWc7igF/T8oxvIfbmwz/POEo="; + }) + + zscroll + + file + + heroic + + #nixgl.auto.nixVulkanNvidia + #nixgl.auto.nixGLNvidiaBumblebee + + opusTools + + shotcut + kdenlive + mediainfo + + dig + vlc + ]; # end pkgs + + fonts.fontconfig.enable = true; + + programs.command-not-found.enable = true; + + home.sessionPath = [ "${config.home.homeDirectory}/.local/bin" ]; + home.sessionVariables = { + VISUAL = "kak"; + EDITOR = "kak"; + BROWSER = "qutebrowser"; + PAGER = "less"; + TERMINAL = "kitty"; + + SSH_AUTH_SOCK = "$XDG_RUNTIME_DIR/ssh-agent.socket"; + }; + + programs.fish = { + enable = true; + shellAliases = { + l = "ls -lah"; + psa = "ps aux"; + swaytree = "swaymsg -p -t get_tree | less"; + apcurl = "curl -H 'Accept: application/activity+json'"; + sway-game-output = + "swaymsg 'output eDP-1 scale 1' && swaymsg 'output eDP-1 mode --custom 1920x1080' && swaymsg 'input * pointer_accel 0.35'"; + sway-normal-output = + "swaymsg 'output eDP-1 scale 2' && swaymsg 'output eDP-1 mode 3000x2000' && swaymsg 'input * pointer_accel 0'"; + yt-mp3 = + "yt-dlp --extract-audio --audio-quality 0 --embed-metadata --embed-thumbnail"; + }; + interactiveShellInit = '' + neofetch + if test -z "$DISPLAY" && test (tty) = "/dev/tty1" + echo "Launching sway...." + exec sh -c "sway | grep -v 'not resolve keysym' >$XDG_RUNTIME_DIR/sway.log 2>&1" + end + ''; + shellInit = '' + #any-nix-shell fish --info-right | source + if command -q nix-your-shell + nix-your-shell fish | source + end + ''; + }; + + programs.swaylock = { + enable = true; + package = pkgs.swaylock-effects; + settings = { + ignore-empty-password = true; + show-failed-attempts = true; + image = lib.mkDefault "${defaultFront.wallpaper}"; + effect-blur = "5x5"; + clock = true; + }; + }; + + services.swayidle = let + mkFullscreenCheck = let + jqFilter = '' + .. + | select (type == "object") + | select (has("type") and (.type == "con" or .type == "floating_con")) + | select (.visible and .fullscreen_mode != 0) + ''; + in cmd: + toString (pkgs.writeScript "fullscreen-check-wrapper" '' + #!/bin/sh + fullscreen_windows="$(${pkgs.sway}/bin/swaymsg -t get_tree | ${pkgs.jq}/bin/jq ${ + lib.strings.escapeShellArg jqFilter + })" + if [ -z "$fullscreen_windows" ]; then + ${cmd} + # else + # Ignoring timeout command because there is a fullscreen window active + # (such as a game or a movie) + fi + ''); + grace-period = 60; + lock-timeout = 300; + screen-timeout = 450; + suspend-timeout = 600; + lock-cmd = "${pkgs.swaylock-effects}/bin/swaylock --daemonize"; + set-screen = state: "${pkgs.sway}/bin/swaymsg 'output * dpms ${state}'"; + in { + enable = true; + events = [ + { + event = "before-sleep"; + command = "${pkgs.systemd}/bin/loginctl lock-session"; + } + { + event = "lock"; + command = "${lock-cmd}"; + } + { + event = "after-resume"; + command = set-screen "on"; + } + ]; + timeouts = [ + { + timeout = lock-timeout; + command = mkFullscreenCheck + "${lock-cmd} --fade-in=3 --grace=${toString grace-period}"; + } + { + timeout = screen-timeout; + command = set-screen "off"; + resumeCommand = set-screen "on"; + } + { + timeout = suspend-timeout; + command = "${pkgs.systemd}/bin/systemctl suspend"; + } + ]; + }; + + services.syncthing.enable = true; + + programs.mangohud.enable = true; + + # Let Home Manager install and manage itself. + programs.home-manager.enable = true; + + # 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 can update Home Manager without changing this value. See + # the Home Manager release notes for a list of state version + # changes in each release. + home.stateVersion = "22.11"; +} diff --git a/home-manager/jwm.nix b/home-manager/jwm.nix new file mode 100644 index 0000000..67fa64f --- /dev/null +++ b/home-manager/jwm.nix @@ -0,0 +1,494 @@ +{ config, pkgs, lib, ... }: + +with lib; +with builtins; +let cfg = config.jainawm; +in { + options.jainawm = { + enable = mkOption { + type = types.bool; + default = false; + }; + + terminal = { + name = mkOption { + type = types.str; + default = "kitty"; + }; + package = mkOption { + type = types.package; + default = pkgs.kitty; + }; + binPath = mkOption { + type = types.str; + readOnly = true; + }; + }; + + fonts = let fontOption = mkOption { type = lib.hm.types.fontType; }; + in { + primary = fontOption; + serif = fontOption; + fixed = fontOption; + wmOverlay = fontOption; + }; + + catppuccin = mkOption { + #type = types.attrs; + default = import ./catppuccin/mocha.nix; + description = '' + Set of colors to use for theme configuration. + ''; + }; + + accents = { + primary = mkOption { type = types.str; }; + secondary = mkOption { type = types.str; }; + }; + + wallpaper = mkOption { type = types.path; }; + + startup = mkOption { + type = types.listOf (type.submodule { + options = { + enable = mkEnableOption "Enable the given startup command"; + + command = mkOption { type = types.str; }; + + always = mkOption { + type = types.bool; + default = false; + descrioption = + "If true, the command will be ran when the window manager is reset"; + }; + }; + }); + }; + }; + + imports = [ + ./jwm/sway.nix + ./jwm/rofi.nix + ./jwm/phelper.nix + ./jwm/kanshi.nix + ./jwm/waybar.nix + ./jwm/ptray.nix + ]; + + config = let + cat = cfg.catppuccin; + #front = getAttr cfg.selectedFront cfg.fronters; + fonts = cfg.fonts; + in mkIf cfg.enable { + jainawm.terminal.binPath = + "${cfg.terminal.package}/bin/${cfg.terminal.name}"; + services.mako = { + enable = true; + anchor = "top-right"; + + height = 100; + width = 500; + padding = "10"; + layer = "overlay"; + + font = "${fonts.primary.name} ${toString (fonts.primary.size + 1)}"; + textColor = cat.text; + backgroundColor = "${cat.surface0}cc"; + progressColor = "over ${cat.surface2}cc"; + + borderColor = + builtins.getAttr (lib.strings.toLower cfg.accents.primary) cat; + borderRadius = 10; + borderSize = 3; + + defaultTimeout = null; + maxVisible = null; + # groupBy = + # iconPath = + extraConfig = '' + on-button-left=invoke-default-action + on-touch=invoke-default-action + on-button-right=dismiss + + [app-name="discord"] + layer=overlay + on-button-left=exec /usr/bin/env dropwinctl show discord && makoctl invoke -n "$id" && makoctl dismiss -n "$id" + + [app-name="JWM"] + layer=overlay + + [app-name="JWM" category="audio" body~="1\([0-9][1-9]|[1-9][0-9]\)"] + background-color=${cat.surface2}f8 + progress-color=over ${cat.red}cc + ''; + }; + + #jainawm.wallpaper = front.wallpaper; + jainawm.rofi.accents = + mapAttrs (n: c: builtins.getAttr (lib.strings.toLower c) cat) cfg.accents; + jainawm.rofi.font = fonts.wmOverlay; + jainawm.ptray = { + enable = true; + items = { + discord = { + match_classes = [ "WebCord" "discord" ]; + exec = + "${pkgs.webcord}/bin/webcord --enable-features=UseOzonePlatform --ozone-platform=wayland --disable-gpu"; + }; + + keepass = { + match_classes = [ "org.keepassxc.KeePassXC" ]; + exec = "${pkgs.keepassxc}/bin/keepassxc"; + }; + }; + # drops = let + # fx = [ + # "opacity 0.97" + # "floating enable" + # "resize set 80ppt 80ppt" + # "move position 10ppt -10" + # "sticky enable" + # ]; + # in { + # discord = { + # match = [ "WebCord" "discord" ]; + # start = "${pkgs.discord}/bin/discord"; + # customization = fx; + # }; + # keepass = { + # match = [ "org.keepassxc.KeePassXC" ]; + # start = "${pkgs.keepassxc}/bin/keepassxc"; + # customization = fx; + # }; + # matrix = { + # match = [ "Element" ]; + # start = "${element-desktop}/bin/element-desktop"; + # customization = fx; + # }; + # }; + }; + #jainawm.rofi.accent = "#ff0000"; + #jainawm.rofi.enable = true; + #programs.waybar.style = builtins.readFile ./waybar/style.css; + + jainawm.kanshi.enable = true; + jainawm.sway.enable = true; + # TODO + xdg.configFile."hypr/hyprpaper.conf".text = '' + preload = ${cfg.wallpaper} + wallpaper = ,${cfg.wallpaper} + ''; + home.activation."switch-hyprpaper-wallpaper" = + lib.hm.dag.entryAfter [ "writeBoundary" ] '' + export PATH="$PATH:${config.wayland.windowManager.hyprland.package}/bin:${pkgs.jq}/bin" + hyprctl hyprpaper preload ${cfg.wallpaper} >/dev/null + hyprctl monitors -j | jq --raw-output '.[] | .name' | \ + xargs -I{} hyprctl hyprpaper wallpaper '{},${cfg.wallpaper}' >/dev/null + hyprctl hyprpaper unload all >/dev/null + ''; + xdg.configFile."eww/theme_cat.scss".text = concatStringsSep "\n" + (mapAttrsToList (name: value: "$cat-${name}: ${value};") cfg.catppuccin); + xdg.configFile."eww/theme_jwm.scss".text = '' + @import "theme_cat" + $jwm-accent: $cat-${lib.strings.toLower cfg.accents.primary}; + $jwm-accent2: $cat-${lib.strings.toLower cfg.accents.secondary}; + $jwm-accent-contrast: $cat-crust; + ''; + + home.activation.reloadHyprland = + lib.hm.dag.entryAfter [ "writeBoundary" ] '' + export PATH="$PATH:${config.wayland.windowManager.hyprland.package}/bin" + hyprctl reload + ''; + wayland.windowManager.hyprland.enable = true; + #wayland.windowManager.hyprland.settings = { }; + wayland.windowManager.hyprland.extraConfig = let + removeHash = col: builtins.replaceStrings [ "#" ] [ "" ] col; + getColor = name: + removeHash (builtins.getAttr (lib.strings.toLower name) cfg.catppuccin); + mainMod = "SUPER"; + playerctl = "${pkgs.playerctl}/bin/playerctl --player strawberry"; + hide-special = pkgs.writeShellScript "jwm-hyprland-hide-special" '' + hyprctl monitors -j | jq -r '.[] | .specialWorkspace.name | select(. | length > 0) | .[8:]' \ + | xargs -I{} hyprctl dispatcher togglespecialworkspace "{}" >/dev/null + ''; + rofi-emoji = let + rofi-emoji-theme = '' + element selected { + background-color: rgba(0,0,0,0 %); + border-color: ${cfg.rofi.accents.primary}ff; + border: 2px; + } + element { + children: ["element-text"]; + } + element-text { + horizontal-align: 0.5; + font: "${fonts.primary.name} 25"; + margin: 0px; + } + listview { + flow: horizontal; + columns: 7; + } + ''; + in pkgs.writeShellScript "rofi-emoji" '' + ${config.programs.rofi.finalPackage}/bin/rofi \ + -show emoji -modes emoji \ + -emoji-format '{emoji}' \ + -theme-str ${lib.strings.escapeShellArg rofi-emoji-theme} \ + $@ + ''; + playerctlPrevOrScan = pkgs.writeScript "playerctlPrevOrScan" '' + if [ "$(${playerctl} metadata --format '{{position}}')" -lt 10000000 ]; then + ${playerctl} previous + else + ${playerctl} position 0 + fi + ''; + in '' + $mainMod = ${mainMod} + + # For all categories, see https://wiki.hyprland.org/Configuring/Variables/ + input { + kb_layout = us + kb_variant = + kb_model = + kb_options = altwin:swap_lalt_lwin,altwin:menu_win + kb_rules = + + follow_mouse = 1 + + touchpad { + natural_scroll = yes + } + + sensitivity = 0 # -1.0 - 1.0, 0 means no modification. + } + + gestures { + workspace_swipe = true + workspace_swipe_fingers = 4 + } + + general { + col.active_border = rgba(${getColor cfg.accents.primary}ee) + col.inactive_border = rgba(${removeHash cfg.catppuccin.surface0}aa) + + gaps_in = 10 + gaps_out = 20 + border_size = 2 + + layout = dwindle + } + + decoration { + rounding = 10 + drop_shadow = yes + shadow_range = 20 + shadow_render_power = 2 + col.shadow = rgba(000000ee) + col.shadow_inactive = rgba(00000000) + + blur { + size = 5 + passes = 2 + + special = true + } + } + + layerrule = blur, rofi|notifications + layerrule = ignorealpha 0.4, rofi|notifications + + animations { + enabled = yes + + # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more + + bezier = myBezier, 0.05, 0.9, 0.1, 1.05 + + animation = windows, 1, 7, myBezier + animation = windowsOut, 1, 7, default, popin 80% + animation = border, 1, 10, default + animation = borderangle, 1, 8, default + animation = fade, 1, 7, default + animation = workspaces, 1, 6, default + animation = specialWorkspace, 1, 6, default, slidevert + } + + dwindle { + preserve_split = yes + } + + gestures { + workspace_swipe = on + } + + bind = ${mainMod}, Return, exec, ${cfg.terminal.binPath} + bind = ${mainMod}, D, exec, rofi -show drun + bind = ${mainMod} SHIFT, S, exec, jwm screenshot-region + binde = ${mainMod} SHIFT, Q, killactive, + bind = ${mainMod} SHIFT, E, exit, + bind = ${mainMod}, F, fullscreen, + bind = ${mainMod}, Q, exec, ${hide-special} + + bindle = , XF86MonBrightnessUp, exec, jwm bright 5 + bindle = , XF86MonBrightnessDown, exec, jwm bright -5 + bindle = , XF86AudioRaiseVolume, exec, jwm vol 5 + bindle = , XF86AudioLowerVolume, exec, jwm vol -5 + bindl = , XF86AudioMute, exec, jwm vol toggle-mute + bindl = , XF86AudioPlay, exec, ${playerctl} play-pause + bindl = , XF86AudioNext, exec, ${playerctl} next + bindl = , XF86AudioPrev, exec, ${playerctlPrevOrScan} + bindl = ${mainMod} CTRL, right, exec, ${playerctl} next + bindl = ${mainMod} CTRL, left, exec, ${playerctlPrevOrScan} + bindl = , XF86AudioStop, exec, ${playerctl} stop + + # Move focus with mainMod + arrow keys + bind = ${mainMod}, left, movefocus, l + bind = ${mainMod}, down, movefocus, d + bind = ${mainMod}, up, movefocus, u + bind = ${mainMod}, right, movefocus, r + bind = ${mainMod}, h, movefocus, l + bind = ${mainMod}, j, movefocus, d + bind = ${mainMod}, k, movefocus, u + bind = ${mainMod}, l, movefocus, r + + # Move focused window with mainMod + Shift + direction keys + bind = ${mainMod} SHIFT, left, moveWindowOrGroup, l + bind = ${mainMod} SHIFT, down, moveWindowOrGroup, d + bind = ${mainMod} SHIFT, up, moveWindowOrGroup, u + bind = ${mainMod} SHIFT, right, moveWindowOrGroup, r + bind = ${mainMod} SHIFT, h, moveWindowOrGroup, l + bind = ${mainMod} SHIFT, j, moveWindowOrGroup, d + bind = ${mainMod} SHIFT, k, moveWindowOrGroup, u + bind = ${mainMod} SHIFT, l, moveWindowOrGroup, r + + # Switch workspaces with mainMod + [0-9] + bind = ${mainMod}, 1, workspace, 1 + bind = ${mainMod}, 2, workspace, 2 + bind = ${mainMod}, 3, workspace, 3 + bind = ${mainMod}, 4, workspace, 4 + bind = ${mainMod}, 5, workspace, 5 + bind = ${mainMod}, 6, workspace, 6 + bind = ${mainMod}, 7, workspace, 7 + bind = ${mainMod}, 8, workspace, 8 + bind = ${mainMod}, 9, workspace, 9 + bind = ${mainMod}, 0, workspace, 10 + + # Move active window to a workspace with mainMod + SHIFT + [0-9] + bind = ${mainMod} SHIFT, 1, movetoworkspace, 1 + bind = ${mainMod} SHIFT, 2, movetoworkspace, 2 + bind = ${mainMod} SHIFT, 3, movetoworkspace, 3 + bind = ${mainMod} SHIFT, 4, movetoworkspace, 4 + bind = ${mainMod} SHIFT, 5, movetoworkspace, 5 + bind = ${mainMod} SHIFT, 6, movetoworkspace, 6 + bind = ${mainMod} SHIFT, 7, movetoworkspace, 7 + bind = ${mainMod} SHIFT, 8, movetoworkspace, 8 + bind = ${mainMod} SHIFT, 9, movetoworkspace, 9 + bind = ${mainMod} SHIFT, 0, movetoworkspace, 10 + + # Scroll through existing workspaces with mainMod + scroll + bind = ${mainMod}, mouse_down, workspace, e+1 + bind = ${mainMod}, mouse_up, workspace, e-1 + + bind = ${mainMod}, TAB, workspace, e+1 + bind = ${mainMod}, GRAVE, workspace, e-1 + bind = ${mainMod} SHIFT, TAB, movetoworkspace, e+1 + bind = ${mainMod} SHIFT, GRAVE, movetoworkspace, e-1 + + # Move/resize windows with mainMod + LMB/RMB and dragging + bindm = ${mainMod}, mouse:272, movewindow + bindm = ${mainMod}, mouse:273, resizewindow + + # Resize current window + bind = ${mainMod}, R, submap, resize + submap = resize + binde =, left, resizeActive, -10 0 + binde =, down, resizeActive, 0 10 + binde =, up, resizeActive, 0 -10 + binde =, right, resizeActive, 10 0 + binde =, h, resizeActive, -10 0 + binde =, j, resizeActive, 0 10 + binde =, k, resizeActive, 0 -10 + binde =, l, resizeActive, 10 0 + bind=,escape,submap,reset + bind=,return,submap,reset + submap = reset + + # App Launcher + bind = ${mainMod}, I, submap, app + submap = app + bind = , D, togglespecialworkspace, discord + bind = , D, submap, reset + bind = SHIFT, D, movetoworkspace, special:discord + bind = SHIFT, D, submap, reset + bind = , K, togglespecialworkspace, keepass + bind = , K, submap, reset + bind = SHIFT, K, movetoworkspace, special:keepass + bind = SHIFT, K, submap, reset + bind = , W, exec, jwm web-launcher + bind = , W, submap, reset + bind = , Return, submap, reset + bind = , Escape, submap, reset + submap = reset + + # OS commands + bind = ${mainMod}, P, submap, command + submap = command + bind = , M, exec, jwm mic toggle-mute + bind = , M, submap, reset + bind = , S, exec, jwm switch-launcher + bind = , S, submap, reset + bind = , D, exec, jwm toggle-dwt + bind = , D, submap, reset + bind = , Return, submap, reset + bind = , Escape, submap, reset + submap = reset + + # Emoji + bind = ${mainMod}, PERIOD, exec, ${rofi-emoji} -emoji-mode stdout | xargs wtype + + windowrule = noborder,^(steam_app_)(.*)$ + windowrule = noblur,^(steam_app_)(.*)$ + + windowrulev2 = workspace special:discord,class:(WebCord) + windowrulev2 = workspace special:keepass,class:(org.keepassxc.KeePassXC) + source=~/.config/hypr/hyprland.conf.backup + ''; + #wayland.windowManager.hyprland = { + # extraConfig = '' + # source=~/.config/hypr/hyprland.conf.backup + # ''; + #enable = true; + #}; + #jainawm.sway.useFx = true; + + home.packages = with pkgs; [ playerctl hyprpaper ]; + + qt = { + enable = true; + platformTheme = "gtk"; + }; + + gtk.enable = true; + gtk.theme = { + name = "Catppuccin-Mocha-Standard-${cfg.accents.primary}-Dark"; + package = pkgs.catppuccin-gtk.override { + accents = [ (lib.strings.toLower cfg.accents.primary) ]; + variant = "mocha"; + }; + }; + programs.swaylock.settings.image = "${cfg.wallpaper}"; + #wayland.windowManager.sway.config.output."*".bg = "${front.wallpaper} fill"; + + # programs.rofi.theme = import ./rofi-theme.nix { + # cat = cat; + # front = front; + # fonts = cfg.fonts; + # lib = lib; + # config = config; + # }; + }; +} diff --git a/home-manager/jwm/eww/eww.scss b/home-manager/jwm/eww/eww.scss new file mode 100644 index 0000000..4e6257a --- /dev/null +++ b/home-manager/jwm/eww/eww.scss @@ -0,0 +1,95 @@ +@import "theme_cat_mocha" +@import "theme_jwm" + +* { + font-family: 'Iosevka Comfy Duo, Symbols Nerd Font, Font Awesome'; +} + +.background { + background-color: rgba(#000, 0); +} + +.bar { + background-color: rgba($cat-mantle, 0.9); + padding: 5px 10px; + border-radius: 10px; + margin: 10px; + margin-bottom: 0px; +} + +.modules > widget { + background-color: rgba(#000, 0); +} + +.modules > widget > *, +.modules > * { + background-color: rgba($cat-surface1, 0.7); + border-radius: 10px; + margin: 0px 10px; + padding: 0px 10px; +} + +.modules > .container { + padding: 0px; +} + +.modules > .container > widget > *, +.modules > .container > * { + padding: 0px 8px; +} +.modules > .container > widget:first-child > *, +.modules > .container > *:first-child { + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; + padding-left: 10px; +} +.modules > .container > widget:last-child > *, +.modules > .container > *:last-child { + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; + padding-right: 10px; +} + +.workspaces { padding: 0px; } +.workspaces .item { + font-size: 90%; + min-width: 12px; + padding: 0px 8px; + border-radius: 10px; + background-color: rgba(0,0,0,0); + color: $cat-text; +} + +.workspaces .item:focus, +.workspaces .item.workspace-active, +.workspaces .item:hover { + font-size: 100%; +} + +.workspaces .item.workspace-active { + background-color: $jwm-accent; + color: $jwm-accent-contrast; +} + +.audio-controls { padding: 0; } +.audio-controls .volume-control { padding-right: 6px; } +.audio-controls .mic-control .icon { padding-left: 6px; } + +.volume-control .icon { font-size: 18px; } +.volume-control .value { padding-left: 6px; } +.volume-control.muted .icon { color: $cat-red; } +.volume-control.muted .value { + color: $cat-subtext0; + text-decoration: line-through; +} + +.mic-control.muted .icon { color: $cat-subtext0; } + +.playerctl.playing .music-icon { + background-color: $jwm-accent; + color: $jwm-accent-contrast; +} +.playerctl.paused .details { color: $cat-subtext0; } +.playerctl .details > *:first-child, .playerctl > *:first-child { padding-left: 0px; } +.playerctl .details > *:last-child, .playerctl > *:last-child { padding-right: 0px; } +.playerctl .details > * { padding: 0px 5px; } diff --git a/home-manager/jwm/eww/eww.yuck b/home-manager/jwm/eww/eww.yuck new file mode 100644 index 0000000..52118f1 --- /dev/null +++ b/home-manager/jwm/eww/eww.yuck @@ -0,0 +1,288 @@ +;; --------- Variables + +;; --------- Listeners + +(deflisten hyprland-window + ` + socat -U - /tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | \ + grep 'activewindow>>' --line-buffered | \ + sed 's/^activewindow>>[^,]*,//' --unbuffered + `) + +(deflisten hyprland-submap + ` + socat -U - /tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | \ + grep 'submap>>' --line-buffered | \ + sed 's/^submap>>//' --unbuffered + `) + +(deflisten workspace-list + :initial '[]' + `hyprland-workspaces _ | jq --compact-output --unbuffered '[ + .[] | select(.id > 0) + ]'`) + +(deflisten current-workspace + :initial '[]' + `hyprland-workspaces _ | jq --compact-output --unbuffered ' + .[] | select(.id > 0) | select(.class | contains("active")) | .id + '`) + + +(deflisten audio-out-volume + :initial 0 + ` + pamixer --get-volume + pactl subscribe | grep --line-buffered "'change' on sink" | xargs -I {} pamixer --get-volume + ` +) + +(deflisten audio-out-mute + :initial false + ` + pamixer --get-mute + pactl subscribe | grep --line-buffered "'change' on sink" | xargs -I {} pamixer --get-mute + ` +) + +(deflisten audio-in-mute + :initial false + ` + pamixer --get-mute --source @DEFAULT_SOURCE@ + pactl subscribe | grep --line-buffered "'change' on source" | xargs -I {} pamixer --get-mute --source @DEFAULT_SOURCE@ + ` +) + + +(deflisten playerctl-status :initial "" `playerctl status --player strawberry --follow --format '{{lc(status)}}'`) +(deflisten playerctl-title `playerctl metadata --player strawberry --follow --format '{{title}}'`) +(deflisten playerctl-artist `playerctl metadata --player strawberry --follow --format '{{artist}}'`) +(deflisten playerctl-album `playerctl metadata --player strawberry --follow --format '{{album}}'`) +(deflisten playerctl-position `playerctl metadata --player strawberry --follow --format '{{duration(position)}}'`) +(deflisten playerctl-length `playerctl metadata --player strawberry --follow --format '{{duration(mpris:length)}}'`) + +;; -------------- Widgets + +(defwidget window-title [?limit-width] + (label + :visible {strlength(hyprland-window) > 0} + :text hyprland-window + :class "window-title" + :tooltip hyprland-window + :limit-width {limit-width ?: 999} + ) +) + +(defwidget wm-mode [] + (eventbox + :class "wm-mode" + :visible {strlength(hyprland-submap) > 0} + :onclick `hyprctl dispatch submap '' >/dev/null` + (label + :text hyprland-submap + :tooltip hyprland-submap + ) + ) +) + +(defwidget workspaces [monitor] + (box + :class "workspaces" + (eventbox + :onscroll `~/.config/eww/hyprworkspace {} ${monitor} ${current-workspace}` + (box + (for i in {jq(workspace-list, '[ .[] | select (.monitor == "${monitor}") ]')} + (button + :onclick "bash -c 'hyprctl dispatch workspace ${i.id} >/dev/null'" + :class "item ${i.class}" + "${i.name}" + ) + ) + ) + ) + ) +) + +(defwidget clock [] + (label + :class "clock" + :text {formattime(EWW_TIME, "%H:%M")} + ) +) + +(defwidget battery [bat] + (box + :class {"battery " + (EWW_BATTERY[bat].capacity < 15 && EWW_BATTERY[bat].status != "Charging" ? "critical" : "") } + :style {EWW_BATTERY[bat].status == "Charging" ? "padding-left: 8px" : "padding-left: 3px"} + :space-evenly false + (box + :visible {EWW_BATTERY[bat].status == 'Charging'} + :style "margin-right: 3px" + (transform + :rotate 75 + :translate-x "-19px" + :translate-y "-4px" + (label :text "")) + ) + (transform + :visible {EWW_BATTERY[bat].status != 'Charging'} + :rotate 75 + :translate-x "-21px" + (label :text { + EWW_BATTERY[bat].capacity < 10 ? "" : + EWW_BATTERY[bat].capacity < 20 ? "" : + EWW_BATTERY[bat].capacity < 30 ? "" : + EWW_BATTERY[bat].capacity < 40 ? "" : + EWW_BATTERY[bat].capacity < 50 ? "" : + EWW_BATTERY[bat].capacity < 60 ? "" : + EWW_BATTERY[bat].capacity < 70 ? "" : + EWW_BATTERY[bat].capacity < 80 ? "" : + EWW_BATTERY[bat].capacity < 90 ? "" : + "" + })) + (label :text "100%") + ) +) + +(defwidget volume-control [] + (eventbox + :onclick `pamixer --toggle-mute` + ;;:onclick `notify-send "handler triggered"` + :onscroll ` + amt=1 + if [ "{}" = "up" ]; then + pamixer --increase $amt + else + pamixer --decrease $amt + fi + ` + (box + :space-evenly false + :class {"volume-control " + (audio-out-mute ? "muted " : "")} + (label + :class "icon" + :text { + audio-out-mute ? "󰸈" : ( + audio-out-volume < 10 ? "󰕿" : + audio-out-volume < 60 ? "󰖀" : + "󰕾" + ) + } + ) + (label :class "value" :text "${audio-out-volume}%") + ) + ) +) + +(defwidget mic-control [] + (eventbox + :class {"mic-control " + (audio-in-mute ? "muted " : "")} + :onclick `pamixer --toggle-mute --source @DEFAULT_SOURCE@` + (label + :class "icon" + :text {audio-in-mute ? "" : ""} + ) + ) +) + +(defwidget audio-controls [] + (box :class "container audio-controls" :space-evenly false (volume-control) (mic-control)) +) + +(defwidget playerctl [?limit-width] + (box + :space-evenly false + :class "container playerctl ${playerctl-status}" + (eventbox + (label :class "music-icon" :text "") + ) + (eventbox + :visible { playerctl-status != '' } + :onclick 'playerctl --player strawberry play-pause' + :onrightclick 'playerctl --player strawberry next' + :onmiddleclick 'playerctl --player strawberry previous' + (box + :class "details" + :space-evenly false + :tooltip `${playerctl-title} - ${playerctl-artist} - ${playerctl-album}` + (label + :class "status-icon" + :text { (playerctl-status == 'playing') ? '' : '' } + ) + (label + :class "track-info" + :limit-width limit-width + :text `${playerctl-title} - ${playerctl-artist} - ${playerctl-album}` + ) + (label + :class "position" + :markup `[${playerctl-position}/${playerctl-length}]` + ) + ) + ) + ) +) + +;; ---------- Bars + +(defwidget bar [monitor ?title-limit-width] + (centerbox :class "bar" + :class "bar" + (box :class "modules modules-left" + :space-evenly false + :halign "start" + (workspaces :monitor monitor) + (wm-mode) + (playerctl :limit-width 60) + ) + (box :class "modules modules-center" + :space-evenly false + :halign "center" + (window-title :limit-width title-limit-width) + ) + (box :class "modules modules-right" + :space-evenly false + :halign "end" + (audio-controls) + (battery :bat "BAT0") + (clock) + ) + ) +) + +(defwindow bar-window-0 + :monitor 0 + :geometry (geometry :x "0%" + :width "100%" + :height "30px" + :anchor "top center") + :stacking "fg" + ;; :reserve (struts :distance "80px" :side "top") + :exclusive true + :windowtype "dock" + (box (bar :monitor "eDP-1" :title-limit-width 100)) +) +(defwindow bar-window-1 + :monitor 1 + :geometry (geometry :x "0%" + :width "100%" + :height "30px" + :anchor "top center") + :stacking "fg" + ;; :reserve (struts :distance "80px" :side "top") + :exclusive true + :windowtype "dock" + (box (bar :monitor "DP-3")) +) +(defwindow bar-window-2 + :monitor 2 + :geometry (geometry :x "0%" + :width "100%" + :height "30px" + :anchor "top center") + :stacking "fg" + ;; :reserve (struts :distance "80px" :side "top") + :exclusive true + :windowtype "dock" + (box (bar :monitor "DP-2" :title-limit-width 60)) +) diff --git a/home-manager/jwm/eww/hyprworkspace b/home-manager/jwm/eww/hyprworkspace new file mode 100755 index 0000000..d2fa1b2 --- /dev/null +++ b/home-manager/jwm/eww/hyprworkspace @@ -0,0 +1,22 @@ +#!/bin/sh + +cmd=$1 +monitor=$2 +current=$3 + + +if [ "$cmd" = "down" ]; then + to_change=$( + hyprctl workspaces -j | jq --raw-output ' + [ .[] | select(.monitor == "'$monitor'" and .id > 0) | .id ] | + ([ .[] | select(. < '$current') ] | max) // max + ') +elif [ "$cmd" = "up" ]; then + to_change=$( + hyprctl workspaces -j | jq --raw-output ' + [ .[] | select(.monitor == "'$monitor'" and .id > 0) | .id ] | + ([ .[] | select(. > '$current') ] | min) // min + ') +fi + +hyprctl dispatch workspace $to_change >/dev/null diff --git a/home-manager/jwm/eww/theme_cat_latte.scss b/home-manager/jwm/eww/theme_cat_latte.scss new file mode 100644 index 0000000..6350423 --- /dev/null +++ b/home-manager/jwm/eww/theme_cat_latte.scss @@ -0,0 +1,26 @@ +$cat-rosewater: #dc8a78; +$cat-flamingo: #dd7878; +$cat-pink: #ea76cb; +$cat-mauve: #8839ef; +$cat-red: #d20f39; +$cat-maroon: #e64553; +$cat-peach: #fe640b; +$cat-yellow: #df8e1d; +$cat-green: #40a02b; +$cat-teal: #179299; +$cat-sky: #04a5e5; +$cat-sapphire: #209fb5; +$cat-blue: #1e66f5; +$cat-lavender: #7287fd; +$cat-text: #4c4f69; +$cat-subtext1: #5c5f77; +$cat-subtext0: #6c6f85; +$cat-overlay2: #7c7f93; +$cat-overlay1: #8c8fa1; +$cat-overlay0: #9ca0b0; +$cat-surface2: #acb0be; +$cat-surface1: #bcc0cc; +$cat-surface0: #ccd0da; +$cat-base: #eff1f5; +$cat-mantle: #e6e9ef; +$cat-crust: #dce0e8; diff --git a/home-manager/jwm/eww/theme_cat_mocha.scss b/home-manager/jwm/eww/theme_cat_mocha.scss new file mode 100644 index 0000000..0fa15c6 --- /dev/null +++ b/home-manager/jwm/eww/theme_cat_mocha.scss @@ -0,0 +1,26 @@ +$cat-rosewater: #f5e0dc; +$cat-flamingo: #f2cdcd; +$cat-pink: #f5c2e7; +$cat-mauve: #cba6f7; +$cat-red: #f38ba8; +$cat-maroon: #eba0ac; +$cat-peach: #fab387; +$cat-yellow: #f9e2af; +$cat-green: #a6e3a1; +$cat-teal: #94e2d5; +$cat-sky: #89dceb; +$cat-sapphire: #74c7ec; +$cat-blue: #89b4fa; +$cat-lavender: #b4befe; +$cat-text: #cdd6f4; +$cat-subtext1: #bac2de; +$cat-subtext0: #a6adc8; +$cat-overlay2: #9399b2; +$cat-overlay1: #7f849c; +$cat-overlay0: #6c7086; +$cat-surface2: #585b70; +$cat-surface1: #45475a; +$cat-surface0: #313244; +$cat-base: #1e1e2e; +$cat-mantle: #181825; +$cat-crust: #11111b; diff --git a/home-manager/jwm/eww/theme_jwm.scss b/home-manager/jwm/eww/theme_jwm.scss new file mode 100644 index 0000000..13e2e13 --- /dev/null +++ b/home-manager/jwm/eww/theme_jwm.scss @@ -0,0 +1,3 @@ +$jwm-accent: $cat-green; +$jwm-accent2: $cat-blue; +$jwm-accent-contrast: $cat-crust; diff --git a/home-manager/jwm/kanshi.nix b/home-manager/jwm/kanshi.nix new file mode 100644 index 0000000..9c52ecf --- /dev/null +++ b/home-manager/jwm/kanshi.nix @@ -0,0 +1,84 @@ +{ config, lib, pkgs, ... }: + +with lib; +with builtins; + +let cfg = config.jainawm.kanshi; +in { + options.jainawm.kanshi = { enable = mkEnableOption "Enable kanshi config"; }; + + config = mkIf cfg.enable { + wayland.windowManager.sway.config.startup = [{ + command = "${pkgs.kanshi}/bin/kanshictl reload"; + always = true; + }]; + home.packages = [ pkgs.kanshi ]; + services.kanshi = { + enable = true; + profiles = let + laptop = "eDP-1"; + asus1440 = "Ancor Communications Inc ASUS MG278 0x00001EC0"; + hp1080 = "HP Inc. HP 24mh 3CM2023MLQ "; + #asus1440 = "DP-3"; + #hp1080 = "DP-2"; + in { + undocked = { + outputs = [{ + criteria = laptop; + mode = "1920x1200"; + }]; + }; + + undocked-game = { + outputs = [{ + criteria = laptop; + mode = "1920x1080"; + transform = "normal"; + status = "enable"; + }]; + }; + + docked = let + # asusCoords = { + # x = 0; + # y = 0; + # }; + asusCoords = { + x = 1080; + y = 100; + }; + mkPosition = x: y: + "${toString (asusCoords.x + x)},${toString (asusCoords.y + y)}"; + in { + outputs = [ + { + criteria = laptop; + mode = "1920x1200"; + #position = "3640,1080"; + position = mkPosition 2560 980; + transform = "normal"; + status = "enable"; + } + { + criteria = asus1440; + mode = "2560x1440"; # TODO: figure out 144Hz + #position = "1080,100"; + position = mkPosition 0 0; + transform = "normal"; + status = "enable"; + } + { + criteria = hp1080; + mode = "1920x1080"; + #position = "0,0"; + #position = "-1080,100"; + position = mkPosition (-1080) 100; + transform = "90"; + status = "enable"; + } + ]; + }; + }; + }; + }; +} diff --git a/home-manager/jwm/phelper.nix b/home-manager/jwm/phelper.nix new file mode 100644 index 0000000..7fc0270 --- /dev/null +++ b/home-manager/jwm/phelper.nix @@ -0,0 +1,152 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.jainawm; + cat = cfg.catppuccin; + profileDir = "${config.xdg.stateHome}/phelper"; + profilePath = "${profileDir}/active-profile"; + +in { + options.jainawm.phelper = { + enable = mkOption { + type = types.bool; + default = true; + }; + + defaultProfile = mkOption { type = types.str; }; + specialisationProfile = mkOption { + type = types.nullOr types.str; + default = null; + }; + makeSpecializations = mkOption { + type = types.bool; + default = false; + }; + + profiles = mkOption { + type = types.attrsOf (types.submodule { + options = { + name = mkOption { type = types.str; }; + + displayName = mkOption { + type = types.nonEmptyStr; + description = '' + Display name to use for the profile. + ''; + }; + + nicknames = mkOption { + type = types.listOf types.str; + default = [ ]; + }; + + accents = let + colorType = types.enum [ + "Rosewater" + "Flamingo" + "Pink" + "Mauve" + "Red" + "Maroon" + "Peach" + "Yellow" + "Green" + "Teal" + "Sky" + "Sapphire" + "Blue" + "Lavender" + ]; + in { + primary = mkOption { + type = colorType; + description = "The primary accent to use."; + }; + secondary = mkOption { + type = colorType; + description = "The secondary accent to use."; + }; + }; + + wallpaper = mkOption { type = types.path; }; + }; + }); + }; + }; + + config = let + useDefault = builtins.isNull cfg.phelper.specialisationProfile; + activeProfileName = if !useDefault then + cfg.phelper.specialisationProfile + else + cfg.phelper.defaultProfile; + activeProfile = getAttr activeProfileName cfg.phelper.profiles; + in mkIf cfg.phelper.enable { + jainawm = { + wallpaper = activeProfile.wallpaper; + accents = activeProfile.accents; + }; + + assertions = [{ + assertion = config.xdg.userDirs.enable; + message = "xdg.userDirs.enable must be set"; + }]; + + home.activation.phelperSetProfile = + let path = "${config.xdg.stateHome}/phelper/active-profile"; + in lib.hm.dag.entryAfter [ "writeBoundary" ] '' + $DRY_RUN_CMD mkdir -p "${config.xdg.stateHome}/phelper" + $DRY_RUN_CMD echo "${activeProfile.name}" > "${path}" + ''; + + # When switching to a "base" (not a profile specialisation) generation, + # keep track of what the + home.activation.phelperTrackSpecialization = lib.mkDefault + (lib.hm.dag.entryAfter [ "writeBoundary" ] '' + $DRY_RUN_CMD rm -f "${config.xdg.stateHome}/phelper/base-generation" + $DRY_RUN_CMD ${pkgs.coreutils}/bin/ln -s "$( + ${pkgs.home-manager}/bin/home-manager generations | \ + ${pkgs.coreutils}/bin/head -n1 | \ + ${pkgs.gawk}/bin/awk '{ print $7; }' + )" \ + "${config.xdg.stateHome}/phelper/base-generation" + ''); + + specialisation = mkIf useDefault (mapAttrs (n: c: { + configuration = { + jainawm.phelper.specialisationProfile = n; + home.activation.phelperTrackSpecialization = + lib.hm.dag.entryAnywhere ""; + }; + }) cfg.phelper.profiles); + + xdg.configFile = let + mkFiles = name: profile: { + "phelper/profiles/${name}/name".text = profile.name; + "phelper/profiles/${name}/display-name".text = profile.displayName; + "phelper/profiles/${name}/nicknames".text = + lib.concatStringsSep "\n" profile.nicknames; + "phelper/profiles/${name}/wallpaper".source = profile.wallpaper; + "phelper/profiles/${name}/wallpaper.${ + builtins.unsafeDiscardStringContext + (lib.lists.last (lib.strings.splitString "." profile.wallpaper)) + }".source = profile.wallpaper; + }; + in lists.foldl lib.trivial.mergeAttrs { } + (mapAttrsToList mkFiles cfg.phelper.profiles); + + home.packages = let + pkg = pkgs.stdenv.mkDerivation { + name = "phelper-tools"; + + dontUnpack = true; + + installPhase = '' + mkdir -p "$out/bin" + cp "${./phelper/phelper.sh}" "$out/bin/phelper" + ''; + }; + in [ pkg ]; + }; +} diff --git a/home-manager/jwm/phelper/phelper.sh b/home-manager/jwm/phelper/phelper.sh new file mode 100755 index 0000000..f56eca9 --- /dev/null +++ b/home-manager/jwm/phelper/phelper.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +profile_dir="$XDG_CONFIG_HOME/phelper/profiles" +active_profile_file="$XDG_STATE_HOME/phelper/active-profile" + +get_option () { + what="$1" + who="$2" + if [ -z "$who" ]; then + who="$(phelper who)" + fi + + path="$profile_dir/$who" + + case "$what" in + "display-name") cat "$path/display-name" ;; + "wallpaper") echo "$path/wallpaper" ;; + "nicknames") cat "$path/nicknames" ;; + #"theme_color") echo "$theme_color" ;; + *) + echo "Unknown var" + exit 1 + ;; + esac +} + +do_switch () { + who="$1" + file="$XDG_STATE_HOME/phelper/base-generation/specialisation/$who/activate" + if [ -e "$file" ]; then + "$file" + else + echo "Profile $who not setup" + exit 1 + fi +} + +arg="$1" +shift 1 +case "$arg" in + "list") ls -1 "$profile_dir" ;; + "switch") do_switch "$@" ;; + "who") cat "$active_profile_file" ;; + "get") get_option "$@" ;; +esac + diff --git a/home-manager/jwm/ptray.nix b/home-manager/jwm/ptray.nix new file mode 100644 index 0000000..aa61f74 --- /dev/null +++ b/home-manager/jwm/ptray.nix @@ -0,0 +1,69 @@ +{ lib, pkgs, config, ... }: + +with lib; +with builtins; + +let cfg = config.jainawm.ptray; +in { + options.jainawm.ptray = { + enable = mkEnableOption "Enable ptray support"; + items = mkOption { + type = types.anything; + default = { }; + }; + + style = mkOption { + type = types.listOf types.str; + default = [ + "floating enable" + "opacity 0.97" + "resize set 80ppt 80ppt" + "move position 10ppt -10" + "sticky enable" + ]; + }; + + finalPackage = mkOption { + type = types.package; + readOnly = true; + }; + }; + + config = mkIf cfg.enable { + wayland.windowManager.sway.config.window.commands = let + mkRules = let + style = concatStringsSep ",, " cfg.style; + mkRulesForClass = class: [ + ({ + command = style; + criteria = { class = class; }; + }) + ({ + command = style; + criteria = { app_id = class; }; + }) + ]; + in name: item: map mkRulesForClass item.match_classes; + in lists.flatten (mapAttrsToList mkRules cfg.items); + wayland.windowManager.sway.config.startup = + [{ command = "${cfg.finalPackage}/bin/ptray"; }]; + + jainawm.ptray.finalPackage = + # prob not the right way to do this but i don't really care + let python = pkgs.python311; + in python.pkgs.buildPythonPackage { + name = "jwm-ptray"; + version = "0.1"; + + src = ./ptray; + + doCheck = false; + + propagatedBuildInputs = with python.pkgs; [ inotify ]; + }; + + xdg.configFile."ptray/config.json".text = + builtins.toJSON ({ items = cfg.items; }); + home.packages = [ cfg.finalPackage ]; + }; +} diff --git a/home-manager/jwm/ptray/config.py b/home-manager/jwm/ptray/config.py new file mode 100644 index 0000000..697e182 --- /dev/null +++ b/home-manager/jwm/ptray/config.py @@ -0,0 +1,18 @@ +import os +import json + +CONFIG_FILE = os.path.join(os.getenv('XDG_CONFIG_HOME'), 'ptray', 'config.json') + +DESKTOP = os.getenv('XDG_CURRENT_DESKTOP') + +if DESKTOP == 'i3' or DESKTOP == 'sway': + STATE_DIR = '{}.{}'.format(os.getenv('I3SOCK'), 'ptray') +elif DESKTOP == "hyprland": + STATE_DIR = '{}/{}.ptray'.format(os.getenv("XDG_RUNTIME_DIR"), os.getenv("HYPRLAND_INSTANCE_SIGNATURE")) +else: + raise ValueError('Unsupported value of XDG_CURRENT_DESKTOP: {}'.format(DESKTOP)) + +def read_config(path=CONFIG_FILE): + with open(path, 'r') as f: + config = json.load(f) + return config diff --git a/home-manager/jwm/ptray/hyprland/__init__.py b/home-manager/jwm/ptray/hyprland/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/home-manager/jwm/ptray/hyprland/protocol.py b/home-manager/jwm/ptray/hyprland/protocol.py new file mode 100644 index 0000000..680476a --- /dev/null +++ b/home-manager/jwm/ptray/hyprland/protocol.py @@ -0,0 +1,117 @@ +import os +import socket +import json +from typing import NamedTuple, Any + +HYPR = "/tmp/hypr/{}".format(os.getenv("HYPRLAND_INSTANCE_SIGNATURE")) + +COMMANDSOCK = "{}/.socket.sock".format(HYPR) +EVENTSOCK = "{}/.socket2.sock".format(HYPR) + +BUF_SIZE = 2 ** 20 + +class EventType(Enum): + WORKSPACE = "workspace" + FOCUSED_MON = "focusedmon" + ACTIVE_WINDOW = "activewindow" + ACTIVE_WINDOW_V2 = "activewindowv2" + FULLSCREEN = "fullscreen" + MONITOR_REMOVED = "monitorremoved" + MONITOR_ADDED = "monitoradded" + CREATE_WORKSPACE = "createworkspace" + DESTROY_WORKSPACE = "destroyworkspace" + MOVE_WORKSPACE = "moveworkspace" + ACTIVE_LAYOUT = "activelayout" + OPEN_WINDOW = "openwindow" + CLOSE_WINDOW = "closewindow" + MOVE_WINDOW = "movewindow" + OPEN_LAYER = "openlayer" + CLOSE_LAYER = "closelayer" + SUBMAP = "submap" + CHANGE_FLOATING_MODE = "changefloatingmode" + URGENT = "urgent" + MINIMIZE = "minimize" + SCREENCAST = "screencast" + WINDOW_TITLE = "windowtitle" + +class Event(NamedTuple): + type : EventType + value : str + +def subscribe(sockfile=EVENTSOCK): + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM | socket.SOCK_CLOEXEC) + sock.connect(sockfile) + + while True: + msg = sock.recvmsg(BUF_SIZE)[0] + type, value = msg.split('>>', 1) + + return Event(type=type, value=value) + +def hyprctl(cmd, sockfile=COMMANDSOCK): + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM | socket.SOCK_CLOEXEC) + try: + sock.connect(sockfile) + + header = 'j/'.encode('utf-8') + payload = cmd.encode('utf-8') + + sock.sendmsg([header, payload]) + + msg = sock.recvmsg(BUF_SIZE)[0] + finally: + sock.close() + + return json.loads(msg) + +print(json.dumps(hyprctl('clients'))) + +class Monitor: + event_handler = None + tracked_classes = None + + window_ids = None + + def __init__(self, event_handler, tracked_classes): + self.event_handler = event_handler + self.tracked_classes = tracked_classes + self.window_ids = {name: set() for name in tracked_classes} + + windows = hyprctl('clients') + monitors = hyprctl('monitors') + open_workspaces = [m['specialWorkspace']['id'] for m in monitors] + for window in windows: + for name: classes in tracked_classes.items(): + for cls in classes: + if cls in window['class']: + id = window['address'] + self.event_handler.on_create(name, id) + self.window_ids[name].add(id) + + workspace_id = window['workspace']['id'] + if workspace_id < 0: + self.event_handler.on_float(name, id) + if workspace_id in open_workspaces: + self.event_handler.on_visible(name, id) + else: + self.event_handler.on_invisible(name, id) + else: + self.event_handler.on_tile(name, id) + self.event_handler.on_visible(name, id) + + def listen(self): + for event in subscribe(): + self.handle_event(event) + + def match_window_id_to_name(self, id): + for name, ids in self.window_ids.items(): + if id in ids: + return name + return None + + def handle_event(self, event): + if event == EventType.MOVE_WINDOW: + id, workspace = event.split(',', 1) + if workspace.startsWith('special'): + self.even + movewindow>>2700e80,special:3 diff --git a/home-manager/jwm/ptray/i3sway/__init__.py b/home-manager/jwm/ptray/i3sway/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/home-manager/jwm/ptray/i3sway/__init__.py @@ -0,0 +1 @@ + diff --git a/home-manager/jwm/ptray/i3sway/commands.py b/home-manager/jwm/ptray/i3sway/commands.py new file mode 100644 index 0000000..8653997 --- /dev/null +++ b/home-manager/jwm/ptray/i3sway/commands.py @@ -0,0 +1,30 @@ +from i3sway.protocol import Connection, ConnType + +class Client: + conn = None + def __init__(self): + self.conn = Connection() + + def __enter__(self): + return self + + def __exit__(self, *details): + self.conn.close() + + def cmd_on_window(self, id, cmd): + if self.conn.type == ConnType.SWAY: + criteria = '[con_id={}]'.format(id) + else: + criteria = '[id={}]'.format(id) + + return self.conn.exec('{} {}'.format(criteria, cmd)) + + def show_window(self, id): + self.cmd_on_window(id, "focus") + + def hide_window(self, id): + self.cmd_on_window(id, "move to scratchpad") + + def run(self, command): + self.conn.exec("exec {}".format(command)) + diff --git a/home-manager/jwm/ptray/i3sway/monitor.py b/home-manager/jwm/ptray/i3sway/monitor.py new file mode 100644 index 0000000..087add9 --- /dev/null +++ b/home-manager/jwm/ptray/i3sway/monitor.py @@ -0,0 +1,112 @@ +from i3sway.protocol import Connection, MessageType + +class Monitor: + tracked_classes = None + cmd_sock = None + subscription_sock = None + event_handler = None + conn_type = None + + def __enter__(self): + return self + + def __exit__(self, *details): + self.cmd_sock.close() + self.subscription_sock.close() + + def __init__(self, event_handler, tracked_classes): + self.event_handler = event_handler + self.tracked_classes = tracked_classes + + self.cmd_sock = Connection() + self.subscription_sock = Connection() + + tree = self.cmd_sock.request(MessageType.GET_TREE).payload + + def parse_tree(root): + if root.get('window') is not None or root.get('app_id') is not None: + # Application window + for name, classes in tracked_classes.items(): + if self.container_matches_classes(root, classes): + id = str(root['id']) + self.event_handler.on_create(name, id) + if root['visible']: + self.event_handler.on_visible(name, id) + + if root['type'] == 'floating_con': + self.event_handler.on_float(name, id) + elif root['type'] == 'con': + self.event_handler.on_tile(name, id) + else: + for node in root['nodes']: + parse_tree(node) + for node in root['floating_nodes']: + parse_tree(node) + + parse_tree(tree) + + def container_matches_classes(self, container, classes): + normalize = lambda v: v.lower() if v is not None else '' + app_id = container.get('app_id') + window_props = container.get('window_properties') + instance = window_props.get('instance') if window_props is not None else None + window_class = window_props.get('class') if window_props is not None else None + + app_id = normalize(app_id) + instance = normalize(instance) + window_class = normalize(window_class) + for keyword in classes: + kw = normalize(keyword) + if kw in app_id or kw in instance or kw in window_class: + return True + + return False + + def listen(self): + for event in self.subscription_sock.subscribe(['window']): + self.handle_event(event) + + def is_window_in_scratchpad(self, id): + def scan_tree(root, is_in_scratch): + if root['id'] == id: + return is_in_scratch + is_scratch = is_in_scratch or ( + root['type'] == 'workspace' and root['name'] == '__i3_scratch' + ) + for node in root['nodes'] + root['floating_nodes']: + result = scan_tree(node, is_scratch) + if result is not None: + return result + + tree = self.cmd_sock.request(MessageType.GET_TREE) + return scan_tree(tree.payload, False) + + def handle_event(self, event): + if event.type == MessageType.window: + return self.handle_window_event(event) + + def handle_window_event(self, event): + container = event['container'] + + for name, classes in self.tracked_classes.items(): + change = event['change'] + if self.container_matches_classes(container, classes): + id = str(container['id']) + if change == 'new': + self.event_handler.on_create(name, id) + elif change == 'focus': + self.event_handler.on_visible(name, id) + elif change == 'close': + self.event_handler.on_destroy(name, id) + elif change == 'move': + if container['visible']: + self.event_handler.on_visible(name, id) + else: + self.event_handler.on_invisible(name, id) + elif change == 'floating': + if container['type'] == 'floating_con': + self.event_handler.on_float(name, id) + elif container['type'] == 'con': + self.event_handler.on_tile(name, id) + + diff --git a/home-manager/jwm/ptray/i3sway/protocol.py b/home-manager/jwm/ptray/i3sway/protocol.py new file mode 100644 index 0000000..0b56cc7 --- /dev/null +++ b/home-manager/jwm/ptray/i3sway/protocol.py @@ -0,0 +1,133 @@ +import json +import socket +import struct +import os + +from enum import Enum, IntEnum +from typing import NamedTuple, Any + +class ConnType(Enum): + SWAY = 'sway' + I3 = 'i3' + +SWAYSOCK = os.getenv('SWAYSOCK') +I3SOCK = os.getenv('I3SOCK') + +class MessageType(IntEnum): + # Commands / Replies + RUN_COMMAND = 0 + GET_WORKSPACES = 1 + SUBSCRIBE = 2 + GET_OUTPUTS = 3 + GET_TREE = 4 + GET_MARKS = 5 + GET_BAR_CONFIG = 6 + GET_VERSION = 7 + GET_BINDING_NODES = 8 + GET_CONFIG = 9 + SEND_TICK = 10 + SYNC = 11 + GET_BINDING_STATE = 12 + GET_INPUTS = 100 + GET_SEATS = 101 + + # Events + workspace = 0x80000000 + mode = 0x80000002 + window = 0x80000003 + barconfig_update = 0x80000004 + binding = 0x80000005 + shutdown = 0x80000006 + tick = 0x80000007 + bar_state_update = 0x80000014 + input = 0x80000015 + +class Message(NamedTuple): + type : MessageType + payload : Any + + MAGIC = 'i3-ipc'.encode('utf-8') + HEADER_FORMAT = '=6sII' + HEADER_LEN = struct.calcsize(HEADER_FORMAT) + + def accept(sock): + header = sock.recvmsg(Message.HEADER_LEN)[0] + magic, len, type = struct.unpack(Message.HEADER_FORMAT, header) + if magic != Message.MAGIC: + raise ValueError('Protocol error, expected magic value {}, got magic value {}' % (Message.MAGIC, magic)) + + payload_buf = sock.recvmsg(len)[0] + payload = json.loads(payload_buf) + + return Message(type=type, payload=payload) + + def send(self, sock): + if self.payload is None: + payload_buf = bytes([]) + elif isinstance(self.payload, str): + payload_buf = self.payload.encode('utf-8') + else: + payload_buf = json.dumps(self.payload).encode('utf-8') + payload_len = len(payload_buf) + + header = struct.pack(Message.HEADER_FORMAT, Message.MAGIC, payload_len, self.type) + sock.sendmsg([header, payload_buf]) + + def __getitem__(self, key): + return self.payload[key] + +class Connection: + sock: socket.socket + type: ConnType + subscription_open: bool = False + + def __init__(self, type=None, sockfile=None): + self.type = type + if sockfile is None: + if type == ConnType.SWAY or (type is None and SWAYSOCK is not None): + sockfile = SWAYSOCK + self.type = ConnType.SWAY + elif type == ConnType.I3 or (type is None and I3SOCK is not None): + sockfile = I3SOCK + self.type = ConnType.I3 + else: + raise ValueError('No compatible window managers found') + + self.sock = socket.socket( + socket.AF_UNIX, + socket.SOCK_STREAM,# | socket.SOCK_NONBLOCK | socket.SOCK_CLOEXEC, + ) + self.sock.connect(sockfile) + + def __enter__(self): + return self + def __exit__(self, *details): + self.close() + + def close(self): + self.sock.close() + + def subscribe(self, events: list): + if self.subscription_open: + raise ValueError('Subscription already open on socket') + + reply = self.request(MessageType.SUBSCRIBE, events) + if not reply['success']: + raise ValueError('Subscription failed') + + self.subscription_open = True + while True: + yield Message.accept(self.sock) + + def exec(self, command: str): + return self.request(MessageType.RUN_COMMAND, command) + + def request(self, type: MessageType, payload: Any = None) -> Message: + if self.subscription_open: + raise ValueError('Subscription open on socket') + message = Message(type=type, payload=payload) + message.send(self.sock) + reply = Message.accept(self.sock) + if reply.type != type: + print('Incorrect reply type', reply.type) + return reply diff --git a/home-manager/jwm/ptray/ptray b/home-manager/jwm/ptray/ptray new file mode 100755 index 0000000..c22768c --- /dev/null +++ b/home-manager/jwm/ptray/ptray @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +from i3sway.monitor import Monitor +from config import read_config +from state import StateWriter + +""" +{ + "items": { + "discord": { + "match_class": [ "discord" "WebCord" ], + "exec": "webcord", + }, + }, +} +""" + +config = read_config() + +state = StateWriter(config) +class_map = {name: defn['match_classes'] for name, defn in config['items'].items()} +with Monitor(state, class_map) as wm: + wm.listen() diff --git a/home-manager/jwm/ptray/ptrayctl b/home-manager/jwm/ptray/ptrayctl new file mode 100755 index 0000000..98fc2c2 --- /dev/null +++ b/home-manager/jwm/ptray/ptrayctl @@ -0,0 +1,96 @@ +#!/usr/bin/env python + +import os +import argparse +import inotify.adapters +from i3sway.commands import Client +from config import read_config +from state import open_file, format_path + +parser = argparse.ArgumentParser( + prog='ptrayctl', + description='manages user pseudo-tray', +) + +parser.add_argument('command', choices=['show', 'hide', 'watch', 'toggle']) +parser.add_argument('name', nargs='?') +parser.add_argument('-a', '--all', action='store_true', help='Include windows that are not floating') + +args = parser.parse_args() +config = read_config() + +def show_window(name): + with Client() as client: + is_open = False + with open_file(name, 'window_ids') as f: + for line in f: + is_open = True + client.show_window(int(line)) + if not is_open: + with open_file(name, 'exec') as f: + client.run(f.read()) + +def hide_window(name): + if not args.all: + with open_file(name, 'tiled_ids') as f: + ignore_ids = f.read().split('\n') + else: + ignore_ids = [] + + with Client() as client: + with open_file(name, 'window_ids') as f: + for line in f: + if line not in ignore_ids: + client.hide_window(int(line)) + +def hide_all(): + for name in config['items']: + hide_window(name) + +def toggle_window(name): + with open_file(name, 'status') as f: + status = f.read() + if status == 'fg': + hide_window(name) + else: + show_window(name) + +def watch_window(name): + i = inotify.adapters.Inotify() + i.add_watch(format_path(name, '')) + def read_status(): + with open_file(name, 'status') as f: + return f.read() + + status = read_status() + print(status, flush=True) + + for event in i.event_gen(yield_nones=False): + (_, type_names, _, filename) = event + if 'IN_CLOSE_WRITE' in type_names and filename == 'status': + new_status = read_status() + if status != new_status: + print(new_status, flush=True) + status = new_status + +if args.command == 'show': + if args.name is None: + raise ValueError('name must be specified for show commands') + + show_window(args.name) +elif args.command == 'hide': + if args.name is None: + hide_all() + else: + hide_window(args.name) +elif args.command == 'toggle': + if args.name is None: + raise ValueError('name must be specified for toggle commands') + + toggle_window(args.name) +elif args.command == 'watch': + if args.name is None: + raise ValueError('name must be specified for watch commands') + + watch_window(args.name) + diff --git a/home-manager/jwm/ptray/requirements.txt b/home-manager/jwm/ptray/requirements.txt new file mode 100644 index 0000000..5d47832 --- /dev/null +++ b/home-manager/jwm/ptray/requirements.txt @@ -0,0 +1 @@ +inotify diff --git a/home-manager/jwm/ptray/setup.py b/home-manager/jwm/ptray/setup.py new file mode 100644 index 0000000..99f2604 --- /dev/null +++ b/home-manager/jwm/ptray/setup.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +from distutils.core import setup + +setup( + name='ptray', + version='0.1', + scripts=[ 'ptray', 'ptrayctl' ], + packages=['', 'i3sway'], +) diff --git a/home-manager/jwm/ptray/state.py b/home-manager/jwm/ptray/state.py new file mode 100644 index 0000000..bc7c3fa --- /dev/null +++ b/home-manager/jwm/ptray/state.py @@ -0,0 +1,85 @@ +import os +from config import STATE_DIR + +def format_path(name, property): + return '{}/{}/{}'.format(STATE_DIR, name, property) + + +def write_file(dir, basename, content): + os.makedirs('{}/{}'.format(STATE_DIR, dir), exist_ok=True) + path = format_path(dir, basename) + with open(path, 'w') as f: + f.write(content) + +def open_file(dir, basename): + path = format_path(dir, basename) + return open(path, 'r') + +def add_window(tracking: dict, name, window_id: str): + new_dict = tracking.copy() + new_dict[name] = new_dict.get(name, set()) | {window_id} + return new_dict + +def remove_window(tracking: dict, name, window_id: str): + new_dict = tracking.copy() + new_dict[name] = new_dict.get(name, set()) - {window_id} + return new_dict + +def read_config(path): + with open(path, 'r') as f: + config = json.load(f) + return config + +class StateWriter: + tracked_ids = None + visible_ids = None + config = None + + def __init__(self, config): + self.config = config + self.tracked_ids = {name: set() for name in config['items'].keys()} + self.visible_ids = {name: set() for name in config['items'].keys()} + self.tiled_ids = {name: set() for name in config['items'].keys()} + for name, defn in config['items'].items(): + write_file(name, 'exec', defn['exec']) + write_file(name, 'status', '') + write_file(name, 'window_ids', '') + + def update_window_state(self, name): + if len(self.visible_ids[name]) != 0: + write_file(name, 'status', 'fg') + elif len(self.tracked_ids[name]) != 0: + write_file(name, 'status', 'bg') + else: + write_file(name, 'status', '') + + write_file(name, 'window_ids', '\n'.join(self.tracked_ids[name])) + write_file(name, 'tiled_ids', '\n'.join(self.tiled_ids[name])) + + def on_visible(self, item_name, window_id, tiled=False): + self.visible_ids[item_name] = self.visible_ids[item_name] | {window_id} + self.update_window_state(item_name) + + def on_invisible(self, item_name, window_id): + self.visible_ids[item_name] = self.visible_ids[item_name] - {window_id} + self.update_window_state(item_name) + + def on_create(self, item_name, window_id): + self.tracked_ids[item_name] = self.tracked_ids[item_name] | {window_id} + self.update_window_state(item_name) + + def on_destroy(self, item_name, window_id): + self.tracked_ids[item_name] = self.tracked_ids[item_name] - {window_id} + self.visible_ids[item_name] = self.visible_ids[item_name] - {window_id} + self.tiled_ids[item_name] = self.tiled_ids[item_name] - {window_id} + self.update_window_state(item_name) + + def on_tile(self, item_name, window_id): + self.tiled_ids[item_name] = self.tiled_ids[item_name] | {window_id} + self.update_window_state(item_name) + + def on_float(self, item_name, window_id): + self.tiled_ids[item_name] = self.tiled_ids[item_name] - {window_id} + self.update_window_state(item_name) + + diff --git a/home-manager/jwm/rofi.nix b/home-manager/jwm/rofi.nix new file mode 100644 index 0000000..dfa451e --- /dev/null +++ b/home-manager/jwm/rofi.nix @@ -0,0 +1,126 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.jainawm; + cat = cfg.catppuccin; +in { + options.jainawm.rofi = { + enable = mkOption { + type = types.bool; + default = true; + }; + + font = mkOption { type = lib.hm.types.fontType; }; + + accents = { + primary = mkOption { type = types.str; }; + secondary = mkOption { type = types.str; }; + }; + }; + + config = { + programs.rofi = let font = cfg.rofi.font; + in { + enable = true; + package = pkgs.rofi-wayland; + plugins = with pkgs; [ rofi-emoji ]; + font = "${font.name} ${builtins.toString font.size}"; + location = "top-left"; + + cycle = true; + terminal = cfg.terminal.binPath; + xoffset = 10; + yoffset = 10; + + theme = let + font = cfg.fonts.wmOverlay; + inherit (config.lib.formats.rasi) mkLiteral; + in { + "*" = { + transparency = "real"; + background-color = mkLiteral "#00000000"; + text-color = mkLiteral cat.text; + }; + + configuration = { + show-icons = true; + # drun = { + # display-name = ""; + # }; + }; + + window = { + background-color = mkLiteral "${cat.base}cc"; + border = mkLiteral "3px"; + border-color = mkLiteral cfg.rofi.accents.primary; + border-radius = mkLiteral "10px"; + x-offset = mkLiteral "10px"; + y-offset = mkLiteral "10px"; + width = mkLiteral "500px"; + location = mkLiteral "northwest"; + }; + + mainbox = { padding = mkLiteral "1em"; }; + + inputbar = { + margin = mkLiteral "0px 5px"; + children = [ (mkLiteral "prompt") (mkLiteral "entry") ]; + }; + + prompt = { vertical-align = mkLiteral "0.5"; }; + + entry = { + border-radius = mkLiteral "100%"; + padding = mkLiteral "5px 15px"; + margin = mkLiteral "0px 0px 0px 10px"; + background-color = mkLiteral "${cat.overlay0}cc"; + vertical-align = mkLiteral "0.5"; + }; + + message = { + horizontal-align = mkLiteral "1.0"; + text-color = mkLiteral cat.subtext0; + margin = mkLiteral "0px 5px"; + }; + + textbox = { + horizontal-align = mkLiteral "inherit"; + text-color = mkLiteral "inherit"; + }; + + listview = { + margin = mkLiteral "15px 0px 0px 0px"; + lines = 10; + fixed-height = false; + dynamic = true; + cycle = false; + }; + + element = { + border-radius = mkLiteral "4px"; + padding = mkLiteral "5px"; + }; + + "element.active" = { + #background-color = mkLiteral "${cat.overlay0}cc"; + border = mkLiteral "2px"; + border-color = mkLiteral cfg.rofi.accents.secondary; + }; + + "element.selected" = { + background-color = mkLiteral cfg.rofi.accents.primary; + text-color = mkLiteral cat.base; + }; + + element-icon = { size = mkLiteral "20px"; }; + + element-text = { + text-color = mkLiteral "inherit"; + vertical-align = mkLiteral "0.5"; + margin = mkLiteral "0px 0px 0px 5px"; + }; + }; + }; + }; +} diff --git a/home-manager/jwm/sway.nix b/home-manager/jwm/sway.nix new file mode 100644 index 0000000..dfa85b5 --- /dev/null +++ b/home-manager/jwm/sway.nix @@ -0,0 +1,213 @@ +{ config, lib, pkgs, nixpkgs, ... }: + +with lib; +let + cfg = config.jainawm; + ptray = config.jainawm.ptray.finalPackage; +in { + options.jainawm.sway = { + enable = mkEnableOption "Enable the use of swaywm, a tiling window manager"; + useFx = mkEnableOption "Replace sway with swayfx"; + }; + + config = let cat = cfg.catppuccin; + in mkIf cfg.enable { + + home.packages = with pkgs; [ wlr-randr ]; + wayland.windowManager.sway = { + enable = cfg.sway.enable; + + # package = pkgs.sway.override { + # sway-unwrapped = pkgs.sway-unwrapped.override { + # wlroots_0_16 = pkgs.wlroots_0_16.overrideAttrs (final: prev: { + # pname = prev.pname + "-displaylink"; + # patches = [ + # (pkgs.fetchpatch { + # url = + # "https://gitlab.freedesktop.org/wlroots/wlroots/uploads/b4f932e370ed03d88f202191eaf60965/DisplayLink.patch"; + # sha256 = "sha256-1HheLsOSnj4OMiA35QCHkWprTNgAeG2tXrGbaQyUrF4="; + # }) + # ]; + # }); + # }; + # }; + + package = let c = config.wayland.windowManager.sway; + in mkIf cfg.sway.useFx (pkgs.unstable.sway.override { + sway-unwrapped = pkgs.unstable.swayfx; + extraSessionCommands = c.extraSessionCommands; + extraOptions = c.extraOptions; + withBaseWrapper = c.wrapperFeatures.base; + withGtkWrapper = c.wrapperFeatures.gtk; + }); + + systemd.enable = true; + config = { + modifier = "Mod4"; + bars = [{ command = "waybar"; }]; + gaps.inner = 20; + + fonts = let font = cfg.fonts.primary; + in { + names = [ font.name ]; + # NOTE: add 0.0 to force conversion to floating point rational + # TODO: Need to cast integer to floating point, what's the right way? + size = font.size + 0.0; + }; + + colors = { + focused = { + border = cat.surface2; + background = cat.surface2; + text = cat.text; + indicator = cat.green; + childBorder = cat.surface2; + }; + focusedInactive = { + border = cat.surface1; + background = cat.surface1; + text = cat.subtext1; + indicator = cat.teal; + childBorder = cat.surface1; + }; + unfocused = { + border = cat.surface0; + background = cat.surface0; + text = cat.subtext0; + indicator = cat.teal; + childBorder = cat.surface0; + }; + urgent = { + border = cat.red; + background = cat.maroon; + text = cat.text; + indicator = cat.red; + childBorder = cat.red; + }; + }; + + menu = "${pkgs.rofi-wayland}/bin/rofi -show drun -modes drun,run"; + terminal = cfg.terminal.binPath; + + focus.mouseWarping = true; + focus.wrapping = "yes"; + + keybindings = let + modifier = config.wayland.windowManager.sway.config.modifier; + screenshotRegion = "jwm screenshot-region"; + # swaymsg -t get_tree | jq '.. | select(type == "object") | select (has("type") and (.type == "con" or .type == "floating_con")) | select(.visible) | "\(.rect.x),\(.rect.y) \(.rect.width)x\(.rect.height) \(.name)"' -r | slurp -r | grim -g - - | wl-copy + volUp = "jwm vol 5"; + volDown = "jwm vol -5"; + volMute = "jwm vol toggle-mute"; + brightUp = "jwm bright 5"; + brightDown = "jwm bright -5"; + musPlay = "playerctl play-pause"; + in lib.mkOptionDefault { + "${modifier}+tab" = "workspace next"; + "${modifier}+grave" = "workspace prev"; + "${modifier}+q" = "exec ptrayctl hide"; + "${modifier}+t" = "layout tabbed"; + "${modifier}+p" = "mode command"; + "${modifier}+i" = "mode app"; + + "--locked XF86MonBrightnessUp" = "exec ${brightUp}"; + "--locked XF86MonBrightnessDown" = "exec ${brightDown}"; + + "--locked XF86AudioRaiseVolume" = "exec ${volUp}"; + "--locked XF86AudioLowerVolume" = "exec ${volDown}"; + "--locked XF86AudioMute" = "exec ${volMute}"; + "--locked XF86AudioPlay" = "exec ${musPlay}"; + "--locked XF86AudioNext" = "exec playerctl next"; + "--locked XF86AudioPrev" = "exec playerctl previous"; + "--locked XF86AudioStop" = "exec playerctl stop"; + + "${modifier}+shift+s" = "exec ${screenshotRegion}"; + + "${modifier}+minus" = "floating toggle"; + "${modifier}+shift+equal" = "move to scratchpad"; + "${modifier}+equal" = + "rofi -show scratchpad -modes 'scratchpad:~/.config/rofi/bin/scratchpad'"; + }; + + input = { + "type:keyboard" = { + xkb_options = lib.strings.concatStringsSep "," [ + "altwin:swap_lalt_lwin" + "altwin:menu_win" + ]; + }; + "type:touchpad" = { + dwt = "enabled"; + tap = "enabled"; + natural_scroll = "enabled"; + middle_emulation = "enabled"; + drag = "enabled"; + }; + }; + + window.hideEdgeBorders = "smart"; + + modes = lib.mkOptionDefault { + app = let + discord = "${ptray}/bin/ptrayctl toggle discord"; + keepass = "${ptray}/bin/ptrayctl toggle keepass"; + web = "jwm web-launcher"; + in { + Escape = "mode default"; + Return = "mode default"; + + d = "exec ${discord},, mode default"; + k = "exec ${keepass},, mode default"; + w = "exec ${web},, mode default"; + }; + + command = let + switch = "jwm switch-launcher"; + micMute = "jwm mic toggle-mute"; + lock = "jwm lock"; + typeEmoji = "rofi -show emoji -emoji-mode stdout | xargs wtype"; + in { + Escape = "mode default"; + Return = "mode default"; + + "e" = "exec ${typeEmoji},, mode default"; + m = "exec ${micMute},, mode default"; + s = "exec ${switch},, mode default"; + l = "exec ${lock},, mode default"; + }; + }; + + window.commands = [{ + command = "floating enable,, sticky enable,, opacity 0.9"; + criteria = { title = "Picture-in-Picture"; }; + }]; + + output = { "*" = { bg = lib.mkDefault "${cfg.wallpaper} fill"; }; }; + + seat = { + "*" = { xcursor_theme = "Catppuccin-Mocha-Light-Cursors 32"; }; + }; + + startup = [ + #{ command = ''plhelper switch "$(plhelper who)"''; always = true; } + #{ command = "dropwind"; } + { command = "mako"; } + { + command = "playerctld"; + } + # { + # command = + # "${pkgs.xdg-desktop-portal-wlr}/libexec/xdg-desktop-portal-wlr"; + # always = true; + # } + + ]; + }; + extraConfig = '' + hide_edge_borders --i3 smart + for_window [title=".*"] inhibit_idle fullscreen + ''; + extraOptions = [ "--unsupported-gpu" ]; + }; + }; +} diff --git a/home-manager/jwm/waybar.css b/home-manager/jwm/waybar.css new file mode 100644 index 0000000..4b6239d --- /dev/null +++ b/home-manager/jwm/waybar.css @@ -0,0 +1,146 @@ +* { + font-family: 'Iosevka Comfy Duo, Symbols Nerd Font, Font Awesome'; +} + +window#waybar { + background-color: rgba(0, 0, 0, 0); + box-shadow: inset 0px 8px 5px -5px rgba(17, 17, 27, 0.9); +} + +window#waybar > box.horizontal { + margin: 8px 10px; + margin-bottom: 0px; + + border-radius: 10px; + padding: 5px 10px; + background-color: rgba(17, 17, 27, 0.9); + /* background-color: @theme_unfocused_base_color; */ +} + +box.modules-left > widget > *, +box.modules-left > box, +box.modules-center > widget > *, +box.modules-center > box, +box.modules-right > widget > *, +box.modules-right > box +{ + background-color: @borders; + border-radius: 10px; + margin: 0px 10px; +} + +#tray > widget > image, +box.modules-left widget > *, +box.modules-center widget > *, +box.modules-right widget > * { + padding: 0px 8px; +} + +box.modules-left box widget:first-child > *, +box.modules-center box widget:first-child > *, +box.modules-right box widget:first-child > * { + padding-left: 10px; + border-bottom-left-radius: 10px; + border-top-left-radius: 10px; +} + +box.modules-left box widget:last-child > *, +box.modules-center box widget:last-child > *, +box.modules-right box widget:last-child > * { + padding-right: 10px; + border-bottom-right-radius: 10px; + border-top-right-radius: 10px; +} + + +/* Light up */ +#custom-player-icon.playing, +#workspaces button.focused, +#workspaces button.active { + background-color: @theme_selected_bg_color; + color: @theme_selected_fg_color; +} + +/* Grey out */ +#custom-mpris.paused, +#pulseaudio.input.source-muted { + color: #a6adc8; +} + +/* individual customizations */ +#workspaces { padding: 0px; } +#workspaces button { + font-size: 90%; + min-width: 12px; + padding: 0px 8px; + border-radius: 10px; +} + +#workspaces button.focused, +#workspaces button.active, +#workspaces button:hover { + font-size: 100%; +} + +window#waybar.empty .modules-center > widget > * { + background-color: rgba(0, 0, 0, 0); +} + +#idle_inhibitor.activated { + color: @theme_bg_color; + background-color: @theme_fg_color; +} + +#tray { padding: 0px; } + +#custom-discord.fg { background-color: #7289DA; /* blurple */ } +#custom-discord.bg { background-color: #4E5D94; /* dark blurple*/ } + +#custom-keepass.fg { background-color: #E6A117; } +#custom-keepass.bg { background-color: #B37D12; } + +#pulseaudio.output-icon.muted { color: @error_color; } +#wireplumber.output.muted, #pulseaudio.output.muted { + /*color: @theme_unfocused_text_color;*/ + color: #a6adc8; + text-decoration: line-through; +} +#pulseaudio.input.source-muted { color: #a6adc8; } + +#pulseaudio.output-icon { + padding-right: 0px; + font-size: 18px +} +#wireplumber.output, #pulseaudio.output { + padding-left: 5px; +} +#pulseaudio.input { + padding-left: 5px; +} + +#battery { + padding-left: 4px; + padding-right: 0px; +} +#battery.secondary { + padding: 0px; +} +#battery.critical:not(.charging) { + /*color: #f53c3c;*/ + color: @error_color; + /*color: #ffffff;*/ + animation-name: blink; + animation-duration: 0.5s; + animation-timing-function: linear; + animation-iteration-count: infinite; + animation-direction: alternate; +} +@keyframes blink { + to { + background-color: @theme_fg_color; + color: @theme_bg_color; + } +} +#upower { + padding-left: 0px; +} diff --git a/home-manager/jwm/waybar.nix b/home-manager/jwm/waybar.nix new file mode 100644 index 0000000..bbff0f8 --- /dev/null +++ b/home-manager/jwm/waybar.nix @@ -0,0 +1,225 @@ +{ lib, pkgs, config, ... }: + +with lib; + +let + ptray = config.jainawm.ptray.finalPackage; + watchPtrayIcon = name: displayName: + pkgs.writeShellScript "watchPtrayIcon-${name}" '' + trap 'kill 0' EXIT + ${ptray}/bin/ptrayctl watch ${name} | while read line; do + echo '{"text":"update","tooltip":"${displayName}","class":"'"$line"'"}' + done + ''; +in { + options.jainawm.waybar = { enable = mkEnableOption "Enable waybar"; }; + + config = { + programs.waybar = { + enable = true; + style = builtins.readFile ./waybar.css; + #package = pkgs.unstable.waybar; + settings = [{ + layer = "top"; + position = "top"; + mode = "dock"; + name = "main"; + + modules-left = [ + "sway/workspaces" + "sway/mode" + + "group/musicplayer" + ]; + modules-center = [ "sway/window" ]; + modules-right = [ + "group/tray" + "group/volume" + "group/battery" + + "clock" + ]; + + "group/musicplayer" = { + orientation = "horizontal"; + modules = [ "custom/player-icon" "custom/mpris" ]; + }; + + "group/tray" = { + orientation = "horizontal"; + modules = + [ "idle_inhibitor" "tray" "custom/discord" "custom/keepass" ]; + }; + "tray" = { }; + + "group/volume" = { + orientation = "horizontal"; + modules = + [ "pulseaudio#output-icon" "pulseaudio#output" "pulseaudio#input" ]; + }; + + "group/battery" = { + orientation = "horizontal"; + modules = [ "battery" "upower" ]; + }; + + "custom/player-icon" = + let playerctl = "${pkgs.playerctl}/bin/playerctl --player strawberry"; + in { + format = "{icon}"; + format-icons = ""; + exec = '' + trap 'kill 0' EXIT + ( + echo ""; + ${playerctl} status --follow --format \ + '{"text":"music","class":"{{lc(status)}}","tooltip":"strawberry"}' + ) | ( + while read line; do + if [ -n "$line" ]; then + echo "$line" + else + echo '{"text":"music","tooltip":"strawberry"}' + fi + done + ); + ''; + on-click = '' + ${pkgs.sway}/bin/swaymsg '[app_id=org.strawberrymusicplayer.] focus' >/dev/null \ + || swaymsg exec strawberry + ''; + return-type = "json"; + }; + + "custom/mpris" = + let playerctl = "${pkgs.playerctl}/bin/playerctl --player strawberry"; + in { + format = "{icon} {}"; + format-icons = { + playing = ""; + paused = ""; + }; + exec = let + playerctlFormat = '' + {"title":"{{title}}","artist":"{{artist}}","album":"{{album}}","position":"{{duration(position)}}","length":"{{duration(mpris:length)}}","status":"{{lc(status)}}"}''; + jqFilter = '' + def escape: . | gsub("&"; "&") | gsub("<"; "<") | gsub(">"; ">"); + try ( + . + { + mainText: ("\([.title,.artist,.album] | map(select(length > 0)) | join(" - "))") | escape, + progressText: ((select((.position | length) > 0 and (.length | length > 0)) | "[\(.position)/\(.length)]" | escape) // "") + } | . + { + progress: ((. | select(.progressText | length > 0) | " \(.progressText)") // "") + } | { + text: (.mainText + .progress), + alt: (.status) + } | { text, alt, tooltip: (.text), class: (.alt) } + ) catch "" + ''; + mainFormat = + "{{title}} - {{artist}} - {{album}} [{{duration(position)}}/{{duration(mpris:length)}}]"; + in '' + trap 'kill 0' EXIT + ${playerctl} metadata --follow --format '${playerctlFormat}' | ( + # playerctl has a bug where it only shows that a stopped stream has stopped after it starts again. but it does spit out an empty line. so we do a lot of work special-casing those + while read line; do + if [ -n "$line" ]; then echo "$line"; else echo '" "'; fi + done + ) | jq '${jqFilter}' --unbuffered --compact-output --raw-output + ''; + max-length = 80; + on-click = "${playerctl} play-pause"; + on-click-middle = "${playerctl} previous"; + on-click-right = "${playerctl} next"; + return-type = "json"; + }; + + idle_inhibitor = { + format = "{icon}"; + format-icons = { + activated = ""; + deactivated = ""; + }; + tooltip-format-activated = "Idle inhibitor enabled"; + tooltip-format-deactivated = "Idle inhibitor disabled"; + }; + + "custom/discord" = { + format = ""; + exec = watchPtrayIcon "discord" "Discord"; + on-click = "${ptray}/bin/ptrayctl toggle discord"; + restart-interval = 5; + return-type = "json"; + }; + + "custom/keepass" = { + format = ""; + exec = watchPtrayIcon "keepass" "KeePassXC (Password Manager)"; + # exec = + # "~/.config/waybar/scripts/watchstatus keepass KeePassXC 'KeePassXC (Password Manager)'"; + #return-type = "json"; + on-click = "${ptray}/bin/ptrayctl toggle keepass"; + on-click-middle = "killall keepassxc"; + restart-interval = 5; + return-type = "json"; + }; + + "pulseaudio#output-icon" = { + format = "{icon}"; + format-muted = "󰸈"; + + format-icons = { + headphone = ""; + hands-free = ""; + headset = ""; + phone = ""; + portable = ""; + car = ""; + default = [ "󰕿" "󰖀" "󰕾" ]; + }; + on-click = "jwm vol toggle-mute"; + on-click-right = "dropwinctl toggle pavucontrol"; + }; + + "pulseaudio#output" = { + format = "{volume}%"; + on-click = "jwm vol toggle-mute"; + on-click-right = "dropwinctl toggle pavucontrol"; + }; + + "pulseaudio#input" = { + format = "{format_source}"; + format-source = ""; + format-source-muted = ""; + on-click = "jwm mic toggle-mute"; + on-click-right = "dropwinctl toggle pavucontrol"; + }; + + battery = { + bat = "BAT0"; + states = { + warning = 30; + critical = 15; + }; + format = "{icon}"; + rotate = 90; + format-charging = ""; + tooltip-format = "Battery: {capacity}%"; + format-icons = [ "" "" "" "" "" "" "" "" "" "" ]; + }; + + upower = { + format = "{percentage}"; + format-alt = "{time}"; + icon-size = 1; + }; + + clock = { + tooltip-format = '' + {:%Y %B} + {calendar}''; + }; + }]; + }; + }; +} diff --git a/home-manager/patches/hyprland-workspaces/Cargo.lock b/home-manager/patches/hyprland-workspaces/Cargo.lock new file mode 100644 index 0000000..cea4c51 --- /dev/null +++ b/home-manager/patches/hyprland-workspaces/Cargo.lock @@ -0,0 +1,773 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "async-trait" +version = "0.1.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hyprland" +version = "0.3.13" +source = "git+https://github.com/hyprland-community/hyprland-rs?rev=4a6ef94#4a6ef944e8453d47dab02ab5e14e4926d2278aee" +dependencies = [ + "async-trait", + "derive_more", + "doc-comment", + "futures", + "hex", + "hyprland-macros", + "lazy_static", + "num-traits", + "paste", + "regex", + "serde", + "serde_json", + "serde_repr", + "strum", + "tokio", +] + +[[package]] +name = "hyprland-macros" +version = "0.3.13" +source = "git+https://github.com/hyprland-community/hyprland-rs?rev=4a6ef94#4a6ef944e8453d47dab02ab5e14e4926d2278aee" +dependencies = [ + "quote", + "syn 2.0.58", +] + +[[package]] +name = "hyprland-workspaces" +version = "1.2.3" +dependencies = [ + "hyprland", + "serde", + "serde_json", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "serde_json" +version = "1.0.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.58", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/home-manager/patches/hyprland-workspaces/output-monitor-info.patch b/home-manager/patches/hyprland-workspaces/output-monitor-info.patch new file mode 100644 index 0000000..13b4182 --- /dev/null +++ b/home-manager/patches/hyprland-workspaces/output-monitor-info.patch @@ -0,0 +1,894 @@ +From 6e78240ab57d6c06444d2d3cc767b69a8e582561 Mon Sep 17 00:00:00 2001 +From: jaina heartles +Date: Thu, 4 Apr 2024 20:07:32 -0700 +Subject: [PATCH] Output monitor and id as well + +--- + Cargo.lock | 432 ++++++++++++++++++++++++++++++++-------------------- + Cargo.toml | 3 +- + src/main.rs | 4 + + 3 files changed, 275 insertions(+), 164 deletions(-) + +diff --git a/Cargo.lock b/Cargo.lock +index f818a23..cea4c51 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -2,31 +2,61 @@ + # It is not intended for manual editing. + version = 3 + ++[[package]] ++name = "addr2line" ++version = "0.21.0" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" ++dependencies = [ ++ "gimli", ++] ++ ++[[package]] ++name = "adler" ++version = "1.0.2" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" ++ + [[package]] + name = "aho-corasick" +-version = "0.7.20" ++version = "1.1.3" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" ++checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" + dependencies = [ + "memchr", + ] + + [[package]] + name = "async-trait" +-version = "0.1.66" ++version = "0.1.79" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc" ++checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" + dependencies = [ + "proc-macro2", + "quote", +- "syn 1.0.109", ++ "syn 2.0.58", + ] + + [[package]] + name = "autocfg" +-version = "1.1.0" ++version = "1.2.0" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" ++checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" ++ ++[[package]] ++name = "backtrace" ++version = "0.3.71" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" ++dependencies = [ ++ "addr2line", ++ "cc", ++ "cfg-if", ++ "libc", ++ "miniz_oxide", ++ "object", ++ "rustc-demangle", ++] + + [[package]] + name = "bitflags" +@@ -36,9 +66,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + + [[package]] + name = "bytes" +-version = "1.4.0" ++version = "1.6.0" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" ++checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" ++ ++[[package]] ++name = "cc" ++version = "1.0.90" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" + + [[package]] + name = "cfg-if" +@@ -73,9 +109,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + + [[package]] + name = "futures" +-version = "0.3.27" ++version = "0.3.30" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549" ++checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" + dependencies = [ + "futures-channel", + "futures-core", +@@ -88,9 +124,9 @@ dependencies = [ + + [[package]] + name = "futures-channel" +-version = "0.3.27" ++version = "0.3.30" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" ++checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" + dependencies = [ + "futures-core", + "futures-sink", +@@ -98,15 +134,15 @@ dependencies = [ + + [[package]] + name = "futures-core" +-version = "0.3.27" ++version = "0.3.30" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" ++checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + + [[package]] + name = "futures-executor" +-version = "0.3.27" ++version = "0.3.30" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83" ++checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" + dependencies = [ + "futures-core", + "futures-task", +@@ -115,38 +151,38 @@ dependencies = [ + + [[package]] + name = "futures-io" +-version = "0.3.27" ++version = "0.3.30" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91" ++checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + + [[package]] + name = "futures-macro" +-version = "0.3.27" ++version = "0.3.30" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6" ++checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" + dependencies = [ + "proc-macro2", + "quote", +- "syn 1.0.109", ++ "syn 2.0.58", + ] + + [[package]] + name = "futures-sink" +-version = "0.3.27" ++version = "0.3.30" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2" ++checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + + [[package]] + name = "futures-task" +-version = "0.3.27" ++version = "0.3.30" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" ++checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + + [[package]] + name = "futures-util" +-version = "0.3.27" ++version = "0.3.30" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" ++checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" + dependencies = [ + "futures-channel", + "futures-core", +@@ -160,6 +196,12 @@ dependencies = [ + "slab", + ] + ++[[package]] ++name = "gimli" ++version = "0.28.1" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" ++ + [[package]] + name = "heck" + version = "0.4.1" +@@ -168,12 +210,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + + [[package]] + name = "hermit-abi" +-version = "0.2.6" ++version = "0.3.9" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +-dependencies = [ +- "libc", +-] ++checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + + [[package]] + name = "hex" +@@ -183,9 +222,8 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + + [[package]] + name = "hyprland" +-version = "0.3.8" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "a84219159a2b7df96e2e6a8b8806d97c94d7ba2f661a0d4dd843d66b59f0ca28" ++version = "0.3.13" ++source = "git+https://github.com/hyprland-community/hyprland-rs?rev=4a6ef94#4a6ef944e8453d47dab02ab5e14e4926d2278aee" + dependencies = [ + "async-trait", + "derive_more", +@@ -206,12 +244,11 @@ dependencies = [ + + [[package]] + name = "hyprland-macros" +-version = "0.3.4" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "c941d3d52e979612af8cb94e8de49000c7fada2014a7791d173ab41339f4e4eb" ++version = "0.3.13" ++source = "git+https://github.com/hyprland-community/hyprland-rs?rev=4a6ef94#4a6ef944e8453d47dab02ab5e14e4926d2278aee" + dependencies = [ + "quote", +- "syn 2.0.12", ++ "syn 2.0.58", + ] + + [[package]] +@@ -225,9 +262,9 @@ dependencies = [ + + [[package]] + name = "itoa" +-version = "1.0.6" ++version = "1.0.11" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" ++checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + + [[package]] + name = "lazy_static" +@@ -237,66 +274,74 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + + [[package]] + name = "libc" +-version = "0.2.140" ++version = "0.2.153" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" ++checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + + [[package]] + name = "lock_api" +-version = "0.4.9" ++version = "0.4.11" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" ++checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" + dependencies = [ + "autocfg", + "scopeguard", + ] + + [[package]] +-name = "log" +-version = "0.4.17" ++name = "memchr" ++version = "2.7.2" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +-dependencies = [ +- "cfg-if", +-] ++checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + + [[package]] +-name = "memchr" +-version = "2.5.0" ++name = "miniz_oxide" ++version = "0.7.2" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" ++checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" ++dependencies = [ ++ "adler", ++] + + [[package]] + name = "mio" +-version = "0.8.6" ++version = "0.8.11" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" ++checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" + dependencies = [ + "libc", +- "log", + "wasi", +- "windows-sys", ++ "windows-sys 0.48.0", + ] + + [[package]] + name = "num-traits" +-version = "0.2.15" ++version = "0.2.18" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" ++checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" + dependencies = [ + "autocfg", + ] + + [[package]] + name = "num_cpus" +-version = "1.15.0" ++version = "1.16.0" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" ++checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" + dependencies = [ + "hermit-abi", + "libc", + ] + ++[[package]] ++name = "object" ++version = "0.32.2" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" ++dependencies = [ ++ "memchr", ++] ++ + [[package]] + name = "parking_lot" + version = "0.12.1" +@@ -309,28 +354,28 @@ dependencies = [ + + [[package]] + name = "parking_lot_core" +-version = "0.9.7" ++version = "0.9.9" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" ++checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" + dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", +- "windows-sys", ++ "windows-targets 0.48.5", + ] + + [[package]] + name = "paste" +-version = "1.0.12" ++version = "1.0.14" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" ++checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + + [[package]] + name = "pin-project-lite" +-version = "0.2.9" ++version = "0.2.14" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" ++checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + + [[package]] + name = "pin-utils" +@@ -340,36 +385,48 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + + [[package]] + name = "proc-macro2" +-version = "1.0.52" ++version = "1.0.79" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" ++checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" + dependencies = [ + "unicode-ident", + ] + + [[package]] + name = "quote" +-version = "1.0.26" ++version = "1.0.35" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" ++checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" + dependencies = [ + "proc-macro2", + ] + + [[package]] + name = "redox_syscall" +-version = "0.2.16" ++version = "0.4.1" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" ++checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" + dependencies = [ + "bitflags", + ] + + [[package]] + name = "regex" +-version = "1.7.1" ++version = "1.10.4" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" ++checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" ++dependencies = [ ++ "aho-corasick", ++ "memchr", ++ "regex-automata", ++ "regex-syntax", ++] ++ ++[[package]] ++name = "regex-automata" ++version = "0.4.6" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" + dependencies = [ + "aho-corasick", + "memchr", +@@ -378,9 +435,15 @@ dependencies = [ + + [[package]] + name = "regex-syntax" +-version = "0.6.28" ++version = "0.8.3" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" ++checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" ++ ++[[package]] ++name = "rustc-demangle" ++version = "0.1.23" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + + [[package]] + name = "rustc_version" +@@ -393,53 +456,53 @@ dependencies = [ + + [[package]] + name = "rustversion" +-version = "1.0.12" ++version = "1.0.14" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" ++checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + + [[package]] + name = "ryu" +-version = "1.0.13" ++version = "1.0.17" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" ++checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + + [[package]] + name = "scopeguard" +-version = "1.1.0" ++version = "1.2.0" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" ++checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + + [[package]] + name = "semver" +-version = "1.0.17" ++version = "1.0.22" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" ++checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + + [[package]] + name = "serde" +-version = "1.0.156" ++version = "1.0.197" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "314b5b092c0ade17c00142951e50ced110ec27cea304b1037c6969246c2469a4" ++checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" + dependencies = [ + "serde_derive", + ] + + [[package]] + name = "serde_derive" +-version = "1.0.156" ++version = "1.0.197" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "d7e29c4601e36bcec74a223228dce795f4cd3616341a4af93520ca1a837c087d" ++checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" + dependencies = [ + "proc-macro2", + "quote", +- "syn 1.0.109", ++ "syn 2.0.58", + ] + + [[package]] + name = "serde_json" +-version = "1.0.94" ++version = "1.0.115" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" ++checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" + dependencies = [ + "itoa", + "ryu", +@@ -448,13 +511,13 @@ dependencies = [ + + [[package]] + name = "serde_repr" +-version = "0.1.11" ++version = "0.1.18" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "395627de918015623b32e7669714206363a7fc00382bf477e72c1f7533e8eafc" ++checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" + dependencies = [ + "proc-macro2", + "quote", +- "syn 1.0.109", ++ "syn 2.0.58", + ] + + [[package]] +@@ -468,49 +531,49 @@ dependencies = [ + + [[package]] + name = "slab" +-version = "0.4.8" ++version = "0.4.9" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" ++checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" + dependencies = [ + "autocfg", + ] + + [[package]] + name = "smallvec" +-version = "1.10.0" ++version = "1.13.2" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" ++checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + + [[package]] + name = "socket2" +-version = "0.4.9" ++version = "0.5.6" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" ++checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" + dependencies = [ + "libc", +- "winapi", ++ "windows-sys 0.52.0", + ] + + [[package]] + name = "strum" +-version = "0.24.1" ++version = "0.26.2" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" ++checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" + dependencies = [ + "strum_macros", + ] + + [[package]] + name = "strum_macros" +-version = "0.24.3" ++version = "0.26.2" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" ++checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" + dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", +- "syn 1.0.109", ++ "syn 2.0.58", + ] + + [[package]] +@@ -526,9 +589,9 @@ dependencies = [ + + [[package]] + name = "syn" +-version = "2.0.12" ++version = "2.0.58" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" ++checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" + dependencies = [ + "proc-macro2", + "quote", +@@ -537,14 +600,13 @@ dependencies = [ + + [[package]] + name = "tokio" +-version = "1.26.0" ++version = "1.37.0" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" ++checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" + dependencies = [ +- "autocfg", ++ "backtrace", + "bytes", + "libc", +- "memchr", + "mio", + "num_cpus", + "parking_lot", +@@ -552,25 +614,25 @@ dependencies = [ + "signal-hook-registry", + "socket2", + "tokio-macros", +- "windows-sys", ++ "windows-sys 0.48.0", + ] + + [[package]] + name = "tokio-macros" +-version = "1.8.2" ++version = "2.2.0" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" ++checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" + dependencies = [ + "proc-macro2", + "quote", +- "syn 1.0.109", ++ "syn 2.0.58", + ] + + [[package]] + name = "unicode-ident" +-version = "1.0.8" ++version = "1.0.12" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" ++checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + + [[package]] + name = "wasi" +@@ -579,89 +641,133 @@ source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + + [[package]] +-name = "winapi" +-version = "0.3.9" ++name = "windows-sys" ++version = "0.48.0" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" ++checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" + dependencies = [ +- "winapi-i686-pc-windows-gnu", +- "winapi-x86_64-pc-windows-gnu", ++ "windows-targets 0.48.5", + ] + + [[package]] +-name = "winapi-i686-pc-windows-gnu" +-version = "0.4.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +- +-[[package]] +-name = "winapi-x86_64-pc-windows-gnu" +-version = "0.4.0" ++name = "windows-sys" ++version = "0.52.0" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" ++checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" ++dependencies = [ ++ "windows-targets 0.52.4", ++] + + [[package]] +-name = "windows-sys" +-version = "0.45.0" ++name = "windows-targets" ++version = "0.48.5" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" ++checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" + dependencies = [ +- "windows-targets", ++ "windows_aarch64_gnullvm 0.48.5", ++ "windows_aarch64_msvc 0.48.5", ++ "windows_i686_gnu 0.48.5", ++ "windows_i686_msvc 0.48.5", ++ "windows_x86_64_gnu 0.48.5", ++ "windows_x86_64_gnullvm 0.48.5", ++ "windows_x86_64_msvc 0.48.5", + ] + + [[package]] + name = "windows-targets" +-version = "0.42.2" ++version = "0.52.4" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" ++checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" + dependencies = [ +- "windows_aarch64_gnullvm", +- "windows_aarch64_msvc", +- "windows_i686_gnu", +- "windows_i686_msvc", +- "windows_x86_64_gnu", +- "windows_x86_64_gnullvm", +- "windows_x86_64_msvc", ++ "windows_aarch64_gnullvm 0.52.4", ++ "windows_aarch64_msvc 0.52.4", ++ "windows_i686_gnu 0.52.4", ++ "windows_i686_msvc 0.52.4", ++ "windows_x86_64_gnu 0.52.4", ++ "windows_x86_64_gnullvm 0.52.4", ++ "windows_x86_64_msvc 0.52.4", + ] + + [[package]] + name = "windows_aarch64_gnullvm" +-version = "0.42.2" ++version = "0.48.5" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" ++ ++[[package]] ++name = "windows_aarch64_gnullvm" ++version = "0.52.4" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" ++ ++[[package]] ++name = "windows_aarch64_msvc" ++version = "0.48.5" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" ++checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + + [[package]] + name = "windows_aarch64_msvc" +-version = "0.42.2" ++version = "0.52.4" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" ++checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + + [[package]] + name = "windows_i686_gnu" +-version = "0.42.2" ++version = "0.48.5" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" ++checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" ++ ++[[package]] ++name = "windows_i686_gnu" ++version = "0.52.4" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + + [[package]] + name = "windows_i686_msvc" +-version = "0.42.2" ++version = "0.48.5" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" ++checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" ++ ++[[package]] ++name = "windows_i686_msvc" ++version = "0.52.4" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + + [[package]] + name = "windows_x86_64_gnu" +-version = "0.42.2" ++version = "0.48.5" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" ++checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" ++ ++[[package]] ++name = "windows_x86_64_gnu" ++version = "0.52.4" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + + [[package]] + name = "windows_x86_64_gnullvm" +-version = "0.42.2" ++version = "0.48.5" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" ++ ++[[package]] ++name = "windows_x86_64_gnullvm" ++version = "0.52.4" ++source = "registry+https://github.com/rust-lang/crates.io-index" ++checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" ++ ++[[package]] ++name = "windows_x86_64_msvc" ++version = "0.48.5" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" ++checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + + [[package]] + name = "windows_x86_64_msvc" +-version = "0.42.2" ++version = "0.52.4" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" ++checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +diff --git a/Cargo.toml b/Cargo.toml +index b2fa53d..5e73508 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -6,6 +6,7 @@ edition = "2021" + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + + [dependencies] +-hyprland = "0.3.8" ++#hyprland = "0.3.8" ++hyprland = { git = "https://github.com/hyprland-community/hyprland-rs", rev = "4a6ef94" } + serde_json = "1.0" + serde = "1.0" +diff --git a/src/main.rs b/src/main.rs +index 6ed7490..7845349 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -26,6 +26,8 @@ struct WorkspaceCustom { + pub id: i32, + pub active: bool, + pub class: String, ++ pub monitor: String, ++ pub monitor_id: u8, + } + + fn output(monitor: &str) { +@@ -67,6 +69,8 @@ fn output(monitor: &str) { + id: workspace.id, + active, + class, ++ monitor: workspace.monitor.clone(), ++ monitor_id: workspace.monitor_id, + }; + out_workspaces.push(ws); + } +-- +2.42.0 + diff --git a/home-manager/wallpapers/denise_picrew_2.png b/home-manager/wallpapers/denise_picrew_2.png new file mode 100644 index 0000000..4efee9b Binary files /dev/null and b/home-manager/wallpapers/denise_picrew_2.png differ diff --git a/home-manager/wallpapers/denise_picrew_3.png b/home-manager/wallpapers/denise_picrew_3.png new file mode 100644 index 0000000..157aed4 Binary files /dev/null and b/home-manager/wallpapers/denise_picrew_3.png differ diff --git a/home-manager/wallpapers/elrena-lauriam-cropped.jpg b/home-manager/wallpapers/elrena-lauriam-cropped.jpg new file mode 100644 index 0000000..be1c109 Binary files /dev/null and b/home-manager/wallpapers/elrena-lauriam-cropped.jpg differ diff --git a/home-manager/wallpapers/sarina.png b/home-manager/wallpapers/sarina.png new file mode 100644 index 0000000..b671f22 Binary files /dev/null and b/home-manager/wallpapers/sarina.png differ diff --git a/home-manager/wallpapers/slimejaina_extinct_lesboba.png b/home-manager/wallpapers/slimejaina_extinct_lesboba.png new file mode 100644 index 0000000..34944be Binary files /dev/null and b/home-manager/wallpapers/slimejaina_extinct_lesboba.png differ diff --git a/home-manager/wallpapers/velma_picrew.png b/home-manager/wallpapers/velma_picrew.png new file mode 100644 index 0000000..482e304 Binary files /dev/null and b/home-manager/wallpapers/velma_picrew.png differ diff --git a/home-manager/wallpapers/velma_picrew_cropped.png b/home-manager/wallpapers/velma_picrew_cropped.png new file mode 100644 index 0000000..cf7ee11 Binary files /dev/null and b/home-manager/wallpapers/velma_picrew_cropped.png differ