diff --git a/AGENTS.md b/AGENTS.md
index 1a34010f..a5b85456 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -140,9 +140,9 @@ repository, and cross-link them — no need to be told.
change.
- `~/codes/nix-secrets` — the private agenix store behind `secrets/` and the `mysecrets` input:
ciphertext and recipient rules for the secrets declared here.
-- `wallpapers`, `nur-ryan4yin`, `nu_scripts`, `mattpocock-skills`, `i-have-adhd` — flake inputs from
- the user's own repositories; bump with `just upp ` after their source changes, do not edit
- them from here.
+- `wallpapers`, `nur-ryan4yin`, `pyclipsync`, `nu_scripts`, `mattpocock-skills`, `i-have-adhd` —
+ flake inputs from the user's own repositories; bump with `just upp ` after their source
+ changes, do not edit them from here.
## Further Context
diff --git a/flake.lock b/flake.lock
index f9cfcc7c..f257ff3a 100644
--- a/flake.lock
+++ b/flake.lock
@@ -851,6 +851,26 @@
"type": "github"
}
},
+ "pyclipsync": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1793503810,
+ "narHash": "sha256-qh3Wjb1gV9FO01vUTGMNcWRwwQ9iUH0tkzVjObEn5J4=",
+ "owner": "ryan4yin",
+ "repo": "pyclipsync",
+ "rev": "080fbb7a21f4afe298d4eaa400645388ec000231",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ryan4yin",
+ "repo": "pyclipsync",
+ "type": "github"
+ }
+ },
"root": {
"inputs": {
"agenix": "agenix",
@@ -884,6 +904,7 @@
"ponytail": "ponytail",
"pre-commit-hooks": "pre-commit-hooks",
"preservation": "preservation",
+ "pyclipsync": "pyclipsync",
"wallpapers": "wallpapers"
}
},
diff --git a/flake.nix b/flake.nix
index 6058e266..9be9d088 100644
--- a/flake.nix
+++ b/flake.nix
@@ -203,5 +203,11 @@
url = "github:ryan4yin/nur-packages";
inputs.nixpkgs.follows = "nixpkgs";
};
+
+ # Wayland <-> X11 clipboard sync for xwayland-satellite (niri).
+ pyclipsync = {
+ url = "github:ryan4yin/pyclipsync";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
};
}
diff --git a/home/linux/gui/niri/default.nix b/home/linux/gui/niri/default.nix
index 422b6050..399d58ea 100644
--- a/home/linux/gui/niri/default.nix
+++ b/home/linux/gui/niri/default.nix
@@ -2,12 +2,18 @@
pkgs,
config,
lib,
+ pyclipsync,
...
}@args:
let
cfg = config.modules.desktop.niri;
in
{
+ imports = [
+ # provides `services.pyclipsync.enable`
+ pyclipsync.homeModules.default
+ ];
+
options.modules.desktop.niri = {
enable = lib.mkEnableOption "niri compositor";
};
@@ -51,6 +57,10 @@ in
};
};
+ # QQ draws a Wayland window but copies through the X11 CLIPBOARD, which
+ # xwayland-satellite bridges only while an X11 window has focus.
+ services.pyclipsync.enable = true;
+
# NOTE: this executable is used by greetd to start a wayland session when system boot up
# with such a vendor-no-locking script, we can switch to another wayland compositor without modifying greetd's config in NixOS module
home.file.".wayland-session" = {