# clipmenu The clipboard manager as a module (novox/hq ADR 0208, research 026/04). - Installs `clipmenu` from the official repositories. It brings `clipnotify`, `xsel`, `xdotool` and `dmenu` as its own dependencies. - Claims the mesh's `node-clipboard` seat and serves its verbs `history` and `copy`. Requires `x11-display` on its own machine. - **Declares `rofi-greenclip` absent** (ADR 0180). This module replaces it. - Starts `clipmenud` **once per session**, from the session's start (the `xinitrc` slot `normal`). It is not a user unit as well. Its packaged unit needs user-scoped units (mesh-host #72, not merged), and the session start alone is one starter. - Binds `$mod+period` to `clipmenu`, as its own i3 drop-in (`50-clipmenu.conf`). clipmenu shows the history through `dmenu`, the seat command of `node-launcher`, so it looks like every other menu. - Its settings are environment contributions (ADR 0203), read by the daemon, the menu and the tools alike: - `CM_SELECTIONS=clipboard`: what was copied, not every highlighted word. The found greenclip did the same. - `CM_MAX_CLIPS=500`: how many clips are kept. - `CM_HISTLENGTH=15`: how many lines the menu shows. ## Tools | tool | does | |---|---| | `node-clipboard.history` | the history, newest first, each entry once with its id, first line, time, size and text (cut) | | `node-clipboard.copy` | put text on the clipboard; it enters the history like any copy | | `clipmenu_paste` | what the clipboard holds now | | `clipmenu_clear` | forget the history; the daemon's locks stay | | `clipmenu_delete` | forget one entry, by id or first line | The history is read from clipmenu's own store, in the account's runtime directory, under clipmenu's own lock, so a copy arriving meanwhile is neither lost nor half-written. `copy` hands the text to an owner (`xsel`) under the account's service manager. As a child of the tools runtime, the clipboard would empty whenever the runtime restarted. ## What it improves on what was found - **No AUR package.** greenclip came from the user repository. clipmenu is in the official one. - **Started once.** greenclip was started by the window manager on both workstations, and on the desktop by an enabled user unit as well. - **No absolute home path** in any configuration. greenclip's named one. - **The history does not outlive a reboot.** greenclip kept it in `~/.cache`, so every password ever copied stayed on disk. clipmenu keeps it in the runtime directory, which is memory. - **One menu.** The history appears in the launcher's own menu, through the seat's `dmenu` command, instead of a theme from a cloned theme repository. ## What it leaves as found - `~/.config/greenclip.toml` and greenclip's history, `~/.cache/greenclip.history`. - On the desktop: greenclip's enabled user unit link (`~/.config/systemd/user/default.target.wants/greenclip.service`). It dangles once the package is gone. ## Migration (ADR 0182) 1. After the first push, delete `~/.config/greenclip.toml` and `~/.cache/greenclip.history`. 2. On the desktop: `systemctl --user disable greenclip.service`, before the push if you can. The package's removal takes the unit file with it. 3. Until the `i3` module carries the main configuration, the found `exec --no-startup-id greenclip daemon` and `$mod+period` lines stay in `~/.config/i3/config`. i3 reports `$mod+period` as bound twice. The `i3` module's configuration carries neither. ## Blockers - `node-clipboard`, `x11-display` and the `xinitrc` slot are ADR 0208's. Until the controller knows them, `mctl` reads them as unknown. - `CM_*` reach the session through `node-env` (ADR 0203), so the account's environment module must be assigned too. Without it clipmenu runs on its defaults: both selections, 1000 clips, 8 lines. ## Only text is read (added 2026-10-04) clipmenud reads a selection with `timeout 1 xsel -o`. A selection holding an image, such as a screenshot copied as `image/png`, arrives in pieces. One second is too short for megabytes, so `timeout` kills xsel half way, and the program owning the image waits for ever for a reader that is gone. From then on every paste hangs, and an app asking on its main thread (Electron: Slack) freezes. The first screenshot after this module was assigned did exactly that. So clipmenud runs with the module's own `xsel` first on its `PATH` (`/usr/local/lib/mesh-clipmenu/xsel`). Before a read it asks the selection for its `TARGETS` and goes ahead only when the selection offers text. It uses `xclip` for that question, which the `xclip` module installs on every workstation.