This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

superconfig / tools / workspace-manager / flake-module.nix
6.6 kB 208 lines
1{ self, ... }: 2{ 3 flake.wrapperModules.workspace-manager = 4 { 5 config, 6 lib, 7 pkgs, 8 ... 9 }: 10 let 11 cfg = config.lass.workspace-manager; 12 13 workspaceType = lib.types.submodule { 14 options = { 15 directory = lib.mkOption { 16 type = lib.types.str; 17 description = "Directory to use for this workspace"; 18 }; 19 }; 20 }; 21 22 # Generate a directory with JSON files for each declared workspace 23 systemConfigDir = pkgs.linkFarm "workspace-manager-configs" ( 24 lib.mapAttrsToList (name: ws: { 25 name = "${name}.json"; 26 path = pkgs.writeText "${name}.json" (builtins.toJSON { inherit (ws) directory; }); 27 }) cfg.workspaces 28 ); 29 in 30 { 31 options.lass.workspace-manager = { 32 enable = lib.mkEnableOption "workspace manager daemon for sway"; 33 34 package = lib.mkOption { 35 type = lib.types.package; 36 default = self.packages.${pkgs.system}.workspace-manager-daemon; 37 description = "The workspace-manager-daemon package to use"; 38 }; 39 40 workspaces = lib.mkOption { 41 type = lib.types.attrsOf workspaceType; 42 default = { }; 43 description = "Declarative workspace configurations (take precedence over user configs)"; 44 example = lib.literalExpression '' 45 { 46 dev = { directory = "/home/user/src/myproject"; }; 47 music = { directory = "/home/user/Music"; }; 48 } 49 ''; 50 }; 51 52 configDir = lib.mkOption { 53 type = lib.types.str; 54 default = "~/workspaces"; 55 description = "Directory containing user workspace configuration files"; 56 }; 57 58 defaultDirectory = lib.mkOption { 59 type = lib.types.str; 60 default = "~"; 61 description = "Default directory for workspaces without configuration"; 62 }; 63 }; 64 65 config = lib.mkIf cfg.enable { 66 systemd.user.services.workspace-manager = { 67 description = "Workspace Manager Daemon"; 68 partOf = [ "sway-session.target" ]; 69 wantedBy = [ "sway-session.target" ]; 70 serviceConfig = { 71 Type = "simple"; 72 ExecStart = "${cfg.package}/bin/workspace-manager-daemon"; 73 Restart = "on-failure"; 74 RestartSec = 5; 75 Environment = [ 76 "WORKSPACE_MANAGER_CONFIG_DIR=${cfg.configDir}" 77 "WORKSPACE_MANAGER_SYSTEM_CONFIG_DIR=${systemConfigDir}" 78 "WORKSPACE_MANAGER_DEFAULT_DIR=${cfg.defaultDirectory}" 79 ]; 80 }; 81 }; 82 }; 83 }; 84 85 perSystem = 86 { 87 pkgs, 88 ... 89 }: 90 let 91 python = pkgs.python3; 92 in 93 { 94 packages.workspace-manager = 95 (pkgs.writeShellApplication { 96 name = "workspace-manager"; 97 runtimeInputs = [ 98 pkgs.socat 99 pkgs.jq 100 ]; 101 text = builtins.readFile ./workspace-manager.sh; 102 }).overrideAttrs 103 { passthru.usage = builtins.readFile ./usage.kdl; }; 104 105 packages.workspace-menu = pkgs.writeShellApplication { 106 name = "workspace-menu"; 107 runtimeInputs = [ 108 pkgs.sway 109 pkgs.jq 110 self.packages.${pkgs.system}.menu 111 pkgs.libnotify 112 pkgs.findutils 113 pkgs.gnused 114 pkgs.coreutils 115 pkgs.gnugrep 116 # The wrapped Dev Edition daemon, not upstream stable firefox — 117 # otherwise "Restore tabs" launches a separate browser/profile. 118 self.packages.${pkgs.system}.firefox 119 ]; 120 text = builtins.readFile ./workspace-menu.sh; 121 }; 122 123 packages.workspace-manager-daemon = pkgs.stdenv.mkDerivation { 124 pname = "workspace-manager-daemon"; 125 version = "0.1.0"; 126 src = ./.; 127 nativeBuildInputs = [ 128 pkgs.makeWrapper 129 pkgs.ruff 130 python.pkgs.mypy 131 ]; 132 doCheck = true; 133 checkPhase = '' 134 runHook preCheck 135 ruff check daemon.py 136 ruff format --check daemon.py 137 mypy --strict daemon.py 138 runHook postCheck 139 ''; 140 installPhase = '' 141 runHook preInstall 142 mkdir -p $out/bin 143 cp daemon.py $out/bin/workspace-manager-daemon 144 chmod +x $out/bin/workspace-manager-daemon 145 wrapProgram $out/bin/workspace-manager-daemon \ 146 --prefix PATH : ${python}/bin:${pkgs.sway}/bin 147 runHook postInstall 148 ''; 149 meta.mainProgram = "workspace-manager-daemon"; 150 }; 151 152 # Open Firefox for the current workspace 153 packages.workspace-browser = pkgs.writeShellScriptBin "workspace-browser" '' 154 exec firefox "$@" 155 ''; 156 157 # Native messaging host for the workspace-tabs Firefox extension 158 packages.workspace-tabs-native-host = pkgs.stdenv.mkDerivation { 159 pname = "workspace-tabs-native-host"; 160 version = "0.1.0"; 161 src = ./.; 162 nativeBuildInputs = [ 163 pkgs.makeWrapper 164 pkgs.ruff 165 python.pkgs.mypy 166 ]; 167 doCheck = true; 168 checkPhase = '' 169 runHook preCheck 170 ruff check workspace-tabs-host.py 171 ruff format --check workspace-tabs-host.py 172 mypy --strict workspace-tabs-host.py 173 runHook postCheck 174 ''; 175 installPhase = '' 176 runHook preInstall 177 mkdir -p $out/bin $out/lib/mozilla/native-messaging-hosts 178 cp workspace-tabs-host.py $out/bin/workspace-tabs-host 179 chmod +x $out/bin/workspace-tabs-host 180 wrapProgram $out/bin/workspace-tabs-host \ 181 --prefix PATH : ${python}/bin:${pkgs.sway}/bin 182 183 cat > $out/lib/mozilla/native-messaging-hosts/workspace_tabs.json <<EOF 184 { 185 "name": "workspace_tabs", 186 "description": "Native messaging host for Workspace Tabs extension", 187 "path": "$out/bin/workspace-tabs-host", 188 "type": "stdio", 189 "allowed_extensions": ["workspace-tabs@workspace-manager"] 190 } 191 EOF 192 runHook postInstall 193 ''; 194 }; 195 196 # Firefox extension for workspace tab management (packaged as .xpi) 197 packages.workspace-tabs-extension = 198 pkgs.runCommand "workspace-tabs-extension" 199 { 200 nativeBuildInputs = [ pkgs.zip ]; 201 } 202 '' 203 mkdir -p $out 204 cd ${./firefox-extension} 205 zip -r "$out/workspace-tabs@workspace-manager.xpi" ./* 206 ''; 207 }; 208}