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
|
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.
|
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
|
## Tools
|
||||||
|
|
||||||
Served by the node's runtime as the operator account (ADR 0175). The tools find the operator's X
|
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.
|
// every desktop module that carries it.
|
||||||
|
|
||||||
type manifest struct {
|
type manifest struct {
|
||||||
Module string `json:"module"`
|
Module string `json:"module"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Capabilities []string `json:"capabilities"`
|
Capabilities []string `json:"capabilities"`
|
||||||
Requires []string `json:"requires"`
|
Requires []string `json:"requires"`
|
||||||
Claims []claim `json:"claims"`
|
Claims []claim `json:"claims"`
|
||||||
Seats []any `json:"seats"`
|
Seats []any `json:"seats"`
|
||||||
Tools []string `json:"tools"`
|
Tools []string `json:"tools"`
|
||||||
Environment *environment `json:"environment"`
|
Settings map[string]setting `json:"settings"`
|
||||||
Shell []shellCode `json:"shell"`
|
Environment *environment `json:"environment"`
|
||||||
Resources []map[string]any `json:"resources"`
|
Shell []shellCode `json:"shell"`
|
||||||
|
Resources []map[string]any `json:"resources"`
|
||||||
Build struct {
|
Build struct {
|
||||||
Artifacts []map[string]any `json:"artifacts"`
|
Artifacts []map[string]any `json:"artifacts"`
|
||||||
} `json:"build"`
|
} `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 {
|
type claim struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Scope string `json:"scope"`
|
Scope string `json:"scope"`
|
||||||
|
|||||||
@@ -59,3 +59,36 @@ func TestTheToolsAgreeWithTheManifest(t *testing.T) {
|
|||||||
checkTheToolsAgree(t, m)
|
checkTheToolsAgree(t, m)
|
||||||
checkNoSecretsOrInstallationNames(t)
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
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" {
|
if r.Global["backend"] != "glx" || r.Global["vsync"] != "true" || r.Global["shadow"] != "false" {
|
||||||
t.Fatalf("global options: %v", r.Global)
|
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
|
# 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.
|
# 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;
|
vsync = true;
|
||||||
|
|
||||||
fading = true;
|
fading = true;
|
||||||
|
|||||||
@@ -13,6 +13,18 @@
|
|||||||
"scope": "node"
|
"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": [
|
"tools": [
|
||||||
"picom_restart",
|
"picom_restart",
|
||||||
"picom_rules",
|
"picom_rules",
|
||||||
@@ -43,7 +55,7 @@
|
|||||||
"path": "${machine:account-home}/.config/picom/picom.conf",
|
"path": "${machine:account-home}/.config/picom/picom.conf",
|
||||||
"owner": "${machine:account}",
|
"owner": "${machine:account}",
|
||||||
"mode": "0644",
|
"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": {
|
"build": {
|
||||||
|
|||||||
Reference in New Issue
Block a user