Files
mesh-catalog/modules/xorg/cmd/xorg/main.go
T
jochen b2c170acda xorg: the display server holds node-display-server and writes the session's start (hq ADR 0208)
The X server, its start and its tools as one module. It provides x11-display with
the machine's reach, gated by the host's seat capability. It writes a block at the
start of ~/.xinitrc: the account's environment, an explicit import into the user
manager, the mesh's X resources merged without cpp, autorandr, the xinitrc slots,
~/.xinitrc.local, and the session's exec from the last slot.

Its Go tools serve the seat's displays and layout (autorandr profiles keyed by
EDID), and set-mode, primary, dpi, input devices and settings, keyboard, a
screenshot (xwd decoded in Go) and the server's log. internal/desktop is how
every desktop tool finds the operator's session from the runtime, which has none:
from the session's own processes, reading only its words, confirmed with logind.
2026-10-04 13:21:47 +02:00

168 lines
8.0 KiB
Go

// xorg's tools (novox/hq ADR 0208, research 026/05): node-display-server's verbs `displays` and
// `layout`, and the module's own tools for one output's mode, the primary output, DPI, input devices,
// the keyboard map, a screenshot and the server's log.
//
// Every tool that touches the screen acts in the operator's running session, which it finds through
// internal/desktop: the node's runtime has none of its own. With no session, the answer says so as
// structured data. A tool that changes the running server changes it until the next login; the
// answer says what makes it last.
package main
import (
"context"
"fmt"
"os"
"time"
stdio "git.novox.be/novox/mesh-sdk/go"
"xorg/internal/desktop"
)
// The session's holders this module prefers as the session's own process.
var sessionHolders = []string{"i3", "sway", "openbox", "bspwm", "awesome", "xmonad"}
func main() {
if err := stdio.Serve("", tools(desktop.Machine(sessionHolders...))); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
// call bounds one tool call below the runtime's 30 s limit.
func call(run func(ctx context.Context, a desktop.Args) (any, error)) func(map[string]any) (any, error) {
return func(args map[string]any) (any, error) {
ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second)
defer cancel()
return run(ctx, desktop.Args(args))
}
}
func tools(d desktop.Desk) []stdio.Tool {
x := xorg{d: d}
return []stdio.Tool{
{
Name: "node-display-server.displays",
Description: "The X screen and every output: connected or not, primary, where it sits, its rotation, " +
"physical size and DPI, the monitor's identity from its EDID (manufacturer, product, serial, name, " +
"fingerprint), the current and preferred mode, and every mode with its rates. Disconnected outputs " +
"are listed by name only unless all is true. Also the autorandr profile in force, when one matches.",
Input: desktop.Schema(map[string]any{
"all": desktop.Flag("list disconnected outputs in full (default false)"),
"modes": desktop.Flag("list every mode of each output (default true)"),
}),
Run: call(x.displays),
},
{
Name: "node-display-server.layout",
Description: "Monitor layout profiles (autorandr), keyed by the connected monitors' identities, so one " +
"profile needs no machine's name. list: every profile with the monitors it is for, which match " +
"the monitors connected now and which is in force. save: the current arrangement under a name " +
"(replace true to overwrite). apply: load one. The profiles are the operator's data, never the mesh's.",
Input: desktop.Schema(map[string]any{
"action": desktop.Enum("list, save or apply", "list", "save", "apply"),
"name": desktop.Str("the profile to save or apply"),
"replace": desktop.Flag("save over an existing profile of that name (default false)"),
}, "action"),
Run: call(x.layout),
},
{
Name: "xorg_set_mode",
Description: "Change one output now, through xrandr: its mode (WxH, or auto for the preferred one), rate, " +
"rotation, scale, position (x/y, or beside another output), on or off, primary. dry_run answers " +
"the command without running it. Lasts until the next login or hotplug: save a layout profile to keep it.",
Input: desktop.Schema(map[string]any{
"output": desktop.Str("the output, as displays names it (e.g. eDP-1)"),
"mode": desktop.Str("WxH, or auto for the monitor's preferred mode"),
"rate": desktop.Num("refresh rate in Hz"),
"rotate": desktop.Enum("rotation", "normal", "left", "right", "inverted"),
"scale": desktop.Num("scale factor, 0.25 to 4 (1 = none)"),
"x": desktop.Int("left edge on the screen, in pixels"),
"y": desktop.Int("top edge on the screen, in pixels"),
"relation": desktop.Enum("place it beside another output instead of at x/y", "right-of", "left-of", "above", "below", "same-as"),
"of": desktop.Str("the output the relation is to"),
"off": desktop.Flag("switch the output off"),
"primary": desktop.Flag("make it the primary output"),
"dry_run": desktop.Flag("answer the command, run nothing"),
}, "output"),
Run: call(x.setMode),
},
{
Name: "xorg_primary",
Description: "Which output is primary (the one the bar's tray and new windows prefer); with output, make it primary now.",
Input: desktop.Schema(map[string]any{"output": desktop.Str("the output to make primary (optional)")}),
Run: call(x.primary),
},
{
Name: "xorg_dpi",
Description: "The DPI X programs are told (Xft.dpi) beside each monitor's physical DPI. With value, set " +
"Xft.dpi and the screen's DPI now: programs started after it use it. The module's resources file " +
"sets it again at the next login (96 until it is a setting).",
Input: desktop.Schema(map[string]any{"value": desktop.Int("dots per inch, 48 to 480 (optional)")}),
Run: call(x.dpi),
},
{
Name: "xorg_input_devices",
Description: "The input devices the X server knows: id, name, pointer or keyboard, master or slave, and " +
"for each pointer its libinput settings (tap, natural scroll, acceleration, disable while typing, " +
"left handed, enabled).",
Input: desktop.Schema(map[string]any{"name": desktop.Str("only devices whose name contains this (optional)")}),
Run: call(x.inputDevices),
},
{
Name: "xorg_input_set",
Description: "Change libinput settings of a device now: tap, tap_drag, natural_scroll, disable_while_typing, " +
"left_handed, middle_emulation, enabled (true/false), accel_speed (-1 to 1). The device is an id or a " +
"name; a name applies to every device of that name that has the setting. Lasts until the device " +
"reconnects or the next login.",
Input: desktop.Schema(map[string]any{
"device": desktop.Str("the device's id or exact name"),
"tap": desktop.Flag("tap to click"),
"tap_drag": desktop.Flag("tap and drag"),
"natural_scroll": desktop.Flag("natural (reversed) scrolling"),
"disable_while_typing": desktop.Flag("ignore the touchpad while typing"),
"left_handed": desktop.Flag("swap the buttons"),
"middle_emulation": desktop.Flag("both buttons together are the middle one"),
"enabled": desktop.Flag("the device takes input at all"),
"accel_speed": desktop.Num("pointer acceleration, -1 to 1"),
}, "device"),
Run: call(x.inputSet),
},
{
Name: "xorg_keyboard",
Description: "The X keyboard map: rules, model, layout, variant and options. With layout, variant, model " +
"or options, set them now (options replace the current ones; an empty list clears them). Lasts " +
"until the next login.",
Input: desktop.Schema(map[string]any{
"layout": desktop.Str("e.g. us, be, us,be"),
"variant": desktop.Str("e.g. intl"),
"model": desktop.Str("e.g. pc105"),
"options": desktop.List("e.g. [\"caps:escape\", \"compose:ralt\"]"),
}),
Run: call(x.keyboard),
},
{
Name: "xorg_screenshot",
Description: "Take a screenshot to a PNG file: the whole screen, one output, or one window by its X id. " +
"Written under the account's home (default ~/Pictures/Screenshots/screenshot-<time>.png). Answers " +
"the path, size and bytes, never the image.",
Input: desktop.Schema(map[string]any{
"output": desktop.Str("only this output (optional)"),
"window": desktop.Str("only this window, by its X id, e.g. 0x3a00007 (optional)"),
"path": desktop.Str("where to write it, inside the home (optional)"),
}),
Run: call(x.screenshot),
},
{
Name: "xorg_x_log",
Description: "The X server's log for the running session (or the newest one): its version, when it " +
"started, and its errors — with warnings when asked — newest last.",
Input: desktop.Schema(map[string]any{
"warnings": desktop.Flag("include warnings (default false)"),
"limit": desktop.Int("at most this many lines (default 100, at most 1000)"),
}),
Run: call(x.xlog),
},
}
}