Files
mesh-catalog/modules/xclip/cmd/xclip-tools/main.go
T
jochen b1b7e58e4b xclip: the package, and the operator's clipboard from the mesh (hq to-be 42 phase 2.7)
A package and nothing else, the tool the desktop's scripts depend on.
Four Go tools: copy, paste (text, base64 for other types, empty when
nothing), targets and session.

The runtime is given no session words, but runs as the account in the
machine's own namespace, so the session is found rather than configured:
the process's DISPLAY, else the account's processes' DISPLAY and XAUTHORITY
from /proc (the window manager's first), else the only X socket with
~/.Xauthority. Measured with both variables unset: :1 found through i3, the
server answered. With no session every tool says so and runs nothing.
2026-10-04 13:02:23 +02:00

103 lines
3.3 KiB
Go

// The xclip module's tools (novox/hq research 026/04, 026/05): the plain X clipboard without a
// manager. Copy puts text on a selection, paste reads one, targets says what a selection offers. A Go
// bundle the node's runtime launches over stdio (ADR 0188, ADR 0193). It runs as the operator account
// and reaches the account's X session as session.go finds it; with no session, every tool says so.
package main
import (
"fmt"
"os"
stdio "git.novox.be/novox/mesh-sdk/go"
)
var providedBy = map[string]string{
"xclip": "the xclip package, which this module installs",
}
func main() {
if err := stdio.Serve("", tools()); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
var selectionArg = map[string]any{"type": "string", "enum": Selections, "description": "which selection: clipboard (default), primary or secondary"}
func selectionOf(args map[string]any) (string, error) {
s, err := optText(args, "selection", "clipboard")
if err != nil {
return "", err
}
return s, oneOf("selection", s, Selections...)
}
func tools() []stdio.Tool {
return []stdio.Tool{
{
Name: "xclip_copy",
Description: "Put text on the operator's clipboard (or the primary or secondary selection), as a given type " +
"(default plain UTF-8 text). Needs the operator's graphical session. (d)",
Input: map[string]any{
"text": map[string]any{"type": "string", "description": "what to copy, at most 1 MiB"},
"selection": selectionArg,
"type": map[string]any{"type": "string", "description": "the content's type, such as text/html (default UTF8_STRING)"},
},
Run: func(args map[string]any) (any, error) {
t, ok := args["text"].(string)
if !ok {
return nil, fmt.Errorf("text is required, as a string (it may be empty)")
}
sel, err := selectionOf(args)
if err != nil {
return nil, err
}
typ, err := optText(args, "type", "")
if err != nil {
return nil, err
}
return Copy(t, sel, typ)
},
},
{
Name: "xclip_paste",
Description: "What the operator's clipboard (or another selection) holds now, as text, or as base64 for a " +
"type that is not text. Cut at 256 KiB. Needs the operator's graphical session. (r)",
Input: map[string]any{
"selection": selectionArg,
"type": map[string]any{"type": "string", "description": "the type to ask for, such as text/html or image/png (default UTF8_STRING)"},
},
Run: func(args map[string]any) (any, error) {
sel, err := selectionOf(args)
if err != nil {
return nil, err
}
typ, err := optText(args, "type", "")
if err != nil {
return nil, err
}
return Paste(sel, typ)
},
},
{
Name: "xclip_targets",
Description: "The types a selection is offered as right now (text, HTML, an image…), without reading the content. (r)",
Input: map[string]any{"selection": selectionArg},
Run: func(args map[string]any) (any, error) {
sel, err := selectionOf(args)
if err != nil {
return nil, err
}
return Targets(sel)
},
},
{
Name: "xclip_session",
Description: "Which X session the clipboard tools reach and how it was found, or why there is none; and " +
"whether the X server answers. (r)",
Input: map[string]any{},
Run: func(map[string]any) (any, error) { return SessionCheck() },
},
}
}