Merge pull request 'picom: the backend and damage tracking are each machine's settings (hq issue 345)' (#157) from feat/picom-backend-and-damage-settings into main
This commit was merged in pull request #157.
This commit is contained in:
@@ -13,6 +13,24 @@ The X compositor as a module (novox/hq ADR 0208, research 026).
|
||||
a process has one starter. Its package's autostart entry is that starter where there is one, and
|
||||
the `xinitrc` slot where there is none.
|
||||
|
||||
## Settings
|
||||
|
||||
Two preferences, each a machine's own (the per-node layer of `settings`), because the right values follow
|
||||
the machine's graphics driver (novox/hq research 037):
|
||||
|
||||
| setting | default | what it changes |
|
||||
|---|---|---|
|
||||
| `backend` | `glx` | how picom draws: `glx` on the graphics card, `xrender` on the CPU |
|
||||
| `use-damage` | `true` | `true` repaints only what changed (picom's own default); `false` repaints the whole screen each frame |
|
||||
|
||||
The defaults are what every machine ran before, so the file filled with them changes nothing. They exist
|
||||
for hq issue 345: a window that is mapped but shows nothing (a calendar reminder) or stays stale after a
|
||||
workspace switch (a chat window) is a known failure of glx with damage tracking on some drivers, and
|
||||
`xrender` or `use-damage` false is how a machine is set to test that. The file stays trusted, so both are set at the
|
||||
controller's terminal alone (issue 339): a value is pasted into picom.conf as it is, and a backend of
|
||||
`xrender"; write-pid-path = "…` would add an option of the caller's (hq issue 346). A changed file is read at
|
||||
the next `picom_restart` or login: the module has no unit to reload.
|
||||
|
||||
## Tools
|
||||
|
||||
Served by the node's runtime as the operator account (ADR 0175). The tools find the operator's X
|
||||
|
||||
@@ -12,21 +12,29 @@ import (
|
||||
// every desktop module that carries it.
|
||||
|
||||
type manifest struct {
|
||||
Module string `json:"module"`
|
||||
Version string `json:"version"`
|
||||
Capabilities []string `json:"capabilities"`
|
||||
Requires []string `json:"requires"`
|
||||
Claims []claim `json:"claims"`
|
||||
Seats []any `json:"seats"`
|
||||
Tools []string `json:"tools"`
|
||||
Environment *environment `json:"environment"`
|
||||
Shell []shellCode `json:"shell"`
|
||||
Resources []map[string]any `json:"resources"`
|
||||
Module string `json:"module"`
|
||||
Version string `json:"version"`
|
||||
Capabilities []string `json:"capabilities"`
|
||||
Requires []string `json:"requires"`
|
||||
Claims []claim `json:"claims"`
|
||||
Seats []any `json:"seats"`
|
||||
Tools []string `json:"tools"`
|
||||
Settings map[string]setting `json:"settings"`
|
||||
Environment *environment `json:"environment"`
|
||||
Shell []shellCode `json:"shell"`
|
||||
Resources []map[string]any `json:"resources"`
|
||||
Build struct {
|
||||
Artifacts []map[string]any `json:"artifacts"`
|
||||
} `json:"build"`
|
||||
}
|
||||
|
||||
// setting is one key's default, as the definition gives it (novox/hq ADR 0262).
|
||||
type setting struct {
|
||||
Kind string `json:"kind"`
|
||||
Default any `json:"default"`
|
||||
Why string `json:"why"`
|
||||
}
|
||||
|
||||
type claim struct {
|
||||
Name string `json:"name"`
|
||||
Scope string `json:"scope"`
|
||||
|
||||
@@ -59,3 +59,36 @@ func TestTheToolsAgreeWithTheManifest(t *testing.T) {
|
||||
checkTheToolsAgree(t, m)
|
||||
checkNoSecretsOrInstallationNames(t)
|
||||
}
|
||||
|
||||
// The backend and damage tracking are each machine's (novox/hq research 037: the backend depends on the
|
||||
// machine's graphics driver; issue 345: a window left unpainted under glx is the first suspect). Both
|
||||
// are settings whose defaults are what every machine ran before, so the file filled with them is today's.
|
||||
func TestTheBackendAndDamageTrackingAreSettingsWithTodaysDefaults(t *testing.T) {
|
||||
m := readManifest(t)
|
||||
b, d := m.Settings["backend"], m.Settings["use-damage"]
|
||||
if b.Kind != "preference" || b.Default != "glx" || b.Why == "" || d.Kind != "preference" || d.Default != true || d.Why == "" {
|
||||
t.Fatalf("settings: %+v", m.Settings)
|
||||
}
|
||||
r := m.resource(t, "configuration")
|
||||
c := r["content"].(string)
|
||||
for _, want := range []string{`backend = "${setting:backend}";`, "use-damage = ${setting:use-damage};"} {
|
||||
if !strings.Contains(c, want) {
|
||||
t.Errorf("the file asks for %q", want)
|
||||
}
|
||||
}
|
||||
// Trusted (unmarked): a value is pasted into the file as it is, so `xrender"; write-pid-path = "…`
|
||||
// would add an option of the caller's. Until settings are typed and quoted (hq issue 346), only the
|
||||
// controller's terminal sets them.
|
||||
if _, marked := r["trusted"]; marked {
|
||||
t.Fatal("the file stays trusted: its settings are set at the terminal alone (hq issue 346)")
|
||||
}
|
||||
got := parseRules("picom.conf", withDefaults(c), nil)
|
||||
if got.Global["backend"] != "glx" || got.Global["use-damage"] != "true" || got.Global["vsync"] != "true" {
|
||||
t.Fatalf("filled with the defaults: %v", got.Global)
|
||||
}
|
||||
}
|
||||
|
||||
// withDefaults fills the file's settings with their defaults, as a machine without its own values gets it.
|
||||
func withDefaults(c string) string {
|
||||
return strings.NewReplacer("${setting:backend}", "glx", "${setting:use-damage}", "true").Replace(c)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func TestTheModulesOwnConfigurationReadsAsRulesInOrder(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r := parseRules("picom.conf", string(raw), nil)
|
||||
r := parseRules("picom.conf", withDefaults(string(raw)), nil)
|
||||
if r.Global["backend"] != "glx" || r.Global["vsync"] != "true" || r.Global["shadow"] != "false" {
|
||||
t.Fatalf("global options: %v", r.Global)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
# replaced at every push. Adopted from the two workstations' file of 2026-10-04 and moved to
|
||||
# picom's window rules, which supersede opacity-rule, inactive-opacity and inactive-dim.
|
||||
|
||||
backend = "glx";
|
||||
# The backend and damage tracking are each machine's settings (backend, use-damage; novox/hq research
|
||||
# 037, issue 345): the right ones depend on the machine's graphics driver. The defaults are what every
|
||||
# machine ran before: glx, and picom's own default of repainting only what changed. xrender, or
|
||||
# use-damage false (repaint the whole screen each frame), is what to try on a machine where a window is
|
||||
# left unpainted or stale.
|
||||
backend = "${setting:backend}";
|
||||
use-damage = ${setting:use-damage};
|
||||
vsync = true;
|
||||
|
||||
fading = true;
|
||||
|
||||
@@ -13,6 +13,18 @@
|
||||
"scope": "node"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"backend": {
|
||||
"kind": "preference",
|
||||
"default": "glx",
|
||||
"why": "glx draws with the graphics card and has served every machine so far; xrender draws on the CPU and is what to try where glx leaves a window unpainted or stale on the machine's driver (novox/hq research 037, issue 345)"
|
||||
},
|
||||
"use-damage": {
|
||||
"kind": "preference",
|
||||
"default": true,
|
||||
"why": "true repaints only what changed, picom's own default; false repaints the whole screen each frame, which costs work and cures a window left stale or unpainted on some drivers (novox/hq issue 345)"
|
||||
}
|
||||
},
|
||||
"tools": [
|
||||
"picom_restart",
|
||||
"picom_rules",
|
||||
@@ -43,7 +55,7 @@
|
||||
"path": "${machine:account-home}/.config/picom/picom.conf",
|
||||
"owner": "${machine:account}",
|
||||
"mode": "0644",
|
||||
"content": "# picom, the X compositor (module picom, novox/hq ADR 0208). Owned by the mesh: this file is\n# replaced at every push. Adopted from the two workstations' file of 2026-10-04 and moved to\n# picom's window rules, which supersede opacity-rule, inactive-opacity and inactive-dim.\n\nbackend = \"glx\";\nvsync = true;\n\nfading = true;\nfade-in-step = 0.05;\nfade-out-step = 0.05;\n\n# Tiled windows hide their shadows and corners, so neither is drawn.\nshadow = false;\ncorner-radius = 0;\nblur-method = \"none\";\n\n# \"Focused\" is i3's _NET_ACTIVE_WINDOW, not X focus events: under i3 those do not reliably reach\n# the toplevel picom tracks, and a terminal then never lifts to its focused opacity.\nuse-ewmh-active-win = true;\n\n# Window rules are applied in order, and a later match wins. Only terminals are translucent:\n# nothing else on screen (browsers, video, games) is touched. A terminal is matched by its class;\n# the node's terminal emulator today is xterm (class XTerm). A window's own opacity property is\n# used wherever no rule sets one, which is what the window-opacity tool sets.\nrules = (\n { match = \"window_type = 'tooltip'\"; fade = false; opacity = 0.95; },\n { match = \"window_type = 'dock' || window_type = 'desktop'\"; fade = false; },\n { match = \"class_g = 'XTerm' && focused\"; opacity = 0.95; },\n { match = \"class_g = 'XTerm' && !focused\"; opacity = 0.75; },\n # A full-screen window is opaque, a terminal included: a video or a game is never see-through.\n { match = \"fullscreen\"; opacity = 1; }\n);\n"
|
||||
"content": "# picom, the X compositor (module picom, novox/hq ADR 0208). Owned by the mesh: this file is\n# replaced at every push. Adopted from the two workstations' file of 2026-10-04 and moved to\n# picom's window rules, which supersede opacity-rule, inactive-opacity and inactive-dim.\n\n# The backend and damage tracking are each machine's settings (backend, use-damage; novox/hq research\n# 037, issue 345): the right ones depend on the machine's graphics driver. The defaults are what every\n# machine ran before: glx, and picom's own default of repainting only what changed. xrender, or\n# use-damage false (repaint the whole screen each frame), is what to try on a machine where a window is\n# left unpainted or stale.\nbackend = \"${setting:backend}\";\nuse-damage = ${setting:use-damage};\nvsync = true;\n\nfading = true;\nfade-in-step = 0.05;\nfade-out-step = 0.05;\n\n# Tiled windows hide their shadows and corners, so neither is drawn.\nshadow = false;\ncorner-radius = 0;\nblur-method = \"none\";\n\n# \"Focused\" is i3's _NET_ACTIVE_WINDOW, not X focus events: under i3 those do not reliably reach\n# the toplevel picom tracks, and a terminal then never lifts to its focused opacity.\nuse-ewmh-active-win = true;\n\n# Window rules are applied in order, and a later match wins. Only terminals are translucent:\n# nothing else on screen (browsers, video, games) is touched. A terminal is matched by its class;\n# the node's terminal emulator today is xterm (class XTerm). A window's own opacity property is\n# used wherever no rule sets one, which is what the window-opacity tool sets.\nrules = (\n { match = \"window_type = 'tooltip'\"; fade = false; opacity = 0.95; },\n { match = \"window_type = 'dock' || window_type = 'desktop'\"; fade = false; },\n { match = \"class_g = 'XTerm' && focused\"; opacity = 0.95; },\n { match = \"class_g = 'XTerm' && !focused\"; opacity = 0.75; },\n # A full-screen window is opaque, a terminal included: a video or a game is never see-through.\n { match = \"fullscreen\"; opacity = 1; }\n);\n"
|
||||
}
|
||||
],
|
||||
"build": {
|
||||
|
||||
Reference in New Issue
Block a user