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
8.5 kB 261 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 on_enter = lib.mkOption { 20 type = lib.types.listOf lib.types.str; 21 default = [ ]; 22 description = "Commands to run when entering this workspace"; 23 }; 24 on_leave = lib.mkOption { 25 type = lib.types.listOf lib.types.str; 26 default = [ ]; 27 description = "Commands to run when leaving this workspace"; 28 }; 29 on_create = lib.mkOption { 30 type = lib.types.listOf lib.types.str; 31 default = [ ]; 32 description = "Commands to run in a tmux session when the workspace is first entered. Each command gets its own tmux window with visible logs. Reattach with: tmux attach -t ws-<name>"; 33 }; 34 }; 35 }; 36 37 # Generate a directory with JSON files for each declared workspace 38 systemConfigDir = pkgs.linkFarm "workspace-manager-configs" ( 39 lib.mapAttrsToList (name: ws: { 40 name = "${name}.json"; 41 path = pkgs.writeText "${name}.json" ( 42 builtins.toJSON { 43 inherit (ws) 44 directory 45 on_enter 46 on_leave 47 on_create 48 ; 49 } 50 ); 51 }) cfg.workspaces 52 ); 53 in 54 { 55 options.lass.workspace-manager = { 56 enable = lib.mkEnableOption "workspace manager daemon for sway"; 57 58 package = lib.mkOption { 59 type = lib.types.package; 60 default = self.packages.${pkgs.system}.workspace-manager-daemon; 61 description = "The workspace-manager-daemon package to use"; 62 }; 63 64 workspaces = lib.mkOption { 65 type = lib.types.attrsOf workspaceType; 66 default = { }; 67 description = "Declarative workspace configurations (take precedence over user configs)"; 68 example = lib.literalExpression '' 69 { 70 dev = { 71 directory = "/home/user/src/myproject"; 72 on_enter = [ "notify-send 'Entered dev workspace'" ]; 73 }; 74 music = { 75 directory = "/home/user/Music"; 76 }; 77 } 78 ''; 79 }; 80 81 configDir = lib.mkOption { 82 type = lib.types.str; 83 default = "~/workspaces"; 84 description = "Directory containing user workspace configuration files"; 85 }; 86 87 defaultDirectory = lib.mkOption { 88 type = lib.types.str; 89 default = "~"; 90 description = "Default directory for workspaces without configuration"; 91 }; 92 93 terminalCommand = lib.mkOption { 94 type = lib.types.str; 95 default = "kitty"; 96 description = "Terminal emulator to use for on_create commands. Must support '-T title' for setting the window title."; 97 }; 98 99 onNewHandler = lib.mkOption { 100 type = lib.types.nullOr lib.types.str; 101 default = "${self.packages.${pkgs.system}.workspace-on-new}/bin/workspace-on-new"; 102 description = "Script called when entering a workspace for the first time. Exit 0 to restore (run on_create), non-zero to skip."; 103 }; 104 }; 105 106 config = lib.mkIf cfg.enable { 107 systemd.user.services.workspace-manager = { 108 description = "Workspace Manager Daemon"; 109 partOf = [ "sway-session.target" ]; 110 wantedBy = [ "sway-session.target" ]; 111 serviceConfig = { 112 Type = "simple"; 113 ExecStart = "${cfg.package}/bin/workspace-manager-daemon"; 114 Restart = "on-failure"; 115 RestartSec = 5; 116 Environment = [ 117 "WORKSPACE_MANAGER_CONFIG_DIR=${cfg.configDir}" 118 "WORKSPACE_MANAGER_SYSTEM_CONFIG_DIR=${systemConfigDir}" 119 "WORKSPACE_MANAGER_DEFAULT_DIR=${cfg.defaultDirectory}" 120 "WORKSPACE_MANAGER_TERMINAL=${cfg.terminalCommand}" 121 ] 122 ++ lib.optional (cfg.onNewHandler != null) "WORKSPACE_MANAGER_ON_NEW_HANDLER=${cfg.onNewHandler}"; 123 }; 124 }; 125 }; 126 }; 127 128 perSystem = 129 { 130 pkgs, 131 ... 132 }: 133 let 134 python = pkgs.python3; 135 in 136 { 137 packages.workspace-manager = 138 (pkgs.writeShellApplication { 139 name = "workspace-manager"; 140 runtimeInputs = [ 141 pkgs.socat 142 pkgs.jq 143 ]; 144 text = builtins.readFile ./workspace-manager.sh; 145 }).overrideAttrs 146 { passthru.usage = builtins.readFile ./usage.kdl; }; 147 148 packages.workspace-menu = pkgs.writeShellApplication { 149 name = "workspace-menu"; 150 runtimeInputs = [ 151 pkgs.sway 152 pkgs.jq 153 pkgs.rofi 154 pkgs.libnotify 155 pkgs.tmux 156 pkgs.kitty 157 pkgs.findutils 158 pkgs.gnused 159 pkgs.coreutils 160 pkgs.gnugrep 161 ]; 162 text = builtins.readFile ./workspace-menu.sh; 163 }; 164 165 packages.workspace-on-new = pkgs.writeShellApplication { 166 name = "workspace-on-new"; 167 runtimeInputs = [ 168 pkgs.jq 169 pkgs.rofi 170 pkgs.coreutils 171 pkgs.gnused 172 ]; 173 text = builtins.readFile ./workspace-on-new.sh; 174 }; 175 176 packages.workspace-manager-daemon = pkgs.stdenv.mkDerivation { 177 pname = "workspace-manager-daemon"; 178 version = "0.1.0"; 179 src = ./.; 180 nativeBuildInputs = [ 181 pkgs.makeWrapper 182 pkgs.ruff 183 python.pkgs.mypy 184 ]; 185 doCheck = true; 186 checkPhase = '' 187 runHook preCheck 188 ruff check daemon.py 189 ruff format --check daemon.py 190 mypy --strict daemon.py 191 runHook postCheck 192 ''; 193 installPhase = '' 194 runHook preInstall 195 mkdir -p $out/bin 196 cp daemon.py $out/bin/workspace-manager-daemon 197 chmod +x $out/bin/workspace-manager-daemon 198 wrapProgram $out/bin/workspace-manager-daemon \ 199 --prefix PATH : ${python}/bin:${pkgs.sway}/bin:${pkgs.tmux}/bin 200 runHook postInstall 201 ''; 202 meta.mainProgram = "workspace-manager-daemon"; 203 }; 204 205 # Open Firefox for the current workspace 206 packages.workspace-browser = pkgs.writeShellScriptBin "workspace-browser" '' 207 exec firefox "$@" 208 ''; 209 210 # Native messaging host for the workspace-tabs Firefox extension 211 packages.workspace-tabs-native-host = pkgs.stdenv.mkDerivation { 212 pname = "workspace-tabs-native-host"; 213 version = "0.1.0"; 214 src = ./.; 215 nativeBuildInputs = [ 216 pkgs.makeWrapper 217 pkgs.ruff 218 python.pkgs.mypy 219 ]; 220 doCheck = true; 221 checkPhase = '' 222 runHook preCheck 223 ruff check workspace-tabs-host.py 224 ruff format --check workspace-tabs-host.py 225 mypy --strict workspace-tabs-host.py 226 runHook postCheck 227 ''; 228 installPhase = '' 229 runHook preInstall 230 mkdir -p $out/bin $out/lib/mozilla/native-messaging-hosts 231 cp workspace-tabs-host.py $out/bin/workspace-tabs-host 232 chmod +x $out/bin/workspace-tabs-host 233 wrapProgram $out/bin/workspace-tabs-host \ 234 --prefix PATH : ${python}/bin:${pkgs.sway}/bin 235 236 cat > $out/lib/mozilla/native-messaging-hosts/workspace_tabs.json <<EOF 237 { 238 "name": "workspace_tabs", 239 "description": "Native messaging host for Workspace Tabs extension", 240 "path": "$out/bin/workspace-tabs-host", 241 "type": "stdio", 242 "allowed_extensions": ["workspace-tabs@workspace-manager"] 243 } 244 EOF 245 runHook postInstall 246 ''; 247 }; 248 249 # Firefox extension for workspace tab management (packaged as .xpi) 250 packages.workspace-tabs-extension = 251 pkgs.runCommand "workspace-tabs-extension" 252 { 253 nativeBuildInputs = [ pkgs.zip ]; 254 } 255 '' 256 mkdir -p $out 257 cd ${./firefox-extension} 258 zip -r "$out/workspace-tabs@workspace-manager.xpi" ./* 259 ''; 260 }; 261}