mesh/merge-gate head c070bea782aa merged into trunk 7443938fef69 — pass: builds clipmenu → g14, shanks; no bus step; every machine composes with the change…
mesh/repo-check head c070bea782aa merged into trunk 7443938fef69 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered
116 lines
5.5 KiB
JSON
116 lines
5.5 KiB
JSON
{
|
|
"module": "clipmenu",
|
|
"version": "1",
|
|
"capabilities": [
|
|
"package-manager"
|
|
],
|
|
"requires": [
|
|
"x11-display"
|
|
],
|
|
"claims": [
|
|
{
|
|
"name": "node-clipboard",
|
|
"scope": "node",
|
|
"serves": [
|
|
"history",
|
|
"copy"
|
|
]
|
|
}
|
|
],
|
|
"tools": [
|
|
"clipmenu_paste",
|
|
"clipmenu_clear",
|
|
"clipmenu_delete"
|
|
],
|
|
"environment": {
|
|
"variables": {
|
|
"CM_SELECTIONS": "clipboard",
|
|
"CM_MAX_CLIPS": "500",
|
|
"CM_HISTLENGTH": "15"
|
|
}
|
|
},
|
|
"resources": [
|
|
{
|
|
"id": "package",
|
|
"type": "package",
|
|
"package": "clipmenu"
|
|
},
|
|
{
|
|
"id": "greenclip",
|
|
"type": "package",
|
|
"package": "rofi-greenclip",
|
|
"absent": true
|
|
},
|
|
{
|
|
"id": "text-only",
|
|
"type": "file",
|
|
"path": "/usr/local/lib/mesh-clipmenu/xsel",
|
|
"mode": "0755",
|
|
"content": "#!/bin/sh\n# xsel as clipmenud sees it, written by the mesh (module clipmenu). Replaced at every push.\n#\n# clipmenud records text, and reads a selection with `timeout 1 xsel -o`. A selection holding an\n# image (a screenshot copied as image/png) is sent in pieces; one second is too short for megabytes,\n# timeout kills xsel half way, and the program owning the image waits for ever for a reader that is\n# gone. From then on nothing can ask the clipboard anything: pastes hang, and an Electron app that\n# asks on its main thread freezes. So a read goes ahead only when the selection offers text.\ncase \" $* \" in\n*\" -o \"* | *\" --output \"*)\n\tselection=clipboard\n\tcase \" $* \" in\n\t*\" --primary \"* | *\" -p \"*) selection=primary ;;\n\t*\" --secondary \"* | *\" -s \"*) selection=secondary ;;\n\tesac\n\ttargets=$(timeout 1 xclip -selection \"$selection\" -t TARGETS -o 2>/dev/null) || exit 1\n\tprintf '%s\\n' \"$targets\" | grep -qxE 'UTF8_STRING|STRING|TEXT|text/plain(;charset=utf-8)?' || exit 1\n\t;;\nesac\nexec /usr/bin/xsel \"$@\"\n"
|
|
},
|
|
{
|
|
"id": "user-units-dir",
|
|
"type": "directory",
|
|
"path": "${machine:account-home}/.config/systemd/user",
|
|
"owner": "${machine:account}",
|
|
"mode": "0755"
|
|
},
|
|
{
|
|
"id": "daemon-dropins",
|
|
"type": "directory",
|
|
"path": "${machine:account-home}/.config/systemd/user/clipmenud.service.d",
|
|
"owner": "${machine:account}",
|
|
"mode": "0755"
|
|
},
|
|
{
|
|
"id": "daemon-dropin",
|
|
"type": "file",
|
|
"path": "${machine:account-home}/.config/systemd/user/clipmenud.service.d/mesh.conf",
|
|
"owner": "${machine:account}",
|
|
"mode": "0644",
|
|
"content": "# clipmenud in the operator's account (module clipmenu, novox/hq ADR 0208). Owned by the mesh: replaced at every push.\n# The package's unit starts clipmenud with no DISPLAY; the module's launcher finds the display and puts the\n# text-only xsel first on the PATH. The settings repeat the module's environment, which the account's\n# service manager does not read.\n[Unit]\nStartLimitIntervalSec=0\n\n[Service]\nRestartSec=2s\nEnvironment=CM_SELECTIONS=clipboard\nEnvironment=CM_MAX_CLIPS=500\nEnvironment=CM_HISTLENGTH=15\nExecStart=\nExecStart=/usr/local/lib/mesh-clipmenu/clipmenud-session\n"
|
|
},
|
|
{
|
|
"id": "launcher",
|
|
"type": "file",
|
|
"path": "/usr/local/lib/mesh-clipmenu/clipmenud-session",
|
|
"mode": "0755",
|
|
"content": "#!/bin/sh\n# clipmenud as the operator's user unit starts it, written by the mesh (module clipmenu). Replaced at every push.\n#\n# The account's service manager starts before the X server does, and has a DISPLAY only once the session's\n# xinitrc has handed it over (module xorg). So this waits, quietly, until the display is known, and exits\n# only when the session ends with it: a quick exit would run the unit into its start limit. DISPLAY, when\n# the manager has it, wins. Without it, exactly one X socket names the display; none or several (a\n# second server beside the session) wait for the session's own to arrive.\n# A running process does not see what the session hands the manager later, so each pass asks the manager.\nuntil [ -n \"$DISPLAY\" ]; do\n\tfor pair in $(systemctl --user show-environment 2>/dev/null | grep -E '^(DISPLAY|XAUTHORITY)='); do\n\t\texport \"$pair\"\n\tdone\n\t[ -n \"$DISPLAY\" ] && break\n\tset -- /tmp/.X11-unix/X*\n\tif [ $# -eq 1 ] && [ -S \"$1\" ]; then\n\t\tDISPLAY=\":${1##*/X}\"\n\t\texport DISPLAY\n\telse\n\t\tsleep 1\n\tfi\ndone\nif [ -z \"$XAUTHORITY\" ] && [ -r \"$HOME/.Xauthority\" ]; then\n\tXAUTHORITY=\"$HOME/.Xauthority\"\n\texport XAUTHORITY\nfi\nPATH=\"/usr/local/lib/mesh-clipmenu:$PATH\"\nexport PATH\nexec clipmenud\n"
|
|
},
|
|
{
|
|
"id": "daemon",
|
|
"type": "service",
|
|
"unit": "clipmenud.service",
|
|
"scope": "user",
|
|
"user": "${machine:account}",
|
|
"state": "running",
|
|
"boot": "enabled",
|
|
"health": {
|
|
"kind": "unit"
|
|
}
|
|
}
|
|
],
|
|
"build": {
|
|
"artifacts": [
|
|
{
|
|
"name": "tools",
|
|
"kind": "bundle",
|
|
"language": "go",
|
|
"system": "arch",
|
|
"from": "cmd/clipmenu-tools",
|
|
"binary": "clipmenu-tools",
|
|
"loads": [
|
|
"clipmenu-tools"
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"contributions": [
|
|
{
|
|
"seat": "node-display-session",
|
|
"kind": "config",
|
|
"content": "# The clipboard's history key (module clipmenu, novox/hq ADR 0208). Owned by the mesh: replaced at\n# every push. clipmenu shows the history through `dmenu`, the node's dmenu-compatible command, which\n# the holder of node-launcher answers (rofi on the workstations); the chosen entry is put back on the\n# clipboard.\nbindsym $mod+period exec --no-startup-id clipmenu -p Clipboard\n"
|
|
}
|
|
]
|
|
}
|