tenseleyflow/hyprkvm / 1042579

Browse files

feat: add home-manager module and improve packaging

- Add home-manager module for declarative service management
- Users can now enable with: services.hyprkvm.enable = true
- Module supports settings for auto-generating config file
- Update contrib/systemd service for system-installed binary
- Remove dev template (users can manually adapt if needed)
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
10425796ac77153455ddf6c64b089d2d41e3b22f
Parents
c5eafea
Tree
2c5e603

2 changed files

StatusFile+-
M contrib/systemd/hyprkvm.service 2 4
M flake.nix 202 113
contrib/systemd/hyprkvm.servicemodified
@@ -5,10 +5,8 @@ PartOf=graphical-session.target
5
 
5
 
6
 [Service]
6
 [Service]
7
 Type=simple
7
 Type=simple
8
-# Set WorkingDirectory to your hyprKVM repo path
8
+# For system-installed binaries (AUR, RPM, etc.)
9
-WorkingDirectory=%h/path/to/hyprKVM
9
+ExecStart=/usr/bin/hyprkvm daemon
10
-# Uses nix develop to provide required libraries
11
-ExecStart=/bin/sh -c 'exec nix develop --command ./target/release/hyprkvm daemon'
12
 Restart=on-failure
10
 Restart=on-failure
13
 RestartSec=1
11
 RestartSec=1
14
 
12
 
flake.nixmodified
@@ -11,134 +11,223 @@
11
   };
11
   };
12
 
12
 
13
   outputs = { self, nixpkgs, flake-utils, rust-overlay }:
13
   outputs = { self, nixpkgs, flake-utils, rust-overlay }:
14
-    flake-utils.lib.eachDefaultSystem (system:
14
+    let
15
-      let
15
+      # System-independent outputs
16
-        pkgs = import nixpkgs {
16
+      systemIndependent = {
17
-          inherit system;
17
+        # Home-manager module for easy service management
18
-          overlays = [ rust-overlay.overlays.default ];
18
+        homeManagerModules.default = { config, lib, pkgs, ... }:
19
-        };
19
+          let
20
-
20
+            cfg = config.services.hyprkvm;
21
-        # Build dependencies
21
+          in {
22
-        buildDeps = with pkgs; [
22
+            options.services.hyprkvm = {
23
-          pkg-config
23
+              enable = lib.mkEnableOption "HyprKVM daemon";
24
-        ];
24
+
25
-
25
+              package = lib.mkOption {
26
-        # Runtime/library dependencies
26
+                type = lib.types.package;
27
-        libDeps = with pkgs; [
27
+                default = self.packages.${pkgs.system}.default;
28
-          # Wayland
28
+                defaultText = lib.literalExpression "pkgs.hyprkvm";
29
-          wayland
29
+                description = "The HyprKVM package to use.";
30
-          wayland-protocols
30
+              };
31
-
31
+
32
-          # For smithay-client-toolkit
32
+              settings = lib.mkOption {
33
-          libxkbcommon
33
+                type = lib.types.attrs;
34
-
34
+                default = {};
35
-          # TLS
35
+                description = ''
36
-          openssl
36
+                  Configuration for HyprKVM. Will be written to
37
-
37
+                  ~/.config/hyprkvm/hyprkvm.toml
38
-          # GUI (Iced) dependencies
38
+                '';
39
-          vulkan-loader
39
+                example = lib.literalExpression ''
40
-          libGL
40
+                  {
41
-          xorg.libX11
41
+                    machines = {
42
-          xorg.libXcursor
42
+                      self_name = "my-machine";
43
-          xorg.libXrandr
43
+                      neighbors = [
44
-          xorg.libXi
44
+                        { name = "other-machine"; direction = "right"; address = "192.168.1.100:24850"; }
45
-        ];
45
+                      ];
46
-
46
+                    };
47
-        rustToolchain = pkgs.rust-bin.stable.latest.default.override {
47
+                    network = {
48
-          extensions = [ "rust-src" "rust-analyzer" ];
48
+                      listen_port = 24850;
49
-        };
49
+                    };
50
-      in
50
+                  }
51
-      {
51
+                '';
52
-        # Development shell
52
+              };
53
-        devShells.default = pkgs.mkShell {
53
+
54
-          buildInputs = buildDeps ++ libDeps ++ [
54
+              extraFlags = lib.mkOption {
55
-            rustToolchain
55
+                type = lib.types.listOf lib.types.str;
56
-          ];
56
+                default = [];
57
-
57
+                description = "Extra command-line flags to pass to the daemon.";
58
-          # Set up pkg-config paths
58
+              };
59
-          PKG_CONFIG_PATH = pkgs.lib.makeSearchPath "lib/pkgconfig" libDeps;
59
+            };
60
-
60
+
61
-          # For wayland-scanner
61
+            config = lib.mkIf cfg.enable {
62
-          WAYLAND_PROTOCOLS = "${pkgs.wayland-protocols}/share/wayland-protocols";
62
+              # Install the package
63
-
63
+              home.packages = [ cfg.package ];
64
-          # Graphics library paths for GUI
64
+
65
-          LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath libDeps;
65
+              # Generate config file if settings provided
66
-
66
+              xdg.configFile."hyprkvm/hyprkvm.toml" = lib.mkIf (cfg.settings != {}) {
67
-          shellHook = ''
67
+                source = (pkgs.formats.toml {}).generate "hyprkvm.toml" cfg.settings;
68
-            echo "HyprKVM development shell"
68
+              };
69
-            echo "Rust: $(rustc --version)"
69
+
70
-            echo ""
70
+              # Systemd user service
71
-            echo "Run 'cargo build' to compile"
71
+              systemd.user.services.hyprkvm = {
72
-          '';
72
+                Unit = {
73
-        };
73
+                  Description = "HyprKVM Daemon - Hyprland-native software KVM switch";
74
+                  After = [ "graphical-session.target" ];
75
+                  PartOf = [ "graphical-session.target" ];
76
+                };
77
+
78
+                Service = {
79
+                  Type = "simple";
80
+                  ExecStart = "${cfg.package}/bin/hyprkvm daemon ${lib.concatStringsSep " " cfg.extraFlags}";
81
+                  Restart = "on-failure";
82
+                  RestartSec = 1;
83
+                  # Exit code 75 triggers restart for direction changes
84
+                  RestartForceExitStatus = [ 75 ];
85
+                  Environment = [ "WAYLAND_DISPLAY=wayland-1" ];
86
+                };
87
+
88
+                Install = {
89
+                  WantedBy = [ "graphical-session.target" ];
90
+                };
91
+              };
92
+            };
93
+          };
74
 
94
 
75
-        # Package (without GUI for smaller binary)
95
+        # Alias for backwards compatibility
76
-        packages.default = pkgs.rustPlatform.buildRustPackage {
96
+        homeManagerModules.hyprkvm = self.homeManagerModules.default;
77
-          pname = "hyprkvm";
97
+      };
78
-          version = "0.5.1";
79
-          src = ./.;
80
 
98
 
81
-          cargoLock = {
99
+      # System-specific outputs (packages, devShells)
82
-            lockFile = ./Cargo.lock;
100
+      systemSpecific = flake-utils.lib.eachDefaultSystem (system:
101
+        let
102
+          pkgs = import nixpkgs {
103
+            inherit system;
104
+            overlays = [ rust-overlay.overlays.default ];
83
           };
105
           };
84
 
106
 
85
-          nativeBuildInputs = buildDeps;
107
+          # Build dependencies
86
-          buildInputs = libDeps;
108
+          buildDeps = with pkgs; [
109
+            pkg-config
110
+          ];
87
 
111
 
88
-          # Builds both hyprkvm (daemon) and hyprkvm-ctl (CLI)
112
+          # Runtime/library dependencies
89
-          # buildRustPackage automatically installs all workspace binaries
113
+          libDeps = with pkgs; [
114
+            # Wayland
115
+            wayland
116
+            wayland-protocols
117
+
118
+            # For smithay-client-toolkit
119
+            libxkbcommon
120
+
121
+            # TLS
122
+            openssl
123
+
124
+            # GUI (Iced) dependencies
125
+            vulkan-loader
126
+            libGL
127
+            xorg.libX11
128
+            xorg.libXcursor
129
+            xorg.libXrandr
130
+            xorg.libXi
131
+          ];
90
 
132
 
91
-          meta = with pkgs.lib; {
133
+          rustToolchain = pkgs.rust-bin.stable.latest.default.override {
92
-            description = "Hyprland-native software KVM switch";
134
+            extensions = [ "rust-src" "rust-analyzer" ];
93
-            longDescription = ''
135
+          };
94
-              HyprKVM enables seamless keyboard/mouse control transfer between
136
+        in
95
-              Linux machines running Hyprland. Move past your last workspace
137
+        {
96
-              to switch to another machine.
138
+          # Development shell
139
+          devShells.default = pkgs.mkShell {
140
+            buildInputs = buildDeps ++ libDeps ++ [
141
+              rustToolchain
142
+            ];
143
+
144
+            # Set up pkg-config paths
145
+            PKG_CONFIG_PATH = pkgs.lib.makeSearchPath "lib/pkgconfig" libDeps;
146
+
147
+            # For wayland-scanner
148
+            WAYLAND_PROTOCOLS = "${pkgs.wayland-protocols}/share/wayland-protocols";
149
+
150
+            # Graphics library paths for GUI
151
+            LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath libDeps;
152
+
153
+            shellHook = ''
154
+              echo "HyprKVM development shell"
155
+              echo "Rust: $(rustc --version)"
156
+              echo ""
157
+              echo "Run 'cargo build' to compile"
97
             '';
158
             '';
98
-            homepage = "https://github.com/tenseleyFlow/hyprKVM";
99
-            license = licenses.mit;
100
-            platforms = platforms.linux;
101
-            mainProgram = "hyprkvm";
102
           };
159
           };
103
-        };
104
 
160
 
105
-        # Package with GUI support
161
+          # Package (without GUI for smaller binary)
106
-        packages.gui = pkgs.rustPlatform.buildRustPackage {
162
+          packages.default = pkgs.rustPlatform.buildRustPackage {
107
-          pname = "hyprkvm";
163
+            pname = "hyprkvm";
108
-          version = "0.5.1";
164
+            version = "0.5.1";
109
-          src = ./.;
165
+            src = ./.;
110
-
166
+
111
-          cargoLock = {
167
+            cargoLock = {
112
-            lockFile = ./Cargo.lock;
168
+              lockFile = ./Cargo.lock;
169
+            };
170
+
171
+            nativeBuildInputs = buildDeps;
172
+            buildInputs = libDeps;
173
+
174
+            # Builds both hyprkvm (daemon) and hyprkvm-ctl (CLI)
175
+            # buildRustPackage automatically installs all workspace binaries
176
+
177
+            meta = with pkgs.lib; {
178
+              description = "Hyprland-native software KVM switch";
179
+              longDescription = ''
180
+                HyprKVM enables seamless keyboard/mouse control transfer between
181
+                Linux machines running Hyprland. Move past your last workspace
182
+                to switch to another machine.
183
+              '';
184
+              homepage = "https://github.com/tenseleyFlow/hyprKVM";
185
+              license = licenses.mit;
186
+              platforms = platforms.linux;
187
+              mainProgram = "hyprkvm";
188
+            };
113
           };
189
           };
114
 
190
 
115
-          nativeBuildInputs = buildDeps ++ [ pkgs.makeWrapper ];
191
+          # Package with GUI support
116
-          buildInputs = libDeps;
192
+          packages.gui = pkgs.rustPlatform.buildRustPackage {
193
+            pname = "hyprkvm";
194
+            version = "0.5.1";
195
+            src = ./.;
117
 
196
 
118
-          # Build with GUI feature
197
+            cargoLock = {
119
-          buildFeatures = [ "gui" ];
198
+              lockFile = ./Cargo.lock;
199
+            };
120
 
200
 
121
-          # Wrap binary to include graphics library paths
201
+            nativeBuildInputs = buildDeps ++ [ pkgs.makeWrapper ];
122
-          postInstall = ''
202
+            buildInputs = libDeps;
123
-            wrapProgram $out/bin/hyprkvm \
124
-              --prefix LD_LIBRARY_PATH : ${pkgs.lib.makeLibraryPath libDeps}
125
-          '';
126
 
203
 
127
-          meta = with pkgs.lib; {
204
+            # Build with GUI feature
128
-            description = "Hyprland-native software KVM switch (with GUI)";
205
+            buildFeatures = [ "gui" ];
129
-            longDescription = ''
130
-              HyprKVM enables seamless keyboard/mouse control transfer between
131
-              Linux machines running Hyprland. Move past your last workspace
132
-              to switch to another machine.
133
 
206
 
134
-              This package includes the GUI configuration tool.
207
+            # Wrap binary to include graphics library paths
208
+            postInstall = ''
209
+              wrapProgram $out/bin/hyprkvm \
210
+                --prefix LD_LIBRARY_PATH : ${pkgs.lib.makeLibraryPath libDeps}
135
             '';
211
             '';
136
-            homepage = "https://github.com/tenseleyFlow/hyprKVM";
212
+
137
-            license = licenses.mit;
213
+            meta = with pkgs.lib; {
138
-            platforms = platforms.linux;
214
+              description = "Hyprland-native software KVM switch (with GUI)";
139
-            mainProgram = "hyprkvm";
215
+              longDescription = ''
216
+                HyprKVM enables seamless keyboard/mouse control transfer between
217
+                Linux machines running Hyprland. Move past your last workspace
218
+                to switch to another machine.
219
+
220
+                This package includes the GUI configuration tool.
221
+              '';
222
+              homepage = "https://github.com/tenseleyFlow/hyprKVM";
223
+              license = licenses.mit;
224
+              platforms = platforms.linux;
225
+              mainProgram = "hyprkvm";
226
+            };
140
           };
227
           };
141
-        };
228
+        }
142
-      }
229
+      );
143
-    );
230
+    in
231
+    # Merge system-independent and system-specific outputs
232
+    systemIndependent // systemSpecific;
144
 }
233
 }