This repository has no description
0

Configure Feed

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

superconfig / wrapperModules / noctalia-shell / flake-module.nix
6.2 kB 166 lines
1{ ... }: 2{ 3 flake.wrapperModules.noctalia-shell = 4 { 5 config, 6 lib, 7 ... 8 }: 9 let 10 pkgs = config.pkgs; 11 jsonFormat = pkgs.formats.json { }; 12 13 sway-focus-workspace = pkgs.writeShellScript "sway-focus-workspace" '' 14 # Bring a workspace to the currently focused output 15 ws="$1" 16 current_output=$(${pkgs.sway}/bin/swaymsg -t get_workspaces \ 17 | ${pkgs.jq}/bin/jq -r '.[] | select(.focused) | .output') 18 ${pkgs.sway}/bin/swaymsg "workspace $ws, move workspace to output $current_output" 19 ''; 20 21 # Patch noctalia-shell for sway: 22 # - Use workspace name instead of number (activate() sends 23 # "workspace number <num>" which fails for named workspaces) 24 # - Show all workspaces on all screens (globalWorkspaces) 25 # - Bring workspace to current screen on click instead of jumping 26 # - Periodically resync the workspace model: the upstream QuickShell 27 # i3 plugin never removes renamed workspaces (a "rename" event is 28 # looked up by the NEW name, misses the old model object, and only 29 # logs "Workspace <name> doesn't exist"). A renamed workspace thus 30 # lingers as a stale pill until a full refresh; clicking that ghost 31 # pill then re-creates the old name as a real workspace. 32 swayPatched = pkgs.noctalia-shell.overrideAttrs (old: { 33 postInstall = (old.postInstall or "") + '' 34 substituteInPlace $out/share/noctalia-shell/Services/Compositor/SwayService.qml \ 35 --replace-fail 'workspace.handle.activate();' \ 36 'Quickshell.execDetached(["${sway-focus-workspace}", workspace.name]);' \ 37 --replace-fail 'property bool initialized: false' \ 38 'property bool globalWorkspaces: true 39 property bool initialized: false 40 41 // Drop stale workspace model entries (see patch note above). 42 Timer { 43 interval: 30000 44 repeat: true 45 running: initialized 46 onTriggered: I3.refreshWorkspaces() 47 }' 48 ''; 49 }); 50 51 declSettingsFile = jsonFormat.generate "noctalia-declarative-settings.json" config.settings; 52 in 53 { 54 _class = "wrapper"; 55 56 options = { 57 settings = lib.mkOption { 58 type = jsonFormat.type; 59 default = { }; 60 example = lib.literalExpression '' 61 { 62 hooks.enabled = true; 63 hooks.darkModeChange = "switch-theme $1"; 64 } 65 ''; 66 description = '' 67 Declarative noctalia settings. Deep-merged into the on-disk 68 `settings.json` on every start (declarative wins). Keys not 69 mentioned here remain user-mutable and survive across 70 invocations — only the fields you set are pinned. 71 ''; 72 }; 73 74 settingsPath = lib.mkOption { 75 type = lib.types.str; 76 default = ".config/noctalia/settings.json"; 77 description = '' 78 Path to the noctalia settings file, relative to `$HOME`. 79 ''; 80 }; 81 82 settingsPatches = lib.mkOption { 83 type = lib.types.listOf lib.types.str; 84 default = [ ]; 85 example = lib.literalExpression '' 86 [ 87 # Force the Workspace bar widget to show workspace names. 88 ".bar.widgets.center |= map(if .id == \"Workspace\" then .labelMode = \"name\" else . end)" 89 ] 90 ''; 91 description = '' 92 jq update expressions applied to `settings.json` on every start, 93 after the deep-merge of `settings`. Use these to pin individual 94 fields inside arrays (where deep-merge would replace the whole 95 array) without touching sibling entries. 96 97 Each string is passed as the filter to a separate `jq` invocation. 98 Patches run in order; if any patch fails the file is left 99 untouched. 100 ''; 101 }; 102 103 swayWorkspaceFix = lib.mkOption { 104 type = lib.types.bool; 105 default = true; 106 description = '' 107 Patch noctalia-shell so its workspace bar works on sway with 108 named/global workspaces and click-to-current-output. Applied 109 to the default package only; ignored if you override `package`. 110 ''; 111 }; 112 }; 113 114 config.package = lib.mkDefault ( 115 if config.swayWorkspaceFix then swayPatched else pkgs.noctalia-shell 116 ); 117 118 config.extraPackages = [ 119 pkgs.jq 120 pkgs.coreutils 121 ]; 122 123 # On every start: merge declarative settings into the user's 124 # writable settings.json. User-edited keys outside the declarative 125 # set are preserved; declarative keys are overwritten each run. 126 config.preHook = '' 127 NOCTALIA_SETTINGS="$HOME/${config.settingsPath}" 128 mkdir -p "$(dirname "$NOCTALIA_SETTINGS")" 129 if [ ! -f "$NOCTALIA_SETTINGS" ]; then 130 echo '{}' > "$NOCTALIA_SETTINGS" 131 fi 132 NOCTALIA_TMP=$(mktemp "$NOCTALIA_SETTINGS.XXXXXX") 133 noctalia_merge_ok=1 134 if ! ${pkgs.jq}/bin/jq --slurpfile decl ${declSettingsFile} \ 135 '. * $decl[0]' "$NOCTALIA_SETTINGS" > "$NOCTALIA_TMP"; then 136 noctalia_merge_ok=0 137 fi 138 ${lib.concatMapStringsSep "\n" (patch: '' 139 if [ "$noctalia_merge_ok" = 1 ]; then 140 NOCTALIA_TMP2=$(mktemp "$NOCTALIA_SETTINGS.XXXXXX") 141 if ${pkgs.jq}/bin/jq ${lib.escapeShellArg patch} "$NOCTALIA_TMP" > "$NOCTALIA_TMP2"; then 142 mv "$NOCTALIA_TMP2" "$NOCTALIA_TMP" 143 else 144 rm -f "$NOCTALIA_TMP2" 145 noctalia_merge_ok=0 146 fi 147 fi 148 '') config.settingsPatches} 149 if [ "$noctalia_merge_ok" = 1 ]; then 150 mv "$NOCTALIA_TMP" "$NOCTALIA_SETTINGS" 151 else 152 rm -f "$NOCTALIA_TMP" 153 echo "noctalia declarative settings merge failed; leaving settings.json untouched" >&2 154 fi 155 ''; 156 157 config.meta.maintainers = [ 158 { 159 name = "lassulus"; 160 github = "lassulus"; 161 githubId = 621375; 162 } 163 ]; 164 config.meta.platforms = lib.platforms.linux; 165 }; 166}