add Ringboard pkg and service module (#445583)

This commit is contained in:
h7x4
2025-10-02 22:49:20 +00:00
committed by GitHub
7 changed files with 242 additions and 0 deletions
@@ -142,6 +142,8 @@
- [nvme-rs](https://github.com/liberodark/nvme-rs), NVMe monitoring [services.nvme-rs](#opt-services.nvme-rs.enable).
- [ringboard](https://github.com/SUPERCILEX/clipboard-history), a fast, efficient, and composable clipboard manager for Linux. Available for x11 as [services.ringboard](#opt-services.ringboard.x11.enable) and for wayland as [services.ringboard](#opt-services.ringboard.wayland.enable).
## Backward Incompatibilities {#sec-release-25.11-incompatibilities}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
+1
View File
@@ -915,6 +915,7 @@
./services/misc/redlib.nix
./services/misc/redmine.nix
./services/misc/renovate.nix
./services/misc/ringboard.nix
./services/misc/rkvm.nix
./services/misc/rmfakecloud.nix
./services/misc/rshim.nix
+78
View File
@@ -0,0 +1,78 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.ringboard;
in
{
options.services.ringboard = {
x11.enable = lib.mkEnableOption "X11 support for Ringboard";
wayland.enable = lib.mkEnableOption "Wayland support for Ringboard";
x11.package = lib.mkPackageOption pkgs "ringboard" { };
wayland.package = lib.mkPackageOption pkgs "ringboard-wayland" { };
};
config = lib.mkIf (cfg.x11.enable || cfg.wayland.enable) {
systemd.user.services.ringboard-server = {
description = "Ringboard server";
documentation = [ "https://github.com/SUPERCILEX/clipboard-history" ];
after = [ "multi-user.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "notify";
Environment = "RUST_LOG=trace";
ExecStart = "${
if cfg.x11.enable then cfg.x11.package else cfg.wayland.package
}/bin/ringboard-server";
Restart = "on-failure";
Slice = "session-ringboard.slice";
};
};
systemd.user.services.ringboard-listener = {
description = "Ringboard clipboard listener";
documentation = [ "https://github.com/SUPERCILEX/clipboard-history" ];
requires = [ "ringboard-server.service" ];
after = [
"ringboard-server.service"
"graphical-session.target"
];
bindsTo = [ "graphical-session.target" ];
wantedBy = [ "graphical-session.target" ];
script =
if cfg.x11.enable && cfg.wayland.enable then
''
if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
exec '${cfg.wayland.package}'/bin/ringboard-wayland
else
exec '${cfg.x11.package}'/bin/ringboard-x11
fi
''
else if cfg.wayland.enable then
''
exec '${cfg.wayland.package}'/bin/ringboard-wayland
''
else
''
exec '${cfg.x11.package}'/bin/ringboard-x11
'';
serviceConfig = {
Type = "exec";
Restart = "on-failure";
Slice = "session-ringboard.slice";
};
environment.RUST_LOG = "trace";
};
systemd.user.slices.session-ringboard = {
description = "Ringboard clipboard services";
};
environment.systemPackages =
lib.optionals cfg.x11.enable [ cfg.x11.package ]
++ lib.optionals cfg.wayland.enable [ cfg.wayland.package ];
};
}
+1
View File
@@ -1300,6 +1300,7 @@ in
restic = runTest ./restic.nix;
restic-rest-server = runTest ./restic-rest-server.nix;
retroarch = runTest ./retroarch.nix;
ringboard = runTest ./ringboard.nix;
rke2 = handleTestOn [ "aarch64-linux" "x86_64-linux" ] ./rke2 { };
rkvm = handleTest ./rkvm { };
rmfakecloud = runTest ./rmfakecloud.nix;
+49
View File
@@ -0,0 +1,49 @@
{
config,
pkgs,
lib,
...
}:
{
name = "ringboard";
meta = { inherit (pkgs.ringboard.meta) maintainers; };
nodes.machine = {
imports = [
./common/user-account.nix
./common/x11.nix
];
test-support.displayManager.auto.user = "alice";
services.xserver.displayManager.sessionCommands = ''
'${lib.getExe pkgs.gedit}' &
'';
services.ringboard.x11.enable = true;
};
testScript =
{ nodes, ... }:
let
inherit (nodes.machine.test-support.displayManager.auto) user;
in
''
@polling_condition
def gedit_running():
machine.succeed("pgrep gedit")
with subtest("Wait for service startup"):
machine.wait_for_unit("graphical.target")
machine.wait_for_unit("ringboard-server.service", "${user}")
machine.wait_for_unit("ringboard-listener.service", "${user}")
with subtest("Ensure clipboard is monitored"):
with gedit_running: # type: ignore[union-attr]
machine.send_chars("Hello world!")
machine.send_key("ctrl-a")
machine.send_key("ctrl-c")
machine.wait_for_console_text("Small selection transfer complete")
machine.succeed("su - '${user}' -c 'ringboard search Hello | grep world!'")
'';
}
+109
View File
@@ -0,0 +1,109 @@
{
stdenv,
rustPlatform,
fetchFromGitHub,
lib,
libxkbcommon,
libGL,
wayland,
xorg,
makeWrapper,
displayServer ? "x11",
nixosTests,
}:
assert lib.assertOneOf "displayServer" displayServer [
"x11"
"wayland"
];
rustPlatform.buildRustPackage (finalAttrs: {
pname = "ringboard" + lib.optionalString (displayServer == "wayland") "-wayland";
# release version needs nightly, so we use a custom tree, see:
# https://github.com/SUPERCILEX/clipboard-history/issues/22#issuecomment-3322075172
version = "0.12.2-unstable-2025-09-23";
src = fetchFromGitHub {
owner = "SUPERCILEX";
repo = "clipboard-history";
rev = "228a39dd8a9aece0bb06f68ad44906b297270628";
hash = "sha256-qA7wwvWnnZHN9edkmubEo37F+peU0LQGo/Zl8FpywuE=";
};
cargoHash = "sha256-MFfuUu/hpb6Uaqe21bvXNKRyJazAL5m+Vw/vAeeDYEk=";
nativeBuildInputs = [
makeWrapper
];
buildInputs = [
libxkbcommon
libGL
]
++ lib.optionals (displayServer == "x11") [
xorg.libXcursor
xorg.libXrandr
xorg.libXi
xorg.libX11
]
++ lib.optionals (displayServer == "wayland") [
wayland
];
buildPhase = ''
runHook preBuild
local flagsArray=("-j $NIX_BUILD_CORES --target ${stdenv.hostPlatform.rust.rustcTarget} --offline --release");
concatTo flagsArray cargoBuildFlags;
echo "Building package: clipboard-history-server"
cargo build $flagsArray --package clipboard-history-server --no-default-features --features systemd
${lib.optionalString (displayServer == "x11") ''
echo "Building package: clipboard-history-x11"
cargo build $flagsArray --package clipboard-history-x11 --no-default-features
''}
${lib.optionalString (displayServer == "wayland") ''
echo "Building package: clipboard-history-wayland"
cargo build $flagsArray --package clipboard-history-wayland --no-default-features
''}
echo "Building package: clipboard-history"
cargo build $flagsArray --package clipboard-history
echo "Building package: clipboard-history-tui"
cargo build $flagsArray --package clipboard-history-tui
echo "Building package: clipboard-history-egui"
cargo build $flagsArray --package clipboard-history-egui --no-default-features --features ${displayServer}
runHook postBuild
'';
# check needs nightly, see:
# https://github.com/SUPERCILEX/clipboard-history/issues/22#issuecomment-3322330559
doCheck = false;
postInstall = ''
# Wrap the program in a script that sets the LD_LIBRARY_PATH environment variable
# so that it can find the shared libraries it depends on. This is currently a
# requirement for running Rust programs that depend on `egui` within a Nix environment.
# https://github.com/emilk/egui/issues/2486
wrapProgram $out/bin/ringboard-egui --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath finalAttrs.buildInputs}"
install -m 444 -D egui/ringboard-egui.desktop $out/share/applications/ringboard-egui.desktop
install -Dm644 logo.jpeg $out/share/icons/hicolor/1024x1024/ringboard.jpeg
# Initializing a GUI can be quite slow, so GUI clients make their windows invisible when closed rather than completely quitting.
# To reopen the window, a special file can be deleted which wakes the GUI via inotify.
# If, instead, a new instance of the GUI is opened, this special file is used to first check for a previously running instance of the GUI and kill it if it exists.
# https://alexsaveau.dev/blog/projects/performance/clipboard/ringboard/ringboard#gui-startup-latency-and-long-lived-client-windows
sed -i "s|Exec=ringboard-egui|Exec=$(echo /bin/sh -c \"ps -p \`cat /tmp/.ringboard/\$USER.egui-sleep 2\> /dev/null\` \> /dev/null 2\>\\\&1 \\\&\\\& exec rm -f /tmp/.ringboard/\$USER.egui-sleep \\\|\\\| exec $out/bin/ringboard-egui\")|g" $out/share/applications/ringboard-egui.desktop
sed -i "s|Icon=ringboard|Icon=$out/share/icons/hicolor/1024x1024/ringboard.jpeg|g" $out/share/applications/ringboard-egui.desktop
'';
passthru.tests.nixos = nixosTests.ringboard;
meta = {
description = "Fast, efficient, and composable clipboard manager for Linux";
homepage = "https://github.com/SUPERCILEX/clipboard-history";
license = lib.licenses.asl20;
platforms = lib.platforms.linux;
maintainers = [ lib.maintainers.magnetophon ];
};
})
+2
View File
@@ -12612,6 +12612,8 @@ with pkgs;
rgp = libsForQt5.callPackage ../development/tools/rgp { };
ringboard-wayland = callPackage ../by-name/ri/ringboard/package.nix { displayServer = "wayland"; };
ripcord =
if stdenv.hostPlatform.isLinux then
qt5.callPackage ../applications/networking/instant-messengers/ripcord { }